This document shows the implementation of the infrared on the UART0 using the FRDM-KE02Z platform.
The FRDM-KE02Z platform is a developing platform for rapid prototyping. The board has a MKE02Z64VQH2 MCU a Kinetis E series MCU which is the first 5-Volt MCU built on the ARM Cortex-M0+ core. You can check the evaluation board in the Freescale’s webpage (FRDM-KE02Z: Kinetis E Series Freedom Development Platform)
The Freedom Board has a lot of great features and one of this is an IrDA transmitter and receiver on it. Check this out!
One of the features of the MCU is that the UART0 module can implement Infrared functions just following some tricks (MCU-magic tricks). According to the Reference Manual (Document Number: MKE02Z64M20SF0RM) this tricks are:
- UART0_TX output can be modulated by FTM0 channel 0 PWM output
- UART0_RX input can be tagged to FTM0 channel 1 or filtered by ACMP0 module
For this example we are going to use the ACMP0 module to implement the UART0_RX functionality.
Note1: The Core is configured to run at the maximum frequency: 20 Mhz
Note2: Refer to the reference manual document for more information about the registers.
Configuring the FTM0.
The next lines show the configuration of the FTM0; the module is configured with a Frequency of 38 KHz which is the ideal frequency for an infrared led. The FTM0_CH0 is in Edge_Aligned PWM mode (EPWM).
#define IR_FREQUENCY 38000 //hz
#define FTM0_CLOCK BUS_CLK_HZ
#define FTM0_MOD_VALUE FTM0_CLOCK/IR_FREQUENCY
#define FTM0_C0V_VALUE FTM0_MOD_VALUE/2
void FTM0CH0_Init( void )
SIM_SCGC |= SIM_SCGC_FTM0_MASK;
// Init FTM0 to PWM output,frequency is 38khz
FTM0_C0SC = 0x28;
FTM0_C0V = FTM0_C0V_VALUE;
FTM0_SC = 0x08; // bus clock divide by 2
With this we accomplish the UART0_TX modulation through a PWM on the FTM0_CH0.
Configuring the ACMP0.
The configuration of the ACMP0 is using a DAC and allowing the ACMP0 can be driven by an analog input.
void ACMP_Init ( void )
SIM_SCGC |= SIM_SCGC_ACMP0_MASK;
ACMP0_C1 |= ACMP_C1_DACEN_MASK |
ACMP_C1_DACVAL(21); // enable DAC
ACMP0_C0 |= ACMP_C0_ACPSEL(0x03)|
ACMP0_C2 |= ACMP_C2_ACIPE(0x02); // enable ACMP1 connect to PIN
ACMP0_CS |= ACMP_CS_ACE_MASK; // enable ACMP
With this we have now implemented the UART0_RX.
Now the important thing is to initialize the UART0 to work together with these tricks and implement the irDA functions.
Basically we initialize the UART0 like when we use normal serial communication (this is not the topic of this post, refer to the project to see the UART_init function) and we write to the most important registers:
SIM_SOPT |= SIM_SOPT_RXDFE_MASK;
- UART0_RX input signal is filtered by ACMP, then injected to UART0.
SIM_SOPT |= SIM_SOPT_TXDME_MASK;
- UART0_TX output is modulated by FTM0 channel 0 before mapped to pinout.
The configuration is as follows:
void IrDA_Init( void )
// initialize UART0, 2400 baudrate
// clear RDRF flag
UART0_S1 |= UART_S1_RDRF_MASK;
// initialize FTM0CH1 as 38k PWM output
// enable ACMP
SIM_SOPT |= SIM_SOPT_RXDFE_MASK; //UART0_RX input signal is filtered by ACMP, then injected to UART0.
UART0_S2 &= ~UART_S2_RXINV_MASK; //inverse data input
SIM_SOPT |= SIM_SOPT_TXDME_MASK; //UART0_TX output is modulated by FTM0 channel 0 before mapped to pinout.
With the irDA initialization we got the infrared features on the UART0.
Philosophy of the Example
In the attachments of this post you can find the example which shows the use of these functions in a basic application; the project was compiled in CodeWarrior 10.6 and the philosophy is:
I hope that the information presented on this document could be useful for you. Thank you!