nrf24l01.c

Go to the documentation of this file.
00001 /*
00002  * File:        nrf24l01.c
00003  * Purpose:     nRF24L01 handler functions
00004  * Author:      Peter Ivanov, Olimex Ltd.
00005  * Modified by:
00006  * Created:     2007-10-14 11:29:32
00007  * Last modify: 2007-10-21 11:50:26 ivanovp {Time-stamp}
00008  * Copyright:   (C) Peter Ivanov, 2007
00009  * Licence:     GPL
00010  */
00019 #include <msp430xG461x.h>
00020 #include "nrf24l01.h"
00021 #include "time.h"
00022 #include "lcd.h"
00023 
00024 #define CSN_TIME      2
00025 #define CE_HIGH_TIME  10000
00026 
00028 unsigned char RX_ADDRESS_P0[5]  = {5,6,7,8,9};
00030 unsigned char RX_ADDRESS_P1[5]  = {0,1,2,3,4};
00032 unsigned char TX_ADDRESS[5]     = {5,6,7,8,9};
00033 unsigned char ADDRESS[5];
00034 
00035 unsigned char status;
00036 
00042 void Delay (unsigned long a)
00043 { 
00044     while (--a != 0); 
00045 }
00046 
00050 inline void CSN_HIGH (void)
00051 {
00052     P8OUT |= BIT3; // P8.3 HIGH
00053 }
00054 
00058 void CSN_LOW (void)
00059 { 
00060     Delay (CSN_TIME);
00061     P8OUT &= ~BIT3; // P8.3 LOW
00062 }
00063 
00067 void CE_HIGH(void)
00068 { 
00069     P8OUT |= BIT4; // P8.4 HIGH
00070     Delay (CE_HIGH_TIME); 
00071 }
00072 
00076 inline void CE_LOW(void)
00077 {
00078     P8OUT &= ~BIT4; // P8.4 LOW
00079 }
00080 
00087 unsigned char SPI_SendByte(unsigned char data)
00088 {
00089     while ((IFG2 & UCA0TXIFG) == 0);    // wait while not ready / for RX
00090     UCA0TXBUF = data;                   // write
00091     while ((IFG2 & UCA0RXIFG) == 0);    // wait for RX buffer (full)
00092     return (UCA0RXBUF);
00093 }
00094 
00103 unsigned char SPI_Send_command_with_ADDR (unsigned char cmd, unsigned char addr, unsigned char data_byte)
00104 {
00105     unsigned char temp,command = 0;
00106     int j, k;
00107     command = (cmd << 5) | addr;
00108     CSN_LOW();
00109     if (cmd == R_REGISTER)
00110     {
00111         if (addr == RX_ADDR_P0 || addr == RX_ADDR_P1 || addr == TX_ADDR)
00112         {
00113 
00114             status = SPI_SendByte(command);
00115             for (k = 0; k < 5; k++)
00116             {
00117                 ADDRESS[k] = SPI_SendByte(NRF_NOP);
00118             }
00119             CSN_HIGH();
00120             return status;
00121         }
00122         else
00123         {
00124             status = SPI_SendByte(command);
00125             temp = SPI_SendByte(NRF_NOP);
00126             CSN_HIGH();
00127             return temp;
00128         }
00129     }
00130     if (cmd == W_REGISTER)
00131     {
00132         if (addr == RX_ADDR_P0)
00133         {
00134             status = SPI_SendByte(command);
00135             for (j = 0; j < 5; j++)
00136             {
00137                 temp = RX_ADDRESS_P0[j];
00138                 SPI_SendByte(temp);
00139             }
00140             CSN_HIGH();
00141             return status;
00142         }
00143 
00144         if (addr == RX_ADDR_P1)
00145         {
00146             status = SPI_SendByte(command);
00147             for (j = 0; j < 5;j++)
00148             {
00149                 temp = RX_ADDRESS_P1[j];
00150                 SPI_SendByte(temp);
00151             }
00152             CSN_HIGH();
00153             return status;
00154         }
00155 
00156         if (addr == TX_ADDR)
00157         {
00158             status = SPI_SendByte(command);
00159             for (j = 0; j < 5;j++)
00160             {
00161                 temp = TX_ADDRESS[j];
00162                 SPI_SendByte(temp);
00163             }
00164             CSN_HIGH();
00165             return status;
00166         }
00167         else
00168         {
00169             temp = SPI_SendByte(command);
00170             SPI_SendByte(data_byte);
00171             CSN_HIGH();
00172             return temp;
00173         }
00174     }
00175 
00176     return 1;
00177 }
00178 
00179 unsigned char SPI_Send_command_without_ADDR (unsigned char cmd, unsigned char data_byte)
00180 {
00181     unsigned char temp = 0;
00182     CSN_LOW();
00183     if (cmd == R_RX_PAYLOAD)
00184     {
00185         status = SPI_SendByte(cmd);
00186         temp = SPI_SendByte(NRF_NOP);
00187         CSN_HIGH();
00188         return temp;
00189     }
00190     if (cmd == W_TX_PAYLOAD)
00191     {
00192         status = SPI_SendByte(cmd);
00193         SPI_SendByte(data_byte);
00194         CSN_HIGH();
00195         return status;
00196     }
00197     status = SPI_SendByte(cmd);
00198     CSN_HIGH();
00199     return status;
00200 
00201 }
00202 
00203 // Setting for nRF chip
00204 void NRF_init (void)
00205 {
00207     // Initialize SPI interface
00209     // master mode, data valid on rising edge, msb first
00210     UCA0CTL0 = UCCKPH + UCMST + UCMSB + UCSYNC;
00211 
00212     // clock -> SMCLK
00213     UCA0CTL1 = UCSSEL1;
00214 
00215     // Baud Rate
00216     UCA0BR0 = 0x02;
00217     UCA0BR1 = 0x00;
00218     
00219     //UCA0MCTL = 0x00;
00220 
00221     P7SEL |= BIT1 | BIT2 | BIT3;    // P7.1-3 SPI option select
00222     P7DIR |= BIT1 | BIT3;           // P7.1 (MOSI) and P7.3 (CLK) are outputs
00223     P7DIR &= ~BIT2;                 // P7.2 (MISO) is input
00224     P8DIR |= BIT3 | BIT4;           // P8.3 (#CS) and P8.4 (CE) are outputs
00225     P8DIR &= ~BIT5;                 // P8.5 (IRQ) is input
00226 
00227     // Disable CS
00228     CSN_HIGH();
00229 
00231     // Configure chip nRF24L01
00233 
00234     // Discard transmission
00235     CE_LOW();
00236 
00237     //Write CONFIG register (addres - 0x00)
00238     //00001010 - CRC enable, power-up, RX
00239     status = SPI_Send_command_with_ADDR(W_REGISTER, CONFIG_REG_ADDR, 0x0B);
00240     //Write RX_ADDR_P0 register -> Set receive address data Pipe0 -> address in RX_ADDRESS_P0 array
00241     status = SPI_Send_command_with_ADDR(W_REGISTER, RX_ADDR_P0, NRF_NOP);
00242     //Write RX_ADDR_P1 register -> Set receive address data Pipe1 -> address in RX_ADDRESS_P1 array
00243     status = SPI_Send_command_with_ADDR(W_REGISTER, RX_ADDR_P1, NRF_NOP);
00244     //Write TX_ADDR register -> Transmit address. Used for a PTX device only. Address in TX_ADDRESS array
00245     status = SPI_Send_command_with_ADDR(W_REGISTER, TX_ADDR, NRF_NOP);
00246     //Write RX_PW_P0 register -> Set number of bytes in RX payload in data pipe0 -> 1 byte
00247     status = SPI_Send_command_with_ADDR(W_REGISTER, RX_PW_P0, 1);
00248     //Write RX_PW_P1 register -> Set number of bytes in RX payload in data pipe1 -> 1 byte
00249     status = SPI_Send_command_with_ADDR(W_REGISTER, RX_PW_P1, 1);
00250     NRF_prepareForReceive ();
00251 }
00252 
00260 void NRF_send (uint8_t byte)
00261 {
00262     uint8_t status_temp;
00263 
00264     // Chip enable low
00265     CE_LOW();
00266 
00267     // Setting for TX device
00268     // Write CONFIG register -> 00001010 - CRC enable, power-up, TX
00269     status = SPI_Send_command_with_ADDR (W_REGISTER,CONFIG_REG_ADDR, 0x0A);
00270 
00271     // Send payload - send any data
00272     status = SPI_Send_command_without_ADDR (W_TX_PAYLOAD, byte);
00273 
00274     // Pulse for CE -> starts the transmission.
00275     CE_HIGH();
00276     CE_LOW();
00277 
00278     // Read STATUS register
00279     status = SPI_Send_command_without_ADDR(NRF_NOP, NRF_NOP);
00280 
00281     // if exceed number of transmision packets
00282     if ((status & MAX_RT) != 0) 
00283     {
00284 
00285         // Clear MAX_RT bit in status register
00286         status_temp = SPI_Send_command_with_ADDR(W_REGISTER, STATUS_ADDR, (status|MAX_RT));
00287 
00288         // No communication event here
00289         LCD_printf ("MAX_RT\n");
00290 
00291         // Flush TX FIFO (in TX mode)
00292         status_temp = SPI_Send_command_without_ADDR(FLUSH_TX, NRF_NOP); // XXX test code
00293     }
00294 
00295     // If packet sent on TX
00296     if ((status & TX_DS) != 0) 
00297     {
00298         // Clear TX_DS bit in status register
00299         status_temp = SPI_Send_command_with_ADDR(W_REGISTER, STATUS_ADDR, (status|TX_DS));
00300 
00301         // Your code here
00302         //LCD_printf ("TX_DS\n");
00303     }
00304 
00305     // If TX full
00306     if ((status & TX_FULL) != 0)
00307     {
00308         // Flush TX FIFO (in TX mode)
00309         status_temp = SPI_Send_command_without_ADDR(FLUSH_TX, NRF_NOP);
00310 
00311         // Your code here
00312         // ...
00313         LCD_printf ("TX_FULL\n");
00314     }
00315 
00316 }
00317 
00321 void NRF_prepareForReceive ()
00322 {
00323     // Setting for RX device
00324     //Write CONFIG register -> 00001010 - CRC enable, power-up, RX
00325     status = SPI_Send_command_with_ADDR(W_REGISTER,CONFIG_REG_ADDR, 0x0B);
00326 }
00327 
00337 bool_t NRF_receive (uint8_t *const byte)
00338 {
00339     uint8_t payload;
00340     uint8_t status_temp;
00341 
00342     CE_HIGH ();
00343     if (IRQ ()) // check interrupt line of nRF24L01...
00344     {
00345         // Read STATUS status register
00346         status = SPI_Send_command_without_ADDR(NRF_NOP, NRF_NOP);
00347 
00348         // Set high when new data arrives RX FIFO
00349         if ((status & RX_DR) != 0)
00350         {
00351             // Chip enable low
00352             CE_LOW();
00353 
00354             //Read payload data
00355             payload = SPI_Send_command_without_ADDR(R_RX_PAYLOAD, NRF_NOP);
00356 
00357             // Clear RX_DR bit in status register
00358             status_temp = SPI_Send_command_with_ADDR(W_REGISTER, STATUS_ADDR, (status|RX_DR));
00359 
00360             *byte = payload;
00361 
00362             // Flush RX FIFO
00363             status_temp = SPI_Send_command_without_ADDR(FLUSH_RX, NRF_NOP); // XXX test code
00364             return TRUE;
00365         }
00366     }
00367     return FALSE;
00368 }

Generated on Sun Dec 9 17:17:10 2007 for Sample MSP430-4619LCD Project by  doxygen 1.5.1