nrf24l01 initialization

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:

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).

Since you apparently have some familiarity with my code, have you tried using my init routine to see if it makes the 24L01 work right on the first try with your write_register function?

I tried it, but your code + the usi → SPI driver I had originally took up about 3KB with -02 on a 2KB flash.

I just figured it out. There wasn’t a high to low transition before the first write. Simply calling nrf24l01_set_csn() before any writes takes care of the problem.

Thanks for that driver, I’ve used it as guidance and it has helped alot. Not to mention I don’t have to write all the bit value in the header file. :slight_smile:

Haha thanks. I’m glad you got it working. I really need to figure out why it takes up a lot of space though, so that I can make it a bit more usable for others.