Hi,
I've mentioned the problem on #leaflabs, but I thought I would post it here for reference:
I experienced random, but frequent, lock ups with a setup where I used USARTS extensively along with an 250 Hz external interrupt with a rather slow ISR. The lock up was clearly related to, in my case, receiving on the USART. I have not figured out exactly what happens, but I think it is something along the lines of:
1. Data arrives on USART ->regs->DR
2. USART interrupt gets called
3. 250 Hz interrupt gets called before USART interrupt is finished or is started
4. 250 Hz interrupt takes so much time there occurs some error on the USART regs->DR part
5. USART interrupt locks up.
The lock up always happened on the line:
usart.c:usart_irq (usart_dev *dev):
rb_push/safe_insert (dev->rb, (uint8)dev->regs->DR);
As I said I don't know exactly what the error is, but by increasing the priority of the usart interrupt the lock up has been completely removed.
My fix: https://github.com/gauteh/libmaple/commit/1e10299b43e255a4029cacc18bdf248289be7092
libmaple/usart.c View file @ 1e10299
... ...
@@ -102,6 +102,11 @@ void usart_init(usart_dev *dev) {
102 102
rb_init(dev->rb, USART_RX_BUF_SIZE, dev->rx_buf);
103 103
rcc_clk_enable(dev->clk_id);
104 104
nvic_irq_enable(dev->irq_num);
105
+
106
+ /* Set to max priority to avoid race condition where register presumably
107
+ * might change before it can be picked out by USART interrupt and cause
108
+ * it to lock up. */
109
+ nvic_irq_set_priority (dev->irq_num, 0);
105 110
}
the other edit in usart.h is for good measure, I haven't had any problems with it.
Regards, Gaute