ibmpc: Replace unit16_t recv_data with ringbuf
This commit is contained in:
parent
d13ce4d06f
commit
c3a0141878
1 changed files with 21 additions and 77 deletions
|
|
@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "debug.h"
|
||||
#include "timer.h"
|
||||
#include "wait.h"
|
||||
#include "ringbuf.h"
|
||||
|
||||
|
||||
#define WAIT(stat, us, err) do { \
|
||||
|
|
@ -60,15 +61,11 @@ volatile uint16_t ibmpc_isr_debug = 0;
|
|||
volatile uint8_t ibmpc_protocol = IBMPC_PROTOCOL_NO;
|
||||
volatile uint8_t ibmpc_error = IBMPC_ERR_NONE;
|
||||
|
||||
/* 2-byte buffer for data received from keyboard
|
||||
* buffer states:
|
||||
* FFFF: empty
|
||||
* FFss: one data
|
||||
* sstt: two data
|
||||
* eeFF: error
|
||||
* where ss, tt and ee are 0x00-0xFE. 0xFF means empty or no data in buffer.
|
||||
*/
|
||||
static volatile uint16_t recv_data = 0xFFFF;
|
||||
/* buffer for data received from device */
|
||||
#define RINGBUF_SIZE 16
|
||||
static uint8_t rbuf[RINGBUF_SIZE];
|
||||
static ringbuf_t rb = {};
|
||||
|
||||
/* internal state of receiving data */
|
||||
static volatile uint16_t isr_state = 0x8000;
|
||||
static uint8_t timer_start = 0;
|
||||
|
|
@ -80,6 +77,7 @@ void ibmpc_host_init(void)
|
|||
inhibit();
|
||||
IBMPC_INT_INIT();
|
||||
IBMPC_INT_OFF();
|
||||
ringbuf_init(&rb, rbuf, RINGBUF_SIZE);
|
||||
}
|
||||
|
||||
void ibmpc_host_enable(void)
|
||||
|
|
@ -180,60 +178,19 @@ ERROR:
|
|||
*/
|
||||
int16_t ibmpc_host_recv(void)
|
||||
{
|
||||
uint16_t data = 0;
|
||||
uint8_t ret = 0xFF;
|
||||
int16_t ret = -1;
|
||||
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
data = recv_data;
|
||||
|
||||
// remove data from buffer:
|
||||
// FFFF(empty) -> FFFF
|
||||
// FFss(one data) -> FFFF
|
||||
// sstt(two data) -> FFtt
|
||||
// eeFF(errror) -> FFFF
|
||||
recv_data = data | (((data&0xFF00) == 0xFF00) ? 0x00FF : 0xFF00);
|
||||
}
|
||||
|
||||
if ((data&0x00FF) == 0x00FF) {
|
||||
// error: eeFF
|
||||
switch (data>>8) {
|
||||
case IBMPC_ERR_FF:
|
||||
// 0xFF(Overrun/Error) from keyboard
|
||||
dprintf("!FF! ");
|
||||
ret = 0xFF;
|
||||
break;
|
||||
case IBMPC_ERR_FULL:
|
||||
// buffer overflow
|
||||
dprintf("!OVF! ");
|
||||
ret = 0xFF;
|
||||
break;
|
||||
case 0xFF:
|
||||
// empty: FFFF
|
||||
return -1;
|
||||
default:
|
||||
// other errors
|
||||
dprintf("e%02X ", data>>8);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if ((data | 0x00FF) != 0xFFFF) {
|
||||
// two data: sstt
|
||||
dprintf("b:%04X ", data);
|
||||
ret = (data>>8);
|
||||
} else {
|
||||
// one data: FFss
|
||||
ret = (data&0x00FF);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable ISR if recv_data is not full
|
||||
if ((recv_data | 0x00FF) == 0xFFFF) {
|
||||
// Enable ISR if buffer was full
|
||||
if (ringbuf_is_full(&rb)) {
|
||||
ibmpc_host_isr_clear();
|
||||
IBMPC_INT_ON();
|
||||
idle();
|
||||
}
|
||||
//dprintf("i%04X ", ibmpc_isr_debug); ibmpc_isr_debug = 0;
|
||||
dprintf("r%02X ", ret);
|
||||
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
ret = ringbuf_get(&rb);
|
||||
}
|
||||
if (ret != -1) dprintf("r%02X ", ret&0xFF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +211,7 @@ void ibmpc_host_isr_clear(void)
|
|||
ibmpc_protocol = 0;
|
||||
ibmpc_error = 0;
|
||||
isr_state = 0x8000;
|
||||
recv_data = 0xFFFF;
|
||||
ringbuf_reset(&rb);
|
||||
}
|
||||
|
||||
#define LO8(w) (*((uint8_t *)&(w)))
|
||||
|
|
@ -407,32 +364,19 @@ ISR(IBMPC_INT_VECT)
|
|||
break;
|
||||
}
|
||||
|
||||
ERROR:
|
||||
// error: eeFF
|
||||
recv_data = (ibmpc_error<<8) | 0x00FF;
|
||||
goto CLEAR;
|
||||
DONE:
|
||||
if ((isr_state & 0x00FF) == 0x00FF) {
|
||||
// receive error code 0xFF
|
||||
ibmpc_error = IBMPC_ERR_FF;
|
||||
goto ERROR;
|
||||
}
|
||||
if (HI8(recv_data) != 0xFF && LO8(recv_data) != 0xFF) {
|
||||
// store data
|
||||
if (!ringbuf_put(&rb, isr_state & 0xFF)) {
|
||||
// buffer overflow
|
||||
ibmpc_error = IBMPC_ERR_FULL;
|
||||
goto ERROR;
|
||||
}
|
||||
// store data
|
||||
recv_data = recv_data<<8;
|
||||
recv_data |= isr_state & 0xFF;
|
||||
CLEAR:
|
||||
// Disable ISR if recv_data is full
|
||||
if ((recv_data | 0x00FF) != 0xFFFF) {
|
||||
|
||||
// Disable ISR if buffer is full
|
||||
IBMPC_INT_OFF();
|
||||
// inhibit: clock_lo
|
||||
IBMPC_CLOCK_PORT &= ~(1<<IBMPC_CLOCK_BIT);
|
||||
IBMPC_CLOCK_DDR |= (1<<IBMPC_CLOCK_BIT);
|
||||
}
|
||||
ERROR:
|
||||
// clear for next data
|
||||
isr_state = 0x8000;
|
||||
NEXT:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue