Changed LED handling
parent
8b308e0404
commit
e6655cb9b5
|
@ -0,0 +1,56 @@
|
||||||
|
#include <Wire.h>
|
||||||
|
#include "Pca9554.h"
|
||||||
|
|
||||||
|
enum class Pca9554_Registers : uint8_t {
|
||||||
|
INPUT_PORT = 0x00,
|
||||||
|
OUTPUT_PORT = 0x01,
|
||||||
|
POLARITY_INVERSION = 0x02,
|
||||||
|
CONFIGURATION = 0x03,
|
||||||
|
};
|
||||||
|
|
||||||
|
Pca9554::Pca9554(uint8_t slaveAddress) :
|
||||||
|
outputValues { 0 }, slaveAddress { slaveAddress }, inputMask { 0 }
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Pca9554::~Pca9554()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pca9554::begin(uint8_t inputMask, uint8_t outputs)
|
||||||
|
{
|
||||||
|
SetInputPins(inputMask);
|
||||||
|
SendOutputValues(outputValues = outputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pca9554::SetInputPins(uint8_t inputMask)
|
||||||
|
{
|
||||||
|
this->inputMask = inputMask;
|
||||||
|
Wire.beginTransmission(slaveAddress | 0x00);
|
||||||
|
Wire.write((uint8_t) Pca9554_Registers::CONFIGURATION);
|
||||||
|
Wire.write(inputMask);
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Pca9554::ReadInputs()
|
||||||
|
{
|
||||||
|
Wire.beginTransmission(slaveAddress | 0x01);
|
||||||
|
int result = Wire.read() & inputMask;
|
||||||
|
Wire.endTransmission();
|
||||||
|
return (uint8_t) result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pca9554::SendOutputValues()
|
||||||
|
{
|
||||||
|
SendOutputValues(outputValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pca9554::SendOutputValues(uint8_t values)
|
||||||
|
{
|
||||||
|
Wire.beginTransmission(slaveAddress | 0x00);
|
||||||
|
Wire.write((uint8_t) Pca9554_Registers::OUTPUT_PORT);
|
||||||
|
Wire.write(values & ~inputMask);
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef PCA9554_H_
|
||||||
|
#define PCA9554_H_ 1
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define PCA9554_ADDR 0x20 //PCA9554 = 0 1 0 0 a2 a1 a0
|
||||||
|
|
||||||
|
class Pca9554 {
|
||||||
|
public:
|
||||||
|
Pca9554(uint8_t slaveAddress = PCA9554_ADDR);
|
||||||
|
~Pca9554();
|
||||||
|
|
||||||
|
void begin(uint8_t inputMask = 0, uint8_t outputs = 0);
|
||||||
|
void SetInputPins(uint8_t inputMask);
|
||||||
|
uint8_t ReadInputs();
|
||||||
|
void SendOutputValues();
|
||||||
|
void SendOutputValues(uint8_t values);
|
||||||
|
|
||||||
|
uint8_t outputValues;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const uint8_t slaveAddress;
|
||||||
|
uint8_t inputMask;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //PCA9554_H_
|
|
@ -3,28 +3,16 @@
|
||||||
|
|
||||||
#define TCS_OVERSAMPLING 8
|
#define TCS_OVERSAMPLING 8
|
||||||
#define TCS_BAUDRATE 475
|
#define TCS_BAUDRATE 475
|
||||||
|
#define TCS_IDLE_TIMEOUT 64 //8 bits
|
||||||
|
|
||||||
//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) :
|
TcsBus::TcsBus(int sendPin, int receivePin) :
|
||||||
sendPin { sendPin },
|
sendPin { sendPin },
|
||||||
receivePin { receivePin },
|
receivePin { receivePin },
|
||||||
state { SamplingState::IDLE },
|
state { SamplingState::IDLE },
|
||||||
rxBits { 0 },
|
rxBits { 0 },
|
||||||
oversamplingStep { 0 }
|
oversamplingStep { 0 },
|
||||||
|
defaultRxEvent { 0 },
|
||||||
|
txEvent { 0 }
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,16 +25,25 @@ static void onTimer(void)
|
||||||
|
|
||||||
static bool TimerSetup(TcsBus* inst)
|
static bool TimerSetup(TcsBus* inst)
|
||||||
{
|
{
|
||||||
if(timer != NULL) return false; //already set up
|
if(inst) {
|
||||||
|
if(timer != NULL) return false; //already set up
|
||||||
|
|
||||||
tcsInstance = inst;
|
tcsInstance = inst;
|
||||||
//time base is 80 MHz, which will be divided by the value from timerBegin, and then
|
//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.
|
//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
|
//80000000 / 50 / 421 = 3800.47 Hz = 8 * 475.06
|
||||||
timer = timerBegin(0, 50, true);
|
timer = timerBegin(0, 50, true);
|
||||||
timerAttachInterrupt(timer, &onTimer, true);
|
timerAttachInterrupt(timer, &onTimer, true);
|
||||||
timerAlarmWrite(timer, 421, true);
|
timerAlarmWrite(timer, 421, true);
|
||||||
timerAlarmEnable(timer);
|
timerAlarmEnable(timer);
|
||||||
|
} else {
|
||||||
|
if(timer == NULL) return false; //not set up
|
||||||
|
timerAlarmDisable(timer);
|
||||||
|
timerDetachInterrupt(timer);
|
||||||
|
timerEnd(timer);
|
||||||
|
timer = NULL;
|
||||||
|
tcsInstance = NULL;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,66 +53,142 @@ void TcsBus::begin()
|
||||||
pinMode(receivePin, INPUT);
|
pinMode(receivePin, INPUT);
|
||||||
pinMode(sendPin, OUTPUT);
|
pinMode(sendPin, OUTPUT);
|
||||||
digitalWrite(sendPin, LOW); //disable sending for now
|
digitalWrite(sendPin, LOW); //disable sending for now
|
||||||
pinMode(0, OUTPUT);
|
//pinMode(0, OUTPUT);
|
||||||
TimerSetup(this);
|
TimerSetup(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TcsBus::end()
|
||||||
|
{
|
||||||
|
pinMode(sendPin, INPUT);
|
||||||
|
TimerSetup(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void TcsBus::TimeBase()
|
void TcsBus::TimeBase()
|
||||||
{
|
{
|
||||||
static int tmp = 0;
|
bool sample = digitalRead(receivePin);
|
||||||
static bool send = false;
|
|
||||||
static int sendIdx = 0;
|
|
||||||
static int over = 0;
|
|
||||||
tmp++;
|
|
||||||
|
|
||||||
if(tmp == 3000) {
|
do {
|
||||||
send = true;
|
if(state != SamplingState::IDLE) {
|
||||||
sendIdx = 0;
|
if(sample) {
|
||||||
over = 0;
|
oversamplingSum++;
|
||||||
|
}
|
||||||
|
if(oversamplingStep) oversamplingStep--;
|
||||||
|
if(oversamplingStep) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(state) {
|
||||||
|
case SamplingState::IDLE: {
|
||||||
|
if(!sample) {
|
||||||
|
state = SamplingState::RECEIVE;
|
||||||
|
oversamplingStep = TCS_OVERSAMPLING;
|
||||||
|
oversamplingSum = 0;
|
||||||
|
currentBitIndex = 0;
|
||||||
|
memset(rxBits, 0x00, (sizeof(rxBits) / sizeof(uint8_t)));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case SamplingState::RECEIVE: {
|
||||||
|
if(oversamplingSum <= TCS_OVERSAMPLING / 4) {
|
||||||
|
ReceiveBit(0);
|
||||||
|
} else if(oversamplingSum >= (TCS_OVERSAMPLING * 3) / 4) {
|
||||||
|
ReceiveBit(1);
|
||||||
|
} else {
|
||||||
|
//If received bit is invalid, go to idle wait
|
||||||
|
EnterWaitIdle();
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case SamplingState::TRANSMIT: {
|
||||||
|
TransmitBit();
|
||||||
|
} break;
|
||||||
|
case SamplingState::WAIT_IDLE: {
|
||||||
|
WaitIdle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} while(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TcsBus::RegisterDefaultRxEvent(EventData_t* evt)
|
||||||
|
{
|
||||||
|
defaultRxEvent = evt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TcsBus::RegisterEvent(const EventData_t* evt)
|
||||||
|
{
|
||||||
|
events.push_back(evt);
|
||||||
|
}
|
||||||
|
void TcsBus::UnRegisterEvent(const EventData_t* evt)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < events.size(); i++) {
|
||||||
|
if(evt == events[i]) {
|
||||||
|
//events.erase(evt); //no, needs iterators
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(send) {
|
void TcsBus::ReceiveBit(uint8_t currentBit)
|
||||||
over++;
|
{
|
||||||
if(over == 8) {
|
//push received bit to buffer.
|
||||||
over = 0;
|
rxBits[currentBitIndex++] = currentBit;
|
||||||
if(sendIdx >= sizeof(door_open)) {
|
|
||||||
digitalWrite(sendPin, LOW);
|
//check against event list
|
||||||
send = false;
|
const EventData_t* found = 0;
|
||||||
tmp = 0;
|
for(const EventData_t* evt: events) {
|
||||||
} else {
|
//std::cout << value << "\n";
|
||||||
digitalWrite(sendPin, (door_open[sendIdx++]) ? LOW : HIGH);
|
if(currentBitIndex >= evt->bitCount) {
|
||||||
|
if(!memcmp(rxBits, evt->bits, evt->bitCount)) {
|
||||||
|
if(found != 0) {
|
||||||
|
//duplicate, skip
|
||||||
|
found = 0;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
found = evt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(found) {
|
||||||
bool sample = digitalRead(receivePin);
|
found->func(found);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if(found || (currentBitIndex >= (sizeof(rxBits) / sizeof(uint8_t)))) {
|
||||||
|
//if done or buffer is full, switch to idle wait state
|
||||||
|
EnterWaitIdle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void TcsBus::EnterWaitIdle()
|
||||||
|
{
|
||||||
|
state = SamplingState::WAIT_IDLE;
|
||||||
|
oversamplingStep = TCS_IDLE_TIMEOUT;
|
||||||
|
oversamplingSum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TcsBus::TransmitBit()
|
||||||
|
{
|
||||||
|
if(currentBitIndex < txEvent->bitCount) {
|
||||||
|
digitalWrite(sendPin, !txEvent->bits[currentBitIndex++]);
|
||||||
|
} else {
|
||||||
|
//disable if done and return to WAIT_IDLE state
|
||||||
|
digitalWrite(sendPin, 0); //disable tx mosfet
|
||||||
|
EnterWaitIdle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TcsBus::WaitIdle()
|
||||||
|
{
|
||||||
|
|
||||||
|
//At this point, the error condition was triggered and the timout is over. If the bus is in idle state, we can
|
||||||
|
//go over to IDLE, otherwise, we must reset the timeout to ensure an idle time on the bus
|
||||||
|
if(oversamplingSum >= TCS_IDLE_TIMEOUT) {
|
||||||
|
state = SamplingState::IDLE;
|
||||||
|
} else {
|
||||||
|
oversamplingStep = TCS_IDLE_TIMEOUT;
|
||||||
|
oversamplingSum = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,33 @@
|
||||||
#ifndef TCS_BUS_H_
|
#ifndef TCS_BUS_H_
|
||||||
#define TCS_BUS_H_ 1
|
#define TCS_BUS_H_ 1
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
class TcsBus {
|
class TcsBus {
|
||||||
public:
|
public:
|
||||||
TcsBus(int sendPin, int receivePin);
|
struct EventData_t;
|
||||||
|
typedef struct EventData_t {
|
||||||
|
void (*func)(const EventData_t* evt);
|
||||||
|
const uint8_t* bits;
|
||||||
|
size_t bitCount;
|
||||||
|
} EventData_t;
|
||||||
|
|
||||||
|
TcsBus(int sendPin, int receivePin);
|
||||||
void begin();
|
void begin();
|
||||||
|
void end();
|
||||||
void TimeBase();
|
void TimeBase();
|
||||||
|
void RegisterDefaultRxEvent(EventData_t* evt);
|
||||||
|
void RegisterEvent(const EventData_t* evt);
|
||||||
|
void UnRegisterEvent(const EventData_t* evt);
|
||||||
|
|
||||||
|
bool StartTransmit(EventData_t* evt);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void EnterWaitIdle();
|
||||||
|
void ReceiveBit(uint8_t currentBit);
|
||||||
|
void TransmitBit();
|
||||||
|
void WaitIdle();
|
||||||
int sendPin;
|
int sendPin;
|
||||||
int receivePin;
|
int receivePin;
|
||||||
|
|
||||||
|
@ -17,12 +36,17 @@ private:
|
||||||
IDLE = 0,
|
IDLE = 0,
|
||||||
RECEIVE = 1,
|
RECEIVE = 1,
|
||||||
TRANSMIT = 2,
|
TRANSMIT = 2,
|
||||||
|
WAIT_IDLE = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
SamplingState state;
|
SamplingState state;
|
||||||
uint16_t rxBits;
|
uint8_t rxBits[256];
|
||||||
|
uint16_t currentBitIndex;
|
||||||
uint8_t oversamplingStep;
|
uint8_t oversamplingStep;
|
||||||
bool lastSample;
|
uint8_t oversamplingSum;
|
||||||
|
std::vector<const EventData_t*> events;
|
||||||
|
EventData_t* defaultRxEvent;
|
||||||
|
EventData_t* txEvent;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //TCS_BUS_H_
|
#endif //TCS_BUS_H_
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef TCS_BUS_MESSAGES_H_
|
||||||
|
#define TCS_BUS_MESSAGES_H_ 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//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};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //TCS_BUS_MESSAGES_H_
|
|
@ -1,7 +1,7 @@
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
|
#include "Pca9554.h"
|
||||||
#include "TcsBus.h"
|
#include "TcsBus.h"
|
||||||
|
#include "TcsBusMessages.h"
|
||||||
#define PCA9554_ADDR 0x20 //PCA9554 = 0 1 0 0 a2 a1 a0
|
|
||||||
|
|
||||||
#define PIN_AUDIO_READ 0
|
#define PIN_AUDIO_READ 0
|
||||||
#define PIN_API_SWITCH 4
|
#define PIN_API_SWITCH 4
|
||||||
|
@ -9,10 +9,73 @@
|
||||||
#define PIN_TCS_SEND 14
|
#define PIN_TCS_SEND 14
|
||||||
#define PIN_AUDIO_SEND 17
|
#define PIN_AUDIO_SEND 17
|
||||||
|
|
||||||
TcsBus tcs(PIN_TCS_SEND, PIN_TCS_READ);
|
#define SREG_PIN_API_SWITCH 0x01u
|
||||||
|
#define SREG_PIN_LED1R 0x02u
|
||||||
|
#define SREG_PIN_REL1CTRL 0x04u
|
||||||
|
#define SREG_PIN_AUDIO_SEND_EN 0x08u
|
||||||
|
#define SREG_PIN_REL2CTRL 0x10u
|
||||||
|
#define SREG_PIN_LED1G 0x20u
|
||||||
|
#define SREG_PIN_LED2R 0x40u
|
||||||
|
#define SREG_PIN_LED2G 0x80u
|
||||||
|
|
||||||
|
#define LEDS 2
|
||||||
|
|
||||||
|
enum class LedColor : uint8_t {
|
||||||
|
OFF = 0,
|
||||||
|
RED = 1,
|
||||||
|
GREEN = 2,
|
||||||
|
YELLOW = 3,
|
||||||
|
|
||||||
|
UBOUND
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct LedState_s {
|
||||||
|
enum LedColor color;
|
||||||
|
bool blink;
|
||||||
|
} LedState_t;
|
||||||
|
|
||||||
|
|
||||||
|
const uint8_t LedBitmask[LEDS][(uint8_t) LedColor::UBOUND] = {
|
||||||
|
{
|
||||||
|
0, SREG_PIN_LED1R, SREG_PIN_LED1G, (SREG_PIN_LED1R | SREG_PIN_LED1G)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0, SREG_PIN_LED2R, SREG_PIN_LED2G, (SREG_PIN_LED2R | SREG_PIN_LED2G)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void DoorbellEvt(const TcsBus::EventData_t* evt)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TcsBus::EventData_t doorbellEvt = {
|
||||||
|
.func = DoorbellEvt,
|
||||||
|
.bits = doorbell,
|
||||||
|
.bitCount = sizeof(doorbell),
|
||||||
|
};
|
||||||
|
|
||||||
|
static LedState_t ledStates[LEDS] = {
|
||||||
|
{ LedColor::OFF, false },
|
||||||
|
{ LedColor::OFF, false }
|
||||||
|
};
|
||||||
|
|
||||||
static uint32_t ms_old = 0;
|
static uint32_t ms_old = 0;
|
||||||
|
|
||||||
|
static TcsBus tcs = TcsBus(PIN_TCS_SEND, PIN_TCS_READ);
|
||||||
|
static Pca9554 sreg = Pca9554();
|
||||||
|
static bool blinkOn = false;
|
||||||
|
|
||||||
|
static void SetLed(uint8_t ledNr, LedState_t newState) {
|
||||||
|
uint8_t ledBitmask = LedBitmask[ledNr][(uint8_t) newState.color];
|
||||||
|
uint8_t ledAll = LedBitmask[ledNr][(uint8_t) LedColor::YELLOW];
|
||||||
|
|
||||||
|
if(newState.blink && !blinkOn) {
|
||||||
|
ledBitmask = LedBitmask[ledNr][(uint8_t) LedColor::OFF];
|
||||||
|
}
|
||||||
|
sreg.outputValues = (sreg.outputValues & ~ledAll) | ledBitmask;
|
||||||
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// put your setup code here, to run once:
|
// put your setup code here, to run once:
|
||||||
Wire.begin();
|
Wire.begin();
|
||||||
|
@ -20,7 +83,20 @@ void setup() {
|
||||||
|
|
||||||
tcs.begin();
|
tcs.begin();
|
||||||
|
|
||||||
|
tcs.RegisterEvent(&doorbellEvt);
|
||||||
|
|
||||||
|
//const uint8_t sregOutputs = (uint8_t) (SREG_PIN_LED1R | SREG_PIN_REL1CTRL | SREG_PIN_AUDIO_SEND_EN | SREG_PIN_REL2CTRL | SREG_PIN_LED1G | SREG_PIN_LED2R | SREG_PIN_LED2G);
|
||||||
|
const uint8_t sregInputs = (uint8_t) (SREG_PIN_API_SWITCH | SREG_PIN_AUDIO_SEND_EN);
|
||||||
|
|
||||||
|
sreg.begin(sregInputs);
|
||||||
|
|
||||||
|
sreg.outputValues = 0;
|
||||||
ms_old = millis();
|
ms_old = millis();
|
||||||
|
|
||||||
|
ledStates[1].color = LedColor::YELLOW;
|
||||||
|
ledStates[0].blink = true;
|
||||||
|
//ledStates[1].color = LedColor::YELLOW;
|
||||||
|
//ledStates[1].blink = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,8 +113,22 @@ void loop() {
|
||||||
if(ms_old != ms) {
|
if(ms_old != ms) {
|
||||||
if(ms_old < ms) ms_old++; else ms_old = ms; //prevent overflow
|
if(ms_old < ms) ms_old++; else ms_old = ms; //prevent overflow
|
||||||
|
|
||||||
if(!(ms & 1023)) {
|
static uint32_t blinkCountdown = 500;
|
||||||
i2cScan();
|
blinkCountdown--;
|
||||||
|
if(!blinkCountdown) {
|
||||||
|
blinkCountdown = 500;
|
||||||
|
blinkOn = !blinkOn;
|
||||||
|
SetLed(0, ledStates[0]);
|
||||||
|
SetLed(1, ledStates[1]);
|
||||||
|
Serial.printf("0x%02x\r\n", sreg.outputValues);
|
||||||
|
sreg.SendOutputValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t inputs = sreg.ReadInputs();
|
||||||
|
static uint8_t inputs_old = 0;
|
||||||
|
if((inputs & SREG_PIN_API_SWITCH) != (inputs_old & SREG_PIN_API_SWITCH)) {
|
||||||
|
Serial.printf("Switch=%u\n", inputs & SREG_PIN_API_SWITCH);
|
||||||
}
|
}
|
||||||
|
inputs_old = inputs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue