Estoy intentando encender el LED rojo en un Stellaris LaunchPad, siguiendo la receta en la hoja de datos p.706 , tomando un par de accesos directos de la Stellaris® Peripheral Driver Library . No puedo entender por qué el LED no brilla. Espero un ciclo de trabajo del 50% a 5 kHz PWM. ¿Alguien ve lo que estoy pasando por alto aquí?
EDITAR: En la media mientras estrechaba el problema. Si incluyo una línea extra:
ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PWM);
en la viñeta 2 el programa comienza a funcionar. Esto es lo que quiero decir en mis comentarios de que las llamadas a la ROM no están muy bien documentadas ya que es difícil identificar qué registros se escriben realmente.
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/cpu.c"
#include "driverlib/gpio.h"
#include "driverlib/rom.h"
#include "inc/hw_sysctl.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.c"
#include <stdint.h>
#define LED_RED GPIO_PIN_1
int main() {
// Set system clock to 80 MHz using PLL and external 16 MHz crystal.
ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
// Enable GPIO for LED.
ROM_SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOF );
ROM_GPIOPinWrite( GPIO_PORTF_BASE , LED_RED , 0x00 );
ROM_GPIOPinTypeGPIOOutput( GPIO_PORTF_BASE , LED_RED );
// Enable timer peripheral.
ROM_SysCtlPeripheralEnable( SYSCTL_PERIPH_TIMER0 );
// the GP Timer module clock must be enabled before the registers can be programmed (see page 313 or page 330).
HWREG( SYSCTL_RCGCTIMER ) |= SYSCTL_RCGCTIMER_R0;
// There must be a delay of 3 system clocks after the Timer module clock is enabled before any Timer module registers are accessed.
ROM_SysCtlDelay( 1 );
// Configure output pin for PWM use.
ROM_GPIOPinConfigure( GPIO_PF1_T0CCP1 );
ROM_GPIOPinTypeTimer( GPIO_PORTF_BASE , LED_RED ); //ROM_GPIOPinTypePWM( GPIO_PORTF_BASE , LED_RED ); => No PWM units on board, the timers are used for PWM.
// LED_RED on PF1 is convenient.
// PF1: T0CCP1 => 16/32-Bit Timer 0 Capture/Compare/PWM 1. (muxed with: PB7)
// PWM 1 implies use of Timer B
// PWM Mode
// A timer is configured to PWM mode using the following sequence:
// 1. Ensure the timer is disabled (the TnEN bit is cleared) before making any changes.
ROM_TimerDisable( TIMER0_BASE , TIMER_B );
// 2. Write the GPTM Configuration (GPTMCFG) register with a value of 0x0000.0004.
HWREG( TIMER0_BASE + 0x000 ) = 0x00000004;
// 3.In the GPTM Timer Mode (GPTMTnMR) register, set the TnAMS bit to 0x1, the TnCMR bit to 0x0, and the TnMR field to 0x2.
HWREG( TIMER0_BASE + 0x004 ) |= TIMER_TBMR_TBAMS | TIMER_TBMR_TBMR_PERIOD;
// 4. Configure the output state of the PWM signal (whether or not it is inverted) in the TnPWML field of the GPTM Control (GPTMCTL) register.
HWREG( TIMER0_BASE + 0x00c ) |= 0; // TIMER_CTL_TAPWML
// 5. If a prescaler is to be used, write the prescale value to the GPTM Timer n Prescale Register (GPTMTnPR).
//HWREG( TIMER0_BASE + 0x038 ) = ...
// 6. If PWM interrupts are used, configure the interrupt condition in the TnEVENT field in the
// GPTMCTL register and enable the interrupts by setting the TnPWMIE bit in the GPTMTnMR
// register. Note that edge detect interrupt behavior is reversed when the PWM output is inverted
//HWREG( TIMER0_BASE + 0x00c ) |= ...
// 7. Load the timer start value into the GPTM Timer n Interval Load (GPTMTnILR) register.
HWREG( TIMER0_BASE + 0x02c ) = 16000 - 1; // 16000 @ 80MHz system clock makes 5 kHz PWM
// 8. Load the GPTM Timer n Match (GPTMTnMATCHR) register with the match value.
HWREG( TIMER0_BASE + 0x034 ) = 8000 - 1; // Defines duty cycle
// 9. Set the TnEN bit in the GPTM Control (GPTMCTL) register to enable the timer and begin generation of the output PWM signal.
HWREG( TIMER0_BASE + 0x00c ) |= TIMER_CTL_TBEN;
// In PWM Timing mode, the timer continues running after the PWM signal has been generated. The
// PWM period can be adjusted at any time by writing the GPTMTnILR register, and the change takes
// effect at the next cycle after the write.
while ( 1 ) {
}
}