I’m using a STK500 with a uMiRF v2 and ATtiny26. I’ve implemented a SPI interface using the USI hardware and all the timing and functionality seem correct from reviewing commands on my scope.
My main program loop continuously reads the nrf24l01’s config register and displays it on PORTA which is connected to my LEDs.
Turning the STK500 board (which also powers the uMiRF) on yields only LED in the 3rd bit position on, CRC0, as the nrf24l01’s spec sheet specifies as the only bit set high for the default register value. This would imply to me that the read register function works correctly.
I have written an init function to initialize my IO ports and initialize the nrf24l01’s config register, however this doesn’t seem to work reliably.
It seem that if I just turn the STk500 on, I get the default value, however, if I turn the board off and watch the VCC pin on the board’s voltage drop due to capacitors discharging and turn it back on before complete discharge, the correct LED sequence is lit up as per my desired configuration.
I’m wondering if there is something I’m doing wrong in my write register function or if there is a weird write sequence for writing the first byte of data to the nrf24l01.
My write_register function is as follows:
/* Write single/multiple register(s) to a nRF24L01
*
* unsigned char regnumber register number to read data from
* see "Memory Map" in nRF24L01 datasheet.
*
* unsigned char data[] pointer to the top of the data array that
* contains data to be written
*
* unsigned char len number of DATA bytes to write,
* aka min size of data array
*/
void nrf24l01_write_register(unsigned char regnumber, unsigned char data[], unsigned char len)
{
unsigned char buffer[6]; // for reorganizing the data
unsigned char set_ce; // bit to store prev value of ce
uint8_t count; // looping variable
// construct our instruction
buffer[0] = nrf24l01_W_REGISTER | (regnumber & nrf24l01_W_REGISTER_DATA);
// append the data to array
for(count = 0; count < len; count++)
buffer[count + 1] = data[count];
// let the nRF24L01 know we are about to talk to it
nrf24l01_clear_csn();
// check if we have CE high (ie receiver), and set it low
// so that we can write to the registers
if( bit_is_set(DDRSPI, CE) ) {
set_ce = 1;
nrf24l01_clear_ce();
}
// write the data out
spi_write(buffer, len + 1);
// if chip enable was high before, make it high again
if(set_ce == 1) {
nrf24l01_set_ce();
}
// let the nRF24L01 know we are done talk to it
nrf24l01_set_csn();
}
(Alot of my nrf24l01 driver code was borrowed from Brennen, and then about 90% rewritten to my taste and reduced code footprint for the 2KB flash ATtiny26).