Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for arbitrary QSPI alt sizes #11602

Merged
merged 2 commits into from
Oct 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions TESTS/mbed_hal/qspi/qspi_test_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ struct Qspi {
#define ADDR_SIZE_24 QSPI_CFG_ADDR_SIZE_24
#define ADDR_SIZE_32 QSPI_CFG_ADDR_SIZE_32

#define ALT_SIZE_8 8u
#define ALT_SIZE_16 16u
#define ALT_SIZE_24 24u
#define ALT_SIZE_32 32u
#define ALT_SIZE_8 QSPI_CFG_ALT_SIZE_8
#define ALT_SIZE_16 QSPI_CFG_ALT_SIZE_16
#define ALT_SIZE_24 QSPI_CFG_ALT_SIZE_24
#define ALT_SIZE_32 QSPI_CFG_ALT_SIZE_32

#define STATUS_REG QSPI_CMD_RDSR
#define CONFIG_REG0 QSPI_CMD_RDCR0
Expand Down
7 changes: 7 additions & 0 deletions hal/qspi_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ typedef enum qspi_address_size {
*/
typedef uint8_t qspi_alt_size_t;

// The following defines are provided for backwards compatibilty. New code should explicitly
// specify the required number of alt bits.
#define QSPI_CFG_ALT_SIZE_8 8u
#define QSPI_CFG_ALT_SIZE_16 16u
#define QSPI_CFG_ALT_SIZE_24 24u
#define QSPI_CFG_ALT_SIZE_32 32u

/** QSPI command
*
* Defines a frame format. It consists of instruction, address, alternative, dummy count and data
Expand Down
54 changes: 42 additions & 12 deletions targets/TARGET_STM/qspi_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,40 @@
/* hence 2^(31+1), then FLASH_SIZE_DEFAULT = 1<<31 */
#define QSPI_FLASH_SIZE_DEFAULT 0x80000000

#if defined(OCTOSPI1)
static uint32_t get_alt_bytes_size(const uint32_t num_bytes)
{
switch (num_bytes) {
case 1:
return HAL_OSPI_ALTERNATE_BYTES_8_BITS;
case 2:
return HAL_OSPI_ALTERNATE_BYTES_16_BITS;
case 3:
return HAL_OSPI_ALTERNATE_BYTES_24_BITS;
case 4:
return HAL_OSPI_ALTERNATE_BYTES_32_BITS;
}
error("Invalid alt bytes size");
return 0xFFFFFFFF;
}
#else /* OCTOSPI1 */
static uint32_t get_alt_bytes_size(const uint32_t num_bytes)
{
switch (num_bytes) {
case 1:
return QSPI_ALTERNATE_BYTES_8_BITS;
case 2:
return QSPI_ALTERNATE_BYTES_16_BITS;
case 3:
return QSPI_ALTERNATE_BYTES_24_BITS;
case 4:
return QSPI_ALTERNATE_BYTES_32_BITS;
}
error("Invalid alt bytes size");
return 0xFFFFFFFF;
}
#endif /* OCTOSPI1 */

#if defined(OCTOSPI1)
qspi_status_t qspi_prepare_command(const qspi_command_t *command, OSPI_RegularCmdTypeDef *st_command)
{
Expand Down Expand Up @@ -151,15 +185,15 @@ qspi_status_t qspi_prepare_command(const qspi_command_t *command, OSPI_RegularCm
}

// Round up to nearest byte - unused parts of byte act as dummy cycles
uint32_t rounded_size = ((command->alt.size - 1) >> 3) + 1;
uint32_t alt_bytes = ((command->alt.size - 1) >> 3) + 1;
// Maximum of 4 alt bytes
if (rounded_size > 4) {
if (alt_bytes > 4) {
error("Command param error: alt size exceeds maximum of 32 bits\n");
return QSPI_STATUS_ERROR;
}

// Unused bits in most significant byte of alt
uint8_t leftover_bits = (rounded_size << 3) - command->alt.size;
uint8_t leftover_bits = (alt_bytes << 3) - command->alt.size;
if (leftover_bits != 0) {
// Account for dummy cycles that will be spent in the alt portion of the command
uint8_t integrated_dummy_cycles = leftover_bits / alt_lines;
Expand All @@ -176,9 +210,7 @@ qspi_status_t qspi_prepare_command(const qspi_command_t *command, OSPI_RegularCm
st_command->AlternateBytes = command->alt.value;
}

/* command->AlternateBytesSize needs to be shifted by OCTOSPI_CCR_ABSIZE_Pos */
// 0b00 = 1 byte, 0b01 = 2 bytes, 0b10 = 3 bytes, 0b11 = 4 bytes
st_command->AlternateBytesSize = ((rounded_size - 1) << OCTOSPI_CCR_ABSIZE_Pos) & OCTOSPI_CCR_ABSIZE_Msk;
st_command->AlternateBytesSize = get_alt_bytes_size(alt_bytes);
}

switch (command->data.bus_width) {
Expand Down Expand Up @@ -283,14 +315,14 @@ qspi_status_t qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTy
}

// Round up to nearest byte - unused parts of byte act as dummy cycles
uint32_t rounded_size = ((command->alt.size - 1) >> 3) + 1;
uint32_t alt_bytes = ((command->alt.size - 1) >> 3) + 1;
// Maximum of 4 alt bytes
if (rounded_size > 4) {
if (alt_bytes > 4) {
return QSPI_STATUS_ERROR;
}

// Unused bits in most significant byte of alt
uint8_t leftover_bits = (rounded_size << 3) - command->alt.size;
uint8_t leftover_bits = (alt_bytes << 3) - command->alt.size;
if (leftover_bits != 0) {
// Account for dummy cycles that will be spent in the alt portion of the command
uint8_t integrated_dummy_cycles = leftover_bits / alt_lines;
Expand All @@ -306,9 +338,7 @@ qspi_status_t qspi_prepare_command(const qspi_command_t *command, QSPI_CommandTy
st_command->AlternateBytes = command->alt.value;
}

/* command->AlternateBytesSize needs to be shifted by QUADSPI_CCR_ABSIZE_Pos */
// 0b00 = 1 byte, 0b01 = 2 bytes, 0b10 = 3 bytes, 0b11 = 4 bytes
st_command->AlternateBytesSize = ((rounded_size - 1) << QUADSPI_CCR_ABSIZE_Pos) & QUADSPI_CCR_ABSIZE_Msk;
st_command->AlternateBytesSize = get_alt_bytes_size(alt_bytes);
}

switch (command->data.bus_width) {
Expand Down