mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 18:48:13 -07:00
CHG: the thread comms refactoring from offical pm3 repo
chg: FPC com speed limited to 115200 when compiled with FPC chg: USART remake (@drandreas)
This commit is contained in:
parent
eb0b5116a2
commit
24eaac8681
45 changed files with 915 additions and 949 deletions
37
common/cmd.c
37
common/cmd.c
|
@ -31,29 +31,9 @@
|
|||
*/
|
||||
#include "cmd.h"
|
||||
|
||||
bool cmd_receive(UsbCommand* cmd) {
|
||||
|
||||
// Check if there is a usb packet available
|
||||
if (!usb_poll_validate_length()) return false;
|
||||
|
||||
// Try to retrieve the available command frame
|
||||
usb_read((uint8_t*)cmd, sizeof(UsbCommand));
|
||||
|
||||
// (iceman) this check is wrong. Since USB can send packages which is not sizeof(usbcommand) 544 bytes.
|
||||
// hence, I comment it out
|
||||
|
||||
// Check if the transfer was complete
|
||||
//if (rxlen != sizeof(UsbCommand)) return false;
|
||||
// Received command successfully
|
||||
//return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len) {
|
||||
|
||||
uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len) {
|
||||
UsbCommand txcmd;
|
||||
|
||||
// 0x00 the whole command.
|
||||
for (size_t i=0; i < sizeof(UsbCommand); i++)
|
||||
((uint8_t*)&txcmd)[i] = 0x00;
|
||||
|
||||
|
@ -70,10 +50,15 @@ bool cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* d
|
|||
txcmd.d.asBytes[i] = ((uint8_t*)data)[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Send frame and make sure all bytes are transmitted
|
||||
if ( usb_write( (uint8_t*)&txcmd, sizeof(UsbCommand)) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
uint32_t sendlen = 0;
|
||||
// Send frame and make sure all bytes are transmitted
|
||||
sendlen = usb_write( (uint8_t*)&txcmd, sizeof(UsbCommand) );
|
||||
|
||||
#ifdef WITH_FPC
|
||||
usart_init();
|
||||
usart_writebuffer( (uint8_t*)&txcmd, sizeof(UsbCommand) );
|
||||
#endif
|
||||
|
||||
return sendlen;
|
||||
}
|
|
@ -39,8 +39,7 @@
|
|||
#include "usart.h"
|
||||
#include "proxmark3.h"
|
||||
|
||||
bool cmd_receive(UsbCommand* cmd);
|
||||
bool cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len);
|
||||
uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len);
|
||||
|
||||
#endif // _PROXMARK_CMD_H_
|
||||
|
||||
|
|
316
common/usart.c
316
common/usart.c
|
@ -1,17 +1,23 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Iceman, July 2018
|
||||
// edists by - Anticat, August 2018
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// The main USART code, for serial communications over FPC connector
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "usart.h"
|
||||
#include "apps.h"
|
||||
#include "string.h"
|
||||
|
||||
#define USART_INTERRUPT_LEVEL 7
|
||||
#define AT91_BAUD_RATE 115200
|
||||
|
||||
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1;
|
||||
volatile AT91PS_USART pUS1 = AT91C_BASE_US1;
|
||||
volatile AT91PS_AIC pAIC = AT91C_BASE_AIC;
|
||||
volatile AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
|
||||
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1;
|
||||
|
||||
#define usart_rx_ready {(pUS1->US_CSR & AT91C_US_RXRDY)}
|
||||
#define usart_tx_ready {(pUS1->US_CSR & AT91C_US_TXRDY)}
|
||||
|
||||
/*
|
||||
void usart_close(void) {
|
||||
// Reset the USART mode
|
||||
pUS1->US_MR = 0;
|
||||
|
@ -25,259 +31,155 @@ void usart_close(void) {
|
|||
// Disable all interrupts
|
||||
pUS1->US_IDR = 0xFFFFFFFF;
|
||||
|
||||
//* Abort the Peripheral Data Transfers
|
||||
//AT91F_PDC_Close((AT91PS_PDC) &(pUSART->US_RPR));
|
||||
// Abort the Peripheral Data Transfers
|
||||
pUS1->US_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
|
||||
|
||||
// Disable receiver and transmitter and stop any activity immediately
|
||||
pUS1->US_CR = AT91C_US_TXDIS | AT91C_US_RXDIS | AT91C_US_RSTTX | AT91C_US_RSTRX;
|
||||
}
|
||||
*/
|
||||
|
||||
/// Reads data from an USART peripheral, filling the provided buffer until it
|
||||
/// becomes full. This function returns immediately with 1 if the buffer has
|
||||
/// been queued for transmission; otherwise 0.
|
||||
static uint8_t outbuf[sizeof(UsbCommand)];
|
||||
//static uint8_t inbuf[sizeof(UsbCommand)];
|
||||
|
||||
|
||||
/// Reads data from an USART peripheral
|
||||
/// \param data Pointer to the buffer where the received data will be stored.
|
||||
/// \param len Size of the data buffer (in bytes).
|
||||
uint8_t usart_readbuffer(uint8_t *data, size_t len) {
|
||||
inline int usart_readbuffer(uint8_t *data, size_t len) {
|
||||
|
||||
pUS1->US_PTSR = AT91C_PDC_TXTEN;
|
||||
pUS1->US_PTCR = AT91C_PDC_TXTEN;
|
||||
|
||||
// Check if the first PDC bank is free
|
||||
if ((pUS1->US_RCR == 0) && (pUS1->US_RNCR == 0)) {
|
||||
|
||||
if (!(pUS1->US_RCR)) {
|
||||
pUS1->US_RPR = (uint32_t)data;
|
||||
pUS1->US_RCR = len;
|
||||
pUS1->US_PTCR = AT91C_PDC_RXTEN;
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
// Check if the second PDC bank is free
|
||||
else if (pUS1->US_RNCR == 0) {
|
||||
|
||||
else if (!(pUS1->US_RNCR)) {
|
||||
pUS1->US_RNPR = (uint32_t)data;
|
||||
pUS1->US_RNCR = len;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
pPDC->PDC_PTSR = AT91C_PDC_RXTEN;
|
||||
pPDC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||
|
||||
//check if data is available
|
||||
if (pPDC->PDC_RCR != 0) return -1;
|
||||
|
||||
memcpy(data, inbuf, len);
|
||||
|
||||
//start next transfer
|
||||
pPDC->PDC_RNPR = (uint32_t)inbuf;
|
||||
pPDC->PDC_RNCR = sizeof(inbuf);
|
||||
|
||||
return sizeof(inbuf);
|
||||
*/
|
||||
}
|
||||
/*
|
||||
int16_t usart_writebuffer(uint8_t *data, size_t len) {
|
||||
|
||||
/// Reads and return a packet of data on the specified USART peripheral. This
|
||||
/// function operates asynchronously, so it waits until some data has been
|
||||
/// received.
|
||||
/// \param timeout Time out value (0 -> no timeout).
|
||||
uint8_t usart_read(uint32_t timeout) {
|
||||
if (timeout == 0) {
|
||||
while ((pUS1->US_CSR & AT91C_US_RXRDY) == 0) {};
|
||||
}
|
||||
else {
|
||||
// pUS1->US_PTSR = AT91C_PDC_TXTEN;
|
||||
pUS1->US_PTCR = AT91C_PDC_TXTEN;
|
||||
|
||||
// if buffer is sent
|
||||
if (pUS1->US_TCR != 0) return -1;
|
||||
|
||||
memcpy(outbuf, data, len);
|
||||
|
||||
while ((pUS1->US_CSR & AT91C_US_RXRDY) == 0) {
|
||||
//start next transfer
|
||||
pUS1->US_TNPR = (uint32_t)outbuf;
|
||||
pUS1->US_TNCR = sizeof(outbuf);
|
||||
|
||||
if (timeout == 0) {
|
||||
|
||||
DbpString("USART_Read: Timed out.");
|
||||
return 0;
|
||||
}
|
||||
timeout--;
|
||||
}
|
||||
}
|
||||
uint8_t res = pUS1->US_RHR;
|
||||
Dbprintf(" usar got %02x", res);
|
||||
return res;
|
||||
return sizeof(outbuf);
|
||||
}
|
||||
*/
|
||||
|
||||
/// Sends one packet of data through the specified USART peripheral. This
|
||||
/// function operates synchronously, so it only returns when the data has been
|
||||
/// actually sent.
|
||||
/// \param data Data to send including 9nth bit and sync field if necessary (in
|
||||
/// the same format as the US_THR register in the datasheet).
|
||||
/// \param timeOut Time out value (0 = no timeout).
|
||||
void usart_write( uint8_t data, uint32_t timeout) {
|
||||
if ( timeout == 0) {
|
||||
|
||||
while ((pUS1->US_CSR & AT91C_US_TXEMPTY) == 0) {};
|
||||
|
||||
} else {
|
||||
while ((pUS1->US_CSR & AT91C_US_TXEMPTY) == 0) {
|
||||
|
||||
if (timeout == 0) {
|
||||
DbpString("USART_Write: Timed out.");
|
||||
return;
|
||||
}
|
||||
timeout--;
|
||||
}
|
||||
}
|
||||
pUS1->US_THR = data;
|
||||
}
|
||||
|
||||
uint8_t usart_writebuffer(uint8_t *data, size_t len, uint32_t timeout) {
|
||||
// works.
|
||||
// transfer to client
|
||||
inline int16_t usart_writebuffer(uint8_t *data, size_t len) {
|
||||
|
||||
pUS1->US_PTSR = AT91C_PDC_TXTEN;
|
||||
pUS1->US_PTCR = AT91C_PDC_TXTEN;
|
||||
|
||||
// Check if the first PDC bank is free
|
||||
if ((pUS1->US_TCR == 0) && (pUS1->US_TNCR == 0)) {
|
||||
|
||||
pUS1->US_TPR = (uint32_t)data;
|
||||
pUS1->US_TCR = len;
|
||||
pUS1->US_PTCR = AT91C_PDC_TXTEN;
|
||||
return 1;
|
||||
if (!(pUS1->US_TCR)) {
|
||||
|
||||
memcpy(outbuf, data, len);
|
||||
|
||||
pUS1->US_TPR = (uint32_t)outbuf;
|
||||
pUS1->US_TCR = sizeof(outbuf);
|
||||
return 2;
|
||||
}
|
||||
// Check if the second PDC bank is free
|
||||
else if (pUS1->US_TNCR == 0) {
|
||||
|
||||
pUS1->US_TNPR = (uint32_t)data;
|
||||
pUS1->US_TNCR = len;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
else if (!(pUS1->US_TNCR)) {
|
||||
memcpy(outbuf, data, len);
|
||||
|
||||
pUS1->US_TNPR = (uint32_t)outbuf;
|
||||
pUS1->US_TNCR = sizeof(outbuf);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// interupt version
|
||||
void Usart_c_irq_handler(void) {
|
||||
|
||||
// get Usart status register
|
||||
uint32_t status = pUS1->US_CSR;
|
||||
|
||||
if ( status & AT91C_US_RXRDY){
|
||||
// Get byte and send
|
||||
pUS1->US_THR = (pUS1->US_RHR & 0x1FF);
|
||||
LED_B_INV();
|
||||
}
|
||||
// tx
|
||||
if ( status & AT91C_US_TXRDY){
|
||||
LED_D_INV();
|
||||
}
|
||||
|
||||
|
||||
if ( status & AT91C_US_OVRE) {
|
||||
// clear US_RXRDY
|
||||
(void)(pUS1->US_RHR & 0x1FF);
|
||||
pUS1->US_THR = ('O' & 0x1FF);
|
||||
}
|
||||
|
||||
// Check error
|
||||
if ( status & AT91C_US_PARE) {
|
||||
pUS1->US_THR = ('P' & 0x1FF);
|
||||
}
|
||||
|
||||
if ( status & AT91C_US_FRAME) {
|
||||
pUS1->US_THR = ('F' & 0x1FF);
|
||||
}
|
||||
|
||||
if ( status & AT91C_US_TIMEOUT){
|
||||
pUS1->US_CR = AT91C_US_STTTO;
|
||||
pUS1->US_THR = ('T' & 0x1FF);
|
||||
}
|
||||
|
||||
// Reset the status bit
|
||||
pUS1->US_CR = AT91C_US_RSTSTA;
|
||||
}
|
||||
|
||||
__inline unsigned int AT91F_AIC_ConfigureIt (
|
||||
AT91PS_AIC pAIC, // \arg pointer to the AIC registers
|
||||
unsigned int irq_id, // \arg interrupt number to initialize
|
||||
unsigned int priority, // \arg priority to give to the interrupt
|
||||
unsigned int src_type, // \arg activation and sense of activation
|
||||
void (*newHandler) (void) ) // \arg address of the interrupt handler
|
||||
{
|
||||
unsigned int oldHandler;
|
||||
unsigned int mask;
|
||||
|
||||
oldHandler = pAIC->AIC_SVR[irq_id];
|
||||
|
||||
mask = (0x1 << irq_id);
|
||||
// Disable the interrupt on the interrupt controller
|
||||
pAIC->AIC_IDCR = mask;
|
||||
// Save the interrupt handler routine pointer and the interrupt priority
|
||||
pAIC->AIC_SVR[irq_id] = (unsigned int) newHandler;
|
||||
// Store the Source Mode Register
|
||||
pAIC->AIC_SMR[irq_id] = (src_type | priority);
|
||||
// Clear the interrupt on the interrupt controller
|
||||
pAIC->AIC_ICCR = mask;
|
||||
|
||||
return oldHandler;
|
||||
}
|
||||
|
||||
void usart_init(void) {
|
||||
|
||||
// disable & reset receiver / transmitter for configuration
|
||||
pUS1->US_CR = (AT91C_US_RSTRX | AT91C_US_RSTTX);
|
||||
|
||||
// disable & reset receiver / transmitter
|
||||
pUS1->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS;
|
||||
|
||||
//enable the USART 1 Peripheral clock
|
||||
//enable the USART1 Peripheral clock
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1);
|
||||
|
||||
// Configure PIO controllers to peripheral mode A
|
||||
pPIOA->PIO_ASR = (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||
|
||||
// Disable PIO control of the following pins, allows use by the SPI peripheral
|
||||
pPIOA->PIO_PDR = (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||
|
||||
// kill pull-ups
|
||||
// pPIOA->PIO_PPUDR = ~(AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||
// pPIOA->PIO_MDDR = (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||
// disable PIO control of receive / transmit pins
|
||||
pPIOA->PIO_PDR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||
|
||||
// Pull-up Enable
|
||||
// enable peripheral mode A on receive / transmit pins
|
||||
pPIOA->PIO_ASR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||
|
||||
// enable pull-up on receive / transmit pins (see 31.5.1 I/O Lines)
|
||||
pPIOA->PIO_PPUER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||
// MultiDriver Enable
|
||||
//pPIOA->PIO_MDER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||
|
||||
// Enable the pins to be controlled
|
||||
pPIOA->PIO_PER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||
|
||||
// Configure the pins to be outputs
|
||||
pPIOA->PIO_OER |= AT91C_PA22_TXD1;
|
||||
|
||||
//enable PIO in input mode
|
||||
//pPIOA->PIO_ODR = AT91C_PA21_RXD1;
|
||||
|
||||
// set mode
|
||||
pUS1->US_MR = AT91C_US_USMODE_NORMAL | // normal mode
|
||||
AT91C_US_CLKS_CLOCK | // MCK
|
||||
AT91C_US_CLKS_CLOCK | // MCK (48MHz)
|
||||
AT91C_US_CHRL_8_BITS | // 8 bits
|
||||
AT91C_US_PAR_NONE | // parity: none
|
||||
AT91C_US_NBSTOP_1_BIT | // 1 stop bit
|
||||
AT91C_US_CHMODE_NORMAL; // channel mode: normal
|
||||
|
||||
// baud rate
|
||||
// CD = MCK / (16 * baud)
|
||||
// MCK = 24027428 (pm3 runs on 24MHZ clock PMC_PCKR[0] )
|
||||
|
||||
|
||||
// baudrate 115200
|
||||
// 16*115200 = 1843200
|
||||
// 24027428 / 1843200 == 13 --< CD
|
||||
|
||||
// baudrate 460800
|
||||
// 16*460800 = 7372800
|
||||
// 24027428 / 7372800 == 3
|
||||
pUS1->US_BRGR = 24*1024*1024/(115200*16); // OVER=0 16
|
||||
// set baudrate to 115200
|
||||
pUS1->US_BRGR = (48UL*1000*1000) / (115200*16);
|
||||
|
||||
// Write the Timeguard Register
|
||||
pUS1->US_TTGR = 0;
|
||||
|
||||
pUS1->US_RTOR = 0;
|
||||
pUS1->US_FIDI = 0;
|
||||
pUS1->US_IF = 0;
|
||||
|
||||
// Enable USART IT error and RXRDY
|
||||
// Write to the IER register
|
||||
// pUS1->US_IER = (AT91C_US_TIMEOUT | AT91C_US_FRAME | AT91C_US_OVRE | AT91C_US_RXRDY);
|
||||
|
||||
// open Usart 1 interrupt
|
||||
/*
|
||||
AT91F_AIC_ConfigureIt(
|
||||
pAIC,
|
||||
AT91C_ID_US1,
|
||||
USART_INTERRUPT_LEVEL,
|
||||
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,
|
||||
Usart_c_irq_handler
|
||||
);
|
||||
*/
|
||||
|
||||
// enable interupt
|
||||
// pAIC->AIC_IECR = (1 << AT91C_ID_US1);
|
||||
|
||||
// trigger interrup software
|
||||
// pAIC->AIC_ISCR = (1 << AT91C_ID_US1) ;
|
||||
|
||||
// enable RX + TX
|
||||
pUS1->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
|
||||
/*
|
||||
//Empty PDC
|
||||
pUS1->US_RNPR = (uint32_t)(char *)0;
|
||||
pUS1->US_RNCR = 0;
|
||||
pUS1->US_RPR = (uint32_t)(char *)0;
|
||||
pUS1->US_RCR = 0;
|
||||
|
||||
pUS1->US_TNPR = (uint32_t)(char *)0;
|
||||
pUS1->US_TNCR = 0;
|
||||
pUS1->US_TPR = (uint32_t)(char *)0;
|
||||
pUS1->US_TCR = 0;
|
||||
*/
|
||||
|
||||
//pUS1->US_PTCR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN);
|
||||
//pUS1->US_PTSR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN);
|
||||
|
||||
// re-enable receiver / transmitter
|
||||
pUS1->US_CR = (AT91C_US_RXEN | AT91C_US_TXEN);
|
||||
|
||||
}
|
|
@ -4,18 +4,9 @@
|
|||
#include <stddef.h>
|
||||
#include "proxmark3.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||
extern void Dbprintf(const char *fmt, ...);
|
||||
|
||||
void usart_init(void);
|
||||
void usart_close(void);
|
||||
|
||||
uint32_t usart_rx_ready();
|
||||
uint32_t usart_tx_ready();
|
||||
|
||||
uint8_t usart_read(uint32_t timeout);
|
||||
uint8_t usart_readbuffer(uint8_t *data, size_t len);
|
||||
|
||||
void usart_write( uint8_t data, uint32_t timeout);
|
||||
uint8_t usart_writebuffer(uint8_t *data, size_t len, uint32_t timeout);
|
||||
int usart_readbuffer(uint8_t *data, size_t len);
|
||||
int16_t usart_writebuffer(uint8_t *data, size_t len);
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue