Skip to content

Commit

Permalink
Merge pull request #27 from ramonaoptics/eeprom
Browse files Browse the repository at this point in the history
Eeprom and serial number
  • Loading branch information
hmaarrfk authored Jan 4, 2024
2 parents 7cbde9c + 702f5d8 commit 0779adc
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 3 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
name: Build Firmware
on: [push, pull_request]
on:
push:
branches:
- main
pull_request:

jobs:
build:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
### 0.4.0 (2024/01/04)

* Provide EEPROM commands.
* Provide a method for the Teensy to read it's own USB Serial Number back to
the device through the USB interface.

### 0.3.0 (2023/11/06)

* Increase the maximum analog pulse duration to 3 minutes.
Expand Down
1 change: 1 addition & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ platform = teensy
board = teensy31
framework = arduino
board_build.f_cpu = 96000000L
upload_protocol = teensy-cli
lib_deps =
https://github.com/nox771/i2c_t3.git
build_flags =
Expand Down
22 changes: 22 additions & 0 deletions src/commandconstants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ int info_func(CommandRouter *cmd, int argc, const char **argv);
int reboot_func(CommandRouter *cmd, int argc, const char **argv);
int version_func(CommandRouter *cmd, int argc, const char **argv);
int mcu_func(CommandRouter *cmd, int argc, const char **argv);
int serialnumber_func(CommandRouter *cmd, int argc, const char **argv);
int command_license_func(CommandRouter *cmd, int argc, const char **argv);

// Digital GPIO
Expand Down Expand Up @@ -58,12 +59,21 @@ int register_read_uint16(CommandRouter *cmd, int argc, const char **argv);
int register_write_uint16(CommandRouter *cmd, int argc, const char **argv);
int register_read_uint32(CommandRouter *cmd, int argc, const char **argv);
int register_write_uint32(CommandRouter *cmd, int argc, const char **argv);

int eeprom_length(CommandRouter *cmd, int argc, const char **argv);
int eeprom_read_uint8(CommandRouter *cmd, int argc, const char **argv);
int eeprom_write_uint8(CommandRouter *cmd, int argc, const char **argv);
int eeprom_update_uint8(CommandRouter *cmd, int argc, const char **argv);
int eeprom_read_string(CommandRouter *cmd, int argc, const char **argv);
int eeprom_write_string(CommandRouter *cmd, int argc, const char **argv);

// Syntax is: {short command, description, syntax}
const command_item_t command_list[] = {
{"?", "Display help info", "?", command_help_func},
{"info", "Displays information about this TeensyToAny device", "about", info_func},
{"reboot", "Runs setup routine again, for this device.", "reboot", reboot_func},
{"mcu", "Displays information about the microcontroller board.", "mcu", mcu_func},
{"serialnumber", "Displays the serial number of the board.", "serialnumber", serialnumber_func},
{"license",
"Display the license information for the source code running on the "
"teensy",
Expand Down Expand Up @@ -162,5 +172,17 @@ const command_item_t command_list[] = {
"register_read_uint32 address", register_read_uint32},
{"register_write_uint32", "Write to an arbitrary hardware register.",
"register_write_uint32 address data", register_write_uint32},
{"eeprom_length", "Return the size of the of the EEPROM in bytes.",
"eeprom_length", eeprom_length},
{"eeprom_read_uint8", "Read data from a given EEPROM address.",
"eeprom_read_uint8 address", eeprom_read_uint8},
{"eeprom_write_uint8", "Write to an EEPROM address.",
"eeprom_write_uint8 address data", eeprom_write_uint8},
{"eeprom_update_uint8", "Write to an EEPROM address if the value has changed.",
"eeprom_update_uint8 address data", eeprom_update_uint8},
{"eeprom_read_string", "Read data from a given EEPROM address.",
"eeprom_read_string address", eeprom_read_string},
{"eeprom_write_string", "Write to an EEPROM address.",
"eeprom_write_string address data", eeprom_write_string},
{nullptr, nullptr, nullptr, nullptr},
};
170 changes: 170 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <Arduino.h>
#include <SPI.h>
#include <errno.h>
#include <usb_names.h>
#include <EEPROM.h>

// TODO: this isn't exactly correct since this main file won't get
// regenerated if it wasn't touched.
Expand Down Expand Up @@ -73,6 +75,23 @@ int version_func(CommandRouter *cmd, int argc, const char **argv) {
return 0;
}

int serialnumber_func(CommandRouter *cmd, int argc, const char **argv) {
(void)argc;
(void)argv;
uint8_t i;
// https://github.com/PaulStoffregen/cores/pull/722
#pragma GCC diagnostic push
// https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html
#pragma GCC diagnostic ignored "-Warray-bounds"
for (i=0; i < (usb_string_serial_number.bLength - 2) / sizeof(uint16_t); i++) {
cmd->buffer[i] = (char)usb_string_serial_number.wString[i];
}
#pragma GCC diagnostic pop
cmd->buffer[i] = '\0';
return 0;
}


int mcu_func(CommandRouter *cmd, int argc, const char **argv) {
(void)argc;
(void)argv;
Expand Down Expand Up @@ -859,6 +878,157 @@ int register_read_uint32(CommandRouter *cmd, int argc, const char **argv) {
return 0;
}

int eeprom_length(CommandRouter *cmd, int argc, const char **argv) {
if (argc != 1) {
return EINVAL;
}

uint16_t length = EEPROM.length();

snprintf(cmd->buffer, cmd->buffer_size, "0x%04X", length);

return 0;
}

int eeprom_read_uint8(CommandRouter *cmd, int argc, const char **argv) {
if (argc != 2) {
return EINVAL;
}
int index;
uint8_t data;

index = strtol(argv[1], nullptr, 0);
if (index > EEPROM.length()) {
return EINVAL;
}

data = EEPROM.read(index);

snprintf(cmd->buffer, cmd->buffer_size, "0x%02X", data);

return 0;
}

int eeprom_write_uint8(CommandRouter *cmd, int argc, const char **argv) {
if (argc != 3) {
return EINVAL;
}
int index;
uint8_t data;

index = strtol(argv[1], nullptr, 0);
data = strtol(argv[2], nullptr, 0);
if (index > EEPROM.length()) {
return EINVAL;
}

EEPROM.write(index, data);

return 0;
}

int eeprom_update_uint8(CommandRouter *cmd, int argc, const char **argv) {
if (argc != 3) {
return EINVAL;
}
int index;
uint8_t data;

index = strtol(argv[1], nullptr, 0);
data = strtol(argv[2], nullptr, 0);
if (index > EEPROM.length()) {
return EINVAL;
}

/*
The function EEPROM.update(address, val) is equivalent to the following:
if( EEPROM.read(address) != val ){
EEPROM.write(address, val);
}
*/
EEPROM.update(index, data);

return 0;
}

int eeprom_read_string(CommandRouter *cmd, int argc, const char **argv) {
if (argc < 2 || argc > 3) {
return EINVAL;
}
int index, i;
int n_read;
char data;

index = strtol(argv[1], nullptr, 0);
if (index > EEPROM.length()) {
return EINVAL;
}
if (argc >= 3) {
n_read = strtol(argv[2], nullptr, 0);
} else {
n_read = EEPROM.length() - index;
}

if (index + n_read > EEPROM.length()) {
return EINVAL;
}

for(i=0; i < n_read; i++, index++){
data = (char) EEPROM.read(index);

if (data == '\0') {
break;
}

cmd->buffer[i] = data;
}
// Terminate, always, even if we "got to the end of EEPROM's length
cmd->buffer[i] = '\0';

return 0;
}

int eeprom_write_string(CommandRouter *cmd, int argc, const char **argv) {
if (argc < 3) {
return EINVAL;
}
int index, i;
int data_length;
const char* data;

index = strtol(argv[1], nullptr, 0);
if (index > EEPROM.length()) {
return EINVAL;
}

// We compute the length of the string "joined" by spaces
data_length = argc - 3;
for (i=2; i < argc; i++) {
data = argv[2];
data_length += strlen(data);
}

if (index + data_length >= EEPROM.length()) {
return EINVAL;
}

for (int j=2; j < argc; j++) {
data = argv[j];
if (j != 2) {
EEPROM.update(index, ' ');
++index;
}
for(i=0; data[i] != '\0'; i++, index++){
EEPROM.update(index, data[i]);
}
}
EEPROM.update(index, '\0');

return 0;
}



void loop() {
// TODO: remove this check on if Serial is available.
Expand Down
4 changes: 2 additions & 2 deletions versioneer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

revision = subprocess.check_output(["git", "describe", "--tags", "--dirty"]).strip()
revision = revision.decode()
revision = revision.replace('-dirty', '+dirty', 1)
revision = revision.replace('-', '.post', 1)
revision = revision.replace('-dirty', '.dirty', 1)
revision = revision.replace('-', '.dev', 1)
revision = revision.replace('-g', '+g', 1)

print('-DGIT_DESCRIBE=\'"%s"\'' % revision)

0 comments on commit 0779adc

Please sign in to comment.