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 "debug.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "wait.h"
|
#include "wait.h"
|
||||||
|
#include "ringbuf.h"
|
||||||
|
|
||||||
|
|
||||||
#define WAIT(stat, us, err) do { \
|
#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_protocol = IBMPC_PROTOCOL_NO;
|
||||||
volatile uint8_t ibmpc_error = IBMPC_ERR_NONE;
|
volatile uint8_t ibmpc_error = IBMPC_ERR_NONE;
|
||||||
|
|
||||||
/* 2-byte buffer for data received from keyboard
|
/* buffer for data received from device */
|
||||||
* buffer states:
|
#define RINGBUF_SIZE 16
|
||||||
* FFFF: empty
|
static uint8_t rbuf[RINGBUF_SIZE];
|
||||||
* FFss: one data
|
static ringbuf_t rb = {};
|
||||||
* 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;
|
|
||||||
/* internal state of receiving data */
|
/* internal state of receiving data */
|
||||||
static volatile uint16_t isr_state = 0x8000;
|
static volatile uint16_t isr_state = 0x8000;
|
||||||
static uint8_t timer_start = 0;
|
static uint8_t timer_start = 0;
|
||||||
|
|
@ -80,6 +77,7 @@ void ibmpc_host_init(void)
|
||||||
inhibit();
|
inhibit();
|
||||||
IBMPC_INT_INIT();
|
IBMPC_INT_INIT();
|
||||||
IBMPC_INT_OFF();
|
IBMPC_INT_OFF();
|
||||||
|
ringbuf_init(&rb, rbuf, RINGBUF_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ibmpc_host_enable(void)
|
void ibmpc_host_enable(void)
|
||||||
|
|
@ -180,60 +178,19 @@ ERROR:
|
||||||
*/
|
*/
|
||||||
int16_t ibmpc_host_recv(void)
|
int16_t ibmpc_host_recv(void)
|
||||||
{
|
{
|
||||||
uint16_t data = 0;
|
int16_t ret = -1;
|
||||||
uint8_t ret = 0xFF;
|
|
||||||
|
|
||||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
// Enable ISR if buffer was full
|
||||||
data = recv_data;
|
if (ringbuf_is_full(&rb)) {
|
||||||
|
|
||||||
// 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) {
|
|
||||||
ibmpc_host_isr_clear();
|
ibmpc_host_isr_clear();
|
||||||
IBMPC_INT_ON();
|
IBMPC_INT_ON();
|
||||||
idle();
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -254,7 +211,7 @@ void ibmpc_host_isr_clear(void)
|
||||||
ibmpc_protocol = 0;
|
ibmpc_protocol = 0;
|
||||||
ibmpc_error = 0;
|
ibmpc_error = 0;
|
||||||
isr_state = 0x8000;
|
isr_state = 0x8000;
|
||||||
recv_data = 0xFFFF;
|
ringbuf_reset(&rb);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LO8(w) (*((uint8_t *)&(w)))
|
#define LO8(w) (*((uint8_t *)&(w)))
|
||||||
|
|
@ -407,32 +364,19 @@ ISR(IBMPC_INT_VECT)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ERROR:
|
|
||||||
// error: eeFF
|
|
||||||
recv_data = (ibmpc_error<<8) | 0x00FF;
|
|
||||||
goto CLEAR;
|
|
||||||
DONE:
|
DONE:
|
||||||
if ((isr_state & 0x00FF) == 0x00FF) {
|
// store data
|
||||||
// receive error code 0xFF
|
if (!ringbuf_put(&rb, isr_state & 0xFF)) {
|
||||||
ibmpc_error = IBMPC_ERR_FF;
|
|
||||||
goto ERROR;
|
|
||||||
}
|
|
||||||
if (HI8(recv_data) != 0xFF && LO8(recv_data) != 0xFF) {
|
|
||||||
// buffer overflow
|
// buffer overflow
|
||||||
ibmpc_error = IBMPC_ERR_FULL;
|
ibmpc_error = IBMPC_ERR_FULL;
|
||||||
goto ERROR;
|
|
||||||
}
|
// Disable ISR if buffer is full
|
||||||
// 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) {
|
|
||||||
IBMPC_INT_OFF();
|
IBMPC_INT_OFF();
|
||||||
// inhibit: clock_lo
|
// inhibit: clock_lo
|
||||||
IBMPC_CLOCK_PORT &= ~(1<<IBMPC_CLOCK_BIT);
|
IBMPC_CLOCK_PORT &= ~(1<<IBMPC_CLOCK_BIT);
|
||||||
IBMPC_CLOCK_DDR |= (1<<IBMPC_CLOCK_BIT);
|
IBMPC_CLOCK_DDR |= (1<<IBMPC_CLOCK_BIT);
|
||||||
}
|
}
|
||||||
|
ERROR:
|
||||||
// clear for next data
|
// clear for next data
|
||||||
isr_state = 0x8000;
|
isr_state = 0x8000;
|
||||||
NEXT:
|
NEXT:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue