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.


Messages - tdrobnak

Pages: [1] 2
1
USB / Re: USB when moving from MK66 to MK24
« on: March 16, 2022, 11:09:18 PM »
Hi Alex,

I had a similar problem with the USB connectivity as you are experiencing in 2014.  On our design, it was found that we had undersized the capacitor for the VOUT33 pin for the MK22 processor we used in a project.  I see the capacitance is 100nF for your design.  This might be too low and cause noise issues on the USB's internal power supply that VOUT33 is designed to supply.  Our design uses a 2.2uF capacitor.  It is not well documented in the reference manual for the microcontroller, but I did find that Freescale's (now NXP) KwikStik-K40 Hardware Errata document on Errata ID KWIKSTIK_06 states "Undersized VOUT33 Capacitor" and the solution on page 10 of that document states: "The recommended value for the capacitor from VOUT33 to GND is from 1.76uF to 8.16uF with 2.2uF being the typical value. The capacitor (C34) connected to VOUT33 on the KwikStik is only 0.1uF. This can result in unstable or non-functioning USB operation.  Workaround: Replace C34 with a capacitor of value 1.76uF to 8.16uF".  The link to the document is: https://www.nxp.com/docs/en/errata/KWIKSTIKK40HWER.pdf

There is also a NXP Community discussion on the USB internal regulator (VOUT33) with NXP TechSupport suggesting a 2.2uF capacitor.  The link for this conversation is:
https://community.nxp.com/t5/Kinetis-Microcontrollers/MK22DX256VMC5-VOUT33-output-not-good-when-VREGIN-changes/m-p/741454?commentID=965047

Hope this helps,

Tom


2
Thank you, Mark for your explanation.  My thought on a solution is in the same line of thinking as yours.  Since I posted this message, I have modified the high level application design to include a acknowledge flag whenever there is a request for information from the slave.  If the slave does not acknowledge within the 1 second software interrupt time, a retry with that same message will occur up to 5 times.  If after 5 times (5 seconds), there is no response from the slave, the application will generate a shutdown error.  In this way, I can be certain that there is a communication problem with any particular slave, and the communication problem is not just missing one acknowledge (maybe due to electrical noise in the environment).  I want to make the shutdown of the unit more I2C noise immune.

3
A recent problem was identified on the I2C bus with uTasker as the master.  An I2C RFID device was causing the SCL line to not go low enough in voltage to be detected by the other slave devices.  A start condition could be sent, but the slave devices could not detect it because of SCL.  Does the Kinetis (KE15Z) version of the uTasker I2C driver support a way to detect that the I2C bus has failed to communicate.  I found an earlier message, https://www.utasker.com/forum/index.php?topic=872.msg3822#msg3822, on this forum that said there was a MASTER_TX_DATA_NOT_ACKED case for the LPC device driver that would detect that the slave was not able to acknowledge the message.  I could not find that same MASTER_TX_DATA_NOT_ACKED case in the Kinetis I2C uTasker source code.  Does anyone know of an already programmed way to detect this situation for uTasker's Kinetis I2C driver?

Thank you.

4
Thank you, Mark!  I also found that I had to create a directory called "KeyPads" in the application directory (where the uTaskerProject.exe program is located) and put the "FRDM_KE15Z.bmp" in the "KeyPads" directory.  I now have a distributable PC version of my uTasker embedded application which others can use to process the log files using the same (embedded) code that created them.  This is a powerful tool for our application.  My supervisor was very impressed.  The uTasker simulation is really a hidden gem of a feature.  Thank you for designing it in and continuing to support it.

5
µTasker general / How to distribute my application as a uTasker Simulation?
« on: September 14, 2021, 10:46:38 PM »
I would like to build my uTasker application as a distributable simulation on the PC.  I have done this, but the graphics for the Kinetis logo and the FRDM-KE15Z are missing when it is built using a setup project in Visual Studio 2017.  Does anyone know what I need to add to the VS setup project to add the missing graphics.  Also where are the missing items located in the uTasker directory?  I am sure there is a message on this forum that has this information on what is needed, but I cannot find it.  If you know where the message is, please send a link to it.

Thank you

6
Thank you, Mark for the explanation and offer to add emulation support for EEPROM emulation of FlexNVM.  When I get to a stopping point on my present task with this application, I will send you a file that provides FlexNVM EEPROM emulation support to uTasker in the hardware.

Tom

7
NXPTM M522XX, KINETIS and i.MX RT / uTasker FlexNVM Simulator support
« on: March 03, 2020, 02:54:19 PM »
Does anyone know if uTasker supports FlexNVM for EEPROM emulation?  NXP has two application notes on the subject:
  • AN4282 - Using Kinetis Family Enhanced EEPROM Functionality
  • AN5338 - How to use FlexMemory as D-Flash and EEPROM in KE1xF

I have looked through uTasker 1.4.12 and found no driver for FlexNVM so I added the necessary driver code from the NXP SDK 2.7.0 flexnvm_eeprom.c example.  I now have access to EEPROM emulation using FlexNVM when run on the hardware.  When I run on the uTasker simulator, I receive exceptions on access to the registers that control FlexNVM partitioning and status.  Has anyone else run into this situation?  Is there a way to work around it?

Thank you.

8
Has anyone tried using two I2C channels on one microcontroller devices independently without issue?  The "uTasker Support Demo and Simulation V1.4" document describes using the I2C interface, but does not mention (or give examples) using multiple I2C channels independently: usSpeed, TxQueueSize, RxQueueSize, Task_to_wake.  Also, will the simulator be able to handle simulating separate I2C devices?

Thank you.

9
The uTasker project uses definitions in application.c to enable specific features for testing:

#if !defined NO_PERIPHERAL_DEMONSTRATIONS
    #define _SPI_READ_CODE                                               // SPI reception checking
        #include "spi_tests.h"                                           // include SPI code to handle reception
    #undef _SPI_READ_CODE

    #define _I2C_READ_CODE                                               // I2C reception checking
    #if !defined BLAZE_K22
        #include "i2c_tests.h"                                           // include I2C code to handle reception
    #endif
    #undef _I2C_READ_CODE

    #define _ADC_POLL_CODE                                               // ADC polling operation
        #include "ADC_Timers.h"
    #undef _ADC_POLL_CODE

    #define _PORT_NMI_CHECK                                              // {53}
        #include "Port_Interrupts.h"                                     // port interrupt timer interrupt event handling - ranges
    #undef _PORT_NMI_CHECK
#endif

Specifically, the i2c_tests.h file has TEST_DS1307 defined.  When looking at the code in:
   1. Visual Studio, the code defined for TEST_DS1307 is enabled to be compiled and shown unghosted.
   2. Eclipse (MCUXpresso), the code defined for TEST_DS1307 is enabled to be compiled and shown ghosted.

Visual Studio does a good job of showing code in the editor that will be executed.  Eclipse does not do this for code included in the C source file with the definition defined in the C source file.

Is there a setting in Eclipse to make it work like it does in Visual Studio?  I believe the Eclipse Indexer is responsible for associating code and definitions viewed with the editor used in the application.  I have set the indexer with the following settings shown in the attachment.  I have been using both Visual Studio to help identify code that will be executed for the Eclipse during development, but would like eliminate this duplication and have Eclipse correctly show the executed code in the editor.

Tom

10
µTasker general / Re: My experience on Upgrading uTasker for the KE15Z
« on: November 22, 2019, 10:47:19 PM »
Thank you for the update, Mark.  I just pulled them into my latest uTasker project, built the executable, and FreeMASTER on the serial port is working well with your new changes to the LPUART0 ALT 6 configuration.

Regards,

Tom

11
Thank you, Mark for your recommendation on pulling the latest version.  I am new to GIT since we use SourceGear Vault at the company I work for.  I have found that GIT does make it very easy to update uTasker by doing a "git pull" on the latest commit.  My project directory is not affected by the pull since it is in the Untracked files.  Only the updated uTasker files will be replaced.

Tom

12
µTasker general / My experience on Upgrading uTasker for the KE15Z
« on: November 21, 2019, 10:40:19 PM »
Recently, I found that an issue with a task not being awakened after an I2C read call (see http://www.utasker.com/forum/index.php?topic=2047.0).  Since this issue was fixed since the build I started using for my project with uTasker, I thought it would be a good idea to use a later build that incorporated the changes I had found.  Created the following steps to upgrade my project.

Steps to Update
   1. Obtain the latest stable uTasker operating system.
   2. Unzip to a directory uTasker_latestStableBuild
   3. Create a MCUXpressoWorkspace directory
   4. Follow the uTaser instructions for creating the MCUXpresso integration of the workspace and project, but copy then import the present .cproject, .project, and .settings directory of the previous uTasker project.
   5. Copy all the .launch configurations and Revision History to the new project.
   6. Use WinMerge to find the differences.  Copy what is appropriate to recreate the project, the project directory located in the Applications directory.
   7. Clean and build the project.

I did this upgrade with uTasker_1.4.12.2019.11.15_11.40.37
After going through the "Steps to Update", on first build found that file CO_driver.h line 382, in structure definition CO_CANmodule_t had and unknown definition called QUEUE_HANDLE for CAN_interface_ID.  I found in the previous version of the file that I had, QUEUE_HANDLE was not used in CO_driver.h.    To work around this issue, I included file "types.h" since QUEUE_HANDLE is defined in this file:

#include "types.h"

Although, I did set up and build the uTaskerV1.4 project in MCUXpresso without my application code and it compiled without a problem for the FRDM_KE15Z.  I found that keeping the same Application files and importing the MCUXpresso project from the previous uTasker_1.4.12.2019.02.28 build did have one compiler problem.

After that change, the program would build, but when run, LPUART0 data was being ignored for our project.  Found that file kinetis.h did not have PA_2_LPUART0_RX and PA_3_LPUART_TX defined for PORT_MUX_ALT6 which is used in our project:

#define PA_2_LPUART0_RX           PORT_MUX_ALT6
#define PA_3_LPUART0_TX           PORT_MUX_ALT6

Found that kinetis_uart_pins.h is missing configuration of the LPUART0 port for PORT_MUX_ALT6.
Added after _CONFIG_PERIPHERAL(A, 2, (PA_2_LPUART0_TX | UART_PULL_UPS)), added line:

#elif defined KINETIS_KE15
            _CONFIG_PERIPHERAL(A, 3, (PA_3_LPUART0_TX | UART_PULL_UPS)); // LPUART0_TX on PA3 (alt. function 6)

Added after _CONFIG_PERIPHERAL(A, 1, (PA_1_LPUART0_RX | UART_PULL_UPS)), added line:

#elif defined KINETIS_KE15
            _CONFIG_PERIPHERAL(A, 2, (PA_2_LPUART0_RX | UART_PULL_UPS)); // LPUART0_RX on PA2 (alt. function 6)

I had added these definitions (see attachment files) on the previous version of uTasker and WinMerge helped identify some corrections I made to those uTasker driver level files.  The upgrade process was easy and went better than expected.  My conclusion is that uTasker is designed in a very modular which simplifies the process of upgrading your application code.

Tom

13
Hi Mark,

Thank you for identifying the difference in version I am using and a later one that you have coded to handle the repeated start condition.  Replacing the kinetis_LPI2C.h file with the newer one you provided fixed the missed uTaskerStateChange(ptrRxControl->wake_task, UTASKER_ACTIVATE).  My application is now working with both TASK_ALTITUDE_SENSOR and TASK_LED_DRIVER.

I did run into one compilation error on the kinetis_LPI2C.h file.  It looks like a new macro is used: WRITE_ONE_TO_CLEAR_INTERRUPT(ptrLPI2C->LPI2C_MSR, LPI2C_MSR_SDF, irq_id).  This one does not exist in my code version, so I replaced it with WRITE_ONE_TO_CLEAR(ptrLPI2C->LPI2C_MSR, LPI2C_MSR_SDF) and the code now compiles and executes with the desired result.

This leads me to the question of if it would be a good idea to update my version of uTasker to the latest in the GIT repository or do you have a specific version that you would recommend.  It might be a little effort on my part to merge my code into the latest version of uTasker, but if this will fix some behind the scene driver issues and not cause what has been working to fail, I will do it.  This missed scheduled task activation issue has cost me a few days of lost time while I try to understand the uTasker code and provide detailed enough observations for some assistance.  If you think using your a later version than uTasker_1.4.12.2019.02.28 for the Kinetis KE15Z processor then please let me know.

Thank you.

Tom

14
Thank you for your feedback, Mark.  The task, TASK_LED_DRIVER, does not use and fnRead() functions; it only uses fnWrite() and assumes the data was transferred.  The task TASK_ALTITUDE_SENSOR needs to read the altitude and temperature from the sensor, so it uses both fnRead() and fnWrite() commands.  Therefore, there should not be any confusion on which task was commanding the read, but  I think I have identified the source of the problem I am having.

Looking over the uTasker code, I think there is the possibility of a missed wake up owner of fnRead() task:
   1. A fnRead() takes place in TASK_ALTITUDE_SENSOR and changes the ucState to RX_ACTIVE and TX_ACTIVE in file kinetis_LPI2C.h line 358 of function fnTxI2C:
           I2C_tx_control[Channel]->ucState |= (RX_ACTIVE | TX_ACTIVE);
   2. The uTaskerStateChange(ptrRxControl->wake_task, UTASKER_ACTIVATE) does not happen until all bytes are transferred into the I2CPortID message queue in the interrupt handler function, fnI2C_Handler(), file kinetis_LPI2C.h:
   static void fnI2C_Handler(KINETIS_LPI2C_CONTROL *ptrLPI2C, int iChannel) // general LPI2C interrupt handler
   {
       I2CQue *ptrTxControl = I2C_tx_control[iChannel];
   
       if ((ptrLPI2C->LPI2C_MIER & ptrLPI2C->LPI2C_MSR) & LPI2C_MSR_SDF) {  // stop condition has completed
           fnLogEvent('S', ptrLPI2C->LPI2C_MSR);
           ptrLPI2C->LPI2C_MIER = 0;                                        // disable all interrupt sources
           WRITE_ONE_TO_CLEAR(ptrLPI2C->LPI2C_MSR, LPI2C_MSR_SDF);          // clear interrupt flag
           if ((ptrTxControl->ucState & RX_ACTIVE) != 0) {
               I2CQue *ptrRxControl = I2C_rx_control[iChannel];
               ptrRxControl->msgs++;
               if (ptrRxControl->wake_task != 0) {                          // wake up the receiver task if desired
                   uTaskerStateChange(ptrRxControl->wake_task, UTASKER_ACTIVATE); // wake up owner task
               }
           }
           else {
               if (ptrTxControl->wake_task != 0) {
                   uTaskerStateChange(ptrTxControl->wake_task, UTASKER_ACTIVATE); // wake up owner task since the transmission has terminated
               }
           }
           ptrTxControl->ucState &= ~(TX_WAIT | TX_ACTIVE | RX_ACTIVE);     // interface is idle
What I think is happening is that while the fnRead() communication on the physical I2C channel 0 is taking place, a fnWrite() command is called in task TASK_LED_DRIVER.  Calling fnWrite() will set the ptrTxControl->ucState to TX_ACTIVE and clear RX_ACTIVE before the " if ((ptrTxControl->ucState & RX_ACTIVE) != 0)" conditional is executed in the interrupt handler fnI2C_Handler().  If this happens, then the uTaskerStateChange(ptrRxControl->wake_task, UTASKER_ACTIVATE) statement will not happen.  This will cause the TASK_ALTITUDE_SENSOR not to wake up and handle the data read from the I2C in the I2CPortID buffer.

I have found that if I disable the TASK_LED_DRIVER, the returned data from the fnRead()s in TASK_ALTITUDE_SENSOR are handled, otherwise, the data is not handled because the TASK_LED_DRIVER is not scheduled to wake up.  By disabling TASK_LED_DRIVER, I can see that it does affect the wake up scheduling of TASK_ALTITUDE_SENSOR.  I checked the address of both where uState is set, line 358 in file kinetis_LPI2C.h, function fnTxI2C() :
       if ((ucAddress & 0x01) != 0) {                                       // reading from the slave
(358)         I2C_tx_control[Channel]->ucState |= (RX_ACTIVE | TX_ACTIVE);
           ptI2CQue->I2C_queue.chars -= 3;
           fnLogEvent('g', (unsigned char)(ptI2CQue->I2C_queue.chars));
           I2C_rx_control[Channel]->wake_task = *ptI2CQue->I2C_queue.get++; // enter task to be woken when reception has completed
           if (ptI2CQue->I2C_queue.get >= ptI2CQue->I2C_queue.buffer_end) {
               ptI2CQue->I2C_queue.get = ptI2CQue->I2C_queue.QUEbuffer;     // handle circular buffer
           }
       }
       else {
           I2C_tx_control[Channel]->ucState &= ~(RX_ACTIVE);
           I2C_tx_control[Channel]->ucState |= (TX_ACTIVE);                 // writing to the slave
           ptI2CQue->I2C_queue.chars -= (ptI2CQue->ucPresentLen + 1);       // the remaining queue content
           fnLogEvent('h', (unsigned char)(ptI2CQue->I2C_queue.chars));
       }
And where it is checked, line 135 in file kinetis_LPI2C.h, function fnI2C_Handler():
   static void fnI2C_Handler(KINETIS_LPI2C_CONTROL *ptrLPI2C, int iChannel) // general LPI2C interrupt handler
   {
       I2CQue *ptrTxControl = I2C_tx_control[iChannel];
   
       if ((ptrLPI2C->LPI2C_MIER & ptrLPI2C->LPI2C_MSR) & LPI2C_MSR_SDF) {  // stop condition has completed
           fnLogEvent('S', ptrLPI2C->LPI2C_MSR);
           ptrLPI2C->LPI2C_MIER = 0;                                        // disable all interrupt sources
           WRITE_ONE_TO_CLEAR(ptrLPI2C->LPI2C_MSR, LPI2C_MSR_SDF);          // clear interrupt flag
(135)          if ((ptrTxControl->ucState & RX_ACTIVE) != 0) {
               I2CQue *ptrRxControl = I2C_rx_control[iChannel];
               ptrRxControl->msgs++;
               if (ptrRxControl->wake_task != 0) {                          // wake up the receiver task if desired
                   uTaskerStateChange(ptrRxControl->wake_task, UTASKER_ACTIVATE); // wake up owner task
               }
           }
           else {
               if (ptrTxControl->wake_task != 0) {
                   uTaskerStateChange(ptrTxControl->wake_task, UTASKER_ACTIVATE); // wake up owner task since the transmission has terminated
               }
           }
           ptrTxControl->ucState &= ~(TX_WAIT | TX_ACTIVE | RX_ACTIVE);     // interface is idle

Both "I2C_tx_control[Channel]->ucState" and "ptrTxControl->ucState" point to the same location (0x200001CF) using the segger j-link debugger.  This tells me that it is possible that ucState can be changed before it is handled.  Was this the intention of uTasker I2C design?  If not, could you provide a solution (fix) that allows an I2C read to be handled even if another task is executing a I2C write?  My thought on a work around right now is to queue up all I2C reads and writes from the two tasks and handle them in one task that will allow only one fnRead() or fnWrite() command at a time until the task that commanded the read or write is woken.

Please let me know you thoughts.  I appreciate your feedback.

15
After reading the "uTasker - I2C Support, Demo and Simulation V1.4" document, I have two questions concerning uTasker task scheduling after an I2C read and write.:
Given the following information:
   There are two devices on the I2C bus: ALTITUDE_SENSOR and LED_DRIVER

   1. If one physical I2C channel is being used on the microcontroller that both ALTITUDE_SENSOR and LED_DRIVER are connected to, would more than one call be needed for fnOpen():?

void
configureI2CInterface (void)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~*/
    I2CTABLE    tI2CParameters;
    /*~~~~~~~~~~~~~~~~~~~~~~~*/

    tI2CParameters.Channel = OUR_I2C_CHANNEL;
    tI2CParameters.usSpeed = 100;   // 100k
    tI2CParameters.Rx_tx_sizes.TxQueueSize = 64;    // transmit queue size
    tI2CParameters.Rx_tx_sizes.RxQueueSize = 64;    // receive queue size
    tI2CParameters.Task_to_wake = TASK_ALTITUDE_SENSOR;                // task to wake on transmission

    if((I2CAltitudeSensorID = fnOpen(TYPE_I2C, FOR_I_O, &tI2CParameters)) != NO_ID_ALLOCATED)
    {   // open the channel with defined configurations
        g_I2CAltitudeSensorIDIsActive = TRUE;
    }

    tI2CParameters.Task_to_wake = LED_DRIVER;                // task to wake on transmission

    if((I2CLedDriverID = fnOpen(TYPE_I2C, FOR_I_O, &tI2CParameters)) != NO_ID_ALLOCATED)
    {   // open the channel with defined configurations
        g_I2CLedDriverIDIsActive = TRUE;
    }

Then when a write takes place it is of the form:
   For ALTITUDE_SENSOR:
      bufferToWrite[] = { 0xc0, 0xfd, 0x0b };
      fnWrite(I2CAltitudeSensorID, (unsigned char *)bufferToWrite, sizeof(bufferToWrite));
      bufferToRead[] = {1, ALTITUDE_SENSOR_ADDR, TASK_ALTITUDE_SENSOR};
      fnRead(I2CAltitudeSensorID, (unsigned char *)bufferToRead, 0);
   
   For LED_DRIVER:
      bufferToWrite[] = { 0xe8, 0x00, 0x55 };
      fnWrite(I2CAltitudeSensorID, (unsigned char *)bufferToWrite, sizeof(bufferToWrite));
      bufferToRead[] = {1,LED_DRIVER_ADDR, TASK_LED_DRIVER};
      fnRead(I2CLedDriverID, (unsigned char *)bufferToRead, 0);
      
By setting up two handles: I2CAltitudeSensorID, I2CLedDriverID uTasker can wake the appropriate task when data is written and read.
   2. If what I proposed in question 1 is not true, how would I set up uTasker to make active the task when data is written and read given only one I2CPortID handle?

Right now I have one handle for both devices called I2CPortID.  The problem is that uTasker seems to not activate the task to handle fnRead() after the data has been read unless a breakpoint is inserted after the fnRead().  When a breakpoint is inserted after the fnRead(), the the proper I2C task will handle the buffer, otherwise the task will not become active.

Any ideas of how I should proceed?

Pages: [1] 2