From bda2c69cd442ddaec7500e01a275db5cad78677a Mon Sep 17 00:00:00 2001 From: Pascal Flores Date: Wed, 10 Apr 2024 08:31:41 +0000 Subject: [PATCH 1/5] added openlog .h --- inc/drivers/OpenLog/openlog.h | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 inc/drivers/OpenLog/openlog.h diff --git a/inc/drivers/OpenLog/openlog.h b/inc/drivers/OpenLog/openlog.h new file mode 100644 index 000000000..dc832d22b --- /dev/null +++ b/inc/drivers/OpenLog/openlog.h @@ -0,0 +1,42 @@ +#pragma once + +#include "STM32Pin.h" +#include "STM32Serial.h" + +namespace codal { + +/** + * @brief the class representing the OpenLog micro-sd card reader + */ +class OpenLog { + public: + /** + * @brief Constructor of the OpenLog class + * + * @param tx the pin used to transmit data via serial to the OpenLog + * @param rx the pin used to receive data via serial to the OpenLog + * @param reset the pin used to reset the OpenLog (via OpenLog's GRN pin) + * + * @note As serial is used to communicate with the OpenLog, serial-compatible pins must be provided + */ + OpenLog(STM32Pin& tx, STM32Pin& rx, STM32Pin& reset); + ~OpenLog(); + + /** + * @brief Writes data to the micro-sd card, in a file which name's defined in the .cpp. + * + * @param data the text to write to the micro-sd card + * @param dataSize the size of the text to write + * + * @return Wether the write operation was successful or not + * + * @note As the OpenLog is implemented in order to allow offline sensor data logging, + * being able to set a file name has not been implemented (as not needed at the moment) + */ + bool write(char* data, unsigned dataSize); + + private: + STM32Serial* serial; + STM32Pin& resetPin; +}; +} // namespace codal \ No newline at end of file From 7b82ec21f4c111d809073ceb013a380baa354b8c Mon Sep 17 00:00:00 2001 From: Pascal Flores Date: Wed, 10 Apr 2024 08:32:42 +0000 Subject: [PATCH 2/5] added private utilitary functions --- inc/drivers/OpenLog/openlog.h | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/inc/drivers/OpenLog/openlog.h b/inc/drivers/OpenLog/openlog.h index dc832d22b..fe3ef927d 100644 --- a/inc/drivers/OpenLog/openlog.h +++ b/inc/drivers/OpenLog/openlog.h @@ -38,5 +38,41 @@ class OpenLog { private: STM32Serial* serial; STM32Pin& resetPin; + uint8_t* buffer; + + /** + * @brief an utility function to send the data via serial in fixed sized buffers + * + * @param data the data to send + * @param dataSize the size of the data to send + * + * @return an int representing the number of transmited bytes (should be equal to dataSize), or an error code + * (DEVICE_INVALID_PARAMETER or DEVICE_SERIAL_IN_USE) + */ + int sendData(const uint8_t* data, unsigned dataSize); + + /** + * @brief Sets the command mode on the OpenLog, enabling file operations on the micro-sd card + * @note Can also be used to end some of the openlog commands (e.g the append command) + */ + void goToCommandMode(); + + /** + * @brief hard resets the OpenLog via `resetPin` + * + * @note this function is used to restart the OpenLog after this class' serial is initialized, in order to ensure + * later that the OpenLog is responding well to the send commands / text + */ + void reset(); + + /** + * @brief listens to the OpenLog's serial output until the character `waitchar` + * + * @param waitChar the char to wait for (must be `>` or `<`) + * @note this function is used to wait until the Openlog is ready to accept commands / text + * @see + * https://github.com/sparkfun/OpenLog/blob/master/firmware/Arduino_Examples/Example3_ReadFile/Example3_ReadFile.ino + */ + void waitUntilReady(char waitChar); }; } // namespace codal \ No newline at end of file From 460ff3aaf34ffd6e49667fcf854d85c39e59e67a Mon Sep 17 00:00:00 2001 From: Pascal Flores Date: Wed, 10 Apr 2024 08:33:01 +0000 Subject: [PATCH 3/5] implemented .h functions --- source/drivers/OpenLog/openlog.cpp | 89 ++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 source/drivers/OpenLog/openlog.cpp diff --git a/source/drivers/OpenLog/openlog.cpp b/source/drivers/OpenLog/openlog.cpp new file mode 100644 index 000000000..ce3cd3bfb --- /dev/null +++ b/source/drivers/OpenLog/openlog.cpp @@ -0,0 +1,89 @@ +#include "openlog.h" + +#include + +using namespace codal; + +constexpr const unsigned BUFFER_SIZE = 100; +constexpr const unsigned OPENLOG_BAUDRATE = 9600; +constexpr const char* APPEND = "append"; +constexpr const char* FILE_NAME = "out.csv"; +constexpr const uint8_t ESCAPE_SEQUENCE[] = {26, 26, 26}; +constexpr const char READY_TO_RECEIVE_ANY = '<'; +constexpr const char READY_TO_RECEIVE_COMMANDS = '>'; + +OpenLog::OpenLog(STM32Pin& tx, STM32Pin& rx, STM32Pin& reset) : resetPin(reset) +{ + this->buffer = (uint8_t*)malloc(BUFFER_SIZE); + this->serial = new STM32Serial(tx, rx); + this->serial->init(OPENLOG_BAUDRATE); + this->reset(); + this->waitUntilReady(READY_TO_RECEIVE_ANY); + this->goToCommandMode(); +} + +OpenLog::~OpenLog() +{ + free(this->buffer); +} + +bool OpenLog::write(char* data, unsigned dataSize) +{ + int sendResult; + const unsigned commandLength = strlen(APPEND) + 1 + strlen(FILE_NAME) + 1; + strcat(strcat(strcat(strcpy((char*)this->buffer, APPEND), " "), FILE_NAME), "\r"); + + sendResult = this->sendData(this->buffer, commandLength); + if (sendResult == DEVICE_INVALID_PARAMETER || sendResult == DEVICE_SERIAL_IN_USE) return false; + + this->waitUntilReady(READY_TO_RECEIVE_ANY); + sendResult = this->sendData((uint8_t*)data, dataSize - 1); // -1 because we're not sending the trailing \0 + if (sendResult == DEVICE_INVALID_PARAMETER || sendResult == DEVICE_SERIAL_IN_USE) return false; + + this->goToCommandMode(); + + return true; +} + +int OpenLog::sendData(const uint8_t* data, unsigned dataSize) +{ + const unsigned maxSendSize = CODAL_SERIAL_DEFAULT_BUFFER_SIZE; + const unsigned sendNumbers = dataSize / maxSendSize + !(dataSize % maxSendSize == 0); + unsigned transmittedBytes = 0; + int sendResult; + + for (unsigned i = 0; i < sendNumbers; ++i) { + unsigned currentSendSize = (i < dataSize / maxSendSize) ? maxSendSize : dataSize % maxSendSize; + buffer = (uint8_t*)memcpy(this->buffer, data + (i * maxSendSize), currentSendSize); + sendResult = this->serial->send(this->buffer, currentSendSize); + + if (sendResult != DEVICE_INVALID_PARAMETER && sendResult != DEVICE_SERIAL_IN_USE) + transmittedBytes += sendResult; + else { + return sendResult; + } + } + return transmittedBytes; +} + +void OpenLog::goToCommandMode() +{ + this->sendData(ESCAPE_SEQUENCE, 3); + this->waitUntilReady(READY_TO_RECEIVE_COMMANDS); +} + +void OpenLog::reset() +{ + this->resetPin.setDigitalValue(0); + fiber_sleep(100); + this->resetPin.setDigitalValue(1); +} + +void OpenLog::waitUntilReady(char waitChar) +{ + if (!(waitChar == '>' || waitChar == '<')) return; + do { + fiber_sleep(10); + unsigned i = this->serial->read(this->buffer, BUFFER_SIZE, ASYNC); + } while (strchr((char*)this->buffer, waitChar) == NULL); +} \ No newline at end of file From 0f0ada4e266eff2ba799e3cb52127c3d0defb60f Mon Sep 17 00:00:00 2001 From: Pascal Flores Date: Wed, 10 Apr 2024 08:39:43 +0000 Subject: [PATCH 4/5] removed unused variable declaration --- source/drivers/OpenLog/openlog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/drivers/OpenLog/openlog.cpp b/source/drivers/OpenLog/openlog.cpp index ce3cd3bfb..ce065efc5 100644 --- a/source/drivers/OpenLog/openlog.cpp +++ b/source/drivers/OpenLog/openlog.cpp @@ -84,6 +84,6 @@ void OpenLog::waitUntilReady(char waitChar) if (!(waitChar == '>' || waitChar == '<')) return; do { fiber_sleep(10); - unsigned i = this->serial->read(this->buffer, BUFFER_SIZE, ASYNC); + this->serial->read(this->buffer, BUFFER_SIZE, ASYNC); } while (strchr((char*)this->buffer, waitChar) == NULL); } \ No newline at end of file From 7ed476571059136ae090781114fe360c64d0497e Mon Sep 17 00:00:00 2001 From: Pascal Flores Date: Thu, 11 Apr 2024 12:35:12 +0000 Subject: [PATCH 5/5] made some parameters const as they were not being modiifed --- inc/drivers/OpenLog/openlog.h | 4 ++-- source/drivers/OpenLog/openlog.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/inc/drivers/OpenLog/openlog.h b/inc/drivers/OpenLog/openlog.h index fe3ef927d..6a873cab0 100644 --- a/inc/drivers/OpenLog/openlog.h +++ b/inc/drivers/OpenLog/openlog.h @@ -33,7 +33,7 @@ class OpenLog { * @note As the OpenLog is implemented in order to allow offline sensor data logging, * being able to set a file name has not been implemented (as not needed at the moment) */ - bool write(char* data, unsigned dataSize); + bool write(const char* data, unsigned dataSize); private: STM32Serial* serial; @@ -73,6 +73,6 @@ class OpenLog { * @see * https://github.com/sparkfun/OpenLog/blob/master/firmware/Arduino_Examples/Example3_ReadFile/Example3_ReadFile.ino */ - void waitUntilReady(char waitChar); + void waitUntilReady(const char waitChar); }; } // namespace codal \ No newline at end of file diff --git a/source/drivers/OpenLog/openlog.cpp b/source/drivers/OpenLog/openlog.cpp index ce065efc5..c9c018d42 100644 --- a/source/drivers/OpenLog/openlog.cpp +++ b/source/drivers/OpenLog/openlog.cpp @@ -27,7 +27,7 @@ OpenLog::~OpenLog() free(this->buffer); } -bool OpenLog::write(char* data, unsigned dataSize) +bool OpenLog::write(const char* data, unsigned dataSize) { int sendResult; const unsigned commandLength = strlen(APPEND) + 1 + strlen(FILE_NAME) + 1; @@ -79,7 +79,7 @@ void OpenLog::reset() this->resetPin.setDigitalValue(1); } -void OpenLog::waitUntilReady(char waitChar) +void OpenLog::waitUntilReady(const char waitChar) { if (!(waitChar == '>' || waitChar == '<')) return; do {