Here are some functions I use for the RF-24G (shockburst mode) connected to an AVR with SPI. The SPI connection is described in:
http://www.nordicsemi.no/files/Product/ … RF2401.pdf
The code is for avr-gcc. I use it with mega32 and mega48 parts (both at 8Mhz and with the SPI clock at 1Mhz).
The ‘trf24g_config.h’ file is where the wanted configuration and pins to use must be specified (the file below is what I use on a mega32).
/Lars
trf24g.h:
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Lars Jonsson (User name Lajon at www.avrfreaks.net) wrote this file.
* As long as you retain this notice you can do whatever you want with this
* stuff. If we meet some day, and you think this stuff is worth it, you can
* buy me a beer in return. Lars Jonsson
* ----------------------------------------------------------------------------
*
*/
#ifndef TRF24G_H
#define TRF24G_H
#include <inttypes.h>
#include <stdbool.h>
extern void trf24gInit(void);
extern bool trf24gReceive(void *buf);
extern void trf24gSend(void *buf);
extern void trf24gReconfigure(uint8_t channel, bool rx);
#define TRF24G_TIME_ON_AIR ((1 + 3 * (1-TRF24G_1MBPS)) * 8 * \
(1 + TRF24G_ADDR_SIZE + TRF24G_PAYLOAD_SIZE + TRF24G_CRC_SIZE))
#endif
trf24g_config.h:
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Lars Jonsson (User name Lajon at www.avrfreaks.net) wrote this file.
* As long as you retain this notice you can do whatever you want with this
* stuff. If we meet some day, and you think this stuff is worth it, you can
* buy me a beer in return. Lars Jonsson
* ----------------------------------------------------------------------------
*
*/
#ifndef TRF24G_CONFIG_H
#define TRF24G_CONFIG_H
#define TRF24G_CHANNEL 2
#define TRF24G_RX 0 // 0 or 1
#define TRF24G_ADDR_SIZE 3 // 1-5
#define TRF24G_ADDR1 0, 0,'L',0x55,0xAF // 5 bytes
#define TRF24G_RX2_EN 0 // 0 or 1
#define TRF24G_ADDR2 0,0,0,0,0 // 5 bytes
#define TRF24G_CRC_SIZE 2 // 0,1,2
#define TRF24G_PAYLOAD_SIZE 12
#define TRF24G_1MBPS 0 // 1== 1MBs 0==250Kbs
#define TRF24G_CONTROL_PORT PORTD
#define TRF24G_CONTROL_DDR DDRD
#define TRF24G_CS_MASK (1<<5)
#define TRF24G_CE_MASK (1<<4)
#define TRF24G_DR1_PIN PIND
#define TRF24G_DR1_MASK (1<<2)
#define TRF24G_SPI_DDR DDRB
#define TRF24G_SPI_SCK_MASK (1<<7)
#define TRF24G_SPI_MOSI_MASK (1<<5)
#endif
trf24g.c:
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Lars Jonsson (User name Lajon at www.avrfreaks.net) wrote this file.
* As long as you retain this notice you can do whatever you want with this
* stuff. If we meet some day, and you think this stuff is worth it, you can
* buy me a beer in return. Lars Jonsson
* ----------------------------------------------------------------------------
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "config.h"
#include <avr/delay.h>
#include "trf24g_config.h"
#define TRF24G_START_CONFIG() TRF24G_CONTROL_PORT |= TRF24G_CS_MASK; _delay_us(5)
#define TRF24G_END_CONFIG() TRF24G_CONTROL_PORT &= (uint8_t)~TRF24G_CS_MASK;
#define TRF24G_ACTIVE() TRF24G_CONTROL_PORT |= TRF24G_CE_MASK; _delay_us(5)
#define TRF24G_INACTIVE() TRF24G_CONTROL_PORT &= ~TRF24G_CE_MASK;
static uint8_t trf24gConfig[15] = {
/* 0 */ TRF24G_PAYLOAD_SIZE * 8, // DATA2_W
/* 1 */ TRF24G_PAYLOAD_SIZE * 8, // DATA1_W
/* 2 */ 0,0,0,0,0, // ADDR2 not used
/* 7 */ TRF24G_ADDR1, // ADDR1
/* 12 */ ((TRF24G_ADDR_SIZE * 8) << 2) |
((TRF24G_CRC_SIZE == 0) ? 0b00 : ((TRF24G_CRC_SIZE == 1) ? 0b01 : 0b11)),
/* 13 */ (0 << 7) | // RX2 active or not (not for now)
(1 << 6) | // Shockburst (always)
(TRF24G_1MBPS << 5) | // Speed
(0b011 << 2) | // 16MHz always
0b11, // Full power always
/* 14 */ (TRF24G_CHANNEL << 1) | TRF24G_RX
};
#define ADDR1 7
static inline uint8_t spiSend(uint8_t d)
{
SPDR = d;
while(!(SPSR & (1<<SPIF)))
;
return SPDR;
}
void trf24gInit(void)
{
uint8_t i;
// DDR for trf24g control, CS and CE are outputs
TRF24G_CONTROL_DDR |= TRF24G_CS_MASK|TRF24G_CE_MASK;
// DDR for SPI, MOSI and SCK are outputs
TRF24G_SPI_DDR |= TRF24G_SPI_MOSI_MASK|TRF24G_SPI_SCK_MASK;
// SPI master, trailing edge setup
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); // /8 clock (8Mhz/8 = 1Mhz)
SPSR |= (1<<SPI2X);
//SPCR = (1<<SPE)|(1<<MSTR)|(0<<SPR0); // /4 clock (works also)
// >3ms startup
_delay_ms(3);
TRF24G_START_CONFIG();
for(i = 0; i < sizeof(trf24gConfig); i++) {
spiSend(trf24gConfig[i]);
}
TRF24G_END_CONFIG();
#if TRF24G_RX
TRF24G_ACTIVE();
#endif
}
void trf24gReconfigure(uint8_t channel, bool rx)
{
uint8_t cfg = channel << 1;
cfg |= rx;
TRF24G_INACTIVE();
TRF24G_START_CONFIG();
spiSend(cfg);
TRF24G_END_CONFIG();
if (rx) {
TRF24G_ACTIVE();
}
}
bool trf24gReceive(void *p)
{
uint8_t dr = TRF24G_DR1_PIN & TRF24G_DR1_MASK;
if (dr) {
uint8_t n = TRF24G_PAYLOAD_SIZE;
uint8_t *buf = (uint8_t*)p;
do {
*buf++ = spiSend(0);
} while(--n);
}
return dr;
}
void trf24gSend(void *p)
{
uint8_t n = TRF24G_ADDR_SIZE;
uint8_t *buf = (uint8_t*)p;
uint8_t *a = trf24gConfig + ADDR1 + 5 - TRF24G_ADDR_SIZE;
TRF24G_ACTIVE();
do {
spiSend(*a++);
} while(--n);
n = TRF24G_PAYLOAD_SIZE;
do {
spiSend(*buf++);
} while(--n);
TRF24G_INACTIVE();
}