From 33e034a429215af455a638c221ba7570615865e1 Mon Sep 17 00:00:00 2001 From: dario Date: Tue, 4 Jun 2024 18:40:48 +0200 Subject: [PATCH] Updated logging, binary search to find starting point. --- include/sta/drivers/w25qxx_defs.hpp | 1 + include/sta/utils/logger.hpp | 15 ++++--- include/sta/utils/logger.tpp | 61 ++++++++++++++++++++--------- src/w25qxx.cpp | 3 ++ 4 files changed, 56 insertions(+), 24 deletions(-) diff --git a/include/sta/drivers/w25qxx_defs.hpp b/include/sta/drivers/w25qxx_defs.hpp index 64fc3b5..8f0b86a 100644 --- a/include/sta/drivers/w25qxx_defs.hpp +++ b/include/sta/drivers/w25qxx_defs.hpp @@ -61,6 +61,7 @@ #define W25QXX_PAGE_SIZE 0x100 #define W25QXX_SECTOR_SIZE 0x1000 +#define W25QXX_PAGE_PER_SECTOR 0x10 #define W25QXX_BLOCK_32_KB_SIZE 0x8000 #define W25QXX_BLOCK_64_KB_SIZE 0xF000 diff --git a/include/sta/utils/logger.hpp b/include/sta/utils/logger.hpp index 9f1be34..4288a80 100644 --- a/include/sta/utils/logger.hpp +++ b/include/sta/utils/logger.hpp @@ -20,14 +20,15 @@ namespace sta * @param endSector The index of the end sector (1 LSB = 4096 bytes). */ Logger(W25Qxx * flash, uint32_t startSector, uint32_t endSector); - + /** * @brief Write a new data point to the flash chip. * @note If the total capacity of this logger was exceeded, it restarts at the first sector, overwriting its data. * - * @param data The data to write to the flash chip. + * @param data The data to write to the flash chip. + * @return true if successful, false if the segment end was reached. */ - void write(T data); + bool write(T data); /** * @brief Clear the flash memory used by the logger. @@ -40,7 +41,7 @@ namespace sta * * @return size_t The number of data points. */ - size_t occupied(); + size_t count(); /** * @brief Get the number of data points that can be written to the logger before an overflow occurs. @@ -54,16 +55,18 @@ namespace sta * * @return size_t The number of data points. */ - size_t length(); + size_t capacity(); /** * @brief Allows reading a single data point from the segment. * * @param idx The index of the segement. - * @return const T& The read data value. + * @return T The read data value. */ T operator[](std::size_t idx); private: + void findLast(); + W25Qxx * flash_; uint32_t start_; uint32_t end_; diff --git a/include/sta/utils/logger.tpp b/include/sta/utils/logger.tpp index 6816ff9..c0885b1 100644 --- a/include/sta/utils/logger.tpp +++ b/include/sta/utils/logger.tpp @@ -17,26 +17,52 @@ namespace sta { STA_ASSERT(flash != nullptr); STA_ASSERT(endAddr > startAddr); + + // Jump to the last written page. + findLast(); } template - void Logger::write(T data) + void Logger::findLast() { - uint8_t * bytes = (uint8_t*)(&data); + address_ = this->flash_->findLast([](uint8_t * buffer) -> bool { + for (size_t i = 0; i < W25QXX_PAGE_SIZE; i++) + { + if (buffer[i] != 0xFF) + { + return true; + } + } + + return false; + }, sta::ChunkSize::PAGE, start_ * W25QXX_SECTOR_SIZE, end_ * W25QXX_SECTOR_SIZE); + + STA_DEBUG_PRINTF("Starting at page with address %d\n", address_); + } + + template + bool Logger::write(T data) + { + // If writing the data would exceed the segment length, return false and don't do anything. + if ((address_ + ptr_ + sizeof(T)) / W25QXX_SECTOR_SIZE == end_) + return false; + + // Convert the data to a byte array. + uint8_t * bytes = reinterpret_cast(&data); uint8_t length = sizeof(T); // Bytes remaining until the page is full. uint8_t remaining = W25QXX_PAGE_SIZE - ptr_; - STA_DEBUG_PRINTF("Writing at address %d\n", address_+ptr_); + STA_DEBUG_PRINTF("Writing at address %d\n", address_ + ptr_); // If the written data exceeds the remaining bytes in the page. if (ptr_ + length >= W25QXX_PAGE_SIZE) { - // If the segment is full, stop writing data to it. - if (address_ / W25QXX_SECTOR_SIZE == end_) + // If the page to written is in a new sector, erase the new sector before writing to it. + if (address_ % W25QXX_SECTOR_SIZE == 0) { - return; + flash_->sectorErase(address_); } std::memcpy(buffer_ + ptr_, bytes, remaining); @@ -45,19 +71,17 @@ namespace sta bytes += remaining; length -= remaining; ptr_ = 0; - STA_DEBUG_PRINTLN("New PAGE!"); - address_ += W25QXX_PAGE_SIZE; - - // If a new sector has to be started, erase the new sector. - if (address_ % W25QXX_SECTOR_SIZE == 0) - { - flash_->sectorErase(address_); - } } std::memcpy(buffer_ + ptr_, bytes, length); ptr_ += length; + + // If the end of the segment was reached, flush the temporally stored data. + if ((address_ + ptr_ + sizeof(T)) / W25QXX_SECTOR_SIZE == end_) + flash_->pageProgram(address_, buffer_, W25QXX_PAGE_SIZE); + + return true; } template @@ -73,19 +97,19 @@ namespace sta } template - size_t Logger::occupied() + size_t Logger::count() { - return (address_ - start_ * W25QXX_SECTOR_SIZE) / sizeof(T); + return ((address_ + ptr_) - start_ * W25QXX_SECTOR_SIZE) / sizeof(T); } template size_t Logger::remaining() { - return (end_ * W25QXX_SECTOR_SIZE - address_) / sizeof(T); + return (end_ * W25QXX_SECTOR_SIZE - (address_ + ptr_)) / sizeof(T); } template - size_t Logger::length() + size_t Logger::capacity() { return (end_ - start_) * W25QXX_SECTOR_SIZE / sizeof(T); } @@ -94,6 +118,7 @@ namespace sta T Logger::operator[](std::size_t idx) { uint32_t address = start_ * W25QXX_SECTOR_SIZE + idx * sizeof(T); + STA_DEBUG_PRINTF("Reading from address %d\n", address); // If the requested element is in the cache, read it from there. if (address / W25QXX_PAGE_SIZE == address_ / W25QXX_PAGE_SIZE) diff --git a/src/w25qxx.cpp b/src/w25qxx.cpp index 1518bae..15031d4 100644 --- a/src/w25qxx.cpp +++ b/src/w25qxx.cpp @@ -88,6 +88,7 @@ namespace sta while (left < right) { middle = (left + right) / 2; + STA_DEBUG_PRINTF("left=%d, middle=%d, right=%d", left, middle, right); readData(middle * bytes, buffer, bytes); if (criterion(buffer)) @@ -101,11 +102,13 @@ namespace sta } middle = (left + right) / 2; + STA_DEBUG_PRINTLN(middle); readData(middle * bytes, buffer, bytes); if (criterion(buffer)) { middle += 1; + STA_DEBUG_PRINTLN("PLUS ONE"); } delete[] buffer;