This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PWM initialization on at91sam7sek


Hi,

I am trying to use the pwm output functionality of the at91sam7s, but
I am not sure how to set it up correctly.
I tried to follow the instructions in the manual (AT91Sam7 series
preliminary), I guess I must have missed some important step.

Parallel IO and serial communication works fine, but using the pwm
produces no output on the pins.

Anyway here is my code:


//-------------------------------------------------------------------------------------------------

#include <cyg/kernel/kapi.h>

#include <cyg/hal/hal_diag.h>	// blinking led
#include <cyg/infra/diag.h>	// For diagnostic printing.


static void pwm_init(void);
static void pwm_set(int pct_value);

#define STOU_PWM_PIN AT91_PWM_PWM0

/// Configure the PWM output pins
void pwm_init(void)
{
  cyg_uint32 tmpStatus;


  // Disable all pwm outputs
  HAL_WRITE_UINT32(AT91_PWM + AT91_PWM_DIS, (1 << AT91_PWM_CHANNEL_ID_0));
  HAL_WRITE_UINT32(AT91_PWM + AT91_PWM_DIS, (1 << AT91_PWM_CHANNEL_ID_1));
  HAL_WRITE_UINT32(AT91_PWM + AT91_PWM_DIS, (1 << AT91_PWM_CHANNEL_ID_2));
  HAL_WRITE_UINT32(AT91_PWM + AT91_PWM_DIS, (1 << AT91_PWM_CHANNEL_ID_3));


  // configure clock generator
  // Enable the PWM clock generator in the power mannager
  HAL_WRITE_UINT32(AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_PWMC);

  HAL_READ_UINT32(AT91_PMC + AT91_PMC_PCSR, tmpStatus);
  diag_printf("1 addr: 0x%X, PMC_PCSR: 0x%X \n", AT91_PMC +
AT91_PMC_PCSR, tmpStatus);

  HAL_READ_UINT32(AT91_PMC + AT91_PMC_SCSR, tmpStatus);
  diag_printf("2 addr: 0x%X, PMC_SCSR: 0x%X \n", AT91_PMC +
AT91_PMC_SCSR, tmpStatus);

  HAL_READ_UINT32(AT91_PMC + AT91_PMC_SR, tmpStatus);
  diag_printf("2 addr: 0x%X, PMC_SR: 0x%X \n", AT91_PMC + AT91_PMC_SR,
tmpStatus);


  HAL_READ_UINT32(AT91_AIC + AT91_AIC_IMR, tmpStatus);
  diag_printf("AIC_IMR addr: 0x%X, AIC_IMR: 0x%X \n", AT91_AIC +
AT91_AIC_IMR, tmpStatus);
  // Enable the PWM interrupt
//  HAL_WRITE_UINT32(AT91_AIC + AT91_AIC_IECR, (1 <<
CYGNUM_HAL_INTERRUPT_PWMC));
  HAL_WRITE_UINT32(AT91_AIC + AT91_AIC_IECR, (1 << CYGNUM_HAL_INTERRUPT_SYS));
  HAL_READ_UINT32(AT91_AIC + AT91_AIC_IMR, tmpStatus);
  diag_printf("1 AIC_IMR addr: 0x%X, tmpStatus: 0x%X \n", AT91_AIC +
AT91_AIC_IMR, tmpStatus);


  // setup clock prescaling
  HAL_WRITE_UINT32(AT91_PWM + AT91_PWM_MR,
       AT91_PWM_MR_PREA_MCK_BY_1024 | (1 << AT91_PWM_MR_DIVA_SHIFT) |
       AT91_PWM_MR_PREB_MCK_BY_512 | (1 << AT91_PWM_MR_DIVB_SHIFT));

  // select clock A,  alignment, polarity, and notification type
  HAL_WRITE_UINT32(AT91_PWM_CH0 + AT91_PWM_CMR,
		   AT91_PWM_CMR_CALG_LEFT | AT91_PWM_CMR_CPOL_HIGH
		   | AT91_PWM_CPD_DUTY | AT91_PWM_CMR_CPRE_MCK_BY_512);
  //AT91_PWM_CMR_CPRE_MCK_A

  // setup period register
  HAL_WRITE_UINT32(AT91_PWM_CH0 + AT91_PWM_CPRDR, 128);

  // Setup duty cycle (initial setting is zero = OFF)
//  HAL_WRITE_UINT32(AT91_PWM_CH0 + AT91_PWM_CDTY,0);
  HAL_WRITE_UINT32(AT91_PWM_CH0 + AT91_PWM_CDTY, 32);	// debug


  // Enable PWM interrupts
  HAL_WRITE_UINT32(AT91_PWM + AT91_PWM_IER, (1 << AT91_PWM_CHANNEL_ID_0));

  // Enable the pwm generator for channels
  HAL_WRITE_UINT32(AT91_PWM + AT91_PWM_ENA, (1 << AT91_PWM_CHANNEL_ID_0));

  // configure pin as output
  HAL_ARM_AT91_GPIO_CFG_DIRECTION(STOU_PWM_PIN, AT91_PIN_OUT);
}


///  set the value of the pwm output
void pwm_set(int pct_value)
{
  cyg_uint32 tmpval = (pct_value * 128) / 100;
  if ((0 > pct_value) || (pct_value > 100)) {
    diag_printf("value out of range, pct_value %d, tmpval %d\n", pct_value,
		tmpval);
    tmpval = 0;
  }

  tmpval = 64;			// debug

  diag_printf("pwm_set(): pct_value %d, tmpval %d\n", pct_value, tmpval);
  HAL_WRITE_UINT32(AT91_PWM_CH0 + AT91_PWM_CUPDR, tmpval);

}



 //
 // Main starting point for the application.
int main(void)
{
  diag_printf("Starting main() \n");

  for (;;) {
    diag_printf("Turning off all LEDs ...\n");
    hal_diag_led(0x0);

    cyg_thread_delay(100);
    hal_diag_led(0xa);
    cyg_thread_delay(100);
    hal_diag_led(0x0);

    diag_printf("Configuring PWM\n");
    pwm_init();

    pwm_set(0);
    cyg_thread_delay(100);
    pwm_set(50);
    cyg_thread_delay(100);
    pwm_set(70);
  }

}

//-------------------------------------------------------------------------------------------------


This is the output produced in the terminal when running:

[snip]
Turning off all LEDs ...
Configuring PWM
1 addr: 0xFFFFFC18, PMC_PCSR: 0x54C0
2 addr: 0xFFFFFC08, PMC_SCSR: 0x1
2 addr: 0xFFFFFC68, PMC_SR: 0xD
AIC_IMR addr: 0xFFFFF110, AIC_IMR: 0x1002
1 AIC_IMR addr: 0xFFFFF110, tmpStatus: 0x1002
pwm_set(): pct_value 0, tmpval 64
pwm_set(): pct_value 50, tmpval 64
pwm_set(): pct_value 70, tmpval 64
Turning off all LEDs ...
[/snip]


Regards
Rasmus Stougaard

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]