SPI communication and connection

Go To Last Post
25 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi So I am narrowing down a problem I am having with an spi conection.
When a button is pressed the mega1284 tries to transmit some data using SPI communication. It never seems to finish. Within the code I can see that it an leave the do while based on two conditions:

	do
	{
		//stop if max_retries reached
		if((mirf_read_register(OBSERVE_TX) & 0b1111) == mirf_RETR)
		{
			breaked = 1;
			break;
		}
		_delay_us(10);
	}
	while( !(mirf_get_status() & _BV(TX_DS)) );

I dont completely understand the if conditon that breaks the loop but the while condition I do.
If SPDR returns 1 here it will leave the loop:

uint8_t spi_writeread(uint8_t data)
{
    SPDR = data;
    while((SPSR & (1<<SPIF)) == 0);
    return SPDR;
}

I have checked it and it never is not 0.
My question is does this suggest a connection problem i.e hardware? I have checked my connections and everything is good as far as I can tell.
I am currently trying to understand the output of my scope...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So my device (the nrf24L01) has its pins labelled as MO and MI
To start with I thought MO was MISO etc but I have since swapped them around so that MO is MOSI and MI is MISO.
It hasnt fixed the problem however seems more right....

Concerned that the interrupt is not doing anything, but actually I think thats just a reading thing, not a writing thing...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Post your SPI and port setup code. Most often the problem is that SS is not made an output.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You haven't shown how mirf_read_register is related to spi_writeread ? Does it send something to the SPI device then clock another byte out of it or something?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The usual problem with SPI is that the punter does not make SS an output. The SPI then goes haywire.

If you ae unsure of connections, post a link to your actual module. e.g. an Ebay photo.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok cool. Some debugging output:
firstly mirf_write contains the above "do" loop.

//read many registers
void mirf_read_registers(uint8_t reg, uint8_t *value, uint8_t len)
{
    mirf_CSN_lo;
    spi_writeread(R_REGISTER | (REGISTER_MASK & reg));
	for (uint8_t i = 0; i < len; i++)
		value[i] = spi_writeread(NOP);
    mirf_CSN_hi;
}

should answer your question Cliff.
I also got output from SPI_writeread:

Quote:

SPDR = 248
SPDR = 120
SPDR = 1

Sternst:
port setup code is

#define CE  PB0
#define CSN PB3

#define PORT_SPI  PORTB
#define DDR_SPI   DDRB
#define SPI_MISO  DDB6
#define SPI_MOSI  DDB5
#define SPI_SCK   DDB7
#define SPI_SS    DDB4
//initialize spi
void spi_init()
{
    DDR_SPI &= ~( (1<<SPI_MOSI) | (1<<SPI_MISO) | (1<<SPI_SS) | (1<<SPI_SCK) );
    DDR_SPI |= ( (1<<SPI_MOSI) | (1<<SPI_SS) | (1<<SPI_SCK) );

    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)|(1<<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 spi speed bit
}
void mirf_init() 
{
    DDRB |= ( (1<<CSN) | (1<<CE) );

    mirf_CE_lo;
    mirf_CSN_hi;

    spi_init();
}

Do you agree that MO sounds more like MOSI and MISO?
Thanks guys.
BTW I am using this guys work as a template - he seems to have got it working but Im using 1284 to send...
http://davidegironi.blogspot.co....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry David, I was writing as you posted.
Here is a picture:
http://www.electrodragon.com/wp-...

Yeah I learnt that lesson (SS lesson) once before when I had a button on the same line!

EDIT: From reading around IRQ is a luxury that isnt needed...

EDIT2:
My mega1284 is running off 8Mhz, the nerf24L01 runs off 16, is that a problem?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have NRF24L01 and your code comes from a NRF24L01+
Note that the "+" boards have a zig-zag folded antenna.

You would need to compare data sheets for the two chips.

Your AVR speed is irrelevant. All that matters is the correct SPI commands and your response to any replies.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

P.S after looking at the pin out of the NRF24L01 chip and the image I posted above, I am now more sure that my new pin connections are correct - i.e MO means MOSI.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Interesting observation...
Ive looked through the data sheets once, comparing them. If there is a significant difference, its very subtle - nothing stands out at the moment.
Im trying to analyse the scope output, to see if the correct things are being sent to the SPI pins, but without a comparison its quite difficult to know whats expected.
EDIT:
How are you able to tell whether the user of the code I am using is using a nrf24L01+ or standard nrf24L01? I google imaged both and both types of board appear with both names...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What kind of thing would I be looking for? I cant see anything that makes the difference...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have no idea. If the manufacturer has released a device with a different identity, it generally means there are differences.

Compare the two data sheets.

It is of course possible (and likely) that the NRF24L01+ will do everything that the NRF24L01 does. But not necessarily the reverse.

Can you post a link to the original code?
And a 'diff' file of 'your' version.

I have some NRF24L01+ modules but not NRF24L01. From distant memory, not all web code actually works properly.

What dev board(s) are you using?

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah, from the datasheet, All I can tell is that the '+' version seems to have a greater range, but cant see any SPI control that is different, still going through it tho...
This is the link to the code Im using:
http://davidegironi.blogspot.co....

But that code is a version of the code at tinkerer - which I am now also trying to work out if that was written for the '+' or normal...
My 'sending' code is attached below:

Im using an Olimex 40 pin avr dev board, its not really a dev board - well it is, but I had to solder the nrf2401 on...

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The NRF24L01+ has a maximum VDD of 3.6V.
The schematic from your link shows a ATmega8 and 5V going to the NRF ! The pcb layout shows a NRF24L01+ module. The photo shows a different antenna.

I have compiled an AS6 project with code from your link.
Of course this is for a mega8 rather than mega1284.

It looks as if you have made the correct edits to mirf.h
However, no-one knows how you have wired up the module.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

well it seems ambiguous as to what the maximum rating is (check attachment from datasheet)
Yeah I noticed he was using 5v as well, which other places also say is ok...
So you then think its a hardware thing (my end?). If so thats very annoying. Software is much easier to debug...

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So...looking at connections...
VCC - VCC
GND - GND
CE - PB0
SCK - SCK
MI - PB6
CSN - PB3
MO - PB5
IRQ - PB2

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The max VDD is what you are permitted to put on pin#2.

The max 'Input Voltage' is what is allowed on a GPIO pin.

Many 3.3V chips are '5V tolerant' on their GPIO inputs.
This often gets very confusing when a pin is used as an 'alternate function'.

I don't know whether the NRF chip will fail immediately with 5V. It is definitely unwise.

If you like, I will try out the original code on a mega168 and mega328P (at 3.3V). This can confirm whether it 'works'.

Then I can try your code on a meg1284P. Bear in mind that without seeing a photo of your 'connections', it is difficult to judge whether it is a wiring or software problem.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That would be great David thanks. (Do you have an nrf24L01?)
I can take a photo, but due to the way the pins are aligned (two rows) its very hard to arrange the wiring in a way that a photo would show what is going on. I have checked the connections with a multimeter and they are connected. There may be a short - i'll check that now, but if you could test the code your end that would be ACE.

EDIT:
Just checked the voltage on my olimex board. Its reading 3.8v which is weird. I know the board doesnt use a 3.3v regulator - its seems to cheat the 3.3v because it uses a jumper to choose it:
https://www.olimex.com/dev/pdf/A...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looking at ebay cheap green module it appears that they use NRF24L01+ chip. And most importantly, they "say" that there is a voltage regulator.

So it is up to you to read your data sheet. Ebay "say" is often b*llocks.

Yes. I will compile and run the software from your link.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is the exact one I bought however:
http://www.ebay.co.uk/itm/ws/eBa...
It says 3.6V rating.. and the title says a built in regulator! I hadnt seen that. But it does say its a non '+' version.
Well if it does have a built in regulator maybe Ive been providing it a voltage below its dropout levels, but Im going to need to confirm that...

EDIT:
Yeah the datasheet does mention an onboard voltage regulator, however gives very little detail about it:

Quote:

Power Management
􀁘 Integrated voltage regulator
􀁘 1.9 to 3.6V supply range
...
...
Internal voltage regulators ensure a high Power Supply Rejection Ratio (PSRR) and a wide power supply
range.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, the code in your link is rather crap.

It uses the Fleury uart library but not 'up to date'. e.g. deprecated SIGNAL() and deprecated SIG_UART_RX etc. The AS6 compiler issues warnings.

The schematic and general coding requires external pull-down resistors and switches that connect to VCC !
This is not a very good way of using an AVR.

I get comms between the two boards but not very reliably.
I presume this is due to bad configuration of the NRF.

I will try some other code. It seems foolish to try your code yet.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok,
Yeah I scrapped the uart code there and used some code Ive been happy with in the past - I think interrupts on uart are generally overkill. If its easier, just grab the uart libraries out of mine...
what voltage are you putting into the nrf24L01 breakout board?
I got rid of all of the code to do with choosing whether its a sender or receiver, and juast hard coded one as the sender and one as the receiver, then with a button start the sending procedure...
Thanks alot for helping me with this David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

P.S I finally realised that a 'diff' file is actually something...Notepad++ has a plugin to do such a thing. Sorry should have picked up on that yesterday.
Did you find any other code, I keep coming across PIC code, and the original code on the tinkerer website, but thats very closely related to the code that you tried yesterday.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I ran 'your' AS4 project by importing it to AS6. I used a mega16. I removed your superfluous printf() calls. It behaves like the original code. i.e. it does not always communicate successfully.

I had to 'adjust' your uart code for a mega16.
I moved the LED to PC0 because PC5 is used by JTAG.

I will dig out some old ARM7 projects. Unfortunately they are on a different PC and may need a bit of 'testing'.

If they are intact, I will post them after I have checked they compile ok for the AVR. I managed to kill my ATmega1284P yesterday.

If everything goes well, do you use AS4, AS6, or what ?
You obviously need two AVRs. What models, and what dev boards?

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When I run the sending code, it doesnt even succesffuly send, regardless of whether there is something to receive it or not, is that the same issue as you've been having? My code never gets out of this loop:

do 
   { 
      //stop if max_retries reached 
      if((mirf_read_register(OBSERVE_TX) & 0b1111) == mirf_RETR) 
      { 
         breaked = 1; 
         break; 
      } 
      _delay_us(10); 
   } 
   while( !(mirf_get_status() & _BV(TX_DS)) ); 

Does yours?
In terms of receiving, well I havent got that far as sending doesnt seem to work...

How did you kill your 1284P? What voltage are you supplying the nrf24l01 with?

Im using AS4 currently, I tried AS5 for a bit, but coudlnt stand it, perhaps 6 is better...

My sending AVR is a 1284 on an Olimex 40 AVR dev board. I have soldered the NRF24L01 to the connections mentioned earlier:
https://www.olimex.com/dev/avr-p...
My receiving AVR is a mega128 I have made a breakout for the NRF24L01 and attached that to the connections on the board:
https://www.olimex.com/dev/avr-m...

Look forward to seeing your code