Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - mark

Pages: [1] 2 3 ... 19
« on: July 11, 2023, 09:30:29 PM »
The i.MX RT 10xx includes a temperature monitor module (TEMPMON) that allows interrupts to be generated if the core temperature exceeds two programmable high temperature levels or falls below a low programmable lower limit level.

Software can also read the present die temperature at any time.

In order for it to work correctly it needs the bandgap reference to be enabled, plus the 480MHz PLL and the 32kHz RTC modules to be operating.

The temperature monitor is factory calibrated and the calibration values can be read from the HW_OCOTP_ANA1 registers. These are used by software to extrapolate the temperature and also to correctly set temperature limits.

The support in the µTasker project is enabled with the define SUPPORT_TEMPMON which adds an interface to read the core temperature via the ADC API in a compatible manner for projects that also run on processors that use ADC based temperature reading.

An example of reading the temperature periodically can be activated in ADC_Timers.h by activating the define ADC_INTERNAL_TEMPERATURE when using the ADC reference. For compatibility the ADC API is used with the input set to

adc_setup.int_adc_bit = ADC_TEMP_SENSOR; // ADC internal temperature

which is how ADC based temperature reading is performed.

Although there is no interrupt generated when the measurement has completed such an interrupt is emulated so that applications remain compatible. The only difference is that the result returned when collecting the value is in °C x 100 (allowing hundredth of degree resolution) and not the raw ADC value itself. Therefore the only modification at the application level is to remove any HW specific conversion that may originally have been performed and use the result directly (or after modification to the desired form). The following shows retrieving and rounding to 1°C resolution:

Code: [Select]
ADC_SETUP adc_setup; // interrupt configuration parameters
ADC_RESULTS results;
adc_setup.int_type = ADC_INTERRUPT; // identifier
adc_setup.int_adc_mode = (ADC_READ_ONLY | ADC_GET_RESULT);
adc_setup.int_adc_controller = 0;
adc_setup.int_adc_result = &results;
fnConfigureInterrupt((void *)&adc_setup);
results.sADC_value[0] += 50;
results.sADC_value[0] /= 100; // the approximate temperature
rounded up/down to 1°C
fnDebugDec(results.sADC_value[0], DISPLAY_NEGATIVE);
fnDebugMsg(" degC\r\n");

In this particular case the conversion was started previously and it shows just the subsequent retrieval. The conversion was started using the standard API for the ADC with the ADC_TEMP_SENSOR defined as input. When multiple ADC controllers are implemented in the i.MX RT the same one should be referenced for the conversion and retrieval, although there is only one TEMPMON module shared by both and the ADC controller is not actually used.

Hi All

With the release of NXP's MCUXpresso V11.5, which is supplied with a newer version of the GCC tool chain, i.MX RT projects could no longer be build due to an incompatibility in the linker scripts.
Interestingly this however didn't affect Kinetis projects, where the same incompatibility was not experienced.

Originally attempts were made to identify what had changed and work around it but this proved to be a dead-end and so finally a new linker script was generated using the NXP SDK and then adapted to suit the uTasker code (such as inserting the same variable section references so that the initialisation code didn't need to be modified).

The result is that by swapping out original linker scripts against newer ones projects can be built with MCUXpresso versions pre-V11.5 and post.

At this time there are still some linker scripts to be adapted and tested but for the main usage I have attached the ones that can already be used (later they will be checked into the repository for general use)

- iMX_RT_10XX_FlexSPI_NOR.ld   This can be saved to \Applications\uTaskerBoot\GNU_iMX (overwriting the original) and allows the primary loader to be built for i.MX RT 10xx parts (excluding the i.MX RT 1064)

- iMX_RT_1064_FlexSPI_NOR.ld. This can be saved to \Applications\uTaskerBoot\GNU_iMX (overwriting the original) and allows the primary loader to be built for  the i.MX RT 1064

- iMX_RT_10XX_FlexSPI_NOR_BOOT.ld. This can be saved to \Applications\uTaskerSerialBoot\GNU_iMX (overwriting the original) and also to \Applications\uTaskerV1.4\GNU_iMX and allows the secondary loaders and application to be built for i.MX RT 10xx parts operating in RAM (the main operation configuration and always used by the serial loaders).

- iMX_RT_10XX_SDP_Boot.ld. This can be saved to \Applications\uTaskerSerialBoot\GNU_iMX (overwriting the original) and allows serial download protocol images for i.MX RT 10xx parts. This tends to be built in parallel with the serial loader and so, even if the SDP outputs are never used, it will stop the build failing.



Hi All

Note that the chip shortage has resulted in the uTasker project investing in the following chips, which are reserved for uTasker users and available at reduced prices (in comparison to distributors):

IMXRT1062DVL6B - commercial
IMXRT1062CVL5B  - industrial

These are 10mmx10mm 196 pin BGA with full features (2 x Ethernet, 2 x USB ,1Meg RAM, TFT display interface) and footprint compatible (and code 99% compatible) with i.MX RT 1051/52/61/62 and are useful for porting Kinetis projects to (they can also be used in place of i.MX RT 1064 as long as there is a QSPI flash connected)). With 600MHz zero wait state operation (up to 1.2G instructions per second) they are FAST as well. As well as having very high compatibility with Kinetis the uTasker project makes it simple to port from Kinetis projects and, with the chip stock, can ensure that supplies are immediately available when needed (some parts still have over a year delivery time otherwise).

The small BGA was chosen after experimentation with soldering (also hand soldering) and layout with 4-layer boards. Reference designs and guidance is thus available for those unsure about using BGAs, whereby it can be stated that they are not as difficult to work with as initially feared and result in small, reliable circuity.

There are good stocks available for immediate delivery or reservation, whereby each new project can order/reserve up to 1'200 pieces at the moment. (Quantities of up to 10'000 are possible for immediate delivery but only under exceptional circumstances since it is preferred to supply as many new projects as possible).



NXPTM M522XX, KINETIS and i.MX RT / Porting projects to the i.MX RT
« on: May 20, 2022, 08:07:16 PM »
Hi All

Due to the present processor shortage - especially Kinetis family parts - there is a lot of activity porting existing products to be able to run in i.MX RT parts, which tend to be more readily available.

During the transfer of code that has run correctly for years on the Kinetis (Cortex M0+, Cortex M4) there are some initial surprises when it hard faults on the Cortex M7 of the i.MX RT. The Cortex-M7 is very sensitive to alignment and I have found that the GCC compiler with high optimisation often generates code that access them with mis-aligned accesses and cause hard faults.

By reducing the optimisation of the compiler it often goes away and I also find that declaring variables that cause hard faults as volatile stops the compiler optimising and then corrects access alignment - from what I hear I expect you have also identified such.

I had a discussion with Eric Styger here (see discussion at the bottom)

where I believe that the use of volatile to solve such things (when they have been correctly understood) is valid. There are arguments about this being the wrong way but - as you can see - I think that it is valid in such cases and that is what I do use. You will find various such work-arounds in the code that were needed for the i.MX RT. For example, new routines
    21.12.2021 Add fnSafeGetBufLittleShort(), fnSafeGetBufLittleLong(), fnSafeGetBufBigShort(), fnSafeGetBufBigLong() {103}
    09.01.2022 Add fnSafePutBufLittleShort(), fnSafePutBufLittleLong(), fnSafePutBufBigShort(), fnSafePutBufBigLong() {104}
are used in some code and drivers to copy buffer content in a safe way.

Usually it is quite obvious that the hard faults are due to the compiler optimising accesses (trying to use 32 bit instead of 8 bit but accessing on unaligned boundaries) by looking at the disassembled code that caused the crash. Then adding the volatile keyword to the variables in question will show that it then doesn't optimise and the code works as expected.

It is a bit of a nuisance (IAR, for example, doesn't have this problem) but when you have experienced and solved it once or twice when moving existing code to the i.MX RT you will find that it is easy to recognise and solve so it is also not that serious.



Hi All

When using VS and its simulation of uTasker projects the "Solution Configuration" drop down (where it shows the target being used) tend to be rather narrow by default and so the target selected is not really visible. It can however be configured to be wider so that it becomes much more useful, as long as it can be worked out how to actually do it.

Here is the method:

1. Hover your mouse over the "Solution Configuration" and press right mouse to see the context menu.

2. Select "Customize..." - right at the bottom.

3. Now select the "Standard" Toolbar in the Commands tab and select "Solution Configurations" before commanding "Modify Selection", which gives the possibility to change its width setting:



NXPTM M522XX, KINETIS and i.MX RT / Kinetis CRC HW Module
« on: February 21, 2021, 06:04:20 AM »
Hi All

The following details concern the CRC HW module in the Kinetis parts and is valid as from 21st Feb. 2021 in the developers version.

1. The driver can be enabled with (in app_hw_kinetis.h) SUPPORT_HW_CRC

2. These are the modes that are  implemented:

3. In debug.c are some test commands in the I/O menu which allow testing two CRC16 and two CRC32 types to be verified

    {"crc16",             "Check CRC-16-Maxim",                    DO_HARDWARE,      DO_CRC_16_MAXIM},
    {"crc16b",            "Check CRC-16-Buypass",                  DO_HARDWARE,      DO_CRC_16_BUYPASS},
    {"crc32",             "Check CRC-32-IEEE",                     DO_HARDWARE,      DO_CRC_32_IEEE},
    {"crc32m",            "Check CRC-32-Mpeg-2",                   DO_HARDWARE,      DO_CRC_32_MPEG2},

4. This is how to use it (see also the code in debug.c which verifies the result with reference values).

Code: [Select]
              static const unsigned char ucRefData[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B'};

              fnCalculateCRC(ucRefData, sizeof(ucRefData), (CRC16_MAXIM_CALCULATION));   // configure the calculation and calculate the first buffer
              fnCalculateCRC(ucRefData, sizeof(ucRefData), 0);           // recalculate without reseeding
              ulCalculated = fnCalculateCRC(ucRefData, sizeof(ucRefData), 0); // recalculate without reseeding
              fnDebugHex(ulCalculated, (WITH_LEADIN | sizeof(unsigned short) | WITH_CR_LF)); // display the result
              if (ulCalculated == 0xf0bc) {                                // recalculate without reseeding and terminate (power down hardware CRC module)
              else {                 

Terminal output example:


The example shows the input being passed 3 times.
If one only needs to calculate a single buffer it is used like this:

Code: [Select]
usCalculated = (unsigned short)fnCalculateCRC(ucRefData, sizeof(ucRefData), (CRC16_MAXIM_CALCULATION));

CRC16_MAXIM_CALCULATION selects the standard to use (internally it uses 0x8005 polynomial, 0x0000 seed value and the result is inverted).
The result returned is always 32 bits in length but in the case of the CRC16 (as shown) it can be cast to a 16 bit result.

If the calculation is to be performed over multiple input buffers without resetting the seed in between following calls can be done with:

Code: [Select]
fnCalculateCRC(ucRefData, sizeof(ucRefData), (0)); // continue calculating the CRC over multiple buffers
fnCalculateCRC(ucRefData, sizeof(ucRefData), (0));
fnCalculateCRC(ucRefData, sizeof(ucRefData), (0));
usCalculated = (unsigned short)fnCalculateCRC(ucRefData, sizeof(ucRefData), (0)); // use the final result

The mode parameter is simply set to 0 so that the mode is retained without setting a new seed value. Intermediate results are returned but don't need to be used until all buffers have been handled.

5. After each calculation the CRC module is automatically powered down.

6. The API should be very easy to use and can be used for a wide range of standard CRC16 and CRC32 calculations just by passing the desired mode parameter (without needing to know all setup details to achieve the mode)

7. The function works in on the Kinetis HW when it has a CRC module integrated. It also works in the simulator when using this command. The simulator emulates the way that the module operates and produces the equivalent output for all of the modes.



How to add new CLI menus and commands - valid from check-in 6th February 2021.

1. Add a new line in the table tMainCommand[]

    {"C",                 "Go to My Commands menu",                DO_HELP,          DO_MENU_HELP_MY_COMMANDS},

and add a new define DO_MENU_HELP_MY_COMMANDS (for example, see where the list with DO_MENU_HELP_MQTT is and add it on to there)

2. Search for the way that DO_MENU_HELP_MQTT is handled:

        else if (DO_MENU_HELP_MQTT == ucType) {
            ucMenu = MENU_HELP_MQTT;                                     // set MQTT menu
            return (fnDisplayHelp(0));                                   // large menu may require special handling

and add a new help handler for your new sub-menu:

        else if (DO_MENU_HELP_MY_COMMANDS == ucType) {
            ucMenu = MENU_HELP_MY_COMMANDS;                                     // set my new menu
            return (fnDisplayHelp(0));                                   // large menu may require special handling

Locate MENU_HELP_MQTT (it is an enum in versions from 6th Feb. 2021) and extend the list with MENU_HELP_MY_COMMANDS (this must be in the enum list menu_help_reference in the same order as the main menu is built up!!!!!).

3. Add a new line in the table



{ tMyCommands,          15, (sizeof(tMyCommands)/sizeof(DEBUG_COMMAND)),          "    My menu"},

Note that the value 15 is the tab spacing when listing commands in this menu. 15 tends to be fine but it can be increased if you have long commands in the menu (which are added next). See reference at the end to see what the TAB SPACING affects.

4. This then needs its own sub-menu (tMyCommands)

Start with

static const DEBUG_COMMAND tMyCommands[] = {
    {"up",                "go to main menu",                       DO_HELP,          DO_HELP_UP},
    {"help",              "Display menu specific help",            DO_HELP,          DO_MAIN_HELP},
    {"quit",              "Leave command mode",                    DO_TELNET,        DO_TELNET_QUIT},

so it supports basic help, quit and up commands.

This should already run, showing a sparse new sub-menu

5. To add a new command insert one in to the tMyCommands[] table

    {"new_command",              "Description",                  DO_MY_GROUP,      DO_MY_COMMAND},

where you need to add new defines

DO_MY_GROUP (see where the list with DO_TELNET is and add it to there)

DO_MY_COMMAND (start a new list of defines dedicated to the new sub-menu - eg. beginning with 1)

You can also use existing groups (such as DO_TELNET) if you want to handle the new command type there rather than creating a new group.

6. Make a group action handle (assuming a new group define was added) where the new command is handled - starting an action, with or without interpreting additional parameters passed in the ptrInput string)

static void fnNewGroup(unsigned char ucType, CHAR *ptrInput)
    switch (ucType) {
    case DO_MY_COMMAND:
        // Handle the command here

and enter it in

static int fnDoCommand(unsigned char ucFunction, unsigned char ucType, CHAR *ptrInput)

    case DO_TELNET:                  <----example of existing group handler
        fnDoTelnet(ucType, ptrInput);
    case DO_MY_GROUP:         <--- the new group handler
        fnNewGroup(ucType, ptrInput);


Now the new sub-menu exists, can be entered and exited and one new command is available. When the command is executed the DO_MY_COMMAND case is hit and the specific new command code can be added there.

     Main menu
N [TAB SPACING]Configure network
S              Configure serial interface
I              Go to I/O menu
A              Go to administration menu
O              Go to overview/statistics menu
U              Go to USB menu
M              MQTT client commands
C              Go to My Commands menu
help           Display menu specific help
quit           Leave command mode

     My menu
up             go to main menu
new_command    Description
help           Display menu specific help
quit           Leave command mode


To extend existing sub-menus with new commands just step 5. can be used to extend existing menus and no new group is usually needed.



Hi All

The i.MX RT 106x parts include high-speed ports that are clocked at the core's clock speed and tightly coupled for fastest control.

This video shows the speeds that the GPIOs can achieve and gives additional background concerning their implementation and use:



NXPTM M522XX, KINETIS and i.MX RT / Teensy 4.1 with Ethernet Kit
« on: December 26, 2020, 12:23:28 AM »
Hi All

Guess what I received for Christmas?

A Teensy 4.1 with Ethernet Kit !!!

So I soldered the Ethernet Kit together and built the uTasker Loader and an application with Ethernet features as found here:

I did have to adapt the PHY configuration slightly to ensure it was configured to match the HW's clocking but then it started working as it should.



Preview of some new feature in the uTasker projects uGLCDLib supporting rich graphics and touch control completely in internal RAM, with i.MX RT processor, peripheral, interrupt, DMA, TFT and touch controller simulation for easy developing which makes embedded processing quick and fun to do!



Hi All

See this video for explanation!



NXPTM M522XX, KINETIS and i.MX RT / i.MX RT XBAR + AOI modules introduced
« on: September 03, 2020, 03:42:08 AM »
Hi All

New video showing XBAR and AOI in operation:



Hi All

This new guide shows how combining the uTasker Serial Loader with the "Bare-Minimum Loader can allow serial loader updates with a code size overhead as low as 2k Bytes:



NXPTM M522XX, KINETIS and i.MX RT / i.MX RT Playlist
« on: May 04, 2020, 04:22:18 AM »
Hi All

Finally I have got to the point that my time is not consumed fully by new i.MX RT development and the new support can be well demonstrated.

To get the ball rolling I have created a new playlist on Youtube "uTasker i.MX RT"

This starts with an introduction to the i.MX RT to give a foundation for future more technically details videos discussing more specific i.MX RT / uTasker topics. The next one will probably be the extended uTasker boot loader concept (secured as standard) now available in the i.MX RT version.

I believe that the results make the chips easier to use and manage (in production and in firmware maintenance once products have been shipped) and am hoping for its use to take off.

The i.MX RT devices are powerful and flexible and so the support journey is gong to be a long one, but fruitful.

If there are burning i.MX RT topics that someone thinks merits its own video please suggest here!



NXPTM M522XX, KINETIS and i.MX RT / i.MX RT 1020 Reference goes on-line
« on: February 21, 2020, 03:12:09 AM »
Hi All

First full-featured uTasker i.MX RT reference is now on-line:
Showing HS USB, TCP/IP and boot loading concept as integrated solution:

- USB-MSD / KBOOT composite loader
- Embedded FTP and web server with files in QSPI flash
- Telnet, USB-CDC, UART command line interfaces
- HS USB MSD composite with emulated FAT for viewing and transferring logged data

Complete reference project (including boot loader concept) runs on any i.MX RT or Kinetis part with the necessary peripherals.



Pages: [1] 2 3 ... 19