.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 <sys\regs16>
#include <usb\defusb>
//
// 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_1 

var i,j,dat: byte;
var desc_siz: byte;
var me: byte;
var desc_idx: byte;
var usb_cfg: byte;

var tmp: Byte @dat;
var T: Bit @sreg.6;   // Temp Bit

#include <ns\usbn9602>
#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;
  end;
  dat := usb_buf6;
  // more than asked             
  if dat<desc_siz then
    desc_siz := dat
  end
  //
  MLTIPKT := 1;
  mlti8; 
end;

procedure setaddress;
begin
  desc_siz := 0;              
  dat := usb_buf2 or AD_EN;
  write_usb(EPC0,DEF);
  write_usb(FAR,dat);
end;

procedure setconfiguration;
begin
  usb_cfg := usb_buf2;
  // Enable Disable
  
end;

procedure getconfiguration;
begin
  write_usb(TXD0,usb_cfg);
end;

procedure getstatus;
begin
  T := 0;
  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;
begin
  dat := usb_buf and 3;
  // 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;
begin
  dat := usb_buf and 3;
  // 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);
  return

procedure usb_int; interrupt;
begin
    // Read Main Event Register
    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
    end

eoi:
end;

Begin
  cpu.OnInt0 := @ usb_int;
  // Init USB
  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.

Перейти: /Главная/ CBuild/ JavaScript 1.2-5.6/ Delifi6/ I2C контроллеры/ AVR контроллеры/ ПЛИС/ AHDL/ VHDL/
LPT EPP/ LPT ECP/ PCI/ COM port/ I2C/ RS-232/
Рейтинг@Mail.ru Rambler's Top100 Rambler's Top100 Rambler's Top100    
Используются технологии uCoz