From ed1d084aeaef1c7216004354bd5b1a08f4a584cf Mon Sep 17 00:00:00 2001 From: michael Date: Tue, 1 Aug 2017 16:00:58 +0800 Subject: [PATCH] fix(spi_master): make the address field more intuitive to use. The address field should be placed at the highest bits of address and slv_wr_status registers. Instead of breaking the address into two parts and fill in each register, move the address to the highest bits and write to the registers respectively. Breaking change: if you fill-in the SPI address filed in a previous version in some way and it works correctly, you still have to rewrite the address, in a more intuitive way. --- components/driver/include/driver/spi_master.h | 6 ++++-- components/driver/spi_master.c | 11 ++++++++--- components/driver/test/test_spi_master.c | 2 +- components/soc/esp32/include/soc/spi_struct.h | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/components/driver/include/driver/spi_master.h b/components/driver/include/driver/spi_master.h index 79eb52d36..b65caa6ec 100644 --- a/components/driver/include/driver/spi_master.h +++ b/components/driver/include/driver/spi_master.h @@ -71,8 +71,10 @@ typedef struct { */ struct spi_transaction_t { uint32_t flags; ///< Bitwise OR of SPI_TRANS_* flags - uint16_t command; ///< Command data. Specific length was given when device was added to the bus. - uint64_t address; ///< Address. Specific length was given when device was added to the bus. + uint16_t command; ///< Command data, of which the length is set in the command_bits of spi_device_interface_config_t. + uint64_t addr; ///< Address data, of which the length is set in the address_bits of spi_device_interface_config_t. + ///< NOTE: this field is re-written to be used in a new way. + ///< - Example: write 0x123400 and address_bits=24 to send address of 0x12, 0x34, 0x00. size_t length; ///< Total data length, in bits size_t rxlength; ///< Total data length received, if different from length. (0 defaults this to the value of ``length``) void *user; ///< User-defined variable. Can be used to store eg transaction ID. diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index f34d5bc90..6bec4eaee 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -548,11 +548,16 @@ static void IRAM_ATTR spi_intr(void *arg) host->hw->miso_dlen.usr_miso_dbitlen=trans->rxlength-1; host->hw->user2.usr_command_value=trans->command; + + // NOTE: WE CHANGED THE WAY USING ADDRESS FIELD. Now address should be filled in, in the following format: + // Example: write 0x123400 and address_bits=24 to send address 0x12, 0x34, 0x00 (in previous version, you may have to write 0x12340000) + // shift the address to MSB of addr (and maybe slv_wr_status) register. + // output address will be sent from MSB to LSB of addr register, then comes the MSB to LSB of slv_wr_status register. if (dev->cfg.address_bits>32) { - host->hw->addr=trans->address >> 32; - host->hw->slv_wr_status=trans->address & 0xffffffff; + host->hw->addr = trans->addr >> (dev->cfg.address_bits - 32); + host->hw->slv_wr_status = trans->addr << (64 - dev->cfg.address_bits); } else { - host->hw->addr=trans->address & 0xffffffff; + host->hw->addr = trans->addr << (32 - dev->cfg.address_bits); } host->hw->user.usr_mosi=(trans->tx_buffer!=NULL || (trans->flags & SPI_TRANS_USE_TXDATA))?1:0; host->hw->user.usr_miso=(trans->rx_buffer!=NULL || (trans->flags & SPI_TRANS_USE_RXDATA))?1:0; diff --git a/components/driver/test/test_spi_master.c b/components/driver/test/test_spi_master.c index 45314b708..9b4b830ec 100644 --- a/components/driver/test/test_spi_master.c +++ b/components/driver/test/test_spi_master.c @@ -131,7 +131,7 @@ static void spi_test(spi_device_handle_t handle, int num_bytes) { t.length=num_bytes*8; t.tx_buffer=sendbuf; t.rx_buffer=recvbuf; - t.address=0xA00000000000000FL; + t.addr=0xA00000000000000FL; t.command=0x55; printf("Transmitting %d bytes...\n", num_bytes); diff --git a/components/soc/esp32/include/soc/spi_struct.h b/components/soc/esp32/include/soc/spi_struct.h index 149782ff1..10bdcbb1c 100644 --- a/components/soc/esp32/include/soc/spi_struct.h +++ b/components/soc/esp32/include/soc/spi_struct.h @@ -36,7 +36,7 @@ typedef volatile struct { }; uint32_t val; } cmd; - uint32_t addr; /*addr to slave / from master */ + uint32_t addr; /*addr to slave / from master. SPI transfer from the MSB to the LSB. If length > 32 bits, then address continues from MSB of slv_wr_status.*/ union { struct { uint32_t reserved0: 10; /*reserved*/