[Keyboard] Add Whale's Split Keyboard(ver.3) (#9859)
Co-authored-by: Joel Challis <git@zvecr.com> Co-authored-by: Ryan <fauxpark@gmail.com> Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com>
This commit is contained in:
parent
2d8703f6cc
commit
871d35aa43
11 changed files with 1328 additions and 0 deletions
134
keyboards/whale/sk/v3/v3.c
Normal file
134
keyboards/whale/sk/v3/v3.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
#include "v3.h"
|
||||
|
||||
#if defined(__AVR__)
|
||||
# include <avr/io.h>
|
||||
# include <avr/interrupt.h>
|
||||
#endif
|
||||
|
||||
#define ROWS_PER_HAND (MATRIX_ROWS / 2)
|
||||
#define SLAVE_MATRIX_SYNC_ADDR (0x01)
|
||||
|
||||
typedef struct {
|
||||
char* buffer;
|
||||
size_t count;
|
||||
bool* flag;
|
||||
} transmit_status;
|
||||
|
||||
transmit_status irx = {}, itx = {};
|
||||
|
||||
// Buffer for master/slave matrix scan transmit.
|
||||
// Master: receive buffer.
|
||||
// Slave: transmit buffer.
|
||||
matrix_row_t sync_matrix[ROWS_PER_HAND];
|
||||
bool matrix_synced = false;
|
||||
|
||||
void USART_init(uint16_t baud) {
|
||||
cli();
|
||||
|
||||
// UBRR1H = (unsigned char)(baud >>8);
|
||||
// UBRR1L = (unsigned char)(baud);
|
||||
UBRR1 = baud;
|
||||
// Enable U2X1 for double speed.
|
||||
UCSR1A = (1 << U2X1);
|
||||
// Enable RX/TX, 9N1 mode
|
||||
UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1) | (1 << TXCIE1) | (1 << UCSZ12);
|
||||
UCSR1C = (1 << UCSZ10) | (1 << UCSZ11);
|
||||
sei();
|
||||
}
|
||||
|
||||
ISR(USART1_RX_vect) {
|
||||
// read data from reg.
|
||||
uint8_t status = UCSR1A;
|
||||
uint8_t high_bit = UCSR1B;
|
||||
uint8_t low_data = UDR1;
|
||||
if (status & ((1 << FE1) | (1 << DOR1) | (1 << UPE1))) {
|
||||
// Something error happen, ignore this package.
|
||||
irx.count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Is it a addr? (9th bit is one/zero?)
|
||||
if (high_bit & (1 << RXB81)) {
|
||||
// data is addr. prepend for receive.
|
||||
switch (low_data) {
|
||||
case SLAVE_MATRIX_SYNC_ADDR:
|
||||
irx.buffer = (char *)sync_matrix;
|
||||
irx.count = sizeof(sync_matrix) * sizeof(matrix_row_t);
|
||||
irx.flag = &matrix_synced;
|
||||
break;
|
||||
|
||||
default:
|
||||
// ignore this package.
|
||||
irx.count = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (irx.count > 0) {
|
||||
*irx.buffer = low_data;
|
||||
++irx.buffer;
|
||||
if (--irx.count == 0 && irx.flag != NULL) {
|
||||
*irx.flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TX complete
|
||||
ISR(USART1_TX_vect) {
|
||||
// Is in transmit?
|
||||
if (itx.count > 0) {
|
||||
// Send data.
|
||||
UCSR1B &= ~(1 << TXB81);
|
||||
UDR1 = *itx.buffer;
|
||||
|
||||
// Move to next char.
|
||||
++itx.buffer;
|
||||
if (--itx.count == 0) {
|
||||
*itx.flag = true;
|
||||
}
|
||||
}
|
||||
// TODO: read queue/register for next message.
|
||||
}
|
||||
|
||||
// return: queue depth.
|
||||
int send_packet(uint8_t addr, char* buffer, size_t length, bool* flag) {
|
||||
// See if we can start transmit right now.
|
||||
if ((itx.count == 0) && (UCSR1A & (1 << UDRE1))) {
|
||||
// Ready to write.
|
||||
// Prepend registers.
|
||||
itx.buffer = buffer;
|
||||
itx.count = length;
|
||||
itx.flag = flag;
|
||||
|
||||
// Write addr to kick start transmit.
|
||||
UCSR1B |= (1 << TXB81);
|
||||
UDR1 = addr;
|
||||
// TODO: put request in queue;
|
||||
// }else{
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void transport_master_init(void) { USART_init(0); }
|
||||
|
||||
void transport_slave_init(void) { USART_init(0); }
|
||||
|
||||
// returns false if valid data not received from slave
|
||||
bool transport_master(matrix_row_t matrix[]) {
|
||||
if (matrix_synced) {
|
||||
for (uint8_t i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
matrix[i] = sync_matrix[i];
|
||||
}
|
||||
matrix_synced = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void transport_slave(matrix_row_t matrix[]) {
|
||||
for (uint8_t i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
sync_matrix[i] = matrix[i];
|
||||
}
|
||||
matrix_synced = false;
|
||||
send_packet(SLAVE_MATRIX_SYNC_ADDR, (char*)sync_matrix, sizeof(sync_matrix) * sizeof(matrix_row_t), &matrix_synced);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue