Code:
'****************************************************************
'* Name : rfm12b.BAS *
'* Author : richard *
'* Notice : Copyright (c) 2013 *
'* : All Rights Reserved *
'* Date : 9/4/2013 *
'* Version : 1.0 16f1825 @3.3 volts *
'* Notes : talk to arduino rfm12b lib with encrypt=null *
'* : pkt size up to maxl , will ack also *
'****************************************************************
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _CP_OFF & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CLKOUTEN_OFF
__config _CONFIG2, _PLLEN_ON & _LVP_OFF
#ENDCONFIG
include "dt_ints-14.bas"
Include "REENTERPBP.bas"
asm
INT_LIST macro
INT_HANDLER INT_INT, _RX, PBP ,NO
endm
INT_CREATE
ENDASM
DEFINE OSC 32
SSPIF VAR PIR1.3 ' SPI interrupt flag
ssc var PORTC.3 ;..... rf12b ss
RNINT VAR PORTA.2 ;.... rf12b irqn // int int
;SDI= PORTC.1 .... rf12b sdo
;SDO PORTC.2 .... rf12b sd1
;SCK PORTC.3 .... rf12b ssk
net con 99
node con 2
MAXL CON 34 ;buffer size ie 0 to 34
RXBUFF VAR BYTE[maxl+1]
BCNT VAR BYTE
GRP VAR RXBUFF[0] ;net sync
DEST VAR RXBUFF[1]
SOURCE VAR RXBUFF[2]
LEN VAR RXBUFF[3]
;data rxbuff[4] to rxbuff[maxl-2]
FLG VAR BYTE
RXDONE VAR FLG.7
CMD VAR WORD
crc var word
CRC_IN var byte
i VAR BYTE ' loop counter
j var byte
OSCCON=$70
ANSELA=0
ANSELC=0
OPTION_REG.6=0
TRISA = %001110
TRISC = %00000010 ' set PORTC I/O
SSP1CON1=$21 ;$22 works too
SSP1CON2=0
SSP1CON3=0
SSP1STAT=$40
high ssc '
serout2 PORTA.0,84,[ "RFM12",13,10]
SSPIF = 0
GOSUB RM12INIT
BCNT=1
INTCON=$90
FLG=0
grp=net
mainloop:
IF RXDONE THEN
CMD=$820D ;receive $820D IDLE
GOSUB SNDCMD
INTCON=0
crc=-1
FOR I= 0 TO LEN+3
CRC_IN = RXBUFF[i]
gosub crc16
next
if rxbuff[len+4]=crc.lowbyte then ;only matching the crc lowbyte seems ok
I=RXBUFF[2]
if ( i.7 ) then gosub ack ; acknowlege reception if asked
; should check here for node id match
serout2 PORTA.0,84, [ HEX2 RXBUFF[1] ,",", HEX2 RXBUFF[2] ,",",HEX2 RXBUFF[3] ,"," ]
FOR I= 4 TO LEN+2
serout2 PORTA.0,84, [ RXBUFF[I] ,"," ]
NEXT
; serout2 PORTA.0,84, ["XXX", RXBUFF[len+3]," ", HEX2 RXBUFF[len+5], HEX2 RXBUFF[len+4]," ",hex4 crc, 13,10] ;len+4=lowbyte
serout2 PORTA.0,84, [RXBUFF[len+3], 13,10]
endif
FOR I= 1 TO MAXL
RXBUFF[I]=0 ;clear buffer
NEXT
CMD=0 ;reset fifo sequence
GOSUB SNDCMD ;
CMD=$CA80
GOSUB SNDCMD ;
CMD=$CA83 ;reset fifo
GOSUB SNDCMD
FLG=0
BCNT=1
INTCON=$90 ; enable rx int
CMD=$82DD ;receive on
GOSUB SNDCMD
ENDIF
I=0 ; something in main loop for the wdt
GoTo mainloop ' do it forever
End
SNDCMD: ;word size send ,note rfm12b dose not drop irq when ready for cmd
LOW SSC
SSPIF = 0
SSPBUF = CMD.HIGHBYTE
WHILE SSPIF =0 ' wait for SPI interupt flag
WEND ' wait for send
SSPIF = 0
SSPBUF = CMD.LOWBYTE
WHILE SSPIF =0 ' wait for SPI interupt flag
WEND ' wait for send
HIGH SSC
Return
RM12INIT: ;leaves radio in rxmode
CMD=0
GOSUB SNDCMD
CMD=$8205 ;SLEEP
GOSUB SNDCMD
PAUSE 1
CMD=$80D7
GOSUB SNDCMD
CMD=$A640
GOSUB SNDCMD
CMD=$C608
GOSUB SNDCMD
CMD=$94A2
GOSUB SNDCMD
CMD=$C2AC
GOSUB SNDCMD
CMD=$CA83
GOSUB SNDCMD
CMD=$CE63
GOSUB SNDCMD
CMD=$C483
GOSUB SNDCMD
CMD=$9850
GOSUB SNDCMD
CMD=$CC77
GOSUB SNDCMD
CMD=$E000
GOSUB SNDCMD
CMD=$C800
GOSUB SNDCMD
CMD=$C043
GOSUB SNDCMD
PAUSE 1
CMD=$82DD ;receive $82dd ' XMIT $823D
GOSUB SNDCMD
RETURN
RX:
LOW SSC
SSPIF = 0
SSPBUF = $B0 '
WHILE SSPIF=0 ' wait for SPI interupt flag
WEND
SSPIF = 0
SSPBUF = 0 ' write to SSPBUF
WHILE SSPIF =0 ' wait for SPI interupt flag
WEND
RXBUFF[BCNT] = SSPBUF ' store received character in array
BCNT=BCNT+1
IF (BCNT > MAXL) OR (BCNT > (LEN+5) )THEN RXDONE=1
HIGH SSC
INTCON=$90
@ INT_RETURN
crc16:
CRC = CRC ^ CRC_IN
for j=0to 7
if crc.0 then
crc= ((crc>>1) ^$a001 ) ;
else
crc= crc>>1
endif
next
return
xmit: ;tx a byte
WHILE RNINT =1 ' wait for irq interupt flag from rfm12b
WEND
cmd =cmd |$b800
GOSUB SNDCMD
return
ack: ;leaves radio idle
CMD=$823d ;tx on
GOSUB SNDCMD
pause 3
crc=-1
CMD=$aa ;preamble
GOSUB xmit
CMD=$aa ;preamble
GOSUB SNDCMD
CMD=$aa ;preamble
GOSUB xmit
CMD=$2d ;sync
GOSUB xmit
CMD=net ;network
CRC_IN=cmd
gosub crc16
GOSUB xmit
CMD=node ;node id
cmd.7=1
CRC_IN=cmd
gosub crc16
GOSUB xmit
CMD=rxbuff[1] ;ack from
CRC_IN=cmd
gosub crc16
GOSUB xmit
CMD=00 ;nill length
CRC_IN=cmd
gosub crc16
GOSUB xmit
CMD=crc.lowbyte
GOSUB xmit
CMD=crc.highbyte
GOSUB xmit
CMD=$aa ;postamble
GOSUB xmit
CMD=$aa ;postamble
GOSUB xmit
pause 4
CMD=$820d
GOSUB SNDCMD
return
sndbuff: ;leaves radio idle and rx int off , to use load dest ,data and len , len is the data payload size and call this sub
INTCON=0 ; watch this
grp=net
source=node
CMD=$823d ;tx on
GOSUB SNDCMD
pause 3
crc=-1
CMD=$aa ;preamble
GOSUB xmit
CMD=$aa ;preamble
GOSUB SNDCMD
CMD=$aa ;preamble
GOSUB xmit
CMD=$2d ;sync
GOSUB xmit
for i=0 to len + 3
CMD= rxbuff[i]
CRC_IN=cmd
gosub crc16
GOSUB xmit
next
CMD=crc.lowbyte
GOSUB xmit
CMD=crc.highbyte
GOSUB xmit
CMD=$aa ;postamble
GOSUB xmit
CMD=$aa ;postamble
GOSUB xmit
pause 4
CMD=$820d
GOSUB SNDCMD
return
Bookmarks