Skip to content

Commit

Permalink
Merge pull request commaai#82 from commaai/uart_dma
Browse files Browse the repository at this point in the history
Uart dma
  • Loading branch information
geohot authored Jan 29, 2018
2 parents 5d2a4ba + fd68f86 commit b42db6d
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 22 deletions.
10 changes: 5 additions & 5 deletions board/drivers/drivers.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ void usb_cb_enumeration_complete();
// ********************* UART *********************
// IRQs: USART1, USART2, USART3, UART5

#define FIFO_SIZE 0x100
#define FIFO_SIZE 0x400
typedef struct uart_ring {
uint8_t w_ptr_tx;
uint8_t r_ptr_tx;
uint16_t w_ptr_tx;
uint16_t r_ptr_tx;
uint8_t elems_tx[FIFO_SIZE];
uint8_t w_ptr_rx;
uint8_t r_ptr_rx;
uint16_t w_ptr_rx;
uint16_t r_ptr_rx;
uint8_t elems_rx[FIFO_SIZE];
USART_TypeDef *uart;
void (*callback)(struct uart_ring*);
Expand Down
85 changes: 73 additions & 12 deletions board/drivers/uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void uart_ring_process(uart_ring *q) {
if (q->w_ptr_tx != q->r_ptr_tx) {
if (sr & USART_SR_TXE) {
q->uart->DR = q->elems_tx[q->r_ptr_tx];
q->r_ptr_tx += 1;
q->r_ptr_tx = (q->r_ptr_tx + 1) % FIFO_SIZE;
} else {
// push on interrupt later
q->uart->CR1 |= USART_CR1_TXEIE;
Expand All @@ -64,11 +64,13 @@ void uart_ring_process(uart_ring *q) {

if (sr & USART_SR_RXNE || sr & USART_SR_ORE) {
uint8_t c = q->uart->DR; // TODO: can drop packets
uint8_t next_w_ptr = q->w_ptr_rx + 1;
if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = c;
q->w_ptr_rx = next_w_ptr;
if (q->callback) q->callback(q);
if (q != &esp_ring) {
uint16_t next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = c;
q->w_ptr_rx = next_w_ptr;
if (q->callback) q->callback(q);
}
}
}

Expand All @@ -92,7 +94,7 @@ int getc(uart_ring *q, char *elem) {
enter_critical_section();
if (q->w_ptr_rx != q->r_ptr_rx) {
*elem = q->elems_rx[q->r_ptr_rx];
q->r_ptr_rx += 1;
q->r_ptr_rx = (q->r_ptr_rx + 1) % FIFO_SIZE;
ret = 1;
}
exit_critical_section();
Expand All @@ -102,10 +104,10 @@ int getc(uart_ring *q, char *elem) {

int injectc(uart_ring *q, char elem) {
int ret = 0;
uint8_t next_w_ptr;
uint16_t next_w_ptr;

enter_critical_section();
next_w_ptr = q->w_ptr_rx + 1;
next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = elem;
q->w_ptr_rx = next_w_ptr;
Expand All @@ -118,10 +120,10 @@ int injectc(uart_ring *q, char elem) {

int putc(uart_ring *q, char elem) {
int ret = 0;
uint8_t next_w_ptr;
uint16_t next_w_ptr;

enter_critical_section();
next_w_ptr = q->w_ptr_tx + 1;
next_w_ptr = (q->w_ptr_tx + 1) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_tx) {
q->elems_tx[q->w_ptr_tx] = elem;
q->w_ptr_tx = next_w_ptr;
Expand Down Expand Up @@ -159,6 +161,51 @@ void uart_set_baud(USART_TypeDef *u, int baud) {
}
}

#define USART1_DMA_LEN 0x20
char usart1_dma[USART1_DMA_LEN];

void uart_dma_drain() {
uart_ring *q = &esp_ring;

enter_critical_section();

if (DMA2->HISR & DMA_HISR_TCIF5 || DMA2->HISR & DMA_HISR_HTIF5 || DMA2_Stream5->NDTR != USART1_DMA_LEN) {
// disable DMA
q->uart->CR3 &= ~USART_CR3_DMAR;
DMA2_Stream5->CR &= ~DMA_SxCR_EN;
while (DMA2_Stream5->CR & DMA_SxCR_EN);

int i;
for (i = 0; i < USART1_DMA_LEN - DMA2_Stream5->NDTR; i++) {
char c = usart1_dma[i];
uint16_t next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = c;
q->w_ptr_rx = next_w_ptr;
}
}

// reset DMA len
DMA2_Stream5->NDTR = USART1_DMA_LEN;

// clear interrupts
DMA2->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5;
//DMA2->HIFCR = DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5;

// enable DMA
DMA2_Stream5->CR |= DMA_SxCR_EN;
q->uart->CR3 |= USART_CR3_DMAR;
}

exit_critical_section();
}

void DMA2_Stream5_IRQHandler(void) {
//set_led(LED_BLUE, 1);
uart_dma_drain();
//set_led(LED_BLUE, 0);
}

void uart_init(USART_TypeDef *u, int baud) {
// enable uart and tx+rx mode
u->CR1 = USART_CR1_UE;
Expand All @@ -170,9 +217,23 @@ void uart_init(USART_TypeDef *u, int baud) {
// ** UART is ready to work **

// enable interrupts
u->CR1 |= USART_CR1_RXNEIE;
if (u != USART1) {
u->CR1 |= USART_CR1_RXNEIE;
}

if (u == USART1) {
// DMA2, stream 2, channel 3
DMA2_Stream5->M0AR = (uint32_t)usart1_dma;
DMA2_Stream5->NDTR = USART1_DMA_LEN;
DMA2_Stream5->PAR = (uint32_t)&(USART1->DR);

// channel4, increment memory, periph -> memory, enable
DMA2_Stream5->CR = DMA_SxCR_CHSEL_2 | DMA_SxCR_MINC | DMA_SxCR_HTIE | DMA_SxCR_TCIE | DMA_SxCR_EN;

// this one uses DMA receiver
u->CR3 = USART_CR3_DMAR;

NVIC_EnableIRQ(DMA2_Stream5_IRQn);
NVIC_EnableIRQ(USART1_IRQn);
} else if (u == USART2) {
NVIC_EnableIRQ(USART2_IRQn);
Expand Down
12 changes: 9 additions & 3 deletions board/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
case 0xe0:
ur = get_ring_by_number(setup->b.wValue.w);
if (!ur) break;
if (ur == &esp_ring) uart_dma_drain();
// read
while ((resp_len < min(setup->b.wLength.w, MAX_RESP_LEN)) &&
getc(ur, (char*)&resp[resp_len])) {
Expand Down Expand Up @@ -508,9 +509,12 @@ int main() {
}

#ifdef PANDA
// enable ESP uart
uart_init(USART1, 115200);

if (is_grey_panda) {
uart_init(USART1, 9600);
} else {
// enable ESP uart
uart_init(USART1, 115200);
}
// enable LIN
uart_init(UART5, 10400);
UART5->CR2 |= USART_CR2_LINEN;
Expand Down Expand Up @@ -560,6 +564,8 @@ int main() {
for (cnt=0;;cnt++) {
can_live = pending_can_live;

//puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n");

#ifdef PANDA
int current = adc_get(ADCCHAN_CURRENT);

Expand Down
3 changes: 1 addition & 2 deletions tests/location_listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ def add_nmea_checksum(msg):
print ser.read(1024)

# upping baud rate
# 460800 has issues
baudrate = 115200
baudrate = 460800

print "upping baud rate"
msg = add_nmea_checksum("$PUBX,41,1,0007,0003,%d,0" % baudrate)+"\r\n"
Expand Down

0 comments on commit b42db6d

Please sign in to comment.