keypad.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include <stdio.h>
  2. #include "pico/stdlib.h"
  3. #include "hardware/pio.h"
  4. #include "hardware/clocks.h"
  5. #include "pico/multicore.h"
  6. #include "keypad_scanner.pio.h"
  7. #include "keypad.h"
  8. volatile uint write_p = 0; // バッファ書き込みインデックス
  9. volatile uint read_p = 0; // バッファ読み出しインデックス
  10. // キーバッファ
  11. volatile key_t keystate_buffer[KEYPAD_BUFFER_SIZE];
  12. // LED
  13. const uint LED_PIN = PICO_DEFAULT_LED_PIN;
  14. // PIO割り込みハンドラ
  15. void pio_irq_handler(void)
  16. {
  17. static uint32_t prev_keycode = 0;
  18. uint32_t keycode;
  19. // IRQクリア
  20. pio_interrupt_clear(pio0, 0);
  21. while(! pio_sm_is_rx_fifo_empty(pio0, 0)) {
  22. keycode = pio_sm_get(pio0, 0);
  23. uint32_t changed_bit = keycode ^ prev_keycode;
  24. prev_keycode = keycode;
  25. for(uint16_t idx = 0; idx < 16; idx++) {
  26. if(changed_bit & 1) {
  27. keystate_buffer[write_p & 0xF].code = idx;
  28. keystate_buffer[write_p & 0xF].state = keycode & 1;
  29. gpio_put(LED_PIN, keystate_buffer[write_p & 0xF].state);
  30. write_p++;
  31. }
  32. changed_bit >>= 1;
  33. keycode >>= 1;
  34. }
  35. }
  36. }
  37. // キーパッド初期化
  38. void keypad_init()
  39. {
  40. // オンボードLED
  41. gpio_init(LED_PIN);
  42. gpio_set_dir(LED_PIN, GPIO_OUT);
  43. gpio_put(LED_PIN, 0);
  44. // PIO
  45. PIO pio = pio0;
  46. // PIO割り込みの設定
  47. irq_set_exclusive_handler(PIO0_IRQ_0, pio_irq_handler);
  48. irq_set_enabled(PIO0_IRQ_0, true);
  49. pio_set_irq0_source_enabled(pio,pis_interrupt0, true );
  50. uint offset = pio_add_program(pio, &keypad_scanner_program);
  51. keypad_scanner_program_init(pio, 0, offset, ROW_BASE, COLUMN_BASE, 16000);
  52. // SM起動
  53. pio_sm_set_enabled(pio, 0, true);
  54. }
  55. // キーバッファからデータを取り出す
  56. key_t get_key(void)
  57. {
  58. key_t retval;
  59. uint wp;
  60. wp = write_p;
  61. if(wp != read_p) {
  62. retval.code = keystate_buffer[read_p & 0x0F].code;
  63. retval.state = keystate_buffer[read_p & 0xF].state;
  64. read_p++;
  65. }
  66. else {
  67. retval.code = 0;
  68. retval.state = KEYPAD_INVALID;
  69. }
  70. return retval;
  71. }