]> granicus.if.org Git - esp-idf/commitdiff
Merge branch 'bugfix/spi_dma' into 'master'
authorIvan Grokhotkov <ivan@espressif.com>
Wed, 16 Aug 2017 10:55:25 +0000 (18:55 +0800)
committerIvan Grokhotkov <ivan@espressif.com>
Wed, 16 Aug 2017 10:55:25 +0000 (18:55 +0800)
bugfix(spi_master): fix several issues when using RX DMA

See merge request !1006

1  2 
components/driver/include/driver/spi_master.h
components/driver/spi_master.c
components/driver/test/test_spi_master.c

index b65caa6ec8a73d4bd273211bcd685f0aa8bc3162,6f928b5a11c2f1c428d414dffeea849e25cc3942..04f4c069944d26f6987a4dd0be8cab55b8acb167
@@@ -71,12 -71,10 +71,12 @@@ 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.
 +                                    ///< <b>NOTE: this field is re-written to be used in a new way.</b> 
 +                                    ///< - 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``)
+     size_t rxlength;                ///< Total data length received, should be not greater than ``length`` in full-duplex mode. (0 defaults this to the value of ``length``)
      void *user;                     ///< User-defined variable. Can be used to store eg transaction ID.
      union {
          const void *tx_buffer;      ///< Pointer to transmit buffer, or NULL for no MOSI phase
index 6bec4eaee498dce6ee8b38f5529ce0e27b283a78,be1b5e03e097f4196a843c0400ed29336e84cce4..e6175ebae9579d8418720b2111eaf3ab9c336264
@@@ -544,23 -541,24 +541,29 @@@ static void IRAM_ATTR spi_intr(void *ar
                  host->hw->user.usr_mosi_highpart=0;
              }
          }
          host->hw->mosi_dlen.usr_mosi_dbitlen=trans->length-1;
-         host->hw->miso_dlen.usr_miso_dbitlen=trans->rxlength-1;
+         if ( dev->cfg.flags & SPI_DEVICE_HALFDUPLEX ) {
+             host->hw->miso_dlen.usr_miso_dbitlen=trans->rxlength-1;
+         } else {
+             //rxlength is not used in full-duplex mode
+             host->hw->miso_dlen.usr_miso_dbitlen=trans->length-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;
+         host->hw->user.usr_mosi=( (!(dev->cfg.flags & SPI_DEVICE_HALFDUPLEX) && trans_buf->buffer_to_rcv) || trans_buf->buffer_to_send)?1:0;
+         host->hw->user.usr_miso=(trans_buf->buffer_to_rcv)?1:0;
  
          //Call pre-transmission callback, if any
          if (dev->cfg.pre_cb) dev->cfg.pre_cb(trans);