'**************************************************************** '* Name : NRF24L01_18F13K22_TX.bas * '* Author : Barak Dar * '* Notice : Copyright (c) 2010 * '* : All Rights Reserved * '* Date : 7/28/2010 * '* Version : 1.0 * '* Notes : nRF24L01+ Primary RX test * '* : transmits segments of a string with a position * '* : pointer for the target array * '* : ShockBurst with ACK and Auto retransmit x 8 * '* : Displays the status TX_DS and MAX_RT * '* : 4 byte packets and 250kbs * '* : Xtal not Shared (nRF module) * '* : All running from 3.3V incl. LCD * '**************************************************************** Device 18F13K22 Xtal = 16 Config_Start FOSC = IRC ;Internal RC oscillator PLLEN = OFF ; PLL is under software control PCLKEN = On ; Primary clock enabled FCMEN = On ; Fail-Safe Clock Monitor disabled IESO = OFF ; Oscillator Switchover mode disabled PWRTEN = OFF ; PWRT disabled BOREN = OFF ; Brown-out Reset disabled in hardware and software BORV = 27 ; VBOR set to 2.2 V nominal WDTEN = OFF ; WDT is controlled by SWDTEN bit of the WDTCON register WDTPS = 128 ; 1:128 MCLRE = OFF ; RE3 input pin enabled; MCLR disabled HFOFST = On ; The system clock is held off until the HFINTOSC is stable. STVREN = On ; Stack full/underflow will cause Reset LVP = OFF ; Single-Supply ICSP disabled BBSIZ = OFF ; 1KW boot block size XINST = OFF ; Instruction set extension and Indexed Addressing mode disabled Config_End '---[LCD Declares]-------------------------- Declare LCD_Type 0 Declare LCD_DTPin PORTC.0 Declare LCD_ENPin PORTA.1 Declare LCD_RSPin PORTA.0 Declare LCD_Interface 4 Declare LCD_Lines 2 '---[Port Setup]---------------------------- PortSetUp: CM1CON0 = 0 ' disable compartor1 CM2CON0 = 0 ' disable compartor2 OSCCON = %01110010 ' IRCF<6:4> and SCS<1:0> => 16MHz internal osc ANSEL = 0 ' all digital ANSELH = 0 ' all digital TRISA = %00001100 ' RA2 input from IRQ, RA3 set for input from low count board switch TRISB = %00010000 ' portB RB6/SCL = 0 output ; RB4/SDI = 1 input TRISC = %00000000 ' portC '---[Weak Pullups Config]------------------- Pullup_Con: WPUA = %00000100 ' week pull-up on RA2 for IRQ (not mandatory if not using interrupt) WPUB = %00000000 ' no other week pull-up Symbol RABPU = INTCON2.7 ' PORTA/PORTB Pull-up Enable/disable RABPU = 0 ' allow weak pullup on portA/B '-----[NRF Interface setup]------------------ NRF_Interface: SSPCON1 = %00000001 ' configure SPI Master, FOSC/16 so SCL is 1MHz Symbol SSPEN = SSPCON1.5 ' SSP Enable bit Symbol CKP = SSPCON1.4 ' Clock Polarity Select Symbol SMP = SSPSTAT.7 ' Data input sample bit Symbol CKE = SSPSTAT.6 ' Clock Edge Select bit Symbol BF = SSPSTAT.0 ' buffer full status bit 1 = buffer full Symbol SSPIF = PIR1.3 ' interrupt flag - last bit set Symbol CSN = PORTC.6 ' "Chip Select Not" pin Symbol CE = PORTC.5 ' Controls Data transmit/receive Symbol IRQ = PORTA.2 ' IRQ can be used with INT2 on RA2 '---[Variables]----------------------------- Dim i As Byte ' loop index Dim j As Byte ' loop index Dim k As Byte ' loop index Dim TX_Status As Byte ' status byte Dim DataOut[20] As Byte ' general array Dim spi_array[20] As Byte ' SPI transmit array '---[nRF command set]------------------------ Symbol W_REGISTER = 0x20 ' Write Register command Symbol R_REGISTER = 0x00 ' Read Register command Symbol R_RX_PAYLOAD = 0x61 ' Read RX spi_array Symbol W_TX_PAYLOAD = 0xA0 ' Write TX spi_array Symbol FLUSH_TX = 0xE1 ' Flush TX FIFO Symbol FLUSH_RX = 0xE2 ' Flush RX FIFO Symbol REUSE_TX_PL = 0xE3 ' Reuse last sent spi_array Symbol R_RX_PL_WID = 0x60 ' read RX spi_array width for the top Rx spi_array in the FIFO Symbol W_ACK_PAYLOAD = 0xA8 ' RX mode: write spi_array to be transmitted with ACK packet mask for last 3 bits in range 000 - 101 Symbol W_TX_PAYLOAD_NOACK = 0xB0 ' Disable auto ACK on the specific packet Symbol NRF_NOP = 0xFF ' Reuse last sent spi_array Symbol NRF_ADDR = 0xCFE7E7CF ' Pipe's address (4 Byte) - fixed in code for the demo, read from EEPROM in application '***[Start here]**************************** TX_Boot: High CSN ' unselect NRF slave otherwise it will never work Low CE ' clear CE until we start working DelayMS 500 ' Wait to stabilize GoSub InitDOG162 ' intialize the LCD in 3.3V Print At 1,1, "PTX V.16" ' version number '---[intilaize the SPI]--------------------- SMP = 0 ' Data input sampled at middle of data output time CKE = 0 ' CPHA - transmit on rising edge idle to active CKP = 0 ' CPOL - idle state is low level SSPEN = 1 ' SSP Enable DelayMS 1000 ' so we can read the display Main: GoSub Init_PTX ' intialize TX mode ' ' Power up the nRF spi_array[0] = W_REGISTER ' CONFIG Register spi_array[1] = 0x4A ' PTX, PWR_UP, CRC 1 Byte, CRC enabled, MASK_MAX_RT, MASK_TX_DS intterupts reflected On IRQ j = 1 CSN = 0 GoSub SPI_Global CSN = 1 DelayUS 1500 ' Critical! min 1500uS Tpd2stby delay ' ' flush all FIFO slots spi_array[0] = FLUSH_TX j = 0 CSN = 0 GoSub SPI_Global CSN = 1 ' Str DataOut = "HELLO REMOTE", 0 ' load a string to array ' ' we will transmit 4 bytes per packet the first byte is a pointer to location ' in the array so if data is lost it can be reconstructed correctly ' then 3 bytes from the string ' k = 0 ' k is a pointer to position of data in receiver's array While 1 = 1 Cursor 2, k + 1 j = 4 ' index for SPI loop (5 bytes command + 4 data bytes) spi_array[0] = W_TX_PAYLOAD ' TX payload command spi_array[1] = k ' pointer to position in array For i = 0 To 2 ' 3 bytes of string data spi_array[i+2] = DataOut[k+i] ' load 3 charchters to SPI array Next CSN = 0 GoSub SPI_Global CSN = 1 High CE ' transmit the Slot in FIFO DelayUS 20 ' CE must be high for min 10uS Low CE ' While IRQ = 1 : Wend ' wait for TX_DS or MAX_RT intterupts ' read STATUS for Interrupt source spi_array[0] = R_REGISTER | 0x07 ' Read Register 0x07 => STATUS j = 0 CSN = 0 GoSub SPI_Global CSN = 1 TX_Status = (spi_array[0] >> 4) & 3 ' shift and mask only bits 5 and 4 Print At 2, 15, Hex2 TX_Status ' show intterupt source: 02 = TX_DS; 01 = MAX_RT DelayMS 2000 ' let us read the display Print At 2, 15, " " ' Clear Interrupts spi_array[0] = W_REGISTER | 0x07 ' W_REGISTER at address 0x07 => STATUS spi_array[1] = 0x70 ' Clear all Interrupts j = 1 CSN = 0 GoSub SPI_Global CSN = 1 Cursor 2, k + 1 For i = 0 To 2 Print DataOut[k+i] Next Print At 1,15, Dec2 k ' show us what we are sending DelayMS 1000 k = k + 3 ' pointer to next segment position If k > 9 Then DelayMS 500 k = 0 Cls Print "PTX_PAYLOAD: " EndIf Wend '---[SPI using global vars]------------------ SPI_Global: i = 0 Repeat SSPBUF = spi_array[i] ' put the output byte in the buffer While SSPIF = 0 : Wend ' wait for end of transaction SSPIF = 0 ' clear the SSP flag spi_array[i] = SSPBUF ' read the input buffer, the status is always in spi_array[0] Inc i Until i > j Return '---[Intialize nRF as TX]-------------------- Init_PTX: CE = 0 ' Clear CE so we can Write to NRF in Standby mode '---------------------------------------- 'REG 00 CONFIG CSN = 0 spi_array[0] = W_REGISTER ' W_REGISTER at address 0x00 => CONFIG spi_array[1] = 0x48 ' 01001000 PTX, PWR_Dn, CRC 1 byte, CRC enabled, MASK_MAX_RT, MASK_TX_DS intterupts reflected on IRQ j = 1 GoSub SPI_Global CSN = 1 '---------------------------------------- 'REG 01 EN_AA CSN = 0 spi_array[0] = W_REGISTER | 0x01 ' W_REGISTER At address 0x01 => EN_AA spi_array[1] = 0x01 ' Enable auto-ack on pipes 0 , TX mode j = 1 GoSub SPI_Global CSN = 1 '---------------------------------------- 'REG 03 SETUP AW CSN = 0 spi_array[0] = W_REGISTER | 0x03 ' W_REGISTER at address 0x03 => SETUP AW spi_array[1] = 0x02 ' Address width = 4 bytes j = 1 GoSub SPI_Global CSN = 1 '---------------------------------------- 'REG 04 SETUP PETR CSN = 0 spi_array[0] = W_REGISTER | 0x04 ' W_REGISTER at address 0x04 => SETUP PETR spi_array[1] = 0x33 ' 0x33 = auto retransmit 1000uS and 8 times. 0x00 = auto retransmit off j = 1 GoSub SPI_Global CSN = 1 '---------------------------------------- 'REG 05 RF_CH CSN = 0 spi_array[0] = W_REGISTER | 0x05 ' W_REGISTER at address 0x05 => RF_CH spi_array[1] = 0x02 ' set channel #2. For the application, make it selectable from E2PROM j = 1 GoSub SPI_Global CSN = 1 '---------------------------------------- 'REG 06 RF_SETUP CSN = 0 spi_array[0] = W_REGISTER | 0x06 ' W_REGISTER at address 0x06 => RF_SETUP spi_array[1] = 0x26 ' Data rate = 250kbps, RF_POWER 0dBm j = 1 GoSub SPI_Global CSN = 1 '---------------------------------------- 'REG 07 STATUS CSN = 0 spi_array[0] = W_REGISTER | 0x07 ' W_REGISTER at address 0x07 => STATUS spi_array[1] = 0x70 ' Clear RX_DR, TX_DS and MAX_RT Interrupts %01110000 j = 1 GoSub SPI_Global CSN = 1 '---------------------------------------- 'REG 10 TX_ADDR CSN = 0 spi_array[0] = W_REGISTER | 0x10 ' W_REGISTER at address 0x10 => TX_ADDR spi_array[1] = NRF_ADDR.Byte0 ' RX address byte 0 LSByte spi_array[2] = NRF_ADDR.Byte1 ' RX address byte 1 spi_array[3] = NRF_ADDR.Byte2 ' RX address byte 2 spi_array[4] = NRF_ADDR.Byte3 ' RX address byte 3 j = 4 GoSub SPI_Global CSN = 1 '---------------------------------------- 'REG 0A RX_ADDR_P0 (Only if ACK is to be received into pipe 0) CSN = 0 spi_array[0] = W_REGISTER | 0x0A ' W_REGISTER at address 0x0A => RX_ADDR_P0 spi_array[1] = NRF_ADDR.Byte0 ' RX address byte 0 LSByte spi_array[2] = NRF_ADDR.Byte1 ' RX address byte 1 spi_array[3] = NRF_ADDR.Byte2 ' RX address byte 2 spi_array[4] = NRF_ADDR.Byte3 ' RX address byte 3 j = 4 GoSub SPI_Global CSN = 1 '---------------------------------------- Return ' this part relates to a specific type of LCD '---[DOG162-4bit-3.3V initialization]-------- InitDOG162: Cls DelayMS 50 ' another delay For i = 0 To 8 j = CRead LCDInit + i ' load intialiazation command Print 0xFE, j ' send the command DelayUS 30 If i = 0x01 Then DelayMS 2 ' longer delay on Cls command Next DelayMS 100 Return '===[place at the end of the code]===================================== LCDInit: ' the command are per page 7 in the EADOGM162 @ 3.3V datasheet CData As Byte 0x29,_ ' Function set: 0x31 is for 1 line, 0x39 is for 2 lines, Instruction table 1 0x14,_ ' Bias set: 1/5, 2 line LCD 0x55,_ ' Power: booster On, contrast: clear C5, set C4 0x6D,_ ' Follower control 0x7C,_ ' Contrast 0x72 = 4 for FSTN, 0x7C is good for STN positive 0x28,_ ' Function Set: 0x28 for 2 lines 4bit 0x0F,_ ' display ON cursor ON, cursor blink 0x01,_ ' clear display cursor Home 0x06 ' cursor auto increment