Hi everyone,
I've found a possible improvement for a Tivaware function that caused me a bit of a bother.
I made a little API that easily configures a wide timer to time capture. To avoid going through the process ever again and even avoid copy paste errors.
But I ran into a problem when I configured first TIMERA and then TIMERB (in WTIMER0). The problem was that the TIMERA configuration was gone! Just gone.
Finding the reason was not that hard. Just take a look at the relevant part of the source code:
// // Set the configuration of the A and B timers and set the TxPWMIE bit. // Note that the B timer configuration is ignored by the hardware in 32-bit // modes. // if(NEW_TIMER_CONFIGURATION) { HWREG(ui32Base + TIMER_O_TAMR) = (((ui32Config & 0x000f0000) >> 4) | (ui32Config & 0xff) | TIMER_TAMR_TAPWMIE); HWREG(ui32Base + TIMER_O_TBMR) = (((ui32Config & 0x00f00000) >> 8) | ((ui32Config >> 8) & 0xff) | TIMER_TBMR_TBPWMIE); } else { HWREG(ui32Base + TIMER_O_TAMR) = ((ui32Config & 0xff) | TIMER_TAMR_TAPWMIE); HWREG(ui32Base + TIMER_O_TBMR) = (((ui32Config >> 8) & 0xff) | TIMER_TBMR_TBPWMIE); }
This is the configuration on the TimerA and TimerB. Note that I will speak only of the TM4C123 part of the code. The rest I cannot speak much since I didn't analyze it (only using the TM4C123 right now - I saw more stuff in the TM4C129 config so I didn't bother) but it seems to be the same.
Now the problem is that it changes both the timers configs every time!! So if you use a function call for TimerA and then for TImerB then you will have a bad time.
Basically:
Calling TimerConfigure() to configure only TimerA or TimerB will unconfigure the other.
Workarounds:
1º option - Always configure the 2 timers at the same time if you can.
2º option - If you can't assure that you will configure the 2 at the same time the only option is editing the register. Ex: Create your own (pretty simple in this case) function:
void User_TimerConfigure(uint32_t _base, uint32_t _timer, uint32_t _config){ // // Disable the timers. // HWREG(_base + TIMER_O_CTL) &= ~(TIMER_CTL_TAEN | TIMER_CTL_TBEN); // // Set the global timer configuration. // HWREG(_base + TIMER_O_CFG) = _config >> 24; /* * Configure the timers * Allows to configure both at the time as well only 1 */ if( (_timer & 0xff) == TIMER_A) HWREG(_base + TIMER_O_TAMR) = ((_config & 0xff) | TIMER_TAMR_TAPWMIE); if( (_timer & 0xff00) == TIMER_B) HWREG(_base + TIMER_O_TBMR) = (((_config >> 8) & 0xff) | TIMER_TBMR_TBPWMIE); }
This is just what I think how the function should work.
Correct me if I am saying something wrong and/or if my problem was related to something else.