mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #14221 from macronix/macronix_rww
Enable the RWW function of Macronix Flash MX25LW51245G in OSPI block device driverpull/14733/head
commit
5fe4dafc34
|
@ -17,7 +17,6 @@
|
|||
#ifndef MBED_OSPI_FLASH_MX25LM51245G_H
|
||||
#define MBED_OSPI_FLASH_MX25LM51245G_H
|
||||
|
||||
|
||||
#define OSPI_FLASH_CHIP_STRING "macronix MX25LM51245G"
|
||||
|
||||
// This is a workaround,
|
||||
|
@ -26,20 +25,13 @@
|
|||
// The code below can be removed when users test with the new flash.
|
||||
#define NEED_DEFINE_SFDP_PARA
|
||||
|
||||
#ifdef NEED_DEFINE_SFDP_PARA
|
||||
uint8_t _sfdp_head_table[32] = {0x53, 0x46, 0x44, 0x50, 0x06, 0x01, 0x02, 0xFF, 0x00, 0x06, 0x01,
|
||||
0x10, 0x30, 0x00, 0x00, 0xFF, 0xC2, 0x00, 0x01, 0x04, 0x10, 0x01,
|
||||
0x00, 0xFF, 0x84, 0x00, 0x01, 0x02, 0xC0, 0x00, 0x00, 0xFF
|
||||
};
|
||||
uint8_t _sfdp_basic_param_table[64] = {0x30, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x14, 0xEC,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0x20,
|
||||
0x10, 0xDC, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x50, 0xF9, 0x80
|
||||
};
|
||||
uint8_t _sfdp_4_byte_inst_table[8] = {0x7F, 0xEF, 0xFF, 0xFF, 0x21, 0x5C, 0xDC, 0x14};
|
||||
#endif
|
||||
#define OSPIF_CR2_OPI_EN_ADDR 0x00000000
|
||||
|
||||
#define MX_FLASH_BLOCK_SIZE 0x10000 /* 1024 blocks of 64 KBytes */
|
||||
#define MX_FLASH_SECTOR_SIZE 0x1000 /* 16384 sectors of 4 kBytes */
|
||||
#define MX_FLASH_PAGE_SIZE 0x100 /* 262144 pages of 256 bytes */
|
||||
#define MX_FLASH_CHUNK_SIZE 0x10 /* 16 bytes */
|
||||
#define MX_FLASH_BANK_SIZE 0x01000000 /* 16 MBytes */
|
||||
#define MX_FLASH_BANK_SIZE_MASK ~(MX_FLASH_BANK_SIZE - 1) /* 0xFF000000 */
|
||||
|
||||
#endif // MBED_OSPI_FLASH_MX25LM51245G_H
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2020 ARM Limited
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MBED_OSPI_FLASH_MX25LW51245G_H
|
||||
#define MBED_OSPI_FLASH_MX25LW51245G_H
|
||||
|
||||
#define OSPI_FLASH_CHIP_STRING "macronix MX25LW51245G"
|
||||
|
||||
// This is a workaround,
|
||||
// The sfdp parameter values in Macronix old octaflash(include the MX25LW51245G on L4R9I_DISCO) are all 0xFF,
|
||||
// so we need to define the parameter values by software to support SFDP parsing.
|
||||
// The code below can be removed when users test with the new flash.
|
||||
#define NEED_DEFINE_SFDP_PARA
|
||||
|
||||
#define MX_FLASH_SUPPORT_RWW 1
|
||||
|
||||
// Configuration Register2 address
|
||||
#define OSPIF_CR2_OPI_EN_ADDR 0x00000000
|
||||
#define OSPIF_CR2_BANK_STATUS_ADDR 0xc0000000
|
||||
#define OSPIF_CR2_RWWDI ((uint8_t)0x00) /*!< No active program or erase operation */
|
||||
#define OSPIF_CR2_RWWDS ((uint8_t)0x01) /*!< Program/erase in other bank */
|
||||
#define OSPIF_CR2_RWWBS ((uint8_t)0x03) /*!< program/erase operation in addressed bank */
|
||||
|
||||
#define MX_FLASH_BLOCK_SIZE 0x10000 /* 1024 blocks of 64 KBytes */
|
||||
#define MX_FLASH_SECTOR_SIZE 0x1000 /* 16384 sectors of 4 kBytes */
|
||||
#define MX_FLASH_PAGE_SIZE 0x100 /* 262144 pages of 256 bytes */
|
||||
#define MX_FLASH_CHUNK_SIZE 0x10 /* 16 bytes */
|
||||
#define MX_FLASH_BANK_SIZE 0x01000000 /* 16 MBytes */
|
||||
#define MX_FLASH_BANK_SIZE_MASK ~(MX_FLASH_BANK_SIZE - 1) /* 0xFF000000 */
|
||||
|
||||
#endif // MBED_OSPI_FLASH_MX25LW51245G_H
|
|
@ -22,6 +22,14 @@
|
|||
#include "blockdevice/BlockDevice.h"
|
||||
#include "platform/Callback.h"
|
||||
|
||||
#if defined(TARGET_MX25LM51245G)
|
||||
#include "MX25LM51245G_config.h"
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_MX25LW51245G)
|
||||
#include "MX25LW51245G_config.h"
|
||||
#endif
|
||||
|
||||
#ifndef MBED_CONF_OSPIF_OSPI_IO0
|
||||
#define MBED_CONF_OSPIF_OSPI_IO0 NC
|
||||
#endif
|
||||
|
@ -381,6 +389,10 @@ private:
|
|||
// Detect 4-byte addressing mode and enable it if supported
|
||||
int _sfdp_detect_and_enable_4byte_addressing(uint8_t *basic_param_table_ptr, int basic_param_table_size);
|
||||
|
||||
#ifdef MX_FLASH_SUPPORT_RWW
|
||||
bool _is_mem_ready_rww(bd_addr_t addr, uint8_t rw);
|
||||
#endif
|
||||
|
||||
private:
|
||||
enum ospif_clear_protection_method_t {
|
||||
OSPIF_BP_ULBPR, // Issue global protection unlock instruction
|
||||
|
@ -449,6 +461,16 @@ private:
|
|||
|
||||
uint32_t _init_ref_count;
|
||||
bool _is_initialized;
|
||||
#ifdef MX_FLASH_SUPPORT_RWW
|
||||
enum wait_flag {
|
||||
NOT_STARTED, // no wait is started
|
||||
WRITE_WAIT_STARTED, // write wait is started
|
||||
ERASE_WAIT_STARTED, // erase wait is started
|
||||
};
|
||||
uint32_t _busy_bank; // Current busy bank
|
||||
wait_flag _wait_flag; // wait flag
|
||||
PlatformMutex _busy_mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,9 +20,6 @@
|
|||
#include "OSPIFBlockDevice.h"
|
||||
#include <string.h>
|
||||
#include "rtos/ThisThread.h"
|
||||
#if defined(TARGET_MX25LM51245G)
|
||||
#include "MX25LM51245G_config.h"
|
||||
#endif
|
||||
|
||||
#ifndef MBED_CONF_MBED_TRACE_ENABLE
|
||||
#define MBED_CONF_MBED_TRACE_ENABLE 0
|
||||
|
@ -51,9 +48,6 @@ using namespace mbed;
|
|||
#define OSPIF_STATUS_BIT_WEL 0x2 // Write Enable Latch
|
||||
#define OSPIF_NO_QUAD_ENABLE (-1)
|
||||
|
||||
// Configuration Register2 address
|
||||
#define OSPIF_CR2_OPI_EN_ADDR 0x00000000
|
||||
|
||||
/* SFDP Header Parsing */
|
||||
/***********************/
|
||||
#define OSPIF_RSFDP_DUMMY_CYCLES 8
|
||||
|
@ -168,6 +162,21 @@ using namespace mbed;
|
|||
// Length of data returned from RDID instruction
|
||||
#define OSPI_RDID_DATA_LENGTH 3
|
||||
|
||||
#ifdef NEED_DEFINE_SFDP_PARA
|
||||
static const uint8_t _sfdp_head_table[32] = {0x53, 0x46, 0x44, 0x50, 0x06, 0x01, 0x02, 0xFF, 0x00, 0x06, 0x01,
|
||||
0x10, 0x30, 0x00, 0x00, 0xFF, 0xC2, 0x00, 0x01, 0x04, 0x10, 0x01,
|
||||
0x00, 0xFF, 0x84, 0x00, 0x01, 0x02, 0xC0, 0x00, 0x00, 0xFF
|
||||
};
|
||||
static const uint8_t _sfdp_basic_param_table[64] = {0x30, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x14, 0xEC,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0x20,
|
||||
0x10, 0xDC, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x50, 0xF9, 0x80
|
||||
};
|
||||
static const uint8_t _sfdp_4_byte_inst_table[8] = {0x7F, 0xEF, 0xFF, 0xFF, 0x21, 0x5C, 0xDC, 0x14};
|
||||
#endif
|
||||
|
||||
/* Init function to initialize Different Devices CS static list */
|
||||
static PinName *generate_initialized_active_ospif_csel_arr();
|
||||
|
@ -232,6 +241,11 @@ OSPIFBlockDevice::OSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
|
|||
_attempt_4_byte_addressing = true;
|
||||
_4byte_msb_reg_write_inst = OSPIF_INST_4BYTE_REG_WRITE_DEFAULT;
|
||||
_support_4_byte_inst = false;
|
||||
|
||||
#ifdef MX_FLASH_SUPPORT_RWW
|
||||
_wait_flag = NOT_STARTED;
|
||||
_busy_bank = 0xffffffff;
|
||||
#endif
|
||||
}
|
||||
|
||||
int OSPIFBlockDevice::init()
|
||||
|
@ -358,6 +372,14 @@ int OSPIFBlockDevice::deinit()
|
|||
return result;
|
||||
}
|
||||
|
||||
if (false == _is_mem_ready()) {
|
||||
tr_error("Device not ready after write, failed");
|
||||
}
|
||||
|
||||
#ifdef MX_FLASH_SUPPORT_RWW
|
||||
_wait_flag = NOT_STARTED;
|
||||
#endif
|
||||
|
||||
change_mode(SPI);
|
||||
|
||||
// Disable Device for Writing
|
||||
|
@ -383,6 +405,29 @@ int OSPIFBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
|
|||
int status = OSPIF_BD_ERROR_OK;
|
||||
tr_debug("Read Inst: 0x%xh", _read_instruction);
|
||||
|
||||
#ifdef MX_FLASH_SUPPORT_RWW
|
||||
bool need_wait;
|
||||
need_wait = (_wait_flag != NOT_STARTED) && ((addr & MX_FLASH_BANK_SIZE_MASK) == _busy_bank);
|
||||
|
||||
// Wait for ready
|
||||
if (need_wait) {
|
||||
|
||||
_busy_mutex.lock();
|
||||
|
||||
if (_is_mem_ready_rww(addr, false) == false) {
|
||||
return OSPIF_BD_ERROR_OK;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (_wait_flag == WRITE_WAIT_STARTED) {
|
||||
tr_debug("\r\n RWW1 CNT");
|
||||
} else if (_wait_flag == ERASE_WAIT_STARTED) {
|
||||
tr_debug("\r\n RWE2 CNT");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
_mutex.lock();
|
||||
|
||||
// In DOPI mode, the number of read data should be even
|
||||
|
@ -397,8 +442,13 @@ int OSPIFBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
|
|||
|
||||
_mutex.unlock();
|
||||
|
||||
return status;
|
||||
#ifdef MX_FLASH_SUPPORT_RWW
|
||||
if (need_wait) {
|
||||
_busy_mutex.unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int OSPIFBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size)
|
||||
|
@ -418,6 +468,16 @@ int OSPIFBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size
|
|||
chunk = (offset + size < _page_size_bytes) ? size : (_page_size_bytes - offset);
|
||||
written_bytes = chunk;
|
||||
|
||||
#ifdef MX_FLASH_SUPPORT_RWW
|
||||
_busy_mutex.lock();
|
||||
|
||||
// Wait for ready
|
||||
if (_is_mem_ready_rww(addr, true) == false) {
|
||||
return OSPIF_BD_ERROR_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
_mutex.lock();
|
||||
|
||||
//Send WREN
|
||||
|
@ -437,10 +497,14 @@ int OSPIFBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size
|
|||
goto exit_point;
|
||||
}
|
||||
|
||||
buffer = static_cast<const uint8_t *>(buffer) + chunk;
|
||||
addr += chunk;
|
||||
size -= chunk;
|
||||
#ifdef MX_FLASH_SUPPORT_RWW
|
||||
_wait_flag = WRITE_WAIT_STARTED;
|
||||
_busy_bank = addr & MX_FLASH_BANK_SIZE_MASK;
|
||||
|
||||
_mutex.unlock();
|
||||
|
||||
_busy_mutex.unlock();
|
||||
#else
|
||||
if (false == _is_mem_ready()) {
|
||||
tr_error("Device not ready after write, failed");
|
||||
program_failed = true;
|
||||
|
@ -448,6 +512,10 @@ int OSPIFBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size
|
|||
goto exit_point;
|
||||
}
|
||||
_mutex.unlock();
|
||||
#endif
|
||||
buffer = static_cast<const uint8_t *>(buffer) + chunk;
|
||||
addr += chunk;
|
||||
size -= chunk;
|
||||
}
|
||||
|
||||
exit_point:
|
||||
|
@ -511,6 +579,15 @@ int OSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t size)
|
|||
tr_debug("Erase - Region: %d, Type:%d ",
|
||||
region, type);
|
||||
|
||||
#ifdef MX_FLASH_SUPPORT_RWW
|
||||
_busy_mutex.lock();
|
||||
|
||||
// Wait for ready
|
||||
if (_is_mem_ready_rww(addr, true) == false) {
|
||||
return OSPIF_BD_ERROR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
_mutex.lock();
|
||||
|
||||
if (_set_write_enable() != 0) {
|
||||
|
@ -527,15 +604,14 @@ int OSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t size)
|
|||
goto exit_point;
|
||||
}
|
||||
|
||||
addr += eu_size;
|
||||
size -= eu_size;
|
||||
#ifdef MX_FLASH_SUPPORT_RWW
|
||||
_wait_flag = ERASE_WAIT_STARTED;
|
||||
_busy_bank = addr & MX_FLASH_BANK_SIZE_MASK;
|
||||
|
||||
if ((size > 0) && (addr > _sfdp_info.smptbl.region_high_boundary[region])) {
|
||||
// erase crossed to next region
|
||||
region++;
|
||||
bitfield = _sfdp_info.smptbl.region_erase_types_bitfld[region];
|
||||
}
|
||||
_mutex.unlock();
|
||||
|
||||
_busy_mutex.unlock();
|
||||
#else
|
||||
if (false == _is_mem_ready()) {
|
||||
tr_error("OSPI After Erase Device not ready - failed");
|
||||
erase_failed = true;
|
||||
|
@ -544,6 +620,16 @@ int OSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t size)
|
|||
}
|
||||
|
||||
_mutex.unlock();
|
||||
#endif
|
||||
|
||||
addr += eu_size;
|
||||
size -= eu_size;
|
||||
|
||||
if ((size > 0) && (addr > _sfdp_info.smptbl.region_high_boundary[region])) {
|
||||
// erase crossed to next region
|
||||
region++;
|
||||
bitfield = _sfdp_info.smptbl.region_erase_types_bitfld[region];
|
||||
}
|
||||
}
|
||||
|
||||
exit_point:
|
||||
|
@ -1537,6 +1623,51 @@ bool OSPIFBlockDevice::_is_mem_ready()
|
|||
return mem_ready;
|
||||
}
|
||||
|
||||
#ifdef MX_FLASH_SUPPORT_RWW
|
||||
bool OSPIFBlockDevice::_is_mem_ready_rww(bd_addr_t addr, uint8_t rw)
|
||||
{
|
||||
uint16_t cr2_value = 0;
|
||||
bool mem_ready = true;
|
||||
static uint32_t rww_cnt = 0; // For testing
|
||||
static uint32_t rwe_cnt = 0; // For testing
|
||||
|
||||
bd_addr_t bank_addr = addr & MX_FLASH_BANK_SIZE_MASK;
|
||||
|
||||
if ((_wait_flag == NOT_STARTED) || (!rw && bank_addr != _busy_bank)) {
|
||||
return mem_ready;
|
||||
}
|
||||
//Read CR2 Register 1 from device, the number of read byte need to be even in octa flash DOPI mode
|
||||
if (OSPI_STATUS_OK != _ospi_send_general_command(OSPIF_INST_RDCR2, bank_addr + OSPIF_CR2_BANK_STATUS_ADDR,
|
||||
NULL, 0,
|
||||
(char *) &cr2_value, OSPI_DEFAULT_STATUS_REGISTERS)) { // store received value in cr2_value
|
||||
tr_error("Reading CR2 Register failed");
|
||||
}
|
||||
|
||||
cr2_value &= OSPIF_CR2_RWWBS;
|
||||
|
||||
if ((cr2_value == OSPIF_CR2_RWWBS) || (rw && (cr2_value == OSPIF_CR2_RWWDS))) {
|
||||
|
||||
// Wait until device ready
|
||||
if (false == _is_mem_ready()) {
|
||||
tr_error(" _is_mem_ready Failed");
|
||||
mem_ready = false;
|
||||
}
|
||||
_wait_flag = NOT_STARTED;
|
||||
} else if (!rw && (cr2_value == OSPIF_CR2_RWWDS)) {
|
||||
// For testing
|
||||
if (_wait_flag == WRITE_WAIT_STARTED) {
|
||||
rww_cnt++;
|
||||
tr_debug("rww_cnt = 0x%x ", rww_cnt);
|
||||
} else {
|
||||
rwe_cnt++;
|
||||
tr_debug("rwe_cnt = 0x%x ", rwe_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
return mem_ready;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************/
|
||||
/*********** OSPI Driver API Functions *************/
|
||||
/***************************************************/
|
||||
|
@ -1665,9 +1796,12 @@ ospi_status_t OSPIFBlockDevice::_ospi_send_general_command(ospi_inst_t instructi
|
|||
if ((_inst_width == OSPI_CFG_BUS_OCTA) || (_inst_width == OSPI_CFG_BUS_OCTA_DTR)) {
|
||||
if ((instruction == OSPIF_INST_RSR1) || (instruction == OSPIF_INST_RDID) ||
|
||||
(instruction == OSPIF_INST_RDCR2) || (instruction == OSPIF_INST_RDCR)) {
|
||||
_ospi.configure_format(_inst_width, _inst_size, _address_width, _address_size, OSPI_CFG_BUS_SINGLE, 0, _data_width, _dummy_cycles);
|
||||
addr = 0;
|
||||
} else if (instruction == OSPIF_INST_WSR1) {
|
||||
_ospi.configure_format(_inst_width, _inst_size, _address_width, _address_size, OSPI_CFG_BUS_SINGLE,
|
||||
0, _data_width, _dummy_cycles);
|
||||
if (instruction != OSPIF_INST_RDCR2) {
|
||||
addr = 0;
|
||||
}
|
||||
} else if ((instruction == OSPIF_INST_WSR1)) {
|
||||
addr = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -433,6 +433,89 @@ void test_multi_threads()
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(MX_FLASH_SUPPORT_RWW)
|
||||
void test_rww_rwe()
|
||||
{
|
||||
utest_printf("\nTest rww and rwe Starts..\n");
|
||||
|
||||
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "no block device found.");
|
||||
|
||||
utest_printf("\ntest read bank1 data when write bank0\n");
|
||||
|
||||
// Determine start_address in bank 0
|
||||
bd_addr_t start_address_B0 = sectors_addr[rand() % num_of_sectors];
|
||||
utest_printf("start_address_B0=0x%016" PRIx64 "\n", start_address_B0);
|
||||
|
||||
// Determine start_address in bank 1
|
||||
bd_addr_t start_address_B1 = start_address_B0 | 0x1000000;
|
||||
utest_printf("start_address_B1=0x%016" PRIx64 "\n", start_address_B1);
|
||||
|
||||
// Determine data_buf_size
|
||||
bd_size_t erase_size = block_device->get_erase_size(start_address_B0);
|
||||
TEST_ASSERT(erase_size > 0);
|
||||
bd_size_t data_buf_size = block_device->get_program_size();;
|
||||
|
||||
// Allocate buffer for write test data
|
||||
uint8_t *data_buf = new (std::nothrow) uint8_t[data_buf_size];
|
||||
TEST_SKIP_UNLESS_MESSAGE(data_buf != NULL, "Not enough memory for test");
|
||||
|
||||
// Allocate buffer for read test data
|
||||
uint8_t *out_data_buf = new (std::nothrow) uint8_t[data_buf_size];
|
||||
TEST_SKIP_UNLESS_MESSAGE(out_data_buf != NULL, "Not enough memory for test");
|
||||
|
||||
// First must Erase given memory region
|
||||
utest_printf("erasing given memory region in bank0\n");
|
||||
int err = block_device->erase(start_address_B0, erase_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
utest_printf("erasing given memory region in bank1\n");
|
||||
err = block_device->erase(start_address_B1, erase_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
// Write random data to selected region to make sure data is not accidentally set to "erased" value.
|
||||
// With this pre-write, the test case will fail even if block_device->erase() is broken.
|
||||
for (bd_size_t i = 0; i < data_buf_size; i++) {
|
||||
data_buf[i] = (uint8_t) rand();
|
||||
}
|
||||
|
||||
utest_printf("writing given memory region in bank1\n");
|
||||
err = block_device->program((const void *)data_buf, start_address_B1, data_buf_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
memset(out_data_buf, 0, data_buf_size);
|
||||
|
||||
utest_printf("writing given memory region in bank0\n");
|
||||
err = block_device->program((const void *)data_buf, start_address_B0, data_buf_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
// Read written memory region in bank1 to verify it contains information
|
||||
// utest_printf("reading written memory region in bank1 when write bank0\n");
|
||||
err = block_device->read((void *)out_data_buf, start_address_B1, data_buf_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
// Verify erased memory region
|
||||
utest_printf("verifying written memory region\n");
|
||||
for (bd_size_t i = 0; i < data_buf_size; i++) {
|
||||
TEST_ASSERT_EQUAL(out_data_buf[i], data_buf[i]);
|
||||
}
|
||||
|
||||
utest_printf("\ntest read bank1 data when erase bank0\n");
|
||||
|
||||
utest_printf("erasing given memory region in bank0\n");
|
||||
memset(out_data_buf, 0, data_buf_size);
|
||||
err = block_device->erase(start_address_B0, erase_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
// Read written memory region in bank1 to verify it contains information
|
||||
|
||||
utest_printf("reading written memory region in bank1 when erase bank0\n");
|
||||
err = block_device->read((void *)out_data_buf, start_address_B1, data_buf_size);
|
||||
TEST_ASSERT_EQUAL(0, err);
|
||||
|
||||
delete[] out_data_buf;
|
||||
delete[] data_buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
void test_erase_functionality()
|
||||
{
|
||||
utest_printf("\nTest BlockDevice::get_erase_value()..\n");
|
||||
|
@ -816,6 +899,9 @@ template_case_t template_cases[] = {
|
|||
{"Testing BlockDevice erase functionality", test_erase_functionality, greentea_failure_handler},
|
||||
{"Testing program read small data sizes", test_program_read_small_data_sizes, greentea_failure_handler},
|
||||
{"Testing unaligned erase blocks", test_unaligned_erase_blocks, greentea_failure_handler},
|
||||
#if defined(MX_FLASH_SUPPORT_RWW)
|
||||
{"Testing read while write and read while erase", test_rww_rwe, greentea_failure_handler},
|
||||
#endif
|
||||
{"Testing Deinit block device", test_deinit_bd, greentea_failure_handler},
|
||||
};
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
/* Max amount of flash size is 4Gbytes */
|
||||
/* hence 2^(31+1), then FLASH_SIZE_DEFAULT = 1<<31 */
|
||||
#define OSPI_FLASH_SIZE_DEFAULT 0x80000000
|
||||
#define OSPI_FLASH_SIZE_DEFAULT 0x4000000 //512Mbits
|
||||
|
||||
static uint32_t get_alt_bytes_size(const uint32_t num_bytes)
|
||||
{
|
||||
|
@ -252,7 +252,7 @@ static ospi_status_t _ospi_init_direct(ospi_t *obj, const ospi_pinmap_t *pinmap,
|
|||
obj->handle.Init.ClockPrescaler = 4; // default value, will be overwritten in ospi_frequency
|
||||
obj->handle.Init.FifoThreshold = 4;
|
||||
obj->handle.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
|
||||
obj->handle.Init.DeviceSize = POSITION_VAL(OSPI_FLASH_SIZE_DEFAULT) - 1;
|
||||
obj->handle.Init.DeviceSize = 32;
|
||||
obj->handle.Init.ChipSelectHighTime = 3;
|
||||
obj->handle.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
|
||||
#if defined(HAL_OSPI_WRAP_NOT_SUPPORTED) // removed in STM32L4
|
||||
|
|
Loading…
Reference in New Issue