keypad.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. keycode = prev_keycode;
  22. if(! pio_sm_is_rx_fifo_empty(pio0, 0)) {
  23. keycode = pio_sm_get(pio0, 0);
  24. }
  25. uint32_t changed_bit = keycode ^ prev_keycode;
  26. prev_keycode = keycode;
  27. for(uint16_t idx = 0; idx < 16; idx++) {
  28. if(changed_bit & 1) {
  29. keystate_buffer[write_p & 0xF].code = idx;
  30. keystate_buffer[write_p & 0xF].state = keycode & 1;
  31. gpio_put(LED_PIN, keystate_buffer[write_p & 0xF].state);
  32. write_p++;
  33. }
  34. changed_bit >>= 1;
  35. keycode >>= 1;
  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, pio_irq_handler );
  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. key_t get_key(void)
  56. {
  57. key_t retval;
  58. uint wp;
  59. wp = write_p;
  60. if(wp != read_p) {
  61. retval.code = keystate_buffer[read_p & 0x0F].code;
  62. retval.state = keystate_buffer[read_p & 0xF].state;
  63. read_p++;
  64. }
  65. else {
  66. retval.code = 0;
  67. retval.state = KEYPAD_INVALID;
  68. }
  69. return retval;
  70. }