1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

Example code for RFM70 and ATmega88

Discussion in 'Embedded' started by wzab, Jan 6, 2011.

  1. wzab

    wzab Guest

    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)")
     
    wzab, Jan 6, 2011
    #1
    1. Advertisements

  2. wzab

    dbr Guest

    If the compiler will generate a listing in assembley language, I'd check
    the "status_mask" first thing.

    Hul

     
    dbr, Jan 6, 2011
    #2
    1. Advertisements

  3. wzab

    hamilton Guest

    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
     
    hamilton, Jan 6, 2011
    #3
  4. wzab

    wzab Guest

    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/ )
     
    wzab, Jan 7, 2011
    #4
  5. wzab

    wzab Guest

    avr-gcc treats it just as it was a constant defined by #define.
    The generated code is quite efficient:


    while ( (UCSR0A & status_mask) != 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 */
     
    wzab, Jan 7, 2011
    #5
  6. wzab

    wzab Guest

    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=((1<<RXC0) | (1<<TXC0));
    /* Wait for empty transmit buffer */
    while ( !( UCSR0A & (1<<UDRE0)) ){};
    /* Put data into buffer, sends the data */
    cli();
    UDR0 = c;
    UCSR0A = (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) != status_mask ){};
    /* Get and return received data from buffer */
    return UDR0;
    }
     
    wzab, Jan 8, 2011
    #6
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.