S12 / MagniV Microcontrollers Knowledge Base

cancel
Showing results for 
Search instead for 
Did you mean: 

S12 / MagniV Microcontrollers Knowledge Base

Labels

Discussions

I've just went through my PC and put some examples here. ( I made them "a few" days ago.) The files are presented with extension BMP because of some firewals.   AN3490.pdf DOC-XEP100-MMC-Memory_Map-Common_Map-V5_0-MSExcel.xls EEE.xls TN263-CodeWarrior IDE.pdf XEP100 - EEPROM Direct Access - CW45.zip XEP100 - Initial data in Emulated EEPROM - CW47.zip XEP100 - MPU - CW47.ZIP XEP100 - RAM addressing - CW45.zip XEP100 - SCI - XonXoff_poll - CW47.zip XEP100 - Security + Backdoor Key Access - CW47.zip XEP100-ATD wakes up from STOP - CW47.zip XEP100-ATD-ATDandXGATEandSharedRAM-CW50.zip XEP100-ATD-CH1toCH4-CW47.ZIP XEP100-ATD-CH1toCH8-CW47.ZIP XEP100-ATD-Cntnuos_SingleCh-v1_0-CW47_Data.zip XEP100-ATD-Tmprture_bandgapV-v1_0-CW47_Data.zip XEP100-BDM-BDMcommExample-CW50.zip XEP100-BufferRAMasOneArray-CW51.zip XEP100-BufferRAMasRAMonly-CW51.zip XEP100-CAN-CAN0-RxTxIsrLoopback-CW47.zip XEP100-CAN-CAN0-TxAtXGATE-CW51.zip XEP100-CAN-CAN0CAN1 - CW45.ZIP XEP100-CAN-CAN2CAN2-Identifiers SandX-loopback-CW51.zip XEP100-CAN-CAN2CAN3-CW47.ZIP XEP100-CAN-CAN2CAN3-FILTER-CW51.ZIP XEP100-CAN-CAN2CAN3-Identifiers SandX-CW51.zip XEP100-CAN-LoopbackInterrupt-CW51.zip XEP100-CAN.ZIP XEP100-CAN0 - CAN1 - CW45.ZIP XEP100-CAN0-RxTxIsrLoopback-CW47.zip XEP100-CAN0-RxTxIsrLoopbackXGATE-CW51.zip XEP100-CAN0-TxAtXGATE-CW51.zip XEP100-CRG-COP-CW47.ZIP XEP100-CRG-PLL-Setup-CW47.zip XEP100-EBI-MRAM256x16-CS0-CW51.zip XEP100-EBI-MRAM256x16-CS2-CW51.zip XEP100-ECT-ECTasPWM-CW47.zip XEP100-ECT-FreqMeasurement-CW51.zip XEP100-ECT-InputCapture-CW51.zip XEP100-ECT-TIM.ZIP XEP100-EEEPROM-Addressing-Lukas-CW46.zip XEP100-EEEPROM-DataPlacement-CW51.zip XEP100-EEEPROM-plusMPU-CW51.zip XEP100-EEPROM-DirectAccess-CW51.zip XEP100-EXBUS-EXRAM256x16-CS1-CW47.zip XEP100-EXBUS-ExRam_MR2A16ACYS35-CS1-CW51.ZIP XEP100-FLASH-PFLASH-CW47.ZIP XEP100-FLASH-PFLASH-CW51.ZIP XEP100-FLASH-PFLASH-PFlashInitData.zip XEP100-FLASH-PFLASH_reading-CW47.zip XEP100-GPIO-PJ2isr-CW47.zip XEP100-GPIO-PortPisrXgate-CW51.zip XEP100-ID-readPartID-CW47.zip XEP100-IIC-Master4Flash24C16-CW51.zip XEP100-INT-INTERRUPTNUMBER-CW51.ZIP XEP100-INT-TRAPPROC-CW51.ZIP XEP100-MDDC-delay generator-v1_0-CW47.zip XEP100-MPU-MPU-CW47.ZIP XEP100-PFLASH-CW47.ZIP XEP100-PFLASH-CW51.ZIP XEP100-PIM-PTPfunctions1-CW47.zip XEP100-PIT-FLOATING PERIOD-CW51.ZIP XEP100-PIT-SERIAL_DATA_OUT-CW45.ZIP XEP100-PIT-XGATE-SEMAPHORES-CW51.ZIP XEP100-PWM-dutyatXGATE-CW47.zip XEP100-RAM-addressing-v1_0-CW51.zip XEP100-RAM-RAMaddressing-CW45.zip XEP100-SCI_PIT-CW47.zip XEP100-SCI-ECHO-isr.zip XEP100-SCI-ECHOatCPU-CW47.zip XEP100-SCI-ECHOatCPUisr-CW47.zip XEP100-SCI-ECHOatXGATEisr-CW47.zip XEP100-SCI-Sci0transmitterOnXGATE-CW45.zip XEP100-SCI-SciTx-CW45.zip XEP100-SCI-SCI_PIT-CW47.zip XEP100-SCI-XonXoff_poll-CW47.zip XEP100-SciTx-CW45.zip XEP100-SECURITY-BackdoorKeyAccess-CW47.zip XEP100-STOP-ATDwakesUp-CW47.zip XEP100-STOP-RTIwakesUp-CW51.zip XEP100-STOP-WakeUp-CW47.zip XEP100-STOP_and_ API_and_PLL-CW47.zip XEP100-STOP_and_XIRQ_and_PLL-CW47.zip XEP100-TIM-10msIsr-CW47.zip XEP100-TIM-FreqMeasurement-CW51.zip XEP100-UnionInPages.zip XEP100-UnionInPagesAndECT.zip XEP100-XGATE-SharedVars-CW51.zip XEP100PWM-PWM8bit-CW45.zip XEP100_SPI_master_w_25AA256.zip XEQ384EXBUS-EXRAM256x16-CS2-4000-7FFF-CW47.zip XEQ512-PWM-10kHz8bit100point-CW51.zip XEQ512-RAM-addressing-v1_0-CW51.zip XEQ512-SWtrigger-CPU_XGATE-CW47.zip XET256-ECT-asPWM-CW47.zip XET256-ECT-OC-CW47.ZIP XET256-EXBUS-ExROM2ExRAM-CW46.zip XET256-RTI-RTIdec and COP-v1_0-CW47.zip XET256-SCI-Tx_Poll-CW51.zip XF256-SCI-ECHOatCPUisr-CW47.zip XF256-SCI-ECHOatXGATEisr-CW47.zip XF256-SCI-ECHOatXGATEisr-CW47.zip
View full article
S12(X) S12 MagniV DOCUMENTS CAN setup calculator for S12(X) and MagniV devices  S12(X) MCU Security  S12(X) devices reference schematics  Useful documents for building own CAN bootloader  How-to Add missing derivatives to CodeWarrior Classic HCS12(X) 5.2 (Unofficial Method)  DOCUMENTS S12Z constant, variable, code allocation in CodeWarrior   BLDC 6-step control speed scaling using S12ZVM  MagniV Power Dissipation Calculator  MTRCKTSBNZVM128 vs MTRCKTSPNZVM128 kit motor  S12ZVM configuration for the motor control applications  Software for S12ZVM motor control kits  DEVKIT-ZVL128 EVB review  S12 family devices - COP recognition consideration calculator  MagniV PLL calculator  Bus-Off Handling in MSCAN   EXAMPLES CAN Standard ID and CAN Extended ID for S12(X) and MagniV devices, memories refreshment  S12XD, S12XE - External BUS design - Addendum To AN2708  S12X Examples Pack  TIC-S12-XDP512-FLASH-E_W-CW47  S12X_Interrupt_catcher (catch all unexpected interrupts)  API example code for S12G  Read paged const in S12  EXAMPLES How to get device ID and write program once field without programming application to the S12Z device in the CodeWarrior (Eclipse)  CAN Standard ID and CAN Extended ID for S12(X) and MagniV devices, memories refreshment  S12Z Protection Override  S12ZVC IFR Program Once Field  S12Z: Simulating ECC errors at EEPROM by cumulative write  S12Z: Simulating ECC errors at RAM by debug access  S12Z: Simulating ECC errors at Flash by cumulative write  S12Z SW example of COP Watchdog Reset  S12Z Interrupt catcher for unexpected interrupts  S12Z voltage measurement  S12Z EEPROM example code  S12Z Flash example code  Autonomous Clock Trimming SW example for MagniV devices  BATS Voltage Supply Sense example code for MagniV devices  High-Voltage Input (HVI) SW examples for MagniV devices  SW examples for MagniV S12ZVC and S12ZVL devices  PWM example code for S12ZVL  S12ZVL-TIM-FrequencyMeasurement-V1_0-CW106-TIC-EXAMPLE  SW example of Security feature with Backdoor Access Key option for S12ZVL  Example S12ZVL ADC0 triggered by TIM0 OC updates PWM duty cycle  S12ZVM clock module and PLL configuration - SW examples  Low power mode example code for S12ZVC  Single / double bit RAM ECC error example code at S12ZVC  S12ZVML-MINIBRD software ported from AN5327  Example: S12ZVC192-ACMP-POT-CW107  Example codes form "Easily Develop LIN-based Actuator Applications with Mixed-signal MCUs" webinar     
View full article
Hello everyone, In this post you are going to find the example codes that where mentioned during the "Learning to Easily Develop LIN-based Actuator Applications with Mixed-signal MCUs" webinar. In the "S12ZVMA_Webinar_ExampleCodes" package you are going to find the code for the S12ZVMA slave node, the code for the S12ZVL master node and the LIN configuration files (LDF and NPF's files).   SETUP CONFIGURATION: In the images below you can find the information you need to know to create the setup and get running your LIN network and the DC motor.   Note: Remember that in this code we are using the active configuration where the High Side Driver and the Low Side Driver are being used to control de motor.   Steps: Place jumper J21 in the position [3-2]. With this step, we are connecting the PHASE_A_HS with the PHASE_A_LS to get the active configuration. Connect one line of your DC motor to J30 (connect it in pin 2 or 3, do not use pin 1) and the other line to any GND point of your S12ZVMAEVB. Connect the master and the slave nodes using J6 jumper.     Best Regards, Atzel Collazo
View full article
The DEVKIT platform The NXP released new board platform for automotive products – DEVKIT. The DEVKIT is a low-cost development platform with Arduino UNO/Mega pin compatibility. In my review, I will focus mainly on DEVKIT-ZVL128 board.                                          The DEVKIT boards are similar to FRDM boards, but they are slightly wider (58mm versus 53mm) due to moving MCU specific pins to external rows of Arduino pin compatible connectors. So, we should be able to access MCU specific pins even when we connect any Arduino shield on top of this board.     The other currently or soon available DEVKIT boards are: DEVKIT-S12ZVL DEVKIT-S12ZVC DEVKIT-S12G128 DEVKIT-S12XE DEVKIT-S12VR64 DEVKIT-MPC5748G DEVKIT-MPC5744P FRDM-KEA128 FRDM-KEA64 FRDM-KEA32 DEVKIT-COMM - 6 LIN and 4 CAN transceivers shield DEVKIT-MOTORGD – three-phase motor control shield with GD3000 N-channel MOSFETs driver and power stage Note: The FRDM-KEA boards belongs also into the DEVKIT platform despite on the “FRDM” in the board name.     The Content What you will get for US$35 (current price on NXP web pages): Antistatic paper box DEVKIT-ZVL128 board short micro-USB cable       The sticker on the box points to the NXP web pages for downloading more documents such as the quick start guide, schematic, PCB BOM and design files, code examples or buy the same board again ;-). Unfortunately, the board User Guide is not available yet.   This web page is also offering “Getting Started” tab with the interactive quick start guide – quite useless feature since the page forgets on necessary 12V power supply for MCU powering and it proposes old CW5.1 (Classic IDE) for S12(X) instead of CW10 (Eclipse IDE).   What else you will need: The IDE – for example, the NXP CodeWarrior or Cosmic ZAP 12V DC power supply (3.8V~40V) with barrel connector (6mm outside diameter x 2mm inside diameter) MCU code   The Board DEVKIT-ZVL128 board is assembled by: S12ZVLA128 MCU (Big Knox) in 48-pin LQFP package 8MHz crystal Standard 2mm DC power jack connector for 12V power supply On-board OSBDM debugger trough micro-USB connector Standard BDM connector Arduino UNO pin compatible connectors with extended connectivity (the internal rows of the connectors are arranged to fulfill Arduino™ shields compatibility) RGB LED and 2 x push button switches LIN and CAN connectors CAN transceiver MC33901 5k potentiometer and RESET switch 3V/150mA and 5V/150mA LDO voltage regulators     The great thing is that the board has connector pins named from the bottom side of the PCB = less tracking on schematic.     On another side, some of the MCU pins may be routed to Arduino connectors trough zero Ohm resistors. Since these resistors are very small (size 0402), the potential re-routing will need a solid hand.     It is great that loop type test points arrived finally also on low-cost development boards – now in surface mount version. The small loops may be simply locked by test hooks and measured by laboratory equipment.       The MCU The S12ZVLA128 is one of MagniV family MCUs using the 180nm NVM + UHV technology that offers the capability to integrate 40V analog components. It integrates S12Z core, features from the existing S12 portfolio together with “high-voltage” analog modules, including the voltage regulator (VREG) and a Local Interconnect Network (LIN) physical layer (LIN PHY). The S12ZVL(A)128/96/64 derivatives introduces several unique enhancements in comparison with older S12ZVL32/S12ZVL16 derivatives: Significantly bigger memories (64/96/128kB flash, 1/2kB EEPROM, and 4/8kB RAM) The VDDX voltage regulator is capable of providing 5V or 3.3V MsCAN module The S12ZVLA derivatives additional features/improvements: 2% VDDX regulator tolerance improvements 10/6 channel 12bit ADC 8bit DAC module the rail-to-rail analog comparator (ACMP) the Programmable Gain Amplifier (PGA) I am going to use the PGA for thermocouple measurement in the near future.   Software The Software Integration Guide guides us through CW 10.6.4 installation and creating a new project with Processor Expert (PE) tool. Unfortunately, while following that guide, I discovered that the CW10.6.4 does not offer PE as an option (only project without PE) when I tried to create an S12ZVL128 project. But this option is available in newer CW10.7 version. Note: If S12ZVL(A)128 derivative is missing in your CW10.6.4 IDE, please update your CW IDE via menu-Help-Install New Software-FSL MCU Eclipse Update Site and focus mainly on “S12Z Support” and “MCU 10.6.4 Updates” folders.   The code examples contains three primitive example projects: DEVKIT-ZVL128_Lab1GPIO – configure GPIO pins DEVKIT-ZVL128_Lab2ADC – initialize and measure ADC value DEVKIT-ZVL128_Lab3PWM – configure voltage regulator, initialize CLOCK, initialize and measure ADC value, generate PWM   Note: The zip file contains already built projects. The loading it into MCU does not work due to different paths. We have to clean it and build again in our workspace prior loading into the MCU.   These projects are really simple, but they omit some specific potential issues. For example: I would like to recommend to configure CPMUVREGCTL_VREG5VEN bit also in GPIO example since this bit influences output pin voltage levels. The value of the CPMUVREGCTL_VREG5VEN bit is not influenced by any MCU reset. So, we have to be careful especially when we are starting a new project with new peripherals connected to the S12ZVL128 GPIO pins. The ADC command lists (adc0_cmdlist) and ADC result lists (adc0_results) are not aligned in these example codes. It may be fixed by simple modification: volatile unsigned char adc0_cmdlist[1][4] __attribute__ ((aligned (4))) = {0xC0,0xD0,0xA0,0x00}; volatile unsigned short adc0_results[1] __attribute__ ((aligned (4)));‍‍‍‍ The NXP offers for this MCU also LIN2.x and SAE J2602 Stack and S12Z NVM Standard Software Driver (Flash/EEPROM driver).   There are also well-documented example codes at Community from Technical support team which may be used for an inspiration. For example: S12ZVM clock module and PLL configuration - SW examples S12Z Interrupt catcher for unexpected interrupts S12Z voltage measurement A Library of Functions for HD44780 Based LCD Modules (no R/W) for S12Z devices S12ZVL-TIM-FrequencyMeasurement S12Z Flash example code S12Z EEPROM example code …   The next source of information may be NXP application notes. For example: AN4723 S12Z MagniV Bootloader with SW, AN4731 Understanding Injection Current on Freescale Automotive Microcontrollers, AN4841 S12ZVL LIN Enabled Ultrasonic Distance Measurement with SW, AN4842 S12ZVL LIN Enabled RGB LED Lighting Application with SW, AN5084 Hardware Design Guidelines for S12ZVL Microcontrollers, AN5122 Using Freescale’s LIN Driver with the MagniV Family with SW   Summary One of the best advantages of DEVKIT platform is the price. When we compare DEVKIT board prices with alternative evaluation boards (if any exist), we may save between 40 and 95 % EVB price depending on target MCU family. For example, the older TRK-S12ZVL board (assembled by S12ZVL32) is bigger, additionally offers 9 user switches, buzzer, HVI potentiometer, switchable LIN_OUT connector and header ring with all MCU pins. But the price is also almost three times higher than the price of DEVKIT-ZVL128. Also, the connectors with standard 100mils pitch are definitely plus in comparison with previously used TWRPI/PCI EXPRESS connectors and the board allows using plenty of available Arduino shields without complex hardware interconnections. You may look for it for example at Arduino pages, shieldlist.org, Adafruit, …   From my side - thumbs up :smileycheck:.
View full article
This document includes in attachment excel file calculation that might be useful for those using the S12 MagniV for motor control and proper PLL setting in their projects.   Following parameters can be set and reused for different scenarios via attached excel sheet calculation for the S12 MagniV BLDC motor control applications: #define CPMU_REFDIV // PLL setting of ref. divider #define CPMU_SYNDIV // PLL setting of multiplier #define CPMU_POSTDIV // PLL setting of the post divider #define CPMU_REFFRQ // PLL setting of ref. frequency #define CPMU_VCOFRQ // PLL setting of VCO frequency #define ADC_TIM // setting of ADC timer #define MIN_ADC_TRIGGER_FIRST // setting of ADC trigger #define MIN_ADC_TRIGGER_SECOND // setting of ADC trigger #define PWM_MODULO // PMF module config. #define PWM_DEADTIME // PMF module config. #define TIM_PRESCALER // Timer prescaler #define TIMER_1MS // Setting of timer #define SCI_BAUDRATE // setting of SCI baud rate   This is how it can look for setting either internal or external clock: // PLL settings /* /* // Internal clock 1MHz, 100/50 MHz CPU/Bus clock, 8.33 MHz ADC clock #define _INTERNAL_CLOCK                        // 1 MHz internal clock is used #define    CPMU_REFDIV        0 #define    CPMU_SYNDIV        49 #define    CPMU_POSTDIV       0 #define    CPMU_REFFRQ        0 #define    CPMU_VCOFRQ        3 #define    ADC_TIM            2 #define    MIN_ADC_TRIGGER_FIRST     24 #define    MIN_ADC_TRIGGER_SECOND    144 #define    PWM_MODULO                5000 #define    PWM_DEADTIME              50 #define    TIM_PRESCALER      6         // Timer prescaler 64; 50 MHz/64 = 1.28 us #define    TIMER_1MS          781 #define    SCI_BAUDRATE       5208 */  // External clock 4MHz, 25/12.5 MHz CPU/Bus clock, 6.25 MHz ADC clock #define _EXTERNAL_CLOCK #define    CPMU_REFDIV        3 #define    CPMU_SYNDIV        24 #define    CPMU_POSTDIV       1 #define    CPMU_REFFRQ        0 #define    CPMU_VCOFRQ        1 #define    ADC_TIM            0 #define    MIN_ADC_TRIGGER_FIRST     8 #define    MIN_ADC_TRIGGER_SECOND    48 #define    PWM_MODULO                1250 #define    PWM_DEADTIME       13 #define    TIM_PRESCALER      4         // Timer prescaler 16; 12.5MHz/16 = 1.28 us #define    TIMER_1MS          781 #define    SCI_BAUDRATE       1302     It is used in following function for Clock, Reset and Power Management Unit configuration: //Clock, Reset and Power Management Unit configuration //* //*****************************************************************************/ void initCPMU(void) {     // Wait for stable supply after power up     while (GDUF_GLVLSF)         GDUF_GLVLSF = 1;      CPMUREFDIV_REFDIV = CPMU_REFDIV;     CPMUREFDIV_REFFRQ = CPMU_REFFRQ;     CPMUSYNR_SYNDIV = CPMU_SYNDIV;     CPMUSYNR_VCOFRQ = CPMU_VCOFRQ;     CPMUPOSTDIV_POSTDIV = CPMU_POSTDIV;  #ifdef _EXTERNAL_CLOCK     CPMUOSC_OSCE = 1;     while (CPMUIFLG_UPOSC == 0) {}; // Wait for oscillator to start up (UPOSC=1) and PLL to lock (LOCK=1) #endif      while (CPMUIFLG_LOCK == 0) {};     CPMURFLG  = 0x60;     //Clear PORF and LVRF }          Or setting of ADC clock for both ADC modules in ADC module configuration function:   //ADC0CTL_1 = 0;        ADC0TIM = ADC_TIM;          // clock: clk = fbus / (2x(reg.value + 1)) [0.25 - 8MHz]        //ADC1CTL_1 = 0;        ADC1TIM = ADC_TIM;          // clock: clk = fbus / (2x(reg.value + 1)) [0.25 - 8MHz]        All the rest of the corresponding registers settings can be found in the example for the BLDC motor control of 3-pase sensorless BLDC development kit with S12 MagniV in section download: MTRCKTSBNZVM128_SW : Complete motor control application software package for MTRCKTSBNZVM128
View full article
Hello Community user, This post is intended to show how to recovery from Bus-Off state using the MSCAN and CANPHY modules in the MagniV devices. This example is focused on S12ZVC due to the internal CANPHY so it makes easier to create a quick example. What is Bus-Off condition? The bus-off condition is a catastrophic condition where the node in this state does not transmit anything on the bus. How to enter in Bus-Off state? A node enters in this state if any of the two error counters, Transmit Error Counter (TEC) and Receive Error Counter (REC) raises above 255. How to recovery from Bus-Off? A note is permitted to become error-active (no longer bus-off) when its error counters both set to 0 after 128 occurrences of 11 consecutive recessive bits have been monitored on the bus. The MSCAN module implements two ways to recover from the fault, the automatic and the manual. The automatic bus-off recovery method puts the node into the error-active state after monitoring 128 occurrences of 11 consecutive bits on the bus. It's important to note that the CANPHY also reports errors on the bus so, the proper error flags must be clear to assure the correct functionality of the node if CANPHY is being used. The manual bus-off recovery method (which is used in this example) puts the note into the error-active state after both independent events have become true in any order: 128 occurrences of 11 consecutive recessive bits on the CAN bus have been monitored. (Cannot be consecutive). CANMISC[BOHOLD] bit has been cleared by the user. Implementation The project contains a header file called  "common.h" which contains three defines that are used to set the CAN nodes. Just one define must be active per node. NODE0_TX and NODE1_TX are transmitting messages on the CAN bus and the NODE_RX is receiving the messages. #define NODE0_TX #define NODE1_TX #define NODE_RX‍‍‍ ‍ ‍ ‍ All nodes are blinking the green led indicating the communication is stable and no errors have occurred. At this point, you should generate the bus-off condition. A way to generate a bus-off condition is grounding one of the two CAN lines (CAN_High or CAN_Low) which will cause a bus-off condition to the transmitters nodes. When the node is in the bus-off state, the yellow led is toggled. At this point, you should not be any message being transmitted on the bus due to the transmitter node is in bus-off. The bus-off condition is detected by the application in the bus-off interrupt (refers Events.c file) which triggers the yellow led toggling. void CAN0_OnBusOff ( void ) { /* Get CAN bus status */ CAN0_GetError ( & gCANErrpr ) ; /* If bus error is set, inform to the application*/ if ( gCANErrpr . errName . BusOff ) { gBusOffState = PENDING ; } CAN0RFLG_CSCIF = 1 ; // Clear flag } ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ In the main.c file when the node transmitters are selected, there is a routine asking for a push-button event. This event triggers the bus-off recovery request by setting the CANMISC[BOHOLD]. At that point, the 128 occurrences of 11 consecutive recessive bits on the CAN bus should have passed and the green led will toggle again indicating the communication is stable again and no errors have occurred. At this point, you should see the messages on the CAN bus again. /* Read button to recovery from bus off condition*/ if ( PushButton3_GetVal ( ) ) { CAN0_BusOffRecoveryRequest ( ) ; // Request get out of bus off gBusOffState = NONPENDING ; /* Clear bus off LED indicator */ LED_YEL_OFF ; } ‍‍‍‍‍‍‍‍‍‍‍‍‍‍ ‍‍‍‍‍‍‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ Note: The VLG-MC9S12ZVC was used for this example and the push button that must be pressed is SW12. Best Regards, Atzel Collazo
View full article
Abstract The paper describes basic scaling procedure of a six-step BLDC motor control application with focus on S12ZVM MCU devices.  Abstract Introduction BLDC six-step control Speed scaling Timing Commutation periods Speed calculation Application note links Calculation accuracy Real applications Resources Introduction Based on the various questions regarding the BLDC speed calculation, I've decided to write this document to make the scale calculation clear. Please use it for your reference and comment in case there is something to be explained in more details. BLDC six-step control This document is linked with the six-step control of BLDC motors, known for the trapezoidal back-EMF shaped voltage. The key is to create a torque using DC current in two phases while the third phase is not connected. As the rotor is moving, the phases are switched (commutated) to keep the stator flux ahead the rotor flux. The principles are well described in many application notes, such as AN4718 or AN4704. The instant of the commutations can be driven by Hall sensors or by the back-EMF signal monitoring (so-called "sensorless"). For field-oriented control, please refer to the PMSM control discussed in AN5135 or AN5327. Speed scaling It's more benefitial to describe in details the sensorless algorithm over the hall-sensor-based control. However, the approach is almost the same. Timing The motor speed is calculated based on the zero-cross detection of BEMF voltage on a non-active phase. These zero-cross events times are measured by capturing a timer (TIM0CNT) register at the time the ADC routine detects a zero-cross (or when the Hall sensor commutation event occurs). That means, the time is scaled by the timer TIM0 settings. There is no general guidance how to set up the timer. However, the timer should be set to cover some reasonable number of ticks between two commutations (which is linked to the speed precission at high speeds) and should be able to cover two commutations "far away" from each other at very low speeds, without the timer overflow. A good practice would be: at least 100 timer ticks between two commutations maximum 16bit = 65535 ticks between two commutations The same aproach can be followed using the Hall-sensor events. Commutation periods In the application, zero-cross (or hall-sensor) periods are captured with  periodZC_F_PhA, periodZC_R_PhA , etc. or periodZC[6], defined as tU16 (16 bit unsigned). The periods are captured using a timer, as mentioned above. In electric motor theory, we recognize "electrical" and "mechanical" speed. The "electrical" speed is linked with the rotational field. The mechanical speed is connected directly with the rotor speed. The relation between these two speeds is determined by number of poles or pole-pairs: (1)   mechanical speed = electrical speed / number of pole-pairs = electrical speed / ( number of poles / 2 ) In the following text, 3-phase BLDC motor is discussed. Speed calculation To calculate one "electrical" revolution of a motor = 6 commutations (or 6 zero-crosses), all the 6 commutation time periods shall be summed. For that case, the resulting " period6ZC " is defined, formated as tU32 (or unsigned long) to prevent an overflow if all six 16-bit zero-cross periods are summed. If you sum all the 6 zero-cross periods, you'll get the number of timer ticks per single "electric" revolution. That means, if the motor is 2-pole motor ( = 1 pole-pair motor), it would be the time per single "mechanical" revolution of the rotor. In thsi case: (2)   mechanical speed = electrical speed; You can easily get the time per mechanical revolution for higher-pole motor simply by multipling it by number of pole-pairs. (3)   time per mechanical revolution = period6ZC * number of pole-pairs   The period per 6 zero-crosses  " period6ZC "  is calculated within the control loop, usually in the 1 ms timer interrupt routine. Since the speed (rotor frequency) is just an inverted time period, we can use following code line to calculate the actualSpeed: (4) actualSpeed = SPEED_CALC_NUMERATOR / period6ZC; Now, how to read it's scale and what is the SPEED_CALC_NUMERATOR ? Let's assume the " actualSpeed " is tFrac32 (1.31 formated signed 32bit number). It would mean the maximal fraction number is 1.0, which is represented by its integer value 2^31 = 2,147,483,648. Why to use 32-bit number over 16-bit is obvious - since the period6ZC is 32-bit value, the result should be of the same resolution or width. The task is to find the  right  SPEED_CALC_NUMERATOR . Let's consider the S12ZVM device and the timer TIM0 used to capture the zero-cross events times. The prescaler is set to 16 (TIM0TSCR2_PR = 4) and the bus clock is 12.5MHz, the timer tick is 12.5MHz / 16 = 781.25 kHz, in time scale it is 1.28us. Let's assume the maximum mechanical speed of the motor is 10,000 RPM and the motor has 6-pole-pairs. That would give us (5)   (10,000 RPM) / (60 seconds) = 166.67 revolutions per second, (6)    166.67*(6 pole-pairs) = 1000 electrical revolutions per second, so (7)    1000 * (6 commutations) = 6000 commutations/zero-crosses per second. (8)    That would make 1/6000 = 166.67us per one commutation. (9)   Ticks per one period at max speed = 166.67 us / 1.28us = 130.28 With our 1.28us timer, we can catch upto 130 periods at maximal speed. For maximal speed of the motor 10,000 RPM, we can simply rearrange the " actualSpeed " calulation shown in (4) into (13) and (14), assuming that: (10)    actualSpeed  = FRAC32(1.0) = 2,147,483,648 (11)    period6ZC   = 6 periods * 130 = 780 (rounded down, since the value is still an integer) In case of S12ZVM device, it is more convenient to use 16-bit (tFrac16) calculations than 32-bit. Hence, we can do a trick with the scaling to use 32-bit actualSpeed to prevent an overflow use the same 32-bit number as 16-bit number just by scaling it correctly benefit from the 16bit calculation, which is good enough and fast enough at the same time The trick is hidden in the casting of the   actualSpeed   from Frac32 to Frac16: (12)    speedErr = requiredSpeed - (tFrac16) actualSpeed; That means, only the lower 15 bits are considered the speed (assuming the actualSpeed will never exceed 32767 so the 16th "sign" bit will always be zero). For maximum speed and the SPEED_CALC_NUMERATOR determination, the " actualSpeed " should be 32767 (which is the range of signed tFrac16). Equation (4) can be used to calculate the  SPEED_CALC_NUMERATOR as follows: (13)    32767 = SPEED_CALC_NUMERATOR / 780 (14)    SPEED_CALC_NUMERATOR  = 780 * 32,767 = 25,558,260 Thus  #define SPEED_CALC_NUMERATOR 25558260 Using the equation (4), the speed for the minimum period6ZC would be: (15)    actualSpeed   =   SPEED_CALC_NUMERATOR   /   period6ZC   = 25,558,260 / 780 = 32,767; Masking that value by lower 15 bits and casting it to tFrac16 would give us 1.0. Since the speed scale has been determined by the maximum speed of the motor 10,000 RPM, we can calculate the real speed simply by: (16)   RealScaleSpeedRPM  = (tFrac16) actualSpeed   / 32,767 *   MAX_SPEED   =   (tFrac16) actualSpeed   / 32,767 * 10,000. Application note links In the application note AN4704, there are several macro constants used to control the application. These constants should be calculated using following definitions, with a little help of the SPEED_SCALE - floating point representation of the real scale of the speed. #define SPEED_SCALE 10000.0  // Used for correct calculation of the following: #define REQUIRED_RUN_SPEED FRAC16(2000.0/SPEED_SCALE) // 2000 rpm #define MIN_SPEED FRAC16(500.0/SPEED_SCALE) // 500 rpm minimal speed for Down button control (should be min 10% of nominal motor speed) #define MAX_SPEED FRAC16(5000.0/SPEED_SCALE) // 5 krpm maximum speed for Up button control #define SPEED_STEP FRAC16(100.0/SPEED_SCALE) // 100 rpm, Up/Down step for button controls   If the application uses FreeMASTER to display or control, the scales shall be updated in the FreeMASTER project as well. The new FM scales for AN4704 are: Variable name Variable watch settings requiredSpeed Real type transformation: Linear: a =   SPEED_SCALE   = 10,000; b = 0 actualSpeed Signed int, Size = 4 Show as: REAL Bit fields maks with: word (0xffff) Real type transformation: Linear: a =   SPEED_SCALE   / 32767.0 = 0.3051851; b = 0  Calculation accuracy Now, let's have a look on the speed resolution (or accuracy): At the full speed, if one period changes by 1 tick, then you'll get the   period6ZC   from 780 to 781 at max speed, which makes 12.8041 RPM difference. The higher the   SPEED_SCALE   is, the higher the error is. If the assumption would be a change in all of the 6 periods (thus the   period6ZC   would change from 780 to 786), the resulting change to the speed would be 76.336 RPM. That makes the speed error 10,000 RPM +- 76, which is 0.76%. In terms of accuracy, it makes sense to set the maximum speed (or the SPEED_SCALE) to the maximal speed of the application instead of copying some high number from the datasheet of the motor. Well, the max speed of the application should not exceed the max speed of the motor, but it doesn't help if the speed scale is unnecessarily high. Real applications In real applications, the calculated speed (actualSpeed) reflects all the deviations and changes of the period6ZC. Therefore, it is a good practice to do some kind of filtering of the period6ZC, either by averaging or using a low-pass filter. In case of one or more zero-crosses are lost, there should a mechanism to process and detect if the motor is stalled (mechanical speed loses lock with the commutation) or if it is just a disturbance to the signal. The stall detection or the Hall-signal fault/damage detection is one of the challenges towards high quality application. Resources S12ZVM MCU  - NXP main S12ZVM page AutoMCDevKits - NXP Automotive Motor Control Development Solutions AN4718 - 3-Phase BLDC Hall Sensor Application Using S12ZVM AN4704 -  3-phase Sensorless BLDC Motor Control Kit with the S12 MagniV MC9S12ZVM AN5201 - Integrating the LIN driver with BLDC sensorless motor controller In the S12ZVM128 device AN5330 -   Migration Guide for S12ZVM Devices
View full article
Introduction In many old-fashioned automotive motor control systems, PWM command communication is still preferred over LIN or CAN. Even for in-lab application debugging, it is very convenient to use PWM command communication to control the motor placed in a test-bench or in an acoustic or thermal chamber, especially when the BDM debugger or the SCI/RS232 communication is not available. PWM control is usually specified on the OEM level and it is not provided as a public standard. Nevertheless, adjustable software driver can be created to help the PWM command signal to be detected. The following code has been developed for S12ZVM, but it can be easily adopted to fit in whatever device with a timer input capture feature. Hardware specification may be different for many cases and the implementation is the matter of proper design case-by-case and may be a very easy task for a skilled designer. However, software design can be abstracted and reused for different hardware implementation. In order to help you use the PWM control signal, the following description is provided. The example provided is targeting NXP MagniV S12ZVML devices, but may be used along with any device accordingly. The S12ZVML MCU contains LIN physical layer which will be used as PWM input in our case. PWM Signal Specification Since there is no public standard specification on PWM signal, let's target a general case with adjustable parameters. Since the PWM control signal is being replaced by LIN communication, the specification may be based on 5.5V to 18V voltage range with nominal 12V level. PWM frequency varies from 10 Hz to 1 kHz (or more), but it really depends on the requirements of the application, compatibility, etc. Duty-cycle range of the PWM signal might be from 15% to 90% from stand-by to full speed. Hysteresis at low duty-cycle range (between 10 and 15%) prevents the system from periodic on/off switching at the lowest duty-cycle. Duty-cycles outside of this range may be identified as not valid and appropriate action may be taken (e.g. full speed command to an engine cooling fan). The signal definition should consider some specific values to help with the signal reading. Following values are defined: Label Description noSignalLevel No signal detected below this duty cycle noSignalOutput Output on "no signal" detected lowSignalOutput Output on "low signal" detected hystLowSignalOff Low level of the hysteresis. Smaller duty-cycle means "low signal" state, higher duty-cycle enters the hysteresis range (min speed or stand-by) hystLowSignalOn High level of the hysteresis. Smaller duty-cycle means "hysteresis area: min speed or stand-by", higher duty-cycle means "run"  in the linear signal range, with the speed given by the duty-cycle. linearSignalOutputMin Low level of the linear mode linearSignalLevelMax High level of the linear mode Considering normal operation in stand-by mode, the duty-cycle is between noSignalLevel and hystLowSignalOff. In order to add some distortion-proof feature, the duty-cycle can go up to the hystLowSignalOn and the stand-by mode would be still detected. In order to engage the "run" state, the duty-cycle has to exceed the hystLowSignalOn value and the linear area is reached. Corresponding output is calculated to meet the linearSignalOutputMin at the hystLowSignalOn value and linearSignalOutputMax at the linearSignalLevelMax. System keeps the output at linearSignalOutputMax for duty-cycles higher than linearSignalLevelMax. When slowing down, reaching the hystLowSignalOn sets the output to linearSignalOutputMin and keeps this output until the hystLowSignalOff is reached. This way, the hysteresis feature is provided in order to prevent motors from randomly switch on and off in case the PWM signal is noisy. Lowering the duty-cycle below the hystLowSignalOff, zero output is set, which represents the stand- by mode. Duty-cycles below the noSignalLevel are treated as not valid and noSignalOutput is engaged (which can be set to zero or to max, according to the application requirements). Requirements on Timer In order to correctly detect PWM signal frequency and duty-cycle, hardware timer with input capture feature and rising/falling edges detection shall be used. Timing and chaining of multiple timer channels may be needed to increase the frequency range or duty-cycle resolution. Following example will be simplified to use just one 16-bit timer channel (timer module TIM16B4CV3 used in S12ZVML128). The input of the timer shall be routed to an input pin, on which the PWM signal will be sensed. Integrated LIN physical layer module of S12ZVML128 device can be used for signal conditioning since the signal voltage range is up to 18V. In the example, LINPhy module has to be enabled and the LPRXD0 signal is routed to the timer T0 input capture channel 3 by setting "T0IC3RR1-0" of the MODRR2 register to 0b01. Input capture and timer overflow interrupts are used to detect correct or faulty signal. Requirements on Application Software PWM signal detection is called within the Timer Input Capture interrupt. This way, the duty-cycle is calculated immediately. Signal lost event is detected within the Timer overflow interrupt. It is recommended that the detected duty-cycle is filtered by a low-pass filter (moving average or IIR), which is usually called within some real-time interrupt routine, such as PWM reload or ADC end-of-scan interrupt. Reading of the output value can be done anytime within the code, e.g. within a speed loop to read the demanded speed command. Algorithm Description Frequency and Duty-cycle Detection Frequency of PWM signal is given by the time between two consecutive rising edges or two falling edges. The duty-cycle is a ratio between the time of high-level state over the entire period, as indicated below. The key is to capture the time of the rising edge t R1 , change the detection mode to the falling edge to capture the time of the falling edge t F1 , again change the detection mode to rising edge, etc. This detection can be easily done within the input capture timer interrupt. The time values captured are then used to calculate "High" and "Period" values. Frequency and duty-cycle is calculated based on the following equations. The timer settings should follow requirements on frequency range and duty-cycle resolution. It is recommended that the timer settings allow detecting frequencies slightly beyond the required frequency range. Let's consider an example of: Limit Specified frequency limits Detected frequency Detected period Minimal PWM frequency 20 Hz 19.5 Hz 0.051282 s Maximal PWM frequency 1000 Hz 1010 Hz 0.00099 s Based on these limits, Timer settings can be calculated, considering the MCU clock settings and prescalers: For example, if the f bus = 50 MHz and the TimerPrescaler = 50, MinPeriodTicks for MaxDetectedFreq = 1010 Hz equals 495 ticks of the timer. The duty-cycle resolution at 1010 Hz is then 1/495, which is 0.202%. MaxPeriodTicks is key information for the timer settings since it needs to fit in the 16bit range with no overflow. In this case, the number of ticks is 25641 for 19.5Hz, which is suitable for 16-bit range with no issues. If the detected period (number of timer ticks) is outside of this range, the algorithm should go to the noSignalLevel state with defined noSignalOutput. Finally, if the PWM signal is lost or corrupted, timer overflow event occurs and corresponding interrupt is called. Within the interrupt routine, the entire algorithm should be reset to wait for another rising edge, while turned in the noSignalLevel   state with defined   noSignalOutput . Selecting Detected State Based on the PWM signal condition, frequency and duty-cycle detected, the algorithm state is selected. Following states are defined to help users with state identification: State Description Output  PWM_NoSignalDetect PWM signal is not detected or the PWM period is outside of the range noSignalOutput, usually zero or full command (according to the application requirements) PWM_LowSignalDetect PWM signal is detected, the duty-cycle is within the noSignalLevel and hystLowSignalOn or hystLowSignalOff (depends on the hysteresis) lowSignalOutput, usually zero/stand-by PWM_LinearCtrlDetect PWM signal is detected, the duty-cycle is within the hystLowSignalOn and linearSignalLevelMax output = (dutyCycle * linearSignalSlope + linearSignalOffset) << linearSignalNshift, from linearSignalOutputMin to linearSignalOutputMax PWM_HighSignalDetect PWM signal is detected, the duty-cycle is higher than linearSignalLevelMax linearSignalOutputMax Linear Output Calculation Linear output calculation is an easy way of interpolating two endpoints by a linear equation. In order to calculate the coefficients (slope and offset) and to improve the fixed point range, shifting is implemented as well. Algorithm Integration Interfaces The algorithm is designed as a set of static functions with a structure of settings as a parameter to all the interfaces. This way, the same functionality can be used in multiple instances.  /* PWM Control data structure */ typedef struct { pwmControlStatus_t flags ; //Control status bits pwmControlConfig_t config ; //Configuration unsigned int period ; //Modulation period unsigned int dutyCycle ; //dutyCycle unsigned int hystDutyCycle ; //previous hysteresis of duty cycle #ifndef PWM_CONTROL_SW unsigned int overflowCntr ; //timer overflow counter #endif tFrac16 outputValue ; //Output value unsigned int ControlInputClass ; //Classification of the input signal } pwmControl_t ; ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ The input-output characteristics are defined by a set of parameters as discussed earlier using the following structure: typedef struct { /* No signal definition */ tFrac16 noSignalLevel ; //Level of the duty cycle for NoSignal detection tFrac16 noSignalOutput ; //Output when NoSignal is detected /* Low signal definition */ tFrac16 lowSignalOutput ; //Output when LowSignal is detected /* Linear signal definition */ tFrac16 hystLowSignalOff ; //LowSignal-to-NoSignal hysteresis level tFrac16 hystLowSignalOn ; //NoSignal-to-LowSignal hysteresis level tFrac16 linearSignalLevelMax ; //Level of the duty cycle for LinearSignal saturation tFrac16 linearSignalOutputMin ; //Output at hystLowSignalOn tFrac16 linearSignalOutputMax ; //Output at linearSignalLevelMax tFrac16 linearSignalSlope ; // ((linearSignalOutputMax - linearSignalOutputMin)/(hystLowSignalOn - linearSignalLevelMax)))*2^(-linearSignalNshift) tFrac16 linearSignalOffset ; // (linearSignalOutputMax - (linearSignalSlope * linearSignalLevelMax))*2^(-linearSignalNshift) tU16 linearSignalNshift ; // scaling shift of the linear curve /* timing settings */ unsigned int minPeriod ; //minimal period of the signal to be detected, shorter period leads to PWM_NoSignalDetect unsigned int maxPeriod ; //maximal period of the signal to be detected, longer period leads to PWM_NoSignalDetect } pwmControlConfig_t ; ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ More details on the structures and values are described in the header file in attachment. There is a set of exported functions to be integrated into the application. /* Exported function headers */ extern void PWMControlInit ( pwmControl_t * data ) ; //Clears all the internal accumulators and prepars the algorithm for usage extern unsigned int PWMControlUpdate ( unsigned int pin , pwmControl_t * data ) ; //To be called within the timer input capture interrupt, updates the internal values and calculates the PWM frequency and duty-cycle extern tFrac16 PWMControlGetOutputValue ( pwmControl_t * data ) ; //To be called where necessary by the application to get the output value extern void PWMControlTimerOverflow ( pwmControl_t * data ) ; ‍‍‍‍‍ //To be called within the timer overflow interrupt to indicate that the signal is lost‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ ‍ ‍ ‍ ‍ ‍ Integration The PWM control source and header files should be included in the project to be compiled. The project uses NXP Automotive Math and Motor Control Library Set (AMMCLib version v1.1.17 or higher), which needs to be added to the project as well. For more information, please visit https://www.nxp.com/support/developer-resources/run-time-software/automotive-software-and-tools/automotive-math-and-motor-control-library-set:AUTOMATH_MCL?lang=en&lang_cd=en& The next step is to include the header file in the main application source code: #include "pwm_control.h" ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ ‍ In order to provide necessary settings and to handle the output, the following global variables are recommended: // PWM Control data pwmControl_t pwmControlData ; //PWM input control data structure static tBool pwmControlEnabled = false ; // Off by default‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ ‍ ‍ ‍ Device initialization should include clock settings, timer, and input pin routing settings accordingly. For S12ZVML device, the configuration of TIM, PIM and LIN modules is following: Within the initialization part of the application, the following code should be placed to initialize the PWM control. Please consider the values as an example only.  // PWM control initial settings pwmControlData . config . minPeriod = 495 ; //Period of the max frequency pwmControlData . config . maxPeriod = 25641 ; //Period of the min frequency pwmControlData . config . noSignalLevel = FRAC16 ( 0.05 ) ; //No signal detected below this duty cycle pwmControlData . config . noSignalOutput = FRAC16 ( 0 ) ; //Output on ""no signal"" detected pwmControlData . config . lowSignalOutput = FRAC16 ( 0 ) ; //Output on ""low signal"" detected pwmControlData . config . hystLowSignalOff = FRAC16 ( 0.1 ) ; //Low level of the hysteresis. Smaller duty cycle means ""low signal"", higher duty cycle means ""switch on"" pwmControlData . config . hystLowSignalOn = FRAC16 ( 0.15 ) ; //High level of the hysteresis. Smaller duty cycle means ""min speed or off"", higher duty cycle means ""switch on and linear"" pwmControlData . config . linearSignalLevelMax = FRAC16 ( 0.85 ) ; //High level of the linear mode pwmControlData . config . linearSignalOutputMin = FRAC16 ( 0.116666666666667 ) ; //Output within the hysteresis mode pwmControlData . config . linearSignalOutputMax = FRAC16 ( 0.833333333333333 ) ; //Output at the linearSignalLevelMax pwmControlData . config . linearSignalSlope = FRAC16 ( 0.511904761904762 ) ; //Linear signal slope = (linearSignalOutputMax - linearSignalOutputMin) / (linearSignalLevelMax - hystLowSignalOn) * 2^(-linearSignalNshift) pwmControlData . config . linearSignalOffset = FRAC16 ( - 0.018452380952381 ) ; //Linear signal offset = (linearSignalOutputMin - (linearSignalOutputMax - linearSignalOutputMin) / (linearSignalLevelMax - hystLowSignalOn) * hystLowSignalOn) * 2^(-linearSignalNshift) pwmControlData . config . linearSignalNshift = 1 ; //Linear signal shift pwmControlData . config . f16pwmInputMA . u16NSamples = 5 ; //Moving average filter settings 2^n samples PWMControlInit ( & pwmControlData ) ; ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ The configuration can be generated using an Excel sheet in the attachment. Content of the cell "D34" can be copied-pasted in the code. Name of the structure can be changed in "H1" cell. Orange-colored cells are customizable, while grey-colored cells use formulas to calculate output. Timer input capture interrupt routine should call the PWM control "Update" routine and switch the input capture mode between the rising edge and falling edge detection. In the case of S12ZVML device, the timer interrupt example follows: INTERRUPT void TIM0chan3_ISR ( void ) { // Read PWM input control pin and update status PWMControlUpdate ( TIM0TC3 , & pwmControlData ) ; // Read the PWM Control output pwmControlData . outputValue = PWMControlGetOutputValue ( & pwmControlData ) ; // Toggle edge detection if ( pwmControlData . flags . risingEdge ) { TIM0TCTL4_EDG3A = 1 ; TIM0TCTL4_EDG3B = 0 ; } if ( pwmControlData . flags . fallingEdge ) { TIM0TCTL4_EDG3A = 0 ; TIM0TCTL4_EDG3B = 1 ; } // Clear interrupt flag TIM0TFLG1 = TIM0TFLG1_C3F_MASK ; //TIM0TFLG1_C0F_MASK | TIM0TFLG1_C1F_MASK | TIM0TFLG1_C2F_MASK | TIM0TFLG1_C3F_MASK; } ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ Timer overflow interrupt routine shall implement PWM control "Overflow" handler as follows (again, for S12ZVML device). Output value updater should be called as well to update the output value. INTERRUPT void TIM0overflow_ISR ( void ) { // Detect PWM input control period overflow (ultra low frequencies PWMControlTimerOverflow ( & pwmControlData ) ; pwmControlData . outputValue = PWMControlGetOutputValue ( & pwmControlData ) ; // Clear interrupt flag TIM0TFLG2 = TIM0TFLG2_TOF_MASK ; } ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ Finally, within the application task, the PWM control data can be accessed and used in the application. For example, based on the ControlInputClass, the input signal processing may be enabled or disabled and the output value can be used as the required speed value of an engine cooling fan. [ Application Task ] { // ... // PWM Control // If no signal is detected, enable manual switch (using FreeMASTER) if ( pwmControlData . ControlInputClass == PWM_NoSignalDetect ) { if ( pwmControlEnabled == true ) { cntrState . usrControl . switchAppOnOff = 0 ; pwmControlEnabled = false ; } } else { pwmControlEnabled = true ; } // If PWM input control enabled, update the demanded speed if ( pwmControlEnabled ) { //If the linear or high signal is detected, switch the app on if ( pwmControlData . ControlInputClass >= PWM_LinearCtrlDetect ) { cntrState . usrControl . switchAppOnOff = 1 ; //Store the demanded speed drvFOC . pospeControl . wRotElReq = pwmControlData . outputValue ; } //else switch off the app... else { cntrState . usrControl . switchAppOnOff = 0 ; //...and if a fault is indicated, clear the fault if ( cntrState . state == fault ) { cntrState . usrControl . switchFaultClear = true ; } } } // ... } ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ Example code Example code is provided for S12ZVML-MINIKIT. The code is a modified devkit SW, which is available here (and related AN5327 here). The FreeMASTER project file is included with added PWM Control subblock. If there is no PWM signal detected, the application can be controlled via FreeMASTER on/off button. If the PWM signal is detected (even with a duty-cycle below the minimal value), the application listens and reacts as defined by the signal definition. Conclusion PWM control is still being used as one of the control signals to control auxiliary electric drives in automotive. Even if being replaced by LIN or CAN communication, there are still facilities which can benefit from software drivers enabling such a feature. In this document, a software driver is provided to be integrated within the application. The example is provided for S12ZVML devices, however, it can be easily adopted to any device which meets the hardware requirements necessary for such PWM control signal detection.
View full article
Hello, Devkit-S12XE includes a bug on the PORT J2. This document shows the correct connection. The pin designation in the schematic, QSG, and pin markings on the board does not correspond to the connection on the board. Schematic: https://www.nxp.com/downloads/en/schematics/DEVKIT-S12XE-SCH.pdf  QSG: https://www.nxp.com/docs/en/quick-reference-guide/DEVKIT-S12XE-QSG.pdf  Pin markings on the board: In particular, these are the following pin numbers of PORT J2 where the bug was found: 16, 17, 18, 19 The real connection is as follows: I hope it helps, Best regards, Diana
View full article
The S12Z devices contain unmaskable machine exception interrupt for severe system problems. The Memory Map Control module (MMC) generates this exception in the case of illegal memory access and uncorrectable ECC errors. The MMCECn register is set to a non-zero value if an S12ZCPU access violation or an uncorrectable ECC error has occurred. At the same time when this register is set to a non-zero value, access information is captured in the MMCPCn (program counter) and MMCCCRn (CCR U, X and I bits) registers. The MMCECn registers are cleared by writing the value 0xFFFF. Unfortunately, the exact address with corrupted data isn’t stored in any user-accessible register and this makes the debugging more difficult.   In the case of reading memory with an uncorrectable ECC error, the MMC causes jump to the address in the Machine Exception vector as soon as the current instruction finishes execution. This may be used in workaround code for detection of the exact address with corrupted data. See attached example code. Note: The code detects only the first address of the phrase with uncorrectable corrupted data. The solution for detecting multiple ECC issues isn't included.     The execution of a machine exception code isn’t straightforward in this case. Please read the simplified procedure: The reading of uncorrectable corrupted data (double bit ECC error) will invoke machine exception. The ma_counter variable is incremented to 1. The MMCEC register is checked for detection of machine exception source. If ECC at EEPROM or P-Flash is detected as a machine exception source, the sequential reading of appropriate memory starts. Note: Since the P-FLASH is protected by 39-Bit ECC Scheme, we should read at leats single word(byte) from every aligned 32bit phrases. The global variable add contains a current reading address. When CPU read the uncorrectable corrupted data again, the MMC causes jump to the address in the Machine Exception vector again. The ma_counter variable is incremented to 2. When ma_counter is 2, we may store add variable address with corrupted data, clear ma_counter and clear pending flags in MMCEC register. Application project-specific user code for machine exception case may be applied (signalization, repair,…) Please be aware that no information is stored on the stack during entering machine exception handler (missing return address). So, default RTI instruction on end of routine cannot be used for returning to the application code. We must end the machine exception routine by MCU reset or jump to some known code entry point or by an endless loop.  This code is only a simple example code and does not cover all conditions. More details regarding simulating ECC issue at EEPROM and P-Flash: S12Z - Simulating ECC errors at EEPROM by cumulative write  https://community.nxp.com/docs/DOC-334327 
View full article
I would like to mention some of the many programming/debugging possibilities by this document. Possibilities for production We have no solution for mass production such as stand-alone programmers, you have to turn to the third party products. CodeWarrior (CW) Simulator/Debugger tool Hiwave: After entering into the debug mode in the CW, we can see the "True-Time Simulator & Real-Time Debugger" window which is  Hiwave. Also, the Hiwave can be launched by hiwave.exe independently from the CodeWarrior which is located in the Prog folder in the CW install directory: \Prog\hiwave.exe However, we need to use it together with PEmicro BDM. PROG12Z- Flash Programmer software: PROG12Z | 68HC(S)12(X) Flash/EEPROM Programmer Software | PEmicro  Also, includes the command-line version of the programmer software - CPROG12Z. But we need to use it together with PEmicro BDM. USB Multilink Universal: USB-ML-UNIVERSAL Compatible with ARM devices from many manufacturers as well as NXP's Kinetis, LPC, S32, ColdFire V1/+V1, ColdFire V2-4, MPC55xx/56xx/57xx, HCS08, RS08, HC(S)12(X), S12Z. For more information look at the link: MULTILINK | Debug Probe | PEmicro 1 Stand-alone programmer, test & debug interface: The CYCLONE_UNIVERSAL  supports a wide variety of ARM Cortex devices from many manufacturers as well many non-Arm based devices including from NXP (S32, Qorivva (MPC5xxx), MPC5xx/8xx, S12Z, RS08, S08, HC08, HC(S)12(X), Coldfire, Kinetis, LPC),  Note: The Cyclone Pro is no available. It has been replaced by the Cyclone Universal and Cyclone Universal FX production programmers. These programmers support all of the devices supported by Cyclone PRO CYCLONE | In-System Flash Programmers | PEmicro  Or LFBDMPGMR: Lead-Free BDM Flash Programmer for S08, S12x|NXP  As a low-cost solution can be used: Open Source BDM interface: OSBDM  Or USBDM: USBDM Debugger interface for Freescale RS08,HCS08,HCS12,Coldfire and ARM-Kinetis Devices.  In the chapter Device Characteristics and links to documentation, can be found supported devices by USBDM and useful links for the USBDM devices where are described, for example, compatible IDEs and other useful information.   And one of the advanced tool TRACE32: LAUTERBACH DEVELOPMENT TOOLS 
View full article
Tested on: DEVKIT-S12ZVC MCU: S12ZVC192 Development tool: CodeWarrior 10.7 This example shows ACMP - analog comparator,  which compares voltage from potentiometer and voltage from DAC. DAC is set at 2.5V and uses the positive input of the comparator. Potentiometer uses the negative input in the range of 0V - 5V. When the potentiometer is moved, the output from ACMP will be changed.  If the voltage at the non-inverting (positive) input > the voltage at the inverting (negative) input, the output result is in the logic level 1 and the red LED is on.
View full article
The calculator was created for the MagniV devices such as S12ZVL, S12ZVC, S12ZVMB, S12ZVM, S12ZVH, and S12VR qualified under junction temperature Tj <= 150°C. It shows the settings of PLL registers as SYNR, REVDIV, and POSTDIV. The description of these registers can be found in the reference manual of each device.  The Oscillator and Bus clock frequency can be selected from the list or can be written manually. The values will be calculated by "Enter" or "Calculate" button. The MagniVPLLCalc.exe is attached.
View full article
The package contains of AN5327_SW ported to S12ZVML-MINIBRD hardware. Just minor changes are introduced, such as removing a button control, moving the LED light to another pin and using internal oscillator. This is just a working version, it is NOT an official release!!! AN5327_SW_CW11_MINIBRD.ZIP CodeWarrior 11.0 and AMMCLib 1.1.13 or higher is required to run this example. If you are not sure about the AMMCLib version, please download the general AN5327_SW from the www.nxp.com/automcdevkits first, install it and then unzip and use the example above.
View full article
Application Note Link SW  SW2 SW3 AN12086 Simple Serial Bootloader for S12Z AN12086 SW AN5330 Migration Guide for S12ZVM Devices AN5330 AN5327 Three-phase Sensorless Single-Shunt Current-Sensing PMSM Motor Control Application with MagniV MC9S12ZVM AN5327 SW AN5264 Emulating I2C Master Mode AN5264 SW AN5207 Hardware Design Guidelines for S12ZVM Microcontrollers AN5207 AN5190 S12ZVM Derivatives Configuring PMF Module AN5190 SW AN5168 Using the ADC Module in S12ZVM AN5168 SW AN5135 3-phase Sensorless PMSM Motor Control Kit with MagniV MC9S12ZVM AN5135 SW AN5122 Using Freescale’s LIN Driver with the MagniV Family AN5122 SW AN5084 Hardware Design Guidelines for S12ZVL Microcontrollers AN5084 AN5082 MagniV in 24V Applications AN5082 AN4975 Using MSCAN on the MagniV Family AN4975 SW AN4912 Tuning 3-Phase PMSM Sensorless Control Application Using MCAT Tool AN4912 AN4867 Hardware Design Guide lines for S12ZVC AN4867 AN4852 Using the SENT Transmitter Module in S12ZVC Devices AN4852 SW AN4842 S12ZVL LIN Enabled RGB LED Lighting Application AN4842 SW AN4841 S12ZVL LIN Enabled Ultrasonic Distance Measurement AN4841 SW AN4731 Understanding Injection Current on Freescale Automotive Microcontrollers AN4731 AN4723 S12Z MagniV Bootloader AN4723 SW AN4722 Real Time Counter (RTC) on the S12ZVH Family AN4722 AN4721 S12ZVH: Hardware Design Guidelines AN4721 AN4718 3-Phase BLDC Hall Sensor Application Using S12ZVM AN4718 SW AN4704 3-phase Sensorless BLDC Motor Control Kit with the S12 MagniV MC9S12ZVM AN4704 AN4680 PMSM Electrical Parameters Measurement AN4680 AN4643 S12VR - Hardware Design Guidelines AN4643 AN4642 Motor Control Application Tuning (MCAT) Tool for 3-Phase PMSM AN4642 AN4618 Sensorless BLDC Motor Control Using S12G240 Based on HVAC Platform AN4618 AN4617 HMI Design Using HVAC Platform AN4617 AN4616 Flap Motor Control Based On HVAC Platform AN4616 AN4558 3-phase Sensorless BLDC Motor Control Development Kit with MC9S12G128 MCU AN4558 SW AN4540 Comparison Between the MC9S12VR and MM912_634 AN4540 AN4506 Software Analysis in CodeWarrior for MCU AN4506 AN4505 Safety Considerations S12G-Family AN4505 AN4483 Emulated EEPROM Routines for the S12P Family AN4483 SW AN4455 MC9S12G128_A240 Demonstration Lab Training AN4455 SW AN4448 MC9S12VR Family Demonstration Lab Training AN4448 SW AN4418 MC9S12G64 Demonstration Lab Training AN4418 SW AN4388 Quad Flat Package (QFP) AN4388 AN4364 Glucose Meter Fundamentals and Design AN4364 SW AN4320 Introduction to the 16-bit Tower Boards Using the MC9S12GN32 AN4320 AN4303 Light control and diagnostics using a MC9S12GN32 MCU AN4303 SW AN4302 Introduction to the S12G Family EEPROM AN4302 SW AN4283 Migrating Software Applications from the S12 (XEXSP) and S08 to S12G Microcontrollers AN4283 AN4268 Three-phase Sensorless BLDC Motor Control Kit with the Qorivva MPC5604P AN4268 AN4263 Modification of the eGUI (D4D) Driver for char Displays (D4CD) AN4263 SW AN4258 Serial Bootloader for S12(X) Microcontrollers Based on 180 nm Technology AN4258 SW AN4236 MC9S12XHY-Family Demonstration Lab Training AN4236 SW AN4143 Migrating from the 16-bit S12XE to 32-bit MPC5604B Family of Microcontrollers AN4143 AN4058 BLDC Motor Control with Hall Effect Sensors Using the 9S08MP AN4058 AN4024 High Speed Stall Detection on the S12HY Family AN4024 SW AN4021 MC9S12HY-Family Demonstration Lab Training AN4021 SW AN3961 EEPROM Emulation for the MC9S12XS and MC9S12P Families Using AN2302 as a Reference AN3961 SW AN3937 MC9S12P-Family Demonstration Lab Training AN3937 SW AN3936 How to install and run Classic CodeWarrior products on 64-bit Windows 7 PC AN3936 AN3832 Sensorless BLDC Motor Control Using MC9S08AC16 AN3832 SW AN3784 Understanding the Memory Scheme in the S12(X) Architecture AN3784 AN3743 Emulated EEPROM Quick Start Guide AN3743 SW AN3624 S12X Temperature Sensor AN3624 AN3622 Comparison of the S12XS CRG Module with S12P CPMU Module AN3622 AN3613 Using the MC9S12XS Family as a Development Platform for MC9S12P Family AN3613 AN3589 Optically-Isolated Multilink BDM Interface for the S08-S12 Microcontrollers AN3589 AN3555 Investigating XGATE Software Errors AN3555 AN3510 S12HZ and S12XHZ Family Compatibility AN3510 AN3497 S12XS Family Compatibility Considerations AN3497 AN3493 TFT display AN3493 SW AN3490 Overview of the MC9S12XE Emulated EEPROM AN3490 AN3469 S12 and S12XE Family Compatibility AN3469 AN3458 Debugging XGATE Code AN3458 AN3419 System Integrity Techniques for the S12XE AN3419 AN3391 LFAE Bootloader Example and Interface for use with AN2546 (CAN bootloader for S12XE) AN3391 SW AN3333 Implementing CAN and LIN Signal Level Gateway AN3333 SW AN3330 Introduction to the Stepper Stall Detector Module AN3330 SW AN3328 HCS12XD Family Compatibility Considerations AN3328 AN3327 Using the S12XE-Family as a Development Platform for the S12XS-Family AN3327 AN3300 General Soldering Temperature Process Guidelines AN3300 AN3298 Solder Joint Temperature and Package Peak Temperature AN3298 AN3292 XGATE Library SCI Emulation AN3292 SW AN3291 How to Use IIC Module on M68HC08, HCS08, and HCS12 MCUs AN3291 AN3289 Low-Power Techniques for the S12X Family AN3289 AN3275 S12 All-Access Bootloader for the HCS12 Microcontroller Family AN3275 SW AN3262 Designing Hardware for the HCS12X D-Family AN3262 AN3257 Meeting IEC 60730 Class B Compliance with the MC9S08AW60 AN3257 AN3253 XGATE Library Load Measurement AN3253 SW AN3242 S12XD and S12XE Family Compatibility AN3242 AN3226 XGATE Library ATD Average AN3226 SW AN3225 XGATE Library PWM Driver AN3225 SW AN3224 Tutorial Introducing the XGATE Module to Consumer and Industrial Application Developers AN3224 AN3219 XGATE Library TN STN LCD Driver AN3219 SW AN3208 Crystal guide AN3208 AN3153 USB - HID - ZSTAR AN3153 SW AN3145 XGATE Library Using the Freescale XGATE Software Library AN3145 AN3144 Using XGATE to Implement a Simple Buffered SCI AN3144 SW AN3034 Using MSCAN on the HCS12 Family AN3034 SW AN3031 Temperature Sensor for the HCS08 Microcontroller Family AN3031 SW AN3015 Using the XGATE for Manchester Decoding AN3015 SW AN2974 Quick Start for Beginners to Drive a Stepper Motor AN2974 AN2881 Mapping Memory Resources on HCS12 Microcontrollers AN2881 AN2880 Using Backdoor Access Capability to Unsecure HCS12 MCUs AN2880 SW AN2836 Web Server Development with MC9S12NE64 and OpenTCP AN2836 SW SW2 SW3 AN2764 Improving the Transient Immunity Performance of MCU-based Applications AN2764 AN2759 Implementing an Ethernet Interface with the MC9S12NE64 AN2759 SW AN2734 HCS12X Family Memory Organization AN2734 AN2732 Using XGATE to Implement LIN Communication on HCS12X AN2732 AN2727 Designing Hardware for the HCS12 D-Family AN2727 AN2726 XGATE Library CAN Driver AN2726 SW AN2724 Using the HCS12X PIT as a 24-bit Elapsed Timer AN2724 AN2720 A Utility for Programming Single FLASH Array HCS12 MCUs, with Minimum RAM Overhead AN2720 SW SW2 AN2708 An Introduction to the External Bus Interface on the HCS12X AN2708 AN2700 Basic Web Server Development with MC9S12NE64 and CMX-MicroNetT TCP-IP Stack AN2700 SW AN2692 MC9S12NE64 Integrated Ethernet Controller AN2692 AN2685 How to Configure and Use the XGATE on S12X Devices AN2685 AN2678 Using the HCS12 NVM Standard Software Drivers with the Cosmic Compiler AN2678 AN2624 Basic Web Server Development with the CMX-MicroNet TCP-IP Stack AN2624 SW AN2617 A Software Piority Interrupt Scheme on HCS12 Microcontrollers AN2617 SW AN2615 HCS12 and S12X Family Compatibility AN2615 AN2612 PWM Generation Using HCS12 Timer Channels AN2612 SW AN2597 Using the MC9S12E128 to Implement an IrDA Interface AN2597 SW AN2573 LINkits LIN Evaluation Boards AN2573 AN2554 Clearing and Disabling Interrupt Flags AN2554 AN2552 Configuring the System and Peripheral Clocks in the MC9C12E128 AN2552 SW AN2548 Serial Monitor Program for HCS12 MCUs AN2548 SW SW2 AN2546 HCS12 Load RAM and Execute Bootloader User Guide AN2546 SW AN2485 HCS12 Software Stationery AN2485 SW AN2461 Low Power Management using HCS12 and SBC devices AN2461 AN2438 ADC Definitions and Specifications AN2438 AN2434 Input-Output Pin Drivers on HCS12 Family MCUs AN2434 AN2433 5V to 3V Design Considerations AN2433 AN2429 Interfacing to the HCS12 ATD Module AN2429 AN2428 An Overview of the HCS12 ATD Module AN2428 AN2408 Examples of HCS12 External Bus Design AN2408 AN2400 HCS12 NVM Guidelines AN2400 AN2396 Servo Motor Control Application on a LIN AN2396 SW AN2342 Opto Isolation Circuits For In Circuit Debugging of 68HC9(S)12 and 68HC908 Microcontrollers AN2342 AN2321 Designing for Board Level Electromagnetic Compatibility AN2321 AN2318 Using the I2C Bus with HCS12 Microcontrollers AN2318 SW AN2304 Implementation of a UDP-IP (User Datagram Protocol) Stack on HCS12 Microcontrollers AN2304 SW AN2302 EEPROM Emulation for the MC9S12C32 AN2302 SW AN2295 Developer's Serial Bootloader for M68HC08 abd HCS08 MCUs AN2295 SW AN2287 HCS12 External Bus Design AN2287 AN2283 Scalable Controller Area Network (MSCAN) Interrupts AN2283 AN2263 PC Master Software: Creation of Advanced Control Pages AN2263 AN2255 MSCAN Low-Power Applications AN2255 AN2250 Audio Reproduction on HCS12 Microcontrollers AN2250 SW SW2 SW3 AN2221 MI Bus Software Driver for the MC9S12DP256 AN2221 SW AN2216 MC9S12DP256 Software Development Using Metrowerk's Codewarrior AN2216 AN2213 Using Cosmic Software's M68HC12 Compiler for MC9S12DP256 Software Development AN2213 AN2204 Fast NVM Programming for the MC9S12DP256 AN2204 SW AN2201 Low Battery Cranking Pulse in Automotive Applications AN2201 AN2189 Using the Clock Generation Module on the HC12 D Family AN2189 AN2153 A Serial Bootloader for reprogramming the MC9S12DP256 FLASH Memory AN2153 SW AN2104 Using Background Debug Mode for the M68HC12 Family AN2104 AN2103 Local Interconnect Network (LIN) Demonstration AN2103 AN2011 The MSCAN on the MC9S12DP256 compared with the MSCAN on the HC12 family AN2011 AN1954 MPXY8000 Series Tire Pressure Monitoring Sensor AN1954 AN1837 Non-Volatile Memory Technology Overview AN1837 AN1798 CAN Bit Timing Requirements AN1798 AN1783 Determining MCU Oscillator Start-up Parameters AN1783 AN1775 Expanding Digital Input with an AD converter AN1775 AN1771 Precision Sine-Wave Tone Synthesis Using 8-Bit MCUs AN1771 AN1716 Using M68HC12 Indexed Indirect Addressing AN1716 AN1705 Noise Reduction Techniques for Microcontroller-Based Systems AN1705 AN1284 Transporting M68HC11 Code to M68HC12 Devices AN1284 AN1280 Using and Extending D-Bug12 Routines AN1280 AN1263 System Design and Layout Techniques with Single-Chip Microcontrollers AN1263 AN1259 System Design and Layout Techniques for Noise Reduction in MCU-Based Systems AN1259 AN1058 Reducing A_D Errors in Microcontroller Applications AN1058 AN1051 Transmission Line Effects in PCB Applications AN1051 AN1050 Designing for Electromagnetic Compatibility (EMC) with HCMOS Microcontrollers AN1050 AN5389 S12Z MagniV LIN Bootloader AN5389 SW AN11967 S12ZVM Family in 48 V Applications AN11967
View full article
******************************************************************************** Detailed Description: TIM0_Ch2 OC triggers ADC measurements on AN2 (DEVKIT S12ZVL32, potentiometer) every 50ms. ADC interrupt updates duty-cycle (0-100%) of 3 PWM signals that are shifted by 90°. ADC can work either in Trigger or Restart mode. PWM signals are routed to RGB LEDs (DEVKIT S12ZVL32). --------------------------------------------------------------------------------------------- Test HW: DEVKIT-S12ZVL32 MCU: S12ZVL32 Debugger: CW11 Target: internal_FLASH ********************************************************************************
View full article
How to get device ID and write program once field without programming application to the S12Z device in the CodeWarrior (Eclipse).   Even the datasheet does not present the device ID it can be read at address 0x1FC000. The device ID is size of 8 bytes from 1F_C000 to 1F_C007. The meaning of the field is confidential information. Of course, other "reserved" fields on higher addresses can also be read but their meaning is also confidential. The ID is not presented in the documentation because it has reason for company only. However, some users require unique identification of the device. It is possible to use this number. In order to read the ID, it is enough to create simple project in the CodeWarrior and connect to the device without programming it and run “mem” command in the debug shell window. If you do not want to remember address ranges, then it is better to prepare command file and execute it.   Of course, we can also simply use memory window.   It is a different story if we want also to see program once field. In this case we have to execute a set of commands to get it. As an example of command file which can be executed to get device ID and program the program once field I present two command files. They can be executed in the debugger window – see and test attached project. They are AAA_Read_Device_ID_And_OTPROM.cmd  and AAA_ProgramOnceField.cmd. The project which also presents reading and writing program once field is not relevant but should be created for the device we want to play with. It is not required to be code (simple code, enough to use what is generated by wizard) loaded into the MCU’s memory. However, necessary is the debugger is connected to a memory. Because of this it is enough to set:   …. And press debug   In the debug enable “Debugger Shell”:   Before continuing please modify flash clock setup in both files to value suitable for programming on the basis of the oscclk you use. In the files search for lines    Write into debugger shell command which runs the AAA_Read_Device_ID_And_OTPROM.cmd: source "c:\D\CODING & SW\ECLIPSE\S12ZVMC-FLASH-WRITEONCEFIELD-CW106\AAA_Read_Device_ID_And_OTPROM.cmd" (it is possible you have different path to the file…please change it)   The command will execute and shows: Device ID And Program field phrase 0. If you want to see another phrase you should modify AAA_Read_Device_ID_And_OTPROM.cmd line set PHRASE 1. Change 1 to the phrase you want to see and run the command presented above “source …..” again. It is enough to press arrow up on the keyboard to see and use previous commands.   In order to program selected field use and run command “source” with the file: AAA_ProgramOnceField.cmd source "c:\D\CODING & SW\ECLIPSE\S12ZVMC-FLASH-WRITEONCEFIELD-CW106\AAA_ProgramOnceField.cmd"   The same note as previosly, the path you have could be different so adjust it. The same line as in previous file should be changed to select the phrase you want to program. As a result, you will see programming algorithm and also read back of the field, example of output: %>source "c:\D\CODING & SW\ECLIPSE\S12ZVMC-FLASH-WRITEONC EFIELD-CW106\AAA_ProgramOnceField .cmd" ############################ Programming Field = 2 ############################ cmdwin::mem 0x0386 %x = 0x30 cmdwin::wait 1000 cmdwin::mem 0x0382 %x = 0x05 cmdwin::mem 0x038C %x = 0x07 cmdwin::mem 0x038D %x = 0x00 cmdwin::mem 0x038E %x = 0x00 cmdwin::mem 0x038F %x = 2 cmdwin::mem 0x0390 %x = 0xA2 cmdwin::mem 0x0391 %x = 0xB2 cmdwin::mem 0x0392 %x = 0xC2 cmdwin::mem 0x0393 %x = 0xD2 cmdwin::mem 0x0394 %x = 0xE2 cmdwin::mem 0x0395 %x = 0xF2 cmdwin::mem 0x0396 %x = 0xA3 cmdwin::mem 0x0397 %x = 0xB3 cmdwin::mem 0x0386 %x = 0x80 cmdwin::wait 1000 ############################ Read back Programmed Field = 2 ############################ cmdwin::mem 0x0386 %x = 0x30 cmdwin::wait 1000 cmdwin::mem 0x0382 %x = 0x01 cmdwin::mem 0x038C %x = 0x04 cmdwin::mem 0x038D %x = 0x00 cmdwin::mem 0x038E %x = 0x00 cmdwin::mem 0x038F %x = 2 cmdwin::mem 0x0386 %x = 0x80 cmdwin::wait 1000 cmdwin::mem 0x0390 8      390  $a2 $b2 $c2 $d2 $e2 $f2  $a3 $b3    . . . . . . . .    Now the question, where to find commands to be able to prepare such a command files, can be asked. 1) The first information source is the CodeWarrior help. For example, search for keyword DW and it could find a command list. 2) Tcl Reference Manual   3) http://www.tcl.tk/     Finally, in the attached project can be seen also approach how to write program once field by SW. Of course, mentioned cmd files are also part of the project.
View full article
CAN Standard ID, CAN Extended ID memories refreshment   A human is a creature forgetting things, procedures and a lot of useful principles in a very short time especially when it often jumps between different projects. I also solve the CAN interface filter setup issues occasionally and even I did it a lot of times I always have to think how to set the filter easily and fast. Because of this, on the basis of last experience, I created an excel sheet this year which provides me an easy return to my CAN filter memories. I am not sure it will be helpful for everyone as it is helpful for me, however, I am sharing..... Each of us has different thinking and ways of visualization so any idea for improvement is appreciated in advance.      
View full article
CAN setup calculator for S12(X) and MagniV devices.   I would like to share my CAN setup calculator I've been using for a few years. I’ll be glad if anyone who sees any discrepancy in calculation or values would contact me with comment or idea for improvement. Even I think the sheet is intuitive I’ll provide a few notes. 1) Entering input values a) fosc – defines frequency of input clocks for CAN peripheral. It can be either oscillator clock or bus clock in dependence what is used in application. Note: Because of CAN clock requirements I suggest to use oscillator clock as a source clock for CAN peripheral to meet oscillator precision parameter. The recommendation is based on the fact of that the PLL is usually used for bus clock generation and the PLL unlock parameter is usually out of clock specification. Especially un-lock parameter which can be observed and processed by PLL lock interrupt. Only for example, S12ZVC defines:   b) Physical Interface Tx+ Rx propagation delay – The parameter can be calculated from the data presented in the data sheet for given CAN transceiver. A few values are presented in the top of the sheet.   c) Required sample point - A good general rule is to set the sample point above 80%. Based on the experiences of the automotive industry, the selected sample point should be near the 80% value.   2) Output values   The results field show calculations for all combinations. The simplification, I use, is the max SJW is always used.   Lines containing correct values for bitrate setup are highlighted with orange color. The only thing which is not checked is sample point. You should check calculated “Sample point calculated” whether it corresponds to your requirements. There are two correct values of CANBTR0 and CANBTR1 for required bitrate but the bottom orange line meets exactly our requirement for sample point.
View full article
This application note was already officially released. Please, download it from: AN12086 Simple Serial Bootloader for S12Z AN12086SW software package    1.  Introduction This application note covers the operation and use of a simple serial Bootloader for the S12Z microcontroller families. The Bootloader can be a convenient way to support programming during production or “in-system”, where support for the dedicated HCS12 Background Debug interface (BDM) may not be available. Users must pre-program the S12Z MCU with the Bootloader during production or at a programming vendor. The Bootloader should reside in the MCU for further use. This Bootloader implementation allows User Application software to be downloaded into the MCU flash and EEPROM memory using the SCI serial interface. The Bootloader may be also configured for self-update similar way as a User Application software update. This Bootloader is originally based on AN4258 Serial Bootloader for S12(X) Microcontrollers Based on 180 nm Technology with several modifications and improvements. The Bootloader described in this document is only an example and comes with no guarantees and no direct support.   2. Bootloader Overview The software architecture consists of two independent software projects: Bootloader Project User Application Project For avoiding compatibility issues between these projects, the minimum interface points must be kept. The switching between Bootloader and User Application codes is managed through MCU reset. So, the Bootloader and application are not limited by write-once registers. The Bootloader Project itself contain small user-defined dispatcher code which is executed directly after MCU reset and decide whether Bootloader or User Application will be executed as next. Figure 1 Software Architecture 2.1.     Hardware Compatibility The Bootloader is written for S12Z derivatives (S12ZVM, S12ZVMB, S12ZVMA, S12ZVC, S12ZVL, S12ZVH, S12ZVHY and S12ZVFP). The Bootloader for S12Z microcontrollers is not optimized for the smallest derivatives. Therefore, S12ZVL8 derivative (only 512B RAM) is not supported and only some of derivatives (with 4kB or more RAM) supports Bootloader self-update feature (rewritable).   2.2.     Dispatcher code The Dispatcher code is executed right after MCU reset. It just temporary initializes stack (write stack pointer) and directly executes user code for testing conditions whether Bootloader code should be executed or not. The most typical testing conditions for Bootloader presents: pushed button some specific value in the EEPROM memory waiting loop for command via the communication interface If User Application code is already loaded and Bootloader was not selected, the User Application is automatically started.   2.3.     Serial interface All S12Z microcontrollers include an on-chip serial communication interface. Notice that the RS-232 or USB to TTL level shifter is necessary to communicate with PC. Optionally, the virtual COM port at OSBDM interface may be used. By default, the serial communication is set to format: 8-data bit one start bit one stop bit no parity Xon / Xoff flow control Default baud rate is configured in Config.h file. The baud rate can be changed via the Bootloader’s menu to 38400, 57600, or 115200 bps. The Bootloader implementation currently assumes using just one of SCI channels. However, this may be changed by Bootloader code modification. The same approach may be used for a different type of channel implementation like CAN or LIN.   2.4.     PC software interface A general terminal emulation program like Microsoft HyperTerminal, Tera Term, RealTerm or similar software can be used on a PC to communicate with a microcontroller. A terminal emulation program must support communications over serial COM ports, Xon / Xoff flow control, and it must be able to send a text file.   3.  Functional Description The operation of the Bootloader is straightforward. This section describes only the most important and specific points. Figure 2 Memory map 3.1.     Bootloader Project Folders The C language codes and appropriate header files are located in Sources and Project_Header folders. The exception is Dispatcher.c and start12z.c files located in Project_Settings\Startup_Code folder. The linker file is located in Project_Settings\Linker_Files folder. The FLASH folder contain generated files like elf, map or s19 files. The SRecCvt folder contains a SRecCvt.exe tool for re-formating generated S-record file. The content of Documentation folder should help you in guide how to use this Bootloader. Figure 3 Bootloader Project Folders 3.2.     Bootloader Configuration The most of the Bootloader configuration settings are collected in Config.h file.   If the modified Bootloader will use any derivative specific registers, the mc9s12zvl128.h and mc9s12zvl128.c files should be replaced with appropriate files from CodeWarrior folders: "c:\Freescale\CW MCU v10.7\MCU\lib\wizard_data\S12Z\DataBase\device\include\.." and "c:\Freescale\CW MCU v10.7\MCU\lib\wizard_data\S12Z\DataBase\device\src\.."  And followed by modification of derivative.h file.   The Config.h contains settings for: Bootloader feature configuration Clock settings SCI module settings Dispatcher definitions MCU derivative configuration and addresses Flash Configuration Field configuration   The Bootloader-persistent.prm and Bootloader-rewritable.prm linker files contain definitions of Flash and RAM ranges for Bootloader. The appropriate linker file is selected by Build Configuration. Figure 4 Build Configuration   3.2.1.     Bootloader features SECURE_MCU: The MCU may be secured after Bootloader loading (default 0 = MCU unsecured) USE_BACKDOOR_KEY: The Flash Configuration Field may already contain Backdoor Key for temporary unsecure of MCU (default 0 = backdoor key 0xFFFF FFFF FFFF FFFF). WRITE_EEPROM: When enabled, the Bootloader menu offers an option for erasing EEPROM and program option will be able to program both Flash and EEPROM. BOOTLODER_REWRITABLE: When enabled, the Bootloader code is automatically loaded into RAM and allow unprotect, erase and program Bootloader Flash area. This variable is already defined differently in used Build Configurations. That allows us to keep BOOTLODER_REWRITABLE value and selected linker file synchronized.   3.2.2.     Serial Channel The current S12Z MCU derivatives offer up to 2 SCI channels. The SCI_MODULE defines whether SCI0 or SCI1 will be used for Bootloader communication (default SCI1). The DEFAULT_BAUDRATE specifies default SCI baud rate for initial Bootloader menu display (default Baud9600: 9600bps). The baud rate can be changed via the Bootloader’s menu to 38400, 57600, or 115200 bps. The S12Z MCU derivatives offer routing options for SCI0, SCI1, and other peripherals channels. The BL_MODRR0 value defines MODRR0 value loaded by Bootloader code after a reset.    Note: The MODRR0 values may be written just once in normal mode and cannot be changed until next MCU reset.   3.2.3.     Configure Dispatcher code The default Dispatcher condition is based on the testing value of pin with push button. The PUSH_BOTTON defines tested port and pin (default PTP_PTP1) while PB_ACTIVE_LEVEL defines active logic level – when the push button is pressed (default 0 = push button to GND with pull-up). The BL_REQUEST_ADD defines tested address (default 0x100000) while BL_REQUEST_VALUE defines active value for bootloader request key. When the memory content fits to the BL_REQUEST_VALUE, Bootloader code is executed (default "BOOT" in ASCII = 0x424F4F54).   3.2.4.     Configure Derivative and addresses The FLASH_START_ADD, EEPROM_START_ADD, EEPROM_END_ADD defines MCU derivative memory ranges. The BOOTLOADER_START_ADD value is automatically obtained from linker file (ROM segment start). The Bootloader automatically move User Application reset vector to the APPLICATION_RESET_VEC_ADD address (default BOOTLOADER_START_ADD-4 = placed to the end of User Application flash area)   3.2.5.     Configure Flash Configuration Field The bytes from BACKDOOR_KEY_0 to BACKDOOR_KEY_7 defines Backdoor Comparison Key (default "UNSECURE" = 0x554E534543555245 in ASCII). The bytes PROTECTION_OVERRIDE_KEY_H and PROTECTION_OVERRIDE_KEY_L defines Protection Override Comparison Key (default "AB" = 0x4142 in ASCII). The Bootloader code should be protected against unwanted erase/rewrite operations. Trying to alter data in any protected area in the P-Flash memory will result in a protection violation error and the FPVIOL bit will be set in the FSTAT register. Flash protection scheme allows protecting 2, 4, 8 or 16KB from upper range of Flash memory. The BL_FPROT defines FPROT value automatically loaded from Flash Configuration Field after reset (default 0xD7 = upper 8kB of P-Flash protected.). The BL_DFPROT defines DFPROT value automatically loaded from Flash Configuration Field after reset (default 0xFF = EEPROM unprotected). The initial configuration of COP watchdog and GDU (S12ZVM derivatives) is given by FOPT register value. The BL_FOPT defines FPROT value automatically loaded from Flash Configuration Field after reset (default 0xFF = COP is not active after reset).   3.2.6.     Bootloader linker file Since the preprocessor functionality is no longer supported directly in prm linker file, the Bootloader use two versions of linker file: Bootloader-persistent.prm Bootloader-rewritable.prm The linker file selection is managed by two Build Configurations (Figure 4 Build Configuration).   3.3     Operation The Bootloader handles reset vector. After reset, the Bootloader’s Dispatcher routine is called. As a first step, the Dispatcher initialize stack and reads the push button pin status. If the value of the pin is equal to the PB_ACTIVE_LEVEL, the Bootloader starts its operation. If the value of this pin is not equal to the PB_ACTIVE_LEVEL, the User Application’s reset vector is tested. If the reset vector of the User Application is not available (long word at address APPLICATION_RESET_VEC_ADD is in erased state = 0xFFFFFFFF) then the Bootloader is called anyway. The User Application is called only when User Application reset vector is already programmed and the condition for Bootloader enter is not true. The user can rewrite this code to start the Bootloader or User Application upon another condition. Note: Since this code is executed prior Bootloader/application startup code, the dispatcher code shouldn’t use any uninitialized global variables.   3.4.     Interrupt vector In the case when the User Application using interrupts, it is necessary to relocate the interrupt vector table using the IVBR register. The Bootloader resides in the upper 4/8/16kB fixed block at the address defined by linker prm file. This area is had to be protected (configured in Config.h), so the User Application cannot rewrite a default location of the interrupt vector table at 0xFFFE10-0xFFFFFF. The advantage of this solution is that the Bootloader cannot be affected by a power failure that could occur when rewriting User Application interrupt and reset vectors. The Bootloader automatically moves User Application’s reset vector from address 0xFFFFFD to the  APPLICATION_RESET_VEC_ADD address = typically the end of User Application’s flash area. Since this moving is managed by the Bootloader, the whole phrase (by default from (BOOTLOADER_START_ADD-8) to BOOTLOADER_START_ADD) must be excluded from User Application’s linker usage and the same sector (512B) shouldn’t be used for User Application’s interrupt vector table.   4.  User Guide This section describes the step-by-step procedure to use the Bootloader.   4.1.     Setup procedure for the Bootloader Open the Simple_Serial_Bootloader_for_S12Z project in CodeWarrior Development Studio for MCU. The Bootloader was tested in current versions v10.7. Select the Build Configuration as shown in Figure 4 Build Configuration. The Persistent Bootloader code option allows just update a User Application. The Bootloader Rewritable code option linker allows updating both User Application and Bootloader itself. Optionally edit appropriate linker file Optionally edit the Config.h header file per your target environment (required features, clocks, channels, derivative addresses, backdoor, and protection override keys). Optionally edit the c file with conditions for select User Application/Bootloader code execution.   4.2.     Bootloader Guide   1. Compile the project and download the Bootloader to the MCU via BDM device. Note: The correct derivative should be selected in debug configuration for successful complete MCU Flash erase and programming (Figure 5 Select derivative for Bootloader download). Figure 5 Select derivative for Bootloader download     2. Open the Microsoft HyperTerminal or any other serial terminal utility (e.g. Realterm, Tera Term,…). Set the baud rate 9600 bps, 1 start bit, 8 data bits, 1 stop bit, and flow control Xon / Xoff.   3. Make sure there is a serial (USB to Serial) cable connection between the PC and the board.   4. Hold the PUSH_BOTTON pin low and reset the MCU.   5. The Bootloader is started and the following response is received in HyperTerminal. See Figure 6 Initial screen.   Figure 6 Initial screen   6. Type “a” to erase the flash memory. This is not necessary the first time because the flash has been already erased by the BDM device.   7. Type “b” to program the flash.   8. Now send the desired S-record as a text file — See Figure 7 Send Text File. Browse for S-record which is downloaded to the MCU. For testing purposes, use demo S-records that are attached to this application note. The S-records must have a specified format. Refer to chapter 3 How to write a User Application and to chapter 4.4 How to convert S-Record that will be downloaded by the Bootloader. Figure 7 Send Text File     9. Confirm the dialog and the S-record are downloaded to the MCU. One printed star (*) means that one line of S-record has been programmed. See Figure 8 Download User Application. Figure 8 Download User Application   Note: If User Application contains any EEPROM data, please erase EEPROM by typing “h” prior the step 7. Note: If you want to reprogram Bootloader code, please use subsequently options “e” (it will ask you for entering protection override key), step “f” and step “g” instead steps 6 and 7.   4.3.     How to write a User Application You must ensure that the User Application does not interfere with Bootloader area defined by Bootloader linker file.   1. Create a new User Application project in CodeWarrior Development Studio for MCU.   2. Open the User Application project.prm file   3. Trim the high address of the segment ROM from the original to the (BOOTLOADER_START_ADD-8). For example, to the address 0xFFDFF7. This is because the area 0xFFDFF8–0xFFFFFF is occupied by the Bootloader and the area at address 0xFFDFF8–0xFFDFFF will be used for the User Application reset vector. If interrupts are used:   4. Trim the low address of the segment ROM from the original to (the original address + 0x200). This area will be used for the relocated interrupt vector table. Note: You may use any other Flash sector in User Application memory for that purpose except the last one (already used for the User Application reset vector). Note: The generated CodeWarrior project doesn’t show warning about memory overlapping between linker and user object placement. This warning is disabled by default (Linker option -WmsgSd1912).      5. Create a vector table as shown in the attached demo applications and set the IVBR register accordingly. The IVBR sets the interrupt vector table base address. It contains 15 most significant bits from 24bit vector table address.   4.4.     How to convert S-Record that will be downloaded by the Bootloader The default S12Z MCU project generated by CW10 does not generate a file with s-records automatically.   1. Check option for generating S-Record file in User Application project settings per Figure 9 Generate S-Record file The <YourProjectName>.sx file will be generated when you will build your project. Figure 9 Generate S-Record file For the simplifying, the Bootloader parser, only s-records with specific format are accepted. All records must be aligned to 32 bytes and the length of records must be 32 bytes.   2. Copy SRecCvt directory with SRecCvt.exe tool from Bootloader/Application Example project to your User Application project   3. Exter command “ ${ProjDirPath}/SRecCvt/sreccvt.exe -hc12 -m 100000 FFFFFF 32 -o ..\FLASH\\${BuildArtifactFileBaseName}.s19 ..\FLASH\\${BuildArtifactFileBaseName}.sx ” as post build step into User Application project settings per Figure 10 Adding Post-build step . Figure 10 Adding Post-build step This command will load S-Records from your <YourProjectName>.sx file and create new <YourProjectName>.s19 file with reformatted S-Records when you build your project. Note: The complete SRecCvt utility may be downloaded from NXP web pages. Unfortunately, the graphical user interface doesn’t support directly S12Z derivatives. Therefore we use this tool in command line mode.   4.5.     How to merge the User Application and Bootloader The User Application can be developed independently, that is without the Bootloader. The User Application can be loaded into the microcontroller and can be debugged directly via the BDM device. However, for production purposes, it is worth merging the User Application and Bootloader together, so it can be downloaded into the microcontroller all at once as a single S-Record file. This is a recommended procedure:   1. Open the User Application that was created as per chapter 3, "How to write a User Application" in the CodeWarrior Development Studio for MCU.   2. Replace a User Application reset vector in Project.prm file from default address to the address (BOOTLOADER_START_ADD-3), so the Bootloader can use this vector for start User Application. For example: //VECTOR 0 _Startup VECTOR ADDRESS 0xFFDFFD _Startup   3. Copy the ready-mades19 file to ..\user_application_project\FLASH directory. Note: the s-record file can be renamed for example to the bootloader.s19.   4. Link this file to the User Application be using command at the beginning of Project.prm: HEXFILE Simple_Serial_Bootloader_for_S12Z.s19   5. Build the project. The final S-Record is ready to be downloaded into the microcontroller by the BDM interface.   5.  Testing The Bootloader and example application were tested on evaluation boards: DEVKIT-ZVL128 S12ZVMC256EVB S12ZVM32EVB S12ZVM-MINIBRD   6.  Content of Zip file All mentioned projects and utilities can be found in a zip file associated with this application note: Simple_Serial_Bootloader_for_S12Z — Bootloader project for S12Z microcontrollers. Application_Example_for_SSBZ — Projects that show how to write User Applications. Converted_srecords — S-Records was taken from Bootloader and Application Example that has been converted by the SRecCvt utility (*.s19 file extension). These S-Record files can be downloaded into the MCU by the Bootloader. SRecCvt — Utility for S-Record files converting.   7.  Reference AN4258 AN4258SW: Serial Bootloader for S12(X) Microcontrollers Based on 180 nm Technology Rev 0. February 2011. S12Z Protection Override S12Z constant, variable, code allocation in CodeWarrior S12Z Interrupt catcher for unexpected interrupts S12Z Flash example code S12Z EEPROM example code   I hope it help you. Please let me know when you find any error or if something missing in this document.   Radek Sestak
View full article