This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
PWM initialization on at91sam7sek
- From: "Rasmus Stougaard" <stou dot nospam at gmail dot com>
- To: ecos-discuss at ecos dot sourceware dot org
- Date: Thu, 11 Oct 2007 14:44:25 +0200
- Subject: [ECOS] 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