audioMux/firmware/Src/message_parser.c

170 lines
3.1 KiB
C

#include <stdint.h>
#include "bd3491.h" // to manipulate the chip further than the normal system ui does
#include "i2c.h" // for the i2c handle
#include "main.h" // to enable control of the system
struct {
char buffer[1000];
volatile uint16_t begin, end;
volatile uint16_t len;
} serial_buffer = {};
void serial_buffer_push(char data) {
if (serial_buffer.len && serial_buffer.end == serial_buffer.begin)
return; // OVF
serial_buffer.buffer[serial_buffer.end] = data;
serial_buffer.end = (serial_buffer.end + 1)%(sizeof(serial_buffer.buffer));
serial_buffer.len++;
}
char serial_buffer_peek() {
if (serial_buffer.len)
return serial_buffer.buffer[serial_buffer.begin];
return 0;
}
char serial_buffer_pop() {
if (!serial_buffer.len)
return 0; // UF
char result = serial_buffer_peek();
serial_buffer.begin = (serial_buffer.begin + 1)%(sizeof(serial_buffer.buffer));
serial_buffer.len--;
return result;
}
int serial_buffer_len() {
return serial_buffer.len;
}
void CDC_Receive_callback(uint8_t * data, uint32_t len) {
while(len--) {
serial_buffer_push(*(data++));
}
}
int skip_white() {
while(serial_buffer_peek() == ' ' || serial_buffer_peek() == '\t')
serial_buffer_pop();
return !serial_buffer_len();
}
int iswhite(char in) {
return in == ' ' || in == '\t' || in == '\n';
}
int skip_non_white() {
while(serial_buffer_len() && !iswhite(serial_buffer_peek()))
serial_buffer_pop();
return !serial_buffer_len();
}
int skip_line() {
while(serial_buffer_len() && serial_buffer_peek() != '\n') serial_buffer_pop();
if (serial_buffer_peek() == '\n') serial_buffer_pop();
return !serial_buffer_len();
}
int next_arg_signed(int16_t * arg) {
*arg = 0;
if (skip_white())
return 1;
int neg = 0;
while(serial_buffer_len() && (serial_buffer_peek() == '-' || serial_buffer_peek() == '+')) {
if(serial_buffer_pop() == '-')
neg = !neg;
}
int count = 0;
while(serial_buffer_len() && serial_buffer_peek() >= '0' && serial_buffer_peek() <= '9') {
*arg *= 10;
*arg += serial_buffer_pop() - '0';
++count;
}
if (neg) {
*arg *= -1;
}
return !count;
}
int next_arg_unsigned(uint16_t * arg) {
*arg = 0;
if (skip_white())
return 1;
int count = 0;
while(serial_buffer_len() && serial_buffer_peek() >= '0' && serial_buffer_peek() <= '9') {
*arg *= 10;
*arg += serial_buffer_pop() - '0';
++count;
}
return !count;
}
#include <ctype.h>
int parse_buffer() {
if (skip_white()) {
return 1;
}
char temp;
switch((temp = toupper(serial_buffer_pop()))) {
case 'C':
// change channel
{
uint16_t channel;
if (next_arg_unsigned(&channel))
break;
set_input(channel);
}
break;
case 'G':
// set gain
{
uint16_t gain;
if (next_arg_unsigned(&gain)) break;
printf("G%d\n", bd_set_gain(&hi2c1, gain));
}
break;
case 'L':
case 'R':
{
uint16_t att;
if (next_arg_unsigned(&att)) break;
printf("%c%d\n", temp, bd_set_attenuation(&hi2c1, temp == 'R', att&0xFF));
}
break;
case 'M':
{
uint16_t mute;
if (next_arg_unsigned(&mute)) break;
set_mute(mute);
}
break;
case 'B':
case 'T':
default:
printf("E\n");
}
return skip_line();
}