Hi TI,
We're experiencing an issue with optimization O2 (and O3) and UART setup. With O0 there is no issue. We're using "9 2019-q4-major".
What seems to be happening is that a part of the setup code for the UART seems to disappear when using optimization. The code section:
static void SetBaudRate(uint32_t Port, uint32_t BaudRate) { uint32_t ulDivUART; uint32_t ulUARTClk; ulUARTClk = system_Clock_PeripheralClockGet(Port); //system_Clock_GetSysFreq(); // Is the required baud rate greater than the maximum rate supported // without the use of high speed mode? if((BaudRate * 16) > ulUARTClk) // CPU support 3Mbps -> always false { // Enable high speed mode. HWREG(Port + UART_O_CTL) |= UART_CTL_HSE; // Half the supplied baud rate to compensate for enabling high speed // mode. This allows the following code to be common to both cases. BaudRate /= 2; } else { // Disable high speed mode. HWREG(Port + UART_O_CTL) &= ~(UART_CTL_HSE); } // Compute the fractional baud rate divider. ulDivUART = (((ulUARTClk * 8) / BaudRate) + 1) / 2; // Set the baud rate. HWREG(Port + UART_O_IBRD) = ulDivUART / 64; HWREG(Port + UART_O_FBRD) = ulDivUART % 64; }
The function "system_Clock_PeripheralClockGet(port)" returns 80000000.
01012250: ldr r0, [pc, #100] ; (0x10122b8 <UART_SetConfig+204>) 01012252: movs r1, #136 ; 0x88 01012254: bl 0x100bb3c <assert_failed> 138 SetBaudRate(Port, BaudRate); 01012258: mov r0, r5 0101225a: bl 0x100bbd0 <system_Clock_PeripheralClockGet> //Register values at this point // sp = 0x2003ff98 // pc = 0x101225e // // r0 = 0x4c4b400 // r1 = 0x1c200 // r2 = 0x4000c000 // r3 = 0x4000d000 // r5 = 0x4000d000 // r6 = 0x60 // r7 = 0x6 // r8 = 0x0 // r10 = 0x1c200 // r12 = 0x20000000 105 if((BaudRate * 16) > ulUARTClk) // CPU support 3Mbps -> always false 0101225e: ldr r3, [r5, #48] ; 0x30 01012260: cmp.w r0, r10, lsl #4 108 HWREG(Port + UART_O_CTL) |= UART_CTL_HSE; 01012264: orr.w r7, r7, r4 01012268: itet cc 0101226a: orrcc.w r3, r3, #32 0101226e: biccs.w r3, r3, #32 01012272: movcc.w r10, r10, lsr #1 121 ulDivUART = (((ulUARTClk * 8) / BaudRate) + 1) / 2; 01012276: lsls r1, r0, #3 01012278: orr.w r8, r7, r8 0101227c: udiv r1, r1, r10 01012280: adds r1, #1 124 HWREG(Port + UART_O_IBRD) = ulDivUART / 64; 01012282: str r3, [r5, #48] ; 0x30 01012284: add.w r12, r5, #48 ; 0x30 01012288: lsrs r3, r1, #7 0101228a: orr.w r6, r8, r6 0101228e: ubfx r1, r1, #1, #6 01012292: str r3, [r5, #36] ; 0x24 125 HWREG(Port + UART_O_FBRD) = ulDivUART % 64; 01012294: str r1, [r5, #40] ; 0x28 140 HWREG_UART(Port, UART_O_LCRH) = WordLength | StopBits | Parity | Mode; // Write to this reg also set the new baudrate 01012296: str r6, [r5, #44] ; 0x2c 141 MODIFY_REG(HWREG_UART(Port, UART_O_CTL), UART_CTL_RTSEN | UART_CTL_CTSEN, HwFlowCtl); 01012298: ldr.w r3, [r12] 0101229c: ldr r2, [sp, #40] ; 0x28 0101229e: bic.w r3, r3, #49152 ; 0xc000 010122a2: orr.w r4, r3, r2 010122a6: str.w r4, [r12]
Above is the assembly output with O2 flag set (i've added the registry values in the function for reference). The compiler seems to have removed the line "HWREG(Port + UART_O_CTL) &= ~(UART_CTL_HSE);" and we can't figure out why. Any assistance in explaining this would be appreciated.
With best regards
Sebastian