Microchip RN4020 Bluetooth LE

Thread Starter

joeyd999

Joined Jun 6, 2011
6,286
Setting the RX pin of the RN4020 was only half the picture. This only got me into deep sleep, not dormant. To go dormant is a lot more complicated and completely undocumented.

In any case, I figured it out. Looking at the code, it looks easy now. But, trust me, it's not. And this is the reason why those on that other board still couldn't get it to work even after being told how to do so. I feel great sympathy for anyone who tries to tackle this who doesn't also enjoy complicated puzzles -- it's obvious from discussions I've read that many have given up on this chip for this very reason. Too bad, because now that I've got it working, it's actually quite a swell part. And I'll never have to write the code again!

The process to go dormant begins at line 415 with the label btsac03.

Here's the code now as it stands. I've put aside data transception until tomorrow. I really wanted to get this power issue put to bed first. Oh, and I've cleaned up quite a bit of the code. Much nicer to read now (though the default tab settings make it a horror!). Enjoy.

Code:
;**************************************
;** 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

    movlw    b'01111111'        ;ignore NWR flag
    andwf    btswait+1,w,1
    iorwf    btswait,w,1        ;are we waiting for a particular response?
    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    bbs    FWRNWR,pbstate        ;improper responses don't throw errors if NWR bit set

    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    btx____            ;no further processing if timer not expired

    movlw    b'01111111'        ;ignore NWR flag
    andwf    btswait+1,w,1
    iorwf    btswait,w,1        ;are we waiting for a particular response?
    bz    pbstate            ;no, just process timed state after delay

;otherwise, flag a timeout error

    bra    pbtrto            ;show timeout error

;not a timed function

pbtntim    bbs    fwrnwr,pbstate        ;don't wait for response if bit is set

    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    btx____            ;otherwise, just wait until response
 
;Handle improper response

pbtimp    btfsc    fsrnsr            ;non-standard response?
    rcall    btpnsr            ;go parse it

    bra    btx____            ;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    btx____            ;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    btx____            ;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
    bra    btsadv            ;state 14:  start advertising

;active with bluetooth on

    bra    btsac0            ;state 15:  idle for connects/disconnects and monitor monitor for shutdown

;shudown bluetooth

    bra    btssd0            ;state 16:  switch to dormant mode
    bra    btssd1            ;state 17:  clear wakesw and shutdown EUSART

;***********************
;** Bluetooth states  **
;***********************

;-- State 0:  wake BT, await BTAWAKE hardware line, then wait for CMD message

btsid0    bbc    fbton,btx____            ;do nothing if bluetooth not activated

    call    uarton                ;turn eusart on

    bsf    wakesw                ;wake bluetooth
    bsf    wakehw 

    bcf    fbtrbt                ;clear reboot flag for setup

    bsf    fwrcmd                ;wait for "CMD"
    bra    btx__LN                ;with a long 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
    bsf    fwrnsr                ;  wait for non-standard response
    bra    btx__T_                ;  wait 200ms and don't advance

btssu01    rxpcstr    sbtsfs                ;expected value received?
    skpnz
    bra    btx___N                ;yes, advance to next state

    bsf    fbtrbt                ;indicate a reboot is going to be required
    txpstr    sbtsfs                ;send feature settings string
    bra    btx_ATN                ;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
    bra    btx__TR                ;  wait 200ms for NSR and don't advance

btssu10    rxpcstr    sbtsfn                ;expected value received?
    skpnz
    bra    btx___N                ;yes, advance to next state

    bsf    fbtrbt                ;indicate a reboot is going to be required
    txpstr    sbtsfn                ;send new friendly name
    bra    btx_ATN                ;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
    bra    btx__TR                ;  wait 200ms for NSR and don't advance

btssu20    rxpcstr    sbtsmod                ;expected value received?
    skpnz
    bra    btx___N                ;yes, advance to next state

    bsf    fbtrbt                ;indicate a reboot is going to be required
    txpstr    sbtsmod                ;send new friendly name
    bra    btx_ATN                ;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
    bra    btx__TR                ;  wait 200ms for NSR and don't advance

btssu30    rxpcstr    sbtsmn                ;expected value received?
    skpnz
    bra    btx___N                ;yes, advance to next state

    bsf    fbtrbt                ;indicate a reboot is going to be required
    txpstr    sbtsmn                ;send new manufacturer's name
    bra    btx_ATN                ;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
    bra    btx__TR                ;  wait 200ms for NSR and don't advance

btssu40    rxpcstr    sbtsbms                ;expected value received?
    skpnz
    bra    btx___N                ;yes, advance to next state

    bsf    fbtrbt                ;indicate a reboot is going to be required
    txpstr    sbtsbms                ;send new bitmap services
    bra    btx_ATN                ;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    btx__TN                ;and advance

;-- 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

    bsf    fwrend                ;allow an END if nothing in the list
    bra    btx__TR                ;await response for END/NSR and return here

btssu60    bsf    fwrnsr                ;wait for non-standard response
    bsf    fwrend                ;allow an END if nothing in the list
    bra    btx__TN                ;and advance
 
;-- 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    fwrend                ;allow an END if nothing in the list
    bra    btx__TR                ;come back to this state with NSR/END 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    btx____

;  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    btx__TN                ;and advance

;-- State 9: scan for END, reboot and reset

btssu8    bbs    fsrend,btrbt            ;reset and reboot if END received

    bsf    fwrend                ;wait for END if nothing in the list
    bra    btx__TR                ;come back to this state with NSR/END 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    btx____

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    btx_ATN                ;and advance

;-- State 11: add private services

btssuA    clrf    bthctr,1            ;preclear handle counter to index private characteristics

    txpstr    sbtsps                ;add private servcie
    bra    btx_ATN                ;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
    bra    btx_AT_                ;AOK and return here

;all characteristics set.  Reboot
 
btssuB0    txpstr    sbtres                ;send reset
    bsf    fwrrbt                ;wait for 'Reboot'
    bra    btx__TN

;-- 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
    bra    btx__L_                ;long timeout for reset

;-- State 14: start advertisement

btsadv    txpstr    sbtadv                ;send start advertisement
    bra    btxEATN                ;  AOK Expected (Error if already advertising)

;-- State 15: active as connected/disconnecedt -- monitor fbton in case bluetooth is to shut down
;             and process all characteristic writes,reads,and requests from central device

btsac0    bbs    FSRCON,btsac00            ;connect received?
    bbs    FSRCEND,btsac02            ;disconnect received? 
    bbc    fbton,btsac03            ;bluetooth needs to turn off?

    bra    btsac01

;connect received

btsac00    bsf    fbtconn                ;indicate connection

;quit and come back

btsac01    bsf    FWRCON                ;allow connection response
    bsf    FWRCEND                ;allow connection end response
    bsf    FWRNSR                ;allow non-standard for notifications
    bsf    FWRNWR                ;don't wait for a response

    bra    btx____                ;and come right back next pass

;disconnect received -- start advertising again for seamless reconnect

btsac02    bcf    fbtconn                ;indicate connection lost

    txpstr    sbtadv                ;send start advertisement
    bra    btx_AT_                ;wait for AOK

;shut down gracefully -- stop advertising or kill a connection

btsac03    bbs    fbtconn,btsac04            ;connected?

;stop advertising

    txpstr    sbtkadv                ;no, send stop advertise command
    bra    btxEATN                ;and advance (allow error, but shouldn't happen)

btsac04    bcf    fbtconn                ;killing connection, so clear it

    txpstr    sbtkill                ;send kill command
    bsf    FWRCEND                ;wait for Connection End
    bra    btxE_TN                ;wait for connection end, but allow for error JIC

;-- State 16:  put bluetooth into dormant mode

btssd0    bcf    wakehw                ;pull line low
    txpstr    sbtdorm                ;send dormant command
    bra    btx__TN                ;result will be 0x00, which we cannot parse, so just time it

;-- State 17: shutdown bluetooth and EUSART

btssd1    call    uartoff                ;turn eusart off
    bcf    wakesw                ;turn off bluetooth uart transmitter
    movlfb    btstate,cbtsid            ;set up idle0 as next state
    bra    btx____                ;and immediate idle

;***** END OF STATES *********

;**** Various Exits of SM to set up next state, timeouts, and responses ****
;     E=ERR A=AOK T=short timeout L=long timeout N=advance to next state R=Allow non-standard response

btxE_TN    movlfb    btstime,cbtsto            ;STO/ERR/NEXT
btxE__N    bsf    FWRERR                ;ERR/NEXT
    bra    btx___N

btxEATN    bsf    FWRERR                ;ERR/AOK/STO/NEXT
btx_ATN    bsf    FWRAOK                ;AOK/STO/NEXT
btx__TN    movlfb    btstime,cbtsto            ;STO/NEXT
btx___N    incf    btstate,f,1            ;NEXT
    bra    btx____

btx__TR    bsf    FWRNSR                ;STO/NSR
    bra    btx__T_

btxEAT_ bsf    FWRERR                ;ERR/AOK/STO
btx_AT_ bsf    FWRAOK                ;AOK/STO
btx__T_    movlfb    btstime,cbtsto
    bra    btx____

btx__LN    incf    btstate,f,1            ;LTO/NEXT     
btx__L_    movlfb    btstime,cbtslo            ;LTO
btx____    movlb    0                ;nothing
    return

;**** END OF SM EXITS ****


;*****************************************
;** 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    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 "btcb.asm"        ;include custom callbacks to main program
    include    "btstrings.asm"        ;include command/response strings
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,286
This is a battery operated device. Here are the measured currents in various modes in the order I recorded them:

Upon inserting the battery: 54 uA
Power on, Bluetooth off: 15.9 mA
Power on, Bluetooth on, advertising: 18.3 mA
Power on, Bluetooth on, connected: 18.1 mA
Power on, Bluetooth on, disconnected, advertising: 18.3 mA
Power on, Bluetooth off: 15.9 mA
Power off: 54 uA.

Cool.
 

cmartinez

Joined Jan 17, 2007
8,762
This is a battery operated device. Here are the measured currents in various modes in the order I recorded them:

Upon inserting the battery: 54 uA
Power on, Bluetooth off: 15.9 mA
Power on, Bluetooth on, advertising: 18.3 mA
Power on, Bluetooth on, connected: 18.1 mA
Power on, Bluetooth on, disconnected, advertising: 18.3 mA
Power on, Bluetooth off: 15.9 mA
Power off: 54 uA.

Cool.
What size of battery will your device be using?
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,286
What size of battery will your device be using?
The answer is irrelevant, considering this thread is about the RN4020 and not my product.

What's important is that the RN4020 consumes a bit more than 2mA when active, and less than 1uA in dormant mode. The larger numbers you see are the combination of the RN4020 and my product's base current requirements.
 

cmartinez

Joined Jan 17, 2007
8,762
The answer is irrelevant, considering this thread is about the RN4020 and not my product.

What's important is that the RN4020 consumes a bit more than 2mA when active, and less than 1uA in dormant mode. The larger numbers you see are the combination of the RN4020 and my product's base current requirements.
Maybe I should've stated my question as follows:

Is your device consuming power,
  • A) Less than expected
  • B) Just as expected
  • C) More than expected
And perhaps: D) Much more, or much less.

Edit: I've got a feeling the answer will be B ;)
 

NorthGuy

Joined Jun 28, 2014
611
Setting the RX pin of the RN4020 was only half the picture. This only got me into deep sleep, not dormant.
It may still be listening to UART. The doc says it'll respond to UART in deep sleep mode if baud rate is 2400, but it doesn't say what happens at other baud rates. If UART is still on, then when you drop your TX low, RN4020 sees it as a start bit. So it just immediately wakes up.

Keeping TX high may not be necessary once you get into true 'dormant' mode.

To go dormant is a lot more complicated and completely undocumented.
The docs for RN4020 are really bad in this respect. They say very little, and what they do say is confusing. Congratulations on figuring that out!

RN4020 must be PIC based, so you always can re-program it for the better ;)
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,286
how many hours did you put into this project?
Quite a few, though I don't count them. I did work solid through the memorial day weekend -- like 6AM through midnight each day.

Coding *definitely* is not the majority of the time. The biggest time sink was the bad documentation for the RN4020. And I do lots and lots of testing of small bits of code. The code has to be absolutely robust, so I do only small amounts between tests to be sure that *every possible* contingency is covered.

The good news is, I will never, ever, have to write any of this code ever again.

Time only matters when your doing something you don't like.
Exactly.
 

cmartinez

Joined Jan 17, 2007
8,762
Coding *definitely* is not the majority of the time. The biggest time sink was the bad documentation for the RN4020. And I do lots and lots of testing of small bits of code. The code has to be absolutely robust, so I do only small amounts between tests to be sure that *every possible* contingency is covered.
And what was the proportional amount of work between coding and designing the electronic hardware/interface?
Hope you don't mind so many questions, I'm just curious.
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,286
And what was the proportional amount of work between coding and designing the electronic hardware/interface?
This is a drop-in addition to an existing product. There was no actual design time. But I did have to sticky-tape the the RN4020 to the existing PCB and run some wires between the MCU and the RN4020. The MCU is an 80 pin PLCC -- so the (wirewrap) wires had to be soldered under a microscope. About an hour of time for the total (prototype) assembly. For production, I'll have a new PCB with the RN4020 footprints, obviously.
 

cmartinez

Joined Jan 17, 2007
8,762
For production, I'll have a new PCB with the RN4020 footprints, obviously.
And you'll be in charge of designing that too? And since it's an addition for an existing product, will it affect its casing/container ... I am guessing that after some point another department will be taking care of that, right?
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,286
And you'll be in charge of designing that too? And since it's an addition for an existing product, will it affect its casing/container ... I am guessing that after some point another department will be taking care of that, right?
I just change hats and hang a different sign on my door.
 

cmartinez

Joined Jan 17, 2007
8,762
I just change hats and hang a different sign on my door.
Well congrats, man. It's not everyday that one gets to accomplish something of this level. From what you've described, this qualifies as a milestone in your professional (and possibly also personal) life. Thanks for sharing.
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,286
Well congrats, man. It's not everyday that one gets to accomplish something of this level. From what you've described, this qualifies as a milestone in your professional (and possibly also personal) life.
I say this ever so humbly: I accomplish this, and more, every day of my life. I've said here once before: I do at least three impossible things every day. But the feeling of accomplishment never get old. And the harder the effort, the better it feels at the end.

I seriously love stuff like this.
 
Top