This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1292NCZAD: Possible Anomalies with Timers configured for one shot PWM and LCD palette animation.

Part Number: TM4C1292NCZAD

I tried sending the following to TI support directly but that was too painful so I'm posting it here in case its of use to anyone else.

During development I came across to problems that I would call chip anomalies but they aren’t currently documented in your errata.

 

  1. I configured Timer 1 A and B and Timer 2 A and B for Daisy chained One Shot PWM. All timers are configured for the same period and duty cycle. If I try to configure the timers with a period longer than 16 bits, the next timer in the chain isn’t trigger when the previous timer expires. Only timer 1A runs. If I configure the timers as repeating they work as expected or if I configure the timers with a period of 65536 or less, they work as expected. If I set the Prescale set or PRESCALE match set to nonzero the next timer in the chain isn’t started. The only workaround I found was to use the ALTCLK to drive the timers to get the longer periods that I want. The system is running at 120 MHz and I was trying to set each phase of the daisy chain to 6 ms.
  2. I’m using palette animation with the LCD controller. Due to a bug in the firmware, a burst of several hundred palette writes would occur every 30 seconds or so. Somewhere between 20 minutes and 8 hours after start up, the display would blank and the only way to recover it was to reset the Main LCD clock (bit MAIN in LCDCLKRESET). The TI LCD library that we’re using writes palette entry zero with the RAM structure every time the palette is modified even if palette entry zero is not being modified. I changed the library code to only update palette entry zero if entry 0 is being changed and the application never changed entry zero once the LCD controller was set up. The TI Library version being used is “This is part of revision 2.0.1.11577 of the Tiva Peripheral Driver Library”. The LCD initialization code is:

 

Ui32SysClkHz = 120000000

 

#define PIXEL_CLOCK_FREQ       6000000

 

.

.

.

 

                SysCtlPeripheralEnable(SYSCTL_PERIPH_LCD0);

                while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_LCD0)));

 

                LCDModeSet(LCD0_BASE, (LCD_MODE_RASTER |LCD_MODE_AUTO_UFLOW_RESTART),PIXEL_CLOCK_FREQ, ui32SysClkHz);

 

                LCDRasterConfigSet(LCD0_BASE, RASTER_FMT_ACTIVE_PALETTIZED_12BIT, 0);

 

                LCDRasterTimingSet(LCD0_BASE, &g_sRasterTimings);

 

                LCDDMAConfigSet(LCD0_BASE, LCD_DMA_BURST_4 | LCD_DMA_BYTE_ORDER_0123);

 

                LCDRasterFrameBufferSet(LCD0_BASE, 0, (uint32_t *)&lcdMemory, sizeof(lcdMemory) );

                LCDRasterPaletteSet(LCD0_BASE, LCD_PALETTE_TYPE_8BPP, (uint32_t *)lcdMemory.palette, (uint32_t *)paletteData, 0, sizearray(paletteData) );

 

                LCDRasterEnable(LCD0_BASE);

  • Hi Keith,
    Thank you for your feedback. When both the A and B parts of timers 1 and 2 are used, they are only 16-bit timers so trying to configure them with a period of greater than 65535 ticks would cause them not to trigger.

    The current release version of TivaWare is 2.1.4.178
    http://www.ti.com/tool/SW-TM4C
  • I was using the 8 bit prescaler which should extend the range to 24 bits. As I said this worked as expected in continuous PWM but not in one shot PWM.

  • Just to clarify, did you load the lower 16 bits of the match value into the match register and the upper 8 bits of the match value into the prescale match register?
  • Yes. I set the period for the four phases with:

    TimerConfigure( TIMER1_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_ONE_SHOT_PWM | TIMER_CFG_B_ONE_SHOT_PWM );

    TimerConfigure( TIMER2_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_ONE_SHOT_PWM | TIMER_CFG_B_ONE_SHOT_PWM );


    load = PHASE_PERIOD;
    // Phase A and B PWM control.
    TimerLoadSet( TIMER1_BASE, TIMER_BOTH, load & 0xffff );
    TimerPrescaleSet( TIMER1_BASE, TIMER_BOTH, load >> 16 );

    // Phase C and D PWM control.
    TimerLoadSet( TIMER2_BASE, TIMER_BOTH, load & 0xffff );
    TimerPrescaleSet( TIMER2_BASE, TIMER_BOTH, load >> 16 );

    // Phase B-D wait for the previous timer to timeout before starting.
    TimerControlWaitOnTrigger( TIMER1_BASE, TIMER_B, true );
    TimerControlWaitOnTrigger( TIMER2_BASE, TIMER_BOTH, true );


    And I set the duty cycle for the 4 phases with a call to:
    static void warmer_SetPhaseDuty( uint32_t duty )
    {
    TimerMatchSet( TIMER1_BASE, TIMER_BOTH, duty & 0xffff );
    TimerPrescaleMatchSet( TIMER1_BASE, TIMER_BOTH, duty >> 16 );
    TimerMatchSet( TIMER2_BASE, TIMER_BOTH, duty & 0xffff );
    TimerPrescaleMatchSet( TIMER2_BASE, TIMER_BOTH, duty >> 16 );
    }

    If PHASE_PERIOD is greater than 65535 only the first timer runs.

    I added the TIMER_CFG_A_ONE_SHOT_PWM and TIMER_CFG_B_ONE_SHOT_PWM as 0x9 and 0x900 rexpectively since the the library that I have didn't support the one shot PWM functionality but the device documentation says that it should.
  • Keith Clifford99 said:
    I added the TIMER_CFG_A_ONE_SHOT_PWM and TIMER_CFG_B_ONE_SHOT_PWM as 0x9 and 0x900  respectively

    Might Yoda's (famed) quote,  'Not so fast young padawan (grasshopper)!'  -  apply equally - here?  

    The driver lib's Timer.h reveals:

    TIMER_CFG_A_ONE_SHOT -  Half-width one-shot timer
    TIMER_CFG_A_PWM -              Half-width PWM output

    TIMER_CFG_A_ONE_SHOT          #define TIMER_CFG_A_ONE_SHOT     0x00000021
    TIMER_CFG_A_PWM                      #define TIMER_CFG_A_PWM                 0x0000000A      Sum is 0x0000.002B - not  0x9 - yet 'B' is illegal.  

    TIMER_CFG_B_ONE_SHOT         #define TIMER_CFG_B_ONE_SHOT     0x00002100
    TIMER_CFG_B_PWM                     #define TIMER_CFG_B_PWM                 0x00000A00      Sum is 0x0000.2B00 - not  0x900 - again 'B' illegal.

    While your method IS 'inventive/resourceful' - neither code bits '0x9 or 0x900' -  'Set bit 5' (TAMIE) w/in Registers 'GPTMTnMR'- which IS RESPONSIBLE for (likely)  'generating your (missing) interrupts!'

    While not implemented (we don't employ the '129 family) - it is believed that 0x0000.002A and 0x0000.2A00 - as replacements - prevent that illegal 'B' value - while (potentially) 'enabling your (desired) interrupts.'

    Keith Clifford99 said:
    the device documentation says that it should.

    Might you 'illustrate' (ideally quote) just where that (confirming documentation) occurred/is located?    Closest we could find was:

    which proves somewhat 'Less than complete/compelling...'    Overall - highly resourceful - and 'just may succeed' - should (unaddressed) bit 'TAMIE' (handled properly by the driver lib) be well managed by your 'just invented, MULTI-MODE defines!'       (maybe)

  • Hi Keith,

    You don't necessarily require interrupts for one shot PWM unless a INT handler reloads match count values. More likely your match set value is greater than load set value and that will lock the counter. Duty cycle updates of GPTM via match count changes inside INT handler of the PWM oneshot CCP edge event does not work well, past reported to this forum.

    A possible work around is to update the match counts via a slower timer interval of another GPTM, that works great!
  • Might it be noted that our poster:

  • I should have made this clear in my original post. My apologies. I have the One shot PWMs working to my satisfaction although not as elegantly as they could given the description in the documentation. The one shot PWM mode works in every way as advertised except that if the Prescale registers are non-zero, the next timer in the chain never starts.They work as expected if the Prescale registers are zero and using ALTCLK as the clock source for the timers I was able to get long enough pulse periods.

  • Thank you - several here become 'distressed' - when issues (impacting posters) are investigated -  and then yield - (only) silence...

    Might you confirm that bit 'TAMIE' - found w/in 'Register 'GPTMTnMR' - was not Set by your code - and thus (appears) NOT REQUIRED?

    This conflicts w/vendor's API - which makes (very) special effort - to SET THAT BIT!     (achieved via vendor's 'lead nibble' coded as '2' - w/out doubt  SETTING Bit  'TAMIE'  (and ONLY that bit!) - and being (that  value 2's) -  'ONLY'  Purpose in LIFE!)

    When 'breaking' from vendor's considered - and long standing/tested code - and (then) reporting an  'Anomaly' - (some) description and/or justification for such 'code break' - most always proves of high/critical interest...

  • I neither needed nor wanted interrupts for handling the PWM. In fact interrupts would have conflicted with other design requirements. The anomaly is with the hardware. Does the hardware behave as described in the data sheet? No. I reported it. I have reported anomalies before and wasted an enormous amount of valuable time trying to get the manufacturer to acknowledge and publish the anomaly. In the end they did acknowledge it but it wasn't worth the several weeks of my time or my companies time to get the manufacturer to that point considering that they simply reported the anomaly and the workaround that I had already worked out. As I tried to make clear in my last post, my issue is resolved to my satisfaction. If you want to investigate the problem I will try and point you in the right direction. If on the other hand you just want to tell me how I should have done it. Don't waste my time.