diff --git a/Examples/Firebase/.gitignore b/Example/.gitignore similarity index 100% rename from Examples/Firebase/.gitignore rename to Example/.gitignore diff --git a/Examples/Firebase/.vscode/extensions.json b/Example/.vscode/extensions.json similarity index 100% rename from Examples/Firebase/.vscode/extensions.json rename to Example/.vscode/extensions.json diff --git a/Examples/Firebase/.vscode/settings.json b/Example/.vscode/settings.json similarity index 100% rename from Examples/Firebase/.vscode/settings.json rename to Example/.vscode/settings.json diff --git a/Examples/Firebase/include/README b/Example/include/README similarity index 100% rename from Examples/Firebase/include/README rename to Example/include/README diff --git a/Example/lib/MSP430/MSP430.cpp b/Example/lib/MSP430/MSP430.cpp new file mode 100644 index 0000000..80a9b68 --- /dev/null +++ b/Example/lib/MSP430/MSP430.cpp @@ -0,0 +1,418 @@ +#include "MSP430.h" + +#define UART_BUFFER_SIZE 300 + +char uart_tx_buf[UART_BUFFER_SIZE] = { 0 }; +char uart_rx_buf[UART_BUFFER_SIZE] = { 0 }; +uint32_t fram_address[MAX_MSP430_MEMORY_SECTIONS]; +uint32_t fram_length_of_sections[MAX_MSP430_MEMORY_SECTIONS]; +uint32_t fram_sections; +uint32_t section[MAX_MSP430_MEMORY_SECTIONS][3]; +unsigned char* firmware; + +//*************************************** +// BSL COMMANDS +//*************************************** + +#define RX_DATA_BLOCK_RESP_CMD 0x3B +#define RX_DATA_BLOCK_RESP_NL 0x02 +#define RX_DATA_BLOCK_RESP_NH 0x00 + +#define PASSWORD_LENGTH 32 +#define RX_PASSWORD_NL 0x21 +#define RX_PASSWORD_NH 0x00 +#define RX_PASSWORD_RESP_CMD 0x3B +#define RX_PASSWORD_RESP_NL 0x02 +#define RX_PASSWORD_RESP_NH 0x00 + +#define MASS_ERASE_NL 0x01 +#define MASS_ERASE_NH 0x00 +#define MASS_ERASE_RESP_CMD 0x3B +#define MASS_ERASE_RESP_NL 0x02 +#define MASS_ERASE_RESP_NH 0x00 + +#define LOAD_PC_NL 0x04 +#define LOAD_PC_NH 0x00 + +#define TX_DATA_BLOCK_NL 0x06 +#define TX_DATA_BLOCK_NH 0x00 +#define TX_DATA_RESP_CMD 0x3A + +#define RX_PASSWORD 0x11 +#define TX_DATA_BLOCK 0x18 +#define RX_DATA_BLOCK 0x10 +#define MASS_ERASE 0x15 +#define LOAD_PC 0x17 + +#define HEADER 0x80 + +#define ACK 0x00 +#define HEADER_INCORRECT 0x51 +#define CHECKSUM_INCORRECT 0x52 +#define PACKET_SIZE_ZERO 0x53 +#define PACKET_SIZE_EXCEEDS 0x54 +#define UNKNOWN_ERROR 0x55 +#define UNKNOWN_BAUDRATE 0x56 +#define PACKET_SIZE_ERROR 0x57 + + +#define GetCKL(cs) (char)(cs) +#define GetCKH(cs) (char)(cs >> 8) + +#define MAX_UART_BSL_BUFFER_SIZE 200 + +void MSP::invoke_target_normal_mode_operation() { + + free(firmware); + + digitalWrite(TEST_PIN, LOW); + digitalWrite(RESET_PIN, HIGH); + delay(200); + + digitalWrite(RESET_PIN, LOW); + delayMicroseconds(100); + digitalWrite(RESET_PIN, HIGH); + delayMicroseconds(100); +} + +void MSP::invoke_target_bsl_mode_operation() { + + println_debug("Invoking BSL by hardware entry sequence..."); + + digitalWrite(RESET_PIN, HIGH); + digitalWrite(TEST_PIN, HIGH); + delay(200); + + digitalWrite(TEST_PIN, LOW); + digitalWrite(RESET_PIN, LOW); + delay(100); + + digitalWrite(TEST_PIN, HIGH); + delay(50); + digitalWrite(TEST_PIN, LOW); + delay(50); + + digitalWrite(TEST_PIN, HIGH); + delay(50); + digitalWrite(RESET_PIN, HIGH); + delay(50); + digitalWrite(TEST_PIN, LOW); + + delay(200); +} + +bool MSP::write_default_password() { + + bool result = false; + uint16_t checksum = 0; + char password[PASSWORD_LENGTH] = { 0 }; + + memset(uart_tx_buf, '\0', UART_BUFFER_SIZE); + memset(uart_rx_buf, '\0', UART_BUFFER_SIZE); + + for (uint16_t i = 0; i < PASSWORD_LENGTH; i++) + password[i] = 0xFF; + + uart_tx_buf[0] = HEADER; + uart_tx_buf[1] = RX_PASSWORD_NL; + uart_tx_buf[2] = RX_PASSWORD_NH; + uart_tx_buf[3] = RX_PASSWORD; + + memcpy(&uart_tx_buf[4], password, PASSWORD_LENGTH); + + checksum = calc_checksum(&uart_tx_buf[3], (uint16_t)(PASSWORD_LENGTH + 1)); + uart_tx_buf[PASSWORD_LENGTH + 4] = GetCKL(checksum); + uart_tx_buf[PASSWORD_LENGTH + 5] = GetCKH(checksum); + + println_debug("Sending BSL password..."); + + flush_bsl_uart_buffer(); + + BSL_UART.write(uart_tx_buf, PASSWORD_LENGTH + 6); + + while (BSL_UART.available() <= 0) { + ; + } + + BSL_UART.readBytes(uart_rx_buf, 8); + + println_debug("BSL password unlock response: "); + print_debug_hex(uart_rx_buf[0], HEX); + print_debug(" "); + print_debug_hex(uart_rx_buf[1], HEX); + print_debug(" "); + print_debug_hex(uart_rx_buf[2], HEX); + print_debug(" "); + print_debug_hex(uart_rx_buf[3], HEX); + print_debug(" "); + print_debug_hex(uart_rx_buf[4], HEX); + print_debug(" "); + print_debug_hex(uart_rx_buf[5], HEX); + println_debug(" "); + + if ((uart_rx_buf[0] == ACK) + && (uart_rx_buf[1] == HEADER) + && (uart_rx_buf[2] == RX_PASSWORD_RESP_NL) + && (uart_rx_buf[3] == RX_PASSWORD_RESP_NH) + && (uart_rx_buf[4] == RX_PASSWORD_RESP_CMD) + && (uart_rx_buf[5] == 0x00)) { + + println_debug("BSL password is correct!"); + result = true; + } + else { + println_debug("BSL password is wrong!"); + result = false; + } + + delay(50); + + return result; +} + +uint16_t MSP::calc_checksum(char* data, uint16_t length) { + + char x; + uint16_t crc = 0xFFFF; + + while (length--) { + x = crc >> 8 ^ *data++; + x ^= x >> 4; + crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x << 5)) ^ ((uint16_t)x); + } + + return crc; +} + +bool MSP::write_firmware() { + + bool numberOfErrors = 0; + bool result = true; + uint16_t region = 0; + unsigned char* framStartOfData = 0; + + for (region = 0; region < fram_sections; region++) { + + framStartOfData = &firmware[section[region][0]]; + + result = send_large_data(fram_address[region], fram_length_of_sections[region], framStartOfData); + + if (!result) { + print_debug("write_memory Large Data To Memory failed\r\n"); + return false; + } + else + print_debug("write_memory Large Data To Memory successful\r\n"); + } + + if (numberOfErrors != 0) + return false; + + return true; +} + +bool MSP::send_large_data(uint32_t startAddress, uint32_t length, unsigned char* data) { + + uint32_t currentAddress = startAddress; + uint32_t currentLength = length; + unsigned char* currentData = data; + bool done = false; + bool result = true; + + while (!done) { + if (currentLength <= 0) { + done = true; + } + else if (currentLength < MAX_UART_BSL_BUFFER_SIZE) { + + result = write_memory(currentAddress, currentLength, currentData); + if (!result) { + return result; + } + done = true; + } + else { + result = write_memory(currentAddress, MAX_UART_BSL_BUFFER_SIZE, currentData); + if (!result) { + return result; + } + currentAddress += MAX_UART_BSL_BUFFER_SIZE; + currentData += MAX_UART_BSL_BUFFER_SIZE; + currentLength -= MAX_UART_BSL_BUFFER_SIZE; + } + } + + return true; +} + +bool MSP::write_memory(uint32_t startAddress, char lenght, unsigned char* data) { + + uint16_t checksum = 0; + + memset(uart_tx_buf, '\0', UART_BUFFER_SIZE); + memset(uart_rx_buf, '\0', UART_BUFFER_SIZE); + + uart_tx_buf[0] = HEADER; + uart_tx_buf[1] = (char)((lenght + 4) & 0x00ff); + uart_tx_buf[2] = (char)(((lenght + 4) >> 8) & 0x00ff); + uart_tx_buf[3] = RX_DATA_BLOCK; + + uart_tx_buf[4] = (char)(startAddress & 0x00ff); + uart_tx_buf[5] = (char)((startAddress >> 8) & 0x00ff); + uart_tx_buf[6] = (char)((startAddress >> 16) & 0x00ff); + + memcpy(&uart_tx_buf[7], data, lenght); + + checksum = calc_checksum(&uart_tx_buf[3], lenght + 4); + uart_tx_buf[lenght + 7] = (char)(checksum); + uart_tx_buf[lenght + 8] = (char)(checksum >> 8); + + println_debug("Writing in memory..."); + + flush_bsl_uart_buffer(); + + BSL_UART.write(uart_tx_buf, lenght + 9); + + while (BSL_UART.available() <= 0) { + ; + } + + BSL_UART.readBytes(uart_rx_buf, 8); + + println_debug("Memory write response:"); + print_debug_hex(uart_rx_buf[0], HEX); + print_debug(" "); + print_debug_hex(uart_rx_buf[1], HEX); + print_debug(" "); + print_debug_hex(uart_rx_buf[2], HEX); + print_debug(" "); + print_debug_hex(uart_rx_buf[3], HEX); + print_debug(" "); + print_debug_hex(uart_rx_buf[4], HEX); + print_debug(" "); + print_debug_hex(uart_rx_buf[5], HEX); + println_debug(" "); + + if ((uart_rx_buf[0] == ACK) + && (uart_rx_buf[1] == HEADER) + && (uart_rx_buf[2] == RX_DATA_BLOCK_RESP_NL) + && (uart_rx_buf[3] == RX_DATA_BLOCK_RESP_NH) + && (uart_rx_buf[4] == RX_DATA_BLOCK_RESP_CMD) + && (uart_rx_buf[5] == 0x00)) { + return true; + } + + return false; +} + +char MSP::ctoh(char data) { + if (data > '9') { + data += 9; + } + return (data &= 0x0F); +} + +void MSP::flush_bsl_uart_buffer() { + while (BSL_UART.available() > 0) { + BSL_UART.read(); + } +} + +void MSP::load_firmware_from_spiffs() { + + File file = SPIFFS.open(SPIFFS_Firmware_Address, "r"); + + if (!file) { + println_debug("Failed to open file in SPIFFS"); + return; + } + + size_t fileSize = file.size(); + print_debug("File size: "); + println_debug(fileSize); + + const uint16_t MAX_MEMORY_LENGTH = 4; + uint16_t sections_count = 0; + uint32_t memory_address[MAX_MSP430_MEMORY_SECTIONS]; + char address[MAX_MEMORY_LENGTH + 1] = { 0 }; + uint32_t i = 0; + unsigned char _byte = 0; + + firmware = (unsigned char*)malloc(fileSize + 32); + + while (file.available()) { + + _byte = (char)file.read(); + + if (_byte != ' ' && _byte != '\r' && _byte != '\n') { + + if (_byte == '@') { + + address[0] = (char)file.read(); + address[1] = (char)file.read(); + address[2] = (char)file.read(); + address[3] = (char)file.read(); + address[4] = '\0'; + + memory_address[sections_count] = strtol(address, NULL, 16); + + section[sections_count][0] = i; // INIT INDEX of section + + if (sections_count > 0) { + section[sections_count - 1][1] = section[sections_count][0] - 1; // END INDEX of section + section[sections_count - 1][2] = section[sections_count - 1][1] - section[sections_count - 1][0] + 1; // LENGTH (in bytes) of section + } + sections_count++; + } + else { + char msb = ctoh(_byte); + char lsb = ctoh((char)file.read()); + firmware[i++] = (unsigned char)((msb << 4) | lsb); + } + } + } + + file.close(); + + int16_t z = 0; + for (z = 0; z < 150; z++) + print_debug_hex(firmware[z], HEX); + println_debug("----------------"); + + printf_debug_1arg("exit: %d\r\n", sections_count); + println_debug(i); + section[sections_count - 1][1] = i - 2; //END INDEX of section + section[sections_count - 1][2] = section[sections_count - 1][1] - section[sections_count - 1][0] + 1; //LENGTH (in bytes) of section + + for (int16_t _i = 0; _i < sections_count; _i++) { + printf_debug_2arg("Section %d: %#lX\r\n", _i, memory_address[_i]); + fram_address[_i] = memory_address[_i]; + } + + printf_debug_1arg("Total memory section: %d\r\n", sections_count); + fram_sections = sections_count; + + print_debug("\r\nINIT: "); + println_debug(section[0][0]); + print_debug("END: "); + println_debug(section[0][1]); + print_debug("LENGTH: "); + println_debug(section[0][2]); + + print_debug("INIT: "); + println_debug(section[1][0]); + print_debug("END: "); + println_debug(section[1][1]); + print_debug("LENGTH: "); + println_debug(section[1][2]); + + print_debug("INIT: "); + println_debug(section[2][0]); + print_debug("END: "); + println_debug(section[2][1]); + print_debug("LENGTH: "); + println_debug(section[2][2]); + + for (int16_t _i = 0; _i < sections_count; _i++) + fram_length_of_sections[_i] = section[_i][2]; +} \ No newline at end of file diff --git a/Example/lib/MSP430/MSP430.h b/Example/lib/MSP430/MSP430.h new file mode 100644 index 0000000..9e8be5e --- /dev/null +++ b/Example/lib/MSP430/MSP430.h @@ -0,0 +1,78 @@ +#pragma once +#define DRIZZLING_BYTES_VERSION "2.0" + +/* + * v1.0 - Initial release. + * v1.1 - Flush RX UART buffer (MSP430 received bytes) before each transmission to allow multiple sequential OTA updates. + * v2.0 - Improvements in memory usage + */ + +#include +#include +#include +#include + +#define SERIAL_DEBUG 0 + +#if SERIAL_DEBUG +#define print_debug(x); Serial.print(x); +#define println_debug(x); Serial.println(x); +#define print_debug_hex(x, base); Serial.print(x, HEX); +#define printf_debug_1arg(x, y); Serial.printf(x, y); +#define printf_debug_2arg(x, y, z); Serial.printf(x, y, z); +#else +#define print_debug(x); +#define println_debug(x); +#define print_debug_hex(x, base); +#define printf_debug_1arg(x, y); +#define printf_debug_2arg(x, y, z); +#endif + +#define MAX_MSP430_MEMORY_SECTIONS 30 + + /** + * @brief Construct a new BSL object to control the Bootstrap Loader programming of the target MCU. + * + * @param RESET_PIN Any GPIO with output mode capability to be connected to the RESET pin of the target MSP430. + * @param TEST_PIN Any GPIO with output mode capability to be connected to the TEST pin of the target MSP430. + * @param Serial_Port HardwareSerial object (TX and RX UART) from Arduino Framework (Serial, Serial1, Serial2...). + * @param SPIFFS_Firmware_Address The local SPI Flash File System address where the BSL object must look for the firmware file in TI-TXT format. + */ +class MSP { + +private: + byte TEST_PIN; + byte RESET_PIN; + HardwareSerial BSL_UART; + String SPIFFS_Firmware_Address; + + uint16_t calc_checksum(char* data, uint16_t length); + bool send_large_data(uint32_t startAddress, uint32_t length, unsigned char* data); + bool write_memory(uint32_t startAddress, char lenght, unsigned char* data); + char ctoh(char data); + void flush_bsl_uart_buffer(); + +public: + MSP(byte RESET_PIN, byte TEST_PIN, HardwareSerial& Serial_Port, String SPIFFS_Firmware_Address) : BSL_UART(Serial_Port) { + + this->TEST_PIN = TEST_PIN; + this->RESET_PIN = RESET_PIN; + this->SPIFFS_Firmware_Address = SPIFFS_Firmware_Address; + + BSL_UART.begin(9600, SERIAL_8E1); + BSL_UART.setTimeout(500); + + pinMode(TEST_PIN, OUTPUT); + pinMode(RESET_PIN, OUTPUT); + + digitalWrite(TEST_PIN, LOW); + digitalWrite(RESET_PIN, HIGH); + } + ~MSP() {} + + void invoke_target_normal_mode_operation(); + void invoke_target_bsl_mode_operation(); + bool write_default_password(); + bool write_firmware(); + void load_firmware_from_spiffs(); +}; diff --git a/Examples/Firebase/platformio.ini b/Example/platformio.ini similarity index 80% rename from Examples/Firebase/platformio.ini rename to Example/platformio.ini index 828d697..a7c9019 100644 --- a/Examples/Firebase/platformio.ini +++ b/Example/platformio.ini @@ -12,7 +12,7 @@ platform = espressif32 board = esp32dev framework = arduino + upload_port = COM7 monitor_port = COM7 -monitor_speed = 9600 -lib_deps = mobizt/Firebase Arduino Client Library for ESP8266 and ESP32@^4.0.0 +monitor_speed = 9600 \ No newline at end of file diff --git a/Example/src/main.cpp b/Example/src/main.cpp new file mode 100644 index 0000000..1c99645 --- /dev/null +++ b/Example/src/main.cpp @@ -0,0 +1,62 @@ +#include +#include +#include "MSP430.h" + +//You need to ensure that the MSP430 firmware is on SPIFFS as TI-TXT format (exactly as compiled). +#define SPIFFS_FIRMWARE_ADDRESS "/txt/firmware.txt" + +MSP BSL(2, 4, Serial2, SPIFFS_FIRMWARE_ADDRESS); + +void setup() { + + Serial.begin(9600); + + if (!SPIFFS.begin()) { + Serial.println("SPIFFS initialization failed."); + return; + } + + Serial.println("\r\n---START---"); +} + +void loop() { + + int16_t attempts = 3; + + BSL.load_firmware_from_spiffs(); + + do { + + BSL.invoke_target_bsl_mode_operation(); + + if (!BSL.write_default_password()) { + attempts--; + + if (!attempts) + break; + + continue; + } + + delay(5); + + if (!BSL.write_firmware()) { + Serial.print("\r\nMSP430 programming failed\r\n"); + attempts--; + continue; + } + + Serial.print("\r\nMSP430 programmed successfully\r\n"); + attempts = 0; + + BSL.invoke_target_normal_mode_operation(); + + Serial.print("Device is reset\r\n"); + + } while (attempts > 0); + + + while (1) { + ; + } +} diff --git a/Examples/Firebase/test/README b/Example/test/README similarity index 100% rename from Examples/Firebase/test/README rename to Example/test/README diff --git a/Examples/Firebase/lib/Auth_Secrets/Firebase_Secrets.h.example b/Examples/Firebase/lib/Auth_Secrets/Firebase_Secrets.h.example deleted file mode 100644 index 2c58d70..0000000 --- a/Examples/Firebase/lib/Auth_Secrets/Firebase_Secrets.h.example +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef FIREBASE_SECRETS_H -#define FIREBASE_SECRETS_H - -/* Define the API Key */ -#define API_KEY "API_KEY" - -/* Define the user Email and password that alreadey registerd or added in your project */ -#define USER_EMAIL "USER_EMAIL" -#define USER_PASSWORD "USER_PASSWORD" - -/* Define the Firebase storage bucket ID e.g bucket-name.appspot.com */ -#define STORAGE_BUCKET_ID "BUCKET-NAME.appspot.com" - -#endif //FIREBASE_SECRETS_H \ No newline at end of file diff --git a/Examples/Firebase/lib/Auth_Secrets/WiFi_Secrets.h.example b/Examples/Firebase/lib/Auth_Secrets/WiFi_Secrets.h.example deleted file mode 100644 index 0ac6d5f..0000000 --- a/Examples/Firebase/lib/Auth_Secrets/WiFi_Secrets.h.example +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef WIFI_SECRETS_H -#define WIFI_SECRETS_H - -/* Define the WiFi credentials */ -#define WIFI_SSID "WIFI_AP" -#define WIFI_PASSWORD "WIFI_PASSWORD" - -#endif //WIFI_SECRETS_H \ No newline at end of file diff --git a/Examples/Firebase/lib/Cloud/Cloud.cpp b/Examples/Firebase/lib/Cloud/Cloud.cpp deleted file mode 100644 index 393f5d7..0000000 --- a/Examples/Firebase/lib/Cloud/Cloud.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include "Cloud.h" -#include -#include "Firebase_Secrets.h" -#include - -FirebaseData fbdo; -FirebaseAuth auth; -FirebaseConfig config; - -void fcsDownloadCallback(FCS_DownloadStatusInfo info) { - if (info.status == fb_esp_fcs_download_status_init) { - Serial.printf("Downloading file %s (%d) to %s\n", info.remoteFileName.c_str(), info.fileSize, info.localFileName.c_str()); - } - else if (info.status == fb_esp_fcs_download_status_download) { - Serial.printf("Downloaded %d%s\n", (int)info.progress, "%"); - } - else if (info.status == fb_esp_fcs_download_status_complete) { - Serial.println("Download completed\n"); - } - else if (info.status == fb_esp_fcs_download_status_error) { - Serial.printf("Download failed, %s\n", info.errorMsg.c_str()); - } -} - -void FirebaseStorage::Firebase_Init(String email, String password, String api_key) { - - Serial.printf("Firebase Client v%s\n\n", FIREBASE_CLIENT_VERSION); - - // Assign the api key (required) - config.api_key = api_key; - - // Assign the user sign in credentials - auth.user.email = email; - auth.user.password = password; - - // Assign the callback function for the long running token generation task - config.token_status_callback = tokenStatusCallback; // see addons/TokenHelper.h - - // Assign download buffer size in byte - // Data to be downloaded will read as multiple chunks with this size, to compromise between speed and memory used for buffering. - // The memory from external SRAM/PSRAM will not use in the TCP client internal rx buffer. - config.fcs.download_buffer_size = 4096; - - Firebase.begin(&config, &auth); - - Firebase.reconnectWiFi(true); -} - -bool FirebaseStorage::Download_Firmware_and_Store_in_SPIFFS() { - - bool success = false; - - if (Firebase.ready()) { - - Serial.println("\nPreparing download...\n"); - if (!Firebase.Storage.download(&fbdo, store_bucket_address, cloud_address, spiffs_address, mem_storage_type_flash, fcsDownloadCallback)) { - Serial.println(fbdo.errorReason()); - ESP.restart(); - } - else - success = true; - } - return success; -} \ No newline at end of file diff --git a/Examples/Firebase/lib/Cloud/Cloud.h b/Examples/Firebase/lib/Cloud/Cloud.h deleted file mode 100644 index 46188ba..0000000 --- a/Examples/Firebase/lib/Cloud/Cloud.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef CLOUD_H -#define CLOUD_H - -#include -#include - -extern FirebaseData fbdo; -extern FirebaseAuth auth; -extern FirebaseConfig config; - -class FirebaseStorage { - - private: - - String cloud_address; - String spiffs_address; - String store_bucket_address; - - public: - FirebaseStorage(String store_bucket_address, String cloud_address, String spiffs_address) { - this->cloud_address = cloud_address; - this->spiffs_address = spiffs_address; - this->store_bucket_address = store_bucket_address; - } - bool Download_Firmware_and_Store_in_SPIFFS(); - void Firebase_Init(String email, String password, String api_key); -}; - -#endif // CLOUD_H \ No newline at end of file diff --git a/Examples/Firebase/lib/MSP430/MSP430.cpp b/Examples/Firebase/lib/MSP430/MSP430.cpp deleted file mode 100644 index f9b95f4..0000000 --- a/Examples/Firebase/lib/MSP430/MSP430.cpp +++ /dev/null @@ -1,411 +0,0 @@ -#include -#include "MSP430.h" -#include "Network.h" -#include "WiFi_Secrets.h" -#include "Firebase_Secrets.h" -#include "Cloud.h" -#include - -File Read_File; - -#define UART_BUFFER_SIZE 300 - -char sendBuffer[UART_BUFFER_SIZE] = { 0 }; -char receiveBuffer[UART_BUFFER_SIZE] = { 0 }; -unsigned long fram_address[MAX_MSP430_MEMORY_SECTIONS]; -unsigned long fram_length_of_sections[MAX_MSP430_MEMORY_SECTIONS]; -unsigned long fram_sections; -unsigned long section[MAX_MSP430_MEMORY_SECTIONS][3]; -unsigned char firmware[FIRMWARE_SIZE]; - -//*************************************** -// BSL COMMANDS -//*************************************** - -#define RX_DATA_BLOCK_RESP_CMD 0x3B -#define RX_DATA_BLOCK_RESP_NL 0x02 -#define RX_DATA_BLOCK_RESP_NH 0x00 - -#define PASSWORD_LENGTH 32 -#define RX_PASSWORD_NL 0x21 -#define RX_PASSWORD_NH 0x00 -#define RX_PASSWORD_RESP_CMD 0x3B -#define RX_PASSWORD_RESP_NL 0x02 -#define RX_PASSWORD_RESP_NH 0x00 - -#define MASS_ERASE_NL 0x01 -#define MASS_ERASE_NH 0x00 -#define MASS_ERASE_RESP_CMD 0x3B -#define MASS_ERASE_RESP_NL 0x02 -#define MASS_ERASE_RESP_NH 0x00 - -#define LOAD_PC_NL 0x04 -#define LOAD_PC_NH 0x00 - -#define TX_DATA_BLOCK_NL 0x06 -#define TX_DATA_BLOCK_NH 0x00 -#define TX_DATA_RESP_CMD 0x3A - -#define RX_PASSWORD 0x11 -#define TX_DATA_BLOCK 0x18 -#define RX_DATA_BLOCK 0x10 -#define MASS_ERASE 0x15 -#define LOAD_PC 0x17 - -#define HEADER 0x80 - -#define ACK 0x00 -#define HEADER_INCORRECT 0x51 -#define CHECKSUM_INCORRECT 0x52 -#define PACKET_SIZE_ZERO 0x53 -#define PACKET_SIZE_EXCEEDS 0x54 -#define UNKNOWN_ERROR 0x55 -#define UNKNOWN_BAUDRATE 0x56 -#define PACKET_SIZE_ERROR 0x57 - -#define GetCKL(cs) (char)(cs) -#define GetCKH(cs) (char)(cs >> 8) - -#define MAX_UART_BSL_BUFFER_SIZE 200 - -void MSP430::Invoke_MSP_Normal_Mode_Operation() { - - digitalWrite(TEST_PIN, LOW); - digitalWrite(RESET_PIN, HIGH); - delay(200); - - digitalWrite(RESET_PIN, LOW); - delayMicroseconds(100); - digitalWrite(RESET_PIN, HIGH); - delayMicroseconds(100); -} - -void MSP430::Invoke_MSP_BSL_Mode_Operation() { - - Serial.println("Invoking BSL by hardware entry sequence..."); - - digitalWrite(RESET_PIN, HIGH); - digitalWrite(TEST_PIN, HIGH); - delay(200); - - digitalWrite(TEST_PIN, LOW); - digitalWrite(RESET_PIN, LOW); - delay(100); - - digitalWrite(TEST_PIN, HIGH); - delay(50); - digitalWrite(TEST_PIN, LOW); - delay(50); - - digitalWrite(TEST_PIN, HIGH); - delay(50); - digitalWrite(RESET_PIN, HIGH); - delay(50); - digitalWrite(TEST_PIN, LOW); - - delay(200); -} - -bool MSP430::Write_Default_Password() { - - bool result = false; - unsigned int checksum = 0; - char password[PASSWORD_LENGTH] = { 0 }; - - memset(sendBuffer, '\0', UART_BUFFER_SIZE); - memset(receiveBuffer, '\0', UART_BUFFER_SIZE); - - for (unsigned int i = 0; i < PASSWORD_LENGTH; i++) - password[i] = 0xFF; - - sendBuffer[0] = HEADER; - sendBuffer[1] = RX_PASSWORD_NL; - sendBuffer[2] = RX_PASSWORD_NH; - sendBuffer[3] = RX_PASSWORD; - - memcpy(&sendBuffer[4], password, PASSWORD_LENGTH); - - checksum = Checksum(&sendBuffer[3], (unsigned int)(PASSWORD_LENGTH + 1)); - sendBuffer[PASSWORD_LENGTH + 4] = GetCKL(checksum); - sendBuffer[PASSWORD_LENGTH + 5] = GetCKH(checksum); - - Serial.println("Sending BSL password..."); - - BSL_UART_Flush(); - - BSL_UART.write(sendBuffer, PASSWORD_LENGTH + 6); - - while (BSL_UART.available() <= 0) { - ; - } - - BSL_UART.readBytes(receiveBuffer, 8); - - Serial.println("BSL password unlock response: "); - Serial.print(receiveBuffer[0], HEX); - Serial.print(" "); - Serial.print(receiveBuffer[1], HEX); - Serial.print(" "); - Serial.print(receiveBuffer[2], HEX); - Serial.print(" "); - Serial.print(receiveBuffer[3], HEX); - Serial.print(" "); - Serial.print(receiveBuffer[4], HEX); - Serial.print(" "); - Serial.print(receiveBuffer[5], HEX); - Serial.println(" "); - - if ((receiveBuffer[0] == ACK) - && (receiveBuffer[1] == HEADER) - && (receiveBuffer[2] == RX_PASSWORD_RESP_NL) - && (receiveBuffer[3] == RX_PASSWORD_RESP_NH) - && (receiveBuffer[4] == RX_PASSWORD_RESP_CMD) - && (receiveBuffer[5] == 0x00)) { - - Serial.println("BSL password is correct!"); - result = true; - } - else { - Serial.println("BSL password is wrong!"); - result = false; - } - - delay(50); - - return result; -} - -unsigned int MSP430::Checksum(char* data, unsigned int length) { - - char x; - unsigned int crc = 0xFFFF; - - while (length--) { - x = crc >> 8 ^ *data++; - x ^= x >> 4; - crc = (crc << 8) ^ ((unsigned int)(x << 12)) ^ ((unsigned int)(x << 5)) ^ ((unsigned int)x); - } - - return crc; -} - -bool MSP430::Write_Firmware() { - - bool numberOfErrors = 0; - bool result = true; - unsigned int region = 0; - unsigned char* framStartOfData = 0; - - for (region = 0; region < fram_sections; region++) { - - framStartOfData = &firmware[section[region][0]]; - - result = Send_Large_Data(fram_address[region], fram_length_of_sections[region], framStartOfData); - - if (!result) { - Serial.print("Write_Memory Large Data To Memory failed\r\n"); - return false; - } - else - Serial.print("Write_Memory Large Data To Memory successful\r\n"); - } - - if (numberOfErrors != 0) - return false; - - return true; -} - -bool MSP430::Send_Large_Data(unsigned long startAddress, unsigned long length, unsigned char* data) { - - unsigned long currentAddress = startAddress; - unsigned long currentLength = length; - unsigned char* currentData = data; - bool done = false; - bool result = true; - - while (!done) { - if (currentLength <= 0) { - done = true; - } - else if (currentLength < MAX_UART_BSL_BUFFER_SIZE) { - - result = Write_Memory(currentAddress, currentLength, currentData); - if (!result) { - return result; - } - done = true; - } - else { - result = Write_Memory(currentAddress, MAX_UART_BSL_BUFFER_SIZE, currentData); - if (!result) { - return result; - } - currentAddress += MAX_UART_BSL_BUFFER_SIZE; - currentData += MAX_UART_BSL_BUFFER_SIZE; - currentLength -= MAX_UART_BSL_BUFFER_SIZE; - } - } - - return true; -} - -bool MSP430::Write_Memory(unsigned long startAddress, char lenght, unsigned char* data) { - - uint16_t checksum = 0; - - memset(sendBuffer, '\0', UART_BUFFER_SIZE); - memset(receiveBuffer, '\0', UART_BUFFER_SIZE); - - sendBuffer[0] = HEADER; - sendBuffer[1] = (char)((lenght + 4) & 0x00ff); - sendBuffer[2] = (char)(((lenght + 4) >> 8) & 0x00ff); - sendBuffer[3] = RX_DATA_BLOCK; - - sendBuffer[4] = (char)(startAddress & 0x00ff); - sendBuffer[5] = (char)((startAddress >> 8) & 0x00ff); - sendBuffer[6] = (char)((startAddress >> 16) & 0x00ff); - - memcpy(&sendBuffer[7], data, lenght); - - checksum = Checksum(&sendBuffer[3], lenght + 4); - sendBuffer[lenght + 7] = (char)(checksum); - sendBuffer[lenght + 8] = (char)(checksum >> 8); - - Serial.println("Writing in memory..."); - - BSL_UART_Flush(); - - BSL_UART.write(sendBuffer, lenght + 9); - - while (BSL_UART.available() <= 0) { - ; - } - - BSL_UART.readBytes(receiveBuffer, 8); - - Serial.println("Memory write response:"); - Serial.print(receiveBuffer[0], HEX); - Serial.print(" "); - Serial.print(receiveBuffer[1], HEX); - Serial.print(" "); - Serial.print(receiveBuffer[2], HEX); - Serial.print(" "); - Serial.print(receiveBuffer[3], HEX); - Serial.print(" "); - Serial.print(receiveBuffer[4], HEX); - Serial.print(" "); - Serial.print(receiveBuffer[5], HEX); - Serial.println(" "); - - if ((receiveBuffer[0] == ACK) - && (receiveBuffer[1] == HEADER) - && (receiveBuffer[2] == RX_DATA_BLOCK_RESP_NL) - && (receiveBuffer[3] == RX_DATA_BLOCK_RESP_NH) - && (receiveBuffer[4] == RX_DATA_BLOCK_RESP_CMD) - && (receiveBuffer[5] == 0x00)) { - return true; - } - - return false; -} - -char MSP430::ctoh(char data) { - if (data > '9') { - data += 9; - } - return (data &= 0x0F); -} - -void MSP430::BSL_UART_Flush() { - while (BSL_UART.available() > 0) { - BSL_UART.read(); - } -} - -void MSP430::Load_from_SPIFFS_and_Store_in_RAM() { - Read_File = SPIFFS.open(SPIFFS_Firmware_Address, "r"); - -#define MAX_MEMORY_LENGTH 4 - unsigned int sections_count = 0; - unsigned long memory_address[MAX_MSP430_MEMORY_SECTIONS]; - char address[MAX_MEMORY_LENGTH + 1] = { 0 }; - unsigned long i = 0; - unsigned char _byte = 0; - - while (Read_File.available()) { - - _byte = (char)Read_File.read(); - - if (_byte != ' ' && _byte != '\r' && _byte != '\n') { - - if (_byte == '@') { - - address[0] = (char)Read_File.read(); - address[1] = (char)Read_File.read(); - address[2] = (char)Read_File.read(); - address[3] = (char)Read_File.read(); - address[4] = '\0'; - - memory_address[sections_count] = strtol(address, NULL, 16); - - section[sections_count][0] = i; // INIT INDEX of section - - if (sections_count > 0) { - section[sections_count - 1][1] = section[sections_count][0] - 1; // END INDEX of section - section[sections_count - 1][2] = section[sections_count - 1][1] - section[sections_count - 1][0] + 1; // LENGTH (in bytes) of section - } - sections_count++; - } - else { - char msb = ctoh(_byte); - char lsb = ctoh((char)Read_File.read()); - firmware[i++] = (unsigned char)((msb << 4) | lsb); - } - } - } - - Read_File.close(); - - for (int z = 0; z < 150; z++) { - Serial.println(firmware[z], HEX); - } - Serial.println("----------------"); - - Serial.printf("exit: %d\r\n", sections_count); - Serial.println(i); - section[sections_count - 1][1] = i - 2; //END INDEX of section - section[sections_count - 1][2] = section[sections_count - 1][1] - section[sections_count - 1][0] + 1; //LENGTH (in bytes) of section - - for (int _i = 0; _i < sections_count; _i++) { - Serial.printf("Section %d: %#lX\r\n", _i, memory_address[_i]); - fram_address[_i] = memory_address[_i]; - } - - Serial.printf("Total memory section: %d\r\n", sections_count); - fram_sections = sections_count; - - Serial.print("\r\nINIT: "); - Serial.println(section[0][0]); - Serial.print("END: "); - Serial.println(section[0][1]); - Serial.print("LENGTH: "); - Serial.println(section[0][2]); - - Serial.print("INIT: "); - Serial.println(section[1][0]); - Serial.print("END: "); - Serial.println(section[1][1]); - Serial.print("LENGTH: "); - Serial.println(section[1][2]); - - Serial.print("INIT: "); - Serial.println(section[2][0]); - Serial.print("END: "); - Serial.println(section[2][1]); - Serial.print("LENGTH: "); - Serial.println(section[2][2]); - - for (int _i = 0; _i < sections_count; _i++) - fram_length_of_sections[_i] = section[_i][2]; -} \ No newline at end of file diff --git a/Examples/Firebase/lib/MSP430/MSP430.h b/Examples/Firebase/lib/MSP430/MSP430.h deleted file mode 100644 index bca2469..0000000 --- a/Examples/Firebase/lib/MSP430/MSP430.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef MSP430_BSL_H -#define MSP430_BSL_H - -#define FIRMWARE_VERSION 1.1 - -/* - * v1.0 - Initial release. - * v1.1 - Flush RX UART buffer (MSP430 received bytes) before each transmission to allow multiple sequential OTA updates. - */ - -#include "Arduino.h" -#include -#include -#include - -extern File Read_File; - -#define MAX_MSP430_MEMORY_SECTIONS 30 -#define MAX_PROGRAM_FRAM_KB 64 //MSP430FR2476 as reference -#define MAX_PROGRAM_FRAM_BYTES (1024 * 64) -#define MAX_INFORMATION_FRAM_BYTES 512 -#define FIRMWARE_SIZE MAX_PROGRAM_FRAM_BYTES + MAX_INFORMATION_FRAM_BYTES - -extern unsigned char firmware[FIRMWARE_SIZE]; -extern unsigned long fram_address[MAX_MSP430_MEMORY_SECTIONS]; -extern unsigned long fram_length_of_sections[MAX_MSP430_MEMORY_SECTIONS]; -extern unsigned long fram_sections; -extern unsigned long section[MAX_MSP430_MEMORY_SECTIONS][3]; -/* -section[n][0] --> INIT INDEX of section n -section[n][1] --> END INDEX of section n -section[n][2] --> LENGTH (in bytes) of section n -*/ - -/** - * @brief Construct a new BSL object to control the Bootstrap Loader programming of the target MCU. - * - * @param RESET_PIN Any GPIO with output mode capability to be connected to the RESET pin of the target MSP430. - * @param TEST_PIN Any GPIO with output mode capability to be connected to the TEST pin of the target MSP430. - * @param Serial_Port HardwareSerial object (TX and RX UART) from Arduino Framework (Serial, Serial1, Serial2...). - * @param SPIFFS_Firmware_Address The local SPI Flash File System address where the BSL object must look for the firmware file in TI-TXT format. - */ -class MSP430 { - - private: - byte TEST_PIN; - byte RESET_PIN; - HardwareSerial BSL_UART; - String SPIFFS_Firmware_Address; - - unsigned int Checksum(char* data, unsigned int length); - bool Send_Large_Data(unsigned long startAddress, unsigned long length, unsigned char* data); - bool Write_Memory(unsigned long startAddress, char lenght, unsigned char* data); - char ctoh(char data); - void BSL_UART_Flush(); - - public: - MSP430(byte RESET_PIN, byte TEST_PIN, HardwareSerial& Serial_Port, String SPIFFS_Firmware_Address) : BSL_UART(Serial_Port) { - - this->TEST_PIN = TEST_PIN; - this->RESET_PIN = RESET_PIN; - this->SPIFFS_Firmware_Address = SPIFFS_Firmware_Address; - - BSL_UART.begin(9600, SERIAL_8E1); - BSL_UART.setTimeout(500); - - pinMode(TEST_PIN, OUTPUT); - pinMode(RESET_PIN, OUTPUT); - - digitalWrite(TEST_PIN, LOW); - digitalWrite(RESET_PIN, HIGH); - } - void Invoke_MSP_Normal_Mode_Operation(); - void Invoke_MSP_BSL_Mode_Operation(); - bool Write_Default_Password(); - bool Write_Firmware(); - void Load_from_SPIFFS_and_Store_in_RAM(); -}; - -#endif //MSP430_BSL_H diff --git a/Examples/Firebase/lib/Network/Network.cpp b/Examples/Firebase/lib/Network/Network.cpp deleted file mode 100644 index 76b7183..0000000 --- a/Examples/Firebase/lib/Network/Network.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "WiFi_Secrets.h" -#include -#include - -void WiFi_Init() { - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - Serial.print("\r\nonnecting to Wi-Fi"); - while (WiFi.status() != WL_CONNECTED) { - - Serial.print("."); - delay(300); - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); -} \ No newline at end of file diff --git a/Examples/Firebase/lib/Network/Network.h b/Examples/Firebase/lib/Network/Network.h deleted file mode 100644 index adf470a..0000000 --- a/Examples/Firebase/lib/Network/Network.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef NETWORK_H -#define NETWORK_H - -#include - -// PROTOTYPES -void WiFi_Init(); - -#endif // NETWORK_H \ No newline at end of file diff --git a/Examples/Firebase/lib/SPIFFS/Flash.cpp b/Examples/Firebase/lib/SPIFFS/Flash.cpp deleted file mode 100644 index e6ee109..0000000 --- a/Examples/Firebase/lib/SPIFFS/Flash.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include - -File Save_File; - -void SPI_Flash_File_System_Init(String SPIFFS_Firmware_Address, bool format_spiffs) { - - if (format_spiffs) { - if (SPIFFS.format()) - Serial.println("Success formatting"); - else - Serial.println("Error formatting"); - } - - if (!SPIFFS.begin(true)) { - Serial.println("SPIFFS/LittleFS initialization failed."); - return; - } - - Serial.print("TOTAL FLASH: "); - Serial.println(SPIFFS.totalBytes()); - - Serial.print("USED FLASH: "); - Serial.println(SPIFFS.usedBytes()); - - Serial.println(ESP.getFlashChipSize()); -} \ No newline at end of file diff --git a/Examples/Firebase/lib/SPIFFS/Flash.h b/Examples/Firebase/lib/SPIFFS/Flash.h deleted file mode 100644 index 2ca9abf..0000000 --- a/Examples/Firebase/lib/SPIFFS/Flash.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef FLASH_H -#define FLASH_H - -#include -#include - -#define RUN_MEMORY_FORMAT true -#define DONT_RUN_MEMORY_FORMAT false - -extern File Save_File; - -// PROTOTYPES -void SPI_Flash_File_System_Init(String SPIFFS_Firmware_Address, bool format_spiffs); - -#endif // FLASH_H \ No newline at end of file diff --git a/Examples/Firebase/src/main.cpp b/Examples/Firebase/src/main.cpp deleted file mode 100644 index 233efd6..0000000 --- a/Examples/Firebase/src/main.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include "MSP430.h" -#include "Network.h" -#include "WiFi_Secrets.h" -#include "Firebase_Secrets.h" -#include "Cloud.h" -#include - -#define FIREBASE_FIRMWARE_ADDRESS "txt/firmware.txt" -#define SPIFFS_FIRMWARE_ADDRESS "/txt/firmware.txt" - -/* -The BSL object from MSP430 class is not Firebase-dependent. It's SPIFFS dependent. - -So, you just need ensure that the firmware there is on SPIFFS in the TI-TXT format (without any modification, exactly as it was compiled). - -In this way, your application can download firmware from any other source and to use the ESP32's internal flash memory as an common interface. -*/ -MSP430 BSL(2, 4, Serial2, SPIFFS_FIRMWARE_ADDRESS); - -/* -Just as an example and for demonstration purposes, -in this implementation Firebase will be used as a server that stores the firmware that will be programmed in the MSP430. -*/ -FirebaseStorage OTA(STORAGE_BUCKET_ADDRESS, FIREBASE_FIRMWARE_ADDRESS, SPIFFS_FIRMWARE_ADDRESS); - -void setup() { - Serial.begin(9600); - - WiFi_Init(); - - OTA.Firebase_Init(USER_EMAIL, USER_PASSWORD, API_KEY); - - SPI_Flash_File_System_Init(SPIFFS_FIRMWARE_ADDRESS, DONT_RUN_MEMORY_FORMAT); - - Serial.println("\r\n---START---"); -} - -void loop() { - - static int retry = 3; - - if (OTA.Download_Firmware_and_Store_in_SPIFFS()) { - - BSL.Load_from_SPIFFS_and_Store_in_RAM(); - - do { - - BSL.Invoke_MSP_BSL_Mode_Operation(); - - if (!BSL.Write_Default_Password()) { - retry--; - - if (!retry) - break; - - continue; - } - - delay(5); - - if (!BSL.Write_Firmware()) { - Serial.print("\r\nMSP430 programming failed\r\n"); - retry--; - continue; - } - - Serial.print("\r\nMSP430 programmed successfully\r\n"); - retry = 0; - - BSL.Invoke_MSP_Normal_Mode_Operation(); - - Serial.print("Device is reset\r\n"); - - } while (retry > 0); - } - - while (1) { - ; - } -}