From 8b308e04047afc40b6902a0362a46bc35911d378 Mon Sep 17 00:00:00 2001 From: phantomix Date: Tue, 26 Jul 2022 18:48:07 +0200 Subject: [PATCH] add Arduino source for TCS control. Porting is not finished yet, but it already opens the door periodically --- source/TcsBus.cpp | 121 ++++++++++++++++++++++++++++++++++++++++++++++ source/TcsBus.h | 28 +++++++++++ source/source.ino | 44 +++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 source/TcsBus.cpp create mode 100644 source/TcsBus.h create mode 100644 source/source.ino diff --git a/source/TcsBus.cpp b/source/TcsBus.cpp new file mode 100644 index 0000000..343a6a6 --- /dev/null +++ b/source/TcsBus.cpp @@ -0,0 +1,121 @@ +#include +#include "TcsBus.h" + +#define TCS_OVERSAMPLING 8 +#define TCS_BAUDRATE 475 + + +//tcs_bus datagrams +static const unsigned char acknowledge[] = {0,0,0,1,0,1,0,1,1,0}; +static const unsigned char ack_audio_on[] = {0,0,0,1,0,1,0,0,1,1,0,0}; +static const unsigned char doorbell[] = {0,0,0,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,0,0,1,1,0,0,1,0,1,0,1,0,1,0,0,1}; +static const unsigned char door_open[] = {0,0,0,1,0,1,0,1,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,0}; +static const unsigned char master_hmmmm[] = {0,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1}; +static const unsigned char pickup[] = {0,0,0,1,1,0,1,0,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,0,1,1,0,1,0,1,0,1,0,0,1,1,0,0,1,0,1,0,1,0,1,0,0}; + +//volatile uint8_t bitIndex = 25; +//const uint8_t datagram[] = { 0,0,0,1,0,1,0,1,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,0, 1 }; +static const unsigned char hang_up[] = {0,0,0,1,0,1,0,0,1,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0}; +static const unsigned char post_hang_up[] = {0,0,0,1,0,1,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,0}; +static const unsigned char light[] = {0,0,0,1,0,1,0,1,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,0}; + +TcsBus::TcsBus(int sendPin, int receivePin) : + sendPin { sendPin }, + receivePin { receivePin }, + state { SamplingState::IDLE }, + rxBits { 0 }, + oversamplingStep { 0 } +{ + +} +static hw_timer_t* timer = NULL; +static TcsBus* tcsInstance = NULL; +static void onTimer(void) +{ + tcsInstance->TimeBase(); +} + +static bool TimerSetup(TcsBus* inst) +{ + if(timer != NULL) return false; //already set up + + tcsInstance = inst; + //time base is 80 MHz, which will be divided by the value from timerBegin, and then + //a counter increments until it reaches the value from timerAlarmWrite. onTimer will then be fired as a callback. + //80000000 / 50 / 421 = 3800.47 Hz = 8 * 475.06 + timer = timerBegin(0, 50, true); + timerAttachInterrupt(timer, &onTimer, true); + timerAlarmWrite(timer, 421, true); + timerAlarmEnable(timer); + return true; +} + +void TcsBus::begin() +{ + //Pin setup + pinMode(receivePin, INPUT); + pinMode(sendPin, OUTPUT); + digitalWrite(sendPin, LOW); //disable sending for now +pinMode(0, OUTPUT); + TimerSetup(this); +} + +void TcsBus::TimeBase() +{ + static int tmp = 0; + static bool send = false; + static int sendIdx = 0; + static int over = 0; +tmp++; + + if(tmp == 3000) { + send = true; + sendIdx = 0; + over = 0; + } + + if(send) { + over++; + if(over == 8) { + over = 0; + if(sendIdx >= sizeof(door_open)) { + digitalWrite(sendPin, LOW); + send = false; + tmp = 0; + } else { + digitalWrite(sendPin, (door_open[sendIdx++]) ? LOW : HIGH); + } + } + } + + bool sample = digitalRead(receivePin); + + digitalWrite(0, sample == 0 ? LOW : HIGH); +return; + + switch(state) { + case SamplingState::IDLE: { + if(sample) { + state = SamplingState::RECEIVE; + } else { + break; + } + } //fall through + + case SamplingState::RECEIVE: { + + } break; + + case SamplingState::TRANSMIT: { + static int i = 0; + i++; + if(i == 1000) + { + digitalWrite(sendPin, HIGH); + } else if(i > 1000) { + digitalWrite(sendPin, LOW); + i = 0; + } + } break; + } +} \ No newline at end of file diff --git a/source/TcsBus.h b/source/TcsBus.h new file mode 100644 index 0000000..9e6de16 --- /dev/null +++ b/source/TcsBus.h @@ -0,0 +1,28 @@ +#ifndef TCS_BUS_H_ +#define TCS_BUS_H_ 1 +#include + +class TcsBus { +public: + TcsBus(int sendPin, int receivePin); + void begin(); + void TimeBase(); + +private: + int sendPin; + int receivePin; + + enum class SamplingState + { + IDLE = 0, + RECEIVE = 1, + TRANSMIT = 2, + }; + + SamplingState state; + uint16_t rxBits; + uint8_t oversamplingStep; + bool lastSample; +}; + +#endif //TCS_BUS_H_ \ No newline at end of file diff --git a/source/source.ino b/source/source.ino new file mode 100644 index 0000000..02418ee --- /dev/null +++ b/source/source.ino @@ -0,0 +1,44 @@ +#include +#include "TcsBus.h" + +#define PCA9554_ADDR 0x20 //PCA9554 = 0 1 0 0 a2 a1 a0 + +#define PIN_AUDIO_READ 0 +#define PIN_API_SWITCH 4 +#define PIN_TCS_READ 13 +#define PIN_TCS_SEND 14 +#define PIN_AUDIO_SEND 17 + +TcsBus tcs(PIN_TCS_SEND, PIN_TCS_READ); + +static uint32_t ms_old = 0; + +void setup() { + // put your setup code here, to run once: + Wire.begin(); + Serial.begin(115200); + + tcs.begin(); + + ms_old = millis(); +} + + +void i2cScan() { + for(uint8_t a = 0; a < 0x80; a++) { + Wire.beginTransmission(a); + byte error = Wire.endTransmission(); + if(!error) Serial.printf("i2cScan: found 0x%0x\n", a); + } +} + +void loop() { + uint32_t ms = millis(); + if(ms_old != ms) { + if(ms_old < ms) ms_old++; else ms_old = ms; //prevent overflow + + if(!(ms & 1023)) { + i2cScan(); + } + } +}