fw: dump accelerometer measurements over uart

This commit is contained in:
jaseg 2021-03-18 10:11:41 +01:00
parent df51e1c508
commit c67f7d626b
3 changed files with 160 additions and 51 deletions

View file

@ -12,6 +12,8 @@
#include <generated/stm32_device.h>
#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
#define APB1_PRESC (1<<(APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1_Msk) >> RCC_CFGR_PPRE1_Pos]))
#define APB2_PRESC (1<<(APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2_Msk) >> RCC_CFGR_PPRE2_Pos]))
#define AHB_PRESC (1<<(AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE_Msk) >> RCC_CFGR_HPRE_Pos]))

View file

@ -4,6 +4,16 @@
#include "microcobs.h"
#include "crc32.h"
static uint8_t crc8_calc(uint8_t *data, size_t len);
static bool parity_calc(uint8_t *data, size_t len);
uint32_t mems_trx_word(uint32_t data);
uint32_t mems_trx_cmd(uint32_t cmd);
void mems_write_reg(int addr, int val);
uint32_t mems_read_reg(int addr);
int16_t mems_read_meas(int ch);
void mems_spi_init(void);
void mems_init(void);
struct __attribute__((packed)) ll_pkt_trailer {
uint32_t crc32;
};
@ -14,8 +24,8 @@ struct __attribute__((packed)) req_pkt {
};
struct __attribute__((packed)) res_pkt {
uint32_t req_seq;
uint32_t res_seq;
uint16_t meas_data[16];
struct ll_pkt_trailer trailer;
};
@ -156,7 +166,7 @@ uint32_t mems_read_reg(int addr) {
int16_t mems_read_meas(int ch) {
ch &= 3;
mems_trx_cmd((ch<<MEMS_OPCODE_Pos) | (1<<MEMS_SEN_Pos));
for (int i=0; i<2000; i++)
for (int i=0; i<10; i++)
asm volatile ("nop");
uint32_t rv = mems_trx_cmd(3<<MEMS_OPCODE_Pos);
/* shift 14-bit data left to align the MSB with the int16_t's sign bit */
@ -166,7 +176,7 @@ int16_t mems_read_meas(int ch) {
}
void mems_spi_init(void) {
SPI1->CR1 = (6<<SPI_CR1_BR_Pos) | SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI;
SPI1->CR1 = (1<<SPI_CR1_BR_Pos) | SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI;
SPI1->CR2 = (15<<SPI_CR2_DS_Pos);
SPI1->CR1 |= SPI_CR1_SPE;
}
@ -182,10 +192,40 @@ void mems_init(void) {
mems_write_reg(MEMS_REG_CTRL0, 0x01);
}
#define WIN_LEN 8
int16_t meas_buf[WIN_LEN * 3] = {0};
size_t meas_buf_wptr = 0;
size_t meas_buf_rptr = 0;
int res_seq = 0;
void TIM1_BRK_TIM15_IRQHandler (void) {
TIM15->SR = 0;
int16_t data = mems_read_meas(0);
/* write into meas_buf as circular buffer */
meas_buf[meas_buf_wptr] = data;
meas_buf_wptr += 1;
if (meas_buf_wptr >= COUNT_OF(meas_buf)) {
meas_buf_wptr = 0;
}
/* set read pointer to oldest 8-measurement block by rounding down meas_buf_wptr by 8, then adding 8 and wrapping */
size_t tmp = 8 * (meas_buf_wptr / 8 + 1);
if (tmp >= COUNT_OF(meas_buf)) {
tmp = 0;
}
/* Update sequence pointer when the transmission window changes. */
if (tmp != meas_buf_rptr) {
res_seq += 1;
meas_buf_rptr = tmp;
}
}
int main(void) {
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_SPI1EN;
RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_SPI1EN | RCC_APB2ENR_TIM15EN;
#define AFRL(pin, val) ((val) << ((pin)*4))
#define AFRH(pin, val) ((val) << (((pin)-8)*4))
@ -210,6 +250,12 @@ int main(void) {
SystemCoreClockUpdate();
int apb2_clock = SystemCoreClock / APB2_PRESC;
TIM15->PSC = apb2_clock / 1000000 * 100 - 1; /* 100us ticks */
TIM15->ARR = 1000 - 1; /* 100ms overflow interrupt interval */
TIM15->DIER = TIM_DIER_UIE;
TIM15->CR1 = TIM_CR1_CEN;
NVIC_EnableIRQ(TIM1_BRK_TIM15_IRQn);
int baudrate = 115200;
USART1->CR1 = USART_CR1_TE | USART_CR1_RE;
@ -217,56 +263,31 @@ int main(void) {
USART1->CR2 |= USART_CR2_RXINV; //| USART_CR2_TXINV;
USART1->CR1 |= USART_CR1_UE;
/* FIXME DEUBG */
while (1) {
mems_init();
for (int i=0; i<100000; i++)
asm volatile("nop");
for (int i=0; i<300; i++) {
mems_read_meas(0);
//mems_read_reg(MEMS_REG_ID_SENSOR_TYPE);
for (int i=0; i<10000; i++)
asm volatile("nop");
}
for (int i=0; i<100000; i++)
asm volatile("nop");
}
mems_init();
int req_seq = 0;
int res_seq = 0;
struct req_pkt req_buf = { 0 };
struct tx_state tx_st = { 0 };
struct res_pkt res_buf = { 0 };
uint8_t rx_buf[512];
uint8_t tx_buf[512];
/*
int req_seq = 0;
struct req_pkt req_buf = { 0 };
uint8_t rx_buf[512];
size_t rx_char = 0;
unsigned int rx_overrun = 0;
unsigned int rx_cobs_error = 0;
unsigned int rx_framing_error = 0;
unsigned int rx_crc_error = 0;
*/
USART1->TDR = 0; /* Kick off transmission */
int i = 0;
while (23) {
if (tx_st.remaining_bytes == 0) {
if (i > 100) {
res_buf.req_seq = req_seq;
res_buf.res_seq = res_seq;
res_seq += 1;
packetize(&res_buf, &res_buf.trailer);
tx_st.tx_char = tx_buf;
tx_st.remaining_bytes = cobs_encode((uint8_t *)&res_buf, sizeof(res_buf), tx_buf, sizeof(tx_buf));;
/*
for (int k=0; k < 8; k++)
tx_buf[k] = 255-k;
for (int k=0; k < 8; k++)
tx_buf[8+k] = (k + 1) % 8;
tx_st.remaining_bytes = 16;
*/
i = 0;
} else {
i++;
}
res_buf.res_seq = res_seq;
memcpy(res_buf.meas_data, meas_buf + meas_buf_rptr, 8 * sizeof(meas_buf[0]));
memcpy(res_buf.meas_data + 8, meas_buf + ((meas_buf_rptr + 8) % COUNT_OF(meas_buf)) , 8 * sizeof(meas_buf[0]));
packetize(&res_buf, &res_buf.trailer);
tx_st.tx_char = tx_buf;
tx_st.remaining_bytes = cobs_encode((uint8_t *)&res_buf, sizeof(res_buf), tx_buf, sizeof(tx_buf));;
}
if (USART1->ISR & USART_ISR_TXE && tx_st.remaining_bytes > 0) {
@ -286,6 +307,8 @@ int main(void) {
if (USART1->ISR & USART_ISR_RXNE) {
uint8_t c = USART1->RDR;
(void) c;
/*
if (!c) {
if (rx_char < sizeof(rx_buf)) {
int rc = cobs_decode(rx_buf, rx_char, (uint8_t *)&req_buf, sizeof(req_buf));
@ -313,10 +336,57 @@ int main(void) {
rx_overrun += 1;
}
}
*/
}
}
}
void *memcpy(void *restrict dest, const void *restrict src, size_t n)
{
unsigned char *d = dest;
const unsigned char *s = src;
for (; n; n--) *d++ = *s++;
return dest;
}
void *memset(void *dest, int c, size_t n)
{
unsigned char *s = dest;
size_t k;
/* Fill head and tail with minimal branching. Each
* conditional ensures that all the subsequently used
* offsets are well-defined and in the dest region. */
if (!n) return dest;
s[0] = c;
s[n-1] = c;
if (n <= 2) return dest;
s[1] = c;
s[2] = c;
s[n-2] = c;
s[n-3] = c;
if (n <= 6) return dest;
s[3] = c;
s[n-4] = c;
if (n <= 8) return dest;
/* Advance pointer to align it at a 4-byte boundary,
* and truncate n to a multiple of 4. The previous code
* already took care of any head/tail that get cut off
* by the alignment. */
k = -(uintptr_t)s & 3;
s += k;
n -= k;
n &= -4;
for (; n; n--, s++) *s = c;
return dest;
}
void __libc_init_array (void) __attribute__((weak));
void __libc_init_array ()
{

View file

@ -7,6 +7,7 @@ import string
import serial
import time
import zlib
import sqlite3
from cobs import cobs
@ -15,8 +16,21 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('port')
parser.add_argument('-b', '--baudrate', type=int, default=115200)
parser.add_argument('-p', '--print-hex', action='store_true', default=False)
parser.add_argument('-d', '--database', default=':memory:')
parser.add_argument('-q', '--quiet', action='store_true', default=False)
args = parser.parse_args()
db = sqlite3.connect(args.database)
db.execute('''CREATE TABLE IF NOT EXISTS packets (
run_id INTEGER,
timestamp_us INTEGER,
data BLOB)''')
run_id, = db.execute('SELECT IFNULL(MAX(run_id), 0) FROM packets').fetchone()
run_id += 1
print(f'Run ID #{run_id}')
ser = serial.Serial(args.port, args.baudrate, timeout=0)
byte_count = 0
@ -29,18 +43,22 @@ if __name__ == '__main__':
field_colors = [ make_color(x) for x in [ 48, 48, 48, 48, 220, 220, 220, 220, 207, 207, 207, 207 ] ]
last_tx = time.time()
lastc = -10000
last_seq = None
while True:
data = ser.read()
for c in data:
#if byte_count == 0:
#print(f'\033[38;5;244m{time.time() - start_time: 8.3f} \033[0m', end='')
if args.print_hex:
if byte_count == 0:
print(f'\033[38;5;244m{time.time() - start_time: 8.3f} \033[0m', end='')
col = '\033[91m' if c == 0 else '\033[0m' # if c == (lastc - 1) % 256 else '\033[92m')
#print(f'{col}{c:02x}', end=' ')
if args.print_hex:
print(f'{col}{c:02x}', end=' ')
line += bytes([c])
byte_count += 1
if c == 0:
#print(' ' * (16 - byte_count), end='\033[0m\n')
if args.print_hex:
print(' ' * (16 - byte_count), end='\033[0m\n')
byte_count = 16
try:
payload = cobs.decode(packet)
@ -51,18 +69,37 @@ if __name__ == '__main__':
else:
crc_ok = False
ref_crc = ''
if len(payload) == 12:
print(' '.join(f'{col if col else ""}{c if c else 0:02x}' for col, c in itertools.zip_longest(field_colors,
payload)), 'OK' if crc_ok else f'WRONG')
#if len(payload) == 40:
# print(' '.join(f'{col if col else ""}{c if c else 0:02x}' for col, c in itertools.zip_longest(field_colors,
# payload)), 'OK' if crc_ok else f'WRONG')
if crc_ok:
seq, *data = struct.unpack('<I16H', payload[:-4])
db.execute('INSERT INTO packets(run_id, timestamp_us, data) VALUES (?,?,?)',
(run_id, int(time.time()*1000000), payload))
db.commit()
if seq != last_seq:
print()
if last_seq is not None:
if seq - last_seq > 2:
for i in range(last_seq+1, seq):
print(make_color(196), i, end=' ', flush=True)
elif seq - last_seq == 2:
print(make_color(248), last_seq+1, end=' ', flush=True)
print(make_color(48), seq, end=' ', flush=True)
last_seq = seq
else:
print('.', end='', flush=True)
except cobs.DecodeError:
print('COBS framing error')
if not args.quiet:
print('COBS framing error', len(packet))
packet = b''
else:
packet += bytes([c])
isprint = lambda c: c in b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ '
if byte_count == 16:
printable = ''.join( chr(c) if isprint(c) else '.' for c in line )
#print(f'\033[93m | {printable}\033[0m')
if args.print_hex:
printable = ''.join( chr(c) if isprint(c) else '.' for c in line )
print(f'\033[93m | {printable}\033[0m')
byte_count = 0
line = b''
lastc = c