1

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.

USART Mode Register

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.

1
  • Did you try USART0->US_WPMR? Couldn't you add it? The register mapping offset is 0xE4 according to the datasheet.
    – Gerben
    Commented Mar 25, 2016 at 14:55

1 Answer 1

1

Under Windows, Arduino puts the source code for hardware specific stuff in User\AppData\Local\Arduino, and not in the installation folder.

/* -------- US_WPMR : (USART Offset: 0xE4) Write Protect Mode Register -------- */
#define US_WPMR_WPEN (0x1u << 0) /**< \brief (US_WPMR) Write Protect Enable */
#define US_WPMR_WPKEY_Pos 8
#define US_WPMR_WPKEY_Msk (0xffffffu << US_WPMR_WPKEY_Pos) /**< \brief (US_WPMR) Write Protect KEY */
#define US_WPMR_WPKEY(value) ((US_WPMR_WPKEY_Msk & ((value) << US_WPMR_WPKEY_Pos)))

I would guess unlocking / locking would take the format:

????->US_WPMR = (US_WPMR_WPEN | US_WPMR_WPKEY(0x555341));
????->US_WPMR = (~US_WPMR_WPEN & US_WPMR_WPKEY(0x555341));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.