Dir cleanup
This commit is contained in:
138
src/paracomm.c
Normal file
138
src/paracomm.c
Normal file
@@ -0,0 +1,138 @@
|
||||
#include "paracomm.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define kMosiIdleByte 0x00
|
||||
#define kMosiStartByte 0x42
|
||||
#define kMisoIdleNibble 0x0
|
||||
#define kMisoStartNibble 0xa
|
||||
|
||||
static uint8_t mosi_workbuf[2][256];
|
||||
static uint8_t mosi_workbuf_idx;
|
||||
static uint8_t mosi_workbuf_size;
|
||||
|
||||
static uint8_t* mosi_sendbuf;
|
||||
static uint8_t mosi_size;
|
||||
static uint8_t mosi_sent;
|
||||
|
||||
static uint8_t mosi_state;
|
||||
|
||||
static uint8_t miso_recvbuf[256];
|
||||
static uint8_t miso_size;
|
||||
static uint8_t miso_received_nibbles;
|
||||
static uint8_t miso_state;
|
||||
|
||||
static void swapbuffers() {
|
||||
mosi_sendbuf = mosi_workbuf[mosi_workbuf_idx];
|
||||
mosi_size = mosi_workbuf_size;
|
||||
|
||||
mosi_workbuf_size = 0;
|
||||
mosi_workbuf_idx = (mosi_workbuf_idx + 1) % 2;
|
||||
}
|
||||
|
||||
uint8_t paracomm_nextbyte() {
|
||||
switch (mosi_state) {
|
||||
case 0:
|
||||
if (mosi_size == 0) {
|
||||
swapbuffers();
|
||||
if (mosi_size == 0) {
|
||||
return kMosiIdleByte;
|
||||
}
|
||||
}
|
||||
mosi_state = 1;
|
||||
return kMosiStartByte;
|
||||
case 1:
|
||||
// assert(mosi_size > 0)
|
||||
mosi_sent = 0;
|
||||
mosi_state = 2;
|
||||
return mosi_size;
|
||||
case 2: {
|
||||
uint8_t b = mosi_sendbuf[mosi_sent];
|
||||
mosi_sent += 1;
|
||||
|
||||
if (mosi_sent == mosi_size) {
|
||||
swapbuffers();
|
||||
mosi_state = 0;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void paracomm_feed(uint8_t n) {
|
||||
switch (miso_state) {
|
||||
case 0:
|
||||
if (n == kMisoStartNibble) {
|
||||
miso_state = 1;
|
||||
} else if (n == kMisoIdleNibble) {
|
||||
} else {
|
||||
// error: spurious nibble
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
miso_size = n;
|
||||
miso_state = 2;
|
||||
break;
|
||||
case 2:
|
||||
miso_size += n << 4;
|
||||
miso_received_nibbles = 0;
|
||||
miso_state = 3;
|
||||
break;
|
||||
case 3: {
|
||||
uint8_t idx = miso_received_nibbles / 2;
|
||||
if (miso_received_nibbles % 2 == 0) {
|
||||
miso_recvbuf[idx] = n;
|
||||
} else {
|
||||
miso_recvbuf[idx] += n << 4;
|
||||
}
|
||||
miso_received_nibbles += 1;
|
||||
|
||||
if (miso_received_nibbles == 2 * miso_size) {
|
||||
miso_state = 0;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void paracomm_init() {
|
||||
mosi_size = 0;
|
||||
mosi_workbuf_idx = 0;
|
||||
mosi_workbuf_size = 0;
|
||||
mosi_state = 0;
|
||||
|
||||
miso_state = 0;
|
||||
}
|
||||
|
||||
int paracomm_send(uint8_t b) {
|
||||
if (mosi_workbuf_size == 256) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t* buff = mosi_workbuf[mosi_workbuf_idx];
|
||||
buff[mosi_workbuf_size] = b;
|
||||
mosi_workbuf_size += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t paracomm_recv(uint8_t* buf, uint8_t size) {
|
||||
if (miso_state != 0) {
|
||||
return 0;
|
||||
}
|
||||
if (size > miso_size) {
|
||||
size = miso_size;
|
||||
}
|
||||
memcpy(buf, miso_recvbuf, size);
|
||||
memcpy(miso_recvbuf, miso_recvbuf+size, miso_size - size);
|
||||
miso_size -= size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
uint8_t paracomm_busy() {
|
||||
return mosi_state != 0 || miso_state != 0;
|
||||
}
|
Reference in New Issue
Block a user