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.