SPI and RFM69

Nargott
Posts: 1
Joined: Tue Apr 11, 2017 2:17 pm

SPI and RFM69

Postby Nargott » Tue Apr 11, 2017 2:26 pm

Hello. I need to operate the RFM69HCW module from esp-idf.
I'm trying to adopt this library for ESP32: https://github.com/ahessling/RFM69-STM32
Also, off course, I know the official docs, like: http://esp-idf.readthedocs.io/en/latest ... aster.html
To init the SPI-master mode I'm using something like this:

#define HSPI 2

Code: Select all

//SPI clk = 40MHz
WRITE_PERI_REG(SPI_CLOCK(HSPI), (0<<SPI_CLKDIV_PRE_S) |
	(1<<SPI_CLKCNT_N_S)|(1<<SPI_CLKCNT_L_S)|(0<<SPI_CLKCNT_H_S));
WRITE_PERI_REG(SPI_CTRL(HSPI), 0);//SPI_WR_BIT_ORDER);
WRITE_PERI_REG(SPI_USER(HSPI), SPI_CS_SETUP|SPI_CS_HOLD|SPI_USR_MOSI|SPI_WR_BYTE_ORDER);
WRITE_PERI_REG(SPI_USER1(HSPI), (9<<SPI_USR_MOSI_DBITLEN_S));
So, there is two questions: is this is right beginning and how to determine which SPI I'm must to use here. And, may be, somebody has a full example of using SPI in ESP-IDF.

P.S. Sorry, for me, newbye. I'm comming from the Arduino world, and new to ESP things.

rsimpsonbusa
Posts: 131
Joined: Tue May 17, 2016 8:12 pm

Re: SPI and RFM69

Postby rsimpsonbusa » Thu Apr 13, 2017 12:19 am

Ill give u my Setup SPI routine, a Write 1 byte routine and a Read 1 byte routine.

This device has the following command structure,

To write: 1 Cmd Write Byte, 2 or 3 Address bytes(depends on the version of the device it needs 16 or 24 bits of address) and the byte to write. Total bytes to write, 4 or 5, total 32 or 40 bits.

To read: 1 Cmd Read byte, 2 or 3 Address bytes and the requested byte.
Total 24 or 32 to send and 1 byte to read

Code follows

Code: Select all

void spiconf(int spimode)
{
		spi_bus_config_t 						buscfg;
		spi_device_interface_config_t 				devcfg;
		 esp_err_t								ret;

		 memset(&buscfg,0,sizeof(buscfg));
		 memset(&devcfg,0,sizeof(devcfg));

		 buscfg.mosi_io_num=GPIO_NUM_XX; //MOSI pin
		 buscfg .miso_io_num=GPIO_NUM_YY; //MISO Pin
		 buscfg.sclk_io_num=GPIO_NUM_ZZ; // Clock Pin
		 buscfg.quadwp_io_num=-1;
		 buscfg .quadhd_io_num=-1;

		    //Initialize the SPI bus
		    ret=spi_bus_initialize(VSPI_HOST, &buscfg, 1);   //1 is for dma channel, can be 2 but its the same basically
		    assert(ret == ESP_OK);

		    devcfg .clock_speed_hz=20000000;               //Clock out at 20 MHz or whatever u need
		    devcfg.mode=spimode;                                //SPI mode 0 or 3 
		    devcfg.spics_io_num=GPIO_NUM_CS;              //CS pin
		    devcfg.queue_size=1;                          		//Can NOT be 0
		   devcfg.flags=SPI_DEVICE_HALFDUPLEX;		//If full duplex remember when receiving drop the SENT/WRITE bytes reply

		    //Attach the LCD to the SPI bus
		    ret=spi_bus_add_device(VSPI_HOST, &devcfg, &spi); //Only two Option HSPI or VSPI. Pins (mosi,miso,clk and cs) can be "almost" any (some restrictions regarding certains predefined pins in ESP32 . Google it)
		    assert(ret==ESP_OK);
		    
		    // Start using the spi
}
To write to the spi

Code: Select all


int FramSPI::write8 (uint32_t framAddr, uint8_t value)
{
    esp_err_t ret=0;
    spi_transaction_t t;
    uint8_t data[5];
    memset(&t, 0, sizeof(t));       //Zero out the transaction
    data[0]=MBRSPI_WRITE; //The Write Cmd for this chip
    if(addressBytes==2) //COuld be 2 or three bytes address
    {
    	data[1]=framAddr &0xff00;
    	data[2]=framAddr& 0xff;
    	data[3]=value;
    	t.length=32;                     //Command is 4 bytes *8 =32 bits
    }
    else
    {
        data[1]=framAddr & 0xff0000;
        data[2]=framAddr& 0xff00;
        data[3]=framAddr& 0xff;
        data[4]=value;
        t.length=40;                     //Command is 5 bytes *8 =40 bits
     }

    t.tx_buffer=&data;
    t.rxlength=0;
    t.rx_buffer=NULL;
    ret=spi_device_transmit(spi, &t);  //Transmit!

    return ret;

}
and to read 1 byte

Code: Select all

uint8_t FramSPI::read8 (uint32_t framAddr)
{

    spi_transaction_t t;
    uint8_t data[4]={0},rxdata[4]={0};
    memset(&t, 0, sizeof(t));       //Zero out the transaction
    data[0]=MBRSPI_READ; //Read Cmd for this device
    if(addressBytes==2)
    {
    	data[1]=framAddr &0xff00;
    	data[2]=framAddr& 0xff;
    	t.length=24;                     //Command is 3 btyes *8 =24 bits
    }
    else
    {
        data[1]=framAddr & 0xff0000;
        data[2]=framAddr& 0xff00;
        data[3]=framAddr& 0xff;
        t.length=32;                     //Command is 4 btyes *8 =32 bits
     }

    t.rxlength=8;
    t.rx_buffer=&rxdata;
    t.tx_buffer=&data;
    spi_device_transmit(spi, &t);  //Transmit!
   return rxdata[0]; //first byte only.
   
   //If you set spi to full duplex you would have received 4 bytes, 1 for each sent byte (3) and the one u really needed (4).
   // Setting to half duplex you only get the requested read byte.

}
Hope it helps

Who is online

Users browsing this forum: No registered users and 109 guests