logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

v3.c (3457B)


  1. #include "quantum.h"
  2. #if defined(__AVR__)
  3. # include <avr/io.h>
  4. # include <avr/interrupt.h>
  5. #endif
  6. #define ROWS_PER_HAND (MATRIX_ROWS / 2)
  7. #define SLAVE_MATRIX_SYNC_ADDR (0x01)
  8. typedef struct {
  9. char* buffer;
  10. size_t count;
  11. bool* flag;
  12. } transmit_status;
  13. transmit_status irx = {}, itx = {};
  14. // Buffer for master/slave matrix scan transmit.
  15. // Master: receive buffer.
  16. // Slave: transmit buffer.
  17. matrix_row_t sync_matrix[ROWS_PER_HAND];
  18. bool matrix_synced = false;
  19. void USART_init(uint16_t baud) {
  20. cli();
  21. // UBRR1H = (unsigned char)(baud >>8);
  22. // UBRR1L = (unsigned char)(baud);
  23. UBRR1 = baud;
  24. // Enable U2X1 for double speed.
  25. UCSR1A = (1 << U2X1);
  26. // Enable RX/TX, 9N1 mode
  27. UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1) | (1 << TXCIE1) | (1 << UCSZ12);
  28. UCSR1C = (1 << UCSZ10) | (1 << UCSZ11);
  29. sei();
  30. }
  31. ISR(USART1_RX_vect) {
  32. // read data from reg.
  33. uint8_t status = UCSR1A;
  34. uint8_t high_bit = UCSR1B;
  35. uint8_t low_data = UDR1;
  36. if (status & ((1 << FE1) | (1 << DOR1) | (1 << UPE1))) {
  37. // Something error happen, ignore this package.
  38. irx.count = 0;
  39. return;
  40. }
  41. // Is it a addr? (9th bit is one/zero?)
  42. if (high_bit & (1 << RXB81)) {
  43. // data is addr. prepend for receive.
  44. switch (low_data) {
  45. case SLAVE_MATRIX_SYNC_ADDR:
  46. irx.buffer = (char *)sync_matrix;
  47. irx.count = sizeof(sync_matrix) * sizeof(matrix_row_t);
  48. irx.flag = &matrix_synced;
  49. break;
  50. default:
  51. // ignore this package.
  52. irx.count = 0;
  53. break;
  54. }
  55. } else if (irx.count > 0) {
  56. *irx.buffer = low_data;
  57. ++irx.buffer;
  58. if (--irx.count == 0 && irx.flag != NULL) {
  59. *irx.flag = true;
  60. }
  61. }
  62. }
  63. // TX complete
  64. ISR(USART1_TX_vect) {
  65. // Is in transmit?
  66. if (itx.count > 0) {
  67. // Send data.
  68. UCSR1B &= ~(1 << TXB81);
  69. UDR1 = *itx.buffer;
  70. // Move to next char.
  71. ++itx.buffer;
  72. if (--itx.count == 0) {
  73. *itx.flag = true;
  74. }
  75. }
  76. // TODO: read queue/register for next message.
  77. }
  78. // return: queue depth.
  79. int send_packet(uint8_t addr, char* buffer, size_t length, bool* flag) {
  80. // See if we can start transmit right now.
  81. if ((itx.count == 0) && (UCSR1A & (1 << UDRE1))) {
  82. // Ready to write.
  83. // Prepend registers.
  84. itx.buffer = buffer;
  85. itx.count = length;
  86. itx.flag = flag;
  87. // Write addr to kick start transmit.
  88. UCSR1B |= (1 << TXB81);
  89. UDR1 = addr;
  90. // TODO: put request in queue;
  91. // }else{
  92. }
  93. return 0;
  94. }
  95. void transport_master_init(void) { USART_init(0); }
  96. void transport_slave_init(void) { USART_init(0); }
  97. // returns false if valid data not received from slave
  98. bool transport_master(matrix_row_t matrix[]) {
  99. if (matrix_synced) {
  100. for (uint8_t i = 0; i < ROWS_PER_HAND; ++i) {
  101. matrix[i] = sync_matrix[i];
  102. }
  103. matrix_synced = false;
  104. return true;
  105. }
  106. return false;
  107. }
  108. void transport_slave(matrix_row_t matrix[]) {
  109. for (uint8_t i = 0; i < ROWS_PER_HAND; ++i) {
  110. sync_matrix[i] = matrix[i];
  111. }
  112. matrix_synced = false;
  113. send_packet(SLAVE_MATRIX_SYNC_ADDR, (char*)sync_matrix, sizeof(sync_matrix) * sizeof(matrix_row_t), &matrix_synced);
  114. }