  '
  '  MyUSB
  '  =====
  '
  '  File name : MyUSB.pbp
  '  Programmer: Abdykerim Mamedov
  '  Date      : July 2, 2007
  '  Device    : PIC 18F2455 & 4MHZ crystal
  '
  '
  '  Supposed to send and read from USB bus.
  '
  '  Hardware:
  '  ---------
  ' Signal genarator (Sinusoidal,triangular or square wave)
  ' USB cable
  ' 4 MHZ crystal
  '
  '
  '  Software: 
  '  ---------  
  '   The PC interface is not ready yet, but supposed to be VB6 source code
  '
  '
  '   Pic Configuration Fuses
  '   =======================
   asm
   __CONFIG    _CONFIG1L, _PLLDIV_1_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L  
                            ;              ;                      ; USB clock source comes from the 96 MHz PLL divided by 2
                            ;              ; [OSC1/OSC2 Src: /1][96 MHz PLL Src: /2]
                            ; No prescale (4 MHz oscillator input drives PLL directly)


   __CONFIG    _CONFIG1H, _FOSC_XTPLL_XT_1H & _FCMEN_OFF_1H & _IESO_OFF_1H 
                            ;                  ;               ; Oscillator Switchover mode disabled
                            ;                  ; Fail-Safe Clock Monitor disabled
                            ; XT oscillator, PLL enabled, XT used by USB
                            
   __CONFIG    _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L  & _BORV_2_2L  & _VREGEN_ON_2L   
   __CONFIG    _CONFIG2H, _WDT_OFF_2H 
   __CONFIG    _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_ON_3H 
   __CONFIG    _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L 
   endasm
   
  DEFINE OSC 48          
    
  '
  '    Hardware configuration
  '    ======================
       '
       '  I/O and PORTs
       '  -------------
   TRISA.0 = 1             ' Set pin 0 of PORTA an input
                       
   TRISA.1 = 0             ' Set pin 1 of PORTA an output
       '
       '   A/D converter
       '  -------------    
   ADCON0 = %00000001      ' Configuring Analog Channel Select bits ,
                           ' A/D Conversion Status bit, A/D On bit
   ADCON1 = %00001101      ' Configuring Voltage Reference Configuration bits,
                           ' (AN0 analog, others digital), A/D Port Configuration Control bits
   ADCON2 = %10001000      ' Configuring A/D Result Format Select bit (Right justified ), 
                           ' A/D Acquisition Time Select bits (4 TAD),  
                           ' A/D Conversion Clock Select bits (Fosc/64) 
       '
       '   USB module
       '   ----------
  UCFG    var byte EXT        ' include UCFG register... Yeah Melabs didn't 
  ucfg    =   %00010100       ' enable internal USB pull-up, Full speed USB

  '
  '   Interrupt definition
  '   ====================
       '   TMR0 interrupt used to keep USB connection alive
       '   by sending USBSERVICE at each 100uSec or so.
  INTCON  =   %10100000       ' Enable global and TMR0 interrupts
  T0CON   =   %10000000       ' TMR0, CLK internal, prescaler 1:2, T0ON
  
  '
  '   Variables & constants definition 
  '   ================================
  USBBufferSizeTX     con 8       ' input 
  USBBufferSizeRX     con 8       ' output
  USBBufferCount      Var Byte    '
  USBBufferIn         var byte[8] ' store incomming USB data
  USBBufferOut        Var Byte[8] ' store outgoing USB data 
  DataToSend          var byte    ' store ADCs
  
  @ADRead = ADRESL                 ; use to read both ADCs register in one shot
  ADRead              VAR WORD EXT ' make it available to use in PBP
 
  @Duty1=_USBBufferIn+1            ; use to read both Duty bytes from specifics
  @Duty2=_USBBufferIn+3            ;     USBBufferIn locations in one shot
  Duty1               var word EXT ' make them available 
  Duty2               var word EXT '     to use in PBP

  '   
  '   Constants definition 
  '   ====================
  TMR0IF              VAR INTCON.2 ' TMR0 overflow int flag
  TMR0ON              VAR T0CON.7  ' TMR0 on/off bit
  TMR0IE              VAR INTCON.5 ' TMR0 interrupt enable/disable bit
  GoDone              var ADCON0.1 ' ADC conversion

  
  '
  '   Macro(s) definition
  '   ===================
  goto SwHwInit           ' skip macros        
  asm 
Reload_TMR0 macro
  ;   Use to stop, reload, clear overflow flag and restart TMR0
  BCF     _TMR0ON         ; stop timer
  MOVE?CW d'65000',TMR0L  ; reload for timebase ~100uSec
  BCF     _TMR0IF         ; clear overflow flag
  BSF     _TMR0ON         ; start timer
  ENDM

SendUSB macro array
  ;   Use to Copy an specific array to USBBufferOut AND send it
  ;   to USB bus
  variable i=0
  while i<8
     MOVE?BB (array+i),(_USBBufferOut+i)
i+=1
  endw
  L?CALL _DoUSBOut
  endm
  endasm

  '   
  '   Software/Hardware initialisation
  '   ================================
SwHwInit:
  pause 500               ' Settle delay
  usbinit                 ' initialise USB 
@ Reload_TMR0             ; Reload timer0
  ON INTERRUPT GOTO DoUSBService
  '
  '   Main program start
  '   ==================
Start: 
  '   
  '   
  '   Do ADC conversion and save it to specific DataToSend array     
  '   ---------------------------------------------------------- 
  PAUSEUS 125                         ' arbitrary SamplingTime
  GODONE=1                            ' start conversion
  WHILE GODONE : WEND                 ' wait 'till finish
  DATATOSEND = ADREAD                 ' save it to DataToSend array
   
  '   Send data to USB bus
  '   --------------------
@ SendUSB _DataToSend 
  '
  '   Check if there's any incomming data
  '   -----------------------------------
  gosub dousbin
  '
  '   Redo from start
  '   ---------------    
  goto start                                     
    '
    '
    '                           Subroutines area
    '                           ================        
    '
DoUSBIn:
    '
    '   Check and receive data from the USB bus                            
    '   =======================================
    tmr0ie = 0                                      ' disbale TMR0 int
    USBBufferCount = USBBufferSizeRX                ' RX buffer size
    USBService                                      ' keep connection alive
    USBIn 1, USBBufferin, USBBufferCount, Timeout   ' read data, if available
Timeout:                                            '
@   Reload_TMR0            
    tmr0ie = 1              ' re-enable TMR0 int
    PORTB  = USBBUFFERIN[0] ' output to PORTB
    return
    '
    '
    '
DoUSBOut:
    '
    '   Send data to the USB bus & Wait for USB interface to attach                         
    '   ===========================================================
    TMR0IE = 0                                      ' Disable TMR0 interrupt
    WaitPC:                                         '
    USBBufferCount = USBBufferSizeTX                ' TX buffer size
    USBService                                      ' keep connection alive
    USBOut 1, USBBufferOut, USBBufferCount, Waitpc  ' if bus available, transmit data
@   Reload_TMR0                                     
    tmr0ie=1                                        ' Re-Enable TMR0 interrupt    
    return

DISABLE
DoUSBService:
    usbservice  ' keep connection alive
@   Reload_TMR0 ; reload timer
    RESUME      ' getout of here
ENABLE    


    

    
     

  
      
       
    
   
            

  
             
   


   
