Skip to content

Commit 8d0cc71

Browse files
committed
Add write protections, fix edge case read halt
1 parent e605ce6 commit 8d0cc71

File tree

1 file changed

+16
-42
lines changed
  • ports/stm32f4/common-hal/busio

1 file changed

+16
-42
lines changed

ports/stm32f4/common-hal/busio/UART.c

Lines changed: 16 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,8 @@
3838
#include "tick.h"
3939
#include "stm32f4xx_hal.h"
4040

41-
bool iflag;
42-
int errflag;
43-
bool rxflag;
44-
bool bsyflag;
45-
4641
STATIC bool reserved_uart[MAX_UART];
42+
int errflag; //Used to restart read halts
4743

4844
void uart_reset(void) {
4945
#ifdef USART1
@@ -88,7 +84,6 @@ void uart_reset(void) {
8884
__HAL_RCC_USART6_RELEASE_RESET();
8985
__HAL_RCC_USART6_CLK_DISABLE();
9086
#endif
91-
//TODO: this technically needs to go to 10 to support F413. Any way to condense?
9287
}
9388

9489
STATIC USART_TypeDef * assign_uart_or_throw(busio_uart_obj_t *self, bool pin_eval,
@@ -302,34 +297,21 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
302297
if ((HAL_UART_GetState(&self->handle) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) {
303298
mp_raise_ValueError(translate("Could not start interrupt, RX busy"));
304299
}
305-
HAL_NVIC_DisableIRQ(self->irq); //prevent handle lock contention
306300

301+
//start the recieve interrupt chain
302+
HAL_NVIC_DisableIRQ(self->irq); //prevent handle lock contention
307303
HAL_UART_Receive_IT(&self->handle, &self->rx_char, 1);
308-
309304
HAL_NVIC_SetPriority(self->irq, UART_IRQPRI, UART_IRQSUB_PRI);
310305
HAL_NVIC_EnableIRQ(self->irq);
311306

312-
//mp_printf(&mp_plat_print, "Started and inited\n");
313-
iflag = 0;
314-
errflag = 0;
315-
rxflag = 0;
316-
bsyflag = 0;
317-
318-
//interrupt debuggery
319-
GPIO_InitStruct.Pin = pin_mask(7);
320-
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
321-
GPIO_InitStruct.Pull = GPIO_NOPULL;
322-
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
323-
HAL_GPIO_Init(pin_port(2), &GPIO_InitStruct);
324-
HAL_GPIO_WritePin(pin_port(2),pin_mask(7),0);
307+
errflag = HAL_OK;
325308
}
326309

327310
bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) {
328311
return self->tx->pin == mp_const_none;
329312
}
330313

331314
void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
332-
//mp_printf(&mp_plat_print, "De-init UART\n");
333315
reset_pin_number(self->tx->pin->port,self->tx->pin->number);
334316
reset_pin_number(self->rx->pin->port,self->rx->pin->number);
335317
self->tx = mp_const_none;
@@ -339,7 +321,6 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
339321
self->rbuf.iput = self->rbuf.iget = 0;
340322
}
341323

342-
// Read characters.
343324
size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
344325
if (self->rx == NULL) {
345326
mp_raise_ValueError(translate("No RX pin"));
@@ -363,20 +344,14 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
363344

364345
// Halt reception
365346
HAL_NVIC_DisableIRQ(self->irq);
366-
367347
// copy received data
368348
rx_bytes = ringbuf_count(&self->rbuf);
369-
//Used for debuggings
370-
//mp_printf(&mp_plat_print, "Read: count:%d, buffer location%p, if:%der:%drx:%dbsy:%d\n", rx_bytes, &self->rbuf,iflag,errflag,rxflag,bsyflag);
371-
iflag = 0;
372-
errflag = 0;
373-
rxflag = 0;
374-
bsyflag = 0;
349+
//Used for debugging
350+
//mp_printf(&mp_plat_print, "Read: count:%d, buffer location%p, er:%d\n", rx_bytes, &self->rbuf,errflag);
375351
rx_bytes = MIN(rx_bytes, len);
376352
for ( uint16_t i = 0; i < rx_bytes; i++ ) {
377353
data[i] = ringbuf_get(&self->rbuf);
378354
}
379-
380355
HAL_NVIC_EnableIRQ(self->irq);
381356

382357
if (rx_bytes == 0) {
@@ -392,25 +367,27 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data,
392367
mp_raise_ValueError(translate("No TX pin"));
393368
}
394369

395-
if (HAL_UART_Transmit(&self->handle, (uint8_t *)data, len, 500) == HAL_OK) {
396-
return len;
397-
} else {
370+
HAL_NVIC_DisableIRQ(self->irq);
371+
372+
if (HAL_UART_Transmit(&self->handle, (uint8_t *)data, len, self->timeout_ms) != HAL_OK) {
398373
mp_raise_ValueError(translate("UART write error"));
399374
}
400-
//mp_printf(&mp_plat_print, "Send\n");
401-
return 0;
375+
376+
HAL_UART_Receive_IT(&self->handle, &self->rx_char, 1);
377+
HAL_NVIC_SetPriority(self->irq, UART_IRQPRI, UART_IRQSUB_PRI);
378+
HAL_NVIC_EnableIRQ(self->irq);
379+
380+
return len;
402381
}
403382

404383
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle)
405384
{
406-
rxflag = 1;
407385
for(int i=0; i<7; i++) {
408386
//get context pointer and cast it as struct pointer
409387
busio_uart_obj_t * context = (busio_uart_obj_t *)MP_STATE_PORT(cpy_uart_obj_all)[i];
410388
if(handle == &context->handle) {
411389
//check if transaction is ongoing
412390
if((HAL_UART_GetState(handle) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) {
413-
bsyflag = 1;
414391
return;
415392
}
416393
ringbuf_put_n(&context->rbuf, &context->rx_char, 1);
@@ -468,25 +445,22 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
468445
}
469446

470447
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
471-
//mp_printf(&mp_plat_print, "Clear RX Buffer\n");
472448
// Halt reception
473449
HAL_NVIC_DisableIRQ(self->irq);
474450
ringbuf_clear(&self->rbuf);
475451
HAL_NVIC_EnableIRQ(self->irq);
476452
}
477453

478454
bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
479-
return true;
455+
return __HAL_UART_GET_FLAG(&self->handle,UART_FLAG_TXE);
480456
}
481457

482458
STATIC void call_hal_irq(int uart_num) {
483-
iflag = 1;
484459
//Create casted context pointer
485460
busio_uart_obj_t * context = (busio_uart_obj_t *)MP_STATE_PORT(cpy_uart_obj_all)[uart_num-1];
486461
if(context != NULL) {
487462
HAL_NVIC_ClearPendingIRQ(context->irq);
488463
HAL_UART_IRQHandler(&context->handle);
489-
HAL_GPIO_TogglePin(pin_port(2),pin_mask(7));
490464
}
491465
}
492466

0 commit comments

Comments
 (0)