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