Skip to content

Commit 699a689

Browse files
author
Marcin Tomczyk
committed
[IOTSTOR-990] SPIFBlockDevice doesn't play nice on shared SPI bus. Back to use select and deselect, use correct spi constructor
1 parent 116a8a7 commit 699a689

File tree

4 files changed

+48
-22
lines changed

4 files changed

+48
-22
lines changed

components/storage/blockdevice/COMPONENT_DATAFLASH/DataFlashBlockDevice.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ DataFlashBlockDevice::DataFlashBlockDevice(PinName mosi,
140140
PinName cs,
141141
int freq,
142142
PinName nwp)
143-
: _spi(mosi, miso, sclk, cs),
143+
: _spi(mosi, miso, sclk, cs, use_gpio_ssel),
144144
_nwp(nwp),
145145
_device_size(0),
146146
_page_size(0),
@@ -330,6 +330,8 @@ int DataFlashBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
330330

331331
uint8_t *external_buffer = static_cast<uint8_t *>(buffer);
332332

333+
_spi.select();
334+
333335
/* send read opcode */
334336
_spi.write(DATAFLASH_OP_READ_LOW_FREQUENCY);
335337

@@ -348,6 +350,8 @@ int DataFlashBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
348350
external_buffer[index] = _spi.write(DATAFLASH_OP_NOP);
349351
}
350352

353+
_spi.deselect();
354+
351355
result = BD_ERROR_OK;
352356
}
353357

@@ -539,13 +543,17 @@ uint16_t DataFlashBlockDevice::_get_register(uint8_t opcode)
539543
_mutex.lock();
540544
DEBUG_PRINTF("_get_register: %" PRIX8 "\r\n", opcode);
541545

546+
_spi.select();
547+
542548
/* write opcode */
543549
_spi.write(opcode);
544550

545551
/* read and store result */
546552
int status = (_spi.write(DATAFLASH_OP_NOP));
547553
status = (status << 8) | (_spi.write(DATAFLASH_OP_NOP));
548554

555+
_spi.deselect();
556+
549557
_mutex.unlock();
550558
return status;
551559
}
@@ -566,6 +574,8 @@ void DataFlashBlockDevice::_write_command(uint32_t command, const uint8_t *buffe
566574
{
567575
DEBUG_PRINTF("_write_command: %" PRIX32 " %p %" PRIX32 "\r\n", command, buffer, size);
568576

577+
_spi.select();
578+
569579
/* send command (opcode with data or 4 byte command) */
570580
_spi.write((command >> 24) & 0xFF);
571581
_spi.write((command >> 16) & 0xFF);
@@ -578,6 +588,8 @@ void DataFlashBlockDevice::_write_command(uint32_t command, const uint8_t *buffe
578588
_spi.write(buffer[index]);
579589
}
580590
}
591+
592+
_spi.deselect();
581593
}
582594

583595
/**

components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.cpp

Lines changed: 20 additions & 16 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), _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), _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-
_spi.deselect();
264263
_card_type = SDCARD_NONE;
265264

266265
// 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_
282281
_init_ref_count(0)
283282
#endif
284283
{
285-
_spi.deselect();
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

@@ -1129,22 +1127,28 @@ void SDBlockDevice::_spi_wait(uint8_t count)
11291127

11301128
void SDBlockDevice::_spi_init()
11311129
{
1130+
_spi.lock();
11321131
// Set to SCK for initialization, and clock card with cs = 1
11331132
_spi.frequency(_init_sck);
11341133
_spi.format(8, 0);
11351134
_spi.set_default_write_value(SPI_FILL_CHAR);
11361135
// Initial 74 cycles required for few cards, before selecting SPI mode
11371136
_spi_wait(10);
1137+
_spi.unlock();
11381138
}
11391139

1140-
void SDBlockDevice::_select()
1140+
void SDBlockDevice::_preclock_then_select()
11411141
{
1142+
_spi.lock();
11421143
_spi.write(SPI_FILL_CHAR);
1144+
_spi.select();
1145+
_spi.unlock();
11431146
}
11441147

1145-
void SDBlockDevice::_deselect()
1148+
void SDBlockDevice::_postclock_then_deselect()
11461149
{
11471150
_spi.write(SPI_FILL_CHAR);
1151+
_spi.deselect();
11481152
}
11491153

11501154
#endif /* DEVICE_SPI */

components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,10 +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-
void _select();
278-
void _deselect();
275+
void _preclock_then_select();
276+
void _postclock_then_deselect();
279277

280278
virtual void lock()
281279
{

components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp

Lines changed: 13 additions & 1 deletion
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, 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;
@@ -470,6 +470,8 @@ 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+
_spi.select();
474+
473475
// Write 1 byte Instruction
474476
_spi.write(read_inst);
475477

@@ -488,6 +490,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_read_command(int read_inst, uint8_t *bu
488490
buffer[i] = _spi.write(0);
489491
}
490492

493+
_spi.deselect();
494+
491495
return SPIF_BD_ERROR_OK;
492496
}
493497

@@ -514,6 +518,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_program_command(int prog_inst, const vo
514518
int dummy_byte = 0;
515519
uint8_t *data = (uint8_t *)buffer;
516520

521+
_spi.select();
522+
517523
// Write 1 byte Instruction
518524
_spi.write(prog_inst);
519525

@@ -532,6 +538,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_program_command(int prog_inst, const vo
532538
_spi.write(data[i]);
533539
}
534540

541+
_spi.deselect();
542+
535543
return SPIF_BD_ERROR_OK;
536544
}
537545

@@ -550,6 +558,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_general_command(int instruction, bd_add
550558
uint32_t dummy_bytes = _dummy_and_mode_cycles / 8;
551559
uint8_t dummy_byte = 0x00;
552560

561+
_spi.select();
562+
553563
// Write 1 byte Instruction
554564
_spi.write(instruction);
555565

@@ -569,6 +579,8 @@ spif_bd_error SPIFBlockDevice::_spi_send_general_command(int instruction, bd_add
569579
// Read/Write Data
570580
_spi.write(tx_buffer, (int)tx_length, rx_buffer, (int)rx_length);
571581

582+
_spi.deselect();
583+
572584
return SPIF_BD_ERROR_OK;
573585
}
574586

0 commit comments

Comments
 (0)