Many Problems : ESP32 communicate to RC522 with SPI

yang278851511
Posts: 1
Joined: Tue Oct 10, 2017 10:49 am

Many Problems : ESP32 communicate to RC522 with SPI

Postby yang278851511 » Tue Oct 10, 2017 11:21 am

Recent time ,I use ESP32 communicate with RC522,but ,I have a very serious problem abaut it !!
I use the SPI master examples to modify my code,and Compiled success.But when I write a byte to the RC522'register,Then,I read it,I found that the value I wrote is inconsistent with the value I read ,I think my spi communicate must be many problem,here are my code ,please help me to make it work.

SPI Connectors

Code: Select all

#define PIN_NUM_MISO GPIO_NUM_25
#define PIN_NUM_MOSI GPIO_NUM_23
#define PIN_NUM_CLK  GPIO_NUM_19
#define PIN_NUM_CS   GPIO_NUM_22

#define PIN_NUM_RST  GPIO_NUM_18
GPIO init

Code: Select all

	GPIO_input_init(PIN_NUM_MISO);
	GPIO_output_init(PIN_NUM_MOSI);
	GPIO_output_init(PIN_NUM_CLK);
	GPIO_output_init(PIN_NUM_CS);

	GPIO_output_init(PIN_NUM_RST);

	gpio_set_direction(PIN_NUM_MISO, GPIO_MODE_INPUT);
	gpio_set_pull_mode(PIN_NUM_MISO, GPIO_PULLUP_ONLY);

SPI init

Code: Select all

spi_device_handle_t spi;
    spi_bus_config_t buscfg={
        .miso_io_num=PIN_NUM_MISO,
        .mosi_io_num=PIN_NUM_MOSI,
        .sclk_io_num=PIN_NUM_CLK,
        .quadwp_io_num=-1,
        .quadhd_io_num=-1,
//		.max_transfer_sz =2048,
    };
    spi_device_interface_config_t devcfg={
    	.command_bits     =0,
		.address_bits     =0,
    	.dummy_bits       =0,
		.mode             =0,        //SPI mode 0
		.duty_cycle_pos   =0,
		.cs_ena_pretrans  =0,
		.cs_ena_posttrans =0,
        .clock_speed_hz   =10*1000*1000,               //Clock out at 10 MHz
        .spics_io_num     =PIN_NUM_CS,               //CS pin
		.flags            =0,
        .queue_size       =1,                          //We want to be able to queue 7 transactions at a time
		.pre_cb           =NULL, 		 //Specify pre-transfer callback to handle D/C line
		.post_cb		  =NULL,
    };
    //Initialize the SPI bus
    ret=spi_bus_initialize(HSPI_HOST, &buscfg, 1);
    ESP_ERROR_CHECK(ret);

    ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
    ESP_ERROR_CHECK(ret);
Then I use SPI to read and write,but ,I only need to write one byte to The RC522,at the same time ,I only need to read one byte from the RC522.

RC522 CMD
This code for write same one cmd to RC522

Code: Select all

void RC522_cmd(spi_device_handle_t spi, uint8_t cmd)
{
    esp_err_t ret;
    spi_transaction_t t;

    memset(&t, 0, sizeof(t));           //Zero out the transaction
    t.addr        =0;
    t.cmd         =0;
    t.flags       =0;
    t.length      =8;			  		//Command is 8 bits
    t.rxlength    =8;
    t.tx_buffer   =&cmd;                   //The data is the cmd itself
//    t.user=(void*)0;                    //D/C needs to be set to 0
    ret=spi_device_transmit(spi, &t);   //Transmit!
    assert(ret==ESP_OK);                //Should have had no issues.
}
RC522 write byte to RC522 ----ONLY one byte is necessary

Code: Select all

void RC522_write_byte(spi_device_handle_t spi,uint8_t value)
{
    esp_err_t ret;
    spi_transaction_t t;

    memset(&t, 0, sizeof(t));       		//Zero out the transaction
    t.addr        =0;
	t.cmd         =0;

	t.length      =8;			  		//Command is 8 bits
    t.rxlength    =8;

    t.tx_buffer        =&value;             //The data is the cmd itself
    t.flags = SPI_TRANS_USE_TXDATA;
//  t.user=(void*)0;               			//D/C needs to be set to 0
    ret=spi_device_transmit(spi, &t);  		//Transmit!

    ESP_ERROR_CHECK(ret);            		//Should have had no issues.
}
RC522_write_addr_value the code for write the value to a addr,for example :
RC522_write_addr_value(spi,TxAutoReg,0x40);

write 0x40 to the addr of "TxAutoReg"

Code: Select all

void RC522_write_addr_value(spi_device_handle_t spi,  uint8_t Address, uint8_t Value)
{
//	uint8_t   ucAddr=0;

	Address = ((Address<<1)&0x7E);
	RC522_cmd(spi,Address);
	RC522_write_byte(spi,Value);

}
RC522_read_data ---this code need to read the data from the address

Code: Select all

uint8_t RC522_read_data(spi_device_handle_t spi, uint8_t Address)
{
//	uint8_t rxdata[];
	Address = ((Address<<1)&0x7E)|0x80;

    spi_transaction_t t;
    memset(&t, 0, sizeof(t));

	RC522_cmd(spi,Address);

	t.addr        =0;
	t.cmd         =0;

	t.length      =8;			  		//Command is 8 bits
	t.rxlength    =8;

    t.flags = SPI_TRANS_USE_RXDATA;
//    t.user = (void*)0;

    esp_err_t ret = spi_device_transmit(spi, &t);
    assert( ret == ESP_OK );

   return *(uint8_t*) t.rx_data;

}
above is the main code ,but when I write a byte to the addr,and then read it,I found it is wrong!!!

Code: Select all

RC522_write_addr_value(spi,TxAutoReg,0x40);   

printf("read TxAutoReg 0 value = %08x \n",RC522_read_data(spi,TxAutoReg));
I write 0x40,but the read value is "read TxAutoReg 0 value = 00000000"

hear are some info for RC522
https://wenku.baidu.com/view/6c881266d ... afb4.html

I have no ways to solve this problems ,please help me ,thank you very much !!

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Many Problems : ESP32 communicate to RC522 with SPI

Postby kolban » Sun Nov 19, 2017 4:16 pm

In case it helps, here is an RC522 port that seems to work for me.

https://github.com/nkolban/esp32-snippe ... FRC522.cpp
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

chegewara
Posts: 2207
Joined: Wed Jun 14, 2017 9:00 pm

Re: Many Problems : ESP32 communicate to RC522 with SPI

Postby chegewara » Sun Nov 19, 2017 6:52 pm

I think this is the problem:

Code: Select all

return *(uint8_t*) t.rx_data;
You need to set rx buffer and ther return that buffer address:

Code: Select all

uint8_t data;
t.rx = &data;
return data; // or
return &data; // watever suits you
Or issue may be here:

Code: Select all

void RC522_cmd(spi_device_handle_t spi, uint8_t cmd)
{
    esp_err_t ret;
    spi_transaction_t t;

    memset(&t, 0, sizeof(t));           //Zero out the transaction
    t.addr        =0;
    t.cmd         =0;
    t.flags       =0;
    t.length      =8;                 //Command is 8 bits
    t.rxlength    =8;   <--- issue
    
You are sending command and reading value in one spi transfer, its synchronous transfer, so next transfer when you are trying to read value is reading from nowhere. Best option is to use logic analyzer and see what you read on miso pin in each transfer.

Who is online

Users browsing this forum: ericchile and 119 guests