Стопор switch() на case 9, дальше идти не хочет

Тема в разделе "Arduino & Shields", создана пользователем Лев Николаевич, 9 сен 2021.

Метки:
  1. Доброго времени суток. Такая проблема.
    Пишу код для работы с PS/2 клавиатурой. При приеме данных клавиатуры switch() работает нормально, но при отправке данных всё стопорится на case 9 и дальше помогает только сброс.
    switch'и находятся в прерывании на пине, к которому подключен CLK клавиатуры. Код и поведение ардуины прилагаю, само собой.
    Попробовал другую плату, попробовал перепрошить загрузчик (ну мало ли) - ничего не дало.
    В чём причина стопора?

    Код (C++):
    #include <GyverWDT.h>

    #define PIN_CLK 2
    #define PIN_DATA 3

    volatile byte ps2_bitCounter;
    volatile byte ps2_mode; // 0 - IDLE, 1 - In, 2 - Out
    volatile bool data;
    volatile byte ps2_dataIn;
    volatile byte ps2_dataOut;
    volatile bool ps2_parity;

    void setup(){
      // Setup PS2 pins
      pinMode(PIN_CLK, INPUT);
      pinMode(PIN_DATA, INPUT);

      // Reset all variables
      ps2_bitCounter = 0;
      ps2_mode = 0;
      ps2_dataIn = 0;
      ps2_dataOut = 0;

      // Debug
      Serial.begin(9600);

      // Enable external interrupts
      attachInterrupt(digitalPinToInterrupt(PIN_CLK), ps2_interrupt, FALLING);

      Watchdog.enable(INTERRUPT_MODE, WDT_PRESCALER_32);
    }

    ISR(WATCHDOG) {
      ps2_dataIn = 0;
      ps2_bitCounter = 0;
      ps2_mode = 0;
      ps2_parity = false;
      pinMode(PIN_DATA, INPUT);
    }

    void ps2_interrupt(){
      Watchdog.reset();

      // Increase counter
      ps2_bitCounter ++;

      // If reading
      if (ps2_mode != 2){
        data = digitalRead(PIN_DATA);
        switch (ps2_bitCounter){
          case 1:
            ps2_mode = 1;
            break;
          case 2:
          case 3:
          case 4:
          case 5:
          case 6:
          case 7:
          case 8:
          case 9:
            bitWrite(ps2_dataIn, ps2_bitCounter - 2, data);
            ps2_parity ^= data;
            break;
          case 10: // Parity bit
            //Serial.println(ps2_parity);
            break;
          case 11: // Stop bit
            ps2_bitCounter = 0;
            ps2_mode = 0;
            ps2_parity = 0;
            break;
          default: // In weird situations
            ps2_bitCounter = 0;
            ps2_mode = 0;
            ps2_parity = 0;
            break;
        }

      // If sending
      } else {
        Serial.print(ps2_bitCounter);
        switch (ps2_bitCounter){
          case 1: // Биты данных DATA0-7
          case 2:
          case 3:
          case 4:
          case 5:
          case 6:
          case 7:
          case 8:
            bool bitt = bitRead(ps2_dataOut, ps2_bitCounter - 1);
            digitalWrite(PIN_DATA, bitt);
            ps2_parity ^= bitt;
            Serial.println("G");
            break;
          case 9: // parity бит
            digitalWrite(PIN_DATA, ps2_parity);
            Serial.println("G");
            break;
          case 10: // STOP бит
            pinMode(PIN_DATA, INPUT);
            Serial.println("G");
            break;
          case 11: // ACK
            if (!digitalRead(PIN_DATA)) Serial.println("ERR");
            Serial.println("G");
            ps2_bitCounter = 0;
            ps2_mode = 0;
            break;
          default: //in weirs situation
            ps2_bitCounter = 0;
            ps2_mode = 0;
            break;
        }
      }
    }

    void switchmode(){
      noInterrupts();
      ps2_mode = 2;
      pinMode(PIN_CLK, OUTPUT);   // Переводим пин Clock на передачу
      delayMicroseconds(100);     // Держим 100 мкс пин Clock
      ps2_bitCounter = 0;         // Сбрасываем счетчик Clock
      ps2_parity = 0;
      //ps2_timeLast = millis();
      pinMode(PIN_DATA, OUTPUT);  // Переводим пин Data на передачу
      pinMode(PIN_CLK, INPUT);    // Отдаем пин Clock клавиатуре
      interrupts();
    }

    void loop(){
      if (ps2_mode == 0){
        if (ps2_dataIn != 0){
          Serial.print("In - ");
          Serial.println(ps2_dataIn, HEX);
          ps2_dataIn = 0;
        }
        if (Serial.available()){
          ps2_dataOut = byte(Serial.parseInt());
          Serial.print("Out - ");
          Serial.println(ps2_dataOut, HEX);
          switchmode();
        }
      }
    }
    P.S. Нет, библиотека не вариант. На особую клавиатуру (Prodikeys DM) нужно будет отправить несколько байт, чтобы активировать весь её функционал
     

    Вложения: