Trying to understand the MODIR values/settings for hardware handshaking
I have a simple setup, two SK146 EVBs sitting next to each other.
Connections are crossed, Rx to Tx and CTS to RTS.
Both boards have UART 0 configured in the same way, one od sending a short message out periodically.
For the purpose of this design, interrupts cannot be used and the receiver is polling the status register and so flow control is required.
There are 8 bits of MODIR involved in the configuration of the handshaking but I find the explanation very confusing.
Is there an application note for this?
Or can someone simply share a known working value for basic cross-connected handshaking?
Thanks
For some further info, here is the init code for UART0:
void UART0_Init(void) { // set the pins for Rx and Tx PCC->PCCn[UART0_PIN_CLOCK] |= PCC_PCCn_CGC_MASK; // Enable clock for PORTA UART0_GPIO_BASE->PDDR |= 1 << UART0_TX_PIN; // Set tx pin for output UART0_PIN_PORT_PAD->PCR[UART0_TX_PIN]|=PORT_PCR_MUX(4); // Port A27: MUX = ALT4,UART0 TX UART0_PIN_PORT_PAD->PCR[UART0_RX_PIN]|=PORT_PCR_MUX(4); // Port A28: MUX = ALT4,UART0 RX PCC->PCCn[PCC_LPUART0_INDEX] &= ~PCC_PCCn_CGC_MASK; // Ensure clk disabled for config PCC->PCCn[PCC_LPUART0_INDEX] |= PCC_PCCn_PCS(3); // PCS=3: Select FIRC PCC->PCCn[PCC_LPUART0_INDEX] |= PCC_PCCn_CGC_MASK; // Enable clock for LPUART0 regs // set pins for HW handshake PCC->PCCn[UART0_HS_PIN_CLOCK] |= PCC_PCCn_CGC_MASK; // Enable clock for PORTA UART0_HS_BASE->PDDR |= 1 << UART0_RTS_PIN; // Set RTS pin for output UART0_HS_PORT_PAD->PCR[UART0_CTS_PIN]|=PORT_PCR_MUX(2); // Port A0: MUX = ALT6,UART0 CTS UART0_HS_PORT_PAD->PCR[UART0_RTS_PIN]|=PORT_PCR_MUX(2); // Port A1: MUX = ALT6,UART0 RTS // Enable the RTS and CTS function LPUART0->MODIR |= LPUART_MODIR_TXCTSE(1); // Bit 1 Tx RTS enable LPUART0->MODIR |= LPUART_MODIR_TXRTSE(1); // Bit 2 Txt RTS polarity (active high / low) LPUART0->MODIR |= LPUART_MODIR_TXRTSPOL(0); // Bit 3 Rx RTS enable LPUART0->MODIR |= LPUART_MODIR_RXRTSE(0); // Bit 4 Tx CTS config LPUART0->MODIR |= LPUART_MODIR_TXCTSC(0); // Bit 5 Transmit CTS source LPUART0->MODIR |= LPUART_MODIR_TXCTSSRC(0); // Bits 8 & 9 // Receive RTS Configuration LPUART0->MODIR |= LPUART_MODIR_RTSWATER(0); // 1000000 baud = 0x0F000003 // 921600 baud = 0x0C000004 (good for Terra Term LPUART0->BAUD = 0x0F000003; // Initialize for 1000000 baud, 1 stop: // SBR=3 (0x3): baud divisor (48MHz/(BAUD_RATE/OSR)) // OSR=15: Over sampling ratio = 15+1=16 // SBNS=0: One stop bit // BOTHEDGE=0: receiver samples only on rising edge // M10=0: Rx and Tx use 7 to 9 bit data characters // RESYNCDIS=0: Resync during rec'd data word supported // LBKDIE, RXEDGIE=0: interrupts disable // TDMAE, RDMAE, TDMAE=0: DMA requests disabled // MAEN1, MAEN2, MATCFG=0: Match disabled LPUART0->CTRL=0x000C0000; // Enable transmitter & receiver, no parity, 8 bit char: // RE=1: Receiver enabled // TE=1: Transmitter enabled // PE,PT=0: No hw parity generation or checking // M7,M,R8T9,R9T8=0: 8-bit data characters // DOZEEN=0: LPUART enabled in Doze mode // ORIE,NEIE,FEIE,PEIE,TIE,TCIE,RIE,ILIE,MA1IE,MA2IE=0: no IRQ // TxDIR=0: TxD pin is input if in single-wire mode // TXINV=0: TRansmit data not inverted // RWU,WAKE=0: normal operation; rcvr not in statndby // IDLCFG=0: one idle character // ILT=0: Idle char bit count starts after start bit // SBK=0: Normal transmitter operation - no break char // LOOPS,Rsrc=0: no loop back }
I know basic Rx and Tx works, I get comms in both directions but, as expected due to polling, I miss the odd character.
For a simple test, I set
LPUART0->MODIR = LPUART_MODIR_TXRTSE(1) As above. Monitor UART0 Tx pin and pull the CTS pin both high and low. In both cases data is transmitted rather than waiting for CTS to be asserted (pulled high I assume);
Hi Brendan Cassidy
According to your description:
LPUART0->MODIR = LPUART_MODIR_TXRTSE(1)
Monitor UART0 Tx pin and pull the CTS pin both high and low.
In both cases data is transmitted rather than waiting for CTS to be asserted
You don't need the TXRTSE bit to enable, you need the TXCTSE bit.
The transmitter checks the state of CTS each time it is ready
to send a character. If CTS is asserted, the character is sent. If CTS is deasserted, the signal TXD
remains in the mark state and transmission is delayed until CTS is asserted.
I checked your configuration and I didn't see any problem with the flow control part, unfortunately, there isn't any example code that implements this.
It is not needed this part of the code:
UART0_HS_BASE->PDDR |= 1 << UART0_RTS_PIN; // Set RTS pin for output
And I also notice that you have the mux(2) and you need the mux(6)
UART0_HS_PORT_PAD->PCR[UART0_CTS_PIN]|=PORT_PCR_MUX(2); // Port A0: MUX = ALT6,UART0 CTS UART0_HS_PORT_PAD->PCR[UART0_RTS_PIN]|=PORT_PCR_MUX(2); // Port A1: MUX = ALT6,UART0 RTS
Hope this could help you
Have a great day,
TIC
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
-------------------------------------------------------------------------------
Hello Jorge
Thanks for the response.
After a few more hours of staring at the code, I did finally realise where the errors were.
The main one was I was using IART 0 but for some reason picked the CTS and RTS pins for UART 1
So we would never work.
Once I hade the correct pins sorted it was a matter of resolving what the did, I found these two:
// bit 0 Tx CTS enable, Enables clear-to-send operation. // The transmitter checks the state of CTS each time it is ready to send a character. // If CTS is asserted, the character is sent. // If CTS is deasserted, the signal TXD remains in the mark state and transmission is delayed until CTS is asserted. // Changes in CTS as a character is being sent do not affect its transmission. LPUART0->MODIR |= LPUART_MODIR_TXCTSE(1); // Confirmed for CTS input. // Pull CTS input low to enable tx, if not, board goes into error state as Tx locks up // Bit 3 Rx RTS enable // RTS is deasserted if the receiver data register is full or // a start bit has been detected that would cause the receiver data register to become full. // RTS is asserted if the receiver data register is not full and // has not detected a start bit that would cause the receiver data register to become full LPUART0->MODIR |= LPUART_MODIR_RXRTSE(1); // Confirmed // is asserted low when data can be sent
provided the required function.
It was not immediately clear as the descriptions sounded so similar but the fundamental facts are:
CTS is an input that hols up transmission
RTS is an output that "says, I'm ready for data"
Thanks for the input and maybe, just maybe, this will help another confuse soul.