'**************************************************************** '* Name : usb765.bas * '* Author : Ranjit Diol * '* Notice : Copyright (c) 2003 * '* : All Rights Reserved * '* Date : 2/08/03 * '* Version : 1.0.6 * '* Notes : Compiler PBP Ver 2.43 * '* : * ' This USB sample program implements the functionality of the Jan Axelson ' demo which accepts two numbers from the host, increments each and sends ' them back. An application running on the host sends the numbers and ' displays the returned values. '**************** NOT FOR COMMERCIAL USE ******************** ' DISCLAIMER: This file is being released as non-commericial ' software. It is being provided "AS IS", neither the author, ' nor COMPSys shall be held liable for any implicit or explicit ' damages, or harm caused by its use. ' ************************************************************* 'System variables used wsave var byte $70 system ssave var byte bank0 system psave var byte bank0 system fsave var byte bank0 system 'Program variables buffer var byte[8] cnt var byte rnd var word idx var byte num var byte chr var byte portval var byte savetris var byte LED var PORTC.0 'System Led adval1 var byte 'ADC values adval2 var byte adval3 var byte adval4 var byte adval5 var byte adval6 var byte lcdcnt var byte lcdchr var byte lcdlen var byte x var byte y var byte j var byte k var byte ln var byte tmp1 var byte 'Program constants LCDWIDTH con 20 LCDLINES con 4 low LED 'Constants Define OSC 24 'Set LCD Data port DEFINE LCD_DREG PORTB 'Set starting Data bit (0 or 4) if 4-bit bus 'DEFINE LCD_DBIT 4 'Set LCD Register Select port DEFINE LCD_RSREG PORTE 'Set LCD Register Select bit DEFINE LCD_RSBIT 2 'Set LCD Enable port DEFINE LCD_EREG PORTE 'Set LCD Enable bit DEFINE LCD_EBIT 0 'LCD RW Register PORT DEFINE LCD_RWREG PORTE 'LCD read/write pin bit DEFINE LCD_RWBIT 1 'Set LCD bus size (4 or 8 bits) DEFINE LCD_BITS 8 'Set number of lines on LCD DEFINE LCD_LINES 4 'Set command delay time in us DEFINE LCD_COMMANDUS 2000 'Set data delay time in us DEFINE LCD_DATAUS 50 'ADC parameters DEFINE ADC_BITS 8 'Number of bits in ADCIN result DEFINE ADC_CLOCK 3 'ADC clock source (rc = 3) DEFINE ADC_SAMPLEUS 50 'ADC sampling time in microseconds Goto start ' Skip around interrupt handler ' Define interrupt handler define INTHAND usbint ' Assembly language interrupt handler asm ; W, STATUS and PCLATH registers already saved, save FSR usbint movf FSR, W movwf fsave ; Check interrupt source and vector there movlw high ServiceUSBInt movwf PCLATH btfsc PIR1, USBIF call ServiceUSBInt ; Restore saved registers clrf STATUS movf fsave, W movwf FSR movf psave, W movwf PCLATH swapf ssave, W movwf STATUS swapf wsave, F swapf wsave, W retfie ; Return from interrupt endasm '**** SUBROUTINES ******* ' Message received. Increment the bytes and send them back. sendbuff: USBOut 1, buffer, 8, sendbuff ' Send the bytes back return getbuff: USBIn 1, buffer,cnt,getbuff return SetAdc: TRISA = %11111111 ' Set PORTA to all input ADCON1 = %00000010 ' Set PORTA analog and right justify result return ReadA: ADCON1 = 7 'Make PortA digital portval = PORTA 'Read the port ADCON1 = %00000010 'Set PORTA analog and right justify result return ReadB: savetris = TRISB TRISB = %11111111 portval = PORTB TRISB = savetris return SetPortB: TRISB = %00000000 PORTB = portval return ReadC: savetris = TRISC TRISC = %11111111 portval = PORTC TRISC = savetris return SetPortC: TRISC = %00000000 PORTC = portval return ReadD: savetris = TRISD TRISD = %11111111 portval = PORTD TRISD = savetris return SetPortD: TRISD = %00000000 PORTD = portval return ReadE: savetris = TRISE TRISE = %11111111 portval = PORTE TRISE = savetris return SetPortE: TRISE = %00000000 PORTE = portval return dispval: lookup buffer[1],["A","B","C","D","E"],chr LCDOUT $FE, 1, "Port:",chr,"=",dec buffer[2] return '**** END OF ROUTINES ****** start: cnt = 8 gosub setadc Low LED USBInit ' Init USB and wait till configured High LED ' Turn on LED for USB ready LCDOUT $FE,1, "USB Ready" ' Wait for USB input of 8 numbers. main: USBIn 1, buffer,cnt,main select case buffer[0] case 0 'LCD Routines '$FE, 1 Clear display '$FE, 2 Return home (beginning of first line) '$FE, $C0 Move cursor to beginning of second line '$FE, $94 Move cursor to beginning of third line '$FE, $D4 Move cursor to beginning of fourth line if buffer[1] = 0 then LCDOUT $FE, 1 else for j = 0 to 3 lookup j,[1,$C0,$94,$D4],ln if buffer[2] = j+1 then lcdlen = buffer[3]+1 LCDOUT $FE, ln for k = 4 to 7 LCDOUT buffer[k] next k lcdcnt= 4 'we have written 4 bytes already if lcdcnt < lcdlen then lcd1: gosub getbuff if buffer[0] = 0 then goto done1 for k = 1 to 7 lcdcnt = lcdcnt + 1 if lcdcnt = lcdlen then goto done1 LCDOUT buffer[k] next k goto lcd1 done1: endif endif next j endif case 1 'Read a port if buffer[1] = 0 then gosub ReadA endif if buffer[1] = 1 then gosub ReadB endif if buffer[1] = 2 then gosub ReadC endif if buffer[1] = 3 then gosub ReadD endif if buffer[1] = 4 then gosub ReadE endif buffer[2] = portval if buffer[3] = 1 then gosub dispval case 2 'Write to a port if buffer[1] = 1 then portval = buffer[2] gosub SetPortB gosub ReadB endif if buffer[1] = 2 then portval = buffer[2] gosub SetPortC gosub ReadC endif if buffer[1] = 3 then portval = buffer[2] gosub SetPortD gosub ReadD endif if buffer[1] = 4 then portval = buffer[2] gosub SetPortE gosub ReadE endif buffer[2] = portval if buffer[3] = 1 then gosub dispval case 3 'Read and send ADC values ADCIN 0, adval1 pause 50 ADCIN 1, adval2 pause 50 ADCIN 2, adval3 pause 50 ADCIN 3, adval4 pause 50 ADCIN 4, adval5 pause 50 buffer(0) = 1 buffer(1) = adval1 buffer(2) = adval2 buffer(3) = adval3 buffer(4) = adval4 buffer(5) = adval5 buffer(6) = 0 buffer(7) = 0 case 4 for idx = 0 to 6 lookup idx,["ACTIVE!"],chr buffer[idx+1] = chr next idx case else LCDOUT $FE,$C0, "Waiting" end select gosub sendbuff Goto main ' Wait for next buffer end