diff --git a/components/storage/blockdevice/COMPONENT_DATAFLASH/DataFlashBlockDevice.cpp b/components/storage/blockdevice/COMPONENT_DATAFLASH/DataFlashBlockDevice.cpp index 5b1bf01fbe..cddcc146c4 100644 --- a/components/storage/blockdevice/COMPONENT_DATAFLASH/DataFlashBlockDevice.cpp +++ b/components/storage/blockdevice/COMPONENT_DATAFLASH/DataFlashBlockDevice.cpp @@ -140,7 +140,7 @@ DataFlashBlockDevice::DataFlashBlockDevice(PinName mosi, PinName cs, int freq, PinName nwp) - : _spi(mosi, miso, sclk, cs), + : _spi(mosi, miso, sclk, cs, use_gpio_ssel), _nwp(nwp), _device_size(0), _page_size(0), @@ -330,6 +330,8 @@ int DataFlashBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size) uint8_t *external_buffer = static_cast(buffer); + _spi.select(); + /* send read opcode */ _spi.write(DATAFLASH_OP_READ_LOW_FREQUENCY); @@ -348,6 +350,8 @@ int DataFlashBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size) external_buffer[index] = _spi.write(DATAFLASH_OP_NOP); } + _spi.deselect(); + result = BD_ERROR_OK; } @@ -539,6 +543,8 @@ uint16_t DataFlashBlockDevice::_get_register(uint8_t opcode) _mutex.lock(); DEBUG_PRINTF("_get_register: %" PRIX8 "\r\n", opcode); + _spi.select(); + /* write opcode */ _spi.write(opcode); @@ -546,6 +552,8 @@ uint16_t DataFlashBlockDevice::_get_register(uint8_t opcode) int status = (_spi.write(DATAFLASH_OP_NOP)); status = (status << 8) | (_spi.write(DATAFLASH_OP_NOP)); + _spi.deselect(); + _mutex.unlock(); return status; } @@ -566,6 +574,8 @@ void DataFlashBlockDevice::_write_command(uint32_t command, const uint8_t *buffe { DEBUG_PRINTF("_write_command: %" PRIX32 " %p %" PRIX32 "\r\n", command, buffer, size); + _spi.select(); + /* send command (opcode with data or 4 byte command) */ _spi.write((command >> 24) & 0xFF); _spi.write((command >> 16) & 0xFF); @@ -578,6 +588,8 @@ void DataFlashBlockDevice::_write_command(uint32_t command, const uint8_t *buffe _spi.write(buffer[index]); } } + + _spi.deselect(); } /** diff --git a/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.cpp b/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.cpp index 882679abf5..2893881cf4 100644 --- a/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.cpp +++ b/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.cpp @@ -252,15 +252,14 @@ const uint32_t SDBlockDevice::_block_size = BLOCK_SIZE_HC; #if MBED_CONF_SD_CRC_ENABLED SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on) - : _sectors(0), _spi(mosi, miso, sclk, cs), _is_initialized(0), + : _sectors(0), _spi(mosi, miso, sclk, cs, use_gpio_ssel), _is_initialized(0), _init_ref_count(0), _crc_on(crc_on) #else SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on) - : _sectors(0), _spi(mosi, miso, sclk, cs), _is_initialized(0), + : _sectors(0), _spi(mosi, miso, sclk, cs, use_gpio_ssel), _is_initialized(0), _init_ref_count(0) #endif { - _spi.deselect(); _card_type = SDCARD_NONE; // Set default to 100kHz for initialisation and 1MHz for data transfer @@ -282,7 +281,6 @@ SDBlockDevice::SDBlockDevice(const spi_pinmap_t &spi_pinmap, PinName cs, uint64_ _init_ref_count(0) #endif { - _spi.deselect(); _card_type = SDCARD_NONE; // Set default to 100kHz for initialisation and 1MHz for data transfer @@ -538,7 +536,7 @@ int SDBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size) _spi.write(SPI_STOP_TRAN); } - _deselect(); + _postclock_then_deselect(); unlock(); return status; } @@ -585,7 +583,7 @@ int SDBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size) buffer += _block_size; --blockCnt; } - _deselect(); + _postclock_then_deselect(); // Send CMD12(0x00000000) to stop the transmission for multi-block transfer if (size > _block_size) { @@ -753,7 +751,7 @@ int SDBlockDevice::_cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg, bool isAc // Select card and wait for card to be ready before sending next command // Note: next command will fail if card is not ready - _select(); + _preclock_then_select(); // No need to wait for card to be ready when sending the stop command if (CMD12_STOP_TRANSMISSION != cmd) { @@ -789,17 +787,17 @@ int SDBlockDevice::_cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg, bool isAc // Process the response R1 : Exit on CRC/Illegal command error/No response if (R1_NO_RESPONSE == response) { - _deselect(); + _postclock_then_deselect(); debug_if(SD_DBG, "No response CMD:%d response: 0x%" PRIx32 "\n", cmd, response); return SD_BLOCK_DEVICE_ERROR_NO_DEVICE; // No device } if (response & R1_COM_CRC_ERROR) { - _deselect(); + _postclock_then_deselect(); debug_if(SD_DBG, "CRC error CMD:%d response 0x%" PRIx32 "\n", cmd, response); return SD_BLOCK_DEVICE_ERROR_CRC; // CRC error } if (response & R1_ILLEGAL_COMMAND) { - _deselect(); + _postclock_then_deselect(); debug_if(SD_DBG, "Illegal command CMD:%d response 0x%" PRIx32 "\n", cmd, response); if (CMD8_SEND_IF_COND == cmd) { // Illegal command is for Ver1 or not SD Card _card_type = CARD_UNKNOWN; @@ -857,7 +855,7 @@ int SDBlockDevice::_cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg, bool isAc return BD_ERROR_OK; } // Deselect card - _deselect(); + _postclock_then_deselect(); return status; } @@ -908,7 +906,7 @@ int SDBlockDevice::_read_bytes(uint8_t *buffer, uint32_t length) // read until start byte (0xFE) if (false == _wait_token(SPI_START_BLOCK)) { debug_if(SD_DBG, "Read timeout\n"); - _deselect(); + _postclock_then_deselect(); return SD_BLOCK_DEVICE_ERROR_NO_RESPONSE; } @@ -930,13 +928,13 @@ int SDBlockDevice::_read_bytes(uint8_t *buffer, uint32_t length) if (crc_result != crc) { debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%" PRIx16 " result of computation 0x%" PRIx32 "\n", crc, crc_result); - _deselect(); + _postclock_then_deselect(); return SD_BLOCK_DEVICE_ERROR_CRC; } } #endif - _deselect(); + _postclock_then_deselect(); return 0; } @@ -1129,22 +1127,28 @@ void SDBlockDevice::_spi_wait(uint8_t count) void SDBlockDevice::_spi_init() { + _spi.lock(); // Set to SCK for initialization, and clock card with cs = 1 _spi.frequency(_init_sck); _spi.format(8, 0); _spi.set_default_write_value(SPI_FILL_CHAR); // Initial 74 cycles required for few cards, before selecting SPI mode _spi_wait(10); + _spi.unlock(); } -void SDBlockDevice::_select() +void SDBlockDevice::_preclock_then_select() { + _spi.lock(); _spi.write(SPI_FILL_CHAR); + _spi.select(); + _spi.unlock(); } -void SDBlockDevice::_deselect() +void SDBlockDevice::_postclock_then_deselect() { _spi.write(SPI_FILL_CHAR); + _spi.deselect(); } #endif /* DEVICE_SPI */ diff --git a/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.h b/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.h index e367c02678..a694cf322c 100644 --- a/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.h +++ b/components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.h @@ -272,10 +272,8 @@ private: int _read_bytes(uint8_t *buffer, uint32_t length); uint8_t _write(const uint8_t *buffer, uint8_t token, uint32_t length); int _freq(void); - - /* Chip Select and SPI mode select */ - void _select(); - void _deselect(); + void _preclock_then_select(); + void _postclock_then_deselect(); virtual void lock() { diff --git a/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp b/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp index f78063a3dd..884b1f549b 100644 --- a/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp +++ b/components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp @@ -87,7 +87,7 @@ SingletonPtr SPIFBlockDevice::_mutex; //*********************** SPIFBlockDevice::SPIFBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName csel, int freq) : - _spi(mosi, miso, sclk, csel), _prog_instruction(0), _erase_instruction(0), + _spi(mosi, miso, sclk, csel, use_gpio_ssel), _prog_instruction(0), _erase_instruction(0), _page_size_bytes(0), _init_ref_count(0), _is_initialized(false) { _address_size = SPIF_ADDR_SIZE_3_BYTES; @@ -470,6 +470,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_read_command(int read_inst, uint8_t *bu uint32_t dummy_bytes = _dummy_and_mode_cycles / 8; int dummy_byte = 0; + _spi.select(); + // Write 1 byte Instruction _spi.write(read_inst); @@ -488,6 +490,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_read_command(int read_inst, uint8_t *bu buffer[i] = _spi.write(0); } + _spi.deselect(); + return SPIF_BD_ERROR_OK; } @@ -514,6 +518,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_program_command(int prog_inst, const vo int dummy_byte = 0; uint8_t *data = (uint8_t *)buffer; + _spi.select(); + // Write 1 byte Instruction _spi.write(prog_inst); @@ -532,6 +538,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_program_command(int prog_inst, const vo _spi.write(data[i]); } + _spi.deselect(); + return SPIF_BD_ERROR_OK; } @@ -550,6 +558,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_general_command(int instruction, bd_add uint32_t dummy_bytes = _dummy_and_mode_cycles / 8; uint8_t dummy_byte = 0x00; + _spi.select(); + // Write 1 byte Instruction _spi.write(instruction); @@ -569,6 +579,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_general_command(int instruction, bd_add // Read/Write Data _spi.write(tx_buffer, (int)tx_length, rx_buffer, (int)rx_length); + _spi.deselect(); + return SPIF_BD_ERROR_OK; }