25 #include "freertos/FreeRTOS.h" 27 #include "esp32/ulp.h" 28 #include "driver/rtc_io.h" 29 #include "soc/sens_reg.h" 33 #include "ulp_macro_ex.h" 48 #define ALU_SEL_STAGE_INC 0 49 #define ALU_SEL_STAGE_DEC 1 50 #define ALU_SEL_STAGE_RST 2 52 #define SUB_OPCODE_STAGEB 2 55 #define I_STAGEINCI(imm_) { .alu_imm = { \ 60 .sel = ALU_SEL_STAGE_INC, \ 61 .sub_opcode = SUB_OPCODE_ALU_CNT, \ 62 .opcode = OPCODE_ALU } } 65 #define I_STAGEDECI(imm_) { .alu_imm = { \ 70 .sel = ALU_SEL_STAGE_DEC, \ 71 .sub_opcode = SUB_OPCODE_ALU_CNT, \ 72 .opcode = OPCODE_ALU } } 75 #define I_STAGERSTI() { .alu_imm = { \ 80 .sel = ALU_SEL_STAGE_RST, \ 81 .sub_opcode = SUB_OPCODE_ALU_CNT, \ 82 .opcode = OPCODE_ALU } } 85 #define I_STAGEBL(pc_offset, imm_value) { .b = { \ 88 .offset = abs(pc_offset), \ 89 .sign = (pc_offset >= 0) ? 0 : 1, \ 90 .sub_opcode = SUB_OPCODE_STAGEB, \ 91 .opcode = OPCODE_BRANCH } } 94 #define I_STAGEBLE(pc_offset, imm_value) { .b = { \ 97 .offset = abs(pc_offset), \ 98 .sign = (pc_offset >= 0) ? 0 : 1, \ 99 .sub_opcode = SUB_OPCODE_STAGEB, \ 100 .opcode = OPCODE_BRANCH } } 103 #define I_STAGEBGE(pc_offset, imm_value) { .b = { \ 104 .imm = 0x8000 | imm_value, \ 106 .offset = abs(pc_offset), \ 107 .sign = (pc_offset >= 0) ? 0 : 1, \ 108 .sub_opcode = SUB_OPCODE_STAGEB, \ 109 .opcode = OPCODE_BRANCH } } 115 #define M_STAGEBL(label_num, imm_value) \ 116 I_STAGEBGE(2, imm_value), \ 119 #define M_STAGEBGE(label_num, imm_value) \ 120 I_STAGEBL(2, imm_value), \ 123 #define M_STAGEBLE(label_num, imm_value) \ 124 I_STAGEBLE(2, imm_value), \ 125 I_STAGEBGE(2, imm_value), \ 132 #define OPCODE_PLACEHOLDER 12 // 12 is an unused ULP opcode we can use as placeholder 134 #define SUB_OPCODE_DAT_ENABLE_OUTPUT 0 135 #define SUB_OPCODE_DAT_ENABLE_INPUT 1 136 #define SUB_OPCODE_CLK_ENABLE_OUTPUT 2 137 #define SUB_OPCODE_CLK_ENABLE_INPUT 3 138 #define SUB_OPCODE_READ_CLK 4 139 #define SUB_OPCODE_READ_DAT 5 140 #define SUB_OPCODE_WRITE_CLK 6 141 #define SUB_OPCODE_WRITE_DAT 7 147 #define DAT_ENABLE_OUTPUT(ps2port, value) { .macro = { \ 150 .sub_opcode = SUB_OPCODE_DAT_ENABLE_OUTPUT, \ 151 .opcode = OPCODE_PLACEHOLDER } } 153 #define DAT_ENABLE_INPUT(ps2port, value) { .macro = { \ 156 .sub_opcode = SUB_OPCODE_DAT_ENABLE_INPUT, \ 157 .opcode = OPCODE_PLACEHOLDER } } 159 #define CLK_ENABLE_OUTPUT(ps2port, value) { .macro = { \ 162 .sub_opcode = SUB_OPCODE_CLK_ENABLE_OUTPUT, \ 163 .opcode = OPCODE_PLACEHOLDER } } 165 #define CLK_ENABLE_INPUT(ps2port, value) { .macro = { \ 168 .sub_opcode = SUB_OPCODE_CLK_ENABLE_INPUT, \ 169 .opcode = OPCODE_PLACEHOLDER } } 172 #define READ_CLK(ps2port) { .macro = { \ 175 .sub_opcode = SUB_OPCODE_READ_CLK, \ 176 .opcode = OPCODE_PLACEHOLDER } } 179 #define READ_DAT(ps2port) { .macro = { \ 182 .sub_opcode = SUB_OPCODE_READ_DAT, \ 183 .opcode = OPCODE_PLACEHOLDER } } 186 #define WRITE_CLK(ps2port, value) { .macro = { \ 189 .sub_opcode = SUB_OPCODE_WRITE_CLK, \ 190 .opcode = OPCODE_PLACEHOLDER } } 193 #define WRITE_DAT(ps2port, value) { .macro = { \ 196 .sub_opcode = SUB_OPCODE_WRITE_DAT, \ 197 .opcode = OPCODE_PLACEHOLDER } } 204 #define CONFIGURE_DAT_INPUT(ps2port) \ 205 DAT_ENABLE_OUTPUT(ps2port, 0), \ 206 DAT_ENABLE_INPUT(ps2port, 1) 209 #define CONFIGURE_DAT_OUTPUT(ps2port) \ 210 DAT_ENABLE_OUTPUT(ps2port, 1), \ 211 DAT_ENABLE_INPUT(ps2port, 0) 214 #define CONFIGURE_CLK_INPUT(ps2port) \ 215 CLK_ENABLE_OUTPUT(ps2port, 0), \ 216 CLK_ENABLE_INPUT(ps2port, 1) 219 #define CONFIGURE_CLK_OUTPUT(ps2port) \ 220 CLK_ENABLE_OUTPUT(ps2port, 1), \ 221 CLK_ENABLE_INPUT(ps2port, 0) 225 #define WRITE_DAT_R0(ps2port) \ 227 WRITE_DAT(ps2port, 1), \ 229 WRITE_DAT(ps2port, 0) 233 #define MEM_WRITEI(addr, value) \ 240 #define MEM_INDWRITEI(addr, value) \ 248 #define MEM_WRITER(addr, reg) \ 254 #define MEM_INDWRITER(addr, reg) \ 260 #define MEM_READR(reg, addr) \ 265 #define MEM_INDREADR(reg, addr) \ 272 #define MEM_INC(addr) \ 280 #define MEM_BL(label, addr, value) \ 287 #define MEM_BGE(label, addr, value) \ 293 #define M_LONG_BGE(label, value) \ 298 #define M_LONG_BL(label, value) \ 306 #define PORT0_RX_BUFFER_SIZE 128 307 #define PORT1_RX_BUFFER_SIZE 1644 312 #define RTCMEM_PROG_START 0x000 // where the program begins 313 #define RTCMEM_VARS_START 0x100 // where the variables begin 315 #define RTCMEM_PORT0_ENABLED (RTCMEM_VARS_START + 0) // if 1 then port 0 is enabled 316 #define RTCMEM_PORT0_MODE (RTCMEM_VARS_START + 1) // MODE_RECEIVE or MODE_SEND 317 #define RTCMEM_PORT0_WRITE_POS (RTCMEM_VARS_START + 2) // position of the next word to receive 318 #define RTCMEM_PORT0_WORD_RX_READY (RTCMEM_VARS_START + 3) // 1 when a word has been received (reset by ISR) 319 #define RTCMEM_PORT0_BIT (RTCMEM_VARS_START + 4) // send bit counter 320 #define RTCMEM_PORT0_STATE (RTCMEM_VARS_START + 5) // STATE_WAIT_CLK_LOW or STATE_WAIT_CLK_HIGH 321 #define RTCMEM_PORT0_SEND_WORD (RTCMEM_VARS_START + 6) // contains the word to send 322 #define RTCMEM_PORT0_WORD_SENT_FLAG (RTCMEM_VARS_START + 7) // 1 when word has been sent (reset by ISR) 324 #define RTCMEM_PORT1_ENABLED (RTCMEM_VARS_START + 8) // if 1 then port 1 is enabled 325 #define RTCMEM_PORT1_MODE (RTCMEM_VARS_START + 9) // MODE_RECEIVE or MODE_SEND 326 #define RTCMEM_PORT1_WRITE_POS (RTCMEM_VARS_START + 10) // position of the next word to receive 327 #define RTCMEM_PORT1_WORD_RX_READY (RTCMEM_VARS_START + 11) // 1 when a word has been received (reset by ISR) 328 #define RTCMEM_PORT1_BIT (RTCMEM_VARS_START + 12) // receive or send bit counter 329 #define RTCMEM_PORT1_STATE (RTCMEM_VARS_START + 13) // STATE_WAIT_CLK_LOW or STATE_WAIT_CLK_HIGH 330 #define RTCMEM_PORT1_SEND_WORD (RTCMEM_VARS_START + 14) // contains the word to send 331 #define RTCMEM_PORT1_WORD_SENT_FLAG (RTCMEM_VARS_START + 15) // 1 when word has been sent (reset by ISR) 333 #define RTCMEM_PORT0_BUFFER_START (RTCMEM_VARS_START + 16) // where the receive buffer begins 334 #define RTCMEM_PORT0_BUFFER_END (RTCMEM_PORT0_BUFFER_START + PORT0_RX_BUFFER_SIZE) // where the receive buffer ends 336 #define RTCMEM_PORT1_BUFFER_START RTCMEM_PORT0_BUFFER_END // where the receive buffer begins 337 #define RTCMEM_PORT1_BUFFER_END (RTCMEM_PORT1_BUFFER_START + PORT1_RX_BUFFER_SIZE) // where the receive buffer ends 341 #if RTCMEM_PORT1_BUFFER_END >= 0x800 342 #error "Port 1 ending buffer overflow" 347 #define MODE_RECEIVE 0 351 #define STATE_WAIT_CLK_HIGH 0 352 #define STATE_WAIT_CLK_LOW 1 356 #define READY_TO_RECEIVE 0 357 #define PORT0_RECEIVE_WORD_READY 1 358 #define PORT0_SEND_WORD 2 359 #define PORT0_SEND_NEXT_BIT 3 360 #define PORT0_SEND_WAIT_FOR_CLK_HIGH 4 361 #define PORT0_CLK_IS_HIGH 5 362 #define PORT1_RECEIVE_WORD_READY 6 363 #define PORT1_SEND_WORD 7 364 #define PORT1_SEND_NEXT_BIT 8 365 #define PORT1_SEND_WAIT_FOR_CLK_HIGH 9 366 #define PORT1_RECEIVE 10 367 #define PORT1_CLK_IS_HIGH 11 369 #define PORT1_INIT 13 377 const ulp_insn_t ULP_code[] = {
382 M_LABEL(READY_TO_RECEIVE),
388 MEM_READR(R0, RTCMEM_PORT0_ENABLED),
392 CONFIGURE_CLK_INPUT(PS2_PORT0),
393 CONFIGURE_DAT_INPUT(PS2_PORT0),
395 MEM_WRITEI(RTCMEM_PORT0_STATE, STATE_WAIT_CLK_LOW),
398 MEM_INDWRITEI(RTCMEM_PORT0_WRITE_POS, 0),
401 MEM_WRITEI(RTCMEM_PORT0_BIT, 0),
414 MEM_READR(R0, RTCMEM_PORT1_ENABLED),
418 CONFIGURE_CLK_INPUT(PS2_PORT1),
419 CONFIGURE_DAT_INPUT(PS2_PORT1),
421 MEM_WRITEI(RTCMEM_PORT1_STATE, STATE_WAIT_CLK_LOW),
424 MEM_INDWRITEI(RTCMEM_PORT1_WRITE_POS, 0),
427 MEM_WRITEI(RTCMEM_PORT1_BIT, 0),
437 MEM_READR(R0, RTCMEM_PORT0_MODE),
438 M_LONG_BGE(PORT0_SEND_WORD, MODE_SEND),
441 MEM_READR(R0, RTCMEM_PORT1_MODE),
442 M_LONG_BGE(PORT1_SEND_WORD, MODE_SEND),
449 MEM_READR(R0, RTCMEM_PORT0_ENABLED),
450 M_BL(PORT1_RECEIVE, 1),
453 MEM_READR(R1, RTCMEM_PORT0_STATE),
460 M_BXZ(PORT1_RECEIVE),
463 M_BGE(PORT0_CLK_IS_HIGH, 1),
466 MEM_WRITEI(RTCMEM_PORT0_STATE, STATE_WAIT_CLK_HIGH),
473 MEM_INDREADR(R1, RTCMEM_PORT0_WRITE_POS),
476 MEM_INDWRITER(RTCMEM_PORT0_WRITE_POS, R1),
481 M_LABEL(PORT0_CLK_IS_HIGH),
484 MEM_WRITEI(RTCMEM_PORT0_STATE, STATE_WAIT_CLK_LOW),
491 M_BL(PORT1_RECEIVE, 11),
496 MEM_INC(RTCMEM_PORT0_WRITE_POS),
497 MEM_BL(PORT0_RECEIVE_WORD_READY, RTCMEM_PORT0_WRITE_POS, RTCMEM_PORT0_BUFFER_END),
500 MEM_WRITEI(RTCMEM_PORT0_WRITE_POS, RTCMEM_PORT0_BUFFER_START),
502 M_LABEL(PORT0_RECEIVE_WORD_READY),
505 MEM_WRITEI(RTCMEM_PORT0_WORD_RX_READY, 1),
511 MEM_INDWRITEI(RTCMEM_PORT0_WRITE_POS, 0),
527 M_LABEL(PORT1_RECEIVE),
530 MEM_READR(R0, RTCMEM_PORT1_ENABLED),
534 MEM_READR(R1, RTCMEM_PORT1_STATE),
544 M_BGE(PORT1_CLK_IS_HIGH, 1),
547 MEM_WRITEI(RTCMEM_PORT1_STATE, STATE_WAIT_CLK_HIGH),
554 MEM_INDREADR(R1, RTCMEM_PORT1_WRITE_POS),
557 MEM_INDWRITER(RTCMEM_PORT1_WRITE_POS, R1),
562 M_LABEL(PORT1_CLK_IS_HIGH),
565 MEM_WRITEI(RTCMEM_PORT1_STATE, STATE_WAIT_CLK_LOW),
577 MEM_INC(RTCMEM_PORT1_WRITE_POS),
578 MEM_BL(PORT1_RECEIVE_WORD_READY, RTCMEM_PORT1_WRITE_POS, RTCMEM_PORT1_BUFFER_END),
581 MEM_WRITEI(RTCMEM_PORT1_WRITE_POS, RTCMEM_PORT1_BUFFER_START),
583 M_LABEL(PORT1_RECEIVE_WORD_READY),
586 MEM_WRITEI(RTCMEM_PORT1_WORD_RX_READY, 1),
592 MEM_INDWRITEI(RTCMEM_PORT1_WRITE_POS, 0),
607 M_LABEL(PORT0_SEND_WORD),
612 CONFIGURE_CLK_OUTPUT(PS2_PORT0),
613 WRITE_CLK(PS2_PORT0, 0),
617 CONFIGURE_DAT_OUTPUT(PS2_PORT0),
618 WRITE_DAT(PS2_PORT0, 0),
621 CONFIGURE_CLK_INPUT(PS2_PORT0),
624 MEM_READR(R3, RTCMEM_PORT0_SEND_WORD),
627 MEM_WRITEI(RTCMEM_PORT0_BIT, 0),
629 M_LABEL(PORT0_SEND_NEXT_BIT),
634 MEM_READR(R0, RTCMEM_PORT0_MODE),
635 M_LONG_BL(READY_TO_RECEIVE, MODE_SEND),
641 M_BGE(PORT0_SEND_NEXT_BIT, 1),
644 MEM_BGE(PORT0_SEND_WAIT_FOR_CLK_HIGH, RTCMEM_PORT0_BIT, 10),
648 WRITE_DAT_R0(PS2_PORT0),
650 M_LABEL(PORT0_SEND_WAIT_FOR_CLK_HIGH),
655 MEM_READR(R0, RTCMEM_PORT0_MODE),
656 M_LONG_BL(READY_TO_RECEIVE, MODE_SEND),
662 M_BL(PORT0_SEND_WAIT_FOR_CLK_HIGH, 1),
668 MEM_INC(RTCMEM_PORT0_BIT),
671 MEM_BL(PORT0_SEND_NEXT_BIT, RTCMEM_PORT0_BIT, 11),
674 MEM_WRITEI(RTCMEM_PORT0_MODE, MODE_RECEIVE),
677 MEM_WRITEI(RTCMEM_PORT0_WORD_SENT_FLAG, 1),
683 M_BX(READY_TO_RECEIVE),
693 M_LABEL(PORT1_SEND_WORD),
698 CONFIGURE_CLK_OUTPUT(PS2_PORT1),
699 WRITE_CLK(PS2_PORT1, 0),
703 CONFIGURE_DAT_OUTPUT(PS2_PORT1),
704 WRITE_DAT(PS2_PORT1, 0),
707 CONFIGURE_CLK_INPUT(PS2_PORT1),
710 MEM_READR(R3, RTCMEM_PORT1_SEND_WORD),
713 MEM_WRITEI(RTCMEM_PORT1_BIT, 0),
715 M_LABEL(PORT1_SEND_NEXT_BIT),
720 MEM_READR(R0, RTCMEM_PORT1_MODE),
721 M_LONG_BL(READY_TO_RECEIVE, MODE_SEND),
727 M_BGE(PORT1_SEND_NEXT_BIT, 1),
730 MEM_BGE(PORT1_SEND_WAIT_FOR_CLK_HIGH, RTCMEM_PORT1_BIT, 10),
734 WRITE_DAT_R0(PS2_PORT1),
736 M_LABEL(PORT1_SEND_WAIT_FOR_CLK_HIGH),
741 MEM_READR(R0, RTCMEM_PORT1_MODE),
742 M_LONG_BL(READY_TO_RECEIVE, MODE_SEND),
748 M_BL(PORT1_SEND_WAIT_FOR_CLK_HIGH, 1),
754 MEM_INC(RTCMEM_PORT1_BIT),
757 MEM_BL(PORT1_SEND_NEXT_BIT, RTCMEM_PORT1_BIT, 11),
760 MEM_WRITEI(RTCMEM_PORT1_MODE, MODE_RECEIVE),
763 MEM_WRITEI(RTCMEM_PORT1_WORD_SENT_FLAG, 1),
769 M_BX(READY_TO_RECEIVE),
783 void replace_placeholders(uint32_t prg_start,
int size,
bool port0Enabled, gpio_num_t port0_clkGPIO, gpio_num_t port0_datGPIO,
bool port1Enabled, gpio_num_t port1_clkGPIO, gpio_num_t port1_datGPIO)
785 uint32_t CLK_rtc_gpio_num[2], CLK_rtc_gpio_reg[2], CLK_rtc_gpio_ie_s[2];
786 uint32_t DAT_rtc_gpio_num[2], DAT_rtc_gpio_reg[2], DAT_rtc_gpio_ie_s[2];
789 CLK_rtc_gpio_num[0] = (uint32_t) rtc_gpio_desc[port0_clkGPIO].rtc_num;
790 CLK_rtc_gpio_reg[0] = rtc_gpio_desc[port0_clkGPIO].reg;
791 CLK_rtc_gpio_ie_s[0] = (uint32_t) ffs(rtc_gpio_desc[port0_clkGPIO].ie) - 1;
792 DAT_rtc_gpio_num[0] = (uint32_t) rtc_gpio_desc[port0_datGPIO].rtc_num;
793 DAT_rtc_gpio_reg[0] = rtc_gpio_desc[port0_datGPIO].reg;
794 DAT_rtc_gpio_ie_s[0] = (uint32_t) ffs(rtc_gpio_desc[port0_datGPIO].ie) - 1;
798 CLK_rtc_gpio_num[1] = (uint32_t) rtc_gpio_desc[port1_clkGPIO].rtc_num;
799 CLK_rtc_gpio_reg[1] = rtc_gpio_desc[port1_clkGPIO].reg;
800 CLK_rtc_gpio_ie_s[1] = (uint32_t) ffs(rtc_gpio_desc[port1_clkGPIO].ie) - 1;
801 DAT_rtc_gpio_num[1] = (uint32_t) rtc_gpio_desc[port1_datGPIO].rtc_num;
802 DAT_rtc_gpio_reg[1] = rtc_gpio_desc[port1_datGPIO].reg;
803 DAT_rtc_gpio_ie_s[1] = (uint32_t) ffs(rtc_gpio_desc[port1_datGPIO].ie) - 1;
806 for (uint32_t i = 0; i < size; ++i) {
807 ulp_insn_t * ins = (ulp_insn_t *) RTC_SLOW_MEM + i;
808 if (ins->macro.opcode == OPCODE_PLACEHOLDER) {
809 int ps2port = ins->macro.unused;
810 if ((port0Enabled && ps2port == 0) || (port1Enabled && ps2port == 1)) {
811 ins->macro.unused = 0;
812 switch (ins->macro.sub_opcode) {
813 case SUB_OPCODE_DAT_ENABLE_OUTPUT:
814 if (ins->macro.label)
815 *ins = (ulp_insn_t) I_WR_REG_BIT(RTC_GPIO_ENABLE_W1TS_REG, DAT_rtc_gpio_num[ps2port] + RTC_GPIO_ENABLE_W1TS_S, 1);
817 *ins = (ulp_insn_t) I_WR_REG_BIT(RTC_GPIO_ENABLE_W1TC_REG, DAT_rtc_gpio_num[ps2port] + RTC_GPIO_ENABLE_W1TC_S, 1);
819 case SUB_OPCODE_DAT_ENABLE_INPUT:
820 *ins = (ulp_insn_t) I_WR_REG_BIT(DAT_rtc_gpio_reg[ps2port], DAT_rtc_gpio_ie_s[ps2port], ins->macro.label);
822 case SUB_OPCODE_CLK_ENABLE_OUTPUT:
823 if (ins->macro.label)
824 *ins = (ulp_insn_t) I_WR_REG_BIT(RTC_GPIO_ENABLE_W1TS_REG, CLK_rtc_gpio_num[ps2port] + RTC_GPIO_ENABLE_W1TS_S, 1);
826 *ins = (ulp_insn_t) I_WR_REG_BIT(RTC_GPIO_ENABLE_W1TC_REG, CLK_rtc_gpio_num[ps2port] + RTC_GPIO_ENABLE_W1TC_S, 1);
828 case SUB_OPCODE_CLK_ENABLE_INPUT:
829 *ins = (ulp_insn_t) I_WR_REG_BIT(CLK_rtc_gpio_reg[ps2port], CLK_rtc_gpio_ie_s[ps2port], ins->macro.label);
831 case SUB_OPCODE_READ_CLK:
832 *ins = (ulp_insn_t) I_RD_REG(RTC_GPIO_IN_REG, CLK_rtc_gpio_num[ps2port] + RTC_GPIO_IN_NEXT_S, CLK_rtc_gpio_num[ps2port] + RTC_GPIO_IN_NEXT_S);
834 case SUB_OPCODE_READ_DAT:
835 *ins = (ulp_insn_t) I_RD_REG(RTC_GPIO_IN_REG, DAT_rtc_gpio_num[ps2port] + RTC_GPIO_IN_NEXT_S, DAT_rtc_gpio_num[ps2port] + RTC_GPIO_IN_NEXT_S);
837 case SUB_OPCODE_WRITE_CLK:
838 *ins = (ulp_insn_t) I_WR_REG_BIT(RTC_GPIO_OUT_REG, CLK_rtc_gpio_num[ps2port] + RTC_GPIO_IN_NEXT_S, ins->macro.label);
840 case SUB_OPCODE_WRITE_DAT:
841 *ins = (ulp_insn_t) I_WR_REG_BIT(RTC_GPIO_OUT_REG, DAT_rtc_gpio_num[ps2port] + RTC_GPIO_IN_NEXT_S, ins->macro.label);
850 PS2Controller * PS2Controller::s_instance =
nullptr;
853 PS2Controller::PS2Controller()
854 : m_keyboard(nullptr),
863 void PS2Controller::begin(gpio_num_t port0_clkGPIO, gpio_num_t port0_datGPIO, gpio_num_t port1_clkGPIO, gpio_num_t port1_datGPIO)
865 bool port0Enabled = (port0_clkGPIO != GPIO_UNUSED && port0_datGPIO != GPIO_UNUSED);
866 bool port1Enabled = (port1_clkGPIO != GPIO_UNUSED && port1_datGPIO != GPIO_UNUSED);
868 m_TXWaitTask[0] = m_TXWaitTask[1] =
nullptr;
869 m_RXWaitTask[0] = m_RXWaitTask[1] =
nullptr;
872 rtc_gpio_init(port0_clkGPIO);
873 rtc_gpio_init(port0_datGPIO);
877 rtc_gpio_init(port1_clkGPIO);
878 rtc_gpio_init(port1_datGPIO);
882 for (
int i = RTCMEM_PROG_START; i < RTCMEM_PORT1_BUFFER_END; ++i)
883 RTC_SLOW_MEM[i] = 0x0000;
886 RTC_SLOW_MEM[RTCMEM_PORT0_ENABLED] = port0Enabled;
887 RTC_SLOW_MEM[RTCMEM_PORT1_ENABLED] = port1Enabled;
892 size_t size =
sizeof(ULP_code) /
sizeof(ulp_insn_t);
893 ulp_process_macros_and_load_ex(RTCMEM_PROG_START, ULP_code, &size);
894 replace_placeholders(RTCMEM_PROG_START, size, port0Enabled, port0_clkGPIO, port0_datGPIO, port1Enabled, port1_clkGPIO, port1_datGPIO);
895 assert(size < RTCMEM_VARS_START &&
"ULP Program too long, increase RTCMEM_VARS_START");
896 REG_SET_FIELD(SENS_SAR_START_FORCE_REG, SENS_PC_INIT, RTCMEM_PROG_START);
897 SET_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_FORCE_START_TOP);
898 SET_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_START_TOP);
903 esp_intr_alloc_pinnedToCore(ETS_RTC_CORE_INTR_SOURCE, ESP_INTR_FLAG_LEVEL2, rtc_isr,
this, &m_isrHandle, 1);
904 SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA);
915 begin(GPIO_NUM_33, GPIO_NUM_32, GPIO_NUM_26, GPIO_NUM_27);
924 (
new Keyboard)->
begin(GPIO_NUM_33, GPIO_NUM_32, generateVirtualKeys, createVKQueue);
937 if (m_suspendCount == 0) {
938 CLEAR_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA);
940 WRITE_PERI_REG(RTC_CNTL_INT_CLR_REG, READ_PERI_REG(RTC_CNTL_INT_ST_REG));
948 if (m_suspendCount <= 0) {
950 SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA);
957 uint32_t RTCMEM_PORTX_WRITE_POS = (PS2Port == 0 ? RTCMEM_PORT0_WRITE_POS : RTCMEM_PORT1_WRITE_POS);
958 uint32_t RTCMEM_PORTX_BUFFER_END = (PS2Port == 0 ? RTCMEM_PORT0_BUFFER_END : RTCMEM_PORT1_BUFFER_END);
959 uint32_t RTCMEM_PORTX_BUFFER_START = (PS2Port == 0 ? RTCMEM_PORT0_BUFFER_START : RTCMEM_PORT1_BUFFER_START);
961 int writePos = RTC_SLOW_MEM[RTCMEM_PORTX_WRITE_POS] & 0xFFFF;
962 if (m_readPos[PS2Port] <= writePos)
963 return writePos - m_readPos[PS2Port];
965 return (RTCMEM_PORTX_BUFFER_END - m_readPos[PS2Port]) + (writePos - RTCMEM_PORTX_BUFFER_START);
972 uint32_t RTCMEM_PORTX_WRITE_POS = (PS2Port == 0 ? RTCMEM_PORT0_WRITE_POS : RTCMEM_PORT1_WRITE_POS);
973 uint32_t RTCMEM_PORTX_BUFFER_END = (PS2Port == 0 ? RTCMEM_PORT0_BUFFER_END : RTCMEM_PORT1_BUFFER_END);
974 uint32_t RTCMEM_PORTX_BUFFER_START = (PS2Port == 0 ? RTCMEM_PORT0_BUFFER_START : RTCMEM_PORT1_BUFFER_START);
978 int writePos = RTC_SLOW_MEM[RTCMEM_PORTX_WRITE_POS] & 0xFFFF;
979 if (m_readPos[PS2Port] != writePos) {
980 uint16_t data16 = (RTC_SLOW_MEM[m_readPos[PS2Port]] & 0xFFFF);
981 data = data16 >> 1 & 0xFF;
983 if ((data16 >> 9 & 1) != !calcParity(
data)) {
988 m_parityError[PS2Port] =
true;
991 ++m_readPos[PS2Port];
992 if (m_readPos[PS2Port] == RTCMEM_PORTX_BUFFER_END)
993 m_readPos[PS2Port] = RTCMEM_PORTX_BUFFER_START;
994 m_parityError[PS2Port] =
false;
1002 void PS2Controller::warmInit()
1004 m_readPos[0] = RTCMEM_PORT0_BUFFER_START;
1005 m_readPos[1] = RTCMEM_PORT1_BUFFER_START;
1008 RTC_SLOW_MEM[RTCMEM_PORT0_WRITE_POS] = RTCMEM_PORT0_BUFFER_START;
1009 RTC_SLOW_MEM[RTCMEM_PORT1_WRITE_POS] = RTCMEM_PORT1_BUFFER_START;
1012 RTC_SLOW_MEM[RTCMEM_PORT0_MODE] = MODE_RECEIVE;
1013 RTC_SLOW_MEM[RTCMEM_PORT1_MODE] = MODE_RECEIVE;
1016 RTC_SLOW_MEM[RTCMEM_PORT0_WORD_SENT_FLAG] = 0;
1017 RTC_SLOW_MEM[RTCMEM_PORT1_WORD_SENT_FLAG] = 0;
1018 RTC_SLOW_MEM[RTCMEM_PORT0_WORD_RX_READY] = 0;
1019 RTC_SLOW_MEM[RTCMEM_PORT1_WORD_RX_READY] = 0;
1022 vTaskDelay(20 / portTICK_PERIOD_MS);
1024 m_parityError[0] =
false;
1025 m_parityError[1] =
false;
1031 uint32_t RTCMEM_PORTX_WRITE_POS = (PS2Port == 0 ? RTCMEM_PORT0_WRITE_POS : RTCMEM_PORT1_WRITE_POS);
1032 uint32_t RTCMEM_PORTX_BUFFER_END = (PS2Port == 0 ? RTCMEM_PORT0_BUFFER_END : RTCMEM_PORT1_BUFFER_END);
1033 uint32_t RTCMEM_PORTX_BUFFER_START = (PS2Port == 0 ? RTCMEM_PORT0_BUFFER_START : RTCMEM_PORT1_BUFFER_START);
1035 int writePos = RTC_SLOW_MEM[RTCMEM_PORTX_WRITE_POS] & 0xFFFF;
1036 RTC_SLOW_MEM[writePos] = value << 1;
1038 if (writePos == RTCMEM_PORTX_BUFFER_END)
1039 writePos = RTCMEM_PORTX_BUFFER_START;
1040 RTC_SLOW_MEM[RTCMEM_PORTX_WRITE_POS] = writePos;
1044 bool PS2Controller::waitData(
int timeOutMS,
int PS2Port)
1046 m_RXWaitTask[PS2Port] = xTaskGetCurrentTaskHandle();
1047 return ulTaskNotifyTake(pdTRUE, msToTicks(timeOutMS));
1053 uint32_t RTCMEM_PORTX_SEND_WORD = (PS2Port == 0 ? RTCMEM_PORT0_SEND_WORD : RTCMEM_PORT1_SEND_WORD);
1054 uint32_t RTCMEM_PORTX_MODE = (PS2Port == 0 ? RTCMEM_PORT0_MODE : RTCMEM_PORT1_MODE);
1056 RTC_SLOW_MEM[RTCMEM_PORTX_SEND_WORD] = 0x200 | ((~calcParity(
data) & 1) << 8) |
data;
1057 RTC_SLOW_MEM[RTCMEM_PORTX_MODE] = MODE_SEND;
1058 m_TXWaitTask[PS2Port] = xTaskGetCurrentTaskHandle();
1059 if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(10)) == pdFALSE) {
1065 void IRAM_ATTR PS2Controller::rtc_isr(
void * arg)
1067 uint32_t rtc_intr = READ_PERI_REG(RTC_CNTL_INT_ST_REG);
1069 if (rtc_intr & RTC_CNTL_SAR_INT_ST) {
1072 for (
int PS2Port = 0; PS2Port < 2; ++PS2Port) {
1074 uint32_t RTCMEM_PORTX_WORD_SENT_FLAG = (PS2Port == 0 ? RTCMEM_PORT0_WORD_SENT_FLAG : RTCMEM_PORT1_WORD_SENT_FLAG);
1075 uint32_t RTCMEM_PORTX_WRITE_POS = (PS2Port == 0 ? RTCMEM_PORT0_WRITE_POS : RTCMEM_PORT1_WRITE_POS);
1076 uint32_t RTCMEM_PORTX_WORD_RX_READY = (PS2Port == 0 ? RTCMEM_PORT0_WORD_RX_READY : RTCMEM_PORT1_WORD_RX_READY);
1079 if (RTC_SLOW_MEM[RTCMEM_PORTX_WORD_SENT_FLAG]) {
1081 RTC_SLOW_MEM[RTCMEM_PORTX_WORD_SENT_FLAG] = 0;
1082 ctrl->m_readPos[PS2Port] = RTC_SLOW_MEM[RTCMEM_PORTX_WRITE_POS] & 0xFFFF;
1083 if (ctrl->m_TXWaitTask[PS2Port]) {
1084 vTaskNotifyGiveFromISR(ctrl->m_TXWaitTask[PS2Port],
nullptr);
1085 ctrl->m_TXWaitTask[PS2Port] =
nullptr;
1090 if (RTC_SLOW_MEM[RTCMEM_PORTX_WORD_RX_READY]) {
1092 RTC_SLOW_MEM[RTCMEM_PORTX_WORD_RX_READY] = 0;
1093 if (ctrl->m_RXWaitTask[PS2Port]) {
1094 vTaskNotifyGiveFromISR(ctrl->m_RXWaitTask[PS2Port],
nullptr);
1095 ctrl->m_RXWaitTask[PS2Port] =
nullptr;
1104 WRITE_PERI_REG(RTC_CNTL_INT_CLR_REG, rtc_intr);
This file contains fabgl::PS2Controller definition.
int dataAvailable(int PS2Port)
Gets the number of scancodes available in the controller buffer.
Keyboard * keyboard()
Returns the instance of Keyboard object automatically created by PS2Controller.
void injectInRXBuffer(int value, int PS2Port)
Injects a byte into the RX buffer.
This file contains fabgl::Keyboard definition.
The PS2 Keyboard controller class.
This file contains fabgl::Mouse definition.
void sendData(uint8_t data, int PS2Port)
Sends a command to the device.
void begin(gpio_num_t clkGPIO, gpio_num_t dataGPIO, bool generateVirtualKeys=true, bool createVKQueue=true)
Initializes Keyboard specifying CLOCK and DATA GPIOs.
This file contains some utility classes and functions.
KbdMode
This enum defines how handle keyboard virtual keys.
The PS2 device controller class.
int getData(int PS2Port)
Gets a scancode from the queue.
void suspend()
Suspends PS/2 ports operations.
void begin(gpio_num_t clkGPIO, gpio_num_t dataGPIO)
Initializes Mouse specifying CLOCK and DATA GPIOs.
PS2Preset
This enum defines what is connected to PS/2 ports.
The PS2 Mouse controller class.
Mouse * mouse()
Returns the instance of Mouse object automatically created by PS2Controller.
void resume()
Resumes PS/2 ports operations.
void begin(gpio_num_t port0_clkGPIO, gpio_num_t port0_datGPIO, gpio_num_t port1_clkGPIO=GPIO_UNUSED, gpio_num_t port1_datGPIO=GPIO_UNUSED)
Initializes PS2 device controller.