Reply by wzab January 8, 20112011-01-08
On Jan 6, 10:49=A0pm, wzab <w...@wzab.nasz.dom> wrote:

> static inline uint8_t SPI_Transfer(uint8_t c) > { > =A0 const uint8_t status_mask=3D((1<<RXC0) | (1<<TXC0)); > =A0 /* Wait for empty transmit buffer */ > =A0 while ( !( UCSR0A & (1<<UDRE0)) ); > =A0 /* Put data into buffer, sends the data */ > =A0 UDR0 =3D c; > =A0 /* Wait for data to be received and transmission completed > =A0 =A0 =A0Please note, that it is not enough to wait for availability > =A0 =A0 =A0of received data (RXC0), if you set SS high right after > =A0 =A0 =A0SS is set, you'll experience SPI frame error in the RFM70! > =A0 =A0 =A0I've lost quite a long time trying to debug this problem!!! > =A0 */ > =A0 while ( (UCSR0A & status_mask) !=3D status_mask ); > =A0 /* Get and return received data from buffer */ > =A0 return UDR0; > > }
Ooops, it seems, that the TXC0 flag is not so easy to use. It is cleared only after interrupt or after writing "1" to it (in polling mode). So the above function must be slightly modified! static inline uint8_t USART_SPI_Transfer(uint8_t c) { const uint8_t status_mask=3D((1<<RXC0) | (1<<TXC0)); /* Wait for empty transmit buffer */ while ( !( UCSR0A & (1<<UDRE0)) ){}; /* Put data into buffer, sends the data */ cli(); UDR0 =3D c; UCSR0A =3D (1<<TXC0); //Clear the completed transfer flag (possibly set by previous transfers)! sei(); /* Wait for data to be received and transmission completed Please note, that it is not enough to wait for availability of received data (RXC0), if you set SS high right after SS is set, you'll experience SPI frame error in the RFM70! I've lost quite a long time trying to debug this problem!!! */ while ( (UCSR0A & status_mask) !=3D status_mask ){}; /* Get and return received data from buffer */ return UDR0; }
Reply by wzab January 7, 20112011-01-07
On Jan 6, 11:31=A0pm, d...@kbrx.com wrote:
> If the compiler will generate a listing in assembley language, I'd check > the "status_mask" first thing. > > Hul
avr-gcc treats it just as it was a constant defined by #define. The generated code is quite efficient: while ( (UCSR0A & status_mask) !=3D status_mask ); f6: 80 91 c0 00 lds r24, 0x00C0 fa: 80 7c andi r24, 0xC0 ; 192 fc: 80 3c cpi r24, 0xC0 ; 192 fe: d9 f7 brne .-10 ; 0xf6 <SPI_Transfer +0xe> /* Get and return received data from buffer */ -- Regards, Wojtek
Reply by wzab January 7, 20112011-01-07
On Jan 6, 11:37=A0pm, hamilton <hamil...@nothere.com> wrote:
> > My whole working code is available in the alt.sources usenet group: > >http://groups.google.com/group/alt.sources/browse_thread/thread/19ce3... > > (or search for "RFM70 - working example code for ATmega88 (no interrupt=
s
> > yet)") > > Thanks for the code, I'll take a look. > > Can you tell me what the 'X' on the front of so many lines is for ?? >
This is a "shar" archive (according to the alt.sources convention). You can save the whole post (in an original form) and run "unshar" on it. Or you can remove all lines before the "#!/binsh" line, and run the remainder as the bash script. The above applies to Linux or other Un*x-like systems. I don't know how to unpack it in Windows (unless you make it Un*x like by installing cygwin http://www.cygwin.com/ ) -- Regards, Wojtek
Reply by hamilton January 6, 20112011-01-06
On 1/6/2011 2:49 PM, wzab wrote:
> In different groups I have seen messages from people > trying to get RFM70 to work with the AVR. > I've faced the similar problem, when I needed > to connect RFM70 to the USART working in the SPI mode. > The problem which disturbed operation of RFM70 > was associated with incorrect SPI frames generated by > ATmega88, when I set SS (CSN in RFM70) line high right > after the RXC0 flag was set. > To obtain the correct operation, I had to modify the > standard SPI transfer routine in the following way: > > static inline uint8_t SPI_Transfer(uint8_t c) > { > const uint8_t status_mask=((1<<RXC0) | (1<<TXC0)); > /* Wait for empty transmit buffer */ > while ( !( UCSR0A& (1<<UDRE0)) ); > /* Put data into buffer, sends the data */ > UDR0 = c; > /* Wait for data to be received and transmission completed > Please note, that it is not enough to wait for availability > of received data (RXC0), if you set SS high right after > SS is set, you'll experience SPI frame error in the RFM70! > I've lost quite a long time trying to debug this problem!!! > */ > while ( (UCSR0A& status_mask) != status_mask ); > /* Get and return received data from buffer */ > return UDR0; > } > > My whole working code is available in the alt.sources usenet group: > http://groups.google.com/group/alt.sources/browse_thread/thread/19ce3c8b83458def > (or search for "RFM70 - working example code for ATmega88 (no interrupts > yet)")
Thanks for the code, I'll take a look. Can you tell me what the 'X' on the front of so many lines is for ?? Thanks hamilton
Reply by January 6, 20112011-01-06
If the compiler will generate a listing in assembley language, I'd check 
the "status_mask" first thing.

Hul

wzab <wzab@wzab.nasz.dom> wrote:
> In different groups I have seen messages from people > trying to get RFM70 to work with the AVR. > I've faced the similar problem, when I needed > to connect RFM70 to the USART working in the SPI mode. > The problem which disturbed operation of RFM70 > was associated with incorrect SPI frames generated by > ATmega88, when I set SS (CSN in RFM70) line high right > after the RXC0 flag was set. > To obtain the correct operation, I had to modify the > standard SPI transfer routine in the following way:
> static inline uint8_t SPI_Transfer(uint8_t c) > { > const uint8_t status_mask=((1<<RXC0) | (1<<TXC0)); > /* Wait for empty transmit buffer */ > while ( !( UCSR0A & (1<<UDRE0)) ); > /* Put data into buffer, sends the data */ > UDR0 = c; > /* Wait for data to be received and transmission completed > Please note, that it is not enough to wait for availability > of received data (RXC0), if you set SS high right after > SS is set, you'll experience SPI frame error in the RFM70! > I've lost quite a long time trying to debug this problem!!! > */ > while ( (UCSR0A & status_mask) != status_mask ); > /* Get and return received data from buffer */ > return UDR0; > }
> My whole working code is available in the alt.sources usenet group: > http://groups.google.com/group/alt.sources/browse_thread/thread/19ce3c8b83458def > (or search for "RFM70 - working example code for ATmega88 (no interrupts > yet)") > -- > HTH & Regards, > Wojciech Zabolotny
Reply by wzab January 6, 20112011-01-06
In different groups I have seen messages from people
trying to get RFM70 to work with the AVR.
I've faced the similar problem, when I needed 
to connect RFM70 to the USART working in the SPI mode.
The problem which disturbed operation of RFM70 
was associated with incorrect SPI frames generated by 
ATmega88, when I set SS (CSN in RFM70) line high right
after the RXC0 flag was set.
To obtain the correct operation, I had to modify the 
standard SPI transfer routine in the following way:

static inline uint8_t SPI_Transfer(uint8_t c)
{
  const uint8_t status_mask=((1<<RXC0) | (1<<TXC0));
  /* Wait for empty transmit buffer */
  while ( !( UCSR0A & (1<<UDRE0)) );
  /* Put data into buffer, sends the data */
  UDR0 = c;
  /* Wait for data to be received and transmission completed
     Please note, that it is not enough to wait for availability
     of received data (RXC0), if you set SS high right after
     SS is set, you'll experience SPI frame error in the RFM70!
     I've lost quite a long time trying to debug this problem!!!
  */
  while ( (UCSR0A & status_mask) != status_mask );
  /* Get and return received data from buffer */
  return UDR0;
}

My whole working code is available in the alt.sources usenet group: 
http://groups.google.com/group/alt.sources/browse_thread/thread/19ce3c8b83458def
(or search for "RFM70 - working example code for ATmega88 (no interrupts
yet)")
-- 
HTH & Regards,
Wojciech Zabolotny