diff --git a/src/shared/drivers/qspi-flash/qspi-flash.cpp b/src/shared/drivers/qspi-flash/qspi-flash.cpp
index 1b23868e8721d4103f6f02a92937b003f096e93d..2f07a30ac76362f7e90010183fb950c898bac262 100644
--- a/src/shared/drivers/qspi-flash/qspi-flash.cpp
+++ b/src/shared/drivers/qspi-flash/qspi-flash.cpp
@@ -561,7 +561,7 @@ bool qspi_flash::sector_erase(uint32_t address)
{
Thread::sleep(1);
dt = dt + 1;
- if (dt >= 260) // max sector erase cycle time = 240 ms
+ if (dt >= 1000) // max sector erase cycle time = 240 ms
{
software_reset(); // device forced reset to default status
return false;
@@ -926,12 +926,12 @@ bool qspi_flash::check_program()
return reg & (1 << 5) ? false : true;
}
-bool qspi_flash::read_sector(std::vector<uint8_t>& vector, uint32_t sector_num)
+bool qspi_flash::read_sector(uint8_t* vector, const size_t size,
+ uint32_t sector_num)
{
- // read an entire sector of the flash and then copy it into a std::vector
- // that will modify the vector and his elements.
- // that fix size and capacity of the vector to SECTOR_SIZE.
+ // read an entire sector of the flash and then copy it into a vector whose
+ // size is equal or greater than the size of a sector.
// check if memory has been initialised
if (initialised == false)
@@ -945,19 +945,10 @@ bool qspi_flash::read_sector(std::vector<uint8_t>& vector, uint32_t sector_num)
return false;
}
- // reserve enough bytes to retain a sector of the flash, also
- // make sure that size parameter of vector match with the capacity.
- if (vector.capacity() < SECTOR_SIZE)
+ // vector's size must be large enough for a sector
+ if (size < SECTOR_SIZE)
{
- vector.reserve(SECTOR_SIZE);
- vector.resize(vector.capacity());
- }
-
- // if vector capacity is larger than the size of a sector
- if (vector.capacity() >= SECTOR_SIZE)
- {
- vector.resize(SECTOR_SIZE);
- vector.shrink_to_fit();
+ return false;
}
// computing correct address of the sector
@@ -965,7 +956,7 @@ bool qspi_flash::read_sector(std::vector<uint8_t>& vector, uint32_t sector_num)
// read the sector and copy its data to vector
uint32_t index = 0;
- for (index = 0; index < vector.capacity(); index++)
+ for (index = 0; index < SECTOR_SIZE; index++)
{
vector[index] = read_byte(addr);
addr++;
@@ -974,13 +965,14 @@ bool qspi_flash::read_sector(std::vector<uint8_t>& vector, uint32_t sector_num)
return true;
}
-bool qspi_flash::page_program(std::vector<uint8_t>& vector,
+bool qspi_flash::page_program(const uint8_t* vector, const size_t size,
uint32_t start_address, bool verify)
{
- // program a vector (max size = 256 bytes) starting by a specific page
- // address. WEL bit is set to zero automatically after the program
- // operation. the address specified must be a starting
+ // program a vector (max size = 256 bytes) on flash memory starting by a
+ // specific page address.
+ // WEL bit is set to zero automatically after the program
+ // operation. The address specified must be a starting
// address of a page !!!!
// check if memory has been initialised
@@ -997,12 +989,12 @@ bool qspi_flash::page_program(std::vector<uint8_t>& vector,
if (start_address >= MEMORY_SIZE)
return false;
- // empty vector
- if (vector.size() == 0)
+ // empty vector or null pointer
+ if (size == 0 || vector == nullptr)
return false;
// vector bigger than a page size
- if (vector.size() > PAGE_SIZE)
+ if (size > PAGE_SIZE)
return false;
// enable data writing
@@ -1024,14 +1016,14 @@ bool qspi_flash::page_program(std::vector<uint8_t>& vector,
QUADSPI->CCR |= Commands::PAGE_PROGRAM;
// set number of bytes to be transferred - 1
- QUADSPI->DLR = vector.size() - 1;
+ QUADSPI->DLR = size - 1;
// adding starting address
QUADSPI->AR = start_address;
// load data vector into the QUADSPI FIFO (buffer)
uint16_t i = 0;
- for (i = 0; i < vector.size(); i++)
+ for (i = 0; i < size; i++)
{
// if FIFO is full - wait till it has at least a byte available.
@@ -1058,7 +1050,7 @@ bool qspi_flash::page_program(std::vector<uint8_t>& vector,
{
Thread::sleep(1);
dt = dt + 1;
- if (dt >= 20) // max page program cycle time = 10ms
+ if (dt >= 50) // max page program cycle time = 10ms
{
software_reset(); // device forced reset to default status
return false;
@@ -1068,9 +1060,8 @@ bool qspi_flash::page_program(std::vector<uint8_t>& vector,
// if verify flag is set, double check on written data
if (verify == true)
{
- for (i = 0; i < vector.size(); i++)
+ for (i = 0; i < size; i++)
{
-
if (read_byte(start_address + i) != vector[i])
return false;
}
@@ -1080,12 +1071,10 @@ bool qspi_flash::page_program(std::vector<uint8_t>& vector,
return check_program();
}
-bool qspi_flash::write_vector(std::vector<uint8_t>& vector, uint32_t sector_num,
- bool verify_write)
+bool qspi_flash::write_vector(const uint8_t* vector, const size_t size,
+ uint32_t sector_num, bool verify_write)
{
- // store a vector of bytes into the flash memory
-
// check if memory has been initialised
if (initialised == false)
{
@@ -1093,83 +1082,91 @@ bool qspi_flash::write_vector(std::vector<uint8_t>& vector, uint32_t sector_num,
}
// wrong sector_num specified
- if (sector_num < 0 || sector_num >= SECTORS_NUM)
+ if (sector_num >= SECTORS_NUM)
{
return false;
}
- // if the vector doesn't have elements
- if (vector.size() == 0 || vector.capacity() == 0)
+ // check that vector is valid and not empty
+ if ((vector == nullptr) || size == 0)
{
return false;
}
// if the vector is bigger than the flash capacity
- if (vector.size() > MEMORY_SIZE)
+ if (size > MEMORY_SIZE)
+ {
return false;
+ }
// if the whole vector is bigger than the rest of sectors starting by
// sector_num
- if (vector.size() > (SECTOR_SIZE * (SECTORS_NUM - sector_num)))
+ if (size > (SECTOR_SIZE * (SECTORS_NUM - sector_num)))
+ {
return false;
+ }
// compute starting address
uint32_t const start_address = SECTOR_SIZE * sector_num;
// compute number of sectors needed to store the vector, then add one more
// to store the last part of vector
- uint32_t sectors_needed = vector.size() / SECTOR_SIZE;
- if ((vector.size() % SECTOR_SIZE) != 0)
+ uint32_t sectors_needed = size / SECTOR_SIZE;
+ if ((size % SECTOR_SIZE) != 0)
+ {
sectors_needed += 1;
+ }
// erase all sectors needed to store the entire vector
uint32_t sector_index = 0;
for (sector_index = 0; sector_index < sectors_needed; sector_index++)
{
if (sector_erase(SECTOR_SIZE * (sector_num + sector_index)) == false)
+ {
return false;
+ }
}
// compute the number of pages needed to store the entire vector, then add
- // one more to store the vector last part.
- uint32_t pages_needed = vector.size() / PAGE_SIZE;
- if ((vector.size() % PAGE_SIZE) != 0)
+ // one more to store the vector last part
+ uint32_t pages_needed = size / PAGE_SIZE;
+ if ((size % PAGE_SIZE) != 0)
+ {
pages_needed += 1;
+ }
- // create a copy vector with capacity as a page size
- std::vector<uint8_t> v;
- v.reserve(PAGE_SIZE);
- v.resize(0);
-
- // for every page needed, first copy data bytes from "vector" to a copy
- // vector "v" and then program the page.
+ // split vector in pages and then program them on flash but the last one
uint32_t page = 0;
- uint32_t elem = 0;
- for (page = 0; page < pages_needed; page++)
+ for (page = 0; page < pages_needed - 1; page++)
{
- v.resize(0);
- uint32_t start_elem = page * PAGE_SIZE;
- // copying 256 bytes from "vector" to "v"
- for (elem = start_elem;
- (elem < start_elem + PAGE_SIZE) && (elem < vector.size()); elem++)
- {
- v.push_back(vector[elem]);
- }
-
- // program the page stored into "v" on flash
- if (page_program(v, start_address + (page * PAGE_SIZE), false) == false)
+ if (page_program(vector + (page * PAGE_SIZE), PAGE_SIZE,
+ start_address + (page * PAGE_SIZE), false) == false)
return false;
}
+ // program the last page, cause probably it has a different size
+ // than others.
+ /*
+ * a little explanation of parameters:
+ * 1 - make the pointer point to the start byte of last page.
+ * 2 - is the size of last page which store the vector final part.
+ * 3 - calculate the start address of last page.
+ */
+ if (page_program(
+ vector + ((pages_needed - 1) * PAGE_SIZE), size % PAGE_SIZE,
+ start_address + ((pages_needed - 1) * PAGE_SIZE), false) == false)
+ {
+ return false;
+ }
+
// if verify_write is true:
// check that the bytes written into the flash match with the ones in the
// vector.
if (verify_write)
{
-
uint32_t index = 0;
uint32_t addr = start_address;
- for (index = 0; index < vector.size(); index++)
+ for (index = 0; index < size; index++)
{
if (read_byte(addr) != vector[index])
{
diff --git a/src/shared/drivers/qspi-flash/qspi-flash.h b/src/shared/drivers/qspi-flash/qspi-flash.h
index cc8afb94de21776d3a3a413029cd370679d1af0a..896e2eeae7d8f63189ce08af70823956e4517e30 100644
--- a/src/shared/drivers/qspi-flash/qspi-flash.h
+++ b/src/shared/drivers/qspi-flash/qspi-flash.h
@@ -138,7 +138,7 @@ public:
* will be memorized on consecutive sectors of the memory, starting by
* sector_num
*
- * @param vector std::vector to be saved in memory
+ * @param vector array to be saved in memory
* @param sector_num number of the starting sector [0 - 1024]
* @param verify_write double check on saved data flag,
* true = double check enabled,
@@ -151,37 +151,40 @@ public:
*
* @return true/false - if the whole operation has been successful.
*/
- bool write_vector(std::vector<uint8_t>& vector, uint32_t sector_num,
- bool verify_write);
+ bool write_vector(const uint8_t* vector, const size_t size,
+ uint32_t sector_num, bool verify_write);
/**
- * @brief copy a whole sector (4KB) from the flash to an std::vector.
- * @param vector reference of the vector which will store the sector.
+ * @brief copy a whole sector (4KB) from flash into a vector whose size is
+ * greater or equal to the size of a sector in memory.
+ * @param vector array which will store the sector.
* @param sector_num number of the sector which has to be copied into the
* vector [0 - 1024]
* @return true/false - if the operation has been successful.
- * @warning this function modify the vector passed! it will also fix its
- * size and capacity to the size of an entire sector of the flash (4096
- * bytes).
+ * @warning the vector size must be enough to contain a whole sector!
+ * @warning This function modify the vector passed!
*/
- bool read_sector(std::vector<uint8_t>& vector, uint32_t sector_num);
+ bool read_sector(uint8_t* vector, const size_t size, uint32_t sector_num);
/**
- * @brief program a page by setting (256 byte) at the starting address
- * specified.
+ * @brief program a page (256 bytes) on memory at the starting address
+ * specified. if vector size is smaller than a whole page size there will be
+ * no effects on other bytes of the page.
* @param vector vector of data bytes to be programmed - its size must not
* be bigger than a page size (256 byte).
* @param start_address starting address of the page to be programmed. must
- * be a starting address.
+ * be a starting address!
* @param verify double check on programmed data. true = enabled, false =
* disabled.
* @return true/false - if the operation has been successful.
* @warning start_address must be a starting address of a page!
- * if vector size is smaller than a page size there will be no effects on
- * other bytes of the page.
+ * This function is only intended to program some bytes on flash by
+ * resetting some bits to "0". If you want to store a page of data you'll
+ * need to erase the sector associated with this page and then reprogram the
+ * page.
*/
- bool page_program(std::vector<uint8_t>& vector, uint32_t start_address,
- bool verify);
+ bool page_program(const uint8_t* vector, const size_t size,
+ uint32_t start_address, bool verify);
/**
* @brief erase the entire memory chip. since this operation is not so
@@ -229,6 +232,9 @@ public:
* @param verify double check on programmed byte. true = enabled, false =
* disabled.
* @return true/false - if the operation has been successful
+ * @warning This function is only intended to program some bytes on flash by
+ * resetting some bits to "0". If you want to store a byte of data, you'll
+ * need to perform an erase operation and then program the byte.
*/
bool byte_program(uint8_t data, uint32_t address, bool verify);
diff --git a/src/tests/drivers/QuadSpi-Flash/test-Qflash.cpp b/src/tests/drivers/QuadSpi-Flash/test-Qflash.cpp
index 3f60f1e674d567d822445bb67ff64a6ae9410e45..7585b5cb09f152ed0639653ad15e7e5f0db0dfb0 100644
--- a/src/tests/drivers/QuadSpi-Flash/test-Qflash.cpp
+++ b/src/tests/drivers/QuadSpi-Flash/test-Qflash.cpp
@@ -31,11 +31,11 @@ qspi_flash mymemory;
int main()
{
- // aggiunti software_reset con timeout: disaccoppiano le operazioni, anche
- // senza delay - permettendo alle operazioni di erase che falliscono di non
- // far fallire le altre operazioni successive. chip_erase se fallisce dopo
- // circa 10 sec fa fallire alcune operazioni come write_vector() e
- // page_program.
+
+ // change API from std::vector to normal arrays with no dynamic allocation.
+ // sector_erase() timeout values increased due to some problems
+ // with write_vector().
+ // read_sector and write_vector tested !
// init qspi-flash communication
mymemory.init();
@@ -47,50 +47,33 @@ int main()
// read device id
printf("\nID: %x\n", mymemory.readID());
- // create a vector of ten bytes to write on memory
- std::vector<uint8_t> v;
- v.reserve(10);
- for (uint32_t i = 0; i < v.capacity(); i++)
- v.push_back(99);
- v.resize(v.capacity()); // make sure that size match with capacity
+ // create a vector
+ const size_t vect_size = 5000;
+ uint8_t vect[vect_size] = {0};
+ uint32_t i = 0;
+ for (i = 0; i < vect_size; i++)
+ {
+ vect[i] = 77;
+ }
- // write vector "v" at 50th sector and double check on data
- if (mymemory.write_vector(v, 88, true) == false)
+ // write vector "vect"
+ if (mymemory.write_vector(vect, vect_size, 883, true) == false)
{
printf("ERROR - write operation failed !\n");
return -1;
}
- // create a vector in which will be copied the bytes of 50th sector
- std::vector<uint8_t> v2;
+ printf("write operaton succeded!\n");
- // read 50th entire sector into the vector "v2"
- if (mymemory.read_sector(v2, 88) == false)
- {
- printf("ERROR - read operation failed ! \n");
- return -1;
- }
+ uint8_t b[6000] = {0};
+ printf("read_sector: %d\n", mymemory.read_sector(b, 6000, 884));
- // print first ten bytes of data in the vector "v2"
- printf("\nvector v2: \n");
- uint32_t a = 0;
- for (a = 0; a < 10 && a < v2.size(); a++)
+ printf("array (b): \n");
+ for (i = 0; i < 6000; i++)
{
- printf("v2[%d]: %d \n", a, v2[a]);
- if (v2[a] != 99)
- {
- printf("ERROR - data mismatch !\n");
- return -1;
- }
+ printf("b[%d]: %d\n", i, b[i]);
}
- printf("v2 size: %d\n", v2.size());
- printf("v2 capacity: %d\n", v2.capacity());
- printf("\n- flash memory is working properly !\n");
+
return 0;
}
- else
- {
- printf("Error - flash memory is not working properly!\n");
- return -1;
- }
}
\ No newline at end of file