Improve USB UART handling. Fix interrupt priorities.

This commit is contained in:
Gareth McMullin 2012-05-26 20:57:47 +12:00
parent b98d01dff8
commit 3dcdc5b26f
4 changed files with 40 additions and 6 deletions

View File

@ -521,7 +521,7 @@ static void cdcacm_set_config(u16 wValue)
/* Serial interface */
usbd_ep_setup(0x03, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, cdcacm_data_rx_cb);
usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, NULL);
usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, uart_usb_buf_drain);
usbd_ep_setup(0x84, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
/* Trace interface */
@ -563,9 +563,9 @@ void cdcacm_init(void)
usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
usbd_register_set_config_callback(cdcacm_set_config);
nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, 1);
nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, IRQ_PRI_USB);
nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ);
nvic_set_priority(USB_VBUS_IRQ, 14);
nvic_set_priority(USB_VBUS_IRQ, IRQ_PRI_USB_VBUS);
nvic_enable_irq(USB_VBUS_IRQ);
gpio_set(USB_VBUS_PORT, USB_VBUS_PIN);

View File

@ -238,15 +238,37 @@ static void uart_init(void)
/* Enable interrupts */
USART1_CR1 |= USART_CR1_RXNEIE;
nvic_set_priority(NVIC_USART1_IRQ, 14);
nvic_set_priority(NVIC_USART1_IRQ, IRQ_PRI_USART1);
nvic_enable_irq(NVIC_USART1_IRQ);
}
static uint8_t uart_usb_buf[CDCACM_PACKET_SIZE];
static uint8_t uart_usb_buf_size;
void uart_usb_buf_drain(uint8_t ep)
{
if (!uart_usb_buf_size)
return;
usbd_ep_write_packet(ep, uart_usb_buf, uart_usb_buf_size);
uart_usb_buf_size = 0;
}
void usart1_isr(void)
{
char c = usart_recv(USART1);
usbd_ep_write_packet(0x83, &c, 1);
/* Try to send now */
if (usbd_ep_write_packet(0x83, &c, 1) == 1)
return;
/* We failed, so queue for later */
if (uart_usb_buf_size == CDCACM_PACKET_SIZE) {
/* Drop if the buffer's full: we have no flow control */
return;
}
uart_usb_buf[uart_usb_buf_size++] = c;
}
#endif

View File

@ -80,6 +80,15 @@
#define LED_IDLE GPIO10
#define LED_ERROR GPIO11
/* Interrupt priorities. Low numbers are high priority.
* For now USART1 preempts USB which may spin while buffer is drained.
* TIM3 is used for traceswo capture and must be highest priority.
*/
#define IRQ_PRI_USB (2 << 4)
#define IRQ_PRI_USART1 (1 << 4)
#define IRQ_PRI_USB_VBUS (14 << 4)
#define IRQ_PRI_TIM3 (0 << 4)
#define DEBUG(...)
extern uint8_t running_status;
@ -121,6 +130,9 @@ void cdcacm_init(void);
int cdcacm_get_config(void);
int cdcacm_get_dtr(void);
/* <platform.h> */
void uart_usb_buf_drain(uint8_t ep);
/* Use newlib provided integer only stdio functions */
#define sscanf siscanf
#define sprintf siprintf

View File

@ -68,7 +68,7 @@ void traceswo_init(void)
timer_slave_set_mode(TIM3, TIM_SMCR_SMS_RM);
/* Enable capture interrupt */
nvic_set_priority(NVIC_TIM3_IRQ, 0);
nvic_set_priority(NVIC_TIM3_IRQ, IRQ_PRI_TIM3);
nvic_enable_irq(NVIC_TIM3_IRQ);
timer_enable_irq(TIM3, TIM_DIER_CC1IE);