Kinetis Microcontrollers Knowledge Base

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Kinetis Microcontrollers Knowledge Base

Discussions

Sort by:
The SPI bus has the capability of addressing multiple slave devices by a single master. The Kinetis L series of devices feature either an 8-bit or 16-bit capable SPI module; however, there is only one dedicated CS/SS signal per instance of the module. Of course this signal is muxed to a few pin locations on the device. Unfortunately, there are not that many pins with the CS/SS muxing and they are most likely they are not near to each other physically. A solution to this issue is to use GPIO as CS/SS lines. This way you can take advantage of the SPI bus protocol and the Kinetis L series IOPORT interface (also known as FGPIO on Kinetis L). The Cortex-M0+ allows accesses to the IOPORT to occur in parallel with any instruction fetches; therefore, these accesses will complete in a single cycle. Core vs. SPI I'm sure many who have tried to use GPIO as CS/SS have written code similar to this pseudo code, I know I have: while(1) {      set_cs_low;      send_byte;      set_cs_high; } Logically this makes sense, but on an oscilloscope you will see the GPIO CS/SS line toggling at irregular intervals and out of sync with the SPI transfers. This is due to the nature of the 'send_byte' function or instruction. Simply transmitting a data packet will not prevent the core from waiting for the transmission to complete. The core will move on from writing data to the SPI data register, and execute the next instruction. If you have a core operating at 48 MHz and you are performing, at most depending on instance, 24 MHz SPI transfers the core will always move onto the next instruction before the data has left the module. The code must either implement a delay or wait for the transmission to complete. Incorporating an accurate delay can be tricky and can be interrupted by any interrupts occurring during the delay process. A more robust solution is to wait for the transmission to complete. However, there appears to be no Transmit Complete Flag (TCF) in the L-Series SPI module. The Solution Fortunately, there is a way to wait for transmit complete. Software must wait for the SPI read buffer full flag (SPRF) to be set in the SPI status register (SPIx_S) after writing data to the SPI data register (SPIx_D) . When the SPRF bit is set, software must read the SPIx_D. This procedure will ensure that the core does not move onto GPIO toggling, or other instructions, until the data has left the SPI module. The following function demonstrates how to write the above procedure in C using SPI0 and PTD0 as the CS/SS line: uint8_t SPI_send(uint8_t spiWrite) {     uint8_t spiRead;                        //Variable for storing SPI data     FGPIOD_PCOR |= (1 << 0);                //Toggle CS/SS line low     while(!(SPI0_S & SPI_S_SPTEF_MASK))     {         __asm("NOP");     }                                       //Wait for SPI transmit empty flag to set     SPI0_D = spiWrite;                            //Write data to SPI     while(!(SPI0_S & SPI_S_SPRF_MASK))     {         __asm("NOP");     }                                       //Wait for receive flag to set     spiRead = SPI0_D;                       //Read the SPI data register     FGPIOD_PSOR |= (1 << 0);                //Toggle CS/SS line high     return spiRead; } Please note that the GPIO CS/SS toggling need not be in the function. It should work just as well if the GPIO CS/SS toggles occur before and after the function is call, just remove the FGPIO instructions from the function and place them outside. I hope this document proves useful to those of you designing multiple slave SPI buses around Kinetis L series parts.
View full article
The Freescale Freedom development platform is a low-cost evaluation and development platform featuring Freescale's newest ARM® Cortex™-M0+ based Kinetis KL25Z MCUs NEW! Quick Start Guide Features: KL25Z128VLK4--Cortex-M0+ MCU with:   - 128KB flash, 16KB SRAM - Up to 48MHz operation  - USB full-speed controller OpenSDA--sophisticated USB debug interface Tri-color LED Capacitive touch "slider" Freescale MMA8451Q accelerometer Flexible power supply options   - Power from either on-board USB connector - Coin cell battery holder (optional population option)  - 5V-9V Vin from optional IO header - 5V provided to optional IO header - 3.3V to or from optional IO header Reset button Expansion IO form factor accepts peripherals designed for Arduino™-compatible hardware
View full article
The FRDM-KL25Z is an ultra-low-cost development platform enabled by Kinetis L Series KL1 and KL2 MCUs families built on ARM® Cortex™-M0+ processor. Features include easy access to MCU I/O, battery-ready, low-power operation, a standard-based form factor with expansion board options and a built-in debug interface for flash programming and run-control. The FRDM-KL25Z is supported by a range of Freescale and third-party development software. Features MKL25Z128VLK4 MCU – 48 MHz, 128 KB flash, 16 KB SRAM, USB OTG (FS), 80LQFP Capacitive touch “slider,” MMA8451Q accelerometer, tri-color LED Easy access to MCU I/O Sophisticated OpenSDA debug interface Mass storage device flash programming interface (default) – no tool installation required to evaluate demo apps P&E Multilink interface provides run-control debugging and compatibility with IDE tools Open-source data logging application provides an example for customer, partner and enthusiast development on the OpenSDA circuit Take a look at these application notes: USB DFU boot loader for MCUs Developer’s Serial Bootloader. Low Cost Universal Motor Drive Using Kinetis L family . Writing your First MQXLite Application Learn more...
View full article
The following document contains a list of documents , questions and discussions that are relevant in the community based on the amount of views they are receiving each month. If you are having a problem, doubt or getting started in Kinetis processors or MCUXpresso, you should check the following links to see if your doubt have been already solved in the following documents and discussions. MCUXpresso MCUXpresso Supported Devices Table FAQ: MCUXpresso Software and Tools  Getting Started with MCUXpresso and FRDM-K64F  Generating a downloadable MCUXpresso SDK v.2 package  Quick Start Guide – Using MCUXpresso SDK with PINs&amp;CLOCKs Config Tools  Moving to MCUXpresso IDE from Kinetis Design Studio Kinetis Microcontrollers Guides and examples Using RTC module on FRDM-KL25Z  Baremetal code examples using FRDM-K64F Using IAR EWARM to program flash configuration field Understanding FlexIO  Kinetis K80 FAQ How To: Secure e-mail client (SMTP + SSL) with KSDK1.3 + WolfSSL for FRDM-K64F  Kinetis Bootloader to Update Multiple Devices in a Network - for Cortex-M0+  PIT- ADC- DMA Example for FRDM-KL25z, FRDM-K64F, TWR-K60D100 and TWR-K70  USB tethering host (RNDIS protocol) implementation for Kinetis - How to use your cellphone to provide internet connectivity for your Freedom Board using KSDK Write / read the internal flash Tracking down Hard Faults  How to create chain of pbuf's to be sent? Send data using UDP.  Kinetis Boot Loader for SREC UART, SD Card and USB-MSD loading  USB VID/PID numbers for small manufacturers and such like  Open SDA and FreeMaster OpenSDAv2  Freedom OpenSDA Firmware Issues Reported on Windows 10 Let´s start with FreeMASTER!  The Kinetis Design Studio IDE (KDS IDE) is no longer being actively developed and is not recommended for new designs. The MCUXpresso IDE has now replaced the Kinetis Design Studio IDE as the recommended software development toolchain for NXP’s Kinetis, LPC and i.MX RT Cortex-M based devices. However, this documents continue to receive considerable amount of views in 2019 which means it could be useful to some people. Kinetis Design Studio New Kinetis Design Studio v3.2.0 available Using Kinetis Design Studio v3.x with Kinetis SDK v2.0  GDB Debugging with Kinetis Design Studio  KDS Debug Configurations (OpenOCD, P&amp;E, Segger) How to use printf() to print string to Console and UART in KDS2.0  Kinetis Design Studio - enabling C++ in KSDK projects  Using MK20DX256xxx7 with KDS and KSDK  Kinetis SDK Kinetis SDK FAQ  Introducing Kinetis SDK v2  How to: install KSDK 2.0  Writing my first KSDK1.2 Application in KDS3.0 - Hello World and Toggle LED with GPIO Interrupt 
View full article
For Remote Control means, that is needed two computers - Server Computer and User Computer, which will be in connection. There are two types of connection, which can be used - HTTP or DCOM. There are two different ways how to set up the remote control in Windows. I made the tutorial, which describes both types of Remote Control. Ok - so, let´s start! HTTP Settings On the Server Computer side: 1. Plug the board to the Server Computer 2. Go to Remote Communication Server 3. Set HTTP connection and choose the right COM Port according the plugged board If the plugged board is on e.g. COM23, it is possible to edit number of Port in Device Manager On the User PC side: 1. Open FreeMASTER,  go to Project -> Options 2. Choose Plug-in Module: FreeMASTER CommPlugin for Remote Server (HTTP) and type the IP address of the server, do not forget join to IP address :8080 3. And start communication by STOP button to successful connection DCOM Settings On the Server Computer side: 1. Plug board to the Server Computer 2. Launch DCOM in FreeMASTER Remote Server Choose COM according plugged board or edit COM according to step 2 - Server Computer in HTTP Connection (up). 3. Setting permissions for the user, User PC. Right click on Computer -> Manage. In Computer Management click to Distributed COM Users. In Distributed COM Users Properties add the user, User Computer. After that, set the permissions in Component Services. In cmd type dcomcnfg.exe In Component Services go to Computers -> My Computer -> DCOM Config -> MCB FreeMASTER Remote Server Application Right click on MCB FreeMASTER Remote Server Application and go to Properties. In Security Tab is possible to add the permissions. There are 3 types of permissions. First permission - Launch and Activation Permissions. There are 4 permission options. Local Launch and Remote Launch means, that user, User Computer can launch e.g. FM Remote Server Application. But for success communication is needed allowing Local Activation and Remote Activation. Second permission - Access Permissions. Click to Edit and Allow Local Access and Remote Access for the user. Do not forget that if there is a change of permissions, specifically allowing, it is necessary for User to log out and log in. On the User Computer side: 1. Open Freemaster, go to Project -> Options 2. Choose Plug-in Module: FreeMASTER CommPlugin for Remote Server (DCOM) and for filling Connect string is possible to use Configure. Definitely, type the IP address of the server and ;Port Name. 3. And start communication by STOP button in FreeMASTER to successful connection And now.. you can do anything 🙂
View full article
La serie Kinetis L es una combinación de eficiencia energética, escalabilidad, valor y facilidad de uso que revolucionará el mercado de microcontroladores de nivel básico. Ofrece a los usuarios de arquitecturas heredadas de 8 y 16 bits una ruta de migración hacia la gama de microcontroladores Kinetis de 32 bits y les permite aumentar el rendimiento y ampliar la funcionalidad de sus productos finales sin incrementar el consumo de energía ni los costes del sistema. La serie Kinetis L se compone de cinco familias de microcontroladores: KL0, KL1, KL2, KL3 y KL4. Cada familia combina excelentes corrientes dinámicas y de parada con una capacidad extraordinaria de procesamiento, una amplia selección de memorias flash y una gran variedad de opciones analógicas, de conectividad y de periféricos HMI. La familia KL0 es compatible en pines con la familia S08Px de 8 bits (lo que tiende un puente entre el desarrollo de 8 bits y la cartera Kinetis) y compatible en software con otras familias de la serie Kinetis L. Las familias KL1, KL2, KL3 y KL4 presentan una compatibilidad mutua en hardware y software, además de ser compatibles con sus equivalentes de la serie Kinetis K basada en el Cortex-M4 (KL1 -> K10, KL2 -> K20…). De este modo, los desarrolladores disponen de una ruta de migración ascendente/descendente hacia mayor/menor rendimiento, memoria y funcionalidad integrada, lo que les permite reutilizar el hardware y el software en todas las plataformas de productos finales y reducir el tiempo necesario para la comercialización. Las primeras familias disponibles en el mercado serán KL0, KL1 y KL2 a finales de septiembre de 2012. La disponibilidad de las familias KL3 y KL4 está prevista para el primer trimestre de 2013. Procesador ARM Cortex-M0+ El procesador ARM Cortex-M0+ ofrece niveles más altos de eficiencia energética y de rendimiento y es más fácil de usar que su antecesor, el Cortex-M0. En cuanto a las instrucciones, mantiene plena compatibilidad con todos los demás procesadores de la clase Cortex-M (Cortex-M0/3/4), por lo que los desarrolladores pueden reutilizar sus compiladores y herramientas de depuración existentes. Principales características: 1,77 coremarks/MHz: entre 2 y 40 veces más que los microcontroladores de 8/16 bits, un 9 % más que el Cortex-M0. Coremarks/mA: entre 2 y 50 veces más que los microcontroladores de 8/16 bits, un 25 % más que el Cortex M0. Pipeline de 2 etapas: reducidos ciclos por instrucción (CPI), lo que permite instrucciones de bifurcación y entradas ISR más rápidas. MTB (Micro Trace Buffer): solución ligera y no intrusiva; la información del rastreo se guarda en una pequeña área de la SRAM del microcontrolador (tamaño definido por el programador), lectura a través de SWD/JTAG. Amplio soporte para el entorno ARM. Acceso E/S monociclo: frecuencia de conmutación de la interfaz GPIO un 50 % más alta que la de la E/S estándar, lo que mejora el tiempo de respuesta a eventos externos y permite manipular bits (bit-banding) y emular protocolos de software. Espacio de direcciones lineal de 4 GB: elimina esquemas de paginación complejos y simplifica la arquitectura de software. Solamente 56 instrucciones: mayoritariamente codificadas en 16 bits; opción para MUL rápida de 32 x 32 bits en un ciclo. Conjunto de instrucciones: totalmente compatible con el procesador Cortex-M0, subconjunto de instrucciones del procesador Cortex-M3/4. La mejor densidad de códigos de su categoría en comparación con arquitecturas de 8/16 bits; menor tamaño de memoria flash y reducción del consumo de energía; mayor rendimiento que sus equivalentes de 8 y 16 bits. Acceso a la memoria del programa; reducción del consumo de energía. Familias de microcontroladores de la serie Kinetis L Los microcontroladores de la serie Kinetis L se basan en la funcionalidad del procesador ARM Cortex-M0+, que presenta un diseño de plataforma de bajo consumo energético así como modos operativos y dispositivos periféricos que ahorran energía. El resultado es un microcontrolador que ofrece la mejor eficiencia energética de la industria, consume menos de 50 μA/MHz en el modo VLPR (Very Low Power Run) y puede despertarse rápidamente desde el estado de reposo, procesar datos y restablecer el modo de reposo, lo cual alarga la vida útil de la batería en las aplicaciones. Para ver una demostración de la eficiencia energética de la serie Kinetis L, visite www.freescale.com/ftf. Familias de microcontroladores: Familia KL0: la puerta de entrada a la serie Kinetis L; microcontroladores de 8-32 kB y de 24-48 pines, compatibles en pines con la familia S08P de 8 bits y en software con todas las demás familias de la serie Kinetis L. Familia KL1: microcontroladores de 32-256 kB y de 32-80 pines con comunicaciones adicionales y periféricos analógicos, compatibles en hardware y software con todas las familias de la serie Kinetis L y con la familia K10 (CM4) de la serie K. Familia KL2: microcontroladores de 32-256 kB y de 32-121 pines con USB 2.0 de máxima velocidad tipo host/device/OTG, compatibles en hardware y software con todas las familias de la serie Kinetis L y con la familia K20 (CM4) de la serie K. Características comunes a todas las familias de microcontroladores de la serie Kinetis L: Procesamiento extremadamente eficiente Procesador ARM Cortex-M0+ de 48 MHz Tecnología flash de bajo consumo de energía: 90 nm Funciones de manipulación de bits < 50 μA/MHz; 35,4 coremarks/mA Barra cruzada de puente periférico Controlador de memoria flash con estado de espera cero Modos de consumo de energía ultrabajo Tecnología flash con baja fuga: 90 nm Múltiples modos RUN, WAIT y STOP Activación en 4,6 μs desde el modo de reposo profundo Bloqueo de reloj y de potencia (clock & power gating), opciones de arranque con bajo consumo de energía Reloj VLPR: precisión con un 3 % máximo de margen de error, que normalmente es del 0,3-0,7 % Consumo de corriente en modo de reposo profundo: 1,4 μA con retención de registros; LVD activo y activación en 4,3μs Periféricos que ahorran energía Los periféricos funcionan en modos de reposo profundo y son capaces de tomar decisiones inteligentes y de procesar datos sin despertar al núcleo: ADMA, UART, temporizadores, convertidor analógico-digital (ADC), pantalla LCD con segmentos, sensores táctiles... ADC de 12/16 bits Convertidor digital-analógico (DAC) de 12 bits Comparadores analógicos de alta velocidad Temporizadores de alta capacidad para una gran variedad de aplicaciones, incluyendo el control de motor Para tener más información del fabricante y de los servicios, por favor visiten nuestra microsite. Via Arrow Europe
View full article
Hello All, Power consumption of devices and implications around designing on embedded systems is a common topic nowadays. Kinetis MCUs offer different power modes to fit user's needs. Among these low power modes, we can find the lowest consumption modes: Low-Leakage Stop (LLS) and Very Low-Leakage Stop modes (VLLS). Attached document provides a brief introduction/explanation on these modes and lists the steps needed to configure MCU to operate in any of these modes. It is a bare-board project for FRDM-KL26Z but same principle applies to other Kinetis families. Also, two projects for KDS v3.2 are attached for reference. I hope you can find them useful! Regards, Isaac
View full article
Introduction This document is being written to communicate the need for serialization of memory operations and events in an end application.  In addition, directions will be provided to properly serialize memory operations in the end application.  Memory operations and event serialization applies to all Kinetis devices but is only necessary in specific scenarios. These scenarios include memory writes and reads, clearing status flags, and changing mode control operations. Serialization of memory operations Serialization of memory operations or events is the action of guaranteeing that said memory operations or events are executed in a specific order.  This action is required when making a change to a peripheral module when that change must complete before continuing with program execution.  Users often make the mistake of assuming that since a peripheral register has been written to, the change is in effect immediately.  However, this is not always the case.  The Kinetis series devices implement a crossbar and peripheral bridge interface system that allows masters (the CPU, DMA, etc.) to interface with the peripherals.  The crossbar allows multiple masters to access the individual peripherals on the bus, and the peripheral bridge functions as a bus protocol translator between the crossbar switch and the slave peripheral bus.  Wait states can be inserted at either stage of the communication channel (crossbar or peripheral bridge).  When a master attempts to access a slave and another master is already accessing this slave or the slave is busy, wait states will be inserted.  If the access is a write, then the master's write is simply pushed to the peripheral bus and the master continues.  However, if the access is a read, the master must wait for a response from the slave.  The slave may insert wait states in this communication as it must finish any commands (or writes) it was previously given before responding.    Peripheral module changes that require serialization actions include clearing interrupt service flags, changing power modes (of the module or the SOC as a whole), or software triggering a hardware event.  If the events or memory operations are not serialized in these situations, the CPU could go on to execute code with undesired effects. When do I need to serialize my memory operations and events? Memory operations and events require serialization anytime the program needs to guarantee that a peripheral access happens before code execution continues.  Examples of these situations includes: Exiting an interrupt service routine (ISR) Changing a clock mode or power mode Configuring a function Configuring a hardware change Software triggering a hardware event How do I serialize my memory operations and events? Memory operations are serialized by performing the following operations: Write the desired peripheral register Read the peripheral register that was just written Continue with the subsequent operations By simply reading the register that was just written, the core is forced to wait for a response from the peripheral module that was written before code execution can continue.   In this manner, it is guaranteed that the peripheral module will have completed the desired operations. Example event serialization The following is an example of a function that services the LPTMR ISR flag and implements the event serialization discussed in this document.  void lptmr_isr(void) {   // Declare dummy variable to store the read of the LPTMR0_CSR register volatile int dummy_var; /****   STEP #1  ****/   // Clear the flag; enable interrupts; enable the timer   LPTMR0_CSR = ( LPTMR_CSR_TEN_MASK | LPTMR_CSR_TIE_MASK | LPTMR_CSR_TCF_MASK  );   /****  STEP #2  ****/    // Store CSR register in dummy_var to serialize the clearing of the TCF flag   dummy_var = LPTMR0_CSR; } Conclusion In conclusion, there are situations where code execution can continue before a peripheral change has taken effect. These situations include clearing interrupt service flags, changing power modes (of the module or the SOC as a whole), or software triggering a hardware event.  Sometimes these events can cause unexpected results or even cause your application to crash.  These situations call for the serialization of memory operations and events, which is simply the act of guaranteeing that events and code are executed in a specific order.  To serialize memory operations, simply follow these directions: Write the desired peripheral register Read the peripheral register that was just written Continue with the subsequent operations Following these steps, you will be guaranteed that peripheral configurations have taken effect before continuing with the application. 
View full article
ROM Bootloader KL43 chip with Kinetis Bootloader residing in the on on-chip read-only memory (ROM), can interface with USB, I2C, SPI, and LPUART peripherals in slave mode and respond to the commands sent by a master (or host) communicating on one of those ports. When KL43 chip with a blank flash, the Kinetis bootloader will execute automatically. Once the flash is programmed, the value of the FOPT field at Flash address0x40D will determine if the device boots the ROM bootloader or the user application in flash. The FTFA_FOPT [BOOTSRC_SEL] will select if boot from customer application (Flash) or boot from ROM bootloader. For example:       When Flash address 0x40D value is 0xFF, boot source is ROM bootloader;       When Flash address 0x40D value is 0x3D, boot source is Flash (Customer application). There with hardware pin(/BOOTCFG0) to control if boot from user application or ROM bootloader with FTFA_FOPT[BOOTPIN_OPT] bit . When FTFA_FOPT[BOOTPIN_OPT]  = 0, it forces boot from ROM if /BOOTCFG0 pin set to 0. blhost utility application The blhost utility is an example host program used to interface with devices running the Kinetis bootloader. The blhost application is released as part of Kinetis bootloader release package available on www.freescale.com/KBOOT . The blhost application default located at C:\Freescale\FSL_Kinetis_Bootloader_1_1_0\bin\win folder. About how to use blhost application, please check KBLHOSTUG document for more detailed info. Call Rom Bootloader from customer application In general, if customer application was programmed, the boot option should be change to Boot from Flash. If customer want to call the ROM bootloader during the application running, customer can refer below example. Set a signal for application code to call the ROM bootloader, such as press a button. In this demo, we use FRDM-KL43Z board SW3 (PTC3) to call the ROM bootloader. //Initalize PTEC3 as GPIO button PORT_Init (PORTC, PORT_MODULE_BUTTON_MODE, PIN_3, 0, NULL); GPIO_Init (GPIOC, GPIO_PIN_INPUT, PIN_3); The bootloader entry point for customer application to call the ROM bootloader.  //prototype of the entry point definition void run_bootloader(void * arg); //Variables uint32_t runBootloaderAddress; void (*runBootloader)(void * arg);   // Read the function address from the ROM API tree. runBootloaderAddress = **(uint32_t **)(0x1c00001c); runBootloader = (void (*)(void * arg))runBootloaderAddress; in <main.c> routine to call the ROM bootloader:   while (1)   {     if ((GPIOC_PDIR & (1 << 3)) == 0)     {       // Start the bootloader. runBootloader(NULL);     }   } Press SW3 button of FRDM-KL43Z board will call ROM bootloader.  Customer could continue to debug the code until the ROM bootloader be called. If customer debug into the runBootloader(NULL) function, there will stop at fixed address: 0x1C00_00C0. In fact, during call the ROM bootloader function , there will setting some parameters and then reset the KL43. When KL43 back from reset, it will boot from ROM bootloader. That reset will cause debugger disconnect with the KL43 product. More detailed info, please check attached demo code. BTW: The demo project is [frdm_led_test] inside of KL43 baremetal sample code, which could be downloaded from here.
View full article
1 Abstract      LIN (Local Interconnect Network) is a concept for low cost automotive networks, which complements the existing portfolio of automotive multiplex networks. LIN is based on the UART/SCT protocol. It can be used in the area of automotive, home appliance, office equipment, etc. The UART module in NXP kinetis L series contains the LIN slave function, it can be used as the LIN slave device in the LIN bus. Because there is few LIN slave KL sample code for the customer’s reference in our website, now this document mainly take KL43 as an example, explain how to use the FRDM-KL43 board as the LIN slave node to communicate with the LIN master device. LIN master use the specific LIN module: PCAN-USB Pro FD. Master send the publisher ID and subscriber ID, slave give the according LIN data response. This document will share the according code, hardware connection and the test result. 2 LIN bus basic knowledge review         For the convenient to understand the LIN bus, this chapter simply describe the basic knowledge for LIN bus. Mainly about the LIN topology and the LIN frame. 2.1 LIN bus topology structure       LIN bus just use the simple low cost single-wire, it uses single master to communicate with multiple slaves. The bus voltage is 12V, the speed can up to 20 kbit/s. LIN network can connect 16 nodes, but in the practical usage, normally use below 12 nodes. Figure 2-1. LIN bus topology 2.2 LIN bus frame structure          LIN Frame consists of a header (provided by the master task) and a response (provided by a slave task).     Master send publisher frame: Master send header+ data +checksum; slave just receive.     Master send subscriber frame: Master send header; slave receive send data +checksum.     The following figure is the structure of a LIN frame: Figure 2-2. LIN frame structure      LIN frame is constructed of one Break field, sync byte field (0X55), PID, data and checksum. 2.2.1 Break filed and break delimiter Break filed is consist of break and break delimiter. Break should at least 13 nominal bit times of dominant value (low voltage). The break delimiter shall be at least one nominal bit time long (high voltage). Figure 2-3. break field 2.2.2 Sync byte field Sync is a byte field with the data value 0X55. The byte field is the standard UART protocol. Figure 2-4. The sync byte field 2.2.3 Protected identifier field A protected identifier field consists of two sub-fields: the frame identifier and the parity. Bits 0 to 5 are the frame identifier and bits 6 and 7 are the parity.     ID value range: 0x00-0x3f, 64 IDs in total. It determine the frame categories and direction. Figure 2-5. The sync byte field P0 = ID0 xor ID1 xor ID2 xor ID4 P1 = -(ID1 xor ID3 xor ID4 xor ID5) -is NOT。  ID can be split in three categories:   Frame categories Frame ID Signal carrying frame Unconditional frame 0x00-0x3B Event triggered frame Sporadic frame Diagnostic frame Master request frame 0x3c Slave response frame 0x3d Reserved frame   0x3e,0x3f     2.2.4 DATA       A frame carries between one and eight bytes of data. The number of data contained in a frame with a specific frame identifier shall be agreed by the publisher and all subscribers.      For data entities longer than one byte, the entity LSB is contained in the byte sent first and the entity MSB in the byte sent last (little-endian). The data fields are labeled data 1, data 2,... up to maximum data 8. 2.2.5 checksum  The checksum contains the inverted eight bits sum with carry over all data bytes or all data bytes and the protected identifier.        Classic checksum: Checksum calculation over the data bytes. Enhanced checksum: Checksum calculation over the data bytes and the protected identifier byte.  Method: eight bits sum with carry is equivalent to sum all values and subtract 255 every time the sum is greater or equal to 256, at last, the sum data do bitwise invert.  In the receive side, do the same sum, but at last, don’t do invert, then add the received checksum data, if the result is 0XFF, it is correct, otherwise, it is wrong. 3 KL43 LIN slave example    This chapter use KL43 as the LIN slave, and communicate with the specific LIN master device, realize the LIN data sending and receiving. 3.1 Hardware prepare Hardware: FRDM-KL43,TRK-KEA8,PCAN-USB Pro FD       LIN bus voltage is 12V, but the FRDM-KL43 don’t have the LIN transceiver, so we need the external LIN transceiver connect the KL43 uart, to realize the LIN voltage switch. Here we use the TRK-KEA8 on board LIN transceiver MC33662LEF for the KL43. The MC33662LEF circuit is like this:    Figure 3-1. LIN transceiver schematic 3.1.1 FRDM-KL43 and TRK-KEA8 connections      FRDM-KL43 need to connect the UART port to the LIN transceiver. The connection shows in this table: No. FRDM-KL43 TRK-KEA8 note 1 J1-2 J10-5 UART0_RX 2 J1-4 J10-6 UART0_TX 3 J3-14 J14-1 GND 3.1.2 TRK-KEA8 and LIN master connections         LIN bus is using the signal wire.  TRK-KEA8 J14_4 is the LIN wire, it should connect with the LIN wire in PCAN-USB Pro FD. GND also need to connect together.        TRK-KEA8 P1 need a 12V DC supplier. Master also need 12V DC supplier. 3.1.3 Object connection picture   Figure 3-2. Object connections 3.2 Software flow chart and code      Now describe how to realize the LIN master and the LIN slave data transfer. LIN master send a publisher frame, the slave will receive the according data. LIN master send a subscriber frame, the slave will send the data to the master. The code is based on the KSDK2.2_FRDM-KL43 lpuart, add the LIN operation code.  3.2.1 Software flow chart         Figure 3-3. Software flow chart   3.2.2 software code     Code is based on KSDK2.2_FRDM-KL43 lpuart project, add the LIN operation code, the added code is list as follows: void LPUART0_IRQHandler(void) {      if(LPUART0->STAT & LPUART_STAT_LBKDIF_MASK)      {        LPUART0->STAT |= LPUART_STAT_LBKDIF_MASK;// clear the bit        Lin_BKflag = 1;        cnt = 0;        state = RECV_SYN;        DisableLinBreak;          }     if(LPUART0->STAT & LPUART_STAT_RDRF_MASK)      {                  rxbuff[cnt] = (uint8_t)((LPUART0->DATA) & 0xff);                  switch(state)          {             case RECV_SYN:                           if(0x55 == rxbuff[cnt])                           {                               state = RECV_PID;                           }                           else                           {                               state = IDLE;                               DisableLinBreak;                           }                           break;             case RECV_PID:                           if(0xAD == rxbuff[cnt])                           {                               state = RECV_DATA;                           }                           else if(0XEC == rxbuff[cnt])                           {                               state = SEND_DATA;                           }                           else                           {                               state = IDLE;                               DisableLinBreak;                           }                           break;             case RECV_DATA:                           recdatacnt++;                           if(recdatacnt >= 4) // 3 Bytes data + 1 Bytes checksum                           {                               recdatacnt=0;                               state = RECV_SYN;                               EnableLinBreak;                           }                           break;          default:break;                                    }                  cnt++;      }     } void uart_LIN_break(void) {     LPUART0->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);   //Disable UART0 first     LPUART0->STAT |= LPUART_STAT_BRK13_MASK; //13 bit times LPUART0->STAT |= LPUART_STAT_LBKDE_MASK;//LIN break detection enable LPUART0->BAUD |= LPUART_BAUD_LBKDIE_MASK;         LPUART0->CTRL |= (LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);     LPUART0->CTRL |= LPUART_CTRL_RIE_MASK;     EnableIRQ(LPUART0_IRQn);    } int main(void) {     uint8_t ch;     lpuart_config_t config;     BOARD_InitPins();     BOARD_BootClockRUN();     CLOCK_SetLpuart0Clock(0x1U);     LPUART_GetDefaultConfig(&config);     config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;     config.enableTx = true;     config.enableRx = true;     LPUART_Init(DEMO_LPUART, &config, DEMO_LPUART_CLK_FREQ);     uart_LIN_break();     while (1)     {        if(state == SEND_DATA)        {           while((LPUART0->STAT & LPUART_STAT_TDRE_MASK) == 0); // hex mode                   LPUART0->DATA = 0X01;           while((LPUART0->STAT & LPUART_STAT_TDRE_MASK) == 0); // hex mode                   LPUART0->DATA = 0X02;           while((LPUART0->STAT & LPUART_STAT_TDRE_MASK) == 0); // hex mode                   LPUART0->DATA = 0X10;//Checksum   0X10 correct, 0xaa is wrong           recdatacnt=0;           state = RECV_SYN;           EnableLinBreak;        }     } }     4 KL43 LIN slave test result   Master defines two frames: Unconditional ID Protected ID Direction Data checksum 0X2C 0XEC subscriber 0x01,0x02 0x10 0X2D 0XAD Publisher 0x01,0x02,0x03 0x4c    Now, master send 0X2C and 0X2D data, give the test result and the according waveform. 4.1 LIN master configuration Uart baud rate is: 9600bps 4.2  Send ID 0X2C and 0X2D frame       From the PC software of LIN master, we can find 0X2D ID can send the data successfully, and 0X2C ID can receive the correct data (0x01, 0x02) and checksum (0x10) from the KL43 LIN slave side. 4.2.1 0X2D ID frame oscilloscope waveform and debug result      From the debug result, we can find the buff can receive the correct ID, data and checksum from the LIN master.    4.2.2 0X2C ID frame oscilloscope waveform 4.2.3 0X2C ID SLAVE send back the wrong checksum     From the PC software, we can find if the KL43 code modify the checksum to the wrong data 0XAA, then the PC software will display the checksum error. This is the according oscilloscope waveform for the wrong checksum data. From all the above test result. We can find, KL43 as the LIN slave, it can receive the correct data from the LIN master, and when LIN master send the subscriber ID, kl43 also can send back the correct LIN data to the master. More detail, please check the attached code project. BTW, LIN spec can be downloaded from this link: http://www.cs-group.de/wp-content/uploads/2016/11/LIN_Specification_Package_2.2A.pdf   Attached is the code and the pdf version of this document:                  
View full article
Introduction The K32L3A60VPJ1AT MCU is a next generation Kinetis dual core device.  This device brings processing and multi-tasking capabilities that legacy Kinetis devices did not support.  In addition, the K32L3A60VPJ1AT offers improved power consumption and security features.   Some important aspects of these security features lie in a nonvolatile information register (IFR) memory region and how this region is programmed.  The IFR memory region is a memory space with restricted access separate from the main array and is comprised of an erasable IFR region and a non-erasable IFR region.  The non-erasable IFR region contains the program once identifier and the version identifier.  The erasable IFR region holds the flash security, flash options, mass erase enable, and other such features that governs how the device behaves.  In legacy Kinetis devices, certain fields of the main flash array (flash addresses 0x400 - 0x40F) configured the IFR at boot time.  In the K32L3A60VPJ1AT however, the IFR memory region is no longer controlled in this manner.  This presents challenges when trying to configure these settings.  The purpose of this document is to explain how these settings can be changed and provide some options of how to make these changes.   IFR Field Programming Process The first step in configuring the IFR fields is understanding how the these fields are programmed via the hardware. IFR fields are programmed using a special flash command called the Program Index Command. Once programmed, the flash configuration values cannot be reprogrammed without first erasing these fields.  The only way to erase these values is via a mass erase.  This provides security in that the IFR values cannot be changed without erasing the user code as well.  In addition, changes to the user code image cannot affect the bootloader operation, ensuring that a secure boot function can be executed.  The procedure for writing the erasable IFR values is described here:   Write FCCOB0 with the Program Index command (0x43). Write FCCOB1 with the Index to be programmed. The possible Indexes are listed in Erasable IFR Map table (table 16.4.1.2 in the K32L3A6 reference manual). Write FCCOB2 and FCCOB3 with 0x00 as they are not used with this command.  Write FCCOB4 - FCCOBB with the desired value.  (Note that not all of the indexes use all of the FCCOB fields.  Be sure to consult the Erasable IFR Map table for which FCCOB fields are used for the index you are programming). NOTE:  For 2 byte IFR fields that map to 2 bit wide register bit fields (i.e., SEC0, FSLACC, MEEN, and KEYEN fields which map to the FSEC register bit fields), the lower FCCOB register maps to the LSB of the bit field and the upper FCCOB register maps to the MSB of the bit field.  For example, to write 0b'10 to the FSEC field, FCCOB6 should be written to 0xFF and FCCOB7 should be written to 0x00 before executing the Flash command.  Write 0x70 to the Flash status register (FSTAT) to clear any errors that might have been present from the last flash command. (Note that this command MUST be a byte write.) Write 0x80 to the Flash status register (FSTAT) to initiate the programmed flash command. Poll the FSTAT register until the CCIF bit field (bit field 7) is one ('1').  (Note that it may not be possible in your scripting language to do this, or it may just be easier to simply wait for the flash command to finish executing. In these cases, wait significantly longer than the typical Program Index command completion time of 110us.)   After the IFR has been programmed, the IFR should be read back to verify that it completed correctly.  The process for this is as follows:   Write FCCOB0 with the Read Index command (0x41). Write FCCOB1 with the Index to be read.  The possible Indexes are listed in Erasable IFR Map table (table 16.4.1.2 in the K32L3A6 reference manual). Write FCCOB2 - FCCOBB with 0. The results will be stored in FCCOB4 - FCCOBB so, these should be cleared to ensure correct results are received. Write 0x70 to the Flash status register (FSTAT) to clear any errors that might have been present from the last flash command. Note that this command MUST be a byte write. Write 0x80 to the Flash status register (FSTAT) to initiate the programmed flash command. Poll the FSTAT register until the CCIF bit field (bit field 7) is one ('1').  (Note that it may not be possible in your scripting language to do this, or it may just be easier to simply wait for the flash command to finish executing. In these cases, wait significantly longer than the maximum Read Index command completion time of 35us.)   When using the Program Index Command, you must know which index you want to modify to create the correct flash commands.  The index list can be found in the IFR descriptions section of the Flash chapter in the K32L3A60VPJ1AT reference manual.     There are several different options for programming the FOPT fields. These options are: Using the Kinetis Flash Tool  Using blhost Debugger script Subroutine in user software   Option #1: Kinetis Flash Tool Using the Kinetis Flash Tool is likely the most convenient method to change the IFR values.  The Kinetis Flash Tool uses either the UART or USB protocol to interface with the K32L3A6 bootloader and write the IFR fields desired. One of the biggest advantages for the Kinetis Flash Tool is that it provides a graphical interface for users to easily program the IFR fields. The following figure is a picture of the Kinetis Flash Tool and highlights the important input controls and tabs to be used when programming the IFR fields:     This field is the Port set box.  It selects the interface (UART or USB) to be used when communicating to the bootloader.  This box also allows for configuration of the interface.  Consult the K32L3A6 reference manual for default configurations.   This is the Flash Utilities tab.  Select this tab to see the controls shown in this image.  This is the Index input field.  The Index of the IFR to program should be entered here.  This is the Hex digits field.  This value will be programmed at the IFR Index indicated in the Index field. The value here should be in hex format WITHOUT the preceding "0x".  Note that this will write to the FCCOBs in descending order.  For example, to write 0b'10 to the KEYEN field, FFFFFF00 should be written to the Hex digits field. Refer to the programming process outlined in the IFR Field Programming Process in this document for more information.    This is the Byte Count field.  This tells the utility how many bytes to program and must be the byte count of that IFR field.  Consult the Erasable IFR Map table in the reference manual for the value of the specific IFR index to be programmed.   This is the Program button.  After all of the fields have been filled out, click this button to program the desired IFR location.    Option #2: BLHOST The MCUBoot package also includes a command line executable to interface with the bootloader.  This tool, blhost, can be used to program the IFR fields as well.  The "flash-program-once" command should be used to program the desired IFR location.  The syntax of this command is as follows:   flash-program-once <index> <byteCount> <data>   So for example, if you want to program the FOPT IFR field (record index 0x84) with 0xFFFFF3FF, the correct syntax using this command would be   flash-program-once 0x84 4 FFFFF3FF   After programming, the "flash-read-once" command can be used to read back and verify the programmed IFR field(s).  Below is an example using the previous IFR locations   flash-read-once 0x84 4   Below is a full example of erasing the device, programming the FOPT IFR, and reading the FOPT IFR back from the command line using blhost.     When Programming two byte fields, blhost orders the bytes in descending FCCOBx order (just like the Kinetis Flash Tool).  The blhost utility also requires the input to be 4 or 8 byte aligned, but the flash-program-once command only uses the last 2 bytes.  The upper 4 bytes can be padded with 0's or F's. For example, to write the KEYEN field such that the KEYEN bit field is 0b'10, the command would be as follows: flash-program-once 0x83 4 FFFFFF00 Below is a full example of using the blhost command line to erase the device, program the KEYEN IFR, read the KEYEN IFR back, and evaluate the FSEC bit field using the Attach to Running Target function in a debugger.     After executing a pin reset and attaching to the running target:     Option #3: Debugger Script A simple debugger script is another convenient way to write the IFR values.  Debugger scripts are executed in the background of the debug session initiation process (therefore are hidden operations from the user) and typically can be edited easily using any text editor.  However, it can be cumbersome to change the value because this generally must done manually with each programming by the user. With that in mind, it is a good idea to have different connect scripts for different configurations   The first step in using a debugger script is writing a debugger script.  The capabilities and syntax of a debugger script are dependent on your toolchain. For the purposes of this document, we will focus on MCUXpresso IDE.  MCUXpresso IDE uses the PokeXX and PeekXX (where XX is 8, 16, or 32 depending on whether you want to byte access, half-word or word access to the desired register) commands, which are debugger agnostic. So the same commands that work on a device will continue to work whether you are debugging with a JLink or CMSIS-DAP, or whatever other debugger you are using. Below is an example of a MCUXpresso connect script which writes the FOPT register and then reads it back for printing to the debug log.    5140 REM ====================Program FOPT=================================== 5150 Poke32 this 0x40023004 0x43840000 5160 REM Stuff FCCOB registers with desired FOPT value 5170 Poke32 this 0x40023008 v% 5171 s% = Peek32 this 0x40023008 5172 Print "New Val ";~s% 5180 Poke32 this 0x4002300c 0x00000000 5180 Poke8 this 0x40023000 0x70 5190 Poke8 this 0x40023000 0x80 5200 wait 1000 6000 REM ================== Read FOPT ===================================== 6001 REM Now read the FOPT back 6010 Poke32 this 0x40023004 0x41840000 6020 Poke32 this 0x40023008 0x00000000 6030 Poke32 this 0x4002300c 0x00000000 6040 Poke8 this 0x40023000 0x70 6050 Poke8 this 0x40023000 0x80 6060 wait 1000 6070 s% = Peek32 this 0x40023008 6080 Print "New FOPT Val ";~s%   Note in the above script that v% is the desired FOPT value and it has been defined in sections of the script not shown (at line 164).    162 REM This is the value to be written to the FOPT 164 v% = 0xfffff3ff   After the script is written, MCUXpresso must be told to use the connect script.  This is done in the Debug Configurations window.  Assuming a debug configuration has already been created, click on the arrow next to the green bug icon and select Debug Configurations.       In the resulting dialog box, select the debug configuration you want to use, and select the Linkserver Debug tab.  In the Connect Script field, point MCUXpresso to the location of your connect script.       That's all that needs to be done in the IDE. The selected debug configuration should now be using the script which was written.     Some debuggers will allow standalone command line running of a script, such as a JLink debugger.  As the JLink is one of the more popular external debuggers that we encounter, an example of programming using this script has been provided below.     // Now Program the FOPT w4 0x40023004, 0x43840000 // The 43 selects the Program Index command. The 84 selects the FOPT IFR field. // Stuff the FCCOB registers (4-7) with the FOPT value we want to write. // ** (Boot Settings) ** w4 0x40023008, 0xfffff3ff // Write 0xFFFF_1FFF to boot the M4 from internal Flash. Asserting the NMI pin will force booting from the ROM. // Write FCCOB registers 8-B with dummy values. w4 0x4002300c, 0x00000000 // Write the FSTAT register to clear any errors that could have been present. w1 0x40023000, 0x70 // Launch the flash command. w1 0x40023000, 0x80 // Wait for the flash command to finish. Sleep 1 // Now Read the FOPT back w4 0x40023004, 0x41840000 // The 43 selects the Program Index command. The 84 selects the FOPT IFR field. // Stuff the FCCOB registers (4-7) with the FOPT value we want to write. // ** (Boot Settings) ** w4 0x40023008, 0x00000000 // Write 0xFFFF_F1FF to boot the M0+ from internal Flash. Asserting the NMI pin will force booting from the ROM. // Write FCCOB registers 8-B with dummy values. w4 0x4002300c, 0x00000000 // Write the FSTAT register to clear any errors that could have been present. w1 0x40023000, 0x70 // Launch the flash command. w1 0x40023000, 0x80 // Wait for the flash command to finish. Sleep 1 // Read the memory back to verify the FOPT settings that should be present after reset. mem32 40023000,4     Option #4: Subroutine in User Software Occasionally the requirements of your system will prevent implementation of any of the above methods to program the IFR values.  In these cases, you may need to implement your own subroutine to program the IFR.  The procedure to do this is essentially the same as in the debugger script methods, just written in code instead of an external script.  The flash drivers provided in the SDK aid in this process.  One key to remember is that you likely will need to erase the entire flash.  So this subroutine and flash drivers should be placed in RAM memory.  The SDK flash drivers also operate a little differently from the Kinetis flash tool and blhost.  The FCCOB registers will be loaded in ascending order.  For example, to write 0b'10 to the SEC0 bit field in the FSEC register, the command would be: result = FLASH_ProgramOnce(&s_flashDriver, 0x80, ifr2write, 0x2); where ifr2write is an array defined as uint8_t ifr2write[2] = {0x00, 0xFF}; The above will result in 0x00 being loaded to FCCOB6 and 0xFF being loaded to FCCOB7 and SEC0 will then be 0b'10 on the reset after the command is successfully executed.   Conclusion In summary, the IFR registers are nonvolatile information registers that govern certain behaviors of the K32L3A MCU.  The IFR is dividing into an erasable IFR space and non-erasable IFR space, both of which are not a part of the main flash array.  Programming these values requires the use of special flash commands and requires that these values haven't been previously written since the last mass erase.  There are, in general, four different methods of programming the FOPT register settings.  The four methods are:   Kinetis Flash Tool BLhost command line interface Debugger script  User software subroutine   Each method has its advantages, therefore, you should pick the one that meets your needs and is most convenient. However with any of the methods chosen, the IFR values must not have been programmed before writing erasable IFR fields. It is best to perform a mass erase (which can be done using any of the methods presented in this document) before attempting to program any IFR fields.     
View full article
Introduction Even with the prevalence of universal asynchronous receiver/transmitter (UART) peripherals on microcontrollers (MCUs), bit banged UART algorithms are still used.  The reasons for this vary from application to application.  Sometimes it is simply because more UARTs are needed than the selected device provides.  Maybe application or layout restrictions require certain pins to be used for the UART functions but the device does not route UART pins to the required package pins.  Maybe the application requires a non-standard or proprietary UART scheme. Whatever the reason, there are applications where a bit banged UART is used and is typically a pure software implementation (a timer is used and the MCU core controls a GPIO pin directly).  A better alternative may be to use Flextimer (FTM) or Timer/PWM Module (TPM) to take advantage of the features of these peripherals and possibly offload the CPU.  This document will explain and provide a sample application of how to emulate a UART using the FTM or TPM peripheral.  A Kinetis SDK example (for the TWR-K22F120M and FRDM-K22F platforms) and a baremetal legacy code example (for the FRDM-KL26Z) are provided here. UART protocol Before creating an application to emulate a UART, the UART protocol and encoding must be understood. The UART protocol is an asynchronous protocol that typically includes a start bit, payload (of 7-10 data bits), and a stop bit but does allow for many variations on the number of stop bits and what/how to transfer the data.  For this document and application example, the focus will be UART transmission that follows 1 start bit, 8 data bits, 1 stop bit, no parity, and no flow control.  The data will be transmitted least significant bit (LSB) first.  The following image is a block diagram of this transmission. However, this doesn't specify what the transmission looks like electrically. The figure below shows a screenshot of an oscilloscope capture of a UART transmission.  The data transmitted is 0x55 or a "U" in the ASCII representation. Notice that the transmission line is initially a logic high, and then transitions low to signal the start of the transmission.  The transmission line must stay low for one bit width for the receiver to detect it.  Then there are 8 data bits, followed by 1 stop bit.  In the case shown above, the data bits are 0x55 or 0b0101_0101.  Remember that the transmissions are sent LSB first, so the screenshot shows 1-0-1-0-1-0-1-0.  The last transition high marks the beginning of the stop bit and the line remains in that state until the start of the next transmission.  The receiver, being asynchronous, does not require any type of identifying transition to mark the end of the stop bit. FTM/TPM configuration The first question many may ask when beginning a project like this is "How do I configure the FTM/TPM when emulating a UART".  The answer to this depends on the aspect of this problem you are trying to solve.  Transmitting and receiving characters require two different configurations.  Transmission requires a configuration that manipulates the output pin at specific points in time.  Receiving characters requires a configuration that samples the receive pin and measures the time between pin transitions.  The FTM and TPM have the modes listed in the following table: The FTM and TPM have four different modes that manipulate an output:  Output compare (no pulse), Output compare (with pulse), Edge-aligned PWM, and Center-aligned PWM.  Neither PWM mode is ideal for the requirements of the application.  This is because the PWM modes are designed to produce a continuous waveform and are always going to return to the initialized state once during the cycle of the waveform.  However, the UART protocol may have continuous 1's or 0's in the data without pin transitions between them. The output compare mode (high-true or low-true pulse modes) is designed to only manipulate the pin once, and only produces pulses that are one FTM/TPM clock cycle in duration.  So this is obviously not desirable for the application.  The output compare mode (Set/Clear/Toggle on match) is promising.  This mode manipulates the output pin every cycle.  There are three different options:  clear output on match, set output on match, and toggle output on match.  Neither "clear output on match" nor "set output on match" are ideal as either would require configuration changes during the transmission of a character.  The "toggle output on match", however, can be used and is the selected configuration mode for this sample application. To receive characters, there is only one mode that is intuitive:  "the input capture mode".  This mode records the timer count value on an edge transition of the selected input pin.  Similar to the output compare mode chosen for the transmit functionality, the input capture mode has three sub-modes:  capture on rising edge, capture of falling edge, and capture on either edge.  It is clear from the descriptions that capture on either edge should be selected. Transmit encoding The selection of the FTM/TPM mode is moderately intuitive, but using this mode to emulate a UART transmission is not.  There are two issues that make this a little tricky. 1) The output pin is initialized low. However, the UART protocol needs the pin to begin in a logical high state. 2) The pin transitions on every cycle provided the channel value is less than the value of the MOD register. Due to continuous strings of 1's or 0's, it is necessary to have periods where the pin does not transition. Both of these points have workarounds. Output pin initialization For the first issue, the channel interrupt is first enabled and the channel value register is loaded with a value much less than the value in the MOD register.  Then in the channel interrupt service routine, the pin is sampled to ensure that it is in the logic high state and the channel interrupt is disabled (and will not be re-enabled throughout the life of the application).  The code for this interrupt service routine is as follows. Output pin control For the second issue, a method of not transitioning the pin value while allowing the timer to continue counting normally is necessary.  The Output Compare mode uses the channel value register to determine when the pin transition occurs.  If a value greater than MOD is written to the channel value register, the channel value will never match the count register and thus, a pin transition will never occur.  So, when a series of continuous 1's or 0's need to be transmitted, a value greater than the value in the MOD register can be written to the channel value register to keep the output pin in its current state. However, when a value greater than MOD is written to the channel value register, no channel match will occur (which means channel interrupts will not occur).  So the timer overflow interrupt must be used to continue writing values.  This requires the updates to be output pin to be planned ahead of time and makes the transmission algorithm a little tricky.  The following diagram displays when which values should be written to the channel value register at which points in time to generate the appropriate pulses. Writing a function to translate a number into the appropriate series of MOD/2 and MOD+1 values can be a little tricky. To do this, we must first notice that MOD/2 needs to be written when changes on the transmission pin are need and MOD+1 needs to be written when pin transmissions are not desired.   So, what logical function can we use to determine when a change has happened?  XOR is the correct answer.  So what two values need to be XOR'd together?  One value is obviously the value that we want to send.  But what is the second value?  It turns out that the second value is a shifted version of the value that we want to send.  Specifically, the second value is the desired value to send shifted to the left by one.  (You can think of it as sort of a "future" value of the desired value).  The following pictures show how to determine the queue to use for the transmission. Receive decoding The receive functionality has an advantage over the transmit functions in that it is possible to use DMA for the reception of characters.  This is because the receive function takes advantage of the input capture functionality of the FTM / TPM and therefore can use the channel match interrupt.  The example application provided with this document implements a DMA method and a non-DMA method for reception. First, the non-DMA method will be discussed. Before discussing the specifics of gathering the input pulse widths, some details of the receive pin need to be discussed. Detecting the start bit The receive pin needs to be able to determine when the start of the packet transmission begins.  To do this, the receive pin is configured as an FTM / TPM pin. At the same time, the GPIO interrupt functionality is configured on the same pin for a falling edge interrupt.  The GPIO interrupt capabilities are enabled in any digital mode, so the GPIO interrupt will still be able to be routed to the Nested Vector Interrupt Controller (NVIC).  The pin interrupt is used to start the FTM / TPM clock when a new character reception begins. In the GPIO interrupt for this pin, the FTM / TPM counter register is reset and the clock to the FTM / TPM is turned on.  The code for the GPIO interrupt service routine is shown below.  Receiving characters without DMA Now, when receiving characters and not using DMA, the first thing to understand is that the Interrupt Service Routine (ISR) will be used and it will mainly be used to record the captured count values.  The interrupt service routine also tracks the current receive character length and resets the counter register.  This is so that the values in the receive queue reflect the time since the last pin transition.  The interrupt function for the non-DMA application is shown below. Notice that the first two actions in the ISR are resetting the count register, and clearing the channel event interrupt flag.  Then the channel value is stored in the receive pulse width array (this is simply an array that holds the receive pulse widths of the current character being received).  Next, recvQueueLength, the variable which holds the current length of the character being received, is updated to reflect the latest character length.  The next step is to determine if the full character has been received.  This is determined by comparing recvQueueLength to the RECV_QUEUE_THRESH, which is the threshold as determined by multiplying the number of expected bits by the expected bit width plus another bit width (for the start bit).  If the recvQueueLength is greater than the RECV_QUEUE_THRESH, then a semaphore is set, recvdChar, to indicate that a full character has been received.  The FTM / TPM clock is turned off, and the pin interrupt functionality of the receive pin is enabled.  The final step in the interrupt routine is to increment the receive queue index, recvQueueIndex.  This variable points to the current entry in the receive queue array. Using DMA to receive characters When using DMA, the receive FTM / TPM interrupt is much different. The interrupt routine simply needs to clear the channel interrupt flag, stop the FTM / TPM timer, disable the DMA channel, and set the received character semaphore.  The character is then decoded outside of the interrupt routine.  The interrupt function when using DMA is shown below: Decoding the received pulse widths Once the array of pulse widths has been populated, the received character needs to be translated into a single number.  This varies slightly when using DMA and when not using DMA. However, the basic principle is the same.  The number of bits in a single entry is determined by dividing by the expected bit width and this is translated into a temporary array that contains 1's and 0's, and then that is used to shift in the appropriate number of 1's and 0's into the returned char variable.  A temporary array is needed because the values are shifted into the UART LSB first, so the bit must be physically flipped from the first entry to the last.  There is no logical operation that will do this automatically. The algorithm to perform this translation is shown below.  In this algorithm, note that recvPulseWidth is the array that contains the raw count value of the pulse width.  The array tempRxChar holds the decoded character in reverse order and rxChar is a char variable that holds the received character. Conclusion This document provides an overview of the UART protocol and describes a method for creating a software UART using the timing features of the FTM or TPM peripheral.  This method allows for accurate timing and while not relying entirely on the CPU and the latency associated with the interrupt and the GPIO pins.  The receive function is open to further optimization by using DMA, which can provide further unloading of the CPU.
View full article
作者 Sam Wang & River Liang 在RISC架构的MCU中,通常是加载-存储(Load and Store)的操作机制,而这种方式不能提供传统8bit架构MCU的直接位操作内存和地址空间。为此飞思卡尔在M0+系列MCU上集成了BME(Bit Manipulation Engine)位操作引擎功能,例如KE和KL系列里都带有BME,它从硬件上提供了对外设地址空间用读-修改-写的操作方式来实现位操作。         使用BME能够降低总线的占用率和CPU执行时间,这些效果都能够降低系统的功耗。另外使用相比于用C语言实现相同功能的代码,使用BME能够更节省代码空间。这些可以参照         BME功能支持访问从0x4000_0000开始的,大小为512K的地址空间,并把它映射成从0x4400_0000到0x5fff_ffff的内存空间。         好了,长话短说。下面转入正题,我们应该如何使用BME来进行位操作,并达到节省代码空间、提高效率的效果。 一、写操作方式,对定义内容用写的方式来实现与、或、异或、位域插入功能 1:BME的&操作可以一次对IO的几个bit清0     //     0x21<<26 | addr (A0~A19) //GPIOA_PDOR   地址为   400F_F000 #define GPIOA_AND *((volatile unsigned char *) (0x44000000+0xFF000)) 例: GPIOA_AND=0xaa; #define GPIOA_AND_I *((volatile unsigned int *) (0x44000000+0xFF000)) 例: GPIOA_AND_I=0x55aa; 实际上命令是将400f_f000的内容与目标数进行&运算。修改volatile unsigned char, volatile unsigned int, volatile unsigned long来实现BME的所谓8,16,32位操作.下面命令相同。 2:BME的|操作可以一次对IO的几个bit置1     //       0x22<<26 | addr (A0~A19) #define GPIOA_OR *((volatile unsigned char *) (0x48000000+0xFF000)) 例: GPIOA_OR=0xaa; #define GPIOA_OR_I *((volatile unsigned int *) (0x48000000+0xFF000)) 例: GPIOA_OR_I=0x55aa; 实际上命令是将400f_f000的内容与目标数进行|运算。 3: BME的^操作          //     0x23<<26 | addr (A0~A19) #define GPIOA_XOR *((volatile unsigned char *) (0x4C000000+0xFF000)) 例:GPIOA_XOR=0xaa; #define GPIOA_XOR_I *((volatile unsigned int *) (0x4C000000+0xFF000)) 例: GPIOA_XOR_=0x55aa; 上面3个例子讲解了一般的与、或、异或等常用操作,下面来点复杂一点的。                                                                                           4: BME的位域插入操作BFI(Bit Field Insert)//   (5<<28) | (bit<<23) | (width<<19) | addr (A0~A18) #define BME_BFI_ADDR (ADDR, BIT, WIDTH)   (*(volatile uint32_t *) (((uint32_t) ADDR) | (1<<28) | (BIT<<23) | (WIDTH<<19))) 在这里bit是插入的位置,表示被操作目标的最低位开始被操作,Width这里是插入的数据长度 例:BME_BFI_ADDR(&ADC0_CFG1, 0x05, 0x01) = 0x40; 结果是将寄存器ADC0_CFG1从bit5开始,用0x40的bit5来替换ADC0_CFG1的bit5,0x40的bit6来替换ADC0_CFG1的bit6,调用该命令后,寄存器ADC0_CFG1_ADIV = 2 相当于执行了mask = ((1 << (w+1)) - 1) << b;                          //等一系列位操作。                             (ADC0_CFG1 & ~mask) | (0x40 & mask); 使用BFI功能需要注意的是,操作地址是A0到A18,而GPIO寄存器的A0到A19是从FF000开始,因此会有1bit 的地址冲突。为此,在使用BFI操作GPIO的寄存器时,使用的是内存映射出来的地址空间,此时GPIO的起始地址将为F000,如果还使用原来的地址,命令将会无效。之前提到的AND、OR、XOR操作,对于GPIO地址空间在FF000还是F000都适用 #define BME_BFI_GPIOA (BIT, WIDTH)        (*(volatile uint32_t *) ((uint32_t) (5<<28) | (BIT<<23) | (WIDTH<<19) | 0xF000)) 例:BME_BFI_GPIOA(0,3) = 0x0a; 结果是GPIO_PDOR从bit0开始,一共4位被1010替换了。 二、读操作方式 5, BME的读操作使某位置1, Load-and-Set 1 Bit// #define PTA1_SET   (void) (*((volatile unsigned char *) (0x4C000000+ (1<<21) + 0xF000))) #define PTA1_SET_I   (void) (*((volatile unsigned int *) (0x4C000000+ (1<<21) + 0xF000))) 例: PTA1_SET;   //效果是GPIOA1高电平         LAS1      第1位    GPIOA_PDOR地址的A0-A15 6, BME的读操作使某位清0, Load-and-Clear 1 Bit #define PTA2_CLR   (void) (*((volatile unsigned char *) (0x48000000 + (2<<21) + 0xF000))) #define PTA2_CLR_I   (void) (*((volatile unsigned int *) (0x48000000 + (2<<21) + 0xF000))) 例: PTA2_CLR;     //效果是GPIOA2低电平        LAC1      第2位     GPIOA_PDOR地址的A0-A15 7, BME同时提取多个bit,Unsigned Bit Field Extract 前8位内                     //UBFX      第1位开始       取1+1位   GPIOA_PDOR地址的A0-A18 #define PTA_OUT    *((volatile unsigned char *) (0x50000000+ (1<<23) + (1<<19) + 0xF000)) 前16位内                   //UBFX      第1位开始       取1+1位   GPIOA_PDOR地址的A0-A18 #define PTA_OUT_I    *((volatile unsigned int *) (0x50000000+ (1<<23) + (1<<19) + 0xF000)) 例: 初始值GPIO_PDOR = 0x3a;   //            11_1010   temp = PTA_OUT; //                    此时temp = 0x01 例: 初始值GPIO_PDOR = 0x35;   //            11_0101   temp = PTA_OUT; //                    此时temp = 0x02 该宏定义UBFX功能是将GPIO_PDOR从bit1开始提取1+1位,并以bit1为最低位赋值到目标变量。          需要注意的是UBFX与BFI一样操作的都是映射内存空间,用来操作GPIO时要以F000为起始地址。         BME执行的是读-修改-写操作,而我们很多寄存器有些位是w1c,也就是所谓的write-1-clear,写1清0的工作方式。使用BME时就需要特别注意和小心了,否则会出现很多不可预料的后果。               如果一个寄存器中有多个连续的W1C位,我们就不要使用LAS1来对寄存器写1清0了,因为在LAS1这个操作中,其中有一步操作是将数据读回(在reference manual中有read data return to core一说)。这一步会将原本不需要清0的位给清了。         下面介绍这个情况的实验。 在我们M0+的PWM模块中,寄存器TPM0_STATUS所有有效位都为w1c,我们模拟一个情景: 系统48MHz,TPM时钟128分频,TPM0定时中断计数器最大值为37499,并使能溢出中断。 通道0设置为output compare模式的match output low,比较值为10000,不触发中断。 通道1设置为output compare模式的match output high,比较值为20000,不触发中断。 上面的设置可以使我们每50ms进入一次中断,需要我们在中断服务程序中清中断标志。 TPM0_STATUS 地址为 0x4003_8050 中断函数中设置断点观察TPM0_STATUS的值,为1_0000_0011 B #define TPM0_STATUS_LAS1   (void) (*((volatile unsigned int *) (0x4C000000| (1<<21) | 0x38050))) 中断程序中用TPM0_STSTUS_LAS1将bit1置1清0,得到的结果是TPM0_STATUS = 0,使用LAS1作用在该寄存器的其他位结果都一样。将其他不需要改动的位都清0了。     我们换种方式。 #define TPM0_ STSTUS_BFI *((volatile unsigned int *) (0x50000000 | (0<<23) | (8<<19) | 0x38050)) =0x001 中断里用BFI去修改该连续的w1c位,从bit0开始,长度为8+1位,执行TPM0_STSTUS_BFI后bit8和bit2仍为1, bit0已经被清0了。这确实是我们想要的效果。         此后我们遇上一个寄存器有多个连续w1c时,可以使用BFI的方式来改写寄存器w1c位的值,而位判断则采用UBFX的方式来提取该位域。 下面是针对比较器的CMP0_SCR寄存器操作的例程. CMP0_SCR是8bit的寄存器bit1和bit2是w1c #define CMP_SCR_CFR_CLR *((volatile unsigned char *) (0x50000000+ (1<<23) + (1<<19) + 0x73003)) =4 #define CMP_SCR_CFF_CLR *((volatile unsigned char *) (0x50000000 + (1<<23) + (1<<19) +0x73003)) =2              //           BFI                    第一位开始   1+1位          2对应bit2bit1为01          4对应bit2bit1为10 #define CMP_SCR_CFR    *((volatile unsigned char *) (0x50000000 + (2<<23) + (0<<19) + 0x73003)) #define CMP_SCR_CFF    *((volatile unsigned char *) (0x50000000 + (1<<23) + (0<<19) + 0x73003))             //            UBFX                分别是提取bit2和bit1的值 void CMP_Change(void) { If (CMP_SCR_CFR) { CMP_SCR_CFR_CLR; }                   If (CMP_SCR_CFF) { CMP_SCR_CFF_CLR; } }         总结,BME功能可以有效提高M0+的位操作性能并减少代码占用空间,但用于处理w1c位时要特别小心,总的来说BME是个好东西,在内核资源紧张的时候可以给用户提供一个精简代码的手段。
View full article
Hi everyone,      I have got customer queries on unavailability of complementary mode PWM on KL25Z . So, I thought let me experiment something and post it onto the community.      The timer module on KL25 is TPM, not FTM!. There are 3 TPMs, TPM0 with 6 channels, TPM1 and TPM2 with 2 channels each. To generate a PWM signal, PWM component can be used. But the PWM bean doesnot provide option to generate complementary PWM. So, we need to configure different channels to get the complementary PWM. Again, there is a limitation for this. PWM component doesn't allow to generate initial polarity high. It says "the inherited component doesnot support this feature". But in run time can set or clear value on the PWM output pin using the SetValue() and ClrValue(). But again the inherited component"TimerUnit_LDD" doesn't support generating SetValue() and ClrValue().      So, I came to a conclusion 'not to use PWM component' and started using Init_TPM. Using this component, 2 channels are configured to have opposite polarity during initialization. They are configured to have the same period. Deadtime is also inserted by configuring different duty cycle on each channel. But methods are not available since the component only provides the initialization function which is good enough to start . Dynamically if dutycycle needs to be changed, methods have to be written explicitly     Project and oscilloscope captures are attached for reference. Hi Note that this is also supported in the uTasker project - see http://www.utasker.com/docs/uTasker/uTaskerHWTimers.PDF See specifically the final page - this is compatible for K and KL processors. Regards Mark http://www.utasker.com/kinetis.html This document was generated from the following discussion: Complementary PWM on FRDM-KL25Z using processor expert
View full article
In this document we are going to see how to use the attached code which implements the configuration of the FRDM-KL25 board as a USB HOST interfacing with a Numeric Keyboard and a 16x2 LCD. The project is compiled in the CodeWarrior IDE using Processor Expert and the Components to support the USB module of the USB Stack 4.1.1. How to add the Processor Expert USB components. The instructions to install the USB components to use them with Processor Expert are in the documentation of the USB Stack 4.1.1; here you can see the steps as well: Download the USB Stack 4.1.1 from the Freescale’s Website (USB Stack 4.1.1) Run the .exe file and install it in the default location. Open CodeWarrior and select Import Components in the Processor Expert button in menu bar. An Open windows will pop up, there you need to go to the path: <install folder>\Freescale USB Stack v4.1.1\ProcessorExpert\Components. To have the complete components and support for the USB module add each PEupd file repeating this step. Close CodeWarrior and open it again to ensure correct installation of the components. Check that the new components are available in the Components Library. About this Project. This project is based in the example code for Processor Expert in the USB Stack 4.1.1 USB_HID_MOUSE_HOST_MKL25Z128_PEx which implements the use of the FRDM-BOARD KL25 and a HID Mouse Device to interface with. In this project the HID Device is a Numeric Keyboard and the HOST Device (FRDM-KL25) is handling the data and printing them in a 16x2 LCD used in 8 bits mode (The LCDHTA component used here was created by Erich Styger; find the component an all the information about it here: http://mcuoneclipse.com/2012/12/22/hd44780-2x16-character-display-for-kinetis-and-freedom-board/ and say Thank you Erich: “Thank you Erich”). Here you can find a video of the implementation of this application: HID HOST WITH FRDM-KL25 The hardware components are: FRMD-KL25 Rev.E Adafruit Prototype Shield v.5 LCD JHD-162A Numeric USB Keyboard (Product Name: Numpad i110, Model No. GK-100010) USB _host Inside the project you can see there is a folder called USB_Host an it contains two important folders with source files: App_keyboard: Contains the specific function for the Keyboard configuration: in use, attached detached, callbacks and more; contain how to handle the data coming from the device. The function process_kdb_buffer is where the data is transmitted to the LCD and use it for the application. Classes: contain the necessary function to handle a hid as the device. Handle all the functions necessary for the USB protocol. Note: The usb_classes.c and usb_classes.h files are generated by processor expert. I attach these two files as well to have a reference how these files must look like. This is because sometimes during the code generation process Processor Expert erases part of the code. I hope this project is useful for you. Best Regards, Adrian.
View full article
我们知道Kinetis L系列的中断向量表中只支持两个外部中断向量(vector_46 and vector_47),而FSL早期推出的的KL系列(包括KL25\KL24、KL15\KL14)只有PORTA和PORTD两个IO口支持中断,不过最新推出的KLx6系列(KL26、KL16和KL46)可以支持PORTA、PORTC和PORTD三个IO口的外部中断,其中PORTC和PORTD这两个IO端口共享同一个中断向量,另外,KL0x系列(包括KL02、KL04和L05)由于外部引脚只有PORTA和PORTB两个IO端口,所以它所支持的外部中断只有PORTA和PORTB。 下图分别为KLx5\KLx4系列(不包括KL05\KL04)、KLx6系列和KL05\KL04\KL02的外部中断向量分配表: KLx5\KLx4: KLx6: KL0x: KLx6的头文件注释: 最后需要注意的是,目前所有官方的demo例程(KLxx_SC)的中断向量表vector.h和MKLxxxx.h文件中关于中断向量的注释仍然是PORTA和PORTD,甚至有一部分例程中中断向量表的注释仍然是M4的注释直接移过来的,容易误导客户编程,这点需要在设计PCB板的时候有所考虑。
View full article
Microgenios viabilizou a realização de videos de treinamentos de curta duração para ensinar os primeiros passos com o microcontrolador Kinetis L como parte do Road Show de Microcontroladores ARM cortex-M0+ (Kinetis L Freescale), projeto realizado em parceria pela a Freescale em 10 cidades espalhadas pelo Brasil. Veja os videos para iniciar seu projeto com Kinetis L: Neste vídeo aprenderemos o processo de download e instalação do CodeWarrior V10.3 e outros pacotes de softwares Freescale: http://www.youtube.com/watch?v=bjtsLHMImDY Neste vídeo aprenderemos o processo de atualização do CodeWarrior V10 (baseado no Eclipse) e conheceremos as pastas criadas na instalação: http://www.youtube.com/watch?v=Sslf0nF0Td8 Neste vídeo conheceremos a ferramenta de hardware Freedom Board da Freescale com microcontrolador ARM cortex-M0+; e entenderemos a utilização da interface de gravação e depuração OpenSDA: http://www.youtube.com/watch?v=jeuq7ErvTGQ Neste vídeo aprenderemos a criar nosso primeiro projeto com a Freedom Board (FRDM-KL25Z), que possui microcontrolador da família Kinetis L (núcleo ARM cortex-M0+) da Freescal; utilizaremos como ferramenta de software o CodeWarrior V10.3 e o Processor Expert: http://www.youtube.com/watch?v=sx2tpDBWDt8 Neste vídeo conheceremos a IDE cloud mbed, que possibilita desenvolvimento e aplicações diretamente no navegador: http://www.youtube.com/watch?v=N7qMvO_R6Sc Mais informações visite: http://www.microgenios.com.br/website/index.php/hands-on-freescale
View full article
Introduction What is a gated timer and why would I need one? A gated timer is a timer whose clock is enabled (or "gated") by some external signal.  This allows for a low code overhead method of synchronizing a timer with an event and/or measuring an event. This functionality is not commonly included on Freescale microcontroller devices (this functionality is only included on devices that are equipped with the upgraded TPM v2 peripheral; currently K66, K65, KL13, KL23, KL33, KL43, KL03) but can be useful in some situations.  Some applications which may find a gated timer useful include asynchronous digital sampling, pulse width duty cycle measurement, and battery charging. How do I implement a gated timer with my Kinetis FTM or TPM peripheral? To implement a true gated timer with a Kinetis device (that does not have the TPM v2 peripheral), additional hardware will be required to implement the enable/disable functionality of a gated timer.  This note will focus on two different ways (low-true and high-true) to implement a gated timer.  The method used will depend on the requirements of your application. Implementing a gated timer for Kinetis devices without the TPM v2 peripheral requires the use of a comparator and a resistive network to implement a gated functionality (NOTE:  Level shifters could be used to replace the resistive network described; however, a resistive network is likely more cost effective, and thus, is presented in this discussion).  Figure 1 below is the block diagram of how to implement a gated timer functionality.  The theory behind this configuration will be explained in later sections. Theory of Operation Comparator and resistive network implementation The comparator is the key piece to implementing this functionality. For those with little experience with comparators (or need a refresher), a comparator is represented by the following figure.  Notice that there are three terminals that will be of relevance in this application: a non-inverting input (labeled with a '+' sign), an inverting input (labeled with a '-' sign), and an output. A comparator does just what the name suggests: it compares two signals and adjusts the output based on the result of the comparison.  This is represented mathematically in the figure below. Considering the above figure, output of the comparator will be a  logic high when the non-inverting input is at a higher electric potential than the inverting input.  The output will be a logic low if the non-inverting input is at a lower electric potential than the inverting input.  The output will be unpredictable if the inputs are exactly the same (oscillations may even occur since comparators are designed to drive the output to a solid high or solid low).  This mechanism allows the clock enable functionality that is required to implement a gated timer function provided that either the non-inverting or inverting input is a clock waveform and the opposite input is a stable logic high or low (depending on the desired configuration) and neither input is ever exactly equal.  Comparator Configurations There are two basic signal configurations that an application can use to enable the clock output out of the comparator: low-true signals and high-true signals.  These two signals and some details on their implementation are explained in the following two sections.  Low-true enable A low-true enable is an enable signal that will have zero electric potential (relative to the microcontroller) or a "grounded" signal in the "active" state.  This configuration is a common implementation when using a push button or momentary switch to provide the enable signal.  When using this type of signal, you will want to connect the enable signal to the non-inverting input of the comparator, and connect the clock signal to the inverting input. The high level of the enable signal should be guaranteed to always be the highest voltage of the input clock plus the maximum input offset of the comparator. To find the maximum input offset of the comparator, consult the device specific datasheet.  See the figure below to see a graphical representation of areas where the signal will be on and off. The external hardware used should ensure that the low level of the enable signal never dips below the lowest voltage of the input clock plus the maximum input offset of the comparator. The following figure displays one possible hardware configuration that is relatively inexpensive and can satisfy these requirements. High-true enable A high-true enable is an enable signal that will have an electric potential equal to VDD of the microcontroller in the "active" state.  This configuration is commonly implemented when the enable signal is provided by an active source or another microcontroller.  When interfacing with this type of signal, you will want to connect the enable signal to the inverting input of the comparator, and connect the clock signal to the non-inverting input.  When the comparator is in the inactive state, it should be at or below the lowest voltage of the clock signal minus the maximum input offset of the comparator.  Refer to the following figure for a diagram of the "on" and "off" regions of the high true configurations. The external hardware will need to guarantee that the when the enable signal is in the active state, it does not rise above the highest voltage of the clock signal minus the maximum input offset of the comparator. The following figure displays one possible hardware configuration that is relatively inexpensive and can satisfy these requirements. Clocking Options Clocking waveform requirements will vary from application to application.  Specifying all of the possibilities is nearly impossible.  The point of this section is to inform what options are available from the Kinetis family and provide some insight as to when it might be relevant to investigate each option. The Kinetis family provides a clock output pin for most devices to allow an internal clock to be routed to a pin.  The uses for this option can vary.  In this particular scenario, it will be used to provide the source clock for the comparator clock input. Here are the most common clock output pin options across the Kinetis K series devices.  (NOTE:  If the application requires a clock frequency that the CLKOUT signal cannot provide, a separate FTM or TPM instance or another timer module can be used to generate the required clock.) In the Kinetis L series devices, the following options will be available. The clock option selected should be the slowest allowable clock for the application being designed.  This will minimize the power consumption of the application.  For applications that require high resolution, the Bus, Flash, or Flexbus clock should be selected (note that the Flexbus clock can provide an independently adjustable clock, if it is not being used in the application, as it is always running).  However, if the target application needs to be more power efficient, the LPO or MCGIRCLK should be used.  The LPO for the Kinetis devices is a fixed 1 kHz frequency and will, therefore, only be useful in applications that require millisecond resolutions.
View full article
How to byte program SPI flash via QSPI QSPI module are used in many Kinetis MCU, like K8x, K27/28 and KL8x. QSPI expands the internal flash range and can run in a fast speed. Compared to DSPI, QSPI is very complex and often takes a lot of time to learn. In KSDK there are two QSPI demo which shows how to program SPI flash in DMA mode and polling mode. Both of them program the QSPI flash with a word type array. But can the QSPI module program SPI Flash in byte? Yes, this article shows how to do it. Device: FRDM_KL82Z Tool: MCUXpresso IDE Debug firmware: JLINK I build the test project base on KL82 SDK/driver_example/qspi/polling_transfer. To byte program SPI flash, a new LUT item must be added. uint32_t lut[FSL_FEATURE_QSPI_LUT_DEPTH] =    {/* Seq0 :Quad Read */          /* CMD:       0xEB - Quad Read, Single pad */          /* ADDR:       0x18 - 24bit address, Quad pads */          /* DUMMY:     0x06 - 6 clock cyles, Quad pads */          /* READ:       0x80 - Read 128 bytes, Quad pads */        …        …        [32] = QSPI_LUT_SEQ(QSPI_CMD, QSPI_PAD_1, 0x02, QSPI_ADDR, QSPI_PAD_1, 0x18),        [13] = QSPI_LUT_SEQ(QSPI_WRITE, QSPI_PAD_1, 0x1, 0, 0, 0),        …        /* Match MISRA rule */        [63] = 0}; This item tells system how to program a single byte. Then when we write the data to TxBuffer, we must write the byte 4 times. This is because a write transaction on the flash with data size of less than 32 bits will lead to the removal of four data entry from Txbuffer. The valid bit will be used and the rest of the bits will be discard. Then before we start programming, we must set the data size.      QSPI_SetIPCommandSize(EXAMPLE_QSPI,1);   After byte program, we can see the result from 0x68000000. Attachment is the demo project. You can find that 0x03 was written to 0x68000005 after running.
View full article
Hi team ,      I would like to share an experiment that about the Fast IO - zero wait state access of KL series . Detail please refer to attached file . Best regards, David
View full article