Fix: USART - better RX/TX with one dma bank and wait loops (@ryan)

This commit is contained in:
iceman1001 2019-04-14 11:08:44 +02:00
commit fc0a62de18
2 changed files with 69 additions and 6 deletions

View file

@ -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<len){
if (check == 0){
StartCountUS();
check = 1;
}
//300ms
if (GetCountUS() > 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;
}

View file

@ -3,6 +3,9 @@
#include <stddef.h>
#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