git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9508 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
Giovanni Di Sirio 2016-05-24 13:57:49 +00:00
parent b36f9f5585
commit a3c37f98cc
6 changed files with 229 additions and 33 deletions

View File

@ -25,8 +25,9 @@
* @{ * @{
*/ */
#include "hal.h" #include <string.h>
#include "hal.h"
#include "m25q.h" #include "m25q.h"
/*===========================================================================*/ /*===========================================================================*/
@ -82,11 +83,7 @@ static flash_descriptor_t descriptor = {
.attributes = FLASH_ATTR_ERASED_IS_ONE | FLASH_ATTR_REWRITABLE | .attributes = FLASH_ATTR_ERASED_IS_ONE | FLASH_ATTR_REWRITABLE |
FLASH_ATTR_SUSPEND_ERASE_CAPABLE, FLASH_ATTR_SUSPEND_ERASE_CAPABLE,
.page_size = 256U, .page_size = 256U,
#if M25Q_USE_SUB_SECTORS == TRUE .sectors_count = 0U, /* It is overwritten.*/
.sectors_count = 4096U,
#else
.sectors_count = 256U,
#endif
.sectors = NULL, .sectors = NULL,
.sectors_size = SECTOR_SIZE, .sectors_size = SECTOR_SIZE,
.address = 0U .address = 0U
@ -209,9 +206,11 @@ static const uint8_t evconf_value[1] = {0xCF};
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L #elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L
static const uint8_t evconf_value[1] = {0x8F}; static const uint8_t evconf_value[1] = {0x8F};
#else #else
static const uint8_t evconf_value[1] = {0xCF};//{0x4F}; static const uint8_t evconf_value[1] = {0x4F};
#endif #endif
static const uint8_t flash_status[1] = {(M25Q_READ_DUMMY_CYCLES << 4U) | 0x0FU};
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ #endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */
/*===========================================================================*/ /*===========================================================================*/
@ -314,6 +313,39 @@ static void flash_cmd_receive(M25QDriver *devp,
#endif #endif
} }
static void flash_cmd_send(M25QDriver *devp,
uint8_t cmd,
size_t n,
const uint8_t *p) {
#if M25Q_BUS_MODE != M25Q_BUS_MODE_SPI
qspi_command_t mode;
mode.cfg = QSPI_CFG_CMD(cmd) |
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L
QSPI_CFG_CMD_MODE_ONE_LINE |
QSPI_CFG_DATA_MODE_ONE_LINE;
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L
QSPI_CFG_CMD_MODE_TWO_LINES |
QSPI_CFG_DATA_MODE_TWO_LINES;
#else
QSPI_CFG_CMD_MODE_FOUR_LINES |
QSPI_CFG_DATA_MODE_FOUR_LINES;
#endif
mode.addr = 0U;
mode.alt = 0U;
qspiSend(devp->config->qspip, &mode, n, p);
#else
uint8_t buf[1];
spiSelect(devp->config->spip);
buf[0] = cmd;
spiSend(devp->config->spip, 1, buf);
spiSend(devp->config->spip, n, p);
spiUnselect(devp->config->spip);
#endif
}
static void flash_cmd_addr(M25QDriver *devp, static void flash_cmd_addr(M25QDriver *devp,
uint8_t cmd, uint8_t cmd,
flash_address_t addr) { flash_address_t addr) {
@ -437,6 +469,42 @@ static void flash_cmd_addr_receive(M25QDriver *devp,
#endif #endif
} }
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) || defined(__DOXYGEN__)
static void flash_cmd_addr_dummy_receive(M25QDriver *devp,
uint8_t cmd,
flash_address_t addr,
uint8_t dummy,
size_t n,
uint8_t *p) {
qspi_command_t mode;
mode.cfg = QSPI_CFG_CMD(cmd) |
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L
QSPI_CFG_CMD_MODE_ONE_LINE |
QSPI_CFG_ADDR_MODE_ONE_LINE |
QSPI_CFG_ADDR_SIZE_24 |
QSPI_CFG_DUMMY_CYCLES(dummy) |
QSPI_CFG_DATA_MODE_ONE_LINE;
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L
QSPI_CFG_CMD_MODE_TWO_LINES |
QSPI_CFG_ADDR_MODE_TWO_LINES |
QSPI_CFG_ADDR_SIZE_24 |
QSPI_CFG_DUMMY_CYCLES(dummy) |
QSPI_CFG_DATA_MODE_TWO_LINES;
#else
QSPI_CFG_CMD_MODE_FOUR_LINES |
QSPI_CFG_ADDR_MODE_FOUR_LINES |
QSPI_CFG_ADDR_SIZE_24 |
QSPI_CFG_DUMMY_CYCLES(dummy) |
QSPI_CFG_DATA_MODE_FOUR_LINES;
#endif
mode.addr = addr;
mode.alt = 0U;
qspiReceive(devp->config->qspip, &mode, n, p);
}
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */
static flash_error_t flash_poll_status(M25QDriver *devp) { static flash_error_t flash_poll_status(M25QDriver *devp) {
return FLASH_NO_ERROR; return FLASH_NO_ERROR;
@ -454,6 +522,38 @@ static const flash_descriptor_t *get_descriptor(void *instance) {
static flash_error_t read(void *instance, flash_address_t addr, static flash_error_t read(void *instance, flash_address_t addr,
uint8_t *rp, size_t n) { uint8_t *rp, size_t n) {
M25QDriver *devp = (M25QDriver *)instance;
osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U));
osalDbgCheck((size_t)addr + n <= (size_t)descriptor.sectors_count *
(size_t)descriptor.sectors_size);
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
"invalid state");
if (devp->state == FLASH_ERASE) {
return FLASH_BUSY_ERASING;
}
/* Bus acquired.*/
flash_bus_acquire(devp);
/* FLASH_READY state while the operation is performed.*/
devp->state = FLASH_READ;
#if M25Q_BUS_MODE != M25Q_BUS_MODE_SPI
/* Fast read command in QSPI mode.*/
flash_cmd_addr_dummy_receive(devp, M25Q_CMD_FAST_READ,
addr, M25Q_READ_DUMMY_CYCLES,
n, rp);
#else
/* Normal read command in SPI mode.*/
#endif
/* Ready state again.*/
devp->state = FLASH_READY;
/* Bus released.*/
flash_bus_release(devp);
return FLASH_NO_ERROR; return FLASH_NO_ERROR;
} }
@ -516,6 +616,18 @@ void m25qObjectInit(M25QDriver *devp) {
#endif #endif
} }
static const qspi_command_t cmd_test_reset_enable_4 = {
.cfg = QSPI_CFG_ALT_MODE_FOUR_LINES,
.addr = 0,
.alt = M25Q_CMD_RESET_ENABLE
};
static const qspi_command_t cmd_test_reset_memory_4 = {
.cfg = QSPI_CFG_ALT_MODE_FOUR_LINES,
.addr = 0,
.alt = M25Q_CMD_RESET_MEMORY
};
/** /**
* @brief Configures and activates N25Q128 driver. * @brief Configures and activates N25Q128 driver.
* *
@ -532,7 +644,6 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) {
devp->config = config; devp->config = config;
if (devp->state == FLASH_STOP) { if (devp->state == FLASH_STOP) {
uint8_t id[3];
/* Bus acquisition.*/ /* Bus acquisition.*/
flash_bus_acquire(devp); flash_bus_acquire(devp);
@ -546,46 +657,62 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) {
/* QSPI initialization.*/ /* QSPI initialization.*/
qspiStart(devp->config->qspip, devp->config->qspicfg); qspiStart(devp->config->qspip, devp->config->qspicfg);
/* Reading device ID and unique ID.*/
#if M25Q_SWITCH_WIDTH == TRUE #if M25Q_SWITCH_WIDTH == TRUE
/* Attempting a device reset with decreasing bus widths, commands /* Attempting a device reset with different bus widths, commands
shorter than 8 bits are ignored.*/ shorter than 8 bits are ignored.*/
qspiCommand(devp->config->qspip, &cmd_reset_enable_4);
qspiCommand(devp->config->qspip, &cmd_reset_memory_4);
qspiCommand(devp->config->qspip, &cmd_reset_enable_2);
qspiCommand(devp->config->qspip, &cmd_reset_memory_2);
qspiCommand(devp->config->qspip, &cmd_reset_enable_1); qspiCommand(devp->config->qspip, &cmd_reset_enable_1);
qspiCommand(devp->config->qspip, &cmd_reset_memory_1); qspiCommand(devp->config->qspip, &cmd_reset_memory_1);
qspiCommand(devp->config->qspip, &cmd_reset_enable_2);
qspiCommand(devp->config->qspip, &cmd_reset_memory_2);
qspiCommand(devp->config->qspip, &cmd_reset_enable_4);
qspiCommand(devp->config->qspip, &cmd_reset_memory_4);
#endif #endif
/* Reading device ID.*/ /* Reading device ID and unique ID.*/
qspiReceive(devp->config->qspip, &cmd_read_id, 3, id); qspiReceive(devp->config->qspip, &cmd_read_id,
sizeof devp->device_id, devp->device_id);
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ #endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */
/* Checking if the device is white listed.*/ /* Checking if the device is white listed.*/
osalDbgAssert(find_id(manufacturer_ids, sizeof manufacturer_ids, id[0]), osalDbgAssert(find_id(manufacturer_ids,
sizeof manufacturer_ids,
devp->device_id[0]),
"invalid manufacturer id"); "invalid manufacturer id");
osalDbgAssert(find_id(memory_type_ids, sizeof memory_type_ids, id[1]), osalDbgAssert(find_id(memory_type_ids,
sizeof memory_type_ids,
devp->device_id[1]),
"invalid memory type id"); "invalid memory type id");
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) && (M25Q_SWITCH_WIDTH == TRUE) #if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) && (M25Q_SWITCH_WIDTH == TRUE)
/* Setting up final bus width.*/ /* Setting up final bus width.*/
qspiCommand(devp->config->qspip, &cmd_write_enable); qspiCommand(devp->config->qspip, &cmd_write_enable);
qspiSend(devp->config->qspip, &cmd_write_evconf, 1, evconf_value); qspiSend(devp->config->qspip, &cmd_write_evconf, 1, evconf_value);
{
uint8_t id[3];
/* Reading ID again for confirmation.*/
flash_cmd_receive(devp, M25Q_CMD_MULTIPLE_IO_READ_ID, 3, id);
/* Checking if the device is white listed.*/
osalDbgAssert(memcmp(id, devp->device_id, 3) == 0,
"id confirmation failed");
}
#endif #endif
flash_cmd_receive(devp, M25Q_CMD_READ_ID, 3, id); /* Setting up the device size.*/
descriptor.sectors_count = (1U << (size_t)devp->device_id[2]) / SECTOR_SIZE;
flash_cmd_receive(devp, M25Q_CMD_READ_ID, 3, id); #if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI)
/* Setting up the dummy cycles to be used for rast read operations.*/
/* Reading device ID.*/ flash_cmd(devp, M25Q_CMD_WRITE_ENABLE);
qspiReceive(devp->config->qspip, &cmd_read_id, 3, id); flash_cmd_send(devp, M25Q_CMD_WRITE_V_CONF_REGISTER,
1, flash_status);
/* Reset Enable command.*/ #endif
// flash_short_cmd(devp, M25Q_CMD_RESET_ENABLE);
/* Reset Memory command.*/
// flash_short_cmd(devp, M25Q_CMD_RESET_MEMORY);
/* Driver in ready state.*/
devp->state = FLASH_READY; devp->state = FLASH_READY;
/* Bus release.*/ /* Bus release.*/
@ -617,6 +744,8 @@ void m25qStop(M25QDriver *devp) {
#endif #endif
devp->config = NULL; devp->config = NULL;
/* Driver stopped.*/
devp->state = FLASH_STOP; devp->state = FLASH_STOP;
/* Bus release.*/ /* Bus release.*/

View File

@ -41,9 +41,10 @@
#define M25Q_CMD_RESET_ENABLE 0x66 #define M25Q_CMD_RESET_ENABLE 0x66
#define M25Q_CMD_RESET_MEMORY 0x99 #define M25Q_CMD_RESET_MEMORY 0x99
#define M25Q_CMD_READ_ID 0x9F #define M25Q_CMD_READ_ID 0x9F
#define M25Q_CMD_MULTIPLE_IO_READ_ID 0xAF
#define M25Q_CMD_READ_DISCOVERY_PARAMETER 0x5A #define M25Q_CMD_READ_DISCOVERY_PARAMETER 0x5A
#define M25Q_CMD_READ 0x03 #define M25Q_CMD_READ 0x03
#define M25Q_CMD_FAST_READ 0x08 #define M25Q_CMD_FAST_READ 0x0B
#define M25Q_CMD_WRITE_ENABLE 0x06 #define M25Q_CMD_WRITE_ENABLE 0x06
#define M25Q_CMD_WRITE_DISABLE 0x04 #define M25Q_CMD_WRITE_DISABLE 0x04
#define M25Q_CMD_READ_STATUS_REGISTER 0x05 #define M25Q_CMD_READ_STATUS_REGISTER 0x05
@ -111,6 +112,15 @@
#define M25Q_BUS_MODE M25Q_BUS_MODE_QSPI4L #define M25Q_BUS_MODE M25Q_BUS_MODE_QSPI4L
#endif #endif
/**
* @brief Number of dummy cycles for fast read (1..15).
* @details This is the number of dummy cycles to be used for fast read
* operations.
*/
#if !defined(M25Q_READ_DUMMY_CYCLES) || defined(__DOXYGEN__)
#define M25Q_READ_DUMMY_CYCLES 8
#endif
/** /**
* @brief Switch QSPI bus width on initialization. * @brief Switch QSPI bus width on initialization.
* @details A bus width initialization is performed by writing the * @details A bus width initialization is performed by writing the
@ -185,6 +195,17 @@
#error "M25Q_SHARED_SPI requires SPI_USE_MUTUAL_EXCLUSION" #error "M25Q_SHARED_SPI requires SPI_USE_MUTUAL_EXCLUSION"
#endif #endif
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) && \
(M25Q_BUS_MODE != M25Q_BUS_MODE_QSPI1L) && \
(M25Q_BUS_MODE != M25Q_BUS_MODE_QSPI2L) && \
(M25Q_BUS_MODE != M25Q_BUS_MODE_QSPI4L)
#error "invalid M25Q_BUS_MODE selected"
#endif
#if (M25Q_READ_DUMMY_CYCLES < 1) || (M25Q_READ_DUMMY_CYCLES > 15)
#error "invalid M25Q_READ_DUMMY_CYCLES value (1..15)"
#endif
/*===========================================================================*/ /*===========================================================================*/
/* Driver data structures and types. */ /* Driver data structures and types. */
/*===========================================================================*/ /*===========================================================================*/
@ -250,6 +271,10 @@ typedef struct {
*/ */
uint32_t qspi_mode; uint32_t qspi_mode;
#endif #endif
/**
* @brief Device ID and unique ID.
*/
uint8_t device_id[20];
} M25QDriver; } M25QDriver;
/*===========================================================================*/ /*===========================================================================*/

View File

@ -211,6 +211,22 @@ void qspi_lld_stop(QSPIDriver *qspip) {
*/ */
void qspi_lld_command(QSPIDriver *qspip, const qspi_command_t *cmdp) { void qspi_lld_command(QSPIDriver *qspip, const qspi_command_t *cmdp) {
#if STM32_USE_STM32_D1_WORKAROUND == TRUE
/* If it is a command without address and alternate phases then the command
is sent as an alternate byte, the command phase is suppressed.*/
if ((cmdp->cfg & (QSPI_CFG_ADDR_MODE_MASK | QSPI_CFG_ALT_MODE_MASK)) == 0U) {
uint32_t cfg;
/* The command mode field is copied in the alternate mode field. All
other fields are not used in this scenario.*/
cfg = (cmdp->cfg & QSPI_CFG_CMD_MODE_MASK) << 6U;
qspip->qspi->DLR = 0U;
qspip->qspi->ABR = cmdp->cfg & QSPI_CFG_CMD_MASK;
qspip->qspi->CCR = cfg;
return;
}
#endif
qspip->qspi->DLR = 0U; qspip->qspi->DLR = 0U;
qspip->qspi->ABR = cmdp->alt; qspip->qspi->ABR = cmdp->alt;
qspip->qspi->CCR = cmdp->cfg; qspip->qspi->CCR = cmdp->cfg;

View File

@ -31,6 +31,17 @@
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name DCR register options
* @{
*/
#define STM32_DCR_CK_MODE (1U << 0U)
#define STM32_DCR_CSHT_MASK (7U << 8U)
#define STM32_DCR_CSHT(n) ((n) << 8U)
#define STM32_DCR_FSIZE_MASK (31U << 16U)
#define STM32_DCR_FSIZE(n) ((n) << 16U)
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
@ -85,6 +96,17 @@
#if !defined(STM32_QSPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__) #if !defined(STM32_QSPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
#define STM32_QSPI_DMA_ERROR_HOOK(qspip) osalSysHalt("DMA failure") #define STM32_QSPI_DMA_ERROR_HOOK(qspip) osalSysHalt("DMA failure")
#endif #endif
/**
* @brief Enables a workaround for a STM32L476 QUADSPI errata.
* @details The document DM00111498 states: "QUADSPI_BK1_IO1 is always an
* input when the command is sent in dual or quad SPI mode".
* This workaround makes commands without address or data phases
* to be sent as alternate bytes.
*/
#if !defined(STM32_USE_STM32_D1_WORKAROUND) || defined(__DOXYGEN__)
#define STM32_USE_STM32_D1_WORKAROUND TRUE
#endif
/** @} */ /** @} */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -33,7 +33,7 @@
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/> <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/> <stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/> <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;contentList&gt;&lt;content id=&quot;id[2]-id-m25qStart-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;id[1]-id-m25qStart-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;id[0]-id-m25qStart-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;cr2-adc_lld_start_conversion-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CR2-adc-null-port_wait_for_interrupt-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CR2-adc-adcp-adc_lld_start_conversion-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;cfg-cmdp-qspiSend-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CR-qspi-qspip-qspi_lld_send-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CCR-qspi-qspip-qspi_lld_send-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;cfg-cmdp-qspiReceive-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;r2-(format)&quot; val=&quot;4&quot;/&gt;&lt;/contentList&gt;"/> <stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;contentList&gt;&lt;content id=&quot;CCR-qspi-qspip-qspi_lld_receive-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;cfg-cmdp-qspi_lld_receive-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;id[2]-id-m25qStart-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;id[1]-id-m25qStart-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;id[0]-id-m25qStart-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;AFRL-gpiop-initgpio-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;AFRH-gpiop-initgpio-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;ODR-gpiop-initgpio-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;IDR-gpiop-initgpio-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;PUPDR-gpiop-initgpio-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;OSPEEDR-gpiop-initgpio-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;MODER-gpiop-initgpio-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;afrh-config-initgpio-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;moder-config-initgpio-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;config-initgpio-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;r2-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;cfg-cmdp-qspiReceive-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CCR-qspi-qspip-qspi_lld_send-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CR-qspi-qspip-qspi_lld_send-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;cfg-cmdp-qspiSend-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CR2-adc-adcp-adc_lld_start_conversion-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CR2-adc-null-port_wait_for_interrupt-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;cr2-adc_lld_start_conversion-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;cmd-flash_cmd_receive-(format)&quot; val=&quot;4&quot;/&gt;&lt;/contentList&gt;"/>
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;globalVariableList/&gt;&#13;&#10;"/> <stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;globalVariableList/&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList/&gt;&#13;&#10;"/> <stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList/&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/> <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>

View File

@ -21,7 +21,7 @@
const QSPIConfig qspicfg1 = { const QSPIConfig qspicfg1 = {
NULL, NULL,
0 STM32_DCR_FSIZE(24) | STM32_DCR_CSHT(1)
}; };
qspi_command_t cmd_read_id = { qspi_command_t cmd_read_id = {
@ -63,6 +63,7 @@ static THD_FUNCTION(Thread1, arg) {
* Application entry point. * Application entry point.
*/ */
int main(void) { int main(void) {
flash_error_t err;
/* /*
* System initializations. * System initializations.
@ -89,8 +90,11 @@ int main(void) {
*/ */
m25qObjectInit(&m25q); m25qObjectInit(&m25q);
m25qStart(&m25q, &m25qcfg1); m25qStart(&m25q, &m25qcfg1);
// qspiStart(&QSPID1, &qspicfg1);
// qspiReceive(&QSPID1, &cmd_read_id, 17, buffer); /* Reading it back.*/
err = flashRead(&m25q, 0, buffer, 128);
if (err != FLASH_NO_ERROR)
chSysHalt("read error");
/* /*
* Normal main() thread activity, in this demo it does nothing. * Normal main() thread activity, in this demo it does nothing.