;Bluetooth Flags
#define fbtinit btflag0,0,1 ;1=bluetooth initialized
;#define btflag0,1,1 ;
;#define btflag0,2,1 ;
;#define btflag0,3,1 ;
;#define btflag0,4,1 ;
;#define btflag0,5,1 ;
;#define btflag0,6,1 ;
;#define btflag0,7,1 ;
;standard response flags
#define FSRAOK btsresp,0,1 ;"AOK"
#define FSRERR btsresp,1,1 ;"ERR"
#define FSRBOND btsresp,2,1 ;"BONDED"
#define FSRSEC btsresp,3,1 ;"SECURED"
#define FSRCEND btsresp,4,1 ;"CONNECTION END"
#define FSRRBT btsresp,5,1 ;"REBOOT"
#define FSRZCMD btsresp,6,1 ;"\0CMD" (reply when reboot complete)
#define FSRCON btsresp,7,1 ;"Connected"
#define FSRNSR btsresp+1,0,1 ;non-standard response received
;#define btsresp+1,1,1 ;
;#define btsresp+1,2,1 ;
;#define btsresp+1,3,1 ;
;#define btsresp+1,4,1 ;
;#define btsresp+1,5,1 ;
;#define btsresp+1,6,1 ;
;#define btsresp+1,7,1 ;
;wait for standard response flags
#define FWRAOK btswait,0,1 ;"AOK"
#define FWRERR btswait,1,1 ;"ERR"
#define FWRBOND btswait,2,1 ;"Bonded"
#define FWRSEC btswait,3,1 ;"Secured"
#define FWRCEND btswait,4,1 ;"Connection End"
#define FWRRBT btswait,5,1 ;"Reboot"
#define FWRZCMD btswait,6,1 ;"\0CMD" (reply when reboot complete)
#define FWRCON btswait,7,1 ;"Connected"
#define FWRNSR btswait+1,0,1 ;non-standard response received
;#define btswait+1,1,1 ;
;#define btswait+1,2,1 ;
;#define btswait+1,3,1 ;
;#define btswait+1,4,1 ;
;#define btswait+1,5,1 ;
;#define btswait+1,6,1 ;
;#define btswait+1,7,1 ;
;*************************************
;** BTININT -- Initialize Bluetooth **
;*************************************
initbt
BANKSEL btstate ;select bluetooth working bank
bsf wakesw ;wake bluetooth
bsf wakehw
bra ibtex ;exit restoring bank
;*****************************************
;** BTPRCV -- Process Bluetooth receiver**
;** return z if no response **
;*****************************************
btprcv retbc fbtinit ;don't receive if in initialzation
movlf fsr1h,high btrcvbuff ;point to receiver buffer
movff btrhead,fsr1l ; and index to next character
btplp rcall rxbyte ;receiver byte available?
retz ; z if none
movwf indf1 ;save character at current position
movlw '\r' ;ignore return characters
cpfseq indf1
movf postinc1,w ;get back in w, and update pointer
movff fsr1l,btrhead ;save new head position
xorlw '\n' ;new character a line feed?
bnz btplp ;no, get some more characters, if available
movlfb btrhead,low btrcvbuff ;reset btrhead for next message
;parse for common messages
;if common response not matched, indicate (likely) parameters returned from RN4020
bsf btsresp,0,1 ;set 1st bit in standard response flags
movdf tblptr,btcmes ;tblptr -> possible responses (\n separated, \r terminated)
btplp0 lfsr 0,btrcvbuff ;fsr0 -> point to head of response buffer
btplp1 tblrd *+ ;get next character from list of responses
movlw '\r' ;\r is response list terminating character
xorwf tablat,w ; end of response list?
bz btpnmf ;yes, no response matched
movf tablat,w ;get character
cpfseq postinc0 ;test against charcter in response buffer
bra btpnom ;!= means no match, skip to next response
xorlw '\n' ;new line character?
bz btpmat ;yes, we have found a match
bra btplp1 ;keep testing characters till match
;no match of current response, skip ahead till /n or /r
btpnom clrc ;roll to next response
rlcf btsresp,f,1
rlcf btsresp+1,f,1
btplp2 tblrd *+ ;get next character from list of responses
movlw '\r' ;get terminating character
xorwf tablat,w ; end of response list?
bz btpnmf ;yes, no response matched
movlw '\n' ;is it a new line character?
xorwf tablat,w
bnz btplp2 ;loop till \0 or \n
bra btplp0 ;and test against next response
;match found, response bit set
btpmat
;match not found, non-standard response bit set
btpnmf clrz ;nz indicates a new reponse has been received
return
btcmes db "AOK\n","ERR\n","Bonded\n","Secured\n","Connection End\n","Reboot\n","\x00CMD\n","Connected\n",'\r'
;***************************************************************
;** POLLBT -- Bluetooth polling -- called each main loop pass **
;***************************************************************
pollbt
BANKSEL btstate ;select bluetooth working bank
clrf btsresp,1 ;clear standard response flags
clrf btsresp+1,1
rcall btprcv ;check to see if a new bluetooth response has been received.
bz pbtnrsp ;no response
;a response has been received from bluetooth
movf btswait,w,1 ;are we waiting for a particular response?
iorwf btswait+1,w,1
bz pbstate ;no, just process machine
;decide whether or not to throw an error
bbs fwrerr,pbteok ;is ERR an acceptable response?
bbs fsrerr,pbterr ;No, flag ERR as error.
pbteok movf btswait,w,1 ;are we waiting for a response?
andwf btsresp,w,1 ;has a proper response been received?
bnz pbstate ;yes, process state machine
movf btswait+1,w,1 ;again, next byte
andwf btsresp+1,w,1
bnz pbstate
bra pbtimp ;flag an improper response
;no response received from bluetooth this pass -- process timed functions
pbtnrsp movf btstime,f,1 ;is timer running?
bz pbtntim ;no, not a timed function
;timed function -- either response time-out or timed state
btfsc tc16ms ;process 16ms timer
decfsz btstime,f,1 ;decrement state timer
bra ibtex ;no further processing if timer not expired
movf btswait,w,1 ;are we waiting for a particular response?
iorwf btswait+1,w,1
bz pbstate ;no, just process timed state after delay
;otherwise, flag a timeout error
bra pbtrto ;show timeout error
;not a timed function
pbtntim movf btswait,w,1 ;are we waiting for a particular response?
iorwf btswait+1,w,1
bz pbstate ;no, just process timed state after delay
bra ibtex ;or wait until timer expires
;Handle improper response
pbtimp bra ibtex ;ignore improper responses (for now)
;Handle ERR response
pbterr movlb 0
movlw bterr ;get ERR error code
call seterr ;and show error
BANKSEL btstate ;select bluetooth working bank
bra ibtex ;ignore erroneous responses
;Handle timeout during reception of response
pbtrto movlb 0
movlw btrto ;get time out error code
call seterr ;and set error limp along
BANKSEL btstate ;select bluetooth working bank
bra ibtex ;ignore erroneous responses
;process Bluetooth state machine
pbstate clrf btswait,1 ;clear waiting flags for next pass
clrf btstime,1 ;and state timer
movfw btstate
call cjump
bra bts0 ;state 0: await BTAWAKE hardware line
bra bts1 ;state 1: send feature string
bra bts2 ;state 2: setup and reboot
bra bts3 ;state 4: wait for reboot to complete
bra bts4 ;state 5: start advertising
bra bts5 ;state 6: await connection
bra bts6 ;state 7: await disconnection
;***********************
;** Bluetooth states **
;***********************
;-- State 0: await BTAWAKE hardware line, then wait 100ms
bts0 bbc btawake,ibtex ;exit if BTAWAKE not asserted
movlfb btstime,clctim(t16ms,115) ;set up 100 ms timer
bra ibtns ;and get out
;-- State 1: clear receive buffer, then send feature string
bts1 call rxbyte ;data in receive buffer?
bnz bts1 ;yes, keep reading till clear
bsf fbtinit ;indicate initialized
txpstr sbtfs ;send feature settings string
bra ibtexat
;-- State 2: setup prior and reboot
bts2 movfw btssubst ;get substate counter
call cjump
bra bts2a ;set friendly name
bra bts2b ;set model
bra bts2c ;set manufacturer name
bra bts2d ;clear private services
bra bts2e ;set server services
bra bts2f ;set private service UUID
bra bts2g ;set private service characteristics
bra bts2h ;reboot
bts2a txpstr sbtfn ;set friendly name
bra ibssx
bts2b txpstr sbtmod ;set model name
bra ibssx
bts2c txpstr sbtmnm ;set manufacturer name
bra ibssx
bts2d txpstr sbtcps ;clear private services
bra ibssx
bts2e txpstr sbtstsrv ;set server services
bra ibssx
bts2f txpstr sbtpsuid ;set private service UUID
bra ibssx
bts2g txpstr sbtpscar ;set private service characteristic
bra ibssx ; and index to next state
bts2h txpstr sbtres ;send reset
bsf fwrrbt ;wait for 'Reboot'
bra ibtext
;-- State 3: wait up to 3,200 ms for reboot sequence
bts3 bsf fwrzcmd ;wait for '\0CMD'
movlfb btstime,clctim(t16ms,3212) ;up to 3212ms allowed for response
bra ibtns
;-- State 4: start advertisement
bts4 movlb 0
call bloff ;turn off for disconnected
BANKSEL btstate ;select bluetooth working bank
txpstr sbtadv ;send start advertisement
bra ibtexae ;and allow ERR in case already advertising
;-- State 5: await connection
bts5 bsf FWRCON ;await connection
bra ibtns
;-- State 6: await disconnection
bts6 movlb 0
call blon ;turn on backlight to show we are connected
BANKSEL btstate ;select bluetooth working bank
bsf FWRCEND ;await disconnection
movlfb btstate,4 ;restart advertisement when disconnected
bra ibtex
;set up next state with AOK/ERR response and 200ms timeout
ibtexae bsf FWRERR ;wait for 'ERR'
;set up next state with AOK response and 200ms timeout
ibtexat bsf FWRAOK ;wait for 'AOK'
;set up next state with 200 ms timeout
ibtext movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
;set up next state
ibtns incf btstate,f,1 ;and skip to next state on completion
;restore BSR and quit till next pass
ibtex movlb 0
return
;set up next substate with AOK, and 200ms
ibssx bsf FWRAOK ;wait for 'AOK'
movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
incf btssubst,f,1 ;go to next substate
movlb 0 ;restore bsr
return ;and get out
;** Strings **
sbtfg db "gr\r\0" ;get features
sbtfs db "sr,00060000\r\0" ;no auto-advertise, no authentication
sbtfn db "s-,WECoyote\r\0" ;set friendly name
sbtmod db "sdm,AAC1000\r\0" ;set model
sbtmnm db "sdn,Acme Products\r\0" ;set manufacturer name
sbtres db "r,1\r\0" ;reset
sbtadv db "A\r\0" ;advertise
sbtunb db "U\r\0" ;unbond
sbtcps db "PZ\r\0" ;clear private services
sbtstsrv db "SS,40000001\r\0" ;allow private services
sbtpsuid db "PS,1000EEE0000000000000000000000000\r\0" ;set private service UUID
sbtpscar db "PC,1000EEE1000000000000000000000000,02,06\r\0" ;add private service characteristic UUID
I think I found the problem...
I was waiting for someone to notice that!
;*************************************
;** BTININT -- Initialize Bluetooth **
;*************************************
initbt
BANKSEL btstate ;select bluetooth working bank
bsf wakesw ;wake bluetooth
bsf wakehw
bra ibtex ;exit restoring bank
;*****************************************
;** BTPRCV -- Process Bluetooth receiver**
;** return z if no response **
;*****************************************
btprcv retbc fbtinit ;don't receive if in initialzation
movlf fsr1h,high btrcvbuff ;point to receiver buffer
movff btrhead,fsr1l ; and index to next character
btplp rcall rxbyte ;receiver byte available?
retz ; z if none
movwf indf1 ;save character at current position
movlw '\r' ;ignore return characters
cpfseq indf1
movf postinc1,w ;get back in w, and update pointer
movff fsr1l,btrhead ;save new head position
xorlw '\n' ;new character a line feed?
bnz btplp ;no, get some more characters, if available
movlfb btrhead,low btrcvbuff ;reset btrhead for next message
;parse for common messages
;if common response not matched, indicate (likely) parameters returned from RN4020
bsf btsresp,0,1 ;set 1st bit in standard response flags
movdf tblptr,btsmes ;tblptr -> possible standard responses (\n separated, \r terminated)
btplp0 lfsr 0,btrcvbuff ;fsr0 -> point to head of response buffer
btplp1 tblrd *+ ;get next character from list of responses
movlw '\r' ;\r is response list terminating character
xorwf tablat,w ; end of response list?
bz btpnmf ;yes, no response matched
movf tablat,w ;get character
cpfseq postinc0 ;test against charcter in response buffer
bra btpnom ;!= means no match, skip to next response
movlw '\n' ;is it a new line character?
xorwf tablat,w
bz btpmat ;yes, we have found a match
bra btplp1 ;keep testing characters till match
;no match of current response, skip ahead till /n or /r
btpnom clrc ;roll to next response
rlcf btsresp,f,1
rlcf btsresp+1,f,1
btplp2 tblrd *+ ;get next character from list of responses
movlw '\r' ;get terminating character
xorwf tablat,w ; end of response list?
bz btpnmf ;yes, no response matched
movlw '\n' ;is it a new line character?
xorwf tablat,w
bnz btplp2 ;loop till \0 or \n
bra btplp0 ;and test against next response
;match found, response bit set
btpmat
;match not found, non-standard response bit set
btpnmf clrz ;nz indicates a new reponse has been received
return
;standard response messages -- list is \r terminated (so we can include 0x00 for reboot)
btsmes db "AOK\n","ERR\n","Bonded\n","Secured\n","Connection End\n","Reboot\n","\x00CMD\n","Connected\n","NFail\n",'\r'
;***************************************************************
;** POLLBT -- Bluetooth polling -- called each main loop pass **
;***************************************************************
pollbt
BANKSEL btstate ;select bluetooth working bank
clrf btsresp,1 ;clear standard response flags
clrf btsresp+1,1
rcall btprcv ;check to see if a new bluetooth response has been received.
bz pbtnrsp ;no response
;a response has been received from bluetooth
movf btswait,w,1 ;are we waiting for a particular response?
iorwf btswait+1,w,1
bz pbstate ;no, just process machine
;decide whether or not to throw an error
bbs fwrerr,pbteok ;is ERR an acceptable response?
bbs fsrerr,pbterr ;No, flag ERR as error.
pbteok movf btswait,w,1 ;are we waiting for a response?
andwf btsresp,w,1 ;has a proper response been received?
bnz pbstate ;yes, process state machine
movf btswait+1,w,1 ;again, next byte
andwf btsresp+1,w,1
bnz pbstate
bra pbtimp ;flag an improper response
;no response received from bluetooth this pass -- process timed functions
pbtnrsp movf btstime,f,1 ;is timer running?
bz pbtntim ;no, not a timed function
;timed function -- either response time-out or timed state
btfsc tc16ms ;process 16ms timer
decfsz btstime,f,1 ;decrement state timer
bra ibtex ;no further processing if timer not expired
movf btswait,w,1 ;are we waiting for a particular response?
iorwf btswait+1,w,1
bz pbstate ;no, just process timed state after delay
;otherwise, flag a timeout error
bra pbtrto ;show timeout error
;not a timed function
pbtntim movf btswait,w,1 ;are we waiting for a particular response?
iorwf btswait+1,w,1
bz pbstate ;no, just process the untimed state
bra ibtex ;otherwise, just wait until response
;Handle improper response
pbtimp btfsc fsrnsr ;non-standard response?
rcall btpnsr ;go parse it
bra ibtex ;ignore improper responses (for now)
;Handle ERR response
pbterr movlb 0
movlw bterr ;get ERR error code
call seterr ;and show error
BANKSEL btstate ;select bluetooth working bank
bra ibtex ;ignore erroneous responses
;Handle timeout during reception of response
pbtrto movlb 0
movlw btrto ;get time out error code
call seterr ;and set error limp along
BANKSEL btstate ;select bluetooth working bank
bra ibtex ;ignore erroneous responses
;process Bluetooth state machine
pbstate clrf btswait,1 ;clear waiting flags for next pass
clrf btstime,1 ;and state timer
movfw btstate
call cjump
bra bts0 ;state 0: await BTAWAKE hardware line
bra bts1 ;state 1: send feature string
bra bts2 ;state 2: setup and reboot
bra bts3 ;state 4: wait for reboot to complete
bra bts4 ;state 5: start advertising
bra bts5 ;state 6: await connection
bra bts6 ;state 7: await disconnection
;***********************
;** Bluetooth states **
;***********************
;-- State 0: await BTAWAKE hardware line, then wait 100ms
bts0 bbc btawake,ibtex ;exit if BTAWAKE not asserted
movlfb btstime,clctim(t16ms,115) ;set up 100 ms timer
bra ibtns ;and get out
;-- State 1: clear receive buffer, then send feature string
bts1 call rxbyte ;data in receive buffer?
bnz bts1 ;yes, keep reading till clear
bsf fbtinit ;indicate initialized
txpstr sbtfs ;send feature settings string
bra ibtexat
;-- State 2: setup prior and reboot
bts2 movfw btssubst ;get substate counter
call cjump
bra bts2a ;set friendly name
bra bts2b ;set model
bra bts2c ;set manufacturer name
bra bts2d ;clear private services
; bra bts2e ;set server services
; bra bts2f ;set private service UUID
; bra bts2g ;set private service characteristics
bra bts2ga ;unbond
bra bts2h ;reboot
bts2a txpstr sbtfn ;set friendly name
bra ibssx
bts2b txpstr sbtmod ;set model name
bra ibssx
bts2c txpstr sbtmnm ;set manufacturer name
bra ibssx
bts2d txpstr sbtcps ;clear private services
bra ibssx
bts2e txpstr sbtstsrv ;set server services
bra ibssx
bts2f txpstr sbtpsuid ;set private service UUID
bra ibssx
bts2g txpstr sbtpscar ;set private service characteristic
bra ibssx ; and index to next state
bts2ga txpstr sbtunb ;unbond
bsf FWRERR ;'ERR' is ok if not bonded
bra ibssx ; and index to next state
bts2h txpstr sbtres ;send reset
bsf fwrrbt ;wait for 'Reboot'
bra ibtext
;-- State 3: wait up to 3,200 ms for reboot sequence
bts3 bsf fwrzcmd ;wait for '\0CMD'
movlfb btstime,clctim(t16ms,3212) ;up to 3212ms allowed for response
bra ibtns
;-- State 4: start advertisement
bts4 movlb 0
call bloff ;turn off for disconnected
BANKSEL btstate ;select bluetooth working bank
txpstr sbtadv ;send start advertisement
bra ibtexae ;and allow ERR in case already advertising
;-- State 5: await connection
bts5 bsf FWRCON ;await connection
bra ibtns
;-- State 6: await disconnection
bts6 movlb 0
call blon ;turn on backlight to show we are connected
BANKSEL btstate ;select bluetooth working bank
bsf FWRCEND ;await disconnection
movlfb btstate,4 ;restart advertisement when disconnected
bra ibtex
;set up next state with AOK/ERR response and 200ms timeout
ibtexae bsf FWRERR ;wait for 'ERR'
;set up next state with AOK response and 200ms timeout
ibtexat bsf FWRAOK ;wait for 'AOK'
;set up next state with 200 ms timeout
ibtext movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
;set up next state
ibtns incf btstate,f,1 ;and skip to next state on completion
;restore BSR and quit till next pass
ibtex movlb 0
return
;set up next substate with AOK, and 200ms
ibssx bsf FWRAOK ;wait for 'AOK'
movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
incf btssubst,f,1 ;go to next substate
movlb 0 ;restore bsr
return ;and get out
;** Strings **
sbtfg db "gr\r\0" ;get features
sbtfs db "sr,00060000\r\0" ;no auto-advertise, no authentication
sbtfn db "s-,WECoyote\r\0" ;set friendly name
sbtmod db "sdm,AAC1000\r\0" ;set model
sbtmnm db "sdn,Acme Products\r\0" ;set manufacturer name
sbtres db "r,1\r\0" ;reset
sbtadv db "A\r\0" ;advertise
sbtunb db "U\r\0" ;unbond
sbtcps db "PZ\r\0" ;clear private services
sbtstsrv db "SS,40000001\r\0" ;allow private services
sbtpsuid db "PS,1000EEE0000000000000000000000000\r\0" ;set private service UUID
sbtpscar db "PC,1000EEE1000000000000000000000000,02,06\r\0" ;add private service characteristic UUID
;********************************************
;** BTPNSR -- Parse Non-Standard Responses **
;********************************************
btpnsr clrf bitcnt ;use bitcnt as index to received response
movdf tblptr,btnsmes ;tblptr -> possible non-standard responses (\n separated, \0 terminated)
btpnlp0 lfsr 0,btrcvbuff ;fsr0 -> point to head of response buffer
btpnlp1 tblrd *+ ;get next character from list of responses
movf tablat,w ;get character from list
bz btpnnf ;z=end of list, not found
movlw '\n' ;== \n means we have a match!
xorwf tablat,w
bz btpnm ;go process for arguments
movf tablat,w ;get character from list
cpfseq postinc0 ;compare with received
bra btpnnm ;no match, skip to next response
bra btpnlp1 ;continue till match/no match
;no match of current response, skip ahead till /0 or /n
btpnnm incf bitcnt,f ;update response counter
btpnlp2 tblrd *+ ;get next character from list of responses
movf tablat,w ;get character
bz btpnnf ;z=end of list -- no match
xorlw '\n' ;is it a new line character?
bnz btpnlp2 ;loop till \0 or \n
bra btpnlp0 ;and test against next non-standard response
;no match found - what do we do?
btpnnf return ;for now, just ignore the response
;match found -- bit count has response number
btpnm movfw bitcnt ;get response number
call cjump ;and process it
bra btnscp ;'ConnParam:'
;ConnParam <hex16>,<hex16>,<hex16> (connection interval, slave latency, supervison timeout)
btnscp lfsr 1,conint+1 ;point to holders
rcall hex2bin ;capture interval
rcall hex2bin ;capture slave latency
rcall hex2bin ;capture supervision timeout
return
;non-standard responses -- list is \n separated, \0 terminated
btnsmes db "ConnParam:\n",0
;**************************************************************
;** HEX2BIN -- Convert arbitrary length hex to binary **
;** store result at fsr1 -> RAM (high byte) **
;** ignore spaces, comma or \n terminated **
;** target RAM must be large enough to hold expected value **
;**************************************************************
hex2bin
;process high byte first
movf postinc0,w ;get next character
sublw '\n' ;is it a newline?
retz ;yes, we are done
addlw 22 ;is it a space?
bz hex2bin ;yes, ignore it
addlw 12 ;is it a comma?
retz ;yes, we are done
sublw -14 ;'A'-'F' = 7-12, '0'-'9' = -10 - -1
skpc ;correct for 0-9
addlw 7 ;'0'-'9' = -3 - 6
addlw 3 ;final result
swapf wreg,f ;swap for high nibble
movwf indf1 ;and save
;then low byte (no need to check for terminators on odd characters)
h2b1 movlw 58
subwf postinc0,w ;'A'-'F' = 7 - 12, '0'-'9' = -10 - -1
skpc ;correct for 0-9
addlw 7 ;'0'-'9' = -3 - 6
addlw 3 ;final result
iorwf postdec1,f ;merge in low nibble
bra hex2bin ;do for all characters
Re private characteristics and nRf:
It seems that the problem is not with nRF. I've found other bluetooth scanner apps, and they all hang when trying to connect when I have the private characteristics defined.
The RN4020 is telling me the private characteristics are setup properly.
So, there is either a problem with my phone, or with the RN4020. Unfortunately, I didn't bring my tablet today to try a different device. Anyone got a phone I can borrow?
Edit: if anyone here has worked with bluetooth LE, and, specifically with private characteristics, can you help?
Thanks.Not to shoo you way from here but the Bluetooth sub-forum over at microchip.com seems to be a hotbed of RN4020 questions and a few excellent people with answers.
http://www.microchip.com/forums/f505.aspx
Congrats, you can take a couple of aspirins now. Fixing that is easy. But finding the problem is a real challenge.Fixed! The problem was the UUID for the private service. The RN4020 seems to choke on all the zeros.
Random numbers work much better.
;important Bluetooth states
cbtsid equ 0 ;idle until bluetooth on and awake
cbtssu equ 1 ;begin setup -- get feature string
cbtsls equ 6 ;send LS command
cbtsrbt equ 10 ;reboot
cbtsaps equ 11 ;add private services
cbtsadv equ 14 ;start advertising
;Bluetooh constants
cnumcar equ 5 ;number of private characteristics
;Bluetooth Flags
#define fbtrbt btflag0,0,1 ;1=bluetooth requires reboot
#define fbtcaph btflag0,1,1 ;1=capture characteristic handle during parsing of UUIDs in LS
;#define btflag0,2,1 ;
;#define btflag0,3,1 ;
;#define btflag0,4,1 ;
;#define btflag0,5,1 ;
;#define btflag0,6,1 ;
;#define btflag0,7,1 ;
;standard response flags
#define FSRAOK btsresp,0,1 ;"AOK"
#define FSRERR btsresp,1,1 ;"ERR"
#define FSRBOND btsresp,2,1 ;"BONDED"
#define FSRSEC btsresp,3,1 ;"SECURED"
#define FSRCEND btsresp,4,1 ;"CONNECTION END"
#define FSRRBT btsresp,5,1 ;"REBOOT"
#define FSRZCMD btsresp,6,1 ;"\0CMD" (reply when reboot complete)
#define FSRCON btsresp,7,1 ;"Connected"
#define FSRNFL btsresp+1,0,1 ;"NFail"
#define FSRCMD btsresp+1,1,1 ;"CMD"
#define FSREND btsresp+1,2,1 ;"END"
#define FSRNSR btsresp+1,3,1 ;non-standard response received
;#define btsresp+1,4,1 ;
;#define btsresp+1,5,1 ;
;#define btsresp+1,6,1 ;
;#define btsresp+1,7,1 ;
;wait for standard response flags
#define FWRAOK btswait,0,1 ;"AOK"
#define FWRERR btswait,1,1 ;"ERR"
#define FWRBOND btswait,2,1 ;"Bonded"
#define FWRSEC btswait,3,1 ;"Secured"
#define FWRCEND btswait,4,1 ;"Connection End"
#define FWRRBT btswait,5,1 ;"Reboot"
#define FWRZCMD btswait,6,1 ;"\0CMD" (reply when reboot complete)
#define FWRCON btswait,7,1 ;"Connected"
#define FWRNFL btswait+1,0,1 ;"NFail"
#define FWRCMD btswait+1,1,1 ;"CMD"
#define FWREND btswait+1,2,1 ;"END"
#define FWRNSR btswait+1,3,1 ;non-standard response received
;#define btswait+1,4,1 ;
;#define btswait+1,5,1 ;
;#define btswait+1,6,1 ;
#define FWRNSRX btswait+1,7,1 ;non-standard response not processed
;macros
txpstr macro paddr ;send string from program memory
movlf tblptrl,low paddr
movlf tblptrh,high paddr
call _txpstr
endm
rxpcstr macro paddr ;compare received string with paddr
movlf tblptrl,low paddr
movlf tblptrh,high paddr
call _rxpcstr
endm
;** Strings **
sbtgfs db "GR\r\0" ;get features
sbtsfs db "SR,00060000\r\0" ;no auto-advertise, no authentication
sbtgfn db "GN\r\0" ;get friendly name
sbtsfn db "S-,WECoyote2\r\0" ;set friendly name
sbtgmod db "GDM\r\0"
sbtsmod db "SDM,AAC1000\r\0" ;set model
sbtgmn db "GDN\r\0"
sbtsmn db "SDN,Acme Products\r\0" ;set manufacturer name
sbtgbms db "GS\r\0"
sbtsbms db "SS,40000001\r\0" ;allow private services
sbtls db "LS\r\0" ;list services
sbtsps db "PS,4FB69667EB9C473992E26908642B1CD0\r\0" ;set private service UUID
sbtsc1 db "PC,4CD584F575A14A36833C83D0E75BA483,02,14\r\0" ;add private service characteristic UUID
sbtsc2 db "PC,4B90C8B122644767AC0FF10630185C19,02,14\r\0"
sbtsc3 db "PC,2402A03123EE4E2B919BCF128281B6D5,02,14\r\0"
sbtsc4 db "PC,4202E4BECC194B2F895234F4AF83609A,02,14\r\0"
sbtsc5 db "PC,7828D3A795EC48BB961C87B0214CA594,02,14\r\0"
sbtcps db "PZ\r\0" ;clear private services
sbtres db "R,1\r\0" ;reset
sbtadv db "A\r\0" ;advertise
sbtkill db "K\r\0" ;kill current connection
sbtdorm db "O\r\0" ;dormant
sbtunb db "U\r\0" ;unbond
;standard response messages -- list is \r terminated (so we can include 0x00 for reboot)
btsmes db "AOK\nERR\nBonded\nSecured\nConnection End\nReboot\n\x00CMD\nConnected\nNFail\nCMD\nEND\n\r"
;non-standard responses -- list is \n separated, \0 terminated
btnsmes db "ConnParam:\nNotify,\nIndicate,\nWV,\nWC,\nRV,\n",0
;**************************************
;** BLTOG -- Toggle Bluetooth on/off **
;**************************************
bltog bbs fbton,bltoff ;turn bluetooth off?
;Turn bluetooth off
blton bsf fbton
return
;Turn bluetooth on
bltoff bcf fbton
return
;***************************************************************
;** POLLBT -- Bluetooth polling -- called each main loop pass **
;***************************************************************
pollbt retbc run ;don't process bluetooth until system initialized and running
BANKSEL btstate ;select bluetooth working bank
clrf btsresp,1 ;clear standard response flags
clrf btsresp+1,1
rcall btprcv ;check to see if a new bluetooth response has been received.
bz pbtnrsp ;no response
;a response has been received from bluetooth
movf btswait,w,1 ;are we waiting for a particular response?
iorwf btswait+1,w,1
bz pbstate ;no, just process machine
;decide whether or not to throw an error
bbs fwrerr,pbteok ;is ERR an acceptable response?
bbs fsrerr,pbterr ;No, flag ERR as error.
pbteok movf btswait,w,1 ;are we waiting for a response?
andwf btsresp,w,1 ;has a proper response been received?
bnz pbstate ;yes, process state machine
movf btswait+1,w,1 ;again, next byte
andwf btsresp+1,w,1
bnz pbstate
bra pbtimp ;flag an improper response
;no response received from bluetooth this pass -- process timed functions
pbtnrsp movf btstime,f,1 ;is timer running?
bz pbtntim ;no, not a timed function
;timed function -- either response time-out or timed state
btfsc tc16ms ;process 16ms timer
decfsz btstime,f,1 ;decrement state timer
bra ibtex ;no further processing if timer not expired
movf btswait,w,1 ;are we waiting for a particular response?
iorwf btswait+1,w,1
bz pbstate ;no, just process timed state after delay
;otherwise, flag a timeout error
bra pbtrto ;show timeout error
;not a timed function
pbtntim movf btswait,w,1 ;are we waiting for a particular response?
iorwf btswait+1,w,1
bz pbstate ;no, just process the untimed state
bra ibtex ;otherwise, just wait until response
;Handle improper response
pbtimp btfsc fsrnsr ;non-standard response?
rcall btpnsr ;go parse it
bra ibtex ;ignore improper responses (for now)
;Handle ERR response
pbterr movlb 0
movlw bterr ;get ERR error code
call seterr ;and show error
BANKSEL btstate ;select bluetooth working bank
bra ibtex ;ignore erroneous responses
;Handle timeout during reception of response
pbtrto movlb 0
movlw btrto ;get time out error code
call seterr ;and set error limp along
BANKSEL btstate ;select bluetooth working bank
bra ibtex ;ignore erroneous responses
;process Bluetooth state machine
pbstate clrf btswait,1 ;clear waiting flags for next pass
clrf btswait+1,1
clrf btstime,1 ;and state timer
movfw btstate
call cjump
;idle with bluetooth off
bra btsid0 ;state 0: idle awaiting BTAWAKE hardware line if bluetooth on
;setup blue tooth
bra btssu0 ;state 1: begin setup, get feature string
bra btssu1 ;state 2: get/set friendly name
bra btssu2 ;state 3: get/set model name
bra btssu3 ;state 4: get/set manufacturers name
bra btssu4 ;state 5: get/set bitmap services
bra btssu5 ;state 6: send LS to confirm private services
bra btssu6 ;state 7: confirm private service UUID is defined
bra btssu7 ;state 8: confirm all private characteristic UUIDs
bra btssu8 ;state 9: scan for end of LS list
bra btssu9 ;state 10: start reset/reboot process -- clear private services
bra btssuA ;state 11: add private services
bra btssuB ;state 12: iteratively add private characteristics then reboot
bra btssuC ;state 13: wait for reboot to complete and redo LS to load handles
;idle with bluetooth on
bra btsadv ;state 14: start advertising
bra btsid1 ;state 15: idle for connects/disconnects and monitor monitor for shutdown
;shudown bluetooth
bra btssd0 ;state 16: put bluetooth in idle mode
bra btssd1 ;state 17: clear wakesw
bra btssd2 ;state 18: clear wakehw
;***********************
;** Bluetooth states **
;***********************
;-- State 0: wake BT, await BTAWAKE hardware line, then wait for CMD message
btsid0 bbc fbton,ibtex ;do nothing if bluetooth not activated
bsf wakesw ;ensure bluetooth is awake
bsf wakehw
bcf fbtrbt ;clear reboot flag for setup
bsf fwrcmd ;wait for "CMD"
bra ibtext ;with 200ms timeout
;-- State 1: begin setup, get, compare, and set feature string if necessary
btssu0 bbs fsrnsr,btssu01 ;gf data received (as non-standard response?)
btssu00 txpstr sbtgfs ;get feature settings string
movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
bsf fwrnsr ; wait for non-standard response
bra ibtex ; wait 200ms and don't advance
btssu01 rxpcstr sbtsfs ;expected value received?
skpnz
bra ibtns ;yes, advance to next state
bsf fbtrbt ;indicate a reboot is going to be required
txpstr sbtsfs ;send feature settings string
bra ibtexat ;and advance
;-- State 2: get, compare, and set friendly name if necessary
btssu1 bbs fsrnsr,btssu10 ;friendly name received (as non-standard response?)
txpstr sbtgfn ;get friendly name string
movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
bsf fwrnsr ; wait for non-standard response
bra ibtex ; wait 200ms and don't advance
btssu10 rxpcstr sbtsfn ;expected value received?
skpnz
bra ibtns ;yes, advance to next state
bsf fbtrbt ;indicate a reboot is going to be required
txpstr sbtsfn ;send new friendly name
bra ibtexat ;and advance
;-- State 3: get, compare, and set model if necessary
btssu2 bbs fsrnsr,btssu20 ;model received (as non-standard response?)
txpstr sbtgmod ;get friendly name string
movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
bsf fwrnsr ; wait for non-standard response
bra ibtex ; wait 200ms and don't advance
btssu20 rxpcstr sbtsmod ;expected value received?
skpnz
bra ibtns ;yes, advance to next state
bsf fbtrbt ;indicate a reboot is going to be required
txpstr sbtsmod ;send new friendly name
bra ibtexat ;and advance
;-- State 4: get, compare, and set msnufacturer's name if necessary
btssu3 bbs fsrnsr,btssu30 ;manufacturer's name received (as non-standard response?)
txpstr sbtgmn ;get manufacturer's name string
movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
bsf fwrnsr ; wait for non-standard response
bra ibtex ; wait 200ms and don't advance
btssu30 rxpcstr sbtsmn ;expected value received?
skpnz
bra ibtns ;yes, advance to next state
bsf fbtrbt ;indicate a reboot is going to be required
txpstr sbtsmn ;send new manufacturer's name
bra ibtexat ;and advance
;-- State 5: get, compare, and set bitmap services if necessary
btssu4 bbs fsrnsr,btssu40 ;bitmap services received (as non-standard response?)
txpstr sbtgbms ;get bitmap services string
movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
bsf fwrnsr ; wait for non-standard response
bra ibtex ; wait 200ms and don't advance
btssu40 rxpcstr sbtsbms ;expected value received?
skpnz
bra ibtns ;yes, advance to next state
bsf fbtrbt ;indicate a reboot is going to be required
txpstr sbtsbms ;send new bitmap services
bra ibtexat ;and advance
;-- State 6: send LS command to confirm private characteristics set up properly
btssu5 clrf bthctr,1 ;clear handle counter for later
txpstr sbtls ;send ls
bsf fwrnsr ;wait for non-standard response
bsf fwrend ;allow an END if nothing in the list
bra ibtext ;and await response
;-- State 7: check if the private service is defined
btssu6 bbs fsrend,btrbt ;if END received, list is empty, reset and reboot
rxpcstr sbtsps ;expected value received?
bz btssu60 ;yes, set up for private characteristics
movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
bsf fwrnsr ;wait for non-standard response
bsf fwrend ;allow an END if nothing in the list
bra ibtex ;await response and return here
btssu60 bsf fwrnsr ;wait for non-standard response
bsf fwrend ;allow an END if nothing in the list
bra ibtext ;and await response
;-- State 8: iterate to check UUID for each private characteristic -- capture handle if exists
btssu7 bbs fsrend,btssu70 ;if END received, ensure we got all characteristics
movfwb bthctr ;have we exhausted the number of characteristics?
xorlw cnumcar ;compare
bz btssu71 ;yes. Should have been END. Scan to END, reset and reboot.
movlf tblptrl,low sbtsc1 ;tblptr->first characteristic setup string
movlf tblptrh,high sbtsc1
movlw 44 ;43 bytes per private service string
mulwf bthctr,1 ;prod = index into list of strings
movfw prodl ;set tblptr->correct characteristic string
addwf tblptrl,f
clrw
addwfc tblptrh,f
bsf fbtcaph ;indicate we want private characteristic handle captured
call _rxpcstr ;compare string & capture handle
bnz btssu71 ;no, string not matched. Scan to end, reboot and reset
incf bthctr,f,1 ;bump counter for next private characteristic
bsf fwrnsr ;wait for non-standard response
bsf fwrend ;allow an END if nothing in the list
movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
bra ibtex ;come back to this state with response
; END received -- ensure we captured [cnumcar] characteristics
btssu70 movfwb bthctr ;have we exhausted the number of characteristics?
xorlw cnumcar ;compare
bnz btrbt ;no. Should have been END. Reset and reboot.
movlfb btstate,cbtsrbt ;all good, but reboot if necessary
bra ibtex
; No match. Scan to END, reboot and reset
btssu71 bsf fwrnsr ;wait for non-standard response
bsf fwrend ;wait for END if nothing in the list
bra ibtext ;and await response
;-- State 9: scan for END, reboot and reset
btssu8 bbs fsrend,btrbt ;reset and reboot if END received
bsf fwrnsr ;otherwise, wait for non-standard response
bsf fwrend ;wait for END if nothing in the list
movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
bra ibtex ;come back to this state with response
;-- State 10: start reset/reboot process if necessary -- clear all private services
btssu9 bbs fbtrbt,btssu90 ;reboot necessary?
movlfb btstate,cbtsadv ;no, start advertising
bra ibtex
btrbt movlfb btstate,cbtsrbt ;jump in here. Set to this state.
btssu90 bcf fbtrbt ;clear reboot flag for next pass
txpstr sbtcps ;clear any existing private services/characteristics
bra ibtexat ;and advance
;-- State 11: add private services
btssuA clrf bthctr,1 ;preclear handle counter to index private characteristics
txpstr sbtsps ;add private servcie
bra ibtexat ;and advance
;-- State 12: iteratively add private characteristics, then, reboot
btssuB movfwb bthctr ;have we exhausted the number of characteristics?
xorlw cnumcar ;compare
bz btssuB0 ;do actual reboot
movlf tblptrl,low sbtsc1 ;tblptr->first characteristic setup string
movlf tblptrh,high sbtsc1
movlw 44 ;43 bytes per private service string
;including stupid assembler padding 0
mulwf bthctr,1 ;prod = index into list of strings
movfw prodl ;set tblptr->correct characteristic string
addwf tblptrl,f
clrw
addwfc tblptrh,f
incf bthctr,f,1 ;index to next characteristic
call _txpstr ;transmit string
bsf FWRAOK ;wait for 'AOK'
movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
bra ibtex ;and return to this state
;all characteristics set. Reboot
btssuB0 txpstr sbtres ;send reset
bsf fwrrbt ;wait for 'Reboot'
bra ibtext
;-- State 13: wait up to 3,200 ms for reboot sequence -- then go do LS all over again to load handles
btssuC bsf fwrzcmd ;wait for '\0CMD'
movlfb btstate,cbtsls ;set up LS as next state
movlfb btstime,clctim(t16ms,3212) ;up to 3212ms allowed for response
bra ibtex
;-- State 14: start advertisement
btsadv txpstr sbtadv ;send start advertisement
bra ibtexae ;and allow ERR in case already advertising
;-- State 15: idle as connected/disconnect -- monitor fbton in case bluetooth is to shut down
btsid1 bbc fbton,btsid11 ;bluetooth needs to turn off?
bbs FSRCEND,btsid10 ;disconnect received?
bsf FWRCON ;allow connection response
bsf FWRCEND ;allow connection end response
bsf FWRNSR ;allow non-standard for notifications
bra ibtex ;and come right back next pass
;disconnect received -- start advertising again for seamless reconnect
btsid10 txpstr sbtadv ;send start advertisement
bsf FWRAOK ;allow ok
bsf FWRERR ;or error
movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
bra ibtex ;and return to this state
;shut down gracefully -- kill any existing connections
btsid11 txpstr sbtkill ;send kill command
bra ibtexae ;allow ERR if not connected
;-- State 16: put bluetooth into dormant mode
btssd0 txpstr sbtdorm ;send dormant command
bra ibtexat ;wait for aok
;-- State 17: shutdown bluetooth
btssd1 bcf wakesw ;turn off bluetooth uart transmitter
bsf FWREND ;end message will be response
bra ibtext ;
;-- State 18: complete shutdown -- pull wakehw low
btssd2 bcf wakehw ;pull line low
movlfb btstate,cbtsid ;set up idle0 as next state
bra ibtex ;no messages expected
;****** END OF STATE MACHINE STATES ******
;set up next state with AOK/ERR response and 200ms timeout
ibtexae bsf FWRERR ;wait for 'ERR'
;set up next state with AOK response and 200ms timeout
ibtexat bsf FWRAOK ;wait for 'AOK'
;set up next state with 200 ms timeout
ibtext movlfb btstime,clctim(t16ms,213) ;up to 213ms allowed for response
;set up next state
ibtns incf btstate,f,1 ;and skip to next state on completion
;restore BSR and quit till next pass
ibtex movlb 0
return
;*****************************************
;** BTPRCV -- Process Bluetooth receiver**
;** return z if no response **
;*****************************************
btprcv movlf fsr1h,high btrcvbuff ;point to receiver buffer
movff btrhead,fsr1l ; and index to next character
btplp rcall rxbyte ;receiver byte available?
retz ; z if none
movwf indf1 ;save character at current position
movlw '\r' ;ignore return characters
cpfseq indf1
movf postinc1,w ;get back in w, and update pointer
movff fsr1l,btrhead ;save new head position
xorlw '\n' ;new character a line feed?
bnz btplp ;no, get some more characters, if available
movlfb btrhead,low btrcvbuff ;reset btrhead for next message
;parse for common messages
;if common response not matched, indicate (likely) parameters returned from RN4020
bsf btsresp,0,1 ;set 1st bit in standard response flags
movdf tblptr,btsmes ;tblptr -> possible standard responses (\n separated, \r terminated)
btplp0 lfsr 0,btrcvbuff ;fsr0 -> point to head of response buffer
btplp1 tblrd *+ ;get next character from list of responses
movlw '\r' ;\r is response list terminating character
xorwf tablat,w ; end of response list?
bz btpnmf ;yes, no response matched
movf tablat,w ;get character
cpfseq postinc0 ;test against charcter in response buffer
bra btpnom ;!= means no match, skip to next response
movlw '\n' ;is it a new line character?
xorwf tablat,w
bz btpmat ;yes, we have found a match
bra btplp1 ;keep testing characters till match
;no match of current response, skip ahead till /n or /r
btpnom clrc ;roll to next response
rlcf btsresp,f,1
rlcf btsresp+1,f,1
btplp2 tblrd *+ ;get next character from list of responses
movlw '\r' ;get terminating character
xorwf tablat,w ; end of response list?
bz btpnmf ;yes, no response matched
movlw '\n' ;is it a new line character?
xorwf tablat,w
bnz btplp2 ;loop till \0 or \n
bra btplp0 ;and test against next response
;match found, response bit set
btpmat
;match not found, non-standard response bit set
btpnmf clrz ;nz indicates a new reponse has been received
return
;********************************************
;** BTPNSR -- Parse Non-Standard Responses **
;********************************************
btpnsr clrf bitcnt ;use bitcnt as index to received response
movdf tblptr,btnsmes ;tblptr -> possible non-standard responses (\n separated, \0 terminated)
btpnlp0 lfsr 0,btrcvbuff ;fsr0 -> point to head of response buffer
btpnlp1 tblrd *+ ;get next character from list of responses
movf tablat,w ;get character from list
bz btpnnf ;z=end of list, not found
movlw '\n' ;== \n means we have a match!
xorwf tablat,w
bz btpnm ;go process for arguments
movf tablat,w ;get character from list
cpfseq postinc0 ;compare with received
bra btpnnm ;no match, skip to next response
bra btpnlp1 ;continue till match/no match
;no match of current response, skip ahead till /0 or /n
btpnnm incf bitcnt,f ;update response counter
btpnlp2 tblrd *+ ;get next character from list of responses
movf tablat,w ;get character
bz btpnnf ;z=end of list -- no match
xorlw '\n' ;is it a new line character?
bnz btpnlp2 ;loop till \0 or \n
bra btpnlp0 ;and test against next non-standard response
;no match found - what do we do?
btpnnf bsf fwrnsrx ;indicate non-standard response not processed
return ;for now, just ignore the response
;match found -- bit count has response number
btpnm movfw bitcnt ;get response number
call cjump ;and process it
bra btnscp ;'ConnParam:'
bra btnsnfy ;'Notify,'
bra btnsind ;'Indicate,'
bra btnswv ;'WV,'
bra btnswc ;'WC,'
bra btnsrv ;'RV,'
;ConnParam <hex16>,<hex16>,<hex16> (connection interval, slave latency, supervison timeout)
btnscp lfsr 1,conint+1 ;point to holders
rcall hex2bin ;capture interval
rcall hex2bin ;capture slave latency
rcall hex2bin ;capture supervision timeout
return
;other non-standard responses -- for later -- just indicate unhandled for now
;notification received
btnsnfy ;'Notify,'
;indication received
btnsind ;'Indicate,'
;write value to local server characteristic
btnswv ;'WV,'
;write configuration to local server characteristic
btnswc ;'WC,'
;real time read (bit must be set in supported features (SR)
btnsrv ;'RV,'
bra btpnnf ;indicate unhandled non-standard response
;**************************************************************
;** HEX2BIN -- Convert arbitrary length hex to binary **
;** store result at fsr1 -> RAM (high byte) **
;** ignore spaces, comma or \n terminated **
;** target RAM must be large enough to hold expected value **
;**************************************************************
hex2bin
;process high byte first
movf postinc0,w ;get next character
sublw '\n' ;is it a newline?
retz ;yes, we are done
addlw 22 ;is it a space?
bz hex2bin ;yes, ignore it
addlw 12 ;is it a comma?
retz ;yes, we are done
sublw -14 ;'A'-'F' = 7-12, '0'-'9' = -10 - -1
skpc ;correct for 0-9
addlw 7 ;'0'-'9' = -3 - 6
addlw 3 ;final result
swapf wreg,f ;swap for high byte
movwf indf1 ;and save
;then low byte (no need to check for terminators on odd characters)
h2b1 movlw 58
subwf postinc0,w ;'A'-'F' = 7 - 12, '0'-'9' = -10 - -1
skpc ;correct for 0-9
addlw 7 ;'0'-'9' = -3 - 6
addlw 3 ;final result
iorwf postdec1,f ;merge in
bra hex2bin ;do for all characters
;****************************************************************
;** RXPCSTR -- Compare received string with program memory **
;** program memory string terminated with \r **
;** tblptr -> string **
;** ignore leading characters in PM until first comma **
;** ignore leading spaces in RAM **
;** z if match, nz if no match **
;** if fbtcaph is set, handle for char #(bthctr) is captured **
;****************************************************************
_rxpcstr
lfsr 0,btrcvbuff ;point to bluetooth receive buffer
movlw ',' ;skip to character after first comma
rxpclp0 tblrd *+
cpfseq tablat
bra rxpclp0
rxpclp1 movlw ' ' ;ignore leading spaces in RAM
xorwf postinc0,w
bz rxpclp1
movf postdec0,w ;move pointer back to first non-space character
rxpclp2 tblrd *+ ;get character from program memory
movlw '\r' ;terminates with /r
xorwf tablat,w ;compare
retz ;return with z to indicate match
bbc fbtcaph,rxpcb0 ;capture handle flag set?
movlw ',' ;handle starts at first comma
xorwf indf0,w ;compare
skpnz
rcall rxpch ;go capture handle
rxpcb0 movf indf0,w
movfw tablat ;get pm character
xorwf postinc0,w ;compare with received character
bz rxpclp2 ;match, keep going
return ;return with no match
;capture handle at current ram position +1
rxpch bcf fbtcaph ;clear capture flag for any remaining commas
lfsr 1,hpchar1 ;fsr1->start of characteristic handle table
rlncf bthctr,w,1 ; *4 (size of handle)
rlncf wreg,w
addwf fsr1l,f ;fsr1->proper handle
movff preinc0,postinc1 ;copy 4 bytes
movff preinc0,postinc1
movff preinc0,postinc1
movff preinc0,postinc1
movf postinc0,f ;index to tailing comma
return ;and go finish scan
include "btstrings.asm" ;include command/response strings
#ifdef BLUETOOTH
;Bank 4 RAM (0x400-0x4ff 256 available) ;Bluetooth configuration only
cblock 0x400
;bluetooth processing registers
btflag0 ;bluetooth flags
btsresp:2 ;standard response flags
btswait:2 ;wait for a particular response
;bit 0 -- AOK
;bit 1 -- ERR
;bit 2 -- BONDED
;bit 3 -- SECURED
;bit 4 -- CONNECTION END
;bit 5 -- REBOOT
;bit 6 -- \0CMD
;bit 7 -- CONNECTED
;bit 8 -- NFail
;bit 9 -- END
;bit 10-- non-standard response
;bit 11--
;bit 12--
;bit 13--
;bit 14--
;bit 15--
btstime ;bluetooth state machine timer
btstate ;bluetooth state machine counter
btrhead ;bluetooth receiver head pointer
;non-standard response received values
; -- from ConnParam:
supto:2 ;supervision timeout
slatency:2 ;slave latency
conint:2 ;connection interval
; -- private characteristic handles from LS command
bthctr ;handle counter for parsing
hpchar1:4
hpchar2:4
hpchar3:4
hpchar4:4
hpchar5:4
endc
;Bank 5 RAM (0x500-0x5ff 256 available) ;Bluetooth configuration only
cblock 0x500
txbuff:256 ;EUSART transmit buffer (256 bytes)
endc
;Bank 6 RAM (0x600-0x6ff 256 available) ;Bluetooth configuration only
cblock 0x600
rxbuff:256 ;EUSART receive buffer (256 bytes)
endc
;Bank 7 RAM (0x700-0x7ff 256 available) ;Bluetooth configuration only
cblock 0x700
btrcvbuff:256 ;BT receiver buffer
endc
#endif
by Aaron Carman
by Jeff Child
by Jake Hertz
by Jake Hertz