diff --git a/TNC/bm78.cpp b/TNC/bm78.cpp index 3d28159..4569a12 100644 --- a/TNC/bm78.cpp +++ b/TNC/bm78.cpp @@ -2,9 +2,11 @@ // All rights reserved. #include "bm78.h" +#include "bm78_eeprom.hpp" #include "GPIO.hpp" #include "Log.h" #include "main.h" +#include "HdlcFrame.hpp" #include "stm32l4xx_hal.h" @@ -15,6 +17,7 @@ extern RTC_HandleTypeDef hrtc; extern UART_HandleTypeDef huart3; +extern CRC_HandleTypeDef hcrc; namespace mobilinkd { namespace tnc { namespace bm78 { @@ -23,60 +26,47 @@ namespace mobilinkd { namespace tnc { namespace bm78 { * transparent data transfer in one or both modes. The module documentation * only clearly describes how to configure the modules using a (horrible) * Windows application. Microchip publishes a library for use with their - * PIC chips that we use as a guide for implementing our own configuration - * code. + * PIC chips that we initially used as a guide for implementing our own + * configuration code. We now use a hybrid mechanism, writing out the + * entire configuration and tweaking a few settings. * * The module must be booted into EEPROM programming mode in order to make - * changes. This mode uses 115200 baud with no hardware flow control + * changes. This mode uses 115200 baud with no hardware flow control. * * We program the module for the following features: * * - The module is set for 115200 baud with hardware flow control. * - The name is changed to TNC3. * - The BT3.0 pairing PIN is set to 1234 - * - The BLE5.0 pairing PIN is set to "625653" (MBLNKD on a phone pad). + * - The BLE5.0 pairing PIN is set to "123456". * - The module power setting is set as low as possible for BLE. */ -const uint32_t BT_INIT_MAGIC = 0xc0a2; - void bm78_reset() { // Must use HAL_Delay() here as osDelay() may not be available. mobilinkd::tnc::gpio::BT_RESET::off(); - HAL_Delay(1200); + HAL_Delay(1); mobilinkd::tnc::gpio::BT_RESET::on(); - HAL_Delay(800); - } -void exit_command_mode() -{ - gpio::BT_CMD::on(); - bm78_reset(); - INFO("BM78 in PASSTHROUGH mode"); -} - -HAL_StatusTypeDef read_response(uint8_t* buffer, uint16_t size, uint32_t timeout) -{ - memset(buffer, 0, size); - - auto result = HAL_UART_Receive(&huart3, buffer, size - 1, timeout); - - if (result == HAL_TIMEOUT) result = HAL_OK; - - return result; -} - -bool enter_program_mode() +/** + * Enter BM78 EEPROM programming mode. + * + * This pulls EAN low on the BM78 and resets the module to enter EEPROM + * programming mode and disable HW flow control on the UART. + * + * @note The timing of this process is not well documented. + */ +void enter_program_mode() { // Ensure we start out disconnected. gpio::BT_CMD::off(); HAL_Delay(10); gpio::BT_RESET::off(); - HAL_Delay(10); // Spec says minimum 63ns + HAL_Delay(1); // Spec says minimum 63ns. gpio::BT_RESET::on(); - HAL_Delay(200); // I could not find timing specifications for this. + HAL_Delay(200); // Timing for EEPROM programming is not specified. huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart3.Init.BaudRate = 115200; @@ -84,95 +74,22 @@ bool enter_program_mode() { CxxErrorHandler(); } - - // Read (cmd = 0x29) all 1K bytes, starting at address 0, 128 bytes at a time. - uint8_t cmd[] = {0x01, 0x29, 0xfc, 0x03, 0x00, 0x00, 0x80}; - - constexpr const uint16_t BLOCK_SIZE = 128; - - for (uint16_t addr = 0; addr != 0x500; addr += BLOCK_SIZE) - { - cmd[5] = addr & 0xFF; - cmd[4] = (addr >> 8) & 0xFF; - if (HAL_UART_Transmit(&huart3, cmd, sizeof(cmd), 10) != HAL_OK) - { - ERROR("Read EEPROM transmit failed"); - return false; - } - - uint8_t buffer[BLOCK_SIZE + 10]; - - if (HAL_UART_Receive(&huart3, buffer, BLOCK_SIZE + 10, 1000) != HAL_OK) - { - ERROR("Read EEPROM receive failed"); - return false; - } - - for (size_t i = 0; i != BLOCK_SIZE; i += 16) { - printf("%04X: ", addr + i); - for (size_t j = 0; j != 16; j++) { - printf("%02X ", buffer[i + j + 10]); - } - printf("\r\n"); - HAL_Delay(10); - } - } - return true; } -bool exit_program_mode() +/** + * Exit BM78 EEPROM programming mode and return to pass-through mode. + * + * This asserts EAN on the BM78 and resets the module to exit EEPROM + * programming mode, reconfigures the UART for HW flow control, then + * waits for the module to become ready. + */ +void exit_program_mode() { - auto result = true; - - // Read (cmd = 0x29) all 1K bytes, starting at address 0, 128 bytes at a time. - uint8_t cmd[] = {0x01, 0x29, 0xfc, 0x03, 0x00, 0x00, 0x80}; - - constexpr const uint16_t BLOCK_SIZE = 128; - - for (uint16_t addr = 0; addr != 0x500; addr += BLOCK_SIZE) - { - cmd[5] = addr & 0xFF; - cmd[4] = (addr >> 8) & 0xFF; - if (HAL_UART_Transmit(&huart3, cmd, sizeof(cmd), 10) != HAL_OK) - { - ERROR("Read EEPROM transmit failed"); - result = false; - break; - } - - uint8_t buffer[BLOCK_SIZE + 10]; - - if (HAL_UART_Receive(&huart3, buffer, BLOCK_SIZE + 10, 1000) != HAL_OK) - { - ERROR("Read EEPROM receive failed"); - result = false; - break; - } - - for (size_t i = 0; i != BLOCK_SIZE; i += 16) { - printf("%04X: ", addr + i); - for (size_t j = 0; j != 16; j++) { - int c = buffer[i + j + 10]; - printf(" %c ", isprint(c) ? (char) c : '.'); - } - printf("\r\n"); - printf("%04X: ", addr + i); - for (size_t j = 0; j != 16; j++) { - printf("%02X ", buffer[i + j + 10]); - } - printf("\r\n"); - HAL_Delay(10); - } - } - - - // Ensure we start out disconnected. gpio::BT_CMD::on(); HAL_Delay(10); gpio::BT_RESET::off(); HAL_Delay(1); // Spec says minimum 63ns. gpio::BT_RESET::on(); - HAL_Delay(400); // Spec says 354ms. huart3.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS; huart3.Init.BaudRate = 115200; @@ -181,21 +98,32 @@ bool exit_program_mode() CxxErrorHandler(); } - return result; -} - -bool set_reset() -{ - return true; + bm78_wait_until_ready(); } +/** + * Parse the result of the previous write. Return true if the write was + * successful and false if either the response could not be read or the + * write failed. + * + * @pre A block of EEPROM data was written to the BM78. + * @post The write response has been written. + * + * The result of the write is 7 bytes in length. The write was successful + * if the last byte returned is a 0. + * + * @param function is the name of the calling function and is used when + * logging to indicate which write operation failed. + * @return true when the write was successful, otherwise false. + */ bool parse_write_result(const char* function) { uint8_t result[7]; - if (HAL_UART_Receive(&huart3, result, sizeof(result), 1000) != HAL_OK) + HAL_StatusTypeDef status; + if ((status = HAL_UART_Receive(&huart3, result, sizeof(result), 1000)) != HAL_OK) { - ERROR("%s receive failed", function); + ERROR("%s receive failed (%d)", function, status); return false; } @@ -207,7 +135,79 @@ bool parse_write_result(const char* function) } return result[6] == 0; +} +/** + * Parse the EEPROM data and write the segments to the BM78 EEPROM. + * + * @pre The BM78 is in programming mode. + * @post The BM78 is programmed. + * + * The data from the EEPROM programming UI is a sparsely populated memory + * map. That data has been converted into
format + * in the eeprom_data block. The last block has a zero length, indicating + * EOF. The address is two bytes, big endian, followed by a one byte + * length and *length* bytes of data. + * + * It is important that memory areas that are not populated by the UI are + * not overwritten as they may contain device-specific data elements. For + * example, the first 6 bytes of data are the Bluetooth device MAC address. + * + * The write command is 7 bytes long. The first three bytes are static: + * {0x01, 0x27, 0xfc}. The 4th byte is *length* + 3. The 5th and 6th + * are the address, and the 7th is *length*. The data to be written + * follows. + * + * Once the data has been written, the BM78 module sends a response. This + * must be read and parse before the next block is written. + * + * @return true if the BM78 is programmed, otherwise false. + */ +bool write_eeprom() +{ + const uint8_t* data = eeprom_data; + + uint8_t cmd[] = {0x01, 0x27, 0xfc, 0x00, 0x00, 0x00, 0x00}; + + bool result = true; + while (result) + { + auto len = data[2]; + + cmd[0] = 0x01; + cmd[1] = 0x27; + cmd[2] = 0xfc; + cmd[3] = len + 3; + cmd[4] = data[0]; + cmd[5] = data[1]; + cmd[6] = len; + + if (len == 0) + break; + + data += 3; + + if (HAL_UART_Transmit(&huart3, cmd, sizeof(cmd), 1000) != HAL_OK) + { + ERROR("%s transmit header failed", __PRETTY_FUNCTION__); + return false; + } + + if (HAL_UART_Transmit(&huart3, const_cast(data), len, 1000) != HAL_OK) + { + ERROR("%s transmit data failed", __PRETTY_FUNCTION__); + return false; + } else { + DEBUG("%s transmit succeeded %d bytes at 0x%02X%02X", + __FUNCTION__, cmd[6], cmd[4], cmd[5]); + } + + result = parse_write_result(__PRETTY_FUNCTION__); + + data += len; + } + + return result; } bool set_name() @@ -331,7 +331,7 @@ bool set_le_attribute_properties() if (HAL_UART_Transmit(&huart3, cmd, sizeof(cmd), 10) != HAL_OK) { - ERROR("set_le_attribute_properties transmit failed"); + ERROR("%s transmit failed", __PRETTY_FUNCTION__); return false; } @@ -429,12 +429,47 @@ bool set_reliable() }}} // mobilinkd::tnc::bm78 +void bm78_wait_until_ready() +{ + auto start = HAL_GetTick(); + // Must wait until P1_5 (BT_STATE2) is high and P0_4 (BT_STATE1) is low. + GPIO_PinState bt_state1, bt_state2; + do { + if (HAL_GetTick() > start + 2000) CxxErrorHandler(); // Timed out. + + HAL_Delay(100); + bt_state2 = HAL_GPIO_ReadPin(BT_STATE2_GPIO_Port, BT_STATE2_Pin); + bt_state1 = HAL_GPIO_ReadPin(BT_STATE1_GPIO_Port, BT_STATE1_Pin); + DEBUG("bt_state2=%d, bt_state1=%d", bt_state2, bt_state1); + } while (!((bt_state2 == GPIO_PIN_SET) and (bt_state1 == GPIO_PIN_RESET))); +} + +uint32_t eeprom_crc() +{ + const uint8_t* data = eeprom_data; + + while (true) + { + data++; + data++; + auto len = *data++; + if (!len) break; + data += len; + } + + uint32_t size = data - eeprom_data; + + return HAL_CRC_Calculate(&hcrc, (uint32_t*)eeprom_data, size); +} + int bm78_initialized() { using namespace mobilinkd::tnc; using namespace mobilinkd::tnc::bm78; - return HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) == BT_INIT_MAGIC; + auto crc = eeprom_crc(); + + return HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) == crc; } int bm78_initialize() @@ -444,34 +479,18 @@ int bm78_initialize() int result = 0; - if (!enter_program_mode()) result = 1; - else if (!set_name()) result = 2; - else if (!set_pin()) result = 3; - else if (!set_misc()) result = 4; - else if (!configure_le_service()) result = 5; + enter_program_mode(); + if (!write_eeprom()) result = 1; exit_program_mode(); -#if 0 - bt_status_init(); - - if (not enter_command_mode()) result = 1; - else if (not set_uart()) result = 4; - else if (not set_work()) result = 7; - else if (not set_power()) result = 8; - else if (not set_secure()) result = 9; - else if (not set_gpio()) result = 3; - else if (not set_name()) result = 2; - else if (not set_reset()) result = 10; - exit_command_mode(); #if 1 if (result == 0) { - /* Write BT_INIT_MAGIC to RTC back-up register RTC_BKP_DR1 to indicate - that the HC-05 module has been initialized. */ + /* Write CRC to RTC back-up register RTC_BKP_DR1 to indicate + that the BM78 module has been initialized. */ HAL_PWR_EnableBkUpAccess(); - HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, BT_INIT_MAGIC); + HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, eeprom_crc()); HAL_PWR_DisableBkUpAccess(); } -#endif #endif return result; } diff --git a/TNC/bm78.h b/TNC/bm78.h index a7367b3..c55a43c 100644 --- a/TNC/bm78.h +++ b/TNC/bm78.h @@ -14,6 +14,19 @@ extern "C" { #include #endif +/** + * The BM78 module says that the module is ready about 475ms after start, + * but that the proper thing to do is wait until P1_5 (BT_STATE2) is high + * and P0_4 (BT_STATE1) is low. + * + * This waits for the module to reach this state. If it fails to become + * ready after 2 seconds, it enters the error handler. + * + * @note This does not work to detect whether the module is ready for + * EEPROM programming, only for transparent data mode. The time required + * and state indication for EEPROM programming mode is not specified. + */ +void bm78_wait_until_ready(void); void bm78_state_change(void); int bm78_disable(void); int bm78_enable(void); diff --git a/TNC/bm78_eeprom.cpp b/TNC/bm78_eeprom.cpp new file mode 100644 index 0000000..d9c39d5 --- /dev/null +++ b/TNC/bm78_eeprom.cpp @@ -0,0 +1,106 @@ + +#include "bm78_eeprom.hpp" + +const uint8_t eeprom_data[] = { + 0x00, 0x07, 0x03, 0x04, 0x04, 0x24, 0x00, 0x0b, + 0x10, 0x54, 0x4e, 0x43, 0x33, 0x20, 0x4d, 0x6f, + 0x62, 0x69, 0x6c, 0x69, 0x6e, 0x6b, 0x64, 0x00, + 0x00, 0x00, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x01, 0x10, + 0x00, 0x31, 0x01, 0x03, 0x00, 0x3b, 0x01, 0x02, + 0x00, 0x56, 0x02, 0x11, 0x11, 0x00, 0x5b, 0x10, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xad, 0x06, 0xc1, 0x0c, 0x08, 0x1b, 0x21, + 0x00, 0x01, 0xb6, 0x02, 0x03, 0x20, 0x01, 0xba, + 0x07, 0x19, 0x00, 0x0c, 0xff, 0xff, 0x01, 0x01, + 0x01, 0xc2, 0x02, 0x00, 0x00, 0x01, 0xc5, 0x0b, + 0x03, 0x0c, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x02, 0x1f, 0x40, 0x01, 0xd4, 0x10, 0xba, 0xb0, + 0x00, 0x08, 0x01, 0x90, 0x00, 0x02, 0x02, 0x00, + 0x01, 0x00, 0x06, 0x01, 0x03, 0x00, 0x01, 0xe4, + 0x02, 0x00, 0x00, 0x01, 0xea, 0x08, 0x1f, 0x18, + 0x10, 0x0b, 0x22, 0x05, 0x05, 0x05, 0x01, 0xf3, + 0x02, 0x05, 0x05, 0x01, 0xf6, 0x04, 0x00, 0x01, + 0x01, 0x01, 0x01, 0xfb, 0x02, 0x02, 0x01, 0x01, + 0xfe, 0x04, 0x00, 0x03, 0x02, 0x03, 0x02, 0x03, + 0x02, 0x04, 0x02, 0x02, 0x06, 0x04, 0x00, 0x01, + 0x03, 0x02, 0x02, 0x0b, 0x02, 0x03, 0x01, 0x02, + 0x0e, 0x04, 0x00, 0x3c, 0x1e, 0x1e, 0x02, 0x13, + 0x02, 0x1e, 0x1e, 0x02, 0x17, 0x10, 0x0e, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x6e, 0x6b, 0x64, + 0x20, 0x54, 0x4e, 0x43, 0x33, 0x00, 0x02, 0x27, + 0x10, 0x00, 0x43, 0x36, 0x50, 0x36, 0x34, 0x4a, + 0x32, 0x4d, 0x5a, 0x58, 0x54, 0x4e, 0x43, 0x33, + 0x00, 0x02, 0x37, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x42, 0x10, 0x41, 0x42, 0x42, 0x41, 0x41, 0x42, + 0x42, 0x41, 0x41, 0x42, 0x42, 0x41, 0x41, 0x42, + 0x42, 0x41, 0x02, 0x52, 0x10, 0x00, 0x39, 0x50, + 0x56, 0x01, 0x00, 0x00, 0x01, 0x43, 0x68, 0x61, + 0x74, 0x62, 0x6f, 0x61, 0x72, 0x02, 0x62, 0x10, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x49, 0x53, + 0x02, 0x72, 0x10, 0x53, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x42, 0x4d, 0x02, 0x82, 0x0e, 0x37, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x10, 0x63, + 0x6f, 0x6d, 0x2e, 0x69, 0x73, 0x73, 0x63, 0x2e, + 0x64, 0x61, 0x74, 0x61, 0x70, 0x61, 0x74, 0x02, + 0xb0, 0x10, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0xc0, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xd0, 0x10, + 0x63, 0x6f, 0x6d, 0x2e, 0x69, 0x73, 0x73, 0x63, + 0x2d, 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x00, + 0x02, 0xe0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0xf0, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x10, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x6e, + 0x6b, 0x64, 0x20, 0x4c, 0x4c, 0x43, 0x00, 0x00, + 0x00, 0x03, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x38, 0x36, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x10, 0x54, + 0x4e, 0x43, 0x33, 0x00, 0x00, 0x01, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x30, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x40, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x50, 0x10, + 0x00, 0x00, 0x00, 0x00, 0xbb, 0x68, 0x1f, 0x96, + 0xb0, 0x01, 0x49, 0xae, 0xc9, 0x46, 0x2a, 0xba, + 0x03, 0x60, 0x10, 0x01, 0x00, 0x00, 0x00, 0xbb, + 0x68, 0x1f, 0x96, 0xb0, 0x01, 0x49, 0xae, 0xc9, + 0x46, 0x2a, 0xba, 0x03, 0x70, 0x10, 0x03, 0x00, + 0x00, 0x00, 0xbb, 0x68, 0x1f, 0x96, 0xb0, 0x01, + 0x49, 0xae, 0xc9, 0x46, 0x2a, 0xba, 0x03, 0x80, + 0x10, 0x02, 0x00, 0x00, 0x00, 0x10, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x04, 0x03, 0x90, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xa0, 0x10, 0x1b, + 0x05, 0x08, 0x54, 0x4e, 0x43, 0x33, 0x11, 0x06, + 0xbb, 0x68, 0x1f, 0x96, 0xb0, 0x01, 0x49, 0x03, + 0xb0, 0x10, 0xae, 0xc9, 0x46, 0x2a, 0xba, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x01, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xc0, 0x10, 0x03, 0x02, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd0, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xe0, 0x10, 0x03, 0x02, 0x01, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xf0, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xf0, 0x10, 0x54, 0x4e, 0x43, + 0x33, 0x20, 0x32, 0x2e, 0x31, 0x2e, 0x31, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; diff --git a/TNC/bm78_eeprom.hpp b/TNC/bm78_eeprom.hpp new file mode 100644 index 0000000..f130102 --- /dev/null +++ b/TNC/bm78_eeprom.hpp @@ -0,0 +1,8 @@ +// Copyright 2018 Rob Riggs +// All rights reserved. + +#include + +extern "C" { +extern const uint8_t eeprom_data[]; +} diff --git a/bm78_eeprom b/bm78_eeprom new file mode 100644 index 0000000..cceb328 --- /dev/null +++ b/bm78_eeprom @@ -0,0 +1,59 @@ +# ADDR1 ADDR2 LEN DATA... +00 07 03 04 04 24 # Class of Device +00 0B 10 54 4E 43 33 20 4D 6F 62 69 6C 69 6E 6B 64 00 00 +00 1B 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 2B 01 10 +00 31 01 03 +00 3B 01 02 +00 56 02 11 11 +00 5B 10 31 32 33 34 35 36 00 00 00 00 00 00 00 00 00 00 +01 AD 06 C1 0C 08 1B 21 00 +01 B6 02 03 20 +01 BA 07 19 00 0C FF FF 01 01 +01 C2 02 00 00 +01 C5 0B 03 0C 00 00 08 00 08 00 02 1F 40 +01 D4 10 BA B0 00 08 01 90 00 02 02 00 01 00 06 01 03 00 +01 E4 02 00 00 +01 EA 08 1F 18 10 0B 22 05 05 05 +01 F3 02 05 05 +01 F6 04 00 01 01 01 +01 FB 02 02 01 +01 FE 04 00 03 02 03 +02 03 02 04 02 +02 06 04 00 01 03 02 +02 0B 02 03 01 +02 0E 04 00 3C 1E 1E +02 13 02 1E 1E +02 17 10 0E 4D 6F 62 69 6C 69 6E 6B 64 20 54 4E 43 33 00 +02 27 10 00 43 36 50 36 34 4A 32 4D 5A 58 54 4E 43 33 00 +02 37 0B 00 00 00 00 00 00 00 00 00 00 00 +02 42 10 41 42 42 41 41 42 42 41 41 42 42 41 41 42 42 41 # Serial Number (can base64 encode the CPUID) +02 52 10 00 39 50 56 01 00 00 01 43 68 61 74 62 6F 61 72 +02 62 10 64 00 00 00 00 00 00 00 01 00 00 01 00 00 49 53 +02 72 10 53 43 00 00 00 00 00 00 00 00 00 00 00 00 42 4D +02 82 0E 37 38 00 00 00 00 00 00 00 00 00 00 00 00 +02 A0 10 63 6F 6D 2E 69 73 73 63 2E 64 61 74 61 70 61 74 +02 B0 10 68 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +02 C0 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +02 D0 10 63 6F 6D 2E 69 73 73 63 2D 74 65 63 68 00 00 00 +02 E0 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +02 F0 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +03 00 10 4D 6F 62 69 6C 69 6E 6B 64 20 4C 4C 43 00 00 00 +03 10 10 00 00 00 00 30 38 36 30 00 00 00 00 00 00 00 00 +03 20 10 54 4E 43 33 00 00 01 00 04 00 00 00 00 00 00 00 +03 30 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +03 40 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +03 50 10 00 00 00 00 BB 68 1F 96 B0 01 49 AE C9 46 2A BA +03 60 10 01 00 00 00 BB 68 1F 96 B0 01 49 AE C9 46 2A BA +03 70 10 03 00 00 00 BB 68 1F 96 B0 01 49 AE C9 46 2A BA +03 80 10 02 00 00 00 10 0C 00 00 00 00 00 00 00 01 00 04 +03 90 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +03 A0 10 1B 05 08 54 4E 43 33 11 06 BB 68 1F 96 B0 01 49 +03 B0 10 AE C9 46 2A BA 01 00 00 00 02 01 02 00 00 00 00 +03 C0 10 03 02 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 +03 D0 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +03 E0 10 03 02 01 06 00 00 00 00 00 00 00 00 00 00 00 00 +03 F0 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +04 00 09 01 00 00 00 00 00 00 00 00 +04 F0 10 54 4E 43 33 20 32 2E 31 2E 31 00 00 00 00 00 00 +00 00 00 diff --git a/make_bm78_eeprom_c.py b/make_bm78_eeprom_c.py new file mode 100755 index 0000000..8bbe21f --- /dev/null +++ b/make_bm78_eeprom_c.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python + +import sys +import re + +regex = re.compile("^([0-9A-Fa-f]{2}\s){3}([0-9A-Fa-f]{2}\s?)*(#.*)?$") + +bytes = [] + +for line in sys.stdin: + atoms = re.split("\s+", line) + for atom in atoms: + if len(atom) == 0 or atom == '#': + break + bytes.append(int(atom, 16)) + +chunks = [bytes[i:i+8] for i in range(0, len(bytes), 8)] + +print("#include ") +print("const uint8_t eeprom_data[] = {") +for chunk in chunks: + s = ", ".join(['0x{:02x}'.format(x) for x in chunk]) + print(" {},".format(s)) +print("};") + +