Skip to content

Commit 7a0a168

Browse files
authored
Merge pull request #12681 from mtomczykmobica/IOTSTOR-990
SPIFBlockDevice doesn't play nice on shared SPI bus #11732.
2 parents d308da1 + 699a689 commit 7a0a168

File tree

6 files changed

+37
-58
lines changed

6 files changed

+37
-58
lines changed

components/storage/blockdevice/COMPONENT_DATAFLASH/DataFlashBlockDevice.cpp

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,7 @@ DataFlashBlockDevice::DataFlashBlockDevice(PinName mosi,
140140
PinName cs,
141141
int freq,
142142
PinName nwp)
143-
: _spi(mosi, miso, sclk),
144-
_cs(cs, 1),
143+
: _spi(mosi, miso, sclk, cs, use_gpio_ssel),
145144
_nwp(nwp),
146145
_device_size(0),
147146
_page_size(0),
@@ -331,8 +330,7 @@ int DataFlashBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
331330

332331
uint8_t *external_buffer = static_cast<uint8_t *>(buffer);
333332

334-
/* activate device */
335-
_cs = 0;
333+
_spi.select();
336334

337335
/* send read opcode */
338336
_spi.write(DATAFLASH_OP_READ_LOW_FREQUENCY);
@@ -352,8 +350,7 @@ int DataFlashBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
352350
external_buffer[index] = _spi.write(DATAFLASH_OP_NOP);
353351
}
354352

355-
/* deactivate device */
356-
_cs = 1;
353+
_spi.deselect();
357354

358355
result = BD_ERROR_OK;
359356
}
@@ -546,8 +543,7 @@ uint16_t DataFlashBlockDevice::_get_register(uint8_t opcode)
546543
_mutex.lock();
547544
DEBUG_PRINTF("_get_register: %" PRIX8 "\r\n", opcode);
548545

549-
/* activate device */
550-
_cs = 0;
546+
_spi.select();
551547

552548
/* write opcode */
553549
_spi.write(opcode);
@@ -556,8 +552,7 @@ uint16_t DataFlashBlockDevice::_get_register(uint8_t opcode)
556552
int status = (_spi.write(DATAFLASH_OP_NOP));
557553
status = (status << 8) | (_spi.write(DATAFLASH_OP_NOP));
558554

559-
/* deactivate device */
560-
_cs = 1;
555+
_spi.deselect();
561556

562557
_mutex.unlock();
563558
return status;
@@ -579,8 +574,7 @@ void DataFlashBlockDevice::_write_command(uint32_t command, const uint8_t *buffe
579574
{
580575
DEBUG_PRINTF("_write_command: %" PRIX32 " %p %" PRIX32 "\r\n", command, buffer, size);
581576

582-
/* activate device */
583-
_cs = 0;
577+
_spi.select();
584578

585579
/* send command (opcode with data or 4 byte command) */
586580
_spi.write((command >> 24) & 0xFF);
@@ -595,8 +589,7 @@ void DataFlashBlockDevice::_write_command(uint32_t command, const uint8_t *buffe
595589
}
596590
}
597591

598-
/* deactivate device */
599-
_cs = 1;
592+
_spi.deselect();
600593
}
601594

602595
/**

components/storage/blockdevice/COMPONENT_DATAFLASH/DataFlashBlockDevice.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ class DataFlashBlockDevice : public mbed::BlockDevice {
182182
private:
183183
// Master side hardware
184184
mbed::SPI _spi;
185-
mbed::DigitalOut _cs;
186185
mbed::DigitalOut _nwp;
187186

188187
// Device configuration

components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.cpp

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,14 @@ const uint32_t SDBlockDevice::_block_size = BLOCK_SIZE_HC;
252252

253253
#if MBED_CONF_SD_CRC_ENABLED
254254
SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on)
255-
: _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0),
255+
: _sectors(0), _spi(mosi, miso, sclk, cs, use_gpio_ssel), _is_initialized(0),
256256
_init_ref_count(0), _crc_on(crc_on)
257257
#else
258258
SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on)
259-
: _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0),
259+
: _sectors(0), _spi(mosi, miso, sclk, cs, use_gpio_ssel), _is_initialized(0),
260260
_init_ref_count(0)
261261
#endif
262262
{
263-
_cs = 1;
264263
_card_type = SDCARD_NONE;
265264

266265
// Set default to 100kHz for initialisation and 1MHz for data transfer
@@ -274,15 +273,14 @@ SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName c
274273

275274
#if MBED_CONF_SD_CRC_ENABLED
276275
SDBlockDevice::SDBlockDevice(const spi_pinmap_t &spi_pinmap, PinName cs, uint64_t hz, bool crc_on)
277-
: _sectors(0), _spi(spi_pinmap), _cs(cs), _is_initialized(0),
276+
: _sectors(0), _spi(spi_pinmap, cs), _is_initialized(0),
278277
_init_ref_count(0), _crc_on(crc_on)
279278
#else
280279
SDBlockDevice::SDBlockDevice(const spi_pinmap_t &spi_pinmap, PinName cs, uint64_t hz, bool crc_on)
281-
: _sectors(0), _spi(spi_pinmap), _cs(cs), _is_initialized(0),
280+
: _sectors(0), _spi(spi_pinmap, cs), _is_initialized(0),
282281
_init_ref_count(0)
283282
#endif
284283
{
285-
_cs = 1;
286284
_card_type = SDCARD_NONE;
287285

288286
// 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)
538536
_spi.write(SPI_STOP_TRAN);
539537
}
540538

541-
_deselect();
539+
_postclock_then_deselect();
542540
unlock();
543541
return status;
544542
}
@@ -585,7 +583,7 @@ int SDBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
585583
buffer += _block_size;
586584
--blockCnt;
587585
}
588-
_deselect();
586+
_postclock_then_deselect();
589587

590588
// Send CMD12(0x00000000) to stop the transmission for multi-block transfer
591589
if (size > _block_size) {
@@ -753,7 +751,7 @@ int SDBlockDevice::_cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg, bool isAc
753751

754752
// Select card and wait for card to be ready before sending next command
755753
// Note: next command will fail if card is not ready
756-
_select();
754+
_preclock_then_select();
757755

758756
// No need to wait for card to be ready when sending the stop command
759757
if (CMD12_STOP_TRANSMISSION != cmd) {
@@ -789,17 +787,17 @@ int SDBlockDevice::_cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg, bool isAc
789787

790788
// Process the response R1 : Exit on CRC/Illegal command error/No response
791789
if (R1_NO_RESPONSE == response) {
792-
_deselect();
790+
_postclock_then_deselect();
793791
debug_if(SD_DBG, "No response CMD:%d response: 0x%" PRIx32 "\n", cmd, response);
794792
return SD_BLOCK_DEVICE_ERROR_NO_DEVICE; // No device
795793
}
796794
if (response & R1_COM_CRC_ERROR) {
797-
_deselect();
795+
_postclock_then_deselect();
798796
debug_if(SD_DBG, "CRC error CMD:%d response 0x%" PRIx32 "\n", cmd, response);
799797
return SD_BLOCK_DEVICE_ERROR_CRC; // CRC error
800798
}
801799
if (response & R1_ILLEGAL_COMMAND) {
802-
_deselect();
800+
_postclock_then_deselect();
803801
debug_if(SD_DBG, "Illegal command CMD:%d response 0x%" PRIx32 "\n", cmd, response);
804802
if (CMD8_SEND_IF_COND == cmd) { // Illegal command is for Ver1 or not SD Card
805803
_card_type = CARD_UNKNOWN;
@@ -857,7 +855,7 @@ int SDBlockDevice::_cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg, bool isAc
857855
return BD_ERROR_OK;
858856
}
859857
// Deselect card
860-
_deselect();
858+
_postclock_then_deselect();
861859
return status;
862860
}
863861

@@ -908,7 +906,7 @@ int SDBlockDevice::_read_bytes(uint8_t *buffer, uint32_t length)
908906
// read until start byte (0xFE)
909907
if (false == _wait_token(SPI_START_BLOCK)) {
910908
debug_if(SD_DBG, "Read timeout\n");
911-
_deselect();
909+
_postclock_then_deselect();
912910
return SD_BLOCK_DEVICE_ERROR_NO_RESPONSE;
913911
}
914912

@@ -930,13 +928,13 @@ int SDBlockDevice::_read_bytes(uint8_t *buffer, uint32_t length)
930928
if (crc_result != crc) {
931929
debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%" PRIx16 " result of computation 0x%" PRIx32 "\n",
932930
crc, crc_result);
933-
_deselect();
931+
_postclock_then_deselect();
934932
return SD_BLOCK_DEVICE_ERROR_CRC;
935933
}
936934
}
937935
#endif
938936

939-
_deselect();
937+
_postclock_then_deselect();
940938
return 0;
941939
}
942940

@@ -1135,23 +1133,22 @@ void SDBlockDevice::_spi_init()
11351133
_spi.format(8, 0);
11361134
_spi.set_default_write_value(SPI_FILL_CHAR);
11371135
// Initial 74 cycles required for few cards, before selecting SPI mode
1138-
_cs = 1;
11391136
_spi_wait(10);
11401137
_spi.unlock();
11411138
}
11421139

1143-
void SDBlockDevice::_select()
1140+
void SDBlockDevice::_preclock_then_select()
11441141
{
11451142
_spi.lock();
11461143
_spi.write(SPI_FILL_CHAR);
1147-
_cs = 0;
1144+
_spi.select();
1145+
_spi.unlock();
11481146
}
11491147

1150-
void SDBlockDevice::_deselect()
1148+
void SDBlockDevice::_postclock_then_deselect()
11511149
{
1152-
_cs = 1;
11531150
_spi.write(SPI_FILL_CHAR);
1154-
_spi.unlock();
1151+
_spi.deselect();
11551152
}
11561153

11571154
#endif /* DEVICE_SPI */

components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,8 @@ class SDBlockDevice : public mbed::BlockDevice {
272272
int _read_bytes(uint8_t *buffer, uint32_t length);
273273
uint8_t _write(const uint8_t *buffer, uint8_t token, uint32_t length);
274274
int _freq(void);
275-
276-
/* Chip Select and SPI mode select */
277-
mbed::DigitalOut _cs;
278-
void _select();
279-
void _deselect();
275+
void _preclock_then_select();
276+
void _postclock_then_deselect();
280277

281278
virtual void lock()
282279
{

components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ SingletonPtr<PlatformMutex> SPIFBlockDevice::_mutex;
8787
//***********************
8888
SPIFBlockDevice::SPIFBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName csel, int freq)
8989
:
90-
_spi(mosi, miso, sclk), _cs(csel), _prog_instruction(0), _erase_instruction(0),
90+
_spi(mosi, miso, sclk, csel, use_gpio_ssel), _prog_instruction(0), _erase_instruction(0),
9191
_page_size_bytes(0), _init_ref_count(0), _is_initialized(false)
9292
{
9393
_address_size = SPIF_ADDR_SIZE_3_BYTES;
@@ -110,7 +110,7 @@ SPIFBlockDevice::SPIFBlockDevice(PinName mosi, PinName miso, PinName sclk, PinNa
110110
tr_error("SPI Set Frequency Failed");
111111
}
112112

113-
_cs = 1;
113+
_spi.deselect();
114114
}
115115

116116
int SPIFBlockDevice::init()
@@ -470,8 +470,7 @@ spif_bd_error SPIFBlockDevice::_spi_send_read_command(int read_inst, uint8_t *bu
470470
uint32_t dummy_bytes = _dummy_and_mode_cycles / 8;
471471
int dummy_byte = 0;
472472

473-
// csel must go low for the entire command (Inst, Address and Data)
474-
_cs = 0;
473+
_spi.select();
475474

476475
// Write 1 byte Instruction
477476
_spi.write(read_inst);
@@ -491,8 +490,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_read_command(int read_inst, uint8_t *bu
491490
buffer[i] = _spi.write(0);
492491
}
493492

494-
// csel back to high
495-
_cs = 1;
493+
_spi.deselect();
494+
496495
return SPIF_BD_ERROR_OK;
497496
}
498497

@@ -519,8 +518,7 @@ spif_bd_error SPIFBlockDevice::_spi_send_program_command(int prog_inst, const vo
519518
int dummy_byte = 0;
520519
uint8_t *data = (uint8_t *)buffer;
521520

522-
// csel must go low for the entire command (Inst, Address and Data)
523-
_cs = 0;
521+
_spi.select();
524522

525523
// Write 1 byte Instruction
526524
_spi.write(prog_inst);
@@ -540,8 +538,7 @@ spif_bd_error SPIFBlockDevice::_spi_send_program_command(int prog_inst, const vo
540538
_spi.write(data[i]);
541539
}
542540

543-
// csel back to high
544-
_cs = 1;
541+
_spi.deselect();
545542

546543
return SPIF_BD_ERROR_OK;
547544
}
@@ -561,8 +558,7 @@ spif_bd_error SPIFBlockDevice::_spi_send_general_command(int instruction, bd_add
561558
uint32_t dummy_bytes = _dummy_and_mode_cycles / 8;
562559
uint8_t dummy_byte = 0x00;
563560

564-
// csel must go low for the entire command (Inst, Address and Data)
565-
_cs = 0;
561+
_spi.select();
566562

567563
// Write 1 byte Instruction
568564
_spi.write(instruction);
@@ -583,8 +579,7 @@ spif_bd_error SPIFBlockDevice::_spi_send_general_command(int instruction, bd_add
583579
// Read/Write Data
584580
_spi.write(tx_buffer, (int)tx_length, rx_buffer, (int)rx_length);
585581

586-
// csel back to high
587-
_cs = 1;
582+
_spi.deselect();
588583

589584
return SPIF_BD_ERROR_OK;
590585
}

components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,6 @@ class SPIFBlockDevice : public mbed::BlockDevice {
266266
private:
267267
// Master side hardware
268268
mbed::SPI _spi;
269-
// Enable CS control (low/high) for SPI driver operations
270-
mbed::DigitalOut _cs;
271269

272270
// Mutex is used to protect Flash device for some SPI Driver commands that must be done sequentially with no other commands in between
273271
// e.g. (1)Set Write Enable, (2)Program, (3)Wait Memory Ready

0 commit comments

Comments
 (0)