AnsweredAssumed Answered

UART IRQ fails to update TPM0_C1V

Question asked by John Connor on Feb 3, 2018
Latest reply on Feb 9, 2018 by Robin_Shen

Hello, I have 2 FRDM KL25Z boards which I am using as a Tx board (with Potentiometer and ADC + UART0 TX), and an Rx board (with a hobby servo connected to UART0 RX). 

 

Basically, one board performs ADC on the Pot, and sends it over via UART0 to the other board, the other board modulates duty cycle based on input from UART0.  Both are driven by simple ISRs.

 

I'm getting good UART0_D values from the Tx board (tested by using output to toggle the tricolor LED pins as GPIO), but when trying with PWM, TPM0_C1V will not update as I expect it to with the UART ISR.

 

Can anyone tell me why TPM0_C1V does not get updated as I move the pot in the following Rx'er code, or provide some tips for further debugging?

 

#include <MKL25Z4.h>

void UART0_init(void);
void PWM_init(void);

int main(void) {
    
    SystemCoreClockUpdate();
    
    __disable_irq();
    
    UART0_init();            // set up UART
    PWM_init();                // set up TPM0
    
    __enable_irq();        // call global IRQ handler
    
    while(1) {
        
        // UART0 Rx & TPM0_C1V updates done by ISR
    }
    
}


void UART0_IRQHandler(void) {
    
    int c = UART0_D;                // UART_D generates 8 bit values 0-255,
    TPM0_C1V = 400 + (c);        // C1V range of 400 - 655 for roughly ~1ms - 2ms pulse width
    
}

void UART0_init(void) {
    
    SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL(1);               // choose PLL output for UART baud rate calc
    SIM_SOPT2 &= ~SIM_SOPT2_UART0SRC_MASK;                                           
  SIM_SOPT2 |= SIM_SOPT2_UART0SRC(1);                 // PLL source            
    SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;             // enable clock to UART0

    UART0_C2 = 0;                                                 // turn off UART0 while changing configuration
                                                                            
    UART0_BDH = 0;                                             // zero out BDH
    UART0_C4 = 16;                                               // 16 samples

    UART0_BDL = 26;                                             // 48mhz with 16samples divide by 26 gives ~115200 baud
    UART0_C1 = 0;                                                 // has effect of choosing 8 bit data stream
    
    UART0_C2 = UART0_C2_RIE_MASK | UART0_C2_RE_MASK;        // enable Rx and RIE UART0
    NVIC->ISER[0] |= 0x00001000;                 // enable int 12 (bit 12 of ISER[0] -- UART0 IRQ on NVIC
    
    SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;     // Clock to PortA
    PORTA_PCR1 = PORT_PCR_MUX(2);              // Set ALT2 for PortA PCR1 (UART0_RX)
    
}

void PWM_init(void) {
        
    SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK;                 // Clock TPM0
    SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK;              // Clock to Port C(TPM output on PTC2)

    SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1);                    // 1 is PLL Clock @48MHz
    
    PORTC_PCR2 = PORT_PCR_MUX(4);                // set to PWM TPM0_CH1 ALT function for IO pin PTC2
    
    TPM0_SC = TPM_SC_CMOD(1) | TPM_SC_PS(7);      // 48MHz clock at 128 prescaler for 375kHz
     // status control register for TPM0: set clock mode to increment counter on every LPTPM tick
    
    TPM0_CNT = 0;                                     // write to CNT as per datasheet
    TPM0_MOD = 7500;                             // 7500 (48MHz / 128(prescaler) / 7500cycles) = 50hz, 20 ms period
    TPM0_C1SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK;
    
}


 

Thank you!

JC

Outcomes