From fc0a62de18c2bb58c7b2f0293c5949c913774af8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 14 Apr 2019 11:08:44 +0200 Subject: [PATCH] Fix: USART - better RX/TX with one dma bank and wait loops (@ryan) --- common/usart.c | 70 +++++++++++++++++++++++++++++++++++++++++++++----- common/usart.h | 5 ++++ 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/common/usart.c b/common/usart.c index 8680d500a..cd657a2b1 100644 --- a/common/usart.c +++ b/common/usart.c @@ -42,7 +42,7 @@ void usart_close(void) { static uint8_t us_inbuf[sizeof(UsbCommand)]; static uint8_t us_outbuf[sizeof(UsbCommand)]; - +/* // transfer from client to device inline int16_t usart_readbuffer(uint8_t *data) { uint32_t rcr = pUS1->US_RCR; @@ -58,6 +58,38 @@ inline int16_t usart_readbuffer(uint8_t *data) { return 0; } } +*/ + +uint8_t check = 0; +inline int16_t usart_readbuffer(uint8_t *data) { + // Check if the first PDC bank is free + if (pUS1->US_RCR == 0) { + pUS1->US_RPR = (uint32_t)data; + pUS1->US_RCR = sizeof(UsbCommand); + pUS1->US_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN; + check = 0; + return 2; + } else { + return 0; + } +} + +void usart_readcheck(uint8_t *data,size_t len) { + if (pUS1->US_RCR 300000){ + pUS1->US_RPR = (uint32_t)data; + pUS1->US_RCR = len; + check = 0; + } + } else { + check = 0; + } +} inline bool usart_dataavailable(void) { return pUS1->US_RCR < sizeof(us_inbuf); @@ -66,14 +98,14 @@ inline bool usart_dataavailable(void) { inline int16_t usart_readcommand(uint8_t *data) { if (pUS1->US_RCR == 0) return usart_readbuffer(data); - else + return 0; } inline bool usart_commandavailable(void) { - return pUS1->US_RCR == 0; + return (pUS1->US_RCR == 0); } - +/* // transfer from device to client inline int16_t usart_writebuffer(uint8_t *data, size_t len) { @@ -90,6 +122,31 @@ inline int16_t usart_writebuffer(uint8_t *data, size_t len) { return 0; } } +*/ + +// transfer from device to client +inline int16_t usart_writebuffer(uint8_t *data, size_t len) { + + while (pUS1->US_TCR && pUS1->US_TNCR) {}; + + // Check if the first PDC bank is free + if (pUS1->US_TCR == 0) { + memcpy(us_outbuf, data, len); + pUS1->US_TPR = (uint32_t)us_outbuf; + pUS1->US_TCR = sizeof(us_outbuf); + pUS1->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN; + } + // Check if the second PDC bank is free + else if (pUS1->US_TNCR == 0) { + memcpy(us_outbuf, data, len); + pUS1->US_TNPR = (uint32_t)us_outbuf; + pUS1->US_TNCR = sizeof(us_outbuf); + pUS1->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTEN; + } + //wait until finishing transfer + while (pUS1->US_TCR && pUS1->US_TNCR) {}; + return 0; +} void usart_init(void) { @@ -141,11 +198,12 @@ void usart_init(void) { pUS1->US_RNPR = (uint32_t)0; pUS1->US_RNCR = 0; - // re-enable receiver / transmitter pUS1->US_CR = (AT91C_US_RXEN | AT91C_US_TXEN); + // ready to receive pUS1->US_RPR = (uint32_t)us_inbuf; - pUS1->US_RCR = sizeof(us_inbuf); + pUS1->US_RCR = 0; + pUS1->US_RNCR = 0; pUS1->US_PTCR = AT91C_PDC_RXTEN; } diff --git a/common/usart.h b/common/usart.h index f98424841..f01968055 100644 --- a/common/usart.h +++ b/common/usart.h @@ -3,6 +3,9 @@ #include #include "proxmark3.h" +#include "../armsrc/ticks.h" // startcountus + +#define AT91_BAUD_RATE 115200 void usart_init(void); void usart_close(void); @@ -11,5 +14,7 @@ int16_t usart_readbuffer(uint8_t *data); int16_t usart_writebuffer(uint8_t *data, size_t len); bool usart_dataavailable(void); int16_t usart_readcommand(uint8_t *data); +void usart_readcheck(uint8_t *data,size_t len); + bool usart_commandavailable(void); #endif