Hi guys,
These nordic wireless chips seem to be fairly popular but I have been battling to get them talking for two days and am out of ideas.
I don’t have access to a scope until tomorrow to check the signals but I have checked the spi setup via a loopback setup and it seems to be fine. The code i’m using is essentially the http://www.tinkerer.eu/AVRLib/nRF24L01 code but I’m having no luck. I only ever get back 0xFF as the status from the device.
Main:
void main()
{
// Initialize AVR for use with mirf
mirf_init();
// Configure mirf
mirf_config();
// Test communication
mirf_CSN_lo;
status_test = spi_fast_shift(NOP);
mirf_CSN_hi;
}
Mirf.c
// Pin definitions for chip select and chip enabled of the MiRF module
#define CSND DDB0
#define CED DDB1
#define DD_MISO DDB6
#define DD_MOSI DDB5
#define DD_SS DDB4
#define DD_SCK DDB7
// Defines for setting the MiRF registers for transmitting or receiving mode
#define TX_POWERUP mirf_config_register(CONFIG, mirf_CONFIG | ( (1<<PWR_UP) | (0<<PRIM_RX) ) )
#define RX_POWERUP mirf_config_register(CONFIG, mirf_CONFIG | ( (1<<PWR_UP) | (1<<PRIM_RX) ) )
// Flag which denotes transmitting mode
volatile uint8_t PTX;
void mirf_init()
// Initializes pins ans interrupt to communicate with the MiRF module
// Should be called in the early initializing phase at startup.
{
// Define CSN and CE as Output and set them to default
DDRB |= ((1<<CSND)|(1<<CED));
mirf_CE_lo;
mirf_CSN_hi;
_delay_ms(5000);
DDRB |= ((1<<CSND)|(1<<CED)|(1<<DD_MOSI)|(1<<DD_SS)|(1<<DD_SCK));
// PORTB |= (1<<PB6); //TRY PULLUP RESISTOR ON MISO
//SPI SETUP
SPCR = ((1<<SPE)| // SPI Enable
(0<<SPIE)| // SPI Interupt Enable
(0<<DORD)| // Data Order (0:MSB first / 1:LSB first)
(1<<MSTR)| // Master/Slave select
(0<<SPR1)|(0<<SPR0)| // SPI Clock Rate
(0<<CPOL)| // Clock Polarity (0:SCK low / 1:SCK hi when idle)
(0<<CPHA)); // Clock Phase (0:leading / 1:trailing edge sampling)
// SPSR = (1<<SPI2X); // Double Clock Rate
}
void mirf_config()
// Sets the important registers in the MiRF module and powers the module
// in receiving mode
{
// Set RF channel
mirf_config_register(RF_CH,mirf_CH);
// Set length of incoming payload
mirf_config_register(RX_PW_P0, mirf_PAYLOAD);
// Start receiver
PTX = 0; // Start in receiving mode
RX_POWERUP; // Power up in receiving mode
mirf_CE_hi; // Listening for pakets
}
void mirf_set_RADDR(uint8_t * adr)
// Sets the receiving address
{
mirf_CE_lo;
mirf_write_register(RX_ADDR_P0,adr,5);
mirf_CE_hi;
}
void mirf_set_TADDR(uint8_t * adr)
// Sets the transmitting address
{
mirf_write_register(TX_ADDR, adr,5);
}
extern uint8_t mirf_data_ready()
// Checks if data is available for reading
{
if (PTX) return 0;
uint8_t status;
// Read MiRF status
mirf_CSN_lo; // Pull down chip select
status = spi_fast_shift(NOP); // Read status register
mirf_CSN_hi; // Pull up chip select
return status & (1<<RX_DR);
}
extern void mirf_get_data(uint8_t * data)
// Reads mirf_PAYLOAD bytes into data array
{
mirf_CSN_lo; // Pull down chip select
spi_fast_shift( R_RX_PAYLOAD ); // Send cmd to read rx payload
spi_transfer_sync(data,data,mirf_PAYLOAD); // Read payload
mirf_CSN_hi; // Pull up chip select
mirf_config_register(STATUS,(1<<RX_DR)); // Reset status register
}
void mirf_config_register(uint8_t reg, uint8_t value)
// Clocks only one byte into the given MiRF register
{
mirf_CSN_lo;;
spi_fast_shift(W_REGISTER | (REGISTER_MASK & reg));
spi_fast_shift(value);
mirf_CSN_hi;
}
void mirf_read_register(uint8_t reg, uint8_t * value, uint8_t len)
// Reads an array of bytes from the given start position in the MiRF registers.
{
mirf_CSN_lo;
spi_fast_shift(R_REGISTER | (REGISTER_MASK & reg));
spi_transfer_sync(value,value,len);
mirf_CSN_hi;
}
void mirf_write_register(uint8_t reg, uint8_t * value, uint8_t len)
// Writes an array of bytes into inte the MiRF registers.
{
mirf_CSN_lo;
spi_fast_shift(W_REGISTER | (REGISTER_MASK & reg));
spi_transmit_sync(value,len);
mirf_CSN_hi;
}
void mirf_send(uint8_t * value, uint8_t len)
// Sends a data package to the default address. Be sure to send the correct
// amount of bytes as configured as payload on the receiver.
{
// while (PTX) {} // HANDLED MANUALLY Wait until last paket is send
mirf_CE_lo;
PTX = 1; // Set to transmitter mode
TX_POWERUP; // Power up
mirf_CSN_lo; // Pull down chip select
spi_fast_shift( FLUSH_TX ); // Write cmd to flush tx fifo
mirf_CSN_hi; // Pull up chip select
mirf_CSN_lo; // Pull down chip select
spi_fast_shift( W_TX_PAYLOAD ); // Write cmd to write payload
spi_transmit_sync(value,len); // Write payload
mirf_CSN_hi; // Pull up chip select
mirf_CE_hi; // Start transmission
}
SPI:
void spi_transfer_sync (uint8_t * dataout, uint8_t * datain, uint8_t len)
// Shift full array through target device
{
uint8_t i;
for (i = 0; i < len; i++) {
SPDR = dataout[i];
while((SPSR & (1<<SPIF))==0);
datain[i] = SPDR;
}
}
void spi_transmit_sync (uint8_t * dataout, uint8_t len)
// Shift full array to target device without receiving any byte
{
uint8_t i;
for (i = 0; i < len; i++) {
SPDR = dataout[i];
while((SPSR & (1<<SPIF))==0);
}
}
uint8_t spi_fast_shift (uint8_t data)
// Clocks only one byte to target device and returns the received one
{
SPDR = data;
while(!(SPSR & (1<<SPIF)));
return SPDR;
}
Anybody got any ideas of something I can try? I’ve been at it for two days and nothing left I can think of trying.