Other Parts Discussed in Thread: SYSBIOS
Tool/software: TI-RTOS
I am using TI-RTOS 2.16.00.08 on the TM4C123GH6PM. I am trying to use some of the Timer module PWMs. The first problem I has was in the setup file when adding the line:
#include <ti/drivers/PWM.h> #include <ti/drivers/pwm/PWMTimerTiva.h> PWMTimerTiva_Object pwmTimerTivaObjects[SCU_REV_A_PWMCOUNT]; const PWMTimerTiva_HWAttrs pwmTimerTivaHWAttrs[] = { { .baseAddr = TIMER1_BASE, .timer = TIMER_A }, { .baseAddr = TIMER1_BASE, .timer = TIMER_B }, { .baseAddr = WTIMER2_BASE, .timer = TIMER_A }, { .baseAddr = WTIMER2_BASE, .timer = TIMER_B }, { .baseAddr = WTIMER3_BASE, .timer = TIMER_A }, { .baseAddr = WTIMER3_BASE, .timer = TIMER_B } };
Since driverlib/timer.h was not included in any of the files the TIME_A was not defined. I fixed this by adding "#include <driverlib/timer.h>" into the PWMTimerTiva.h file. I just want to check if this is the best solution or if there is a better way of fixing it? Also feel like this is something that should be fixed in the driver files when downloaded.
The next problem I had was that the wide timers do not initiate and return with NULL. The problem appears to be with the following lines in the PWMTimerTiva.c:
kernelTimerID = 1 << ((hwAttrs->baseAddr >> 12) & 0xF); timerPairEnabledBit = (TIMER_BOTH & (~hwAttrs->timer)) & (TIMER_CTL_TAEN | TIMER_CTL_TBEN); if (kernelTimerID & Timer_getAvailMask()) { /* Timer unused, claim timer from Kernel */ kernelTimerID = (~kernelTimerID) & 0x0F; Timer_setAvailMask(Timer_getAvailMask() & kernelTimerID); } else if (!(HWREG(hwAttrs->baseAddr + TIMER_O_CTL) & timerPairEnabledBit)) { /* Timer used and was not initialized by the other half timer */ Hwi_restore(key); return (NULL); }
The Timer_getAvailMask() seems to return 0b111100 and the Timer_getNumTimers() returns 6. This seems to indicate that there are only the first 6 drivers initiated in the bios which would leave the wide-timers inaccessible. Is there a way to change this so that the rest of the timer modules are accessible or are they already being used by the BIOS and therefore can't use them for PWM?
In addition to that kernelTimerID = 1 << ((hwAttrs->baseAddr >> 12) & 0xF); only works for TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5 and maybe WTIMER0 and WTIMER1 i havn't tried them all out. This is because there is a break in the base address of the timers and the kernelTimerID is base address dependent. The timer base addresses from hw_memmap.h are below:
#define TIMER0_BASE 0x40030000 // Timer0 #define TIMER1_BASE 0x40031000 // Timer1 #define TIMER2_BASE 0x40032000 // Timer2 #define TIMER3_BASE 0x40033000 // Timer3 #define TIMER4_BASE 0x40034000 // Timer4 #define TIMER5_BASE 0x40035000 // Timer5 #define WTIMER0_BASE 0x40036000 // Wide Timer0 #define WTIMER1_BASE 0x40037000 // Wide Timer1 #define WTIMER2_BASE 0x4004C000 // Wide Timer2 #define WTIMER3_BASE 0x4004D000 // Wide Timer3 #define WTIMER4_BASE 0x4004E000 // Wide Timer4 #define WTIMER5_BASE 0x4004F000 // Wide Timer5 #define TIMER6_BASE 0x400E0000 // General-Purpose Timers #define TIMER7_BASE 0x400E1000 // General-Purpose Timers
Finally, the checking to make sure that the timer module is not already open in the BIOS seems insufficient. If the module is being used in the Timer_getAvailMask(), then if the TIMER_A is being initiated it checks to see if the TIMER_B module is in use. If it is in use then it assumes that the module was initiated by the TIMER_B part of the module, but it does not check if the TIMER_A is already initiated and therefore could attempt to over wright a previous initiation. It could also happen that the TIMER_B is being initiated, if the BIOS already initiated the module as a full 32 bit (in 16/32 bit module) then it will check if TIMER_A is initiated, which will be true. It will then over wright the full timer with the half timer. Has anybody else had these problems, I am new to TI-RTOS and am not sure if it is an actual problem? Are there any fixes to these problems available?