inital commit

This commit is contained in:
matthias@arch 2023-06-13 19:59:34 +02:00
parent efece36694
commit 3cffc98fe7
7 changed files with 442 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*build*

104
teng/address.hpp Normal file
View File

@ -0,0 +1,104 @@
#pragma once
#include <Arduino.h>
class Counter {
public:
const unsigned MAX_NUMBER = 4096; // 12-bit
const int RES = 18;
const int CB = 19;
void reset() {
digitalWrite(CB, HIGH);
digitalWrite(RES, HIGH);
delay(1);
digitalWrite(RES, LOW);
currentValue = 0;
}
/**
* @brief Increment the counter value
* @returns true if overflown to zero
*/
bool increment() {
digitalWrite(CB, LOW);
delay(1);
digitalWrite(CB, HIGH);
currentValue++;
if (currentValue >= MAX_NUMBER) {
currentValue = 0;
return true;
}
return false;
}
unsigned get() { return currentValue; }
private:
unsigned currentValue = 0;
};
class AddressState {
public:
AddressState(Counter counter_, int addressPinCount_, const int* addressPins_)
: counter(counter_), addressPinCount(addressPinCount_), addressPins(addressPins_) {
counter.reset();
}
void set(unsigned targetAddress) {
unsigned targetCounterValue = targetAddress % counter.MAX_NUMBER;
if (counter.get() > targetCounterValue) {
counter.reset();
}
for (unsigned i = 0; i < (targetCounterValue - counter.get()); i++) {
counter.increment();
}
unsigned pinValues = targetAddress / counter.MAX_NUMBER;
addressPinStateMask = 0;
for (unsigned i = 0; i < addressPinCount; i++) {
unsigned bitSet = pinValues & (1 << i);
if (bitSet > 0) {
digitalWrite(addressPins[i], HIGH);
addressPinStateMask |= (1 << (addressPins[i] - 1));
}
else {
digitalWrite(addressPins[i], LOW);
}
}
address = targetAddress;
}
void increment() {
if (counter.increment()) { // if overflow
// add 1 to the other pins
for (unsigned i = 0; i < addressPinCount; i++) {
if ((addressPinStateMask & (addressPins[i] - 1)) == 0) {
addressPinStateMask |= (1 << (addressPins[i] - 1));
digitalWrite(addressPins[i], HIGH);
break;
}
else {
addressPinStateMask ^= (1 << (addressPins[i] - 1));
digitalWrite(addressPins[i], LOW);
}
}
}
address++;
}
unsigned getAddress() { return address; }
unsigned reset() {
counter.reset();
for (unsigned i = 0; i < addressPinCount; i++) {
digitalWrite(addressPins[i], LOW);
}
}
private:
// if counter is 12 bit and address is 16 bit, this is the value of the top 4 bits
// i-th bit represents i-th pin
unsigned addressPinStateMask = 0;
unsigned address = 0;
Counter counter;
const int* addressPins;
int addressPinCount;
};

7
teng/control_bytes.hpp Normal file
View File

@ -0,0 +1,7 @@
#pragma once
const char CTRL_WRITE = 1;
const char CTRL_READ = 2;
const char CTRL_256KB = 11;
const char CTRL_2M = 14;

70
teng/eeprom.hpp Normal file
View File

@ -0,0 +1,70 @@
#pragma once
#include <Arduino.h>
#include "address.hpp"
class EEPROM {
public:
void setup() {
for (unsigned i = 0; i < addressPinCount; i++) {
pinMode(addressPins[i], OUTPUT);
}
for (unsigned i = 0; i < 8; i++) {
pinMode(dataPins[i], INPUT);
}
pinMode(OEb, OUTPUT);
pinMode(WEb, OUTPUT);
}
/**
* @brief Read the data pins.
*/
uint8_t readDataPins() {
uint8_t b = 0;
for (unsigned i = 0; i < 8; i++) {
b |= (digitalRead(dataPins[i]) << i);
}
return b;
}
// set start address in via AddressState
void read(uint8_t* data, unsigned dataSize, AddressState& address) {
unsigned i = 0;
for (unsigned i = 0; i < dataSize; i++) {
digitalWrite(OEb, LOW);
delay(t_OUTPUT_DELAY);
data[i] = readDataPins();
digitalWrite(OEb, HIGH);
delay(t_OUTPUT_FLOAT);
address.increment();
}
}
/* private: */
int OEb;
int WEb;
int addressPins[6];
unsigned addressPinCount;
int dataPins[8] = { 2, 3, 4, 5, 6, 7, 8, 9 };
// in ms
unsigned t_OUTPUT_DELAY = 1;
unsigned t_MIN_WRITE_PULSE_WIDTH = 1;
unsigned t_OUTPUT_FLOAT = 1;
unsigned t_DATA_HOLD_TIME = 0;
};
constexpr EEPROM AT28C256 {
.OEb = 17,
.WEb = 16,
.addressPins = {10, 15, 11},
.addressPinCount = 3
};
constexpr EEPROM SST39SF02A {
.OEb = 17,
.WEb = 16,
.addressPins = {10, 15, 16, 11, 12, 14},
.addressPinCount = 6
};

23
teng/packet.hpp Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <vector>
#include <cstdint>
enum PacketType : uint8_t {
MESSAGE, STATUS, COMMAND
};
struct Packet {
public:
using size_type = uint16_t;
Packet(PacketType type, size_type size)
: type(type), size(size) {
payload = new uint8_t[size];
}
~Packet() {
delete[] payload;
}
uint8_t type;
size_type size;
uint8_t* payload;
};

6
teng/sketch.yaml Normal file
View File

@ -0,0 +1,6 @@
profiles:
nanorp:
fqbn: arduino:mbed_nano:nanorp2040connect
platforms:
- platform: arduino:mbed_nano (4.0.2)
libraries:

231
teng/teng.ino Normal file
View File

@ -0,0 +1,231 @@
/*
* EEPROM PROGRAMMER
* 15-18 Address Pins
* 8 Data Pins
* 2 Control Pins (OEb, WEb)
*
* CEb must tied to ground
*/
#include <Arduino.h>
#include <ArduinoBLE.h>
/* #include "eeprom.hpp" */
/* #include "address.hpp" */
/* #include "control_bytes.hpp" */
constexpr int LED_RED = 2;
constexpr int LED_YELLOW = 3;
constexpr int LED_GREEN = 4;
constexpr int PIN_TENG = 0;
/* void maskedWrite(uint32_t mask, uint32_t bits) { */
/* for (uint32_t i = 0; i < 32; i++) { */
/* if (mask & (1 << i)) { */
/* digitalWrite(i, bits & (1 << i)); */
/* } */
/* } */
/* } */
void blinkLED(unsigned n=5, unsigned delay_=200) {
for (unsigned i = 0; i < n; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(delay_);
digitalWrite(LED_BUILTIN, LOW);
delay(delay_);
}
}
unsigned MAX_DEVIATION = 0;
unsigned BASELINE = 0;
void measureBaseline(unsigned nMeas, unsigned interval=50) {
uint64_t value = 0;
unsigned minVal = 1023;
unsigned maxVal = 0;
for (unsigned i = 0; i < nMeas; i++) {
unsigned reading = analogRead(PIN_TENG);
value += reading;
delay(interval);
if (reading > maxVal) { maxVal = reading; }
if (reading < minVal) { minVal = reading; }
}
BASELINE = value / nMeas;
if (BASELINE - minVal > maxVal - BASELINE) {
MAX_DEVIATION = BASELINE - minVal;
}
else {
MAX_DEVIATION = maxVal - BASELINE;
}
}
void setup() {
/* pinMode(LED_BUILTIN, OUTPUT); */
/* digitalWrite(LED_BUILTIN, HIGH); */
/* delay(200); */
Serial.begin(9600);
/* // wait until available */
while (!Serial);
digitalWrite(LED_BUILTIN, LOW);
delay(200); // empty buffer
while (Serial.read() != -1);
/* digitalWrite(LED_BUILTIN, HIGH); */
/* delay(5000); */
/* // reset counter */
/* blinkLED(); */
/* uint8_t payload[] = { 1, 2, 3, 4, 5, 69 }; */
/* uint8_t type = '#'; */
/* static_assert(sizeof(payload) == 6); */
/* uint16_t size = sizeof(payload); */
/* Serial.write(type); */
/* Serial.write(lowByte(size)); */
/* Serial.write(highByte(size));u */
/* Serial.write(payload, size); */
/* delay(5000); */
blinkLED(4);
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");
}
BLE.setDeviceName("ArduinoTeng");
BLE.advertise();
measureBaseline(100);
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_YELLOW, HIGH);
digitalWrite(LED_GREEN, HIGH);
delay(500);
digitalWrite(LED_RED, LOW);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_GREEN, LOW);
}
/* constexpr int max_val = 1023 / 5 * 3.5; // 1023 max val for 5V */
// the loop function runs over and over again forever
void loop() {
int led_red = LOW;
int led_yellow = LOW;
int led_green = LOW;
int val = analogRead(PIN_TENG);
Serial.print(val, DEC);
val -= BASELINE;
if (val < 0) { val = -val; }
Serial.print("/");
Serial.println(val, DEC);
if (val >= MAX_DEVIATION * 1) {
led_green = HIGH;
}
if (val >= MAX_DEVIATION * 2) {
led_yellow = HIGH;
}
if (val >= MAX_DEVIATION * 3) {
led_red = HIGH;
}
digitalWrite(LED_RED, led_red);
digitalWrite(LED_YELLOW, led_yellow);
digitalWrite(LED_GREEN, led_green);
delay(100);
/* // init address */
/* const int* addressPins = nullptr; */
/* unsigned addressPinCount = 0; */
/* // TODO pass eeprom via serial */
/* EEPROM eeprom = AT28C256; */
/* if (mem_size = CTRL_2M) { */
/* eeprom = SST39SF02A; */
/* } */
/* AddressState address(Counter(), eeprom.addressPinCount, eeprom.addressPins); */
/* const int dataSize = 0x8000; */
/* uint8_t data[dataSize]; */
/* while (true) { */
/* } */
/* if (!Serial.available()) { continue; } */
/* // read packet */
/* uint8_t type = Serial.read(); */
/* uint16_t size = Serial.read(); // low byte */
/* size |= (Serial.read() << 8); // high byte */
/* Packet packet(type, size); */
/* Serial.readBytes(packet.payload, size); */
/* switch(type) { */
/* case PacketType::WRITE: { */
/* break; */
/* } */
/* case PacketType::READ: { */
/* break; */
/* } */
/* case PacketType::SET_ADDRESS { */
/* } */
/* default: { */
/* break; */
/* } */
/* } */
/* byte mem_size = 0; */
/* byte action = 0; */
/* byte x = 0; */
/* while (action == 0 || mem_size == 0) { */
/* digitalWrite(LED_BUILTIN, HIGH); */
/* if (Serial.available() <= 0) { */
/* blinkLED(3); */
/* } */
/* else { */
/* /1* while (Serial.available() > 0) { *1/ */
/* /1* Serial.write(Serial.read()); *1/ */
/* /1* } *1/ */
/* /1* Serial.write('\n'); *1/ */
/* Serial.write(static_cast<uint8_t>(Serial.available())); */
/* int cmd = Serial.read(); */
/* switch (cmd) { */
/* case CTRL_WRITE: */
/* case CTRL_READ: */
/* action = cmd; */
/* Serial.write('\0'); */
/* Serial.write('\0'); */
/* break; */
/* default: */
/* mem_size = cmd; */
/* Serial.write('\1'); */
/* Serial.write('\1'); */
/* } */
/* Serial.write(static_cast<uint8_t>(cmd)); */
/* Serial.write('\2'); */
/* Serial.write('\2'); */
/* } */
/* Serial.write(x); */
/* Serial.print('\n'); */
/* x++; */
/* delay(1000); */
/* digitalWrite(LED_BUILTIN, LOW); */
/* delay(1000); */
/* } */
/* if (action == CTRL_WRITE) { */
/* Serial.println("Write"); */
/* } */
/* else if (action == CTRL_READ) { */
/* Serial.println("Read"); */
/* eeprom.read(data, dataSize, address); */
/* Serial.write(data, dataSize); */
/* blinkLED(10); */
/* } */
}