DIY :- Wireless Chat Using RFM70

DIY: - Do It Yourself ​

Wireless Data Transmission​ Wireless Chat using RFM70


RFM70 is a GFSK transceiver module operating in the world wide ISM frequency band at 2400 - 2483.5 MHz. Burst mode transmission and up to 2Mbps air data rate make them suitable for applications requiring ultra low power consumption.

The embedded packet processing engines enable their full operation with a very simple MCU as a radio system. Auto re-transmission and auto acknowledge give reliable link without any MCU interference.

​Block Diagram:-

Block diagram
​[FONT=&amp]
[/FONT]


This is the basic Block Diagram for the project in which you have to catch the data from any device or you can use Personal Computer or Laptop to send the data for that you need to interface the Computer with the project board and here it is Serial Communication as now a days serial port are not available on Laptop you can also use USB to Serial cable and that data is given to the Microcontroller.

For the communication between Microcontroller and RFM70 module you have to use SPI protocol many controller gives the Hardware SPI but in this project we are going to use Software SPI.

Data which is received by the Microcontroller is now transffered to the RFM70 and RFM70 transmit that data in RF.

This is all about the Transmitter and for the Receiver it will do the same procedure but in reverse order first RFM70 Module collects the Data from RF and then on the request from Microcontroller via SPI Command it gives the received data to Microcontroller and the same data now also available on the other Computer or Laptop.

​Interfacing PC with Microcontroller
​To interface PC with microcontroller you have to use the MAX232 or any equivalent IC have a look at #-Link-Snipped-# for the other details.

Here is the Circuit Diagram for the same.
​max232

Microcontroller Section


[​IMG]
​This is the Circuit Section for Microcontroller Here I have used Freescale Microcontroller but you can use any Microcontroller. Now if you see that there is Name given to every Pin which shows that pin's Connection.
Now as we are going to interface controller with MAX232 and RFM70 there are CE,CSN,SCK,MOSI,MISO and IRQ signals are used to communicate with RF Module and RXD,TXD to communicate with Serial Port of PC.

Now Before we start SPI Communication with RF Module you must have knowledge of SPI. for that again refer #-Link-Snipped-# for Some basic Information about SPI.

Note:- Remember as the RF module is working on 3.3Volt you must have to choose MCU which is working on 3.3 Volt. Here MCU_SUP is 3.3Volt
RFM70 Connection

[​IMG]
​This is the connection detail for RFM70. Now we have to make a software which communicate with RFM70 using microcontroller. For More information about RFM70 and its internal register please refer datasheet.

Replies

Welcome, guest

Join CrazyEngineers to reply, ask questions, and participate in conversations.

CrazyEngineers powered by Jatra Community Platform

  • Harshad Italiya

    @harshad-ukH5ww • Jan 8, 2012

    That means your software SPI is not proper yet. Do one thing take the reference code again and then change it according to your compiler and controller.
    To save versions in backup is good thing 😉. So can do this please and let me know. And also follow Big_K's tip. 😀

  • fantomas2002ro

    @fantomas2002ro-hDTzQ8 • Jan 8, 2012

    I will addapt the code again for lpc1343 and I will post here the output 😁.
    About that tip... I wanted but I could not add nothing because the site didn't let me( "More Option" button didn't work).

    Thank you again. 😁

    The source from where I was inspired are here #-Link-Snipped-#

  • Harshad Italiya

    @harshad-ukH5ww • Jan 8, 2012

    fantomas2002roI will addapt the code again for lpc1343 and I will post here the output 😁.
    About that tip... I wanted but I could not add nothing because the site didn't let me( "More Option" button didn't work).

    Thank you again. 😁

    The source from where I was inspired are here #-Link-Snipped-#

    You can use that text directly paste your code as said by Big K and let me know your controller operating speed and SPI clock speed.
    @BIG_K check please why he is not able to get more options. 😀

  • fantomas2002ro

    @fantomas2002ro-hDTzQ8 • Jan 8, 2012

    The controller operating speed is72MHz and the clock speed of the SPI block is 72/2= 36MHz.

    P.S. : I changed the speed to 1MHz for SPI block. No difference.

  • Harshad Italiya

    @harshad-ukH5ww • Jan 8, 2012

    Keep it bellow 1Mhz when you're updating code again. Ok. So your first task is to write and read properly from the module. 😀

  • fantomas2002ro

    @fantomas2002ro-hDTzQ8 • Jan 9, 2012

    Hello.

    I recreated the hole code(spi main speed is 0.72 MHz) and inserted into the schematic a logic port analyzer(<a href="https://www.pctestinstruments.com/" target="_blank" rel="nofollow noopener noreferrer">    Intronix 34 Channel 500MHz PC-Based Logic Analyzer Just $439 - Includes CAN, I2C, SPI, RS232 Interpreters</a>) to sniffer the protocol.
    I create a while loop to see if the communication is working:

    while(1){
            for(j=0;j<5;j++)
            {
                WriteArr[j]=RX0_Address[j];
            }
            SPI_Write_Buf((WRITE_REG|10),&(WriteArr[0]),5);
        }
    (WRITE_REG|10) = 0x2a;
    WriteArr[0] = 0x34
    WriteArr[1] = 0x43
    WriteArr[2] = 0x10
    WriteArr[3] = 0x10
    WriteArr[4] = 0x1

    [​IMG]

    As you can see, in to the picture the protocol is running well, but the values read from registers are the same as the last time.

    P.S: I also aded this line of code to read all of the registers

    for(j=0;j<0x17;j++)
                test_data1[j] = SPI_Read_Reg(j);

    What to think?

    And the output is the same as yesterday 😔.
    [​IMG]

    I added the project.

  • Harshad Italiya

    @harshad-ukH5ww • Jan 9, 2012

    Well seems this time have to check all things again. Have to check your whole project too. Right now not able to access internet on desktop or laptop surfing from mobile only. But noted down your task will get back to you very soon. Sorry for the delay.

  • fantomas2002ro

    @fantomas2002ro-hDTzQ8 • Jan 9, 2012

    Thank you very much. I don't know what is going wrong. I ported the program for lpc1343, that's all.
    I have two lpcxpresso boards and two rfm70 module. I do not think I fried my two modules connected to different lpcxpresso board.

  • AaiRIz

    @aairiz-0qo8cU • May 9, 2012

    Sir, I am a new bee in RFM70

    so sir please help me to communicate with rfm70.
    please provide me the schematic & also the procedure for how to configure RFM70 as transmitter or as a receiver.

    Waiting for your reply.
    Thanks.

  • Harshad Italiya

    @harshad-ukH5ww • May 9, 2012

    AaiRIzSir, I am a new bee in RFM70

    so sir please help me to communicate with rfm70.
    please provide me the schematic & also the procedure for how to configure RFM70 as transmitter or as a receiver.

    Waiting for your reply.
    Thanks.

    Which microcontroller you are going to use? Have you gone through the RFM70 Datasheet?

  • fantomas2002ro

    @fantomas2002ro-hDTzQ8 • May 9, 2012

    After all the trouble I didn't manage to have a communication between these 2 modules. I outher words I can't help you 😔

  • Harshad Italiya

    @harshad-ukH5ww • May 10, 2012

    fantomas2002roAfter all the trouble I didn't manage to have a communication between these 2 modules. I outher words I can't help you 😔

    Still you want to give it a try? then Lets start again.

  • ky3orr

    @ky3orr-szi0Qi • Jul 2, 2012

    Hello Gents,

    I am working now on project that incorporates RFM70 modules.
    I was reading what You'd posted here and I am concerned about modules addressing scheme.

    You state that TX address should be different that RX_0 on the same module and that those should be crossed between two connecting modules: TX addx (PTX)= RX_0 addr (PRX) and RX_0 addr (PTX) = TX addr (PRX).

    In documentation of the RFM70 it is stated that TX addr of PTX should be the same as RX address of the pipe You want to send data for selected PRX module. Also if You'd like to make use of ACK packets in PTX module its RX_0 addr should be the same sa TX addx (because PRX module takes address of the pipe on which it received packet with ACK request and sends ACK back to the same address).

    So it such configuration we would have two modules with the same address sets. Why It should work? At the same time both modules are in oposite modes (PTX, PRX), so they are not listening from/sending to themselves 😀

    That's my concern about crossing addresses, You say it's working. 😀

    Anyway - I am trying to get receiver working. I believe transmitter is sending data, but there is nothing on receiver side, so I really don't know where is the problem.
    My question is: For PTX is it needed to generate positive CE pulse each time I am sending data to TX_FIFO, or it is sufficient if I just hold it logical 1 all the time I am in TX mode?
    Is packet generated and aired just after payload data was put in TX_FIFO?

    thanks for any hints.

    regards

  • Harshad Italiya

    @harshad-ukH5ww • Jul 2, 2012

    #-Link-Snipped-# I have tried to make it working with same address field and few days back I come to know that it is working.

    now regarding your problem have you checked that your SPI is properly working? By writing and reading one Register you can check it out.

    you can keep CE pin active high everytime.

  • ky3orr

    @ky3orr-szi0Qi • Jul 3, 2012

    #-Link-Snipped-#

    thanks for answer. My SPI is working and all the stuff i am writing is readable 😀

    Today I was going again through list of examples and I've found that in datasheet for bank1 manufacturer is saying:
    "Must write with 0xD99E860B(High Power), For single carrier mode:0xD99E8621".
    It is not said which values are for which occasions and if use only one or both...
    In software example they initialize it with 0xf99E860B that looks like nothing fron datasheet 😛
    Moreover they also write, after that, to bank1 address 4 such two weird things: 0x(f9 | 0x6)9E860B and later on 0x(f9 & ~0x6)9E860B.

    what tha...?

    Anyone could explain me, please, where such things are explained and why in example initialization is different than in datasheet? 😀

    Weird - isn't it?

    regards

  • Harshad Italiya

    @harshad-ukH5ww • Jul 3, 2012

    ky3orr#-Link-Snipped-#

    thanks for answer. My SPI is working and all the stuff i am writing is readable 😀

    Today I was going again through list of examples and I've found that in datasheet for bank1 manufacturer is saying:
    "Must write with 0xD99E860B(High Power), For single carrier mode:0xD99E8621".
    It is not said which values are for which occasions and if use only one or both...
    In software example they initialize it with 0xf99E860B that looks like nothing fron datasheet 😛
    Moreover they also write, after that, to bank1 address 4 such two weird things: 0x(f9 | 0x6)9E860B and later on 0x(f9 & ~0x6)9E860B.

    what tha...?

    Anyone could explain me, please, where such things are explained and why in example initialization is different than in datasheet? 😀

    Weird - isn't it?

    regards

    Ah that is weird I never give it attention. You can mail HopeRF they will surely reply to your this query.

  • Harshad Italiya

    @harshad-ukH5ww • Jul 3, 2012

    I'll spare some time for this but not possible in next few days..

  • ky3orr

    @ky3orr-szi0Qi • Jul 10, 2012

    Ok then,

    Is it possible for You to do a dump of RFMs register values after power up and after successful configuration?
    I can't bring those modules to life so maybe there is some bug in my initialization.

    I did it partly this morning and I see that there are some registers (bank1) that give all 0's while reading them but anyway It would be nice just to print out values of ALL registers (both banks) found in spec and just compare those.

    I hope it is not so much effort for You, as You do have already running modules.

    I asked HopeRF for detailed description of the registers, and mentioned the difference in spec and example code, but they say "use sample code" and "go to max supply voltage".

    If anyone could help I will appreciate.
    Is it needed to post sample code of dump routine in C?

    regards

  • ky3orr

    @ky3orr-szi0Qi • Jul 10, 2012

    This is my configuration for receiver (decimal notation).

    --- Bank 0 ---
    0 -> 127
    1 -> 63
    2 -> 63
    3 -> 3
    4 -> 63
    5 -> 40
    6 -> 48
    7 -> 14
    8 -> 0
    9 -> 0
    10 -> 231
    11 -> 165
    12 -> 195
    13 -> 196
    14 -> 197
    15 -> 198
    16 -> 231
    17 -> 0
    18 -> 0
    19 -> 0
    20 -> 0
    21 -> 0
    22 -> 0
    23 -> 17
    24 -> 0
    25 -> 0
    26 -> 0
    27 -> 0
    28 -> 63
    29 -> 4
    --- Bank 1 ---
    0 -> 0, 0, 0, 0,
    1 -> 0, 0, 0, 0,
    2 -> 0, 0, 0, 0,
    3 -> 0, 0, 0, 0,
    4 -> 0, 0, 0, 0,
    5 -> 0, 0, 0, 0,
    6 -> 0, 0, 0, 0,
    7 -> 142, 0, 0, 0,
    8 -> 99, 0, 0, 0,
    9 -> 0, 0, 0, 0,
    10 -> 0, 0, 0, 0,
    11 -> 0, 0, 0, 0,
    12 -> 0, 18, 115, 0,
    13 -> 54, 180, 128, 0,
    14 -> 65, 32, 8, 4, 129, 32, 207, 247, 254, 255, 255,
    

    Transmitter gets the same with difference that PRX=0.

    Could You take a look if all is ok or post Yours register dump?

    regards

  • ky3orr

    @ky3orr-szi0Qi • Jul 10, 2012

    @#-Link-Snipped-# I was trying to run sample code but it didn;t worked.
    Is it some special way of setting CE after sending payload to the buffer?
    I am asking because right now CE is always high after initialization, but it seems not working as I do not see anything received on receiver side.

    As I understand after initialization if I use write payload with no ack receiver should get aired data?

    could You share Your library with init and important routines code?

    Mine is below:

    static uint8_t init_values_bank0_addresses[][6] = {
    {0x10, 0xE7, 0x18, 0xE7, 0x18, 0xFF},    //default transmit address (packets go to PRX with that addr)
    {0x0A, 0xE7, 0x18, 0xE7, 0x18, 0xFF},    //default receive address for pipe0 (the same as above for ACK's)
    {0x0B, 0xA5, 0x5A, 0xA5, 0x5A, 0x01}    //default receive address for pipe1
    };
     
    static uint8_t init_values_bank0[][2] = {
        #if PRX_MODULE == 1
            {0x00, 0x7F},    //no interrupts, 2-byte CRC, power up, PRX
        #else
            {0x00, 0x7E},    //no interrupts, 2-byte CRC, power up, PTX
        #endif
        {0x01, 0x3F},    //auto acknowledgment for all pipes
        {0x02, 0x3F},    //enable RX for all pipes
        {0x03, 0x03},    //address length 5 bytes
        {0x04, 0x3F},    //up to 15 retransmissions with delay of 1000[us]
        {0x05, 0x28},    //initial channel 40 (2440[MHz])
        //{0x06, 0x35},    //LNA high gain, TX power 0[dBm], burst air rate 1[Mbit]
        {0x06, 0x30},    //LNA low gain, TX power -10[dBm], burst air rate 1[Mbit]
        {0x07, 0x07},    //status written with default value (reset int flags)
        {0x0C, 0xC3},    //default RX address LSB for pipe2
        {0x0D, 0xC4},    //default RX address LSB for pipe3
        {0x0E, 0xC5},    //default RX address LSB for pipe4
        {0x0F, 0xC6},    //default RX address LSB for pipe5
        {0x11, 0x00},  //payload length not used for pipe0 (dynamic payload)
        {0x12, 0x00},  //payload length not used for pipe1 (dynamic payload)
        {0x13, 0x00},  //payload length not used for pipe2 (dynamic payload)
        {0x14, 0x00},  //payload length not used for pipe3 (dynamic payload)
        {0x15, 0x00},  //payload length not used for pipe4 (dynamic payload)
        {0x16, 0x00},  //payload length not used for pipe5 (dynamic payload)
        {0x1C, 0x3F},    //enable reception with dynamic payload for all pipes
        {0x1D, 0x04}    //enable transmissions with dynamic payload, no ACK
    };
     
    static uint8_t init_values_bank1[][5] = {
        {0x00, 0x40, 0x4B, 0x01, 0xE2},    //default
        {0x01, 0xC0, 0x4B, 0x00, 0x00},    //default
        {0x02, 0xD0, 0xFC, 0x8C, 0x02},    //default
        {0x03, 0x99, 0x00, 0x39, 0x41},    //default
        //{0x04, 0xD9, 0x9E, 0x86, 0x0B},    //High Power
        {0x04, 0xF9, 0x9E, 0x86, 0x0B},
        {0x05, 0x24, 0x06, 0x7F, 0xA6},    //Disable RSSI
            //reversed
        {0x0C, 0x00, 0x12, 0x73, 0x00}, //default
        {0x0D, 0x36, 0xB4, 0x80, 0x00}    //default
    };
     
    static uint8_t init_values_bank1_14[12] = {0x0E, 0x41, 0x20, 0x08, 0x04, 0x81, 0x20, 0xCF, 0xF7, 0xFE, 0xFF, 0xFF};    //default
     
    void RFM70_set_CS(uint8_t value) {
        if (value) {
            RFM70_PORT_CS |= (1<<RFM70_CS);
        } else {
            RFM70_PORT_CS &= ~(1<<RFM70_CS);
        }
    }
     
    void RFM70_set_CE(uint8_t value) {
        if (value) {
            RFM70_PORT_CE |= (1<<RFM70_CE);
        } else {
            RFM70_PORT_CE &= ~(1<<RFM70_CE);
        }
    }
     
    uint8_t RFM70_byte_io(uint8_t data_byte) {
        SPDR = data_byte;                        //load data into buffer
        while(!(SPSR & (1<<SPIF)));                //wait for transmission to finish
        return SPDR;                            //read data back and return it
    }
     
    void RFM70_use_bank(uint8_t bank_no) {
        uint8_t active_bank;
     
        bank_no = (bank_no) ? 1 : 0;
        RFM70_set_CS(0);
        active_bank = (RFM70_byte_io(READ_STATUS) & (1<<RBANK)) ? 1 : 0;
        RFM70_set_CS(1);
        if (bank_no ^ active_bank) {            //if set other bank - change it
            RFM70_set_CS(0);
            RFM70_byte_io(ACTIVATE);
            RFM70_byte_io(TOGGLE_BANK);
            RFM70_set_CS(1);
        }     
    }
     
    void RFM70_enable_features(uint8_t features) {
        uint8_t feature_register;
     
        RFM70_set_CS(0);
        RFM70_byte_io(R_REGISTER | FEATURE);
        feature_register = RFM70_byte_io(READ_BYTE);
        RFM70_set_CS(1);
     
        if (feature_register != features) {
            RFM70_set_CS(0);
            RFM70_byte_io(W_REGISTER | FEATURE);
            RFM70_byte_io(features);
            RFM70_set_CS(1);
         
            RFM70_set_CS(0);
            RFM70_byte_io(R_REGISTER | FEATURE);
            feature_register = RFM70_byte_io(READ_BYTE);
            RFM70_set_CS(1);
            if (feature_register != features) {
                RFM70_set_CS(0);
                RFM70_byte_io(ACTIVATE);
                RFM70_byte_io(FEATURES);
                RFM70_set_CS(1);
            }         
        }
    }
     
    void RFM70_init() {
        uint8_t row_counter, element_counter;
        volatile uint16_t delay_counter;
     
        //prepare external signals
        RFM70_DDR_CE |= (1<<RFM70_CE);            //CE as an output
        RFM70_PORT_CE &= ~(1<<RFM70_CE);        //0 by default (STBY RFM70)
        RFM70_DDR_CS |= (1<<RFM70_CS);            //CS as an output
        RFM70_PORT_CS |= (1<<RFM70_CS);            //1 by default (idle SPI)
        //delay before transmission
        delay_counter = 0xFFFF;
        while (delay_counter--);
        //enable features setting
        RFM70_enable_features(0x1); //anything !=0 for features acivation
        RFM70_enable_features(0x0); //0 (default) in case nothing is set during init
        //initialize register bank0
        RFM70_use_bank(0);
        delay_counter = 0xFFFF;
        while (delay_counter--);
        for (row_counter = 0; row_counter < (sizeof(init_values_bank0) / sizeof(init_values_bank0[0])); row_counter++) {
            RFM70_set_CS(0);
            RFM70_byte_io(W_REGISTER | init_values_bank0[row_counter][0]);
            for (element_counter = 1; element_counter < (sizeof(init_values_bank0[0]) / sizeof(init_values_bank0[0][0])); element_counter++) {
                RFM70_byte_io(init_values_bank0[row_counter][element_counter]);
            }
            RFM70_set_CS(1);
        }
        for (row_counter = 0; row_counter < (sizeof(init_values_bank0_addresses) / sizeof(init_values_bank0_addresses[0])); row_counter++) {
            RFM70_set_CS(0);
            RFM70_byte_io(W_REGISTER | init_values_bank0_addresses[row_counter][0]);
            for (element_counter = 1; element_counter < (sizeof(init_values_bank0_addresses[0]) / sizeof(init_values_bank0_addresses[0][0])); element_counter++) {
                RFM70_byte_io(init_values_bank0_addresses[row_counter][element_counter]);
            }
            RFM70_set_CS(1);
        }
        //delay
        delay_counter = 0xFFFF;
        while (delay_counter--);
        //initialize register bank1
        RFM70_use_bank(1);
        delay_counter = 0xFFFF;
        while (delay_counter--);
        for (row_counter = 0; row_counter < (sizeof(init_values_bank1) / sizeof(init_values_bank1[0])); row_counter++) {
            RFM70_set_CS(0);
            RFM70_byte_io(W_REGISTER | init_values_bank1[row_counter][0]);
            for (element_counter = 1; element_counter < (sizeof(init_values_bank1[0]) / sizeof(init_values_bank1[0][0])); element_counter++) {
                RFM70_byte_io(init_values_bank1[row_counter][element_counter]);
            }
            RFM70_set_CS(1);
        }
        RFM70_set_CS(0);
        RFM70_byte_io(W_REGISTER | init_values_bank1_14[0]);
        for (element_counter = 1; element_counter < (sizeof(init_values_bank1_14) / sizeof(init_values_bank1_14[0])); element_counter++) {
            RFM70_byte_io(init_values_bank1_14[element_counter]);
        }
        //writing again bank1, reg4 with 24 and 25 bit toggling
        for (row_counter = 0; row_counter < 2; row_counter++) {
            RFM70_set_CS(0);
            RFM70_byte_io(W_REGISTER | 0x4);
            for (element_counter = 1; element_counter < (sizeof(init_values_bank1[0]) / sizeof(init_values_bank1[0][0])); element_counter++) {
                switch (element_counter) {
                    case 1:
                        if (row_counter == 0) {
                            RFM70_byte_io(init_values_bank1[4][element_counter] | 0x6);
                        } else {
                            RFM70_byte_io(init_values_bank1[4][element_counter] & ~(0x6));
                        }
                        break;
                    default:
                        RFM70_byte_io(init_values_bank1[4][element_counter]);
                        break;
                }
            }
            RFM70_set_CS(1);
        }
        //delay before transmission
        delay_counter = 0xFFFF;
        while (delay_counter--);
        //restore bank0
        RFM70_use_bank(0);
    }
     
    void tx_fifo_flush(void) {
        RFM70_set_CS(0);
        RFM70_byte_io(FLUSH_TX);
        RFM70_set_CS(1);
    }
     
    void rx_fifo_flush(void) {
        RFM70_set_CS(0);
        RFM70_byte_io(FLUSH_RX);
        RFM70_set_CS(1);
    }
     
    void transmitter_mode(void) {
        uint8_t status, config;
        //flush fifo
        tx_fifo_flush();
        //standby
        RFM70_set_CE(0);
        //reset active interrupt flags
        RFM70_set_CS(0);
        status = RFM70_byte_io(READ_STATUS);
        RFM70_set_CS(1);
        RFM70_set_CS(0);
        RFM70_byte_io(W_REGISTER | STATUS);
        RFM70_byte_io(status);
        RFM70_set_CS(1);
        //switch to tx mode
        RFM70_set_CS(0);
        RFM70_byte_io(R_REGISTER | CONFIG);
        config = RFM70_byte_io(READ_BYTE);
        RFM70_set_CS(1);
        config &= ~(1<<PRIM_RX);
        RFM70_set_CS(0);
        RFM70_byte_io(W_REGISTER | CONFIG);
        RFM70_byte_io(config);
        RFM70_set_CS(1);
        //go active
        RFM70_set_CE(1);
    }
     
    void receiver_mode(void) {
        uint8_t status, config;
        //flush fifo
        rx_fifo_flush();
        //standby
        RFM70_set_CE(0);
        //reset active interrupt flags
        RFM70_set_CS(0);
        status = RFM70_byte_io(READ_STATUS);
        RFM70_set_CS(1);
        RFM70_set_CS(0);
        RFM70_byte_io(W_REGISTER | STATUS);
        RFM70_byte_io(status);
        RFM70_set_CS(1); 
        //switch to rx mode
        RFM70_set_CS(0);
        RFM70_byte_io(R_REGISTER | CONFIG);
        config = RFM70_byte_io(READ_BYTE);
        RFM70_set_CS(1);
        config |= (1<<PRIM_RX);
        RFM70_set_CS(0);
        RFM70_byte_io(W_REGISTER | CONFIG);
        RFM70_byte_io(config);
        RFM70_set_CS(1);
        //go active
        RFM70_set_CE(1);
    }
     
    void write_payload(uint8_t *data, uint8_t size) {
        uint8_t element_counter;
     
        if (size > 32) { size = 32;    }
     
        RFM70_set_CS(0);
        RFM70_byte_io(W_TX_PAYLOAD);
        for (element_counter = 0; element_counter < size; element_counter++) {
            RFM70_byte_io(data[element_counter]);
        } 
        RFM70_set_CS(1);
    }
     
    void write_payload_no_ack(uint8_t *data, uint8_t size) {
        uint8_t element_counter;
     
        if (size > 32) { size = 32;    }
     
        RFM70_set_CS(0);
        RFM70_byte_io(W_TX_PAYLOAD_NOACK);
        for (element_counter = 0; element_counter < size; element_counter++) {
            RFM70_byte_io(data[element_counter]);
        }
        RFM70_set_CS(1);
    }
     
    uint8_t data_transmitted(void) {
        uint8_t status;
     
        RFM70_set_CS(0);
        status = RFM70_byte_io(READ_STATUS);
        RFM70_set_CS(1);
     
        if (status & (1<<TX_DS)) {
            RFM70_set_CS(0);
            RFM70_byte_io(W_REGISTER | STATUS);
            //RFM70_byte_io(status |= (1<<TX_DS));
            RFM70_byte_io(status);
            RFM70_set_CS(1);
            return 1;
        }
        return 0;
    }
     
    uint8_t data_received(void) {
        uint8_t status;
     
        RFM70_set_CS(0);
        status = RFM70_byte_io(READ_STATUS);
        RFM70_set_CS(1);
     
        if (status & (1<<RX_DR)) {
            RFM70_set_CS(0);
            RFM70_byte_io(W_REGISTER | STATUS);
            RFM70_byte_io(status |= (1<<RX_DR));
            RFM70_set_CS(1);
            return 1;
        }
        return 0;
    }
     
    uint8_t read_payload_length(void) {
        uint8_t payload_length;
     
        RFM70_set_CS(0);
        RFM70_byte_io(R_RX_PL_WID);
        payload_length = RFM70_byte_io(READ_BYTE);
        RFM70_set_CS(1);
     
        return payload_length;
    }
     
    void read_payload(uint8_t *payload_buffer, uint8_t size) {
        uint8_t index;
     
        RFM70_set_CS(0);
        RFM70_byte_io(R_RX_PAYLOAD);
        for (index = 0; index < size; index++) {
            payload_buffer[index] = RFM70_byte_io(READ_BYTE);
        }
        RFM70_set_CS(1);
        payload_buffer[index] = '\0';
    }
     
    

    regards

  • Harshad Italiya

    @harshad-ukH5ww • Jul 10, 2012

    Ok it will take some time as I am away from my PC but meanwhile you can check your SPI routine using Registor read write. If it works fine we can focus on CE pin only.

  • ky3orr

    @ky3orr-szi0Qi • Jul 10, 2012

    Yes, SPI is working. It is visible in register dump. Data read from the device is consistent with those used during initialization.
    I also did example code to see if CE pin can toggle its value - it's working.

    I am wondering if all is set up correctly.
    Maybe some delays I forgot.
    I am most interested in Your banks initialization values and order of setting them.

    If You could post Your code it would be much easier and the fastest way to find differences.

    Anyway thanks for Your interest in my problem. I hope it will work soon 😀

    regards

  • Harshad Italiya

    @harshad-ukH5ww • Jul 10, 2012

    ky3orrYes, SPI is working. It is visible in register dump. Data read from the device is consistent with those used during initialization.
    I also did example code to see if CE pin can toggle its value - it's working.

    I am wondering if all is set up correctly.
    Maybe some delays I forgot.
    I am most interested in Your banks initialization values and order of setting them.

    If You could post Your code it would be much easier and the fastest way to find differences.

    Anyway thanks for Your interest in my problem. I hope it will work soon 😀

    regards

    Yes mostly by today I'll post codes.

  • ky3orr

    @ky3orr-szi0Qi • Jul 10, 2012

    Thanks,

    right now I am guessing that I might do have a problem because in register 1D bank0 I set only EN_DPL but I guess I also should enable EN_DYN_ACK while sending data with W_TX_PAYLOAD_NO_ACK command...

    Maybe that's why receiver can't receive anything because I am not letting it to get any of air frames without ACK.
    Is my thinking right?

    I guess if I set all pipes to work in ACK mode and if I want to send data without ACK needed I should use W_TX_PAYLOAD_NO_ACK command then (so EN_DYN_ACK should be enabled in features)?

    best regards

  • Harshad Italiya

    @harshad-ukH5ww • Jul 11, 2012

    #include <hidef.h> /* for EnableInterrupts macro */
    #include "derivative.h" /* include peripheral declarations */
    #include "RF70.h"
    #include "pindef.h"

    UINT8 op_status;

    extern unsigned int test;



    //Bank1 register initialization value

    //In the array RegArrFSKAnalog,all the register value is the byte reversed!!!!!!!!!!!!!!!!!!!!!
    const unsigned long Bank1_Reg0_13[]={ //latest config txt
    0xE2014B40,
    0x00004BC0,
    0x028CFCD0,
    0x41390099,
    0x0B869Ef9,
    0xA67F0624,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00127300,
    0x36B48000,
    };

    const UINT8 Bank1_Reg14[]=
    {
    0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF,0xFF
    };

    //Bank0 register initialization value
    const UINT8 Bank0_Reg[][2]={
    {0,0x0F},//reflect RX_DR\TX_DS\MAX_RT,Enable CRC ,2byte,POWER UP,PRX
    {1,0x3F},//Enable auto acknowledgement data pipe5\4\3\2\1\0
    {2,0x3F},//Enable RX Addresses pipe5\4\3\2\1\0
    {3,0x03},//RX/TX address field width 5byte
    {4,0xff},//auto retransmission dalay (4000us),auto retransmission count(15)
    {5,0x17},//23 channel
    {6,0x1f/*0x17*/},//air data rate-1M,out power 5dbm,setup LNA gain
    {7,0x07},//
    {8,0x00},//
    {9,0x00},
    {12,0xc3},//only LSB Receive address data pipe 2, MSB bytes is equal to RX_ADDR_P1[39:8]
    {13,0xc4},//only LSB Receive address data pipe 3, MSB bytes is equal to RX_ADDR_P1[39:8]
    {14,0xc5},//only LSB Receive address data pipe 4, MSB bytes is equal to RX_ADDR_P1[39:8]
    {15,0xc6},//only LSB Receive address data pipe 5, MSB bytes is equal to RX_ADDR_P1[39:8]
    {17,0x20},//Number of bytes in RX payload in data pipe0(32 byte)
    {18,0x20},//Number of bytes in RX payload in data pipe1(32 byte)
    {19,0x20},//Number of bytes in RX payload in data pipe2(32 byte)
    {20,0x20},//Number of bytes in RX payload in data pipe3(32 byte)
    {21,0x20},//Number of bytes in RX payload in data pipe4(32 byte)
    {22,0x20},//Number of bytes in RX payload in data pipe5(32 byte)
    {23,0x00},//fifo status
    {28,0x3F},//Enable dynamic payload length data pipe5\4\3\2\1\0
    {29,0x07}//Enables Dynamic Payload Length,Enables Payload with ACK,Enables the W_TX_PAYLOAD_NOACK command
    };


    #ifdef device1
    const UINT8 Tx_address[] ={0x00,0x00,0x00,0x00,0x01}; // Transmitter Address.
    const UINT8 RX0_Address[]={0x00,0x00,0x00,0x00,0x02};//Receive address data pipe 0
    const UINT8 RX1_Address[]={0x00,0x00,0x00,0x00,0x03};////Receive address data pipe 1
    #endif

    #ifdef device2
    const UINT8 Tx_address[] ={0x00,0x00,0x00,0x00,0x02}; // Transmitter Address.
    const UINT8 RX0_Address[]={0x00,0x00,0x00,0x00,0x01};//Receive address data pipe 0
    const UINT8 RX1_Address[]={0x00,0x00,0x00,0x00,0x03};////Receive address data pipe 1
    #endif

    #ifdef device3
    const UINT8 Tx_address[] ={0x00,0x00,0x00,0x00,0x03}; // Transmitter Address.
    const UINT8 RX0_Address[]={0x00,0x00,0x00,0x00,0x01};//Receive address data pipe 0
    const UINT8 RX1_Address[]={0x00,0x00,0x00,0x00,0x02};////Receive address data pipe 1
    #endif

    extern UINT8 test_data;
    extern UINT8 channel;
    extern UINT8 power;
    extern UINT8 data_rate;
    extern UINT8 rx_buf[MAX_PACKET_LEN];


    extern void delay_200ms(void);
    extern void delay_50ms(void);
    ///////////////////////////////////////////////////////////////////////////////
    // SPI access //
    ///////////////////////////////////////////////////////////////////////////////

    ///////////////////////////////////////////////////////////
    // Function: SPI_RW();
    //
    //Description:
    // Writes one UINT8 to RFM70, and return the UINT8 read
    //////////////////////////////////////////////////////////

    UINT8 SPI_RW(UINT8 value)
    {
    UINT8 bit_ctr;
    for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
    {
    if(value & 0x80)
    {
    MOSI = 1;
    }
    else
    {
    MOSI=0;
    }
    value = (value << 1); // shift next bit into MSB..
    SCK = 1; // Set SCK high..
    // asm(nop);
    value |= MISO; // capture current MISO bit
    SCK = 0; // ..then set SCK low again
    }
    return(value); // return read UINT8
    }

    //**************************************************
    //Function: SPI_Write_Reg();
    //
    //Description:
    // Writes value 'value' to register 'reg'
    //**************************************************/
    void SPI_Write_Reg(UINT8 reg, UINT8 value) //--unsigned int UINT8
    {
    CSN = 0; // CSN low, init SPI transaction
    op_status = SPI_RW(reg); // select register
    op_status = SPI_RW(value); // ..and write value to it..
    CSN = 1; // CSN high again
    }


    //**************************************************/

    //**************************************************
    //Function: SPI_Read_Reg();
    //
    //Description:
    // Read one UINT8 from BK2421 register, 'reg'
    //**************************************************/
    UINT8 SPI_Read_Reg(UINT8 reg)
    {

    UINT8 value;
    CSN = 0; // CSN low, initialize SPI communication...
    op_status=SPI_RW(reg); // Select register to read from..
    value = SPI_RW(0); // ..then read register value
    CSN = 1; // CSN high, terminate SPI communication
    asm(NOP);
    return(value); // return register value
    }
    //**************************************************/

    //**************************************************
    //Function: SPI_Read_Buf();
    //
    //Description:
    // Reads 'length' #of length from register 'reg'
    //**************************************************/
    void SPI_Read_Buf(UINT8 reg, UINT8 *pBuf, UINT8 length)
    {
    UINT8 status,byte_ctr;

    CSN = 0; // Set CSN l
    status = SPI_RW(reg); // Select register to write, and read status UINT8

    for(byte_ctr=0;byte_ctr<length;byte_ctr++)
    pBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read UINT8 from RFM70

    CSN = 1; // Set CSN high again

    }
    //**************************************************/

    //**************************************************
    //Function: SPI_Write_Buf();
    //
    //Description:
    // Writes contents of buffer '*pBuf' to RFM70
    //**************************************************/
    void SPI_Write_Buf(UINT8 reg, UINT8 *pBuf, UINT8 length)
    {
    UINT8 byte_ctr;

    CSN = 0; // Set CSN low, init SPI tranaction
    op_status = SPI_RW(reg); // Select register to write to and read status UINT8
    for(byte_ctr=0; byte_ctr<length; byte_ctr++) // then write all UINT8 in buffer(*pBuf)
    SPI_RW(*pBuf++);
    CSN = 1; // Set CSN high again

    }
    //**************************************************
    //Function: SwitchToRxMode();
    //Description:
    // switch to Rx mode
    //**************************************************/
    void SwitchToRxMode()
    {
    UINT8 value;

    SPI_Write_Reg(FLUSH_RX,0);//flush Rx

    value=SPI_Read_Reg(STATUS); // read register STATUS's value
    SPI_Write_Reg(WRITE_REG|STATUS,value);// clear RX_DR or TX_DS or MAX_RT interrupt flag

    CE=0;

    value=SPI_Read_Reg(CONFIG); // read register CONFIG's value
    test = value;

    //PRX
    value=value|0x01;//set bit 1
    SPI_Write_Reg(WRITE_REG | CONFIG, value); // Set PWR_UP bit, enable CRC(2 length) & Prim:RX. RX_DR enabled..
    CE=1;
    }

    //**************************************************
    //Function: SwitchToTxMode();
    //Description:
    // switch to Tx mode
    ///**************************************************/
    void SwitchToTxMode()
    {
    UINT8 value;
    SPI_Write_Reg(FLUSH_TX,0);//flush Tx

    CE=0;
    value=SPI_Read_Reg(CONFIG); // read register CONFIG's value
    //PTX
    value=value&0xfe; //set bit 0
    SPI_Write_Reg(WRITE_REG | CONFIG, value); // Set PWR_UP bit, enable CRC(2 length) & Prim:RX. RX_DR enabled.

    CE=1;
    }

    //**************************************************
    //Function: SwitchCFG();
    //
    //Description:
    // access switch between Bank1 and Bank0

    ///Parameter:
    // _cfg 1:register bank1
    // 0:register bank0
    //Return:
    // None
    //**************************************************/
    void SwitchCFG(char _cfg)//1:Bank1 0:Bank0
    {
    UINT8 Tmp;

    Tmp=SPI_Read_Reg(7);
    Tmp=Tmp&0x80;

    if( ( (Tmp)&&(_cfg==0) )
    ||( ((Tmp)==0)&&(_cfg) ) )
    {
    SPI_Write_Reg(ACTIVATE_CMD,0x53);
    }
    }

    ///**************************************************
    //Function: SetChannelNum();
    //Description:
    // set channel number
    //
    //**************************************************/
    void SetChannelNum(UINT8 ch)
    {
    SPI_Write_Reg((UINT8)(WRITE_REG|5),(UINT8)(ch));
    }



    ///////////////////////////////////////////////////////////////////////////////
    // RFM70 initialization //
    ///////////////////////////////////////////////////////////////////////////////
    //**************************************************
    //Function: RFM70_Initialize();
    ///
    //Description:
    // register initialization
    //**************************************************/
    void RFM70_Initialize()
    {
    UINT8 i,j,temp;
    UINT8 WriteArr[12];

    //DelayMs(100);//delay more than 50ms.
    delay_200ms();

    SwitchCFG(0);

    for(i=0;i<20;i++)
    {
    SPI_Write_Reg((WRITE_REG|Bank0_Reg[0]),Bank0_Reg[1]);
    }

    for(j=0;j<5;j++)
    {
    WriteArr[j]=RX0_Address[j];
    }
    SPI_Write_Buf((WRITE_REG|10),&(WriteArr[0]),5);

    //REG 11 - Rx1 addr
    for(j=0;j<5;j++)
    {
    WriteArr[j]=RX1_Address[j];
    }
    SPI_Write_Buf((WRITE_REG|11),&(WriteArr[0]),5);

    //REG 16 - TX addr
    for(j=0;j<5;j++)
    {
    WriteArr[j]=Tx_address[j];
    }
    SPI_Write_Buf((WRITE_REG|16),&(WriteArr[0]),5);

    // printf("\nEnd Load Reg");

    i=SPI_Read_Reg(29);//read Feature Register ���Ҫ֧�ֶ�̬���Ȼ��� Payload With ACK����Ҫ�ȸ�оƬ���� ACTIVATE������Ϊ0x73),Ȼ��ʹ�ܶ�̬���Ȼ��� Payload With ACK (REG28,REG29).

    if(i==0) // i!=0 showed that chip has been actived.so do not active again.
    SPI_Write_Reg(ACTIVATE_CMD,0x73);// Active

    for(i=22;i>=21;i--)
    {
    SPI_Write_Reg((WRITE_REG|Bank0_Reg[0]),Bank0_Reg[1]);
    //SPI_Write_Reg_Bank0(Bank0_Reg[0],Bank0_Reg[1]);
    }

    //********************Write Bank1 register******************
    SwitchCFG(1);

    for(i=0;i<=8;i++)//reverse
    {
    for(j=0;j<4;j++)
    WriteArr[j]=(Bank1_Reg0_13>>(8*(j) ) )&0xff;

    SPI_Write_Buf((WRITE_REG|i),&(WriteArr[0]),4);
    }

    for(i=9;i<=13;i++)
    {
    for(j=0;j<4;j++)
    WriteArr[j]=(Bank1_Reg0_13>>(8*(3-j) ) )&0xff;

    SPI_Write_Buf((WRITE_REG|i),&(WriteArr[0]),4);
    }

    //SPI_Write_Buf((WRITE_REG|14),&(Bank1_Reg14[0]),11);
    for(j=0;j<11;j++)
    {
    WriteArr[j]=Bank1_Reg14[j];
    }
    SPI_Write_Buf((WRITE_REG|14),&(WriteArr[0]),11);

    //toggle REG4<25,26>
    for(j=0;j<4;j++)
    //WriteArr[j]=(RegArrFSKAnalog[4]>>(8*(j) ) )&0xff;
    WriteArr[j]=(Bank1_Reg0_13[4]>>(8*(j) ) )&0xff;

    WriteArr[0]=WriteArr[0]|0x06;
    SPI_Write_Buf((WRITE_REG|4),&(WriteArr[0]),4);

    WriteArr[0]=WriteArr[0]&0xf9;
    SPI_Write_Buf((WRITE_REG|4),&(WriteArr[0]),4);

    //**************************Test spi*****************************//
    //SPI_Write_Reg((WRITE_REG|Bank0_Reg[2][0]),0x0f);
    //test_data = SPI_Read_Reg(0x02);


    //DelayMs(10);
    delay_50ms();

    //********************switch back to Bank0 register access******************
    SwitchCFG(0);
    SwitchToRxMode();//switch to RX mode
    }
    //**************************************************
    //Function: DelayMs();
    //
    //Description:
    // delay ms,please implement this function according to your MCU.
    //**************************************************/
    void DelayMs(UINT16 ms)
    {


    }

  • ky3orr

    @ky3orr-szi0Qi • Jul 11, 2012

    #-Link-Snipped-# thanks for that,

    It's pretty much the same with difference on 1D register and addressing idea.

    I will check If I could get modules working.

    BTW: As long as addresses for pipe0 and tx are different I assume You're using transmissions without ACK?
    I read in datasheet that those should be configured in that way because PRX sends back ACK packet to the PTX with address that is the same as PRX receiver pipe.

    regards

  • ky3orr

    @ky3orr-szi0Qi • Jul 11, 2012

    Bingo!
    I initialized register 1D with value 0x5 and everything is working.
    I do have link between two modules and it is possible now to transmit data.

    It wasn't working because I was transmitting with no ACK feature, that was not enabled on receiver side.

    thanks for help.

    regards

  • Harshad Italiya

    @harshad-ukH5ww • Jul 11, 2012

    ky3orrBingo!
    I initialized register 1D with value 0x5 and everything is working.
    I do have link between two modules and it is possible now to transmit data.

    It wasn't working because I was transmitting with no ACK feature, that was not enabled on receiver side.

    thanks for help.

    regards

    Great ! share your project video if you have no any issue. and looking forward to see you active on forum so we can help more and more people with our little knowledge.

  • ky3orr

    @ky3orr-szi0Qi • Jul 11, 2012

    No problem,
    I will surely would like to share something to the community but I need to overcome all problems 😀

    I was working now with polling readout of data and now I am shifting to the IRQ routine.

    My problem now is that ISR doesn't want to trigger relevant function - I need to investigate all AVR register settings.

    regards

  • Harshad Italiya

    @harshad-ukH5ww • Jul 11, 2012

    So you are going to connect IRQ of RF module to MCU's Interrupt pin? Make sure you need to provide sufficient delay to initialize Module on power up.

  • ky3orr

    @ky3orr-szi0Qi • Jul 11, 2012

    Yes, of course.

    I am investigating now interrupt response on atmega8 now. It seems not to work yet as I expected.
    So I believe it's just some misconfiguration.

    Do You know if IRQ pin of RFM70 is kind of CMOS/TTL/or OC?

    regards

  • Harshad Italiya

    @harshad-ukH5ww • Jul 12, 2012

    Yes TTL Logic. It remains High 3.3V and when receives data goes low.

  • Futterama

    @futterama-RLmhQR • Oct 3, 2012

    Hi there, newbie at this forum.

    I have been working with the RFM70 too, and I have overcome a lot of the wierd things about the RFM70. The one thing that annoys me right now, is that if I want to change PRIM_RX from 1 to 0 (change mode from RX to TX) I need to power down the module (clearing PWR_UP) before changing the mode, and then power back up. This is not in the datasheet.

    Also when powering back up, there need to be a delay for the module to power back up, but I can't find any info in the datasheet about how long the module needs to power up.

    A lot of trial and error need to be done with these devices since so many things are left out of the datasheet :-(

  • Harshad Italiya

    @harshad-ukH5ww • Oct 3, 2012

    FutteramaHi there, newbie at this forum.

    I have been working with the RFM70 too, and I have overcome a lot of the wierd things about the RFM70. The one thing that annoys me right now, is that if I want to change PRIM_RX from 1 to 0 (change mode from RX to TX) I need to power down the module (clearing PWR_UP) before changing the mode, and then power back up. This is not in the datasheet.

    Also when powering back up, there need to be a delay for the module to power back up, but I can't find any info in the datasheet about how long the module needs to power up.

    A lot of trial and error need to be done with these devices since so many things are left out of the datasheet :-(

    I have developed more than 15 application based on RFM70 and I never face such problem. Are you sure that you are following the proper initialization?

  • Futterama

    @futterama-RLmhQR • Oct 3, 2012

    godfatherI have developed more than 15 application based on RFM70 and I never face such problem. Are you sure that you are following the proper initialization?

    I am pretty sure, but when you say it like that, it makes me think.

    Another strange thing is that I get high packet loss when using 2 bytes CRC.

    I would be happy if you wanted to help check my initialization. Do you have a problem reading other peoples code or should I translate to pseudo code? I did make a lot of comments in the code to help track down errors.

  • Futterama

    @futterama-RLmhQR • Oct 3, 2012

    Do you initialize Bank1?

    HopeRF says the default values are fine and that the memory in Bank1 is non-volatile. But you need at least to initialize the register 04 in Bank1 if you want low power mode (which I do).

  • Harshad Italiya

    @harshad-ukH5ww • Oct 3, 2012

    FutteramaDo you initialize Bank1?

    HopeRF says the default values are fine and that the memory in Bank1 is non-volatile. But you need at least to initialize the register 04 in Bank1 if you want low power mode (which I do).

    I have used the reference code given by HopeRF and slight modification depend on my application parameter. I am afraid you might have changed some critical registers and because of that you are facing this issue.

    Post your initialization I will try my best to spent some time on same.

  • Futterama

    @futterama-RLmhQR • Oct 3, 2012

    Thanks, when I get the time, I will test for the problem again, but this time without changing any parameters in Bank1 and with an unused module. Then I will get back to you. I will probably not have time before tomorrow :-(

  • Harshad Italiya

    @harshad-ukH5ww • Oct 3, 2012

    FutteramaThanks, when I get the time, I will test for the problem again, but this time without changing any parameters in Bank1 and with an unused module. Then I will get back to you. I will probably not have time before tomorrow :-(

    Take your time and make code better. 😀

  • Futterama

    @futterama-RLmhQR • Oct 4, 2012

    Ok, I made some time for testing tonight.

    I have disabled all Bank1 writes so I only do a minimum of initialization on the RFM70 for testing.

    I made one setup (setup 1) which transmits a packet and another setup (setup 2) that receives it. After receiving the packet, dynamic payload length is read from the RX buffer and mode is changed to TX in setup 2 and a packet is sent. The packet is sent fine, but only if I don't read the dynamic payload length first! If I read the dynamic payload length first, the TX fails.

    My code for reading the dynamic payload length using the R_RX_PL_WID command:

    CSN = 0;                  // Start SPI communication
    SPI_RW(R_RX_PL_WID);      // Write command: Read RX-payload width
    PacketLen = SPI_RW(0);    // Read payload width
    CSN = 1;                  // End SPI communication)
    

    So somehow the RFM70 gets stuck when using the R_RX_PL_WID, maybe because there is something I missed on how to read this value?
    I must add that when I read the payload length value, I do get a valid value, but I must be shutting down the SPI communication in a wrong way?

  • Futterama

    @futterama-RLmhQR • Oct 4, 2012

    Ohh, I can read the dynamic payload AND make the TX work if I have a small delay (like 1us) between setting CS = 0 to enter standby-1 mode and reading the payload length. So the RFM70 needs a small amount of time before reading the payoad length after CE is set low (to disable RX and enter the standby-1 mode). I don't see this in the datasheet :-(

  • Futterama

    @futterama-RLmhQR • Oct 4, 2012

    Another thing I noticed. When a packet is received and the IRQ pin goes low, I read the RX_DR bit in the STATUS register, just to make sure the interrupt was caused by reception of a package.

    If I disable the RX by setting CE = 0 before I read the STATUS register, RX_DR will be 0. If I wait and set CE = 0 after I have read the STATUS register, RX_DR will be 1.

    I don't see this behavior in the datasheet either! And of course I want to disable the RX as soon as I have received a packet to conserve power.

  • Harshad Italiya

    @harshad-ukH5ww • Oct 4, 2012

    FutteramaOhh, I can read the dynamic payload AND make the TX work if I have a small delay (like 1us) between setting CS = 0 to enter standby-1 mode and reading the payload length. So the RFM70 needs a small amount of time before reading the payoad length after CE is set low (to disable RX and enter the standby-1 mode). I don't see this in the datasheet :-(

    Yes that is required as SPI is little slow for RFM70 and it is also good way to make communication in reliable way.

  • Harshad Italiya

    @harshad-ukH5ww • Oct 4, 2012

    FutteramaAnother thing I noticed. When a packet is received and the IRQ pin goes low, I read the RX_DR bit in the STATUS register, just to make sure the interrupt was caused by reception of a package.

    If I disable the RX by setting CE = 0 before I read the STATUS register, RX_DR will be 0. If I wait and set CE = 0 after I have read the STATUS register, RX_DR will be 1.

    I don't see this behavior in the datasheet either! And of course I want to disable the RX as soon as I have received a packet to conserve power.

    CE is used to for Chip Enable so if you are disabling RX by setting CE = 0 then after any of your command is not going to receive by RFM70 or say any SPI. So you must have to be sure that you have enabled CE pin of any SPI device before you are sending any command to SPI device.

    And what I suggest you can use CE in always enable mode if you are communicating with only one SPI device say RFM70.

  • Futterama

    @futterama-RLmhQR • Oct 4, 2012

    Well, maybe I got some things mixed up. In power down mode, all SPI registers are available. But the datasheet does not say anything about the SPI registers being available in standby-1 mode. It just says that standby-1 mode is the mode the RFM70 returns to after RX or TX when CE is low. But some registers must be available in this mode because I can change the PRIM_RX bit when CE is low. I will take a closer look with the thing in mind that CE is Chip Enable and also "SPI Enable" 😉

  • Harshad Italiya

    @harshad-ukH5ww • Oct 4, 2012

    FutteramaWell, maybe I got some things mixed up. In power down mode, all SPI registers are available. But the datasheet does not say anything about the SPI registers being available in standby-1 mode. It just says that standby-1 mode is the mode the RFM70 returns to after RX or TX when CE is low. But some registers must be available in this mode because I can change the PRIM_RX bit when CE is low. I will take a closer look with the thing in mind that CE is Chip Enable and also "SPI Enable" 😉

    Oh ! Then it would be really messy thing for you to get the list of the registers available in standby-1 mode.

    what is your application?

  • Futterama

    @futterama-RLmhQR • Oct 4, 2012

    I can tell you for sure, many registers are active in standby-1 mode (CE = 0) because I do ALL my initialization with CE held low. My understanding of the function of the CE pin is that it only controls the RFM70 mode between "RX/TX" and "standby-1". So with CE = 0 that RFM70 will enter standby-1 mode and with CE = 1 the RFM70 will enter RX or TX mode, depending on the PRIM_RX bit setting. And to me it makes sense to configure the PRIM_RX bit BEFORE you let the RFM70 enter an active mode (RX or TX).

  • Futterama

    @futterama-RLmhQR • Oct 4, 2012

    godfatherAnd what I suggest you can use CE in always enable mode if you are communicating with only one SPI device say RFM70.

    I am only communicating with one device. So you mean I should hold CE high at all times? This does not really make sense to me since one of the big advantages of the RFM70 is its ability to maintain a low power consumption using the standby modes.

    I will need to make a list of registers readable and writeable in standby-1 mode and also a list of usable SPI commands. Or maybe my contact at HopeRF can give me a good answer (they tend to give short useless answers).

  • Harshad Italiya

    @harshad-ukH5ww • Oct 5, 2012

    FutteramaI am only communicating with one device. So you mean I should hold CE high at all times? This does not really make sense to me since one of the big advantages of the RFM70 is its ability to maintain a low power consumption using the standby modes.

    I will need to make a list of registers readable and writeable in standby-1 mode and also a list of usable SPI commands. Or maybe my contact at HopeRF can give me a good answer (they tend to give short useless answers).

    That is another way. If you are getting reply then you have to work less. 😀

  • Futterama

    @futterama-RLmhQR • Oct 5, 2012

    Yeah, but they have just had a week of holiday, so I guess their mailbox is full of technical questions from customers so I don't expect a quick reply ;-)