121 lines
3.2 KiB
C++
121 lines
3.2 KiB
C++
#include <Arduino.h>
|
|
#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;
|
|
}
|
|
} |