Make status request work, fix uc-side cobs encoding bug
This commit is contained in:
parent
75d4d0f3df
commit
a70ad99b36
3 changed files with 96 additions and 53 deletions
111
fw/main.c
111
fw/main.c
|
|
@ -83,8 +83,8 @@ void strobe_leds(void) {
|
|||
GPIOA->BSRR = GPIO_BSRR_BR_9;
|
||||
}
|
||||
|
||||
#define FIRMWARE_VERSION 1
|
||||
#define HARDWARE_VERSION 1
|
||||
#define FIRMWARE_VERSION 2
|
||||
#define HARDWARE_VERSION 4
|
||||
|
||||
#define TS_CAL1 (*(uint16_t *)0x1FFFF7B8)
|
||||
#define VREFINT_CAL (*(uint16_t *)0x1FFFF7BA)
|
||||
|
|
@ -108,23 +108,6 @@ volatile union {
|
|||
uint32_t mac_data;
|
||||
} rx_buf;
|
||||
|
||||
volatile union {
|
||||
struct { uint32_t magic; } ping_reply;
|
||||
struct __attribute__((packed)) {
|
||||
uint8_t firmware_version,
|
||||
hardware_version,
|
||||
digit_rows,
|
||||
digit_cols;
|
||||
uint32_t uptime;
|
||||
uint32_t millifps;
|
||||
int16_t vcc_mv,
|
||||
temp_tenth_celsius;
|
||||
uint8_t nbits;
|
||||
} desc_reply;
|
||||
} tx_buf;
|
||||
|
||||
extern uint8_t bus_addr;
|
||||
|
||||
#define LED_COMM 0x0001
|
||||
#define LED_ERROR 0x0002
|
||||
#define LED_ID 0x0004
|
||||
|
|
@ -372,14 +355,6 @@ void TIM3_IRQHandler() {
|
|||
GPIOA->BSRR = GPIO_BSRR_BR_0; // Debug
|
||||
}
|
||||
|
||||
enum Command {
|
||||
CMD_PING,
|
||||
CMD_SET_FB,
|
||||
CMD_SET_NBITS,
|
||||
CMD_GET_DESC,
|
||||
N_CMDS
|
||||
};
|
||||
|
||||
void uart_config(void) {
|
||||
USART1->CR1 = /* 8-bit -> M1, M0 clear */
|
||||
/* RTOIE clear */
|
||||
|
|
@ -426,9 +401,9 @@ void trigger_id_led() {
|
|||
}
|
||||
|
||||
/* Error counters for debugging */
|
||||
static unsigned int overruns = 0;
|
||||
static unsigned int uart_overruns = 0;
|
||||
static unsigned int frame_overruns = 0;
|
||||
static unsigned int invalid = 0;
|
||||
static unsigned int invalid_frames = 0;
|
||||
|
||||
void tx_char(uint8_t c) {
|
||||
while (!(USART1->ISR & USART_ISR_TC));
|
||||
|
|
@ -443,16 +418,51 @@ void send_frame_formatted(uint8_t *buf, int len) {
|
|||
tx_char(q-p+1);
|
||||
while (*p && p!=end)
|
||||
tx_char(*p++);
|
||||
} while (p != end);
|
||||
p++, q++;
|
||||
} while (p < end);
|
||||
tx_char('\0');
|
||||
}
|
||||
|
||||
union {
|
||||
struct __attribute__((packed)) {
|
||||
uint8_t firmware_version,
|
||||
hardware_version,
|
||||
digit_rows,
|
||||
digit_cols;
|
||||
uint32_t uptime_s,
|
||||
framerate_millifps,
|
||||
uart_overruns,
|
||||
frame_overruns,
|
||||
invalid_frames;
|
||||
int16_t vcc_mv,
|
||||
temp_celsius;
|
||||
uint8_t nbits;
|
||||
} desc_reply;
|
||||
uint8_t byte_data[0];
|
||||
} tx_buf;
|
||||
|
||||
void send_status_reply(void) {
|
||||
tx_buf.desc_reply.firmware_version = FIRMWARE_VERSION;
|
||||
tx_buf.desc_reply.hardware_version = HARDWARE_VERSION;
|
||||
tx_buf.desc_reply.digit_rows = NROWS;
|
||||
tx_buf.desc_reply.digit_cols = NCOLS;
|
||||
tx_buf.desc_reply.uptime_s = sys_time_seconds;
|
||||
tx_buf.desc_reply.vcc_mv = adc_vcc_mv;
|
||||
tx_buf.desc_reply.temp_celsius = adc_temp_celsius;
|
||||
tx_buf.desc_reply.nbits = nbits;
|
||||
tx_buf.desc_reply.framerate_millifps = frame_duration_us > 0 ? 1000000000 / frame_duration_us : 0;
|
||||
tx_buf.desc_reply.uart_overruns = uart_overruns;
|
||||
tx_buf.desc_reply.frame_overruns = frame_overruns;
|
||||
tx_buf.desc_reply.invalid_frames = invalid_frames;
|
||||
send_frame_formatted(tx_buf.byte_data, sizeof(tx_buf.desc_reply));
|
||||
}
|
||||
|
||||
/* This is the higher-level protocol handler for the serial protocol. It gets passed the number of data bytes in this
|
||||
* frame (which may be zero) and returns a pointer to the buffer where the next frame should be stored.
|
||||
*/
|
||||
volatile uint8_t *packet_received(int len) {
|
||||
static enum {
|
||||
PROT_EXPECT_FRAME_FIRST_HALF = 0,
|
||||
PROT_ADDRESSED = 0,
|
||||
PROT_EXPECT_FRAME_SECOND_HALF = 1,
|
||||
PROT_IGNORE = 2,
|
||||
} protocol_state = PROT_IGNORE;
|
||||
|
|
@ -463,15 +473,32 @@ volatile uint8_t *packet_received(int len) {
|
|||
send_frame_formatted((uint8_t*)&device_mac, sizeof(device_mac));
|
||||
}
|
||||
|
||||
} else if (len == 1) { /* Command packet */
|
||||
if (protocol_state == PROT_ADDRESSED) {
|
||||
switch (rx_buf.byte_data[0]) {
|
||||
case 0x01:
|
||||
GPIOA->BSRR = GPIO_BSRR_BS_4; // Debug
|
||||
//for (int i=0; i<100; i++)
|
||||
// tick();
|
||||
send_status_reply();
|
||||
GPIOA->BSRR = GPIO_BSRR_BR_4; // Debug
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
invalid_frames++;
|
||||
trigger_error_led();
|
||||
}
|
||||
protocol_state = PROT_IGNORE;
|
||||
|
||||
} else if (len == 4) { /* Address packet */
|
||||
if (rx_buf.mac_data == device_mac) { /* we are addressed */
|
||||
protocol_state = PROT_EXPECT_FRAME_FIRST_HALF; /* start listening for frame buffer data */
|
||||
protocol_state = PROT_ADDRESSED; /* start listening for frame buffer data */
|
||||
} else { /* we are not addressed */
|
||||
protocol_state = PROT_IGNORE; /* ignore packet */
|
||||
}
|
||||
|
||||
} else if (len == sizeof(rx_buf.set_fb_rq)/2) {
|
||||
if (protocol_state == PROT_EXPECT_FRAME_FIRST_HALF) { /* First of two half-framebuffer data frames */
|
||||
if (protocol_state == PROT_ADDRESSED) { /* First of two half-framebuffer data frames */
|
||||
protocol_state = PROT_EXPECT_FRAME_SECOND_HALF;
|
||||
/* Return second half of receive buffer */
|
||||
return rx_buf.byte_data + (sizeof(rx_buf.set_fb_rq)/2);
|
||||
|
|
@ -494,7 +521,7 @@ volatile uint8_t *packet_received(int len) {
|
|||
|
||||
} else {
|
||||
/* FIXME An invalid packet has been received. What should we do? */
|
||||
invalid++;
|
||||
invalid_frames++;
|
||||
trigger_error_led();
|
||||
protocol_state = PROT_IGNORE; /* go into "hang mode" until next zero-length packet */
|
||||
}
|
||||
|
|
@ -553,9 +580,8 @@ void USART1_IRQHandler(void) {
|
|||
/* COBS skip counter. During payload processing this contains the remaining non-null payload bytes */
|
||||
static int cobs_count = 0;
|
||||
|
||||
GPIOA->BSRR = GPIO_BSRR_BS_4; // Debug
|
||||
if (USART1->ISR & USART_ISR_ORE) { /* Overrun handling */
|
||||
overruns++;
|
||||
uart_overruns++;
|
||||
trigger_error_led();
|
||||
/* Reset and re-synchronize. Retry next frame. */
|
||||
rxpos = 0;
|
||||
|
|
@ -593,7 +619,6 @@ void USART1_IRQHandler(void) {
|
|||
}
|
||||
}
|
||||
}
|
||||
GPIOA->BSRR = GPIO_BSRR_BR_4; // Debug
|
||||
}
|
||||
|
||||
#define ADC_OVERSAMPLING 8
|
||||
|
|
@ -669,18 +694,6 @@ void adc_config(void) {
|
|||
NVIC_SetPriority(DMA1_Channel1_IRQn, 3);
|
||||
}
|
||||
|
||||
/*
|
||||
tx_buf.desc_reply.firmware_version = FIRMWARE_VERSION;
|
||||
tx_buf.desc_reply.hardware_version = HARDWARE_VERSION;
|
||||
tx_buf.desc_reply.digit_rows = NROWS;
|
||||
tx_buf.desc_reply.digit_cols = NCOLS;
|
||||
tx_buf.desc_reply.uptime = sys_time_seconds;
|
||||
tx_buf.desc_reply.vcc_mv = adc_vcc_mv;
|
||||
tx_buf.desc_reply.temp_tenth_celsius = adc_temp_tenth_celsius;
|
||||
tx_buf.desc_reply.nbits = nbits;
|
||||
tx_buf.desc_reply.millifps = frame_duration_us > 0 ? 1000000000 / frame_duration_us : 0;
|
||||
*/
|
||||
|
||||
int main(void) {
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while (!(RCC->CR&RCC_CR_HSERDY));
|
||||
|
|
|
|||
38
fw/test.py
38
fw/test.py
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
import serial
|
||||
import struct
|
||||
from itertools import takewhile
|
||||
|
||||
def chunked(data, chunk_size):
|
||||
|
|
@ -50,10 +51,12 @@ def unstuff(data):
|
|||
def receive_frame(ser):
|
||||
return unstuff(read_frame(ser))
|
||||
|
||||
def mac_frame(mac):
|
||||
return frame_packet(struct.pack('<I', mac))
|
||||
|
||||
def send_framebuffer(ser, mac, frame):
|
||||
formatted = format_packet(frame)
|
||||
mac_packet = struct.pack('<I', mac)
|
||||
framed = frame_packet(mac_packet) + frame_packet(formatted[:162]) + frame_packet(formatted[162:])
|
||||
framed = mac_frame(mac) + frame_packet(formatted[:162]) + frame_packet(formatted[162:])
|
||||
ser.write(framed)
|
||||
|
||||
def discover_macs(ser, count=20):
|
||||
|
|
@ -72,10 +75,32 @@ def discover_macs(ser, count=20):
|
|||
print('Invalid frame of length {}:'.format(len(frame)), frame)
|
||||
time.sleep(0.05)
|
||||
|
||||
def parse_status_frame(frame):
|
||||
print('frame len:', len(frame))
|
||||
( firmware_version,
|
||||
hardware_version,
|
||||
digit_rows,
|
||||
digit_cols,
|
||||
uptime_s,
|
||||
framerate_millifps,
|
||||
uart_overruns,
|
||||
frame_overruns,
|
||||
invalid_frames,
|
||||
vcc_mv,
|
||||
temp_celsius,
|
||||
nbits ) = struct.unpack('<4B5IhhB', frame)
|
||||
del frame
|
||||
return locals()
|
||||
|
||||
def fetch_status(ser, mac):
|
||||
ser.flushInput()
|
||||
ser.write(mac_frame(mac))
|
||||
ser.write(frame_packet(b'\x01'))
|
||||
return parse_status_frame(receive_frame(ser))
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
import time
|
||||
import struct
|
||||
from binascii import hexlify
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
|
@ -95,10 +120,15 @@ if __name__ == '__main__':
|
|||
#frames = [red, black]*5
|
||||
#frames = [ x for l in [[([0]*i+[255]+[0]*(7-i))*32]*2 for i in range(8)] for x in l ]
|
||||
found_macs = discover_macs(ser, 1)
|
||||
mac, = found_macs
|
||||
|
||||
import pprint
|
||||
while True:
|
||||
pprint.pprint(fetch_status(ser, mac))
|
||||
time.sleep(0.02)
|
||||
|
||||
while True:
|
||||
for i, frame in enumerate(frames):
|
||||
mac, = found_macs
|
||||
send_framebuffer(ser, mac, frame)
|
||||
print('sending', i, len(frame))
|
||||
time.sleep(0.02)
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue