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_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};
|
||||
#define TCS_IDLE_TIMEOUT 64 //8 bits
|
||||
|
||||
TcsBus::TcsBus(int sendPin, int receivePin) :
|
||||
sendPin { sendPin },
|
||||
receivePin { receivePin },
|
||||
state { SamplingState::IDLE },
|
||||
rxBits { 0 },
|
||||
oversamplingStep { 0 }
|
||||
oversamplingStep { 0 },
|
||||
defaultRxEvent { 0 },
|
||||
txEvent { 0 }
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -37,16 +25,25 @@ static void onTimer(void)
|
|||
|
||||
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;
|
||||
//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);
|
||||
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);
|
||||
} else {
|
||||
if(timer == NULL) return false; //not set up
|
||||
timerAlarmDisable(timer);
|
||||
timerDetachInterrupt(timer);
|
||||
timerEnd(timer);
|
||||
timer = NULL;
|
||||
tcsInstance = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -56,66 +53,142 @@ void TcsBus::begin()
|
|||
pinMode(receivePin, INPUT);
|
||||
pinMode(sendPin, OUTPUT);
|
||||
digitalWrite(sendPin, LOW); //disable sending for now
|
||||
pinMode(0, OUTPUT);
|
||||
//pinMode(0, OUTPUT);
|
||||
TimerSetup(this);
|
||||
}
|
||||
|
||||
void TcsBus::end()
|
||||
{
|
||||
pinMode(sendPin, INPUT);
|
||||
TimerSetup(NULL);
|
||||
}
|
||||
|
||||
void TcsBus::TimeBase()
|
||||
{
|
||||
static int tmp = 0;
|
||||
static bool send = false;
|
||||
static int sendIdx = 0;
|
||||
static int over = 0;
|
||||
tmp++;
|
||||
bool sample = digitalRead(receivePin);
|
||||
|
||||
if(tmp == 3000) {
|
||||
send = true;
|
||||
sendIdx = 0;
|
||||
over = 0;
|
||||
do {
|
||||
if(state != SamplingState::IDLE) {
|
||||
if(sample) {
|
||||
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) {
|
||||
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);
|
||||
void TcsBus::ReceiveBit(uint8_t currentBit)
|
||||
{
|
||||
//push received bit to buffer.
|
||||
rxBits[currentBitIndex++] = currentBit;
|
||||
|
||||
//check against event list
|
||||
const EventData_t* found = 0;
|
||||
for(const EventData_t* evt: events) {
|
||||
//std::cout << value << "\n";
|
||||
if(currentBitIndex >= evt->bitCount) {
|
||||
if(!memcmp(rxBits, evt->bits, evt->bitCount)) {
|
||||
if(found != 0) {
|
||||
//duplicate, skip
|
||||
found = 0;
|
||||
break;
|
||||
} else {
|
||||
found = evt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(found) {
|
||||
found->func(found);
|
||||
}
|
||||
|
||||
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;
|
||||
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_
|
||||
#define TCS_BUS_H_ 1
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class TcsBus {
|
||||
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 end();
|
||||
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:
|
||||
void EnterWaitIdle();
|
||||
void ReceiveBit(uint8_t currentBit);
|
||||
void TransmitBit();
|
||||
void WaitIdle();
|
||||
int sendPin;
|
||||
int receivePin;
|
||||
|
||||
|
@ -17,12 +36,17 @@ private:
|
|||
IDLE = 0,
|
||||
RECEIVE = 1,
|
||||
TRANSMIT = 2,
|
||||
WAIT_IDLE = 3,
|
||||
};
|
||||
|
||||
SamplingState state;
|
||||
uint16_t rxBits;
|
||||
uint8_t rxBits[256];
|
||||
uint16_t currentBitIndex;
|
||||
uint8_t oversamplingStep;
|
||||
bool lastSample;
|
||||
uint8_t oversamplingSum;
|
||||
std::vector<const EventData_t*> events;
|
||||
EventData_t* defaultRxEvent;
|
||||
EventData_t* txEvent;
|
||||
};
|
||||
|
||||
#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 "Pca9554.h"
|
||||
#include "TcsBus.h"
|
||||
|
||||
#define PCA9554_ADDR 0x20 //PCA9554 = 0 1 0 0 a2 a1 a0
|
||||
#include "TcsBusMessages.h"
|
||||
|
||||
#define PIN_AUDIO_READ 0
|
||||
#define PIN_API_SWITCH 4
|
||||
|
@ -9,10 +9,73 @@
|
|||
#define PIN_TCS_SEND 14
|
||||
#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 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() {
|
||||
// put your setup code here, to run once:
|
||||
Wire.begin();
|
||||
|
@ -20,7 +83,20 @@ void setup() {
|
|||
|
||||
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();
|
||||
|
||||
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) ms_old++; else ms_old = ms; //prevent overflow
|
||||
|
||||
if(!(ms & 1023)) {
|
||||
i2cScan();
|
||||
static uint32_t blinkCountdown = 500;
|
||||
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