Skip to content

Commit d68508c

Browse files
robbederksrbiasini
authored andcommittedAug 28, 2019
Gpio race condition fix (#263)
* Fixed pedal not initializing * Interrupt changes * More changes
1 parent d69d05f commit d68508c

File tree

10 files changed

+70
-47
lines changed

10 files changed

+70
-47
lines changed
 

‎board/board.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,12 @@ void detect_configuration(void) {
4848
has_external_debug_serial = detect_with_pull(GPIOA, 3, PULL_DOWN);
4949

5050
#ifdef PANDA
51-
// check if the ESP is trying to put me in boot mode
52-
is_entering_bootmode = !detect_with_pull(GPIOB, 0, PULL_UP);
51+
if(hw_type == HW_TYPE_WHITE_PANDA) {
52+
// check if the ESP is trying to put me in boot mode
53+
is_entering_bootmode = !detect_with_pull(GPIOB, 0, PULL_UP);
54+
} else {
55+
is_entering_bootmode = 0;
56+
}
5357
#else
5458
is_entering_bootmode = 0;
5559
#endif
@@ -58,4 +62,4 @@ void detect_configuration(void) {
5862
// ///// Board functions ///// //
5963
bool board_has_gps(void) {
6064
return ((hw_type == HW_TYPE_GREY_PANDA) || (hw_type == HW_TYPE_BLACK_PANDA));
61-
}
65+
}

‎board/bootstub.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ extern void *_app_start[];
6363
// BOUNTY: $200 coupon on shop.comma.ai or $100 check.
6464

6565
int main(void) {
66-
__disable_irq();
66+
disable_interrupts();
6767
clock_init();
6868
detect_configuration();
6969
detect_board_type();

‎board/drivers/can.h

+13-12
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ int can_overflow_cnt = 0;
6262
bool can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
6363
bool ret = 0;
6464

65-
enter_critical_section();
65+
ENTER_CRITICAL();
6666
if (q->w_ptr != q->r_ptr) {
6767
*elem = q->elems[q->r_ptr];
6868
if ((q->r_ptr + 1U) == q->fifo_size) {
@@ -72,7 +72,7 @@ bool can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
7272
}
7373
ret = 1;
7474
}
75-
exit_critical_section();
75+
EXIT_CRITICAL();
7676

7777
return ret;
7878
}
@@ -81,7 +81,7 @@ bool can_push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
8181
bool ret = false;
8282
uint32_t next_w_ptr;
8383

84-
enter_critical_section();
84+
ENTER_CRITICAL();
8585
if ((q->w_ptr + 1U) == q->fifo_size) {
8686
next_w_ptr = 0;
8787
} else {
@@ -92,7 +92,7 @@ bool can_push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
9292
q->w_ptr = next_w_ptr;
9393
ret = true;
9494
}
95-
exit_critical_section();
95+
EXIT_CRITICAL();
9696
if (!ret) {
9797
can_overflow_cnt++;
9898
#ifdef DEBUG
@@ -103,10 +103,10 @@ bool can_push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
103103
}
104104

105105
void can_clear(can_ring *q) {
106-
enter_critical_section();
106+
ENTER_CRITICAL();
107107
q->w_ptr = 0;
108108
q->r_ptr = 0;
109-
exit_critical_section();
109+
EXIT_CRITICAL();
110110
}
111111

112112
// assign CAN numbering
@@ -124,7 +124,7 @@ uint8_t bus_lookup[] = {0,1,2};
124124
uint8_t can_num_lookup[] = {0,1,2,-1};
125125
int8_t can_forwarding[] = {-1,-1,-1,-1};
126126
uint32_t can_speed[] = {5000, 5000, 5000, 333};
127-
#define CAN_MAX 3
127+
#define CAN_MAX 3U
128128

129129
#define CANIF_FROM_CAN_NUM(num) (cans[num])
130130
#define CAN_NUM_FROM_CANIF(CAN) ((CAN)==CAN1 ? 0 : ((CAN) == CAN2 ? 1 : 2))
@@ -158,9 +158,10 @@ void can_init(uint8_t can_number) {
158158
}
159159

160160
void can_init_all(void) {
161-
for (int i=0; i < CAN_MAX; i++) {
161+
for (uint8_t i=0U; i < CAN_MAX; i++) {
162162
can_init(i);
163163
}
164+
current_board->enable_can_transcievers(true);
164165
}
165166

166167
void can_flip_buses(uint8_t bus1, uint8_t bus2){
@@ -248,7 +249,7 @@ void can_set_obd(uint8_t harness_orientation, bool obd){
248249

249250
// CAN error
250251
void can_sce(CAN_TypeDef *CAN) {
251-
enter_critical_section();
252+
ENTER_CRITICAL();
252253

253254
#ifdef DEBUG
254255
if (CAN==CAN1) puts("CAN1: ");
@@ -271,15 +272,15 @@ void can_sce(CAN_TypeDef *CAN) {
271272

272273
can_err_cnt += 1;
273274
llcan_clear_send(CAN);
274-
exit_critical_section();
275+
EXIT_CRITICAL();
275276
}
276277

277278
// ***************************** CAN *****************************
278279

279280
void process_can(uint8_t can_number) {
280281
if (can_number != 0xffU) {
281282

282-
enter_critical_section();
283+
ENTER_CRITICAL();
283284

284285
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
285286
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
@@ -327,7 +328,7 @@ void process_can(uint8_t can_number) {
327328
}
328329
}
329330

330-
exit_critical_section();
331+
EXIT_CRITICAL();
331332
}
332333
}
333334

‎board/drivers/llgpio.h

+10
Original file line numberDiff line numberDiff line change
@@ -11,42 +11,52 @@
1111
#define OUTPUT_TYPE_OPEN_DRAIN 1U
1212

1313
void set_gpio_mode(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int mode) {
14+
ENTER_CRITICAL();
1415
uint32_t tmp = GPIO->MODER;
1516
tmp &= ~(3U << (pin * 2U));
1617
tmp |= (mode << (pin * 2U));
1718
GPIO->MODER = tmp;
19+
EXIT_CRITICAL();
1820
}
1921

2022
void set_gpio_output(GPIO_TypeDef *GPIO, unsigned int pin, bool enabled) {
23+
ENTER_CRITICAL();
2124
if (enabled) {
2225
GPIO->ODR |= (1U << pin);
2326
} else {
2427
GPIO->ODR &= ~(1U << pin);
2528
}
2629
set_gpio_mode(GPIO, pin, MODE_OUTPUT);
30+
EXIT_CRITICAL();
2731
}
2832

2933
void set_gpio_output_type(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int output_type){
34+
ENTER_CRITICAL();
3035
if(output_type == OUTPUT_TYPE_OPEN_DRAIN) {
3136
GPIO->OTYPER |= (1U << pin);
3237
} else {
3338
GPIO->OTYPER &= ~(1U << pin);
3439
}
40+
EXIT_CRITICAL();
3541
}
3642

3743
void set_gpio_alternate(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int mode) {
44+
ENTER_CRITICAL();
3845
uint32_t tmp = GPIO->AFR[pin >> 3U];
3946
tmp &= ~(0xFU << ((pin & 7U) * 4U));
4047
tmp |= mode << ((pin & 7U) * 4U);
4148
GPIO->AFR[pin >> 3] = tmp;
4249
set_gpio_mode(GPIO, pin, MODE_ALTERNATE);
50+
EXIT_CRITICAL();
4351
}
4452

4553
void set_gpio_pullup(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int mode) {
54+
ENTER_CRITICAL();
4655
uint32_t tmp = GPIO->PUPDR;
4756
tmp &= ~(3U << (pin * 2U));
4857
tmp |= (mode << (pin * 2U));
4958
GPIO->PUPDR = tmp;
59+
EXIT_CRITICAL();
5060
}
5161

5262
int get_gpio_input(GPIO_TypeDef *GPIO, unsigned int pin) {

‎board/drivers/uart.h

+12-12
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ uart_ring *get_ring_by_number(int a) {
7474
// ***************************** serial port *****************************
7575

7676
void uart_ring_process(uart_ring *q) {
77-
enter_critical_section();
77+
ENTER_CRITICAL();
7878
// TODO: check if external serial is connected
7979
int sr = q->uart->SR;
8080

@@ -108,7 +108,7 @@ void uart_ring_process(uart_ring *q) {
108108
// set dropped packet flag?
109109
}
110110

111-
exit_critical_section();
111+
EXIT_CRITICAL();
112112
}
113113

114114
// interrupt boilerplate
@@ -121,13 +121,13 @@ void UART5_IRQHandler(void) { uart_ring_process(&lin1_ring); }
121121
bool getc(uart_ring *q, char *elem) {
122122
bool ret = false;
123123

124-
enter_critical_section();
124+
ENTER_CRITICAL();
125125
if (q->w_ptr_rx != q->r_ptr_rx) {
126126
if (elem != NULL) *elem = q->elems_rx[q->r_ptr_rx];
127127
q->r_ptr_rx = (q->r_ptr_rx + 1U) % FIFO_SIZE;
128128
ret = true;
129129
}
130-
exit_critical_section();
130+
EXIT_CRITICAL();
131131

132132
return ret;
133133
}
@@ -136,14 +136,14 @@ bool injectc(uart_ring *q, char elem) {
136136
int ret = false;
137137
uint16_t next_w_ptr;
138138

139-
enter_critical_section();
139+
ENTER_CRITICAL();
140140
next_w_ptr = (q->w_ptr_rx + 1U) % FIFO_SIZE;
141141
if (next_w_ptr != q->r_ptr_rx) {
142142
q->elems_rx[q->w_ptr_rx] = elem;
143143
q->w_ptr_rx = next_w_ptr;
144144
ret = true;
145145
}
146-
exit_critical_section();
146+
EXIT_CRITICAL();
147147

148148
return ret;
149149
}
@@ -152,14 +152,14 @@ bool putc(uart_ring *q, char elem) {
152152
bool ret = false;
153153
uint16_t next_w_ptr;
154154

155-
enter_critical_section();
155+
ENTER_CRITICAL();
156156
next_w_ptr = (q->w_ptr_tx + 1U) % FIFO_SIZE;
157157
if (next_w_ptr != q->r_ptr_tx) {
158158
q->elems_tx[q->w_ptr_tx] = elem;
159159
q->w_ptr_tx = next_w_ptr;
160160
ret = true;
161161
}
162-
exit_critical_section();
162+
EXIT_CRITICAL();
163163

164164
uart_ring_process(q);
165165

@@ -185,12 +185,12 @@ void uart_send_break(uart_ring *u) {
185185
}
186186

187187
void clear_uart_buff(uart_ring *q) {
188-
enter_critical_section();
188+
ENTER_CRITICAL();
189189
q->w_ptr_tx = 0;
190190
q->r_ptr_tx = 0;
191191
q->w_ptr_rx = 0;
192192
q->r_ptr_rx = 0;
193-
exit_critical_section();
193+
EXIT_CRITICAL();
194194
}
195195

196196
// ***************************** start UART code *****************************
@@ -215,7 +215,7 @@ char usart1_dma[USART1_DMA_LEN];
215215
void uart_dma_drain(void) {
216216
uart_ring *q = &esp_ring;
217217

218-
enter_critical_section();
218+
ENTER_CRITICAL();
219219

220220
if ((DMA2->HISR & DMA_HISR_TCIF5) || (DMA2->HISR & DMA_HISR_HTIF5) || (DMA2_Stream5->NDTR != USART1_DMA_LEN)) {
221221
// disable DMA
@@ -245,7 +245,7 @@ void uart_dma_drain(void) {
245245
q->uart->CR3 |= USART_CR3_DMAR;
246246
}
247247

248-
exit_critical_section();
248+
EXIT_CRITICAL();
249249
}
250250

251251
void DMA2_Stream5_IRQHandler(void) {

‎board/gpio.h

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ void jump_to_bootloader(void) {
2020
}
2121

2222
void early(void) {
23+
// Reset global critical depth
24+
global_critical_depth = 0;
25+
26+
// neccesary for DFU flashing on a non-power cycled white panda
27+
enable_interrupts();
28+
2329
// after it's been in the bootloader, things are initted differently, so we reset
2430
if ((enter_bootloader_mode != BOOT_NORMAL) &&
2531
(enter_bootloader_mode != ENTER_BOOTLOADER_MAGIC) &&

‎board/libc.h

+14-12
Original file line numberDiff line numberDiff line change
@@ -42,24 +42,26 @@ int memcmp(const void * ptr1, const void * ptr2, unsigned int num) {
4242

4343
// ********************* IRQ helpers *********************
4444

45-
int interrupts_enabled = 0;
45+
volatile bool interrupts_enabled = false;
46+
4647
void enable_interrupts(void) {
47-
interrupts_enabled = 1;
48+
interrupts_enabled = true;
4849
__enable_irq();
4950
}
5051

51-
int critical_depth = 0;
52-
void enter_critical_section(void) {
52+
void disable_interrupts(void) {
53+
interrupts_enabled = false;
5354
__disable_irq();
54-
// this is safe because interrupts are disabled
55-
critical_depth += 1;
5655
}
5756

58-
void exit_critical_section(void) {
59-
// this is safe because interrupts are disabled
60-
critical_depth -= 1;
61-
if ((critical_depth == 0) && interrupts_enabled) {
62-
__enable_irq();
57+
uint8_t global_critical_depth = 0U;
58+
#define ENTER_CRITICAL() \
59+
__disable_irq(); \
60+
global_critical_depth += 1U;
61+
62+
#define EXIT_CRITICAL() \
63+
global_critical_depth -= 1U; \
64+
if ((global_critical_depth == 0U) && interrupts_enabled) { \
65+
__enable_irq(); \
6366
}
64-
}
6567

‎board/main.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ void TIM3_IRQHandler(void) {
645645

646646
int main(void) {
647647
// shouldn't have interrupts here, but just in case
648-
__disable_irq();
648+
disable_interrupts();
649649

650650
// init early devices
651651
clock_init();

‎board/pedal/main.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,18 @@ void debug_ring_callback(uart_ring *ring) {
5555
}
5656
}
5757

58-
int usb_cb_ep1_in(uint8_t *usbdata, int len, bool hardwired) {
58+
int usb_cb_ep1_in(void *usbdata, int len, bool hardwired) {
5959
UNUSED(usbdata);
6060
UNUSED(len);
6161
UNUSED(hardwired);
6262
return 0;
6363
}
64-
void usb_cb_ep2_out(uint8_t *usbdata, int len, bool hardwired) {
64+
void usb_cb_ep2_out(void *usbdata, int len, bool hardwired) {
6565
UNUSED(usbdata);
6666
UNUSED(len);
6767
UNUSED(hardwired);
6868
}
69-
void usb_cb_ep3_out(uint8_t *usbdata, int len, bool hardwired) {
69+
void usb_cb_ep3_out(void *usbdata, int len, bool hardwired) {
7070
UNUSED(usbdata);
7171
UNUSED(len);
7272
UNUSED(hardwired);
@@ -299,7 +299,7 @@ void pedal(void) {
299299
}
300300

301301
int main(void) {
302-
__disable_irq();
302+
disable_interrupts();
303303

304304
// init devices
305305
clock_init();
@@ -334,7 +334,7 @@ int main(void) {
334334
watchdog_init();
335335

336336
puts("**** INTERRUPTS ON ****\n");
337-
__enable_irq();
337+
enable_interrupts();
338338

339339
// main pedal loop
340340
while (1) {

0 commit comments

Comments
 (0)