[an error occurred while processing this directive]
[an error occurred while processing this directive]
|
Нужно набрать критическую массу знаний по USB. У меня на это ушло года два неинтенсивного чтения спецификаций, книжек, примеров и т.п.
Пример PIC+USBN, ассемблер :-(
http://www.geocities.com/smetanko/usbk_ind.htm
Cохраненную страницу, с исходником на Паскале :-( для AVR выслал на e-mail. И сейчас попробую ее сюда вставить, не уверен, что получится.
Мой исходник собирается опубликовать John Hide на сайте поддержки его книжки www.usb-by-example.com. Жди :-)
.list off
//
// Copyright (C) 1999 Silicon Studio Ltd. http://www.sistudio.com
// AVR+USB Test.
//
// this is first working version!!
//
CPU.Clock = 8000000;
#device 8515
#include//
#include
// PAGE 0 Required things
//
#include descr
req_jumps:
GOTO getstatus; //0
GOTO clearfeature; //1
NOP //2-missing
GOTO setfeature; //3
NOP //4-missing
GOTO setaddress; //5
GOTO getdescriptor; //6
GOTO setdescriptor; //7
GOTO getconfiguration;//8
GOTO setconfiguration;//9
GOTO getinterface; //A
GOTO setinterface; //B//
//
//
#include spidef
#include spi
//var TGL0PID: Bit;
// EP0 DATA0/1 pid
var MLTIPKT: Bit; // Multi Packet
var stall0: Bit; // Stall_0
var stall1: Bit; // Stall_1var i,j,dat: byte;
var desc_siz: byte;
var me: byte;
var desc_idx: byte;
var usb_cfg: byte;var tmp: Byte @dat;
6; // Temp Bit#include
var T: Bit @sreg.
#include usbfun
procedure getdescriptor;
begin
dat := usb_buf3;
desc_siz = 0;
switch dat
DEVICE:
desc_siz = 18;
desc_idx = addr DEV_DESC;
break;
CONFIGURATION:
desc_siz = 9+9+7;
desc_idx = addr CONF_DESC;
break;
default:break;
// more than asked
end;
dat := usb_buf6;
if datthen //
desc_siz := dat
end
MLTIPKT := 1;
mlti8;
end;procedure setaddress;
0;
begin
desc_siz :=
dat := usb_buf2 or AD_EN;
write_usb(EPC0,DEF);
write_usb(FAR,dat);
end;procedure setconfiguration;
// Enable Disable
begin
usb_cfg := usb_buf2;
end;procedure getconfiguration;
begin
write_usb(TXD0,usb_cfg);
end;procedure getstatus;
0;
begin
T :=
dat := usb_buf and 3;
// Endpoint
if dat = 2 then
dat = usb_buf4 and $0F
if dat = 0 then
T := stall0;
end;
if dat = 1 then
T := stall1;
end;
end
EPSTATUS(T);
write_usb(TXD0,0);
end;procedure setfeature;
3;
begin
dat := usb_buf and
// Endpoint
if dat = 2 then
dat = usb_buf4 and $0F
if dat = 0 then
stall0 := 1;
end;
if dat = 1 then
stall1 := 1;
SETSTALL(EPC1,stall1);
end;
end
end;procedure clearfeature;
3;
begin
dat := usb_buf and
// Endpoint
if dat = 2 then
dat = usb_buf4 and $0F
if dat = 0 then
stall0 := 0;
SETSTALL(EPC0,stall0);
end;
if dat = 1 then
stall1 := 0;
SETSTALL(EPC1,stall1);
end;
end
end;setdescriptor:
getinterface:
setinterface:err_reqtype:
// stall EP0!
stall0 := 1;
SETSTALL(EPC0,stall0);
returnprocedure usb_int; interrupt;
// Read Main Event Register
begin
me := read_usb(MAEV);
// RX Event?
if me.6 then
dat := read_usb(RXEV);
// EP 0?
if dat.0 then
j := read_usb(RXS0);
if !j.6 then
// Zero Length SETUP!
j := read_usb(RXS0);
end
// SETUP Packet
if j.6 then
j := j and $0F
if j > 0 then
Z := addr usb_buf;
repeat
dat := read_usb(RXD0);
RAM[Z++] := dat;
until --j=0;
// Clear Stall
SETSTALL(EPC0,0);
flushrx0; flushtx0;
dat := usb_buf and $60;
// standard Request?
if dat = 0 then
Z.lo := usb_buf1;
// request type
if Z.lo > $0B then err_reqtype
// Calc Address
Z.lo := Z.lo + addr req_jumps;
GOSUB ROM[Z];
bad_req:
end
end
// all setup packets
TGL0PID := 1;
TXEN0_PID;
else
// OUT Packet ???
MLTIPKT := 0;
flushtx0;
write_usb(RXC0,RX_EN);
end
else
// ?
j := read_usb(RXS0);
end
goto eoi
end
// TX Event
if me.2 then
dat := read_usb(TXEV);
if dat.0 then
dat := read_usb(TXS0);
if dat.5 then
flushtx0;
if dat.6 then
// TX_DONE and TX_ACK
if MLTIPKT then
if desc_siz > 0 then
mlti8;
TXEN0_PID;
else
write_usb(RXC0,RX_EN);
end
else
write_usb(RXC0,RX_EN);
end
else
// Transmit complete but no ACK
MLTIPKT := 0;
write_usb(RXC0,RX_EN);
end
else
// Transmit didnt complete
end
else
// not EP0
end;
goto eoi
end
// Alternate Event
if me.1 then
dat := read_usb(ALTEV);
if dat.6 then
desc_siz := 0;
write_usb(NFSR,0); // Reset
write_usb(FAR,AD_EN+0);
write_usb(EPC0,0);
flushtx0;
//
// we must be in RESET for >= 100uS
//
write_usb(RXC0,RX_EN);
write_usb(NFSR,OPR_ST); // Operational state
goto eoi
end
if dat.4 then
write_usb(ALTMSK,RESET_A+RESUME_A);
write_usb(NFSR,SUS_ST); // Operational state
end
if dat.7 then
write_usb(ALTMSK,RESET_A+SD3);
write_usb(NFSR,OPR_ST); // Operational state
end
goto eoi
end
// NAK Event
if me.4 then
dat := read_usb(NAKEV);
if dat.4 then
if MLTIPKT then
MLTIPKT := 0;
flushtx0;
write_usb(RXC0,RX_EN);
end
end
endeoi:
end;Begin
// Init USB
cpu.OnInt0 := @ usb_int;
usb_cfg := 0;
RAM[addr stall0] := 0; // Clear bit flags (all)write_usb(MCNTRL,SRST);
// Soft reset.
write_usb(MCNTRL,VGE); //
flushrx0; flushtx0; // ?
write_usb(FAR,AD_EN); // Address enable
write_usb(EPC0,0); //
write_usb(MAMSK,INTR_E+RX_EV+NAK+TX_EV+ALT);
write_usb(RXMSK, $0B); // FIFO_0
write_usb(ALTMSK,RESET_A+SD3);
write_usb(TXMSK, $0B); // FIFO_0
write_usb(NAKMSK,NAK_O0); // FIFO_0
write_usb(RXC0,RX_EN); //
write_usb(NFSR,OPR_ST); // Operational state
write_usb(MCNTRL,INT_L_P+VGE+NAT); // Node operatioanl+VGE
// Enable AVR INT0
GIMSK := $40; CPU.Interrupt.Enabled := True;
End.
E-mail: info@telesys.ru