cpu/sam3: adapted to PWM interface changes
This commit is contained in:
parent
b41f915d86
commit
ba8cda7894
@ -19,37 +19,25 @@
|
|||||||
*/
|
*/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
#include "periph_conf.h"
|
||||||
|
|
||||||
|
/* guard file in case no PWM device is defined */
|
||||||
|
#if (PWM_0_EN || PWM_1_EN)
|
||||||
|
|
||||||
|
/* pull the PWM header inside the guards for now. Guards will be removed on
|
||||||
|
* adapting this driver implementation... */
|
||||||
#include "periph/pwm.h"
|
#include "periph/pwm.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* guard file in case no PWM device is defined,
|
|
||||||
*/
|
|
||||||
#if PWM_NUMOF && PWM_0_EN
|
|
||||||
|
|
||||||
#define ERR_INIT_MODE (-1)
|
|
||||||
#define ERR_INIT_BWTH (-2)
|
|
||||||
#define ERR_SET_CHAN (-1)
|
|
||||||
#define MCK_DIV_LB_MAX (10U)
|
#define MCK_DIV_LB_MAX (10U)
|
||||||
|
|
||||||
int pwm_init(pwm_t dev, pwm_mode_t mode,
|
uint32_t pwm_init(pwm_t dev, pwm_mode_t mode, uint32_t freq, uint16_t res)
|
||||||
unsigned int frequency,
|
|
||||||
unsigned int resolution)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
int32_t retval = ERR_INIT_MODE; /* Worst/First case */
|
|
||||||
uint32_t pwm_clk = 0; /* Desired/real pwm_clock */
|
uint32_t pwm_clk = 0; /* Desired/real pwm_clock */
|
||||||
uint32_t diva = 1; /* Candidate for 8bit divider */
|
uint32_t diva = 1; /* Candidate for 8bit divider */
|
||||||
uint32_t prea = 0; /* Candidate for clock select */
|
uint32_t prea = 0; /* Candidate for clock select */
|
||||||
|
|
||||||
switch (dev) {
|
if (dev != PWM_0) {
|
||||||
#if PWM_0_EN
|
return 0;
|
||||||
|
|
||||||
case PWM_0:
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
return ERR_INIT_MODE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -63,18 +51,18 @@ int pwm_init(pwm_t dev, pwm_mode_t mode,
|
|||||||
case PWM_RIGHT:
|
case PWM_RIGHT:
|
||||||
case PWM_CENTER:
|
case PWM_CENTER:
|
||||||
default:
|
default:
|
||||||
return ERR_INIT_MODE;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Should check if "|log_2 frequency|+|log_2 resolution| <= 32" */
|
/* Should check if "|log_2 frequency|+|log_2 resolution| <= 32" */
|
||||||
pwm_clk = frequency * resolution;
|
pwm_clk = freq * res;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The pwm provides 11 prescaled clocks with (MCK/2^prea | prea=[0,10])
|
* The pwm provides 11 prescaled clocks with (MCK/2^prea | prea=[0,10])
|
||||||
* and a divider (diva) with a denominator range [1,255] in line.
|
* and a divider (diva) with a denominator range [1,255] in line.
|
||||||
*/
|
*/
|
||||||
if (CLOCK_CORECLOCK < pwm_clk) { /* Have to cut down resulting frequency. */
|
if (CLOCK_CORECLOCK < pwm_clk) { /* Have to cut down resulting frequency. */
|
||||||
frequency = CLOCK_CORECLOCK / resolution;
|
freq = CLOCK_CORECLOCK / res;
|
||||||
}
|
}
|
||||||
else { /* Estimate prescaler and divider. */
|
else { /* Estimate prescaler and divider. */
|
||||||
diva = CLOCK_CORECLOCK / pwm_clk;
|
diva = CLOCK_CORECLOCK / pwm_clk;
|
||||||
@ -84,11 +72,9 @@ int pwm_init(pwm_t dev, pwm_mode_t mode,
|
|||||||
diva = diva >> 1;
|
diva = diva >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
frequency = CLOCK_CORECLOCK / ((resolution * diva) << prea);
|
freq = CLOCK_CORECLOCK / ((res * diva) << prea);
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = frequency;
|
|
||||||
|
|
||||||
/* Activate PWM block by enabling it's clock. */
|
/* Activate PWM block by enabling it's clock. */
|
||||||
PMC->PMC_PCER1 = PMC_PCER1_PID36;
|
PMC->PMC_PCER1 = PMC_PCER1_PID36;
|
||||||
|
|
||||||
@ -108,25 +94,25 @@ int pwm_init(pwm_t dev, pwm_mode_t mode,
|
|||||||
/* Set clock source, resolution, duty-cycle and enable */
|
/* Set clock source, resolution, duty-cycle and enable */
|
||||||
#if PWM_0_CHANNELS > 0
|
#if PWM_0_CHANNELS > 0
|
||||||
PWM_0_DEV_CH0->PWM_CMR = PWM_CMR_CPRE_CLKA;
|
PWM_0_DEV_CH0->PWM_CMR = PWM_CMR_CPRE_CLKA;
|
||||||
PWM_0_DEV_CH0->PWM_CPRD = resolution - 1;
|
PWM_0_DEV_CH0->PWM_CPRD = res - 1;
|
||||||
PWM_0_DEV_CH0->PWM_CDTY = 0;
|
PWM_0_DEV_CH0->PWM_CDTY = 0;
|
||||||
PWM_0_DEV->PWM_ENA = PWM_0_ENA_CH0;
|
PWM_0_DEV->PWM_ENA = PWM_0_ENA_CH0;
|
||||||
#endif
|
#endif
|
||||||
#if PWM_0_CHANNELS > 1
|
#if PWM_0_CHANNELS > 1
|
||||||
PWM_0_DEV_CH1->PWM_CMR = PWM_CMR_CPRE_CLKA;
|
PWM_0_DEV_CH1->PWM_CMR = PWM_CMR_CPRE_CLKA;
|
||||||
PWM_0_DEV_CH1->PWM_CPRD = resolution - 1;
|
PWM_0_DEV_CH1->PWM_CPRD = res - 1;
|
||||||
PWM_0_DEV_CH1->PWM_CDTY = 0;
|
PWM_0_DEV_CH1->PWM_CDTY = 0;
|
||||||
PWM_0_DEV->PWM_ENA = PWM_0_ENA_CH1;
|
PWM_0_DEV->PWM_ENA = PWM_0_ENA_CH1;
|
||||||
#endif
|
#endif
|
||||||
#if PWM_0_CHANNELS > 2
|
#if PWM_0_CHANNELS > 2
|
||||||
PWM_0_DEV_CH2->PWM_CMR = PWM_CMR_CPRE_CLKA;
|
PWM_0_DEV_CH2->PWM_CMR = PWM_CMR_CPRE_CLKA;
|
||||||
PWM_0_DEV_CH2->PWM_CPRD = resolution - 1;
|
PWM_0_DEV_CH2->PWM_CPRD = res - 1;
|
||||||
PWM_0_DEV_CH2->PWM_CDTY = 0;
|
PWM_0_DEV_CH2->PWM_CDTY = 0;
|
||||||
PWM_0_DEV->PWM_ENA = PWM_0_ENA_CH2;
|
PWM_0_DEV->PWM_ENA = PWM_0_ENA_CH2;
|
||||||
#endif
|
#endif
|
||||||
#if PWM_0_CHANNELS > 3
|
#if PWM_0_CHANNELS > 3
|
||||||
PWM_0_DEV_CH3->PWM_CMR = PWM_CMR_CPRE_CLKA;
|
PWM_0_DEV_CH3->PWM_CMR = PWM_CMR_CPRE_CLKA;
|
||||||
PWM_0_DEV_CH3->PWM_CPRD = resolution - 1;
|
PWM_0_DEV_CH3->PWM_CPRD = res - 1;
|
||||||
PWM_0_DEV_CH3->PWM_CDTY = 0;
|
PWM_0_DEV_CH3->PWM_CDTY = 0;
|
||||||
PWM_0_DEV->PWM_ENA = PWM_0_ENA_CH3;
|
PWM_0_DEV->PWM_ENA = PWM_0_ENA_CH3;
|
||||||
#endif
|
#endif
|
||||||
@ -154,17 +140,24 @@ int pwm_init(pwm_t dev, pwm_mode_t mode,
|
|||||||
PWM_0_PORT_CH3->PIO_ABSR |= PWM_0_PIN_CH3;
|
PWM_0_PORT_CH3->PIO_ABSR |= PWM_0_PIN_CH3;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return retval;
|
return freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t pwm_channels(pwm_t dev)
|
||||||
|
{
|
||||||
|
if (dev == 0) {
|
||||||
|
return PWM_0_CHANNELS;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update duty-cycle in channel with value.
|
* Update duty-cycle in channel with value.
|
||||||
* If value is larger than resolution set by pwm_init() it is cropped.
|
* If value is larger than resolution set by pwm_init() it is cropped.
|
||||||
*/
|
*/
|
||||||
int pwm_set(pwm_t dev, int channel, unsigned int value)
|
void pwm_set(pwm_t dev, uint8_t channel, uint16_t value)
|
||||||
{
|
{
|
||||||
|
|
||||||
int retval = ERR_SET_CHAN; /* Worst case */
|
|
||||||
uint32_t period = 0; /* Store pwm period */
|
uint32_t period = 0; /* Store pwm period */
|
||||||
PwmCh_num *chan = (void *)0; /* Addressed channel. */
|
PwmCh_num *chan = (void *)0; /* Addressed channel. */
|
||||||
|
|
||||||
@ -176,7 +169,7 @@ int pwm_set(pwm_t dev, int channel, unsigned int value)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ERR_SET_CHAN;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -207,7 +200,7 @@ int pwm_set(pwm_t dev, int channel, unsigned int value)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
retval = ERR_SET_CHAN;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan) {
|
if (chan) {
|
||||||
@ -220,11 +213,7 @@ int pwm_set(pwm_t dev, int channel, unsigned int value)
|
|||||||
else { /* Value Out of range. Clip silent as required by interface. */
|
else { /* Value Out of range. Clip silent as required by interface. */
|
||||||
chan->PWM_CDTYUPD = period;
|
chan->PWM_CDTYUPD = period;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -288,4 +277,4 @@ void pwm_poweroff(pwm_t dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* PWM_NUMOF */
|
#endif /* (PWM_0_EN || PWM_1_EN) */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user