I am trying to get the LPUART clocked from the OSC using a FRDMK22FUG board (MK22FN512VLH12 processor). The schematic for this board shows an 8 MHz crystal connected to XTAL0 and EXTAL0. I have the LPUART transmitting from the PLLFLLSEL clock source, but when I switch to the OSCERCLK source, nothing is transmitted.
It's very simple code:
int main(void)
{
#if 0
SIM_SOPT2 = (SIM_SOPT2 & ~SIM_SOPT2_LPUARTSRC_MASK) | SIM_SOPT2_LPUARTSRC(SIM_SOPT2_LPUARTSRC_OSCERCLK);
#else
SIM_SOPT2 = (SIM_SOPT2 & ~SIM_SOPT2_LPUARTSRC_MASK) | SIM_SOPT2_LPUARTSRC(SIM_SOPT2_LPUARTSRC_PLLFLLSEL);
#endif
OSC_CR = OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK |
OSC_CR_SC16P_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC2P_MASK;
OSC_DIV = 0;
/* */
ports_init();
/* Configure UART */
lpuart_init();
while(true)
{
lpuart_transmit("UUUUUUUUUUUUUUUUUUUUUUU");
for(int i = 0; i < 1000000; i++) {}
}
return 0;
}
with
//
// SOPT2 LPUART clock sources
//
#define SIM_SOPT2_LPUARTSRC_CLOCK_DISABLED (0x00)
#define SIM_SOPT2_LPUARTSRC_PLLFLLSEL (0x01)
#define SIM_SOPT2_LPUARTSRC_OSCERCLK (0x02)
#define SIM_SOPT2_LPUARTSRC_MCGIRCLK (0x03)
ports_init() is just:
/*
* Initialize all ports
*/
void ports_init(void)
{
/* Enable port clocking */
SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTD_MASK);
/*
* Port A
*/
PORTA->PCR[PORT_EXTAL0] = PORT_PCR_MUX(GPIO_PCR_MUX_ANALOG);
PORTA->PCR[PORT_XTAL0] = PORT_PCR_MUX(GPIO_PCR_MUX_ANALOG);
/*
* Port D
*/
PORTD->PCR[PORT_LPUART0_RX] = PORT_PCR_MUX(GPIO_PCR_MUX_ALT6);
PORTD->PCR[PORT_LPUART0_TX] = PORT_PCR_MUX(GPIO_PCR_MUX_ALT6);
}
where PORT_EXTAL0 is defined as 18 and PORT_XTAL0 is defined as 19. GPIO_PCR_MUX_ANALOG is 0.
The lpuart commands are defined as:
#define LPUART_OSR (16)
#define LPUART_SBR (49)
/*
*
*/
void lpuart_init(void)
{
SIM_SCGC6 |= SIM_SCGC6_LPUART0_MASK;
LPUART0_BAUD = LPUART_BAUD_OSR(LPUART_OSR) |
LPUART_BAUD_SBR(LPUART_SBR);
LPUART0_CTRL |= LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK;
}
/*
*
*/
void lpuart_transmit(uint8_t* data)
{
while (*data)
{
while (!(LPUART0_STAT & LPUART_STAT_TC_MASK)) {}
LPUART0_DATA = *data;
data++;
}
}
I have tried different capacitance settings in OSC_CR and tried to see if it's oscillating with an oscilloscope, but I don't see anything (it may be that the scope probe stops the oscillation, don't know).
I'm attempting to work toward a low power solution where the LPUART is running all the time, waking the processor when data is received. My first step is what I'm trying here to get the LPUART running from the external clock so that I can put the core in a sleep mode.
I directed OSCERCLK0 (don't know why the zero is on there in the reference manual) to PTC3/ALT5, CLKOUT and I don't see anything. If I direct the flash clock to PTC3, I can see a ~10.5 MHz clock so I know the port is working.
Thanks.
Solved! Go to Solution.
I figured it out. It was the HGO, RANGE and EREFS bits in the MCG_C2 register that were wrong. For the FRDMK22FUG board, HGO is off, RANGE is set to high frequency (0x1) and EREFS bit is set. Now I can see the OSCINIT0 bit set in MCG_S and the UART is working. I'm also seeing an 8 MHz clock on CLKOUT as I would expect.
I figured it out. It was the HGO, RANGE and EREFS bits in the MCG_C2 register that were wrong. For the FRDMK22FUG board, HGO is off, RANGE is set to high frequency (0x1) and EREFS bit is set. Now I can see the OSCINIT0 bit set in MCG_S and the UART is working. I'm also seeing an 8 MHz clock on CLKOUT as I would expect.