WIP
This commit is contained in:
parent
c5d0320696
commit
7959c72fc7
14 changed files with 265 additions and 219 deletions
2
Makefile
2
Makefile
|
|
@ -34,8 +34,10 @@ C_SOURCES := src/main.c \
|
|||
src/adc.c \
|
||||
src/lcd.c \
|
||||
src/led.c \
|
||||
src/led7seg.c \
|
||||
src/cobs.c \
|
||||
src/serial.c \
|
||||
src/proto.c \
|
||||
src/usb_if.c \
|
||||
upstream/libusb_stm32/src/usbd_stm32l052_devfs.c \
|
||||
upstream/libusb_stm32/src/usbd_core.c
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ struct adc_state {
|
|||
bool has_adc;
|
||||
bool overload[2];
|
||||
ErrorCode error;
|
||||
uint64_t last_error;
|
||||
};
|
||||
|
||||
extern struct adc_state st_adc;
|
||||
|
|
|
|||
|
|
@ -23,21 +23,35 @@
|
|||
#define APB1_PRESC (1<<(APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1_Msk) >> RCC_CFGR_PPRE1_Pos]))
|
||||
#define AHB_PRESC (1<<(AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE_Msk) >> RCC_CFGR_HPRE_Pos]))
|
||||
|
||||
#define AFRL(pin, val) ((val) << ((pin)*4))
|
||||
#define AFRH(pin, val) ((val) << (((pin)-8)*4))
|
||||
#define AF(pin) (2<<(2*(pin)))
|
||||
#define OUT(pin) (1<<(2*(pin)))
|
||||
#define IN(pin) (0)
|
||||
#define ANALOG(pin) (3<<(2*(pin)))
|
||||
#define CLEAR(pin) (3<<(2*(pin)))
|
||||
#define PULLUP(pin) (1<<(2*pin))
|
||||
#define PULLDOWN(pin) (2<<(2*pin))
|
||||
#define BSRR_CLEAR(pin) ((1<<pin)<<16)
|
||||
#define BSRR_SET(pin) (1<<pin)
|
||||
#define BSRR_VALUE(pin, value) ((((!(value))<<pin)<<16) | ((!!(value))<<pin))
|
||||
|
||||
#ifndef SYSTICK_INTERVAL_US
|
||||
#define SYSTICK_INTERVAL_US 1000
|
||||
#endif /* SYSTICK_INTERVAL_US */
|
||||
|
||||
|
||||
enum ErrorCode {
|
||||
ERR_SUCCESS = 0,
|
||||
ERR_TIMEOUT,
|
||||
ERR_PHYSICAL_LAYER,
|
||||
ERR_FRAMING,
|
||||
ERR_PROTOCOL,
|
||||
ERR_DMA,
|
||||
ERR_BUSY,
|
||||
ERR_BUFFER_OVERFLOW,
|
||||
ERR_RX_OVERRUN,
|
||||
ERR_TX_OVERRUN,
|
||||
ERR_FRAMING,
|
||||
ERR_PROTOCOL,
|
||||
};
|
||||
|
||||
typedef enum ErrorCode ErrorCode;
|
||||
|
|
@ -58,7 +72,7 @@ enum board_config {
|
|||
*/
|
||||
|
||||
BCFG_MOTOR,
|
||||
/* When no LCD is connected and the BT0 input on the buttons connector is tied to ground, the board assumes its
|
||||
/* When no LCD is connected and the BT0 input on the buttons connector is open, the board assumes its
|
||||
* motor configuration. In this configuration, the board controls a motor connected through the Buttons and LCD
|
||||
* connectors, and the USB control interface is enabled. The board acts as the host on the RS-485 bus.
|
||||
*
|
||||
|
|
@ -66,7 +80,7 @@ enum board_config {
|
|||
*/
|
||||
|
||||
BCFG_MEAS,
|
||||
/* When no LCD is connected and the BT0 input on the buttons connector is open or tied to VDD, the board assumes its
|
||||
/* When no LCD is connected and the BT0 input on the buttons connector is tied to ground, the board assumes its
|
||||
* senesor configuration. In this configuration, the board periodically. The board acts as a peripheral on the
|
||||
* RS-485 bus, relaying measurements on the bus when requested by the host. The board's bus address is set by pins
|
||||
* BT1 and BT0 of the buttons connector. Both pins have pullups enabled, and will read zero when tied to ground on
|
||||
|
|
|
|||
|
|
@ -34,5 +34,6 @@ extern struct led_state st_led;
|
|||
|
||||
void led_init(void);
|
||||
void led_set_global_brightness(int brightness);
|
||||
void set_led(int led, uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
#endif /* __LED_H__ */
|
||||
|
|
|
|||
27
include/led7seg.h
Normal file
27
include/led7seg.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef __LED7SEG_H__
|
||||
#define __LED7SEG_H__
|
||||
|
||||
#include <global.h>
|
||||
|
||||
|
||||
struct st_7seg {
|
||||
uint8_t data[3][8];
|
||||
uint8_t dp[3];
|
||||
int module;
|
||||
int digit;
|
||||
int bit;
|
||||
uint16_t datagram;
|
||||
};
|
||||
|
||||
|
||||
extern struct st_7seg st_7seg;
|
||||
|
||||
|
||||
void init_7seg(void);
|
||||
void step_7seg(void);
|
||||
int bt_inputs(void);
|
||||
void decimal_7seg(int module, int value, int dp);
|
||||
void hex_7seg(int module, uint32_t value, uint8_t dp);
|
||||
void blank_7seg(int module);
|
||||
|
||||
#endif /* __LED7SEG_H__ */
|
||||
|
|
@ -86,7 +86,7 @@ struct __attribute__((__packed__)) pkt_button_state {
|
|||
|
||||
struct __attribute__((__packed__)) pkt_time_sync {
|
||||
struct ll_pkt ll_pkt;
|
||||
uint64_t timestamp;
|
||||
uint64_t time;
|
||||
};
|
||||
|
||||
struct __attribute__((__packed__)) pkt_adc_data {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ tcl_port disabled
|
|||
telnet_port disabled
|
||||
|
||||
source [find interface/stlink.cfg]
|
||||
hla_serial "X"
|
||||
adapter serial "X"
|
||||
|
||||
source [find target/stm32f0x.cfg]
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ tcl_port disabled
|
|||
telnet_port disabled
|
||||
|
||||
source [find interface/stlink.cfg]
|
||||
hla_serial "U"
|
||||
adapter serial "U"
|
||||
|
||||
source [find target/stm32f0x.cfg]
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ void adc_init() {
|
|||
adc_sync_write(ADC_REG_CLOCK, ADC_CLOCK_CH1_EN | ADC_CLOCK_CH2_EN | ADC_CLOCK_OSR_8192 | ADC_CLOCK_PWR_HIRES);
|
||||
adc_sync_write(ADC_REG_GAIN, ADC_GAIN1_PGAGAIN1_4 | ADC_GAIN1_PGAGAIN0_4);
|
||||
adc_sync_write(ADC_REG_MODE, (1<<ADC_MODE_WLENGTH_Pos) | ADC_MODE_TIMEOUT);
|
||||
st_adc.sampling_interval_us =
|
||||
st_adc.sampling_interval_us = 1000; /* FIXME */
|
||||
|
||||
/* wait for ~DRDY to go high (inactive) */
|
||||
int i;
|
||||
|
|
@ -179,7 +179,7 @@ void adc_dma_interrupt(uint32_t channel, uint32_t flags) {
|
|||
}
|
||||
st_adc.samples[wr_idx][1] = val;
|
||||
st_adc.sample_rd_idx = wr_idx;
|
||||
st_adc.sample_wr_idx = (wr_idx+1) % COUNT_OF(st_adc.data);
|
||||
st_adc.sample_wr_idx = (wr_idx+1) % COUNT_OF(st_adc.samples);
|
||||
st_adc.sample_count++;
|
||||
|
||||
if (val > ADC_FSR_POS || val < ADC_FSR_NEG) {
|
||||
|
|
|
|||
153
src/led7seg.c
Normal file
153
src/led7seg.c
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
|
||||
#include <global.h>
|
||||
#include <led7seg.h>
|
||||
|
||||
|
||||
struct st_7seg st_7seg;
|
||||
|
||||
|
||||
int bt_inputs() {
|
||||
bool bt0 = !!(GPIOB->IDR & (1<<2));
|
||||
bool bt1 = !!(GPIOB->IDR & (1<<1));
|
||||
bool bt2 = !!(GPIOB->IDR & (1<<0));
|
||||
bool bt3 = !!(GPIOB->IDR & (1<<12));
|
||||
bool bt4 = !!(GPIOB->IDR & (1<<4));
|
||||
bool bt5 = !!(GPIOA->IDR & (1<<15));
|
||||
return (bt5<<5) | (bt4<<4) | (bt3<<3) | (bt2<<2) | (bt1<<1) | (bt0<<0);
|
||||
}
|
||||
|
||||
void init_7seg() {
|
||||
GPIOA->MODER |= OUT(15);
|
||||
GPIOB->MODER |= OUT(12) | OUT(3);
|
||||
GPIOA->BRR = (1<<15);
|
||||
GPIOB->BRR = (1<<12) | (1<<3);
|
||||
memset(&st_7seg, 0, sizeof(st_7seg));
|
||||
|
||||
uint16_t dgrams[] = {
|
||||
0x0c01, /* Shutdown off */
|
||||
0x0a03, /* Max intensity */
|
||||
0x0b07, /* 8 digit scan */
|
||||
};
|
||||
for (size_t dgram=0; dgram<COUNT_OF(dgrams); dgram++) {
|
||||
for (size_t mod=0; mod<3; mod++) {
|
||||
uint16_t datagram = dgrams[dgram];
|
||||
for (int bit=0; bit<16; bit++) {
|
||||
delay_us(1);
|
||||
GPIOB->BSRR = BSRR_VALUE(12, datagram&0x8000) | BSRR_CLEAR(3);
|
||||
datagram <<= 1;
|
||||
delay_us(1);
|
||||
GPIOB->BSRR = BSRR_SET(3);
|
||||
}
|
||||
}
|
||||
GPIOA->BSRR = BSRR_SET(15);
|
||||
delay_us(1);
|
||||
GPIOA->BSRR = BSRR_CLEAR(15);
|
||||
}
|
||||
}
|
||||
|
||||
void decimal_7seg(int module, int value, int dp) {
|
||||
if (value < -9999999 || value > 99999999) {
|
||||
st_7seg.data[module][0] = 0xE;
|
||||
st_7seg.data[module][1] = 16; /* blank */
|
||||
st_7seg.data[module][2] = 16; /* blank */
|
||||
st_7seg.data[module][3] = 16; /* blank */
|
||||
st_7seg.data[module][4] = 16; /* blank */
|
||||
st_7seg.data[module][5] = 16; /* blank */
|
||||
st_7seg.data[module][6] = 16; /* blank */
|
||||
st_7seg.data[module][7] = 16; /* blank */
|
||||
st_7seg.dp[module] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int digit=0; digit<8; digit++) {
|
||||
int f = value/10;
|
||||
int r = value - f*10;
|
||||
value = f;
|
||||
st_7seg.data[module][digit] = r;
|
||||
}
|
||||
|
||||
st_7seg.dp[module] = dp > 0 ? (1<<dp) : 0;
|
||||
}
|
||||
|
||||
void hex_7seg(int module, uint32_t value, uint8_t dp) {
|
||||
for (int digit=0; digit<8; digit++) {
|
||||
st_7seg.data[module][digit] = value&0xf;
|
||||
value >>= 4;
|
||||
}
|
||||
|
||||
st_7seg.dp[module] = dp;
|
||||
}
|
||||
|
||||
void blank_7seg(int module) {
|
||||
st_7seg.dp[module] = 0;
|
||||
for (int digit=0; digit<8; digit++) {
|
||||
st_7seg.data[module][digit] = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
/* Segment map:
|
||||
* +- 6 -+
|
||||
* 1 5
|
||||
* +- 0 -+
|
||||
* 2 4
|
||||
* +- 3 -+ [7]
|
||||
*
|
||||
* +- 40-+
|
||||
* 02 20
|
||||
* +- 01-+
|
||||
* 04 10
|
||||
* +- 08-+ [7]
|
||||
*/
|
||||
static uint8_t led7seg_font_lut[] = {
|
||||
0x7e, /* 0 */
|
||||
0x30, /* 1 */
|
||||
0x6d, /* 2 */
|
||||
0x79, /* 3 */
|
||||
0x33, /* 4 */
|
||||
0x5b, /* 5 */
|
||||
0x5f, /* 6 */
|
||||
0x70, /* 7 */
|
||||
0x7f, /* 8 */
|
||||
0x7b, /* 9 */
|
||||
0x77, /* A */
|
||||
0x1f, /* B */
|
||||
0x4e, /* C */
|
||||
0x3d, /* D */
|
||||
0x4f, /* E */
|
||||
0x47, /* F */
|
||||
0x00, /* 0x10 ^= blank */
|
||||
0x01, /* 0x11 ^= "-" */
|
||||
};
|
||||
|
||||
void step_7seg() {
|
||||
GPIOA->BSRR = BSRR_CLEAR(15);
|
||||
|
||||
if (st_7seg.bit&1) {
|
||||
GPIOB->BSRR = BSRR_SET(3);
|
||||
st_7seg.datagram <<= 1;
|
||||
} else {
|
||||
GPIOB->BSRR = BSRR_VALUE(12, st_7seg.datagram&0x8000) | BSRR_CLEAR(3);
|
||||
}
|
||||
|
||||
st_7seg.bit++;
|
||||
if (st_7seg.bit == 16*2) {
|
||||
st_7seg.bit = 0;
|
||||
|
||||
st_7seg.module++;
|
||||
if (st_7seg.module == 3) {
|
||||
st_7seg.module = 0;
|
||||
GPIOA->BSRR = BSRR_SET(15);
|
||||
|
||||
st_7seg.digit++;
|
||||
if (st_7seg.digit == 8) {
|
||||
st_7seg.digit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t dp = (st_7seg.dp[st_7seg.module] & (1<<st_7seg.digit)) ? 0x80 : 0x00;
|
||||
st_7seg.datagram = ((st_7seg.digit+1)<<8) |
|
||||
led7seg_font_lut[st_7seg.data[st_7seg.module][st_7seg.digit]] |
|
||||
dp;
|
||||
}
|
||||
}
|
||||
|
||||
230
src/main.c
230
src/main.c
|
|
@ -1,31 +1,16 @@
|
|||
|
||||
#include <global.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <adc.h>
|
||||
#include <serial.h>
|
||||
#include <proto.h>
|
||||
#include <lcd.h>
|
||||
#include <led.h>
|
||||
#include <led7seg.h>
|
||||
#include <usb_if.h>
|
||||
#include <usb_proto.h>
|
||||
|
||||
#define AFRL(pin, val) ((val) << ((pin)*4))
|
||||
#define AFRH(pin, val) ((val) << (((pin)-8)*4))
|
||||
#define AF(pin) (2<<(2*(pin)))
|
||||
#define OUT(pin) (1<<(2*(pin)))
|
||||
#define IN(pin) (0)
|
||||
#define ANALOG(pin) (3<<(2*(pin)))
|
||||
#define CLEAR(pin) (3<<(2*(pin)))
|
||||
#define PULLUP(pin) (1<<(2*pin))
|
||||
#define PULLDOWN(pin) (2<<(2*pin))
|
||||
#define BSRR_CLEAR(pin) ((1<<pin)<<16)
|
||||
#define BSRR_SET(pin) (1<<pin)
|
||||
#define BSRR_VALUE(pin, value) ((((!(value))<<pin)<<16) | ((!!(value))<<pin))
|
||||
|
||||
static int bt_inputs(void);
|
||||
static void init_7seg(void);
|
||||
void step_7seg(void);
|
||||
void decimal_7seg(int module, int value, int dp);
|
||||
static void update_leds(void);
|
||||
static void loop_display(void);
|
||||
static void loop_motor(void);
|
||||
|
|
@ -36,150 +21,6 @@ enum board_config board_config;
|
|||
uint64_t sys_time_us;
|
||||
uint64_t sync_time_us;
|
||||
|
||||
int bt_inputs() {
|
||||
bool bt0 = !!(GPIOB->IDR & (1<<2));
|
||||
bool bt1 = !!(GPIOB->IDR & (1<<1));
|
||||
bool bt2 = !!(GPIOB->IDR & (1<<0));
|
||||
bool bt3 = !!(GPIOB->IDR & (1<<12));
|
||||
bool bt4 = !!(GPIOB->IDR & (1<<4));
|
||||
bool bt5 = !!(GPIOA->IDR & (1<<15));
|
||||
return (bt5<<5) | (bt4<<4) | (bt3<<3) | (bt2<<2) | (bt1<<1) | (bt0<<0);
|
||||
}
|
||||
|
||||
struct {
|
||||
uint8_t data[3][8];
|
||||
uint8_t dp[3];
|
||||
int module;
|
||||
int digit;
|
||||
int bit;
|
||||
uint16_t datagram;
|
||||
} st_7seg;
|
||||
|
||||
void init_7seg() {
|
||||
GPIOA->BRR = (1<<15);
|
||||
GPIOB->BRR = (1<<12) | (1<<3);
|
||||
memset(&st_7seg, 0, sizeof(st_7seg));
|
||||
|
||||
uint16_t dgrams[] = {
|
||||
0x0c01, /* Shutdown off */
|
||||
0x0a03, /* Max intensity */
|
||||
0x0b07, /* 8 digit scan */
|
||||
};
|
||||
for (int dgram=0; dgram<COUNT_OF(dgrams); dgram++) {
|
||||
for (int mod=0; mod<3; mod++) {
|
||||
uint16_t datagram = dgrams[dgram];
|
||||
for (int bit=0; bit<16; bit++) {
|
||||
delay_us(1);
|
||||
GPIOB->BSRR = BSRR_VALUE(12, datagram&0x8000) | BSRR_CLEAR(3);
|
||||
datagram <<= 1;
|
||||
delay_us(1);
|
||||
GPIOB->BSRR = BSRR_SET(3);
|
||||
}
|
||||
}
|
||||
GPIOA->BSRR = BSRR_SET(15);
|
||||
delay_us(1);
|
||||
GPIOA->BSRR = BSRR_CLEAR(15);
|
||||
}
|
||||
}
|
||||
|
||||
void decimal_7seg(int module, int value, int dp) {
|
||||
if (value < -9999999 || value > 99999999) {
|
||||
st_7seg.data[module][0] = 0xE;
|
||||
st_7seg.data[module][1] = 16; /* blank */
|
||||
st_7seg.data[module][2] = 16; /* blank */
|
||||
st_7seg.data[module][3] = 16; /* blank */
|
||||
st_7seg.data[module][4] = 16; /* blank */
|
||||
st_7seg.data[module][5] = 16; /* blank */
|
||||
st_7seg.data[module][6] = 16; /* blank */
|
||||
st_7seg.data[module][7] = 16; /* blank */
|
||||
st_7seg.dp[module] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int digit=0; digit<8; digit++) {
|
||||
int f = value/10;
|
||||
int r = value - f*10;
|
||||
value = f;
|
||||
st_7seg.data[module][digit] = r;
|
||||
}
|
||||
|
||||
st_7seg.dp[module] = dp > 0 ? (1<<dp) : 0;
|
||||
}
|
||||
|
||||
void hex_7seg(int module, uint32_t value, uint8_t dp) {
|
||||
for (int digit=0; digit<8; digit++) {
|
||||
st_7seg.data[module][digit] = value&0xf;
|
||||
value >>= 4;
|
||||
}
|
||||
|
||||
st_7seg.dp[module] = dp;
|
||||
}
|
||||
|
||||
/* Segment map:
|
||||
* +- 6 -+
|
||||
* 1 5
|
||||
* +- 0 -+
|
||||
* 2 4
|
||||
* +- 3 -+ [7]
|
||||
*
|
||||
* +- 40-+
|
||||
* 02 20
|
||||
* +- 01-+
|
||||
* 04 10
|
||||
* +- 08-+ [7]
|
||||
*/
|
||||
uint8_t font_lut[] = {
|
||||
0x7e, /* 0 */
|
||||
0x30, /* 1 */
|
||||
0x6d, /* 2 */
|
||||
0x79, /* 3 */
|
||||
0x33, /* 4 */
|
||||
0x5b, /* 5 */
|
||||
0x5f, /* 6 */
|
||||
0x70, /* 7 */
|
||||
0x7f, /* 8 */
|
||||
0x7b, /* 9 */
|
||||
0x77, /* A */
|
||||
0x1f, /* B */
|
||||
0x4e, /* C */
|
||||
0x3d, /* D */
|
||||
0x4f, /* E */
|
||||
0x47, /* F */
|
||||
0x00, /* blank */
|
||||
0x01, /* "-" */
|
||||
};
|
||||
|
||||
void step_7seg() {
|
||||
GPIOA->BSRR = BSRR_CLEAR(15);
|
||||
|
||||
if (st_7seg.bit&1) {
|
||||
GPIOB->BSRR = BSRR_SET(3);
|
||||
st_7seg.datagram <<= 1;
|
||||
} else {
|
||||
GPIOB->BSRR = BSRR_VALUE(12, st_7seg.datagram&0x8000) | BSRR_CLEAR(3);
|
||||
}
|
||||
|
||||
st_7seg.bit++;
|
||||
if (st_7seg.bit == 16*2) {
|
||||
st_7seg.bit = 0;
|
||||
|
||||
st_7seg.module++;
|
||||
if (st_7seg.module == 3) {
|
||||
st_7seg.module = 0;
|
||||
GPIOA->BSRR = BSRR_SET(15);
|
||||
|
||||
st_7seg.digit++;
|
||||
if (st_7seg.digit == 8) {
|
||||
st_7seg.digit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t dp = (st_7seg.dp[st_7seg.module] & (1<<st_7seg.digit)) ? 0x80 : 0x00;
|
||||
st_7seg.datagram = ((st_7seg.digit+1)<<8) |
|
||||
font_lut[st_7seg.data[st_7seg.module][st_7seg.digit]] |
|
||||
dp;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
/* Enable HSE w/ 8 MHz crystal */
|
||||
|
|
@ -242,7 +83,7 @@ int main(void) {
|
|||
*/
|
||||
GPIOA->MODER &= (~(CLEAR(15))); /* Clear JTAG TDI pin mode */
|
||||
GPIOA->MODER |= AF(0) | OUT(1) | OUT(2) | ANALOG(3) | OUT(4) | AF(5) | AF(6) | AF(7) | AF(8) | AF(9) | AF(10) | IN(11)
|
||||
| IN(12) | IN(13) | IN(14) | OUT(15);
|
||||
| IN(12) | IN(13) | IN(14) | IN(15);
|
||||
GPIOA->AFR[0] = AFRL( 0, 2) | /* TIM2 ETR */
|
||||
AFRL( 2, 2) | /* TIM2 CH3 to ADC CS */
|
||||
AFRL( 5, 0) | /* SPI1 SCK (to ADC) */
|
||||
|
|
@ -285,8 +126,8 @@ int main(void) {
|
|||
* 15 - LED_HOPI
|
||||
*/
|
||||
|
||||
GPIOB->MODER = IN(0) | IN(1) | IN(2) | OUT(3) | AF(4) | AF(5) | AF(6) | AF(7) | AF(8) | IN(9) | AF(10) | AF(11) |
|
||||
OUT(12) | AF(13) | AF(14) | AF(15);
|
||||
GPIOB->MODER = IN(0) | IN(1) | IN(2) | IN(3) | AF(4) | AF(5) | AF(6) | AF(7) | AF(8) | IN(9) | AF(10) | AF(11) |
|
||||
IN(12) | AF(13) | AF(14) | AF(15);
|
||||
GPIOB->AFR[0] = AFRL( 4, 1) | /* TIM3 CH1 (Encoder) */
|
||||
AFRL( 5, 1) | /* TIM3 CH2 */
|
||||
AFRL( 6, 1) | /* I2C1 SCL (Display) */
|
||||
|
|
@ -338,13 +179,16 @@ int main(void) {
|
|||
board_config = BCFG_DISPLAY;
|
||||
uart_st.addr = BADDR_DISPLAY;
|
||||
|
||||
blank_7seg(0);
|
||||
blank_7seg(1);
|
||||
blank_7seg(2);
|
||||
|
||||
} else {
|
||||
uart_dma_init(USART3, 7, 1);
|
||||
int bt = bt_inputs();
|
||||
if (bt&0) {
|
||||
if (bt&1) {
|
||||
set_led(LED_DISPLAY, 0, 0, 255); /* blue */
|
||||
set_led(LED_BUTTONS, 0, 0, 255); /* blue */
|
||||
tx_state = 0;
|
||||
board_config = BCFG_MOTOR;
|
||||
uart_st.addr = BADDR_MOTOR;
|
||||
|
||||
|
|
@ -355,6 +199,7 @@ int main(void) {
|
|||
uart_st.addr = BADDR_MEAS_BASE + ((bt>>1) & 3);
|
||||
}
|
||||
}
|
||||
|
||||
proto_init();
|
||||
usb_init();
|
||||
|
||||
|
|
@ -372,17 +217,11 @@ int main(void) {
|
|||
NVIC_EnableIRQ(USART3_4_IRQn);
|
||||
NVIC_SetPriority(USART3_4_IRQn, 1<<5);
|
||||
|
||||
for (size_t i=0; i<10; i++) {
|
||||
st_led.led[i].r = i*10;
|
||||
st_led.led[i].g = i*20;
|
||||
st_led.led[i].b = i*3;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
while (23) {
|
||||
n++;
|
||||
if (n&64) {
|
||||
update_leds();
|
||||
//update_leds();
|
||||
}
|
||||
|
||||
proto_loop();
|
||||
|
|
@ -402,7 +241,7 @@ int main(void) {
|
|||
|
||||
void update_leds() {
|
||||
static uint64_t last_error = 0;
|
||||
static int blink_flag = (sys_time_us & (512*1024-1)) < 384*1024;
|
||||
int blink_flag = (sys_time_us & (512*1024-1)) < (384*1024);
|
||||
|
||||
/* "Error" status LED */
|
||||
if (st_adc.has_adc && st_adc.error) {
|
||||
|
|
@ -420,6 +259,7 @@ void update_leds() {
|
|||
if (uart_st.error && (sys_time_us - uart_st.last_error) < LED_ERROR_TIMEOUT_MS*1000) {
|
||||
/* UART protocol error */
|
||||
set_led(LED_CONNECTED, 255, 0, 0); /* red */
|
||||
}
|
||||
|
||||
if (st_usb.error && (sys_time_us - st_usb.last_error) < LED_ERROR_TIMEOUT_MS*1000) {
|
||||
/* USB error */
|
||||
|
|
@ -450,8 +290,8 @@ void update_leds() {
|
|||
/* ADC hardware error */
|
||||
set_led(LED_ACQUIRING, 255, 0, 0); /* red */
|
||||
set_led(LED_OVERLOAD, 0, 0, 0); /* off */
|
||||
set_led(CHANNEL_A, 0, 0, 0); /* off */
|
||||
set_led(CHANNEL_B, 0, 0, 0); /* off */
|
||||
set_led(LED_CHANNEL_A, 0, 0, 0); /* off */
|
||||
set_led(LED_CHANNEL_B, 0, 0, 0); /* off */
|
||||
|
||||
} else {
|
||||
if (st_adc.has_adc) {
|
||||
|
|
@ -468,12 +308,13 @@ void update_leds() {
|
|||
set_led(led_ch, 0, 0, 0); /* off */
|
||||
|
||||
} else {
|
||||
if (st_adc.data[i] >= 0) {
|
||||
int val = st_adc.data[i] >> 15;
|
||||
int sample = st_adc.samples[st_adc.sample_rd_idx][i];
|
||||
if (sample >= 0) {
|
||||
int val = sample >> 15;
|
||||
set_led(led_ch, 255, 255-val, 255-val); /* white (0) -> red (fsr-1) */
|
||||
|
||||
} else {
|
||||
int val = (-st_adc.data[i]) >> 15;
|
||||
int val = (-sample) >> 15;
|
||||
if (val == 256) {
|
||||
val = 255;
|
||||
}
|
||||
|
|
@ -484,8 +325,8 @@ void update_leds() {
|
|||
} else {
|
||||
set_led(LED_ACQUIRING, 0, 0, 0); /* off */
|
||||
set_led(LED_OVERLOAD, 0, 0, 0); /* off */
|
||||
set_led(CHANNEL_A, 0, 0, 0); /* off */
|
||||
set_led(CHANNEL_B, 0, 0, 0); /* off */
|
||||
set_led(LED_CHANNEL_A, 0, 0, 0); /* off */
|
||||
set_led(LED_CHANNEL_B, 0, 0, 0); /* off */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -533,15 +374,12 @@ void handle_usb_packet(void *packet, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
void uart_handle_user_packet(struct ll_pkt *pkt, size_t len) {
|
||||
}
|
||||
|
||||
void DMA1_Channel2_3_IRQHandler() {
|
||||
int flags = DMA1->ISR;
|
||||
DMA1->IFCR = DMA_IFCR_CGIF2 | DMA_IFCR_CGIF3;
|
||||
|
||||
if (flags & DMA_ISR_FLAGS_CH(2)) {
|
||||
if (st_adc.has_adc) {
|
||||
if (board_config == BCFG_MEAS) {
|
||||
adc_dma_interrupt(2, flags>>DMA_ISR_FLAGS_Pos(2));
|
||||
} else {
|
||||
uart_dma_interrupt(2, flags>>DMA_ISR_FLAGS_Pos(2));
|
||||
|
|
@ -550,7 +388,7 @@ void DMA1_Channel2_3_IRQHandler() {
|
|||
}
|
||||
|
||||
if (flags & DMA_ISR_FLAGS_CH(3)) {
|
||||
if (st_adc.has_adc) {
|
||||
if (board_config == BCFG_MEAS) {
|
||||
adc_dma_interrupt(3, flags>>DMA_ISR_FLAGS_Pos(3));
|
||||
}
|
||||
}
|
||||
|
|
@ -561,13 +399,13 @@ void DMA1_Channel4_5_6_7_IRQHandler() {
|
|||
DMA1->IFCR = DMA_IFCR_CGIF4 | DMA_IFCR_CGIF5 | DMA_IFCR_CGIF6 | DMA_IFCR_CGIF7;
|
||||
|
||||
if (flags & DMA_ISR_FLAGS_CH(6)) {
|
||||
if (st_lcd.has_lcd) {
|
||||
if (board_config == BCFG_DISPLAY) {
|
||||
lcd_dma_interrupt(6, flags>>DMA_ISR_FLAGS_Pos(6));
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & DMA_ISR_FLAGS_CH(7)) {
|
||||
if (st_lcd.has_lcd) {
|
||||
if (board_config == BCFG_DISPLAY) {
|
||||
lcd_dma_interrupt(6, flags>>DMA_ISR_FLAGS_Pos(7));
|
||||
} else {
|
||||
uart_dma_interrupt(7, flags>>DMA_ISR_FLAGS_Pos(7));
|
||||
|
|
@ -605,7 +443,9 @@ 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++;
|
||||
for (; n; n--) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
|
@ -623,7 +463,15 @@ void *memset(void *dest, int c, size_t n)
|
|||
return dest;
|
||||
}
|
||||
|
||||
void __libc_init_array (void) __attribute__((weak));
|
||||
void __libc_init_array ()
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *start = s;
|
||||
while (*s) {
|
||||
s++;
|
||||
}
|
||||
return s - start;
|
||||
}
|
||||
|
||||
void __libc_init_array (void) __attribute__((weak));
|
||||
void __libc_init_array () {
|
||||
}
|
||||
|
|
|
|||
22
src/proto.c
22
src/proto.c
|
|
@ -19,7 +19,7 @@ void proto_init() {
|
|||
|
||||
void proto_loop() {
|
||||
if (board_config == BCFG_MOTOR) { /* We are the protocol host */
|
||||
if (sys_time_us - st_proto.last_start > PROTO_UPDATE_INTERVAL_MS*1000 - st_proto.delta ) {
|
||||
if (sys_time_us - st_proto.last_start > PROTO_UPDATE_INTERVAL_MS*1000UL - st_proto.delta ) {
|
||||
st_proto.fsm = ST_START;
|
||||
proto_handle_host(false);
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ void uart_handle_user_packet(struct ll_pkt *pkt, size_t len) {
|
|||
st_proto.rx_estop = st_proto.rx_buttons & PROTO_DSP_BT_ESTOP;
|
||||
|
||||
} else if (pkt->type == PK_TIME_SYNC) {
|
||||
sync_time_us = ((pkt_time_sync *)pkt)->timestamp;
|
||||
sync_time_us = ((struct pkt_time_sync *)pkt)->time;
|
||||
}
|
||||
|
||||
if (board_config == BCFG_MOTOR) { /* We are the protocol host */
|
||||
|
|
@ -68,7 +68,7 @@ void proto_handle_host(bool timeout) {
|
|||
ErrorCode rc = ERR_SUCCESS;
|
||||
switch (st_proto.fsm) {
|
||||
case ST_START:
|
||||
st_proto.delta += (sys_time_us - st_proto.last_start) - UPDATE_INTERVAL_MS*1000;
|
||||
st_proto.delta += (sys_time_us - st_proto.last_start) - PROTO_UPDATE_INTERVAL_MS*1000;
|
||||
st_proto.last_start = sys_time_us;
|
||||
tx_time_sync();
|
||||
st_proto.fsm = ST_TIME_SYNC;
|
||||
|
|
@ -123,8 +123,8 @@ void tx_adc_data() {
|
|||
|
||||
/* Format samples stored in native 32 bit ints into 24 bit fields */
|
||||
ssize_t rd_idx = st_adc.sample_rd_idx;
|
||||
uint8_t *p = samples;
|
||||
for (size_t i=0; i<COUNT_OF(pk.samples)) {
|
||||
uint8_t *p = (uint8_t *)pk.samples;
|
||||
for (size_t i=0; i<COUNT_OF(pk.samples); i++) {
|
||||
uint32_t sp = st_adc.samples[rd_idx][0];
|
||||
*p++ = sp&0xff;
|
||||
*p++ = (sp>>8)&0xff;
|
||||
|
|
@ -141,7 +141,7 @@ void tx_adc_data() {
|
|||
}
|
||||
}
|
||||
|
||||
ErrorCode rc = uart_send_packet_nonblocking(&pk, sizeof(pk));
|
||||
ErrorCode rc = uart_send_packet_nonblocking(&pk.ll_pkt, sizeof(pk));
|
||||
if (rc) {
|
||||
st_proto.error = rc;
|
||||
st_proto.last_error = sys_time_us;
|
||||
|
|
@ -156,10 +156,10 @@ void tx_time_sync() {
|
|||
.pid = 0,
|
||||
.type = PK_TIME_SYNC,
|
||||
},
|
||||
.time = sys_time_us;
|
||||
.time = sys_time_us,
|
||||
};
|
||||
|
||||
ErrorCode rc = uart_send_packet_nonblocking(&pk, sizeof(pk));
|
||||
ErrorCode rc = uart_send_packet_nonblocking(&pk.ll_pkt, sizeof(pk));
|
||||
if (rc) {
|
||||
st_proto.error = rc;
|
||||
st_proto.last_error = sys_time_us;
|
||||
|
|
@ -212,11 +212,11 @@ ErrorCode tx_update_display() {
|
|||
|
||||
memset(pk.lcd, ' ', sizeof(pk.lcd));
|
||||
if (st_proto.error_msg) {
|
||||
memcpy(pk.lcd[0], st_proto.error_msg, strlen(st_proto.error_msg));
|
||||
memcpy(pk.lcd, st_proto.error_msg, strlen(st_proto.error_msg));
|
||||
} else if (st_proto.status_msg) {
|
||||
memcpy(pk.lcd[0], st_proto.status_msg, strlen(st_proto.status_msg));
|
||||
memcpy(pk.lcd, st_proto.status_msg, strlen(st_proto.status_msg));
|
||||
}
|
||||
|
||||
return uart_send_packet_nonblocking(&pk, sizeof(pk));
|
||||
return uart_send_packet_nonblocking(&pk.ll_pkt, sizeof(pk));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,14 +71,14 @@ void uart_interrupt(uint32_t isr) {
|
|||
return;
|
||||
|
||||
if (rc < 0) {
|
||||
uart_st.error = ERR_RX_FRAMING;
|
||||
uart_st.error = ERR_FRAMING;
|
||||
uart_st.last_error = sys_time_us;
|
||||
return;
|
||||
}
|
||||
|
||||
/* A complete frame received */
|
||||
if (rc < (int)sizeof(struct ll_pkt)) {
|
||||
uart_st.error = ERR_RX_PROTOCOL;
|
||||
uart_st.error = ERR_PROTOCOL;
|
||||
uart_st.last_error = sys_time_us;
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
12
src/usb_if.c
12
src/usb_if.c
|
|
@ -148,16 +148,16 @@ static usbd_respond usb_getdesc (usbd_ctlreq *req, void **address, uint16_t *len
|
|||
const uint8_t dtype = req->wValue >> 8;
|
||||
const uint8_t dnumber = req->wValue & 0xFF;
|
||||
switch (dtype) {
|
||||
case USB_DTYPE_DEVICE: *address = &device_desc; *length = device_desc.bLength; return usbd_ack;
|
||||
case USB_DTYPE_CONFIGURATION: *address = &config_desc; *length = sizeof(config_desc); return usbd_ack;
|
||||
case USB_DTYPE_DEVICE: *address = (void **)&device_desc; *length = device_desc.bLength; return usbd_ack;
|
||||
case USB_DTYPE_CONFIGURATION: *address = (void **)&config_desc; *length = sizeof(config_desc); return usbd_ack;
|
||||
case USB_DTYPE_STRING: break;
|
||||
default: return usbd_fail;
|
||||
}
|
||||
|
||||
switch (dnumber) {
|
||||
case 0: *address = &lang_desc; *length = lang_desc.bLength; return usbd_ack;
|
||||
case 1: *address = &manuf_desc_en; *length = manuf_desc_en.bLength; return usbd_ack;
|
||||
case 2: *address = &prod_desc_en; *length = prod_desc_en.bLength; return usbd_ack;
|
||||
case 0: *address = (void **)&lang_desc; *length = lang_desc.bLength; return usbd_ack;
|
||||
case 1: *address = (void **)&manuf_desc_en; *length = manuf_desc_en.bLength; return usbd_ack;
|
||||
case 2: *address = (void **)&prod_desc_en; *length = prod_desc_en.bLength; return usbd_ack;
|
||||
default: return usbd_fail;
|
||||
}
|
||||
}
|
||||
|
|
@ -271,7 +271,7 @@ static usbd_respond usb_setconf (usbd_device *dev, uint8_t cfg) {
|
|||
}
|
||||
|
||||
void usb_init() {
|
||||
memset(st_usb, 0, sizeof(st_usb));
|
||||
memset(&st_usb, 0, sizeof(st_usb));
|
||||
usbd_init(&st_usb.usb_dev, &usbd_hw, USB_EP0_SIZE, st_usb.usb_buf, sizeof(st_usb.usb_buf));
|
||||
usbd_reg_config(&st_usb.usb_dev, usb_setconf);
|
||||
usbd_reg_control(&st_usb.usb_dev, usb_control);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue