Julian Daube
41ee7ab012
firmware accepts commands over usb and switches inputs based on button presses
162 lines
3.0 KiB
C
162 lines
3.0 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 'B':
|
|
case 'T':
|
|
|
|
default:
|
|
printf("E\n");
|
|
}
|
|
|
|
return skip_line();
|
|
}
|