matrix.c 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /*
  2. * ----------------------------------------------------------------------------
  3. * "THE BEER-WARE LICENSE" (Revision 42):
  4. * <https://github.com/KarlK90> wrote this file. As long as you retain this
  5. * notice you can do whatever you want with this stuff. If we meet some day, and
  6. * you think this stuff is worth it, you can buy me a beer in return. KarlK90
  7. * ----------------------------------------------------------------------------
  8. */
  9. #include "matrix.h"
  10. #include "atomic_util.h"
  11. #include "gpio.h"
  12. static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
  13. void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
  14. /* Drive row pin low. */
  15. ATOMIC_BLOCK_FORCEON { writePinLow(row_pins[current_row]); }
  16. matrix_output_select_delay();
  17. /* Read all columns in one go, aka port scanning. */
  18. uint16_t porta = palReadPort(GPIOA);
  19. uint16_t portb = palReadPort(GPIOB);
  20. /* Order of pins on the mun is: A0, B11, B0, B10, B12, B2, A8
  21. Pin is active low, therefore we have to invert the result. */
  22. matrix_row_t cols = ~(((porta & (0x1 << 0)) >> 0) // A0 (0)
  23. | ((portb & (0x1 << 11)) >> 10) // B11 (1)
  24. | ((portb & (0x1 << 0)) << 2) // B0 (2)
  25. | ((portb & (0x1 << 10)) >> 7) // B10 (3)
  26. | ((portb & (0x1 << 12)) >> 8) // B12 (4)
  27. | ((portb & (0x1 << 2)) << 3) // B2 (5)
  28. | ((porta & (0x1 << 8)) >> 2)); // A8 (6)
  29. /* Reverse the order of columns for left hand as the board is flipped. */
  30. // if (isLeftHand) {
  31. // #if defined(__arm__)
  32. // /* rbit assembly reverses bit order of 32bit registers. */
  33. // uint32_t temp = cols;
  34. // __asm__("rbit %0, %1" : "=r"(temp) : "r"(temp));
  35. // cols = temp >> 24;
  36. // #else
  37. // /* RISC-V bit manipulation extension not present. Use bit-hack.
  38. // https://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits */
  39. // cols = (matrix_row_t)(((cols * 0x0802LU & 0x22110LU) | (cols * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16);
  40. // #endif
  41. // }
  42. current_matrix[current_row] = cols;
  43. /* Drive row pin high again. */
  44. ATOMIC_BLOCK_FORCEON { writePinHigh(row_pins[current_row]); }
  45. matrix_output_unselect_delay(current_row, row_pins[current_row] != 0);
  46. }
  47. #if defined(BUSY_WAIT)
  48. void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
  49. for (int32_t i = 0; i < BUSY_WAIT_INSTRUCTIONS; i++) {
  50. __asm__ volatile("nop" ::: "memory");
  51. }
  52. }
  53. #endif