Merge branch 'console_ringbuf_fix'
This commit is contained in:
commit
e3d7b50f63
4 changed files with 207 additions and 136 deletions
|
|
@ -92,7 +92,7 @@ uint8_t matrix_scan(void)
|
||||||
|
|
||||||
uint8_t code = xt_host_recv();
|
uint8_t code = xt_host_recv();
|
||||||
if (!code) return 0;
|
if (!code) return 0;
|
||||||
xprintf("%02X ", code);
|
dprintf("%02X ", code);
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case INIT:
|
case INIT:
|
||||||
switch (code) {
|
switch (code) {
|
||||||
|
|
|
||||||
73
tmk_core/common/ringbuf.h
Normal file
73
tmk_core/common/ringbuf.h
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
#ifndef RINGBUF_H
|
||||||
|
#define RINGBUF_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
// NOTE: buffer size must be 2^n and up to 255. size_mask should be 2^n - 1 due to using &(AND) instead of %(modulo)
|
||||||
|
typedef struct {
|
||||||
|
uint8_t *buffer;
|
||||||
|
uint8_t head;
|
||||||
|
uint8_t tail;
|
||||||
|
uint8_t size_mask;
|
||||||
|
} ringbuf_t;
|
||||||
|
|
||||||
|
static inline void ringbuf_init(ringbuf_t *buf, uint8_t *array, uint8_t size);
|
||||||
|
static inline int16_t ringbuf_get(ringbuf_t *buf);
|
||||||
|
static inline bool ringbuf_put(ringbuf_t *buf, uint8_t data);
|
||||||
|
static inline void ringbuf_write(ringbuf_t *buf, uint8_t data);
|
||||||
|
static inline bool ringbuf_is_empty(ringbuf_t *buf);
|
||||||
|
static inline bool ringbuf_is_full(ringbuf_t *buf);
|
||||||
|
static inline void ringbuf_reset(ringbuf_t *buf);
|
||||||
|
|
||||||
|
static inline void ringbuf_init(ringbuf_t *buf, uint8_t *array, uint8_t size)
|
||||||
|
{
|
||||||
|
buf->buffer = array;
|
||||||
|
buf->head = 0;
|
||||||
|
buf->tail = 0;
|
||||||
|
buf->size_mask = size - 1;
|
||||||
|
}
|
||||||
|
static inline int16_t ringbuf_get(ringbuf_t *buf)
|
||||||
|
{
|
||||||
|
if (ringbuf_is_empty(buf)) return -1;
|
||||||
|
uint8_t data = buf->buffer[buf->tail];
|
||||||
|
buf->tail++;
|
||||||
|
buf->tail &= buf->size_mask;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
static inline bool ringbuf_put(ringbuf_t *buf, uint8_t data)
|
||||||
|
{
|
||||||
|
if (ringbuf_is_full(buf)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buf->buffer[buf->head] = data;
|
||||||
|
buf->head++;
|
||||||
|
buf->head &= buf->size_mask;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// this overrides data in buffer when it is full
|
||||||
|
static inline void ringbuf_write(ringbuf_t *buf, uint8_t data)
|
||||||
|
{
|
||||||
|
buf->buffer[buf->head] = data;
|
||||||
|
buf->head++;
|
||||||
|
buf->head &= buf->size_mask;
|
||||||
|
// eat tail: override data yet to be consumed
|
||||||
|
if (buf->head == buf->tail) {
|
||||||
|
buf->tail++;
|
||||||
|
buf->tail &= buf->size_mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static inline bool ringbuf_is_empty(ringbuf_t *buf)
|
||||||
|
{
|
||||||
|
return (buf->head == buf->tail);
|
||||||
|
}
|
||||||
|
static inline bool ringbuf_is_full(ringbuf_t *buf)
|
||||||
|
{
|
||||||
|
return (((buf->head + 1) & buf->size_mask) == buf->tail);
|
||||||
|
}
|
||||||
|
static inline void ringbuf_reset(ringbuf_t *buf)
|
||||||
|
{
|
||||||
|
buf->head = 0;
|
||||||
|
buf->tail = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
#include "action.h"
|
#include "action.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
#include "sendchar.h"
|
#include "sendchar.h"
|
||||||
|
#include "ringbuf.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#ifdef SLEEP_LED_ENABLE
|
#ifdef SLEEP_LED_ENABLE
|
||||||
#include "sleep_led.h"
|
#include "sleep_led.h"
|
||||||
|
|
@ -89,60 +90,97 @@ host_driver_t lufa_driver = {
|
||||||
* Console
|
* Console
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#ifdef CONSOLE_ENABLE
|
#ifdef CONSOLE_ENABLE
|
||||||
static void Console_Task(void)
|
#define SENDBUF_SIZE 256
|
||||||
|
static uint8_t sbuf[SENDBUF_SIZE];
|
||||||
|
static ringbuf_t sendbuf = {
|
||||||
|
.buffer = sbuf,
|
||||||
|
.head = 0,
|
||||||
|
.tail = 0,
|
||||||
|
.size_mask = SENDBUF_SIZE - 1
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool console_putc(uint8_t c)
|
||||||
|
{
|
||||||
|
// return immediately if called while interrupt
|
||||||
|
if (!(SREG & (1<<SREG_I)))
|
||||||
|
goto EXIT;;
|
||||||
|
|
||||||
|
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||||
|
goto EXIT;;
|
||||||
|
|
||||||
|
uint8_t ep = Endpoint_GetCurrentEndpoint();
|
||||||
|
|
||||||
|
Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
|
||||||
|
if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
|
||||||
|
goto EXIT_RESTORE_EP;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write from buffer to endpoint bank
|
||||||
|
while (!ringbuf_is_empty(&sendbuf) && Endpoint_IsReadWriteAllowed()) {
|
||||||
|
Endpoint_Write_8(ringbuf_get(&sendbuf));
|
||||||
|
|
||||||
|
// clear bank when it is full
|
||||||
|
if (!Endpoint_IsReadWriteAllowed() && Endpoint_IsINReady()) {
|
||||||
|
Endpoint_ClearIN();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write c to bank directly if there is no others in buffer
|
||||||
|
if (ringbuf_is_empty(&sendbuf) && Endpoint_IsReadWriteAllowed()) {
|
||||||
|
Endpoint_Write_8(c);
|
||||||
|
Endpoint_SelectEndpoint(ep);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXIT_RESTORE_EP:
|
||||||
|
Endpoint_SelectEndpoint(ep);
|
||||||
|
EXIT:
|
||||||
|
return ringbuf_put(&sendbuf, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void console_flush(void)
|
||||||
{
|
{
|
||||||
/* Device must be connected and configured for the task to run */
|
|
||||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint8_t ep = Endpoint_GetCurrentEndpoint();
|
uint8_t ep = Endpoint_GetCurrentEndpoint();
|
||||||
|
|
||||||
#if 0
|
|
||||||
// TODO: impl receivechar()/recvchar()
|
|
||||||
Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
|
|
||||||
|
|
||||||
/* Check to see if a packet has been sent from the host */
|
|
||||||
if (Endpoint_IsOUTReceived())
|
|
||||||
{
|
|
||||||
/* Check to see if the packet contains data */
|
|
||||||
if (Endpoint_IsReadWriteAllowed())
|
|
||||||
{
|
|
||||||
/* Create a temporary buffer to hold the read in report from the host */
|
|
||||||
uint8_t ConsoleData[CONSOLE_EPSIZE];
|
|
||||||
|
|
||||||
/* Read Console Report Data */
|
|
||||||
Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
|
|
||||||
|
|
||||||
/* Process Console Report Data */
|
|
||||||
//ProcessConsoleHIDReport(ConsoleData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finalize the stream transfer to send the last packet */
|
|
||||||
Endpoint_ClearOUT();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* IN packet */
|
|
||||||
Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
|
Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
|
||||||
if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
|
if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
|
||||||
Endpoint_SelectEndpoint(ep);
|
Endpoint_SelectEndpoint(ep);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill empty bank
|
// write from buffer to endpoint bank
|
||||||
while (Endpoint_IsReadWriteAllowed())
|
while (!ringbuf_is_empty(&sendbuf) && Endpoint_IsReadWriteAllowed()) {
|
||||||
Endpoint_Write_8(0);
|
Endpoint_Write_8(ringbuf_get(&sendbuf));
|
||||||
|
|
||||||
// flash senchar packet
|
// clear bank when it is full
|
||||||
if (Endpoint_IsINReady()) {
|
if (!Endpoint_IsReadWriteAllowed() && Endpoint_IsINReady()) {
|
||||||
|
Endpoint_ClearIN();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear bank when there are chars in bank
|
||||||
|
if (Endpoint_BytesInEndpoint() && Endpoint_IsINReady()) {
|
||||||
|
// Windows needs to fill packet with 0
|
||||||
|
while (Endpoint_IsReadWriteAllowed()) {
|
||||||
|
Endpoint_Write_8(0);
|
||||||
|
}
|
||||||
Endpoint_ClearIN();
|
Endpoint_ClearIN();
|
||||||
}
|
}
|
||||||
|
|
||||||
Endpoint_SelectEndpoint(ep);
|
Endpoint_SelectEndpoint(ep);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static void Console_Task(void)
|
static void console_task(void)
|
||||||
{
|
{
|
||||||
|
static uint16_t fn = 0;
|
||||||
|
if (fn == USB_Device_GetFrameNumber()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fn = USB_Device_GetFrameNumber();
|
||||||
|
console_flush();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -205,24 +243,10 @@ void EVENT_USB_Device_WakeUp()
|
||||||
hook_usb_wakeup();
|
hook_usb_wakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONSOLE_ENABLE
|
|
||||||
static bool console_flush = false;
|
|
||||||
#define CONSOLE_FLUSH_SET(b) do { \
|
|
||||||
uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
// called every 1ms
|
// called every 1ms
|
||||||
void EVENT_USB_Device_StartOfFrame(void)
|
void EVENT_USB_Device_StartOfFrame(void)
|
||||||
{
|
{
|
||||||
static uint8_t count;
|
|
||||||
if (++count % 50) return;
|
|
||||||
count = 0;
|
|
||||||
|
|
||||||
if (!console_flush) return;
|
|
||||||
Console_Task();
|
|
||||||
console_flush = false;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Event handler for the USB_ConfigurationChanged event.
|
/** Event handler for the USB_ConfigurationChanged event.
|
||||||
* This is fired when the host sets the current configuration of the USB device after enumeration.
|
* This is fired when the host sets the current configuration of the USB device after enumeration.
|
||||||
|
|
@ -419,7 +443,7 @@ static uint8_t keyboard_leds(void)
|
||||||
|
|
||||||
static void send_keyboard(report_keyboard_t *report)
|
static void send_keyboard(report_keyboard_t *report)
|
||||||
{
|
{
|
||||||
uint8_t timeout = 255;
|
uint8_t timeout = 128;
|
||||||
|
|
||||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||||
return;
|
return;
|
||||||
|
|
@ -444,7 +468,7 @@ static void send_keyboard(report_keyboard_t *report)
|
||||||
Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
|
Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
|
||||||
|
|
||||||
/* Check if write ready for a polling interval around 10ms */
|
/* Check if write ready for a polling interval around 10ms */
|
||||||
while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
|
while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(80);
|
||||||
if (!Endpoint_IsReadWriteAllowed()) return;
|
if (!Endpoint_IsReadWriteAllowed()) return;
|
||||||
|
|
||||||
/* Write Keyboard Report Data */
|
/* Write Keyboard Report Data */
|
||||||
|
|
@ -531,72 +555,21 @@ static void send_consumer(uint16_t data)
|
||||||
* sendchar
|
* sendchar
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#ifdef CONSOLE_ENABLE
|
#ifdef CONSOLE_ENABLE
|
||||||
#define SEND_TIMEOUT 5
|
|
||||||
int8_t sendchar(uint8_t c)
|
int8_t sendchar(uint8_t c)
|
||||||
{
|
{
|
||||||
#ifdef LUFA_DEBUG_SUART
|
#ifdef LUFA_DEBUG_SUART
|
||||||
xmit(c);
|
xmit(c);
|
||||||
#endif
|
#endif
|
||||||
// Not wait once timeouted.
|
|
||||||
// Because sendchar() is called so many times, waiting each call causes big lag.
|
|
||||||
static bool timeouted = false;
|
|
||||||
|
|
||||||
// prevents Console_Task() from running during sendchar() runs.
|
bool r = console_putc(c);
|
||||||
// or char will be lost. These two function is mutually exclusive.
|
return (r ? 0 : -1);
|
||||||
CONSOLE_FLUSH_SET(false);
|
|
||||||
|
|
||||||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
uint8_t ep = Endpoint_GetCurrentEndpoint();
|
|
||||||
Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
|
|
||||||
if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
|
|
||||||
goto ERROR_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timeouted && !Endpoint_IsReadWriteAllowed()) {
|
|
||||||
goto ERROR_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
timeouted = false;
|
|
||||||
|
|
||||||
uint8_t timeout = SEND_TIMEOUT;
|
|
||||||
while (!Endpoint_IsReadWriteAllowed()) {
|
|
||||||
if (USB_DeviceState != DEVICE_STATE_Configured) {
|
|
||||||
goto ERROR_EXIT;
|
|
||||||
}
|
|
||||||
if (Endpoint_IsStalled()) {
|
|
||||||
goto ERROR_EXIT;
|
|
||||||
}
|
|
||||||
if (!(timeout--)) {
|
|
||||||
timeouted = true;
|
|
||||||
goto ERROR_EXIT;
|
|
||||||
}
|
|
||||||
_delay_ms(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Endpoint_Write_8(c);
|
|
||||||
|
|
||||||
// send when bank is full
|
|
||||||
if (!Endpoint_IsReadWriteAllowed()) {
|
|
||||||
while (!(Endpoint_IsINReady()));
|
|
||||||
Endpoint_ClearIN();
|
|
||||||
} else {
|
|
||||||
CONSOLE_FLUSH_SET(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Endpoint_SelectEndpoint(ep);
|
|
||||||
return 0;
|
|
||||||
ERROR_EXIT:
|
|
||||||
Endpoint_SelectEndpoint(ep);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int8_t sendchar(uint8_t c)
|
int8_t sendchar(uint8_t c)
|
||||||
{
|
{
|
||||||
#ifdef LUFA_DEBUG_SUART
|
#ifdef LUFA_DEBUG_SUART
|
||||||
xmit(c);
|
xmit(c);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -622,7 +595,6 @@ static void setup_usb(void)
|
||||||
|
|
||||||
USB_Init();
|
USB_Init();
|
||||||
|
|
||||||
// for Console_Task
|
|
||||||
USB_Device_EnableSOFEvents();
|
USB_Device_EnableSOFEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -635,15 +607,22 @@ int main(void)
|
||||||
SUART_OUT_DDR |= (1<<SUART_OUT_BIT);
|
SUART_OUT_DDR |= (1<<SUART_OUT_BIT);
|
||||||
SUART_OUT_PORT |= (1<<SUART_OUT_BIT);
|
SUART_OUT_PORT |= (1<<SUART_OUT_BIT);
|
||||||
#endif
|
#endif
|
||||||
print_set_sendchar(sendchar);
|
|
||||||
print("\r\ninit\n");
|
|
||||||
|
|
||||||
|
// setup sendchar: DO NOT USE print functions before this line
|
||||||
|
print_set_sendchar(sendchar);
|
||||||
|
host_set_driver(&lufa_driver);
|
||||||
|
|
||||||
|
print("Keyboard init.\n");
|
||||||
hook_early_init();
|
hook_early_init();
|
||||||
keyboard_setup();
|
keyboard_setup();
|
||||||
setup_usb();
|
setup_usb();
|
||||||
|
#ifdef SLEEP_LED_ENABLE
|
||||||
|
sleep_led_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
sei();
|
sei();
|
||||||
|
|
||||||
/* wait for USB startup & debug output */
|
/* wait for USB startup */
|
||||||
while (USB_DeviceState != DEVICE_STATE_Configured) {
|
while (USB_DeviceState != DEVICE_STATE_Configured) {
|
||||||
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||||
;
|
;
|
||||||
|
|
@ -652,27 +631,26 @@ int main(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait for Console startup */
|
|
||||||
// TODO: long delay often works anyhoo but proper startup would be better
|
|
||||||
uint16_t delay = 2000;
|
|
||||||
while (delay--) {
|
|
||||||
#ifndef INTERRUPT_CONTROL_ENDPOINT
|
|
||||||
USB_USBTask();
|
|
||||||
#endif
|
|
||||||
_delay_ms(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
print("USB configured.\n");
|
|
||||||
|
|
||||||
/* init modules */
|
|
||||||
keyboard_init();
|
keyboard_init();
|
||||||
host_set_driver(&lufa_driver);
|
|
||||||
#ifdef SLEEP_LED_ENABLE
|
/* wait for Console startup */
|
||||||
sleep_led_init();
|
// TODO: 2000ms delay often works anyhoo but proper startup would be better
|
||||||
#endif
|
// 1000ms delay of hid_listen affects this probably
|
||||||
|
#ifdef CONSOLE_ENABLE
|
||||||
|
if (debug_enable) {
|
||||||
|
uint16_t delay = 2000;
|
||||||
|
while (delay--) {
|
||||||
|
#ifndef INTERRUPT_CONTROL_ENDPOINT
|
||||||
|
USB_USBTask();
|
||||||
|
#endif
|
||||||
|
_delay_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hook_late_init();
|
||||||
|
|
||||||
print("Keyboard start.\n");
|
print("Keyboard start.\n");
|
||||||
hook_late_init();
|
|
||||||
while (1) {
|
while (1) {
|
||||||
while (USB_DeviceState == DEVICE_STATE_Suspended) {
|
while (USB_DeviceState == DEVICE_STATE_Suspended) {
|
||||||
#ifdef LUFA_DEBUG
|
#ifdef LUFA_DEBUG
|
||||||
|
|
@ -683,6 +661,10 @@ int main(void)
|
||||||
|
|
||||||
keyboard_task();
|
keyboard_task();
|
||||||
|
|
||||||
|
#ifdef CONSOLE_ENABLE
|
||||||
|
console_task();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||||
USB_USBTask();
|
USB_USBTask();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,20 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include "pbuff.h"
|
|
||||||
#include "xt.h"
|
#include "xt.h"
|
||||||
#include "wait.h"
|
#include "wait.h"
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
|
#include "ringbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define BUF_SIZE 16
|
||||||
|
static uint8_t buf[BUF_SIZE];
|
||||||
|
static ringbuf_t rb = {
|
||||||
|
.buffer = buf,
|
||||||
|
.head = 0,
|
||||||
|
.tail = 0,
|
||||||
|
.size_mask = BUF_SIZE - 1
|
||||||
|
};
|
||||||
|
|
||||||
void xt_host_init(void)
|
void xt_host_init(void)
|
||||||
{
|
{
|
||||||
|
|
@ -69,10 +79,12 @@ void xt_host_init(void)
|
||||||
/* get data received by interrupt */
|
/* get data received by interrupt */
|
||||||
uint8_t xt_host_recv(void)
|
uint8_t xt_host_recv(void)
|
||||||
{
|
{
|
||||||
if (pbuf_has_data()) {
|
if (ringbuf_is_empty(&rb)) {
|
||||||
return pbuf_dequeue();
|
|
||||||
} else {
|
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
int16_t d = ringbuf_get(&rb);
|
||||||
|
XT_DATA_IN(); // ready to receive from keyboard
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +123,11 @@ ISR(XT_INT_VECT)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (state++ == BIT7) {
|
if (state++ == BIT7) {
|
||||||
pbuf_enqueue(data);
|
ringbuf_put(&rb, data);
|
||||||
|
if (ringbuf_is_full(&rb)) {
|
||||||
|
XT_DATA_LO(); // inhibit keyboard sending
|
||||||
|
print("Full");
|
||||||
|
}
|
||||||
state = START;
|
state = START;
|
||||||
data = 0;
|
data = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue