165 lines
4.1 KiB
C++
165 lines
4.1 KiB
C++
#include <Arduino.h>
|
|
#include "log.h"
|
|
#include "comms.h"
|
|
#include "lua.hpp"
|
|
|
|
#define HWS Serial2
|
|
|
|
#define PACK_OVERHEAD 5
|
|
#define BUFF_SIZE 128
|
|
|
|
uint8_t buff[BUFF_SIZE + 1]; // makes it easier to handle a trailing null
|
|
|
|
int maybe_packet(uint8_t *p) {
|
|
uint8_t type = p[0];
|
|
|
|
if (type < 32)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
uint16_t packet_length(uint8_t *p) {
|
|
if (!maybe_packet(p)) {
|
|
return -1;
|
|
}
|
|
|
|
uint16_t l = p[1] << 8 + p[2];
|
|
return l;
|
|
}
|
|
|
|
uint16_t crc16(uint8_t *p, int l) {
|
|
return 1; // TODO actually make this generate crcs
|
|
}
|
|
|
|
// takes in a max size, how many bytes are received and how many should be
|
|
int read_pack(uint8_t *p, uint16_t max, uint16_t recv_len, uint16_t pack_len) {
|
|
if (pack_len == 0) // quick shortcut
|
|
return 0;
|
|
|
|
if (recv_len < pack_len) { // if we haven't received everything, we should try
|
|
if (pack_len > max) { // packet is too large to fit in buffer, return -1
|
|
return -1; // say we can't handle this with the buffer provided
|
|
} else {
|
|
uint16_t i = pack_len - recv_len; // off by one?
|
|
uint16_t q = 0;
|
|
while(i > 0) {
|
|
if (HWS.available()) {
|
|
*p++ = HWS.read();
|
|
i--;
|
|
q++;
|
|
} else {
|
|
delayMicroseconds(1); // short delay
|
|
}
|
|
}
|
|
|
|
return q; // we read some data
|
|
}
|
|
}
|
|
|
|
return 0; // nothing to read
|
|
}
|
|
|
|
int parse_packet(uint8_t *p, uint16_t recv_len) {
|
|
if (maybe_packet(p)) {
|
|
uint16_t pack_len = packet_length(p);
|
|
|
|
// TODO CRC check on smaller packets
|
|
|
|
switch(p[0]) {
|
|
case 1:
|
|
// otherwise we'll need to load it ourselves into the program buffer
|
|
if (recv_len == pack_len) {
|
|
p[PACK_OVERHEAD + pack_len + 1] = 0;
|
|
lua_start(p + PACK_OVERHEAD); // load it directly from our buffer
|
|
} else {
|
|
int t = read_pack(l_prog_buff, MAX_PRGMSIZE - 1, 0, pack_len);
|
|
|
|
if (t < 0) { // program too big.
|
|
// all programs should have no values that are valid packet starts, so we'll just let the rest of the code skip them. might be a bug later TODO
|
|
HWS.write(0x03);
|
|
HWS.write(0x00);
|
|
HWS.write(38);
|
|
HWS.write(0);
|
|
HWS.write(0);
|
|
HWS.print("Program too big, reduce the total size");
|
|
} else {
|
|
l_prog_buff[t+1] = 0; // null byte
|
|
lua_start(l_prog_buff);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 5: // send the output log
|
|
HWS.write(0x06); // send packet header
|
|
HWS.write(LOG_RINGSIZE >> 8);
|
|
HWS.write(LOG_RINGSIZE & 0xFF);
|
|
HWS.write(0);
|
|
HWS.write(0);
|
|
|
|
char *rb_p = log_curpos+1;
|
|
if (rb_p - log_ringbuffer >= LOG_RINGSIZE)
|
|
rb_p = log_ringbuffer;
|
|
|
|
while(rb_p != log_curpos) {
|
|
if (*rb_p)
|
|
HWS.write(*rb_p);
|
|
rb_p++;
|
|
if (rb_p - log_ringbuffer >= LOG_RINGSIZE)
|
|
rb_p = log_ringbuffer;
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
// TODO recv bitmap
|
|
break;
|
|
|
|
case 10: // KV data for lua
|
|
// TODO call lua func for this
|
|
break;
|
|
case 11: // set brightness. Do not honor currently.
|
|
// TODO
|
|
break;
|
|
|
|
case 9: // req KV data
|
|
case 7: // we should never get this, we send request for bitmap
|
|
case 6: // we should never get this, we send output log
|
|
case 4: // we should never get this, we send PRGMACK
|
|
case 3: // we should never get this, we send error
|
|
case 2: // we should never get this, we send it
|
|
case 0: // null packet, do nothing
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void setup_comms() {
|
|
HWS.begin(115200);
|
|
}
|
|
|
|
void loop_comms() {
|
|
if (HWS.available() >= 5) {
|
|
uint c = 5;
|
|
|
|
buff[0] = HWS.read();
|
|
if (!maybe_packet(buff))
|
|
return; // skip this byte, we'll check on the next loop
|
|
|
|
uint16_t pack_len = packet_length(buff);
|
|
|
|
int len = read_pack(buff + PACK_OVERHEAD, BUFF_SIZE - PACK_OVERHEAD, 0, pack_len);
|
|
|
|
// we read the rest of the packet, tell parser
|
|
if (len > 0) {
|
|
c+ = len;
|
|
}
|
|
|
|
parse_packet(buff, c);
|
|
}
|
|
}
|
|
|