Untitled

mail@pastecode.io avatarunknown
plain_text
2 months ago
7.3 kB
1
Indexable
Never
#include <CmdMessenger.h>
#include "Mux.h"
CmdMessenger messenger(Serial);
using namespace admux;

typedef uint16_t ButtonState;

ButtonState buttonStateLast[4];
ButtonState buttonStateCurrent[4];
ButtonState directStateLast = 0;
ButtonState directStateCurrent = 0;

const String guid = "{e5a183bc-a90f-42ca-8293-5c8f1f4130c0}";
const String authkey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const uint8_t directPins[8] = { 17, 19, 21, 23, 25, 27, 29, 31};
const uint8_t ledPins[9] = { 12, 14, 16, 18, 20, 22, 24, 26, 28};

bool isReady = false;
bool isStarted = false;

Mux mux_0(Pin(2, INPUT_PULLUP, PinType::Digital), Pinset(3, 5, 7, 9));
Mux mux_1(Pin(4, INPUT_PULLUP, PinType::Digital), Pinset(3, 5, 7, 9));
Mux mux_2(Pin(6, INPUT_PULLUP, PinType::Digital), Pinset(3, 5, 7, 9));
Mux mux_3(Pin(8, INPUT_PULLUP, PinType::Digital), Pinset(3, 5, 7, 9));

Mux* muxList[4] = {&mux_0, &mux_1, &mux_2, &mux_3};

void led_anim()
{
  for(uint8_t i = 0; i < 9; i++)
  {
    digitalWrite(ledPins[i], HIGH);
    delay(56);
  }
  for(uint8_t i = 0; i < 9; i++)
  {
    digitalWrite(ledPins[i], LOW);
    delay(56);
  }
}


/* SPAD PROTOCOL IMPL */
void spad_id_request_isr()
{
  char *szRequest = messenger.readStringArg();

  if (strcmp(szRequest, "INIT") == 0)
    {
        messenger.sendCmdStart(0);
        messenger.sendCmdArg("SPAD");
        messenger.sendCmdArg(guid); // GUID  
        messenger.sendCmdArg("Airbus MCDU"); // DEVICE DISPLAY NAME
        messenger.sendCmdArg(2); // SPAD SERIAL VERSION, DON'T CHANGE
        messenger.sendCmdArg("1"); // DEVICE VERSION NUMBER        
//        messenger.sendCmdArg("AUTHOR="+authkey); // AUTHOR ID - Edit the variable on top part of the code and remove // at the beginning of this line to activate your  auth code.     
        messenger.sendCmdEnd();
        return;
    }
    
  if (strcmp(szRequest, "SCANSTATE") == 0)
    {
        messenger.sendCmdStart(0);
        messenger.sendCmdArg("STATESCAN");
        messenger.sendCmdEnd();
        return;
    }

  if (strcmp(szRequest, "PING") == 0){
    messenger.sendCmdStart(0);
    messenger.sendCmdArg("PONG");
    messenger.sendCmdArg(messenger.readInt32Arg());
    messenger.sendCmdEnd();
    return;
  }

  if (strcmp(szRequest, "CONFIG") == 0)
  {
    messenger.sendCmdStart(0);
    messenger.sendCmdArg("OPTION");
    messenger.sendCmdArg("ISGENERIC=1");
    messenger.sendCmdArg("PAGESUPPORT=1");
    messenger.sendCmdArg("NO_DISPLAY_CLEAR=1");
    messenger.sendCmdEnd();

    for(uint8_t i = 0; i < 64; i++)
    {
      char str_buf[64];
      sprintf(str_buf, "BTN_%d", i+1);
      messenger.sendCmdStart(0);
      messenger.sendCmdArg("INPUT");
      messenger.sendCmdArg(i+1);
      messenger.sendCmdArg(str_buf);
      messenger.sendCmdArg("PUSHBUTTON");
      messenger.sendCmdArg("SPAD_SIMPLEBUTTON");
      messenger.sendCmdEnd();
    }

    for(uint8_t i = 0; i < 8; i++)
    {
      char str_buf[16];
      sprintf(str_buf, "BTN_%d", i+65);
      messenger.sendCmdStart(0);
      messenger.sendCmdArg("INPUT");
      messenger.sendCmdArg(i+65);
      messenger.sendCmdArg(str_buf);
      messenger.sendCmdArg("PUSHBUTTON");
      messenger.sendCmdArg("SPAD_SIMPLEBUTTON");
      messenger.sendCmdEnd();
    }

    for(uint8_t i = 0; i < 9; i++)
    {
        char str_buf[16];
        sprintf(str_buf, "LED_%d", i+1);
        messenger.sendCmdStart(0);
        messenger.sendCmdArg("OUTPUT");
        messenger.sendCmdArg(i+1);             // This is the LED ID 
        messenger.sendCmdArg(str_buf);    //SPAD GUI Display name
        messenger.sendCmdArg("LED");   // Type
        messenger.sendCmdArg("SPAD_LED");  // Behaviour
        messenger.sendCmdEnd();
        digitalWrite(ledPins[i], LOW);
    }
  }

  messenger.sendCmd(0, "CONFIG");
  led_anim();
  return;
}

void attachCommandCallbacks()
{
    messenger.sendCmd(3, "ATTACHING CALLBACKS!");
    messenger.attach(0, spad_id_request_isr); 
    messenger.attach(2, onSpadEvent);       
    messenger.attach(3, onUnknownCommand);
    messenger.attach(6, onDeviceLed);  
}

void onSpadEvent()
{
  char *szEvent = messenger.readStringArg();
  if (strcmp(szEvent, "START") == 0) { // SPAD tells device, it's ok to send input now
    isStarted = 1;
    return;
  }
  if (strcmp(szEvent, "END") == 0) { // SPAD tells device it will exit now
    isStarted = 0;
    return;
  }
}

void onUnknownCommand()
{
  messenger.sendCmd(3, "UNKNOWN COMMAND"); 
}

ButtonState read_mux(uint8_t mux_id)
{
  ButtonState retval = 0;
  for(uint8_t i = 0; i < 16; i++)
  {
    if(!muxList[mux_id]->read(i))
      retval |= 1;

    if(i<15) retval <<= 1;
  }
  return retval;
}

ButtonState read_direct()
{
  ButtonState retval = 0;
  for(uint8_t i = 0; i < 8; i++)
  {
    if(!digitalRead(directPins[i]))
    {
      retval |= 1;
    }
    
    if(i<7) retval <<= 1;
  }
  return retval;
}

void onDeviceLed(){ 
  int32_t ledID = messenger.readInt32Arg();       // Led ID
  int32_t ledVal = messenger.readInt32Arg();      // Led value
  
  (ledVal) ? (digitalWrite( ledPins[ledID-1], HIGH) ) : ( digitalWrite( ledPins[ledID-1], LOW) );
    
}

void setup() {
  Serial.begin(115200); while (!Serial); Serial.flush(); /* Waits for serial port to connect (needed for Leonardo only) */;

  for(uint8_t i = 0; i < 8; i++)
  {
    pinMode(directPins[i], INPUT_PULLUP);
  }
  
  for(uint8_t i = 0; i < 9; i++)
  {
    pinMode(ledPins[i], OUTPUT);
    digitalWrite(ledPins[i], LOW);
  }

  for(uint8_t i = 0; i < 4; i++)
  {
    buttonStateCurrent[i] = 0;
    buttonStateLast[i] = 0;
  }

  attachCommandCallbacks();
}

void loop() {

  if(isStarted)
  {
    for(uint8_t mux_n = 0; mux_n < 4; mux_n++)
    {
      buttonStateCurrent[mux_n] = read_mux(mux_n);
      if(buttonStateCurrent[mux_n] != buttonStateLast[mux_n])
      {
        for(uint8_t btn_n = 0; btn_n < 16; btn_n++)
        {
          uint8_t btn_cur = (uint8_t)(buttonStateCurrent[mux_n] >> btn_n) & 1;
          uint8_t btn_last = (uint8_t)(buttonStateLast[mux_n] >> btn_n) & 1;
          if(btn_cur != btn_last)
          {
            messenger.sendCmdStart(8); // Channel no for sending input state to SPAD NEXT
            messenger.sendCmdArg((mux_n * 16) + btn_n + 1); // Input ID
            messenger.sendCmdArg(btn_cur); // Value for off state
            messenger.sendCmdEnd();
          }
        }
        buttonStateLast[mux_n] = buttonStateCurrent[mux_n];
      }
    }
  }


  directStateCurrent = read_direct();
  if(directStateCurrent != directStateLast)
  {
    for(uint8_t i = 0; i < 8; i++)
    {
      uint8_t btnCur = (directStateCurrent >> i) & 1;
      uint8_t btnLast = (directStateLast >> i) & 1;
      if(btnLast != btnCur)
      {
        messenger.sendCmdStart(8); // Channel no for sending input state to SPAD NEXT
        messenger.sendCmdArg(i+65); // Input ID
        messenger.sendCmdArg(btnCur); // Value for off state
        messenger.sendCmdEnd();
      }
    }
    directStateLast = directStateCurrent;
  }

  messenger.feedinSerialData();

}