; ; standalong data logger ; ; SL003.ASM - Simple Logic analyser hack. ; ; FOR PIC 16F88 18 PIN DEVICE - with internal AtoD converters. ; ; Doug Rice 24/08/2008 ; ; Output at 4800 baud with added stop bits. ; ; It took 3 monutes 30 seconds to upload 32K 24LC256 chip using the HEX format. ; ; TX D9 Pin 3 -[4k7]----+----- PB0 - check which pin is used. see EQU for each chip. ; RX D9 Pin 2 ----------/ ; ; GND D9 Pin 5 ---------------- 0V ; ; commands: ; r - rAA read AA ; w - wAADD write DD to AA ; g - gAA get fromm EEPROM address A ; p - p AADD put DD to EEPROM ; l - lAADD trigger mask , delay ; L - LAADD trigger , writes TMR0 values into buffer. ; ; w8140 - clocks Fosc/4 /2 ; w8141 - clocks Fosc/4 /4 ; w8142 - clocks Fosc/4 /8 ; w8143 - clocks Fosc/4 /16 **** set to this on reset ; w8144 - clocks Fosc/4 /32 ; w8145 - clocks Fosc/4 /64 ; w8146 - clocks Fosc/4 /128 ; w8147 - clocks Fosc/4 /256 ; ; ;* - ;w8144;* - ;L04; ;A0 DC 00 ;A1 E9 0D +32*13us = 416 us ;A2 01 18 +32*24us = 768 us ;A3 0E 0D +32*13us = 416 us ;A4 39 2B +32*43us =1376 us ;A5 47 0E ;A6 5E 17 ; ; ; EEPROM ; 00 - bit mask to cause carry. 0xF8 for 24LF16, 0xE0 for 24LC64 ; 02 - sample ticks 50 ms interval. For 1 second set to 1A, for 10 seconds set to c8. ; ; Example of output: ; ; ;-------------------------------------------------------------------------- ; Sec 0. #Defines tofor different chips ;-------------------------------------------------------------------------- ; uncomment only one of these ; #define pic16F84 1 ;#define pic16F819 1 #define pic16F88 1 ; Configure for different size EEPROM ;MEM24LC16 EQU 1 ;MEM24LC65 EQU 1 MEM24LC256 EQU 1 debug equ 1 ;-------------------------------------------------------------------------- ; Sec 0. #Defines to select code ;-------------------------------------------------------------------------- ;#define oldRSR232 1 ;-------------------------------------------------------------------------- ; Sec 0.1 #Defines for 16F84 ;-------------------------------------------------------------------------- ifdef pic16F84 LIST C=132 ; COLUMN WIDTH FOR PRINTING LIST P=16F84, R=DEC INCLUDE "p16F84.inc" __idlocs 0x0084 __config _XT_OSC & _PWRTE_ON & _WDT_OFF cblock 0x0c endc ;PORTA PORT_RS232 EQU PORTA TRIS_RS232 EQU TRISA RS232tx EQU 0 ; Serial Out RS232rx EQU 0 ; Serial In needs to be equal to BUTTON_RS232 PORTLED EQU PORTB PORTEEPROM EQU PORTB TRISEEPROM EQU TRISB ;PORTB PB0 EQU 0 ; Pull LEDoutput EQU 2 ; LED Output EEPROMscl EQU 3 ; eeprom scl EEPROMsda EQU 4 ; eeprom sda ADdout EQU 5 ; A/D Dout ADclk EQU 6 ; A/D clk AD_cs EQU 7 ; A/D -cs endif ;-------------------------------------------------------------------------- ; Sec 0.1 #Defines for 16F819 ;-------------------------------------------------------------------------- ; ; There is no AtoD configuration the allows a digital PA0 for the rs232 ; Logger hardware would need re wiring. ; ;-------------------------------------------------------------------------- ; Sec 0.1 #Defines for 16F88 ;-------------------------------------------------------------------------- ifdef pic16F88 LIST P=16F88, R=DEC INCLUDE "p16F88.inc" __idlocs 0x0088 ; __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;#define wantAtoD 1 cblock 0x20 endc T0IF EQU TMR0IF ;PORTA PORT_RS232 EQU PORTB TRIS_RS232 EQU TRISB RS232tx EQU 0 ; Serial Out RS232rx EQU 0 ; Serial In needs to be equal to BUTTON_RS232 PORTLED EQU PORTB PORTEEPROM EQU PORTB TRISEEPROM EQU TRISB ;PORTB PB0 EQU 0 ; Pull LEDoutput EQU 2 ; LED Output EEPROMscl EQU 3 ; eeprom scl EEPROMsda EQU 4 ; eeprom sda ADdout EQU 5 ; A/D Dout ADclk EQU 6 ; A/D clk AD_cs EQU 7 ; A/D -cs endif ;-------------------------------------------------------------------------- ; Sec 0.2 Constants ;-------------------------------------------------------------------------- BIT0 EQU 0 BIT1 EQU 1 BIT2 EQU 2 BIT3 EQU 3 BIT4 EQU 4 BIT5 EQU 5 BIT6 EQU 6 BIT7 EQU 7 ; *********** I/O EQUATES ************** ;PORTA EQU 5 ; 5 BITS ;PA0 EQU 0 ; Serial Out, Serial In ;PA1 EQU 1 ; ;PA2 EQU 2 ; RC1 output ;PA3 EQU 3 ; RC2 Output ;PA4 EQU 4 ; RC measure ;PORTB EQU 6 ;PB0 EQU 0 ;PB1 EQU 1 ;PB2 EQU 2 ; LED Output - Flashes during error ;PB3 EQU 3 ; eeprom scl ;PB4 EQU 4 ; eeprom sda ;PB5 EQU 5 ; A/D Dout ;PB6 EQU 6 ; A/D clk ;PB7 EQU 7 ; A/D -cs ;-------------------------------------------------------------------------- ; Sec 0.2 PIC's EEPROM constants ;-------------------------------------------------------------------------- EE_MAX_WRTH EQU 0 EE_SAMPLERATEH EQU 1 EE_SAMPLERATEL EQU 2 ;-------------------------------------------------------------------------- ; Sec 1.1 Button and LED ;-------------------------------------------------------------------------- BUTTON_RS232 EQU RS232rx BUTTON_DOWN EQU 0 ; PORTB ; DoTimeSlice bits ; these bits are set to schedule a timer chain event DTsS4event EQU 0 ; RUN_BUFF EQU 0 ; ; IPtrigMenu DTSFast EQU 0 ; ************ MEMORY EQUATES **************** ; cblock 0x20 cblock ;iic Address to set iic to at start of write and start of read ;ADDRH ; use bit 7 as a flag to indicate end. ;ADDRL DDATA ; data byte and iic DDATAH DDATAL IICwrtPtrH ; IIC memory address incremented by writes IICwrtPtrL ; IICrdPtrH ; IIC memory address incremented by writes IICrdPtrL ; IICprtTest TRAM ; used to transmit byte to IIC memory DELL DELH LoopCnt w_temp status_temp LoopCnt2 TXCHARTMP ;ACKFLAG ; bit 0 = ACK / NACK DoTimeSlice ; if bit 7 set then do not do samples CLcntH CLcnt IPnew IPlast IPbuttonEvent IPnewFast IPlastFast IPbuttonEventUp IPtrigMenu ; ********************************************** ; variables used by Serial input and output routines RStxTemp RSloopCnt RSdelayCnt RSin RSout RSinterCharDelay RSafterCRCharDelay ; Serial input buffer RSipBuffCnt ; input buffer counter ; start of buffer RScmd RSAa ; RSaA ; RSDd ; RSdD ; RSterminator ; end of buffer ; temporary variables RSaddr RSdata LAsampleMSB ; RC5 read LAsampleLSB LAnewTMR0 ; portA LAlastTMR0 ; portA LAminTime LAlast ; portA LAnew ; LAtrigger ; mask LAdelayCnt LAtmp LAptr LAbitCount endc ; ; LA buffer in 0xA0 to 0xFF ; ; cblock 0xA0 LAbuff endc cblock 0xff LAbuffEnd endc ORG 0x00 GOTO Start ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register BCF INTCON,RBIF ; isr code can go here or be located as a call subroutine elsewhere retfie ; return from interrupt ;-------------------------------------------------------------------------- ; Sec 4.2 Main Program Init Code ;-------------------------------------------------------------------------- ; ; Logic Analyser ; ; wait trigger; ; sample ; write samples ; goto wait trigger ; Start movlw 0x0A movwf RSdata movlw 0x04 movwf LAtrigger banksel OPTION_REG MOVLW 1<< INTEDG | 0 << NOT_RBPU | 0 << T0CS | 0 << PSA + 0x03 ; T0CS + For Tmr0 0=/2, 1=/4, 2=/8,3=/16 MOVWF OPTION_REG banksel ANSEL CLRF ANSEL banksel PORTA ; call LAiir movlw 0x20 movwf LAminTime debug1 call LAstartTog goto debug1 CALL RS232sendCR CALL RS232sendLF MOVlw 'L' CALL RS232sendWByte MOVlw 'A' CALL RS232sendWByte CALL RS232sendSpace CALL RS232sendCR CALL RS232sendLF banksel PORTA ; ; Set up ports ; MOVLW 1< min ; start timer ; timeLastToggle = now ; sample ; ; ; Another way ; wait for 0 to 1 ; start timer ; on timeout ; sample ; ; wait for 0 to 1 ; start timer ; on timeout ; sample ; ; ; wait for toggle ; start timer ; on timeout ; sample ; ; Another way ; await Toggle ; if Toggle LAinitTimer banksel OPTION_REG movlw 1<< INTEDG | 0 << NOT_RBPU | 0 << T0CS | 0 << PSA + 0x03 ; T0CS + For Tmr0 0=/2, 1=/4, 2=/8,3=/16 movwf OPTION_REG return LAnextBit ; start timer ; on timeout sample ; wait for edge ; loop movlw .55 banksel TMR0 movwf TMR0 bcf INTCON,TMR0IF LAawaitTimeout ; flush edge detect movfw LAnew movwf LAlast movfw PORTA movwf LAnew btfss INTCON,TMR0IF goto LAawaitTimeout ; sample movwf LAnew andwf LAtrigger,w addlw 0xff rlf LAsampleLSB rlf LAsampleMSB return LAawaitToggle ; look for a change on PORTA masked by Addr ; returns non zero movfw LAnew movwf LAlast movfw PORTA movwf LAnew xorwf LAlast,w andwf LAtrigger,w bz LAawaitToggle ; edge found return ; LAiir call LAinitTimer banksel PORTA movfw LAnew movwf LAlast movfw PORTA movwf LAnew call LAawaitToggle call LAnextBit call LAawaitToggle call LAnextBit call LAawaitToggle call LAnextBit call LAawaitToggle call LAnextBit call LAawaitToggle call LAnextBit call LAawaitToggle call LAnextBit call LAawaitToggle call LAnextBit call LAawaitToggle call LAnextBit return ; ___---|___---|___---|---___|___--- ; ; |--->| |--->| |---> |--->| ; ; Init ; ; ; ; ; On Toggle ; measure time from last toggle ; ; if timed out ; using TMR0IF ; start timer ; sample ; ; ; if timed out ; ( now - timeLastToggle ) > min ; start timer ; timeLastToggle = now ; sample ; LAstartTog ; look for a change on PORTA masked by Addr movfw LAnew movwf LAlast movfw PORTA movwf LAnew xorwf LAlast,w andwf LAtrigger,w ; trigger happened skpnz return ; on toggle code ; test if init state or sampling state ; if init state LAbitCnt = 0 movfw LAbitCount bnz LAstartTogLookForTimeout ; ------_______-_-_ ; init if first bit is rising edge ___---- movfw LAnew andwf LAtrigger,w skpz return ; clrf LAsampleLSB clrf LAsampleMSB movlw .14 movwf LAbitCount LAstartTogLookForTimeout ; ; This correctly differences new - old sample ; movfw TMR0 movwf LAnewTMR0 ; portA ; Look for timeout. ; ; calc ( LAlastTMR0 - LAnewTMR0 + LAminTime ) which should be < 0 when timed out ; subwf LAlastTMR0,w ; SUB LAtmp from LAlastTMR0 addwf LAminTime,w skpnc return ; ; timed out - sample ; movfw LAnewTMR0 movwf LAlastTMR0 ; sample input movfw LAnew andwf LAtrigger,w addlw 0xFF rlf LAsampleLSB,f rlf LAsampleMSB,f decfsz LAbitCount,f return goto LAdisp LAdisp movfw LAsampleMSB call SRwrtWasHex movfw LAsampleLSB call SRwrtWasHex call RS232sendSpace call RS232sendCR call RS232sendLF clrf LAsampleLSB clrf LAsampleMSB return ; LA_testBit ; look for a change on PORTA masked by Addr movfw LAnew movwf LAlast movfw PORTA movwf LAnew xorwf LAlast,w andwf LAtrigger,w ; trigger happened skpnz return ; onToggle btfss INTCON,TMR0IF return ;timedout ;start TMR0 movlw 0x001 movwf TMR0 ;clrf TMR0 bcf INTCON,TMR0IF ;sample Input movwf PORTA andwf LAtrigger,w addlw 0xFF rlf LAsampleLSB rlf LAsampleMSB return ;************************************************* ; This routine transmits out the DDATA on the RS232 port ; SRwrtWasHex ; ; Write W reg as HEX to RS232 ; MOVWF TXCHARTMP SWAPF TXCHARTMP,W CALL SRwrtHexNibble MOVFW TXCHARTMP GOTO SRwrtHexNibble SRwrtHexNibble ; currently only displays 0..9, A..F ANDLW 0x0F ADDLW 0x06 ; is it A..F, if so trigger a digit overflow SKPNDC ADDLW 7; subtract 10, then add 'A'-'0' ADDLW 0x30-6 ; Subtract extra 6 added to cause DC GOTO RS232sendWByte RS232sendCR MOVLW 0x0D GOTO RS232sendWByte RS232sendLF MOVLW 0x0A GOTO RS232sendWByte RS232sendSpace MOVLW ' ' GOTO RS232sendWByte ifdef oldRSR232 RS232sendWByte MOVWF TXCHAR ;RS232sendByte movlw 8 movwf LoopCnt ; send startbit - note sense of bit is inverted ; so send RS232 High by applying low. ; BCF PORTA,RS232tx BSF PORTA,RS232tx CALL Delay5 RS232sendByte0 ; Test the least significant bit ; BTFSS TXCHAR,BIT0 BTFSC TXCHAR,BIT0 GOTO H1 BSF PORTA,RS232tx GOTO H2 H1 BCF PORTA,RS232tx H2 CALL Delay5 RRF TXCHAR,f NOP DECFSZ LoopCnt,f goto RS232sendByte0 ; send the stop bit - a High RS232 ; BSF PORTA,RS232tx BCF PORTA,RS232tx CALL Delay5 CALL Delay5 CALL Delay5 CALL Delay5 CALL Delay5 CALL Delay5 CALL Delay5 CALL Delay5 CALL Delay5 RETURN endif ;*************** L_delay1min MOVLW 0x1A MOVWF DELL BSF STATUS,RP0 MOVLW 0xFF MOVWF OPTION_REG BCF STATUS,RP0 L21 SLEEP BTFSC PORTA,RS232rx GOTO MAIN DECFSZ DELL,f GOTO L21 GOTO L4 ;*************** ; Delay for one hour using the watch dog timer and perscaler L_delay1hour CLRF DELL CLRF DELH BSF STATUS,RP0 MOVLW 0xFF MOVWF OPTION_REG BCF STATUS,RP0 L31 SLEEP BTFSC PORTA,RS232rx GOTO MAIN INCFSZ DELL,f GOTO L32 INCF DELH,f L32 MOVLW 0x1D SUBWF DELL,f BTFSC STATUS,Z GOTO L31 MOVLW 0x6 SUBWF DELH,f BTFSS STATUS,Z GOTO L31 BSF STATUS,RP0 MOVLW 0xFD SUBWF OPTION_REG,f BCF STATUS,RP0 SLEEP BTFSC PORTA,RS232rx GOTO MAIN L4 BSF STATUS,RP0 MOVLW 0xFF MOVWF OPTION_REG CLRWDT BCF STATUS,RP0 RETURN ;************************************************** ; Delay 0x1d * 3 ticks of 4Mhz ~= 87us ; used to space bits for 9600 baud ; ; For 9600 baud, we need: ; ; 1 bit = 104.1666666667 us ; 1.5 bit= 156.25 us ; ; bit to bit = 103 cycles ; ; 1 bit delay = 206us ; ; For a clock rate of 4.014175Mhz for a bit delay of 1 bit = 104.1666666667 us ; 104.5358072248 cycles are needed. ; ; ; for Send Delay to delay = 16/17 cycles ( delay = 12 cycles = 6+3*movlw n) ; for Send Delay to delay = 16/17 cycles ( delay = 12 cycles = 6+3*movlw n) ; 104.5 ; -16.5 ; - 6 ; ====== ; 92 ; - 2 to make divisable by 3 ; ======= ; 90 ; / 3 ; ====== ; 30 or 0x1E Delay5 ; RETURN NOP NOP MOVLW 0x1E DelayOne MOVWF DELL Delay51 DECFSZ DELL,f ; 1 GOTO Delay51 ; 2 clk CLRWDT RETURN ;*************** ; Delay 255 * 3 ticks of 4Mhz ~= 765us Delay7 MOVLW 0xFF GOTO DelayOne ;*************** ; Delay 255 * 3 ticks of 4Mhz ~= 5ms Delay7a MOVLW 0xFF MOVWF DELL Delay71a DECFSZ DELL,f RETURN GOTO $+1 GOTO $+1 GOTO $+1 GOTO $+1 GOTO $+1 GOTO $+1 CLRWDT GOTO Delay71a ;*************** ; Delay 0x36 * 3 ticks of 4Mhz ~= 162us Delay9 MOVLW 0x36 GOTO DelayOne ;*************** ; Delay 255 * 255 * 3 ticks of 4Mhz ~= 0.195075 seconds DelayA MOVLW 0xFF MOVWF DELH DelayA2 MOVLW 0xFF MOVWF DELL CLRWDT DelayA1 DECFSZ DELL,f GOTO DelayA1 DECFSZ DELH,f GOTO DelayA2 CLRWDT RETURN ;*************** ; Delay 255 * 255 * 3 ticks of 4Mhz ~= 0.195075 seconds Delay5ms MOVLW 0x08 MOVWF DELH DelayB2 MOVLW 0x4B MOVWF DELL CLRWDT DelayB1 DECFSZ DELL,f GOTO DelayB1 DECFSZ DELH,f GOTO DelayB1 CLRWDT RETURN ;************************************************* ;-------------------------------------------------------------------------- ; Sec 5.1 Button Poll Routine ;-------------------------------------------------------------------------- IPtimeslice ; --_____ button press ; ----___ ; --_____ IPnew ; ____--- /IPlast ; __--___ ; ; This reads all Port A inputs and looks for Press MOVFW IPnew MOVWF IPlast MOVFW PORTB MOVWF IPnew ; IP last contains new setting, IPlast contains previous ; look for falling edges COMF IPnew,W ANDWF IPlast,W ; now force IPbuttonEvent bits to high for new pressed button ; the service routine should reset the bit to clear the event. IORWF IPbuttonEvent,F RETURN IPtimesliceFast ; Look for falling edges ; --_____ button press ; ----___ ; --_____ IPnew ; ____--- /IPlast ; __--___ ; MOVFW IPnewFast MOVWF IPlastFast MOVFW PORT_RS232 MOVWF IPnewFast COMF IPlastFast,W ANDWF IPnewFast,W IORWF IPbuttonEventUp,F RETURN ;-------------------------------------------------------------------------- ; Sec 5.2 ;-------------------------------------------------------------------------- ;-------------------------------------------------------------------------- ; Sec 5.2 .1 run process on request ;-------------------------------------------------------------------------- DLrunBuff BCF DoTimeSlice,RUN_BUFF MOVFW RSin CALL RSbuffInput return ;-------------------------------------------------------------------------- ; Sec 5.3 Button Input functions ;-------------------------------------------------------------------------- IPdownPressed BCF IPbuttonEvent,BUTTON_DOWN return IPrs232 BCF IPbuttonEventUp,BUTTON_RS232 GOTO RSrs232in ;-------------------------------------------------------------------------- ; Sec 5.4 Clock Chain Routine ;-------------------------------------------------------------------------- CLtimeslice ; banksel INTCON BTFSS INTCON,T0IF RETURN movlw .54 ADDWF TMR0,f ; ; TMR0 timeout BCF INTCON,T0IF ;BSF DoTimeSlice,DTsS4event ; stop sampling when key pressed or memory full BTFSS DoTimeSlice,7 RETURN ; This is called about every 50 ms DECFSZ CLcnt return ; read eeprom 0 movlw EE_SAMPLERATEL call EEread banksel CLcnt MOVWF CLcnt ; sample AtoD untill full RETURN CLdisableAutoSample ; disable time sample. reaneable by clearing BCF DoTimeSlice,7 return CLenableAutoSample BSF DoTimeSlice,7 return ;-------------------------------------------------------------------------- ; Sec 5.5 Serial Input Routine ;-------------------------------------------------------------------------- RSinit ; zero pointer banksel RSipbuffStart ; reset input buffer MOVLW RSipbuffStart MOVWF RSipBuffCnt CLRF RSin return ;************************************************** ;RS232in RSrs232in ; Test is in main loop or uncomment code below to ; spin for a start bit ; CLRWDT ; BTFSS PORT_RS232,RS232rx ; GOTO RSrs232in ; CALL RSdelayBit ; delay through Stop Bit CALL RSdelayHalfBit ; delay halfway into first bit movlw 8 movwf RSloopCnt RSrs232inL0 CALL RSdelayBit ; delay halfway into first bit MOVFW PORT_RS232 ANDLW 1<< RS232rx ; mask off bit ADDLW -1<< RS232rx ; use ripple carry to move into C RRF RSin,F ; CALL RSdelayBit DECFSZ RSloopCnt,f goto RSrs232inL0 ; do not test for Stop bit COMF RSin,f BSF DoTimeSlice,RUN_BUFF call CLdisableAutoSample RETURN ;-------------------------------------------------------------------------- ; Sec 5.6 Serial Output Routines ;-------------------------------------------------------------------------- RSwrtHexNibble ; currently only displays 0..9, A..F ANDLW 0x0F ADDLW 0x06 ; is it A..F, if so trigger a digit overflow SKPNDC ADDLW 7; subtract 10, then add 'A'-'0' ADDLW 0x30-6 ; Subtract extra 6 added to cause DC MOVWF RSout GOTO RStxChar RS232sendWByte RStxChar ; ; Output Start Bit ; Start bit is low, data bits are inverted ; movwf RStxTemp comf RStxTemp,f BANKSEL PORT_RS232 BCF PORT_RS232,RS232tx ; Make RS232 pin an ouput while transmitting character BANKSEL TRIS_RS232 BCF TRIS_RS232,RS232tx BANKSEL PORT_RS232 ; 1200 baud output ; move the char into RStxtemp, it is destroyed. ; zzz_-xxxxxxxx__ ; ; Do one more stop bit for luck ; ; This was needed on my XP machine ; but has not been needed before. ; ; BCF PORT_RS232,RS232tx call RSdelayBit ;Start Bit BSF PORT_RS232,RS232tx call RSdelayBit movlw 8 movwf RSloopCnt RStxCharLp1 ; After start bit, which is 1, then test each bit ; I need to set PA:0 to same as LSB RStxTemp ; this compares PA:0 with RStxTemp so see if it needs toggling ; The xorwf PORT_RS232,f causes the bit to be toggled if required. RRF RStxTemp,f movfw STATUS andlw 1 << C ; mask off bit addlw ( 1 << RS232tx) -1 ; shift bit by using a ripple carry xorwf PORT_RS232,W ; Doeas output need toggling ? andlw 1 << RS232tx ; Mask off output pin xorwf PORT_RS232,f ; Toggle output pin if needed call RSdelayBit ; delay bit decfsz RSloopCnt,f goto RStxCharLp1 BCF PORT_RS232,RS232tx call RSdelayBit ; apply stop bit ; apply an inter character delay of 4 bits ; call RSdelayBit ; get inter character delay from the EEPROM ; you have to read from RAM, and not EEPROM as pXXXX; does not work as EEwrt needs delay before EEread ; MOVFW RSinterCharDelay movlw 1 RStxCharInterDelay movwf RSloopCnt RStxCharLp2 call RSdelayBit decfsz RSloopCnt,f goto RStxCharLp2 ; Make RS232 pin an input so that main loop can test for start bit BANKSEL TRIS_RS232 BSF TRIS_RS232,RS232tx BANKSEL PORT_RS232 RETURN ; timing functions to delay serial routines for a bit or half bit. RSdelayHalfBit MOVLW 0x1D ; shorten delay as edge detector takes about 22 us for 4800 baud GOTO RSdelayBit0 RSdelayBit NOP MOVLW 0x40 ; for 4800 baud RSdelayBit0 MOVWF RSdelayCnt RSdelayBit1 DECFSZ RSdelayCnt,f ; 1 GOTO RSdelayBit1 ; 2 clk CLRWDT RETURN ;-------------------------------------------------------------------------- ; Sec 5.7 Serial Output Format Routines ;-------------------------------------------------------------------------- RSasciiToNibble MOVWF RSin ; if 0..1 then 0x30 to 0x39 ; if A..F then 0x41 to 0x46 ; if a..f then 0x61 to 0x66 ; test if bit 4 set and assume a letter or number BTFSS RSin,4 ADDLW 0x09 ; letter so add 9 ANDLW 0x0F ; mask of nibble return ;-------------------------------------------------------------------------- ; Sec 5.8 Serial Input Buffer Routine ;-------------------------------------------------------------------------- ; take serial input CAADD and put into buffer ; if char id ; the do command ; if char is CR reset buffer pointer ; if buff end then reset buff pointer RSipbuffStart EQU RScmd RSipbuffEnd EQU RSterminator RSbuffInput MOVWF RSin ; look for line feed and reset buff cnt ADDLW -0x0D BNZ RSbuffInput1 MOVLW RSipbuffStart MOVWF RSipBuffCnt RETURN RSbuffInput1 ; end of line command - do command ADDLW -';'+0x0D BNZ RSbuffInput2 GOTO RSbuffInputProcess RSbuffInput2 ; Store the current time into the next register. MOVFW RSipBuffCnt MOVWF FSR MOVFW RSin MOVWF INDF INCFSZ RSipBuffCnt,f MOVFW RSipBuffCnt ADDLW -(RSipbuffEnd+1) ; Check if the end of memory SKPZ GOTO RSbuffInputEnd1 MOVLW RSipbuffStart MOVWF RSipBuffCnt ; reset cursor MOVLW 0x0D CALL RStxChar RETURN RSbuffInputProcess MOVLW RSipbuffStart MOVWF RSipBuffCnt MOVFW RSAa ; if 0..1 then 0x30 to 0x39 ; if A..F then 0x41 to 0x46 ; if a..f then 0x61 to 0x66 ; test if bit 4 set and assume a letter or number BTFSS RSAa,4 ADDLW 0x09 ; letter so add 9 ANDLW 0x0F ; mask of nibble MOVWF RSin SWAPF RSin,F MOVFW RSaA BTFSS RSaA,4 ADDLW 0x09 ; letter so add 9 ANDLW 0x0F ; mask of nibble ADDWF RSin,w MOVWF RSaddr MOVFW RSDd BTFSS RSDd,4 ADDLW 0x09 ; letter so add 9 ANDLW 0x0F ; mask of nibble MOVWF RSin SWAPF RSin,F MOVFW RSdD BTFSS RSdD,4 ADDLW 0x09 ; letter so add 9 ANDLW 0x0F ; mask of nibble ADDWF RSin,w MOVWF RSdata ; CALL RStxChar ; got to end of buffer so process. does not allow for backspace ; Write to file register MOVLW -'w' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput3 MOVFW RSaddr MOVWF FSR MOVFW RSdata MOVWF INDF GOTO RSbuffInputEndOK RSbuffInput3 ; put octet in EEPROM MOVLW -'p' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput4 BANKSEL RSaddr MOVFW RSaddr CALL EEsetAddr BANKSEL RSdata MOVFW RSdata CALL EEwrt GOTO RSbuffInputEndOK RSbuffInput4 ; read from file register MOVLW -'r' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput5 MOVFW RSaddr MOVWF FSR MOVFW INDF MOVWF RSin RSbuffInput4display MOVLW '=' CALL RStxChar SWAPF RSin,w CALL RSwrtHexNibble MOVFW RSin CALL RSwrtHexNibble GOTO RSbuffInputEnd RSbuffInput5 ; get from EEPROM register MOVLW -'g' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput6 MOVFW RSaddr CALL EEread MOVWF RSin GOTO RSbuffInput4display RSbuffInput6 RSbuffInput10 ; ; start Logic analyser - delta samples ; addr = trigger MASK 1 in bit position enables pin change trigger. ; data = delay MOVLW -'L' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput11 movfw RSaddr call LAstartSampleDelta GOTO RSbuffInputEndOK RSbuffInput11 ; ; start Logic analyser ; addr = trigger MASK 1 in bit position enables pin change trigger. ; data = delay MOVLW -'l' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput12 movfw RSaddr call LAstart GOTO RSbuffInputEndOK RSbuffInput12 MOVLW '?' CALL RStxChar GOTO RSbuffInputEnd RSbuffInputEndOK MOVLW '*' CALL RStxChar RSbuffInputEnd MOVLW ' ' CALL RStxChar RSbuffInputEnd0 MOVLW '-' CALL RStxChar MOVLW 0x0D CALL RStxChar MOVLW 0x0A CALL RStxChar BCF PORTLED,LEDoutput RSbuffInputEnd1 return cblock LASTFILE endc ;-------------------------------------------------------------------------- ; Sec 5.10 EEprom Routines for 16F628 ;-------------------------------------------------------------------------- EEread ; w contains address banksel EEADR MOVWF EEADR banksel EECON1 ifdef EEPGD BCF EECON1, EEPGD; Point to Data memory endif BSF EECON1,RD BANKSEL EEDATA ; Select Bank of EEDATA MOVFW EEDATA banksel 0 RETURN EEsetAddr banksel EEADR MOVWF EEADR RETURN EEwrt ; blocking, EEADR and EEDATA set up. banksel EEDATA MOVWF EEDATA ;BCF PIR1,EEIF banksel EECON1 BCF EECON1,WREN ; disable EROM ifdef EEPGD BCF EECON1, EEPGD ; Point to DATA endif BSF EECON1,WREN BCF INTCON,GIE MOVLW 0x55 MOVWF EECON2 MOVLW 0xAA MOVWF EECON2 BSF EECON1,WR BsF INTCON,GIE ; Now wait for EEwrt to finish write EEwaitForWrt ; block until EEPROM write has finished. BCF EECON1,WREN ; disable EROM ; NOTE:- I have commented out the goto and the write to eeprom started to work ; BTFSC EECON1,WR ; GOTO EEwaitForWrt ;BCF EECON1,EEIF ; EEPROM finished banksel 0 RETURN LastProgWord ;-------------------------------------------------------------------------- ; Sec 7.0 EEPROM data ;-------------------------------------------------------------------------- ORG 0x2100 ; set up a bit map to stop upload. ifdef MEM24LC16 DE 0xF8 ; EE_MAX_WRTH endif ifdef MEM24LC65 DE 0xE0 ; EE_MAX_WRTH endif ifdef MEM24LC256 DE 0x80 ; EE_MAX_WRTH ;DE 0xFF ; EE_MAX_WRTH endif DE .1 ; EE_SAMPLERATEH Sample counts in 50 ms intervals DE .20 ; EE_SAMPLERATEL Sample counts in 50 ms intervals 20 times per second ;DE .20 ; EE_SAMPLERATEL Sample counts in 50 ms intervals 20 times per second ;DE .80 ; EE_SAMPLERATEL Sample counts in 50 ms intervals 20 times per second cblock LastVar endc END