mirror of https://github.com/ARMmbed/mbed-os.git
[IOTSTOR-990] SPIFBlockDevice doesn't play nice on shared SPI bus. Back to use select and deselect, use correct spi constructor
parent
116a8a75b6
commit
699a68968c
|
|
@ -140,7 +140,7 @@ DataFlashBlockDevice::DataFlashBlockDevice(PinName mosi,
|
||||||
PinName cs,
|
PinName cs,
|
||||||
int freq,
|
int freq,
|
||||||
PinName nwp)
|
PinName nwp)
|
||||||
: _spi(mosi, miso, sclk, cs),
|
: _spi(mosi, miso, sclk, cs, use_gpio_ssel),
|
||||||
_nwp(nwp),
|
_nwp(nwp),
|
||||||
_device_size(0),
|
_device_size(0),
|
||||||
_page_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<uint8_t *>(buffer);
|
uint8_t *external_buffer = static_cast<uint8_t *>(buffer);
|
||||||
|
|
||||||
|
_spi.select();
|
||||||
|
|
||||||
/* send read opcode */
|
/* send read opcode */
|
||||||
_spi.write(DATAFLASH_OP_READ_LOW_FREQUENCY);
|
_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);
|
external_buffer[index] = _spi.write(DATAFLASH_OP_NOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_spi.deselect();
|
||||||
|
|
||||||
result = BD_ERROR_OK;
|
result = BD_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -539,6 +543,8 @@ uint16_t DataFlashBlockDevice::_get_register(uint8_t opcode)
|
||||||
_mutex.lock();
|
_mutex.lock();
|
||||||
DEBUG_PRINTF("_get_register: %" PRIX8 "\r\n", opcode);
|
DEBUG_PRINTF("_get_register: %" PRIX8 "\r\n", opcode);
|
||||||
|
|
||||||
|
_spi.select();
|
||||||
|
|
||||||
/* write opcode */
|
/* write opcode */
|
||||||
_spi.write(opcode);
|
_spi.write(opcode);
|
||||||
|
|
||||||
|
|
@ -546,6 +552,8 @@ uint16_t DataFlashBlockDevice::_get_register(uint8_t opcode)
|
||||||
int status = (_spi.write(DATAFLASH_OP_NOP));
|
int status = (_spi.write(DATAFLASH_OP_NOP));
|
||||||
status = (status << 8) | (_spi.write(DATAFLASH_OP_NOP));
|
status = (status << 8) | (_spi.write(DATAFLASH_OP_NOP));
|
||||||
|
|
||||||
|
_spi.deselect();
|
||||||
|
|
||||||
_mutex.unlock();
|
_mutex.unlock();
|
||||||
return status;
|
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);
|
DEBUG_PRINTF("_write_command: %" PRIX32 " %p %" PRIX32 "\r\n", command, buffer, size);
|
||||||
|
|
||||||
|
_spi.select();
|
||||||
|
|
||||||
/* send command (opcode with data or 4 byte command) */
|
/* send command (opcode with data or 4 byte command) */
|
||||||
_spi.write((command >> 24) & 0xFF);
|
_spi.write((command >> 24) & 0xFF);
|
||||||
_spi.write((command >> 16) & 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.write(buffer[index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_spi.deselect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -252,15 +252,14 @@ const uint32_t SDBlockDevice::_block_size = BLOCK_SIZE_HC;
|
||||||
|
|
||||||
#if MBED_CONF_SD_CRC_ENABLED
|
#if MBED_CONF_SD_CRC_ENABLED
|
||||||
SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on)
|
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)
|
_init_ref_count(0), _crc_on(crc_on)
|
||||||
#else
|
#else
|
||||||
SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on)
|
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)
|
_init_ref_count(0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
_spi.deselect();
|
|
||||||
_card_type = SDCARD_NONE;
|
_card_type = SDCARD_NONE;
|
||||||
|
|
||||||
// Set default to 100kHz for initialisation and 1MHz for data transfer
|
// 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)
|
_init_ref_count(0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
_spi.deselect();
|
|
||||||
_card_type = SDCARD_NONE;
|
_card_type = SDCARD_NONE;
|
||||||
|
|
||||||
// Set default to 100kHz for initialisation and 1MHz for data transfer
|
// 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);
|
_spi.write(SPI_STOP_TRAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
_deselect();
|
_postclock_then_deselect();
|
||||||
unlock();
|
unlock();
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
@ -585,7 +583,7 @@ int SDBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
|
||||||
buffer += _block_size;
|
buffer += _block_size;
|
||||||
--blockCnt;
|
--blockCnt;
|
||||||
}
|
}
|
||||||
_deselect();
|
_postclock_then_deselect();
|
||||||
|
|
||||||
// Send CMD12(0x00000000) to stop the transmission for multi-block transfer
|
// Send CMD12(0x00000000) to stop the transmission for multi-block transfer
|
||||||
if (size > _block_size) {
|
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
|
// Select card and wait for card to be ready before sending next command
|
||||||
// Note: next command will fail if card is not ready
|
// 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
|
// No need to wait for card to be ready when sending the stop command
|
||||||
if (CMD12_STOP_TRANSMISSION != cmd) {
|
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
|
// Process the response R1 : Exit on CRC/Illegal command error/No response
|
||||||
if (R1_NO_RESPONSE == response) {
|
if (R1_NO_RESPONSE == response) {
|
||||||
_deselect();
|
_postclock_then_deselect();
|
||||||
debug_if(SD_DBG, "No response CMD:%d response: 0x%" PRIx32 "\n", cmd, response);
|
debug_if(SD_DBG, "No response CMD:%d response: 0x%" PRIx32 "\n", cmd, response);
|
||||||
return SD_BLOCK_DEVICE_ERROR_NO_DEVICE; // No device
|
return SD_BLOCK_DEVICE_ERROR_NO_DEVICE; // No device
|
||||||
}
|
}
|
||||||
if (response & R1_COM_CRC_ERROR) {
|
if (response & R1_COM_CRC_ERROR) {
|
||||||
_deselect();
|
_postclock_then_deselect();
|
||||||
debug_if(SD_DBG, "CRC error CMD:%d response 0x%" PRIx32 "\n", cmd, response);
|
debug_if(SD_DBG, "CRC error CMD:%d response 0x%" PRIx32 "\n", cmd, response);
|
||||||
return SD_BLOCK_DEVICE_ERROR_CRC; // CRC error
|
return SD_BLOCK_DEVICE_ERROR_CRC; // CRC error
|
||||||
}
|
}
|
||||||
if (response & R1_ILLEGAL_COMMAND) {
|
if (response & R1_ILLEGAL_COMMAND) {
|
||||||
_deselect();
|
_postclock_then_deselect();
|
||||||
debug_if(SD_DBG, "Illegal command CMD:%d response 0x%" PRIx32 "\n", cmd, response);
|
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
|
if (CMD8_SEND_IF_COND == cmd) { // Illegal command is for Ver1 or not SD Card
|
||||||
_card_type = CARD_UNKNOWN;
|
_card_type = CARD_UNKNOWN;
|
||||||
|
|
@ -857,7 +855,7 @@ int SDBlockDevice::_cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg, bool isAc
|
||||||
return BD_ERROR_OK;
|
return BD_ERROR_OK;
|
||||||
}
|
}
|
||||||
// Deselect card
|
// Deselect card
|
||||||
_deselect();
|
_postclock_then_deselect();
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -908,7 +906,7 @@ int SDBlockDevice::_read_bytes(uint8_t *buffer, uint32_t length)
|
||||||
// read until start byte (0xFE)
|
// read until start byte (0xFE)
|
||||||
if (false == _wait_token(SPI_START_BLOCK)) {
|
if (false == _wait_token(SPI_START_BLOCK)) {
|
||||||
debug_if(SD_DBG, "Read timeout\n");
|
debug_if(SD_DBG, "Read timeout\n");
|
||||||
_deselect();
|
_postclock_then_deselect();
|
||||||
return SD_BLOCK_DEVICE_ERROR_NO_RESPONSE;
|
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) {
|
if (crc_result != crc) {
|
||||||
debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%" PRIx16 " result of computation 0x%" PRIx32 "\n",
|
debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%" PRIx16 " result of computation 0x%" PRIx32 "\n",
|
||||||
crc, crc_result);
|
crc, crc_result);
|
||||||
_deselect();
|
_postclock_then_deselect();
|
||||||
return SD_BLOCK_DEVICE_ERROR_CRC;
|
return SD_BLOCK_DEVICE_ERROR_CRC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_deselect();
|
_postclock_then_deselect();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1129,22 +1127,28 @@ void SDBlockDevice::_spi_wait(uint8_t count)
|
||||||
|
|
||||||
void SDBlockDevice::_spi_init()
|
void SDBlockDevice::_spi_init()
|
||||||
{
|
{
|
||||||
|
_spi.lock();
|
||||||
// Set to SCK for initialization, and clock card with cs = 1
|
// Set to SCK for initialization, and clock card with cs = 1
|
||||||
_spi.frequency(_init_sck);
|
_spi.frequency(_init_sck);
|
||||||
_spi.format(8, 0);
|
_spi.format(8, 0);
|
||||||
_spi.set_default_write_value(SPI_FILL_CHAR);
|
_spi.set_default_write_value(SPI_FILL_CHAR);
|
||||||
// Initial 74 cycles required for few cards, before selecting SPI mode
|
// Initial 74 cycles required for few cards, before selecting SPI mode
|
||||||
_spi_wait(10);
|
_spi_wait(10);
|
||||||
|
_spi.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDBlockDevice::_select()
|
void SDBlockDevice::_preclock_then_select()
|
||||||
{
|
{
|
||||||
|
_spi.lock();
|
||||||
_spi.write(SPI_FILL_CHAR);
|
_spi.write(SPI_FILL_CHAR);
|
||||||
|
_spi.select();
|
||||||
|
_spi.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDBlockDevice::_deselect()
|
void SDBlockDevice::_postclock_then_deselect()
|
||||||
{
|
{
|
||||||
_spi.write(SPI_FILL_CHAR);
|
_spi.write(SPI_FILL_CHAR);
|
||||||
|
_spi.deselect();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* DEVICE_SPI */
|
#endif /* DEVICE_SPI */
|
||||||
|
|
|
||||||
|
|
@ -272,10 +272,8 @@ private:
|
||||||
int _read_bytes(uint8_t *buffer, uint32_t length);
|
int _read_bytes(uint8_t *buffer, uint32_t length);
|
||||||
uint8_t _write(const uint8_t *buffer, uint8_t token, uint32_t length);
|
uint8_t _write(const uint8_t *buffer, uint8_t token, uint32_t length);
|
||||||
int _freq(void);
|
int _freq(void);
|
||||||
|
void _preclock_then_select();
|
||||||
/* Chip Select and SPI mode select */
|
void _postclock_then_deselect();
|
||||||
void _select();
|
|
||||||
void _deselect();
|
|
||||||
|
|
||||||
virtual void lock()
|
virtual void lock()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ SingletonPtr<PlatformMutex> SPIFBlockDevice::_mutex;
|
||||||
//***********************
|
//***********************
|
||||||
SPIFBlockDevice::SPIFBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName csel, int freq)
|
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)
|
_page_size_bytes(0), _init_ref_count(0), _is_initialized(false)
|
||||||
{
|
{
|
||||||
_address_size = SPIF_ADDR_SIZE_3_BYTES;
|
_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;
|
uint32_t dummy_bytes = _dummy_and_mode_cycles / 8;
|
||||||
int dummy_byte = 0;
|
int dummy_byte = 0;
|
||||||
|
|
||||||
|
_spi.select();
|
||||||
|
|
||||||
// Write 1 byte Instruction
|
// Write 1 byte Instruction
|
||||||
_spi.write(read_inst);
|
_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);
|
buffer[i] = _spi.write(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_spi.deselect();
|
||||||
|
|
||||||
return SPIF_BD_ERROR_OK;
|
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;
|
int dummy_byte = 0;
|
||||||
uint8_t *data = (uint8_t *)buffer;
|
uint8_t *data = (uint8_t *)buffer;
|
||||||
|
|
||||||
|
_spi.select();
|
||||||
|
|
||||||
// Write 1 byte Instruction
|
// Write 1 byte Instruction
|
||||||
_spi.write(prog_inst);
|
_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.write(data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_spi.deselect();
|
||||||
|
|
||||||
return SPIF_BD_ERROR_OK;
|
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;
|
uint32_t dummy_bytes = _dummy_and_mode_cycles / 8;
|
||||||
uint8_t dummy_byte = 0x00;
|
uint8_t dummy_byte = 0x00;
|
||||||
|
|
||||||
|
_spi.select();
|
||||||
|
|
||||||
// Write 1 byte Instruction
|
// Write 1 byte Instruction
|
||||||
_spi.write(instruction);
|
_spi.write(instruction);
|
||||||
|
|
||||||
|
|
@ -569,6 +579,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_general_command(int instruction, bd_add
|
||||||
// Read/Write Data
|
// Read/Write Data
|
||||||
_spi.write(tx_buffer, (int)tx_length, rx_buffer, (int)rx_length);
|
_spi.write(tx_buffer, (int)tx_length, rx_buffer, (int)rx_length);
|
||||||
|
|
||||||
|
_spi.deselect();
|
||||||
|
|
||||||
return SPIF_BD_ERROR_OK;
|
return SPIF_BD_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue