I have a device which transmits USART with inverted polarity, and I would like to read data from it with the help of an Arduino. I use an Arduino Due, which has a SAM3X processor, so it should be able to invert the polarity without any external hardware.
The settings accessible from the Arduino SDK are minimalistic, Serial.begin()
only allows to set the baudrate and start/parity/stop, nothing else.
In the SAM3X datasheet I found the "USART Mode Register", US_MR
, which dedicates bit 23 (INVDATA
) to invert the polarity.
Although it seems not to be documented anywhere, I found in a forum that to access the US_MR
register, I have to use UART->UART_MR
. I can read that register but cannot change it. The SAM3X datasheet mentions that this register might be write protected, and that the write protection can be cleared in the US_WPMR
register.
However, the Arduino SDK doesn't seem to know about this register. I tried several possibilities,
US_WPMR
UART_WPMR
WPMR
UART->US_WPMR
UART->UART_WPMR
UART->WPMR
None of which are known.
The string WPMR
is nowhere to be found in any of the files in my Arduino installation folder.
EDIT:
Interestingly, the source code for the UART class doesn't contain any reference to the WPMR. It just sets the required configuration registers without bothering with it.
void UARTClass::begin( const uint32_t dwBaudRate )
{
// Configure PMC
pmc_enable_periph_clk( _dwId ) ;
// Disable PDC channel
_pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS ;
// Reset and disable receiver and transmitter
_pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS ;
// Configure mode
_pUart->UART_MR = UART_MR_PAR_NO | UART_MR_CHMODE_NORMAL ;
// Configure baudrate (asynchronous, no oversampling)
_pUart->UART_BRGR = (SystemCoreClock / dwBaudRate) >> 4 ;
// Configure interrupts
_pUart->UART_IDR = 0xFFFFFFFF;
_pUart->UART_IER = UART_IER_RXRDY | UART_IER_OVRE | UART_IER_FRAME;
// Enable UART interrupt in NVIC
NVIC_EnableIRQ(_dwIrq);
// Enable receiver and transmitter
_pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN ;
}
However, when I try to change UART_MR
, it remains the same.
USART0->US_WPMR
? Couldn't you add it? The register mapping offset is 0xE4 according to the datasheet.