nRF_CommandHandler

Purpose: Execute an nRF24L01+ command from MCU logic that could be entered as a text "N" script command from a command line.
Assumes:   All script text commands are supported; a command issued by a script might be already processing.
Passed: R27:R26   BYTE *   bptrCommand   pointer to the SRAM buffer containing the ASCIIz command text.
R25 BYTE bCmdCHAR3   third character in the SRAM buffer specifed, in UPPERCASE.
R24 BYTE bCmdCHAR2   second character in the SRAM buffer above, in UPPERCASE.
Returns: Nothing, specifically; it would vary by command.
Alters: Varies; assume R0, R18 through 27, R30, R31, the FLAGs (SREG)
Example:   Broadcast a time synchronization string as each MINUTE begins:
BroadcastTimeSync:
   MOVW    R30, R4                     ; Point 'Z' at this routine's structure
   LDD     R24, Z + 7                  ; Read the "spare" (8th) structure BYTE
   ANDI    R24, B00111111              ; Strip the BITs not needed for Minutes
   LDS     R25, bRTC_Minute            ; Retrieve the Real Time Clock's Minutes
   CP      R24, R25                    ; See if the Minutes value has changed
   BREQ    ALocal_Ret                  ; If not, we're done for now

   ANDI    R24, B11000000              ; Mask OFF the six (6) Minutes BITs
   OR      R24, R25                    ; Combine in the two (2) "other uses" BITs
   STD     Z + 7, R24                  ; Save the user BYTE back to the structure

   CALL    AStackAlloc50               ; Setup a small temporary buffer
   MOVW    R24, R30                    ; Copy destination = start of the SRAM
   ADIW    R24, 1                      ;  temporary buffer + 1
   LDI     R23, ACSZ_Start >> 8
   LDI     R22, ACSZ_Start & 0xFF      ; Point to the FLASH string to copy
   LDI     R21, 0
   LDI     R20, CSZ_End - CSZ_Start    ; R21:R20 = number of BYTEs to copy
   CALL    AmemcpyPGM                  ; memcpyPGM() alters R18, but not R31:R30
   MOVW    R18, R30                    ; Save the stack-based buffer pointer

   ADIW    R30, CSZ_End - CSZ_Start    ; Point 'Z' at the end of the string just
   LDI     R27, sWallClock >> 8        ;  copied and 'X' at the Real Time Clock
   LDI     R26, sWallClock & 0xFF      ;  structure in SRAM
   LDI     R25, ' '                    ; This is for the intercharacter space

Loop:
   ST      Z+, R25                     ; Enbuffer a space (' ') character
   LD      R24, X+                     ; Retrieve the next Real-Time Clock BYTE
   LDI     R23, 0                      ; Initialize the 10s counter to 0
   RCALL   AStoreDecimalValue          ; Call local subroutine to calc & store
   CPI     R26,  bRTC_Year & 0xFF      ; To send Seconds through Month
;  CPI     R26, (bRTC_Year & 0xFF) + 1 ; To send Seconds through Year
   BRLO    ALoop                       ; Loop all clock digits are placed

   LDI     R25, '''                    ; Store the trailing single quote, which
   ST      Z+, R25                     ;  is also the 3rd buffered BYTE
   ST      Z, R1                       ; Terminate the string with a NULL
   SUB     R30, R18
   SBC     R31, R19                    ; Determine the length of the string just
   SBIW    R30, 1                      ;  placed in the buffer

   MOVW    R26, R18                    ; Point 'X' at the start of the temporary
   ST      X+, R30                     ;  buffer and set its string length
   LDI     R24, ' '                    ; R24 now has the 2nd buffered BYTE
;  LDI     R25, '''                    ; R25 already has 3rd buffered BYTE
;     Use the command "R = 0x7A" beforehand to also see the stack-based buffer:
   CALL    ADumpRegisters              ; Enable this to see the parameters ...
   CALL    AnRF_CommandHandler         ; Send the command to the nRF24L01+
   CALL    AStackFree50                ; Delete the temp buffer & restore stack
Local_Ret: RET

TensLoop:
   SUBI    R24, 10                     ; Decrease R24, the data BYTE, by 10
   INC     R23                         ; Increment the 10s counter
StoreDecimalValue:         ; <-- Here is the entry point for this subroutine
   CPI     R24, 10                     ; If the value of R24 is 10 or greater,
   BRSH    ATensLoop                   ;  loop back to subtract (another?) ten
CheckTensDigit:
   CPI     R23, 0                      ; This suppresses any leading zeros
   BREQ    AStoreOnesDigit
   ORI     R23, '0'                    ; Convert ten's digit to ASCII
   ST      Z+, R23                     ; Store the ASCII tens digit
StoreOnesDigit:
   ORI     R24, '0'                    ; Convert one's digit to ASCII
   ST      Z+, R24                     ; Store the ASCIC ones digit
   RET

CSZ_Start: .STRING "N 'ES 0x1D8 ="     ; Could also be "N 'T =" ...
CSZ_End:   .BYTE 0
Test it:
>E   0x2D  = 0x30            ; Set EEbTaskList_UVIndex; start at uVars.B[ 48 ] = 0x2B0
>ESW 0x2B0 = 100 M 0x3900 0  ; Every 100 mSec, call task at 0x3900
>E      1 |= 0x80            ; Toggle multitasking ON (outputs on each new minute)
>nRF Tx [29, 0xB0]: 28, 80, 'ES 0x1D8 = 50 45 11 2 26 7'
nRF Tx [28, 0xB0]: 27, 81, 'ES 0x1D8 = 0 46 11 2 26 7'
nRF Tx [28, 0xB0]: 27, 82, 'ES 0x1D8 = 0 47 11 2 26 7'
nRF Tx [28, 0xB0]: 27, 83, 'ES 0x1D8 = 0 48 11 2 26 7'
nRF Tx [28, 0xB0]: 27, 84, 'ES 0x1D8 = 0 49 11 2 26 7'
nRF Tx [28, 0xB0]: 27, 85, 'ES 0x1D8 = 0 50 11 2 26 7'
nRF Tx [28, 0xB0]: 27, 86, 'ES 0x1D8 = 0 51 11 2 26 7'
nRF Tx [28, 0xB0]: 27, 87, 'ES 0x1D8 = 0 52 11 2 26 7'
nRF Tx [28, 0xB0]: 27, 88, 'ES 0x1D8 = 0 53 11 2 26 7'
nRF Tx [28, 0xB0]: 27, 89, 'ES 0x1D8 = 0 54 11 2 26 7'
nRF Tx [28, 0xB0]: 27, 90, 'ES 0x1D8 = 0 55 11 2 26 7'
nRF Tx [28, 0xB0]: 27, 91, 'ES 0x1D8 = 0 56 11 2 26 7'
E 1 ^= 0x80                  ; Toggle multitasking OFF
>                                                                                           
Notes: Refer to the multitasking page for more information about the mulitasking time structure. The user-configurable (spare) BYTE at its index 7 was used in the example above.
All nRF24L01+ Registers are 1-BYTE wide except REG_10_RX_ADDR_P0, REG_11_RX_ADDR_P1, and REG_16_TX_ADDR, which are each 5-BYTE wide Registers.
For more information about the nRF24L01+ radio microchip itself, please refer to the Nordic Semiconductor ® nRF24L01+ Product Specification, version 1.0, dated September, 2008.
Dropin: 
(setup
code)
;   Setup for the NRF_CommandHandler() call:
; Passed:  R27:R26 BYTE * bptrCommand pointer to the command buffer in SRAM
;              R25 CHAR   cCmdCHAR3   command string BYTE #3, in UPPERCASE
;              R24 CHAR   cCmdCHAR2   command CHAR #2 (after 'N'), in UPPERCASE
; Returns: Nothing in particular.
; Alters:  Varies; assume R0, R18 through R27, R30, R31, and the FLAGs
Also see:  The nRF_SPI_Command System Function and the Nordic nRF24L01+ radio script commands.