Hi all.
I'm testing the uartEcho example from the StarterWare 02.00.00.05 on the AM3358 evaluation kit.
It works.
When I change the uart FIFO TRANSMITTER trigger level (txTrigLvl) with a value like 3, the uart Tx Fifo doesn't wait 3 characters to send data but sends each byte immediatly.
I tried to call UARTFIFOEnable(baseAdd) without success.
Any suggestions ?
Hello Mickael,
The UART Interrupt application in its current state uses a Transmitter trigger level of 1.
If the Transmitter Trigger Level has to be changed, then an appropriate value (from 1 to 63) has to be programmed in the parameterized macro ‘UART_FIFO_CONFIG’ which in turn is passed as an argument to the API UARTFIFOConfig().
In the present case that you are discussing about, the Transmitter Trigger Level is 3. Therefore, you have to send 3 bytes in the ISR for every Transmitter Interrupt.
I have myself tested this locally and a code snippet of the appropriate changes is given below.
#define UART_TX_TRIGGER_LVL (3)
main()
{
……………………….
………………………
………………………..
UartFIFOConfigure()
……………………………..
……………………………….
}
static void UartFIFOConfigure(void)
unsigned int fifoConfig = 0;
/* Setting the TX and RX FIFO Trigger levels as 1. No DMA enabled. */
fifoConfig = UART_FIFO_CONFIG(UART_TRIG_LVL_GRANULARITY_1,
UART_TRIG_LVL_GRANULARITY_1,
UART_TX_TRIGGER_LVL,
1,
UART_DMA_EN_PATH_SCR,
UART_DMA_MODE_0_ENABLE);
/* Configuring the FIFO settings. */
UARTFIFOConfig(SOC_UART_0_REGS, fifoConfig);
static void UARTIsr(void)
static unsigned int txStrLength = sizeof(txArray);
static unsigned int count = 0;
unsigned int lIndex = 0;
unsigned char rxByte = 0;
unsigned int intId = 0;
/* Checking ths source of UART interrupt. */
intId = UARTIntIdentityGet(SOC_UART_0_REGS);
switch(intId)
case UART_INTID_TX_THRES_REACH:
if(txStrLength > 0)
for(lIndex = 0; lIndex < UART_TX_TRIGGER_LVL; lIndex++)
UARTCharPut(SOC_UART_0_REGS, txArray[count]);
txStrLength--;
count++;
if(0 == txStrLength)
break;
else
/* Disabling the THR interrupt. */
UARTIntDisable(SOC_UART_0_REGS, UART_INT_THR);
…………………………………………..
………………………………………………
Thanks for your answer.I did this modification, like in your example.I can see this behavior : After each call of "UARTCharPut()" in the IRQ function, a character is send on the line.Is it the correct behavior ?Normaly, with a FIFO, we have to write into the FIFO buffer (in the main function for example). When the Tx FIFO treshold is reached, an interrupt is set and we send the FIFO buffer.How can I have this behavior ?
Firstly, I would like to briefly explain the structure of the UART Interrupt application (uartEcho), though the flow is quite obvious.
The idea that I am trying to stress here is that if interrupts are enabled, the data is written/read from the FIFO in the ISR. This is usually followed as a standard practice.
Transmit Trigger Level
Secondly, I would like to briefly explain the meaning of Transmit Trigger Level.
The Transmit Interrupt is raised when the number of bytes in the Transmit FIFO is less than the Transmit Trigger Level. Once sufficient numbers of bytes are written to the Transmit FIFO so that the number of bytes crosses the Transmit Trigger Level, the Transmit interrupt is de-asserted. It is again asserted if the number of bytes falls short of the Transmit Trigger Level. The following figure explains it well.
UARTCharGet() transmits single bytes
True. The above function transmits single bytes. This is used in the ISR because the Transmit trigger level used is 1. If multiple bytes are required to be transmitted, then use the utility function UARTPuts().
This function can be found in ‘utils/uartStdio.c’.
I have rewritten the ISR using UARTPuts() which I think would help you.
/* Transmitter FIFO length is 64 bytes. */
if(txStrLength < 64)
UARTPuts(txArray + count, txStrLength);
txStrLength = 0;
else if(txStrLength >= 64)
UARTPuts(txArray + count, 64);
count += 64;
txStrLength -= 64;
………………………………
By writing 64 bytes to the TX FIFO at one shot, we are actually buying good amount of time for the processor to do other tasks before we get another Transmit Interrupt. The next transmit interrupt is generated when the UART transmits bytes and the byte count drops below the trigger level.
Thus, irrespective of the Transmit Trigger Level, the TX FIFO could be filled to the brim if there are sufficient numbers of bytes to be transmitted.
Please revert back if you have any queries.
Thanks and Regards.
Gurudutt.
Thank you, your answer was helpful.
Now I'm trying to use UART1 by using the J10 RS232 connector on the Daugther board of the EVM3358 evaluation kit.
I changed, in the uartEcho project, the "UART0ModuleClkConfig" by the "UART1ModuleClkConfig" (see below) , the "UARTPinMuxSetup(0)" function code (see below) and all Uart base addresse ("SOC_UART_0_REGS" by "SOC_UART_1_REGS").
Result : The programme goes in the "UARTIsr" interrupt function, send all characters but nothing appends in my PC terminal (same BaudRate, Stopbit, parity...)
I tryed each profiles (with the profile selection switch on the DaugtherBoard of the EVM3358 evaluation kit).
Have you any programs which use UART1 ?
Code modifications :
void UART1ModuleClkConfig(void){ HWREG(SOC_PRCM_REGS + CM_PER_L3S_CLKSTCTRL) |= CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP; while((HWREG(SOC_PRCM_REGS + CM_PER_L3S_CLKSTCTRL) & CM_PER_L3S_CLKSTCTRL_CLKTRCTRL) != CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP); HWREG(SOC_PRCM_REGS + CM_PER_L3_CLKSTCTRL) |= CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP; while((HWREG(SOC_PRCM_REGS + CM_PER_L3_CLKSTCTRL) & CM_PER_L3_CLKSTCTRL_CLKTRCTRL) != CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP); HWREG(SOC_PRCM_REGS + CM_PER_L3_INSTR_CLKCTRL) |= CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE; while((HWREG(SOC_PRCM_REGS + CM_PER_L3_INSTR_CLKCTRL) & CM_PER_L3_INSTR_CLKCTRL_MODULEMODE) != CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE); HWREG(SOC_PRCM_REGS + CM_PER_L3_CLKCTRL) |= CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE; while((HWREG(SOC_PRCM_REGS + CM_PER_L3_CLKCTRL) & CM_PER_L3_CLKCTRL_MODULEMODE) != CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE); HWREG(SOC_PRCM_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) |= CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP; while((HWREG(SOC_PRCM_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) & CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL) != CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP); HWREG(SOC_PRCM_REGS + CM_PER_L4LS_CLKSTCTRL) |= CM_PER_L4LS_CLKSTCTRL_CLKTRCTRL_SW_WKUP; while((HWREG(SOC_PRCM_REGS + CM_PER_L4LS_CLKSTCTRL) & CM_PER_L4LS_CLKSTCTRL_CLKTRCTRL) != CM_PER_L4LS_CLKSTCTRL_CLKTRCTRL_SW_WKUP); HWREG(SOC_PRCM_REGS + CM_PER_L4LS_CLKCTRL) |= CM_PER_L4LS_CLKCTRL_MODULEMODE_ENABLE; while((HWREG(SOC_PRCM_REGS + CM_PER_L4LS_CLKCTRL) & CM_PER_L4LS_CLKCTRL_MODULEMODE) != CM_PER_L4LS_CLKCTRL_MODULEMODE_ENABLE); HWREG(SOC_PRCM_REGS + CM_PER_UART1_CLKCTRL) |= CM_PER_UART1_CLKCTRL_MODULEMODE_ENABLE; while((HWREG(SOC_PRCM_REGS + CM_PER_UART1_CLKCTRL) & CM_PER_UART1_CLKCTRL_MODULEMODE) != CM_PER_UART1_CLKCTRL_MODULEMODE_ENABLE); while(!(HWREG(SOC_PRCM_REGS + CM_PER_L3S_CLKSTCTRL) & CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK)); while(!(HWREG(SOC_PRCM_REGS + CM_PER_L3_CLKSTCTRL) & CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK)); while(!(HWREG(SOC_PRCM_REGS + CM_PER_OCPWP_L3_CLKSTCTRL) & (CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK | CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L4_GCLK))); while(!(HWREG(SOC_PRCM_REGS + CM_PER_L4LS_CLKSTCTRL) & (CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_L4LS_GCLK | CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_I2C_FCLK)));}
New "UARTPinMuxSetup" code :
/* RXD */ HWREG(SOC_CONTROL_REGS + 0x0980) = (CONTROL_CONF_UART0_RXD_CONF_UART0_RXD_PUTYPESEL | CONTROL_CONF_UART0_RXD_CONF_UART0_RXD_RXACTIVE);
/* TXD */ HWREG(SOC_CONTROL_REGS + 0x0984) = CONTROL_CONF_UART0_TXD_CONF_UART0_TXD_PUTYPESEL;
Thanks for your help.
Correction for the"UARTPinMuxSetup" code modification part. I using CONTROL defined for UART1.
/* RXD */ HWREG(SOC_CONTROL_REGS + 0x0980) = (CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_PUTYPESEL | CONTROL_CONF_UART1_RXD_CONF_UART1_RXD_RXACTIVE);
/* TXD */ HWREG(SOC_CONTROL_REGS + 0x0984) = CONTROL_CONF_UART1_TXD_CONF_UART1_TXD_PUTYPESEL;
Hi,
while(!(HWREG(SOC_PRCM_REGS + CM_PER_L4LS_CLKSTCTRL) & (CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_L4LS_GCLK | CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_I2C_FCLK)));
Now :
while(!(HWREG(SOC_PRCM_REGS + CM_PER_L4LS_CLKSTCTRL) & (CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_L4LS_GCLK | CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_UART_GFCLK)));
I think than the UART1 clock function seems ok (it's close of the UART2 clock function).
Could you help me ? Don't hesitate if you need more informations ?
Firstly, I am sorry that I did not reply to your queries within time. I was involved in other tasks and could not devote time to this query thread.
I understand that you want to use UART1 in your application. Though you have configured the functional clocks and performed the necessary Pin Multiplexing for UART1, you are not able to see any characters on the serial console of the host PC.
As an alternative, you tried to use UART2 instance making pre-requisite configurations based on the ones you did for UART1.
Now that you have moved the status of the above query to Verified state, have your issues been resolved? Do you have any related issues for which you need help from our side?
If you were able to resolve the issue that you faced, I request you to share the fix in this thread. This will help other engineers facing the same or similar issues in travelling to their solution.
Please revert back for any queries.
I am sorry but, I selected "Verify answer" by mistake.
I still have an issue with the UART1 (no data received on the PC hyperterminal) and with the UART2 (No data send when we use the DMA).
the UARTPuts you are using in the isr, it was used at non-FIFO mode, you can track UARTPuts , it uses the UARTCharPut( uart_irda_cir.c), and this function, haven't using the advantage of fifo, it waiting for the empty of THR register and shift register.
so ,in your code ,it was wrong.