You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
2.3 KiB

  1. #include <stdbool.h>
  2. #include "action.h"
  3. #include "i2cmaster.h"
  4. #include "expander.h"
  5. #include "debug.h"
  6. static uint8_t expander_status = 0;
  7. static uint8_t expander_input = 0;
  8. void expander_config(void);
  9. uint8_t expander_write(uint8_t reg, uint8_t data);
  10. uint8_t expander_read(uint8_t reg, uint8_t *data);
  11. void expander_init(void)
  12. {
  13. i2c_init();
  14. expander_scan();
  15. }
  16. void expander_scan(void)
  17. {
  18. dprintf("expander status: %d ... ", expander_status);
  19. uint8_t ret = i2c_start(EXPANDER_ADDR | I2C_WRITE);
  20. if (ret == 0) {
  21. i2c_stop();
  22. if (expander_status == 0) {
  23. dprintf("attached\n");
  24. expander_status = 1;
  25. expander_config();
  26. clear_keyboard();
  27. }
  28. }
  29. else {
  30. if (expander_status == 1) {
  31. dprintf("detached\n");
  32. expander_status = 0;
  33. clear_keyboard();
  34. }
  35. }
  36. dprintf("%d\n", expander_status);
  37. }
  38. void expander_read_cols(void)
  39. {
  40. expander_read(EXPANDER_REG_GPIOA, &expander_input);
  41. }
  42. uint8_t expander_get_col(uint8_t col)
  43. {
  44. if (col > 4) {
  45. col++;
  46. }
  47. return expander_input & (1<<col) ? 1 : 0;
  48. }
  49. matrix_row_t expander_read_row(void)
  50. {
  51. expander_read_cols();
  52. /* make cols */
  53. matrix_row_t cols = 0;
  54. for (uint8_t col = 0; col < MATRIX_COLS; col++) {
  55. if (expander_get_col(col)) {
  56. cols |= (1UL << (MATRIX_COLS - 1 - col));
  57. }
  58. }
  59. return cols;
  60. }
  61. void expander_unselect_rows(void)
  62. {
  63. expander_write(EXPANDER_REG_IODIRB, 0xFF);
  64. }
  65. void expander_select_row(uint8_t row)
  66. {
  67. expander_write(EXPANDER_REG_IODIRB, ~(1<<(row+1)));
  68. }
  69. void expander_config(void)
  70. {
  71. expander_write(EXPANDER_REG_IPOLA, 0xFF);
  72. expander_write(EXPANDER_REG_GPPUA, 0xFF);
  73. expander_write(EXPANDER_REG_IODIRB, 0xFF);
  74. }
  75. uint8_t expander_write(uint8_t reg, uint8_t data)
  76. {
  77. if (expander_status == 0) {
  78. return 0;
  79. }
  80. uint8_t ret;
  81. ret = i2c_start(EXPANDER_ADDR | I2C_WRITE);
  82. if (ret) goto stop;
  83. ret = i2c_write(reg);
  84. if (ret) goto stop;
  85. ret = i2c_write(data);
  86. stop:
  87. i2c_stop();
  88. return ret;
  89. }
  90. uint8_t expander_read(uint8_t reg, uint8_t *data)
  91. {
  92. if (expander_status == 0) {
  93. return 0;
  94. }
  95. uint8_t ret;
  96. ret = i2c_start(EXPANDER_ADDR | I2C_WRITE);
  97. if (ret) goto stop;
  98. ret = i2c_write(reg);
  99. if (ret) goto stop;
  100. ret = i2c_rep_start(EXPANDER_ADDR | I2C_READ);
  101. if (ret) goto stop;
  102. *data = i2c_readNak();
  103. stop:
  104. i2c_stop();
  105. return ret;
  106. }