1
0
Fork 0
forked from nuttx/nuttx-update

SAMA5 PWM: Driver now in build and configuration system

This commit is contained in:
Gregory Nutt 2013-11-06 12:24:51 -06:00
parent e73d77c73f
commit b5791ac7a6
7 changed files with 399 additions and 132 deletions

View file

@ -5974,4 +5974,7 @@
* arch/arm/src/sama5/sam_pwm.c and .h: Add PWM driver for SAMA5
untested on initial checkout (not even incorporated in to build
system) (2013-11-6).
* arch/arm/src/sama5/Make.defs and Kconfig: SAMA5 PWM driver now
incorporated into build and configuration system. Builds with
no errors (2013-11-6).

View file

@ -196,6 +196,7 @@ config SAMA5_TC1
config SAMA5_PWM
bool "Pulse Width Modulation Controller (PWM)"
default n
select PWM
config SAMA5_ADC
bool "Touch Screen ADC Controller (ADC)"
@ -2368,6 +2369,239 @@ endif # SAMA5_TSD
endmenu # Touchscreen Configuration
endif # SAMA5_ADC
if SAMA5_PWM
menu "PWM configuration"
config SAMA5_PWM_CLKA
bool "Enable PWM CLKA"
default n
---help---
Enable the PWM CLKA source.
config SAMA5_PWM_CLKA_FREQUENCY
int "CLKA frequency"
default 100
depends on SAMA5_PWM_CLKA
---help---
If the CLKA source is enabled, then you must also provide the
frequency of the CLKA. This frequency will be derived from from MCK
using a prescaler and divider. Therefore, a wide range of
frequencies are possible.
config SAMA5_PWM_CLKB
bool "Enable PWM CLKB"
default n
---help---
Enable the PWM CLKB source.
config SAMA5_PWM_CLKB_FREQUENCY
int "CLKB frequency"
default 100
depends on SAMA5_PWM_CLKB
---help---
If the CLKB source is enabled, then you must also provide the
frequency of the CLKB. This frequency will be derived from from MCK
using a prescaler and divider. Therefore, a wide range of
frequencies are possible.
config SAMA5_PWM_CHAN0
bool "Enable PWM channel 0"
default n
if SAMA5_PWM_CHAN0
choice
prompt "PWM channel 0 clock source"
default SAMA5_PWM_CHAN0_MCK
config SAMA5_PWM_CHAN0_MCK
bool "MCK (divided)"
config SAMA5_PWM_CHAN0_CLKA
bool "CLKA"
depends on SAMA5_PWM_CLKA
config SAMA5_PWM_CHAN0_CLKB
bool "CLKB"
depends on SAMA5_PWM_CLKB
endchoice # PWM channel 0 clock source
config SAMA5_PWM_CHAN0_MCKDIV
int "MCK divider"
default 1
depends on SAMA5_PWM_CHAN0_MCK
---help---
If source clock for the PWM channel is the MCK, then you must also
specify the MCK divider to use with the MCK. The only valid options
are 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, and 1024. Other
selections will cause compile time errors.
config SAMA5_PWM_CHAN0_OUTPUTH
bool "Configure OUTPUT H pin"
default n
config SAMA5_PWM_CHAN0_OUTPUTL
bool "Configure OUTPUT L pin"
default n
config SAMA5_PWM_CHAN0_FAULTINPUT
bool "Configure Fault Input pin"
default n
endif # SAMA5_PWM_CHAN0
config SAMA5_PWM_CHAN1
bool "Enable PWM channel 1"
default n
if SAMA5_PWM_CHAN1
choice
prompt "PWM channel 1 clock source"
default SAMA5_PWM_CHAN1_MCK
config SAMA5_PWM_CHAN1_MCK
bool "MCK (divided)"
config SAMA5_PWM_CHAN1_CLKA
bool "CLKA"
depends on SAMA5_PWM_CLKA
config SAMA5_PWM_CHAN1_CLKB
bool "CLKB"
depends on SAMA5_PWM_CLKB
endchoice # PWM channel 1 clock source
config SAMA5_PWM_CHAN1_MCKDIV
int "MCK divider"
default 1
depends on SAMA5_PWM_CHAN1_MCK
---help---
If source clock for the PWM channel is the MCK, then you must also
specify the MCK divider to use with the MCK. The only valid options
are 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, and 1024. Other
selections will cause compile time errors.
config SAMA5_PWM_CHAN1_OUTPUTH
bool "Configure OUTPUT H pin"
default n
config SAMA5_PWM_CHAN1_OUTPUTL
bool "Configure OUTPUT L pin"
default n
config SAMA5_PWM_CHAN1_FAULTINPUT
bool "Configure Fault Input pin"
default n
endif # SAMA5_PWM_CHAN1
config SAMA5_PWM_CHAN2
bool "Enable PWM channel 2"
default n
if SAMA5_PWM_CHAN2
choice
prompt "PWM channel 2 clock source"
default SAMA5_PWM_CHAN2_MCK
config SAMA5_PWM_CHAN2_MCK
bool "MCK (divided)"
config SAMA5_PWM_CHAN2_CLKA
bool "CLKA"
depends on SAMA5_PWM_CLKA
config SAMA5_PWM_CHAN2_CLKB
bool "CLKB"
depends on SAMA5_PWM_CLKB
endchoice # PWM channel 2 clock source
config SAMA5_PWM_CHAN2_MCKDIV
int "MCK divider"
default 1
depends on SAMA5_PWM_CHAN2_MCK
---help---
If source clock for the PWM channel is the MCK, then you must also
specify the MCK divider to use with the MCK. The only valid options
are 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, and 1024. Other
selections will cause compile time errors.
config SAMA5_PWM_CHAN2_OUTPUTH
bool "Configure OUTPUT H pin"
default n
config SAMA5_PWM_CHAN2_OUTPUTL
bool "Configure OUTPUT L pin"
default n
config SAMA5_PWM_CHAN2_FAULTINPUT
bool "Configure Fault Input pin"
default n
endif # SAMA5_PWM_CHAN2
config SAMA5_PWM_CHAN3
bool "Enable PWM channel 3"
default n
if SAMA5_PWM_CHAN3
choice
prompt "PWM channel 3 clock source"
default SAMA5_PWM_CHAN3_MCK
config SAMA5_PWM_CHAN3_MCK
bool "MCK (divided)"
config SAMA5_PWM_CHAN3_CLKA
bool "CLKA"
depends on SAMA5_PWM_CLKA
config SAMA5_PWM_CHAN3_CLKB
bool "CLKB"
depends on SAMA5_PWM_CLKB
endchoice # PWM channel 3 clock source
config SAMA5_PWM_CHAN3_MCKDIV
int "MCK divider"
default 1
depends on SAMA5_PWM_CHAN3_MCK
---help---
If source clock for the PWM channel is the MCK, then you must also
specify the MCK divider to use with the MCK. The only valid options
are 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, and 1024. Other
selections will cause compile time errors.
config SAMA5_PWM_CHAN3_OUTPUTH
bool "Configure OUTPUT H pin"
default n
config SAMA5_PWM_CHAN3_OUTPUTL
bool "Configure OUTPUT L pin"
default n
config SAMA5_PWM_CHAN3_FAULTINPUT
bool "Configure Fault Input pin"
default n
endif # SAMA5_PWM_CHAN3
config SAMA5_PWM_REGDEBUG
bool "Enable register-level PWM debug"
default n
depends on DEBUG
---help---
Enable very low register-level debug output.
endmenu # PWM configuration
endif # SAMA5_PWM
if SAMA5_WDT
menu "Watchdog Configuration"

View file

@ -205,6 +205,10 @@ CHIP_CSRCS += sam_tsd.c
endif
endif
ifeq ($(CONFIG_SAMA5_PWM),y)
CHIP_CSRCS += sam_pwm.c
endif
ifeq ($(CONFIG_SAMA5_TC0),y)
CHIP_CSRCS += sam_tc.c
else

View file

@ -48,6 +48,8 @@
#include <nuttx/arch.h>
#include <nuttx/pwm.h>
#include "chip/sam_pinmap.h"
#include <arch/board/board.h>
#include "up_internal.h"
@ -105,48 +107,48 @@
# error CONFIG_SAMA5_PWM_CLKA_FREQUENCY is not defined
# elif (BOARD_MCK_FREQUENCY / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256
# define PWM_CLK_PREA PWM_CLK_PREA_DIV1
# define CLKA_PRE 1
# define CLKA_PRE_BITS PWM_CLK_PREA_DIV1
# define CLKA_PRE 1
# elif (BOARD_MCK_FREQUENCY / 2 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256
# define PWM_CLK_PREA PWM_CLK_PREA_DIV2
# define CLKA_PRE 2
# define CLKA_PRE_BITS PWM_CLK_PREA_DIV2
# define CLKA_PRE 2
# elif (BOARD_MCK_FREQUENCY / 4 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256
# define PWM_CLK_PREA PWM_CLK_PREA_DIV4
# define CLKA_PRE 4
# define CLKA_PRE_BITS PWM_CLK_PREA_DIV4
# define CLKA_PRE 4
# elif (BOARD_MCK_FREQUENCY / 8 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256
# define PWM_CLK_PREA PWM_CLK_PREA_DIV8
# define CLKA_PRE 8
# define CLKA_PRE_BITS PWM_CLK_PREA_DIV8
# define CLKA_PRE 8
# elif (BOARD_MCK_FREQUENCY / 16 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256
# define PWM_CLK_PREA PWM_CLK_PREA_DIV16
# define CLKA_PRE 16
# define CLKA_PRE_BITS PWM_CLK_PREA_DIV16
# define CLKA_PRE 16
# elif (BOARD_MCK_FREQUENCY / 32 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256
# define PWM_CLK_PREA PWM_CLK_PREA_DIV32
# define CLKA_PRE 32
# define CLKA_PRE_BITS PWM_CLK_PREA_DIV32
# define CLKA_PRE 32
# elif (BOARD_MCK_FREQUENCY / 64 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256
# define PWM_CLK_PREA PWM_CLK_PREA_DIV64
# define CLKA_PRE 64
# define CLKA_PRE_BITS PWM_CLK_PREA_DIV64
# define CLKA_PRE 64
# elif (BOARD_MCK_FREQUENCY / 128 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256
# define PWM_CLK_PREA PWM_CLK_PREA_DIV128
# define CLKA_PRE 128
# define CLKA_PRE_BITS PWM_CLK_PREA_DIV128
# define CLKA_PRE 128
# elif (BOARD_MCK_FREQUENCY / 256 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256
# define PWM_CLK_PREA PWM_CLK_PREA_DIV256
# define CLKA_PRE 256
# define CLKA_PRE_BITS PWM_CLK_PREA_DIV256
# define CLKA_PRE 256
# elif (BOARD_MCK_FREQUENCY / 512 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256
# define PWM_CLK_PREA PWM_CLK_PREA_DIV512
# define CLKA_PRE 512
# define CLKA_PRE_BITS PWM_CLK_PREA_DIV512
# define CLKA_PRE 512
# elif (BOARD_MCK_FREQUENCY / 1024 / CONFIG_SAMA5_PWM_CLKA_FREQUENCY) < 256
# define PWM_CLK_PREA PWM_CLK_PREA_DIV1024
# define CLKA_PRE 1024
# define CLKA_PRE_BITS PWM_CLK_PREA_DIV1024
# define CLKA_PRE 1024
# else
# error Cannot realize CONFIG_SAMA5_PWM_CLKA_FREQUENCY
@ -154,12 +156,12 @@
# define CLKA_DIV (BOARD_MCK_FREQUENCY / CLKA_PRE / CONFIG_SAMA5_PWM_CLKA_FREQUENCY)
# define CLKA_FREQUENCY (BOARD_MCK_FREQUENCY / CLKA_PRE / CLKA_DIV)
# define PWM_CLK_DIVA PWM_CLK_DIVA(CLKA_DIV)
# define CLKA_DIV_BITS PWM_CLK_DIVA(CLKA_DIV)
#else
# undef CONFIG_SAMA5_PWM_CLKA_FREQUENCY
# define PWM_CLK_PREA PWM_CLK_PREA_DIV1
# define PWM_CLK_DIVA PWM_CLK_DIVA_OFF
# undef CONFIG_SAMA5_PWM_CLKA_FREQUENCY
# define CLKA_PRE_BITS PWM_CLK_PREA_DIV1
# define CLKA_DIV_BITS PWM_CLK_DIVA_OFF
#endif
#ifdef CONFIG_SAMA5_PWM_CLKB
@ -168,61 +170,61 @@
# error CONFIG_SAMA5_PWM_CLKB_FREQUENCY is not defined
# elif (BOARD_MCK_FREQUENCY / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256
# define PWM_CLK_PREB PWM_CLK_PREB_DIV1
# define CLKB_PRE 1
# define CLKB_PRE_BITS PWM_CLK_PREB_DIV1
# define CLKB_PRE 1
# elif (BOARD_MCK_FREQUENCY / 2 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256
# define PWM_CLK_PREB PWM_CLK_PREB_DIV2
# define CLKB_PRE 2
# define CLKB_PRE_BITS PWM_CLK_PREB_DIV2
# define CLKB_PRE 2
# elif (BOARD_MCK_FREQUENCY / 4 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256
# define PWM_CLK_PREB PWM_CLK_PREB_DIV4
# define CLKB_PRE 4
# define CLKB_PRE_BITS PWM_CLK_PREB_DIV4
# define CLKB_PRE 4
# elif (BOARD_MCK_FREQUENCY / 8 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256
# define PWM_CLK_PREB PWM_CLK_PREB_DIV8
# define CLKB_PRE 8
# define CLKB_PRE_BITS PWM_CLK_PREB_DIV8
# define CLKB_PRE 8
# elif (BOARD_MCK_FREQUENCY / 16 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256
# define PWM_CLK_PREB PWM_CLK_PREB_DIV16
# define CLKB_PRE 16
# define CLKB_PRE_BITS PWM_CLK_PREB_DIV16
# define CLKB_PRE 16
# elif (BOARD_MCK_FREQUENCY / 32 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256
# define PWM_CLK_PREB PWM_CLK_PREB_DIV32
# define CLKB_PRE 32
# define CLKB_PRE_BITS PWM_CLK_PREB_DIV32
# define CLKB_PRE 32
# elif (BOARD_MCK_FREQUENCY / 64 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256
# define PWM_CLK_PREB PWM_CLK_PREB_DIV64
# define CLKB_PRE 64
# define CLKB_PRE_BITS PWM_CLK_PREB_DIV64
# define CLKB_PRE 64
# elif (BOARD_MCK_FREQUENCY / 128 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256
# define PWM_CLK_PREB PWM_CLK_PREB_DIV128
# define CLKB_PRE 128
# define CLKB_PRE_BITS PWM_CLK_PREB_DIV128
# define CLKB_PRE 128
# elif (BOARD_MCK_FREQUENCY / 256 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256
# define PWM_CLK_PREB PWM_CLK_PREB_DIV256
# define CLKB_PRE 256
# define CLKB_PRE_BITS PWM_CLK_PREB_DIV256
# define CLKB_PRE 256
# elif (BOARD_MCK_FREQUENCY / 512 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256
# define PWM_CLK_PREB PWM_CLK_PREB_DIV512
# define CLKB_PRE 512
# define CLKB_PRE_BITS PWM_CLK_PREB_DIV512
# define CLKB_PRE 512
# elif (BOARD_MCK_FREQUENCY / 1024 / CONFIG_SAMA5_PWM_CLKB_FREQUENCY) < 256
# define PWM_CLK_PREB PWM_CLK_PREB_DIV1024
# define CLKB_PRE 1024
# define CLKB_PRE_BITS PWM_CLK_PREB_DIV1024
# define CLKB_PRE 1024
# else
# error Cannot realize CONFIG_SAMA5_PWM_CLKB_FREQUENCY
# endif
# define CLKB_DIV (BOARD_MCK_FREQUENCY / CLKB_PRE / CONFIG_SAMA5_PWM_CLKB_FREQUENCY / )
# define CLKB_DIV (BOARD_MCK_FREQUENCY / CLKB_PRE / CONFIG_SAMA5_PWM_CLKB_FREQUENCY)
# define CLKB_FREQUENCY (BOARD_MCK_FREQUENCY / CLKB_PRE / CLKB_DIV)
# define PWM_CLK_DIVB PWM_CLK_DIVB(CLKB_DIV)
# define CLKB_DIV_BITS PWM_CLK_DIVB(CLKB_DIV)
#else
# undef CONFIG_SAMA5_PWM_CLKB_FREQUENCY
# define PWM_CLK_PREB PWM_CLK_PREB_DIV1
# define PWM_CLK_DIVB PWM_CLK_DIVB_OFF
# undef CONFIG_SAMA5_PWM_CLKB_FREQUENCY
# define CLKB_PRE_BITS PWM_CLK_PREB_DIV1
# define CLKB_DIV_BITS PWM_CLK_DIVB_OFF
#endif
#ifdef CONFIG_SAMA5_PWM_CHAN0
@ -230,27 +232,27 @@
# undef CONFIG_SAMA5_PWM_CHAN0_CLKA
# undef CONFIG_SAMA5_PWM_CHAN0_CLKB
# if CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 1
# SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 0
# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 0
# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 2
# SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 1
# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 1
# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 4
# SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 2
# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 2
# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 8
# SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 3
# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 3
# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 16
# SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 4
# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 4
# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 32
# SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 5
# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 5
# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 64
# SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 6
# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 6
# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 128
# SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 7
# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 7
# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 256
# SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 8
# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 8
# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 512
# SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 9
# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 9
# elif CONFIG_SAMA5_PWM_CHAN0_MCKDIV == 1024
# SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 10
# define SAMA5_PWM_CHAN0_MCKDIV_LOG2 = 10
# else
# error Unsupported MCK divider value
# endif
@ -269,27 +271,27 @@
# undef CONFIG_SAMA5_PWM_CHAN1_CLKA
# undef CONFIG_SAMA5_PWM_CHAN1_CLKB
# if CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 1
# SAMA5_PWM_CHAN1_MCKDIV_LOG2 = 0
# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 0
# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 2
# SAMA5_PWM_CHAN1_MCKDIV_LOG2 = 1
# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 1
# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 4
# SAMA5_PWM_CHAN1_MCKDIV_LOG2 = 2
# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 2
# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 8
# SAMA5_PWM_CHAN1_MCKDIV_LOG2 = 3
# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 3
# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 16
# SAMA5_PWM_CHAN1_MCKDIV_LOG2 = 4
# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 4
# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 32
# SAMA5_PWM_CHAN1_MCKDIV_LOG2 = 5
# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 5
# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 64
# SAMA5_PWM_CHAN1_MCKDIV_LOG2 = 6
# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 6
# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 128
# SAMA5_PWM_CHAN1_MCKDIV_LOG2 = 7
# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 7
# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 256
# SAMA5_PWM_CHAN1_MCKDIV_LOG2 = 8
# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 8
# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 512
# SAMA5_PWM_CHAN1_MCKDIV_LOG2 = 9
# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 9
# elif CONFIG_SAMA5_PWM_CHAN1_MCKDIV == 1024
# SAMA5_PWM_CHAN1_MCKDIV_LOG2 = 10
# define SAMA5_PWM_CHAN1_MCKDIV_LOG2 10
# else
# error Unsupported MCK divider value
# endif
@ -308,27 +310,27 @@
# undef CONFIG_SAMA5_PWM_CHAN2_CLKA
# undef CONFIG_SAMA5_PWM_CHAN2_CLKB
# if CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 1
# SAMA5_PWM_CHAN2_MCKDIV_LOG2 = 0
# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 0
# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 2
# SAMA5_PWM_CHAN2_MCKDIV_LOG2 = 1
# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 1
# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 4
# SAMA5_PWM_CHAN2_MCKDIV_LOG2 = 2
# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 2
# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 8
# SAMA5_PWM_CHAN2_MCKDIV_LOG2 = 3
# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 3
# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 16
# SAMA5_PWM_CHAN2_MCKDIV_LOG2 = 4
# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 4
# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 32
# SAMA5_PWM_CHAN2_MCKDIV_LOG2 = 5
# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 5
# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 64
# SAMA5_PWM_CHAN2_MCKDIV_LOG2 = 6
# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 6
# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 128
# SAMA5_PWM_CHAN2_MCKDIV_LOG2 = 7
# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 7
# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 256
# SAMA5_PWM_CHAN2_MCKDIV_LOG2 = 8
# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 8
# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 512
# SAMA5_PWM_CHAN2_MCKDIV_LOG2 = 9
# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 9
# elif CONFIG_SAMA5_PWM_CHAN2_MCKDIV == 1024
# SAMA5_PWM_CHAN2_MCKDIV_LOG2 = 10
# define SAMA5_PWM_CHAN2_MCKDIV_LOG2 10
# else
# error Unsupported MCK divider value
# endif
@ -347,27 +349,27 @@
# undef CONFIG_SAMA5_PWM_CHAN3_CLKA
# undef CONFIG_SAMA5_PWM_CHAN3_CLKB
# if CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 1
# SAMA5_PWM_CHAN3_MCKDIV_LOG2 = 0
# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 0
# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 2
# SAMA5_PWM_CHAN3_MCKDIV_LOG2 = 1
# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 1
# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 4
# SAMA5_PWM_CHAN3_MCKDIV_LOG2 = 2
# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 2
# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 8
# SAMA5_PWM_CHAN3_MCKDIV_LOG2 = 3
# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 3
# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 16
# SAMA5_PWM_CHAN3_MCKDIV_LOG2 = 4
# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 4
# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 32
# SAMA5_PWM_CHAN3_MCKDIV_LOG2 = 5
# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 5
# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 64
# SAMA5_PWM_CHAN3_MCKDIV_LOG2 = 6
# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 6
# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 128
# SAMA5_PWM_CHAN3_MCKDIV_LOG2 = 7
# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 7
# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 256
# SAMA5_PWM_CHAN3_MCKDIV_LOG2 = 8
# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 8
# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 512
# SAMA5_PWM_CHAN3_MCKDIV_LOG2 = 9
# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 9
# elif CONFIG_SAMA5_PWM_CHAN3_MCKDIV == 1024
# SAMA5_PWM_CHAN3_MCKDIV_LOG2 = 10
# define SAMA5_PWM_CHAN3_MCKDIV_LOG2 10
# else
# error Unsupported MCK divider value
# endif
@ -413,7 +415,6 @@
# define pwmlldbg(x...)
# define pwmvdbg(x...)
# define pwmllvdbg(x...)
# define pwm_dumpgpio(p,m)
#endif
/****************************************************************************
@ -523,7 +524,7 @@ static const struct pwm_ops_s g_pwmops =
/* This is the overall state of the PWM peripheral */
static sam_pwm_s g_pwm =
static struct sam_pwm_s g_pwm =
{
.initialized = false,
#ifndef PWM_SINGLE
@ -537,7 +538,9 @@ static sam_pwm_s g_pwm =
static struct sam_pwm_chan_s g_pwm_chan0 =
{
.ops = &g_pwmops,
#ifndef PWM_SINGLE
.pwm = &g_pwm,
#endif
.channel = 0,
.base = SAM_PWM_CHAN_BASE(0),
@ -570,7 +573,9 @@ static struct sam_pwm_chan_s g_pwm_chan0 =
static struct sam_pwm_chan_s g_pwm_chan1 =
{
.ops = &g_pwmops,
#ifndef PWM_SINGLE
.pwm = &g_pwm,
#endif
.channel = 1,
.base = SAM_PWM_CHAN_BASE(1),
@ -585,13 +590,13 @@ static struct sam_pwm_chan_s g_pwm_chan1 =
# error No clock source for channel 0
#endif
#ifdef CONFIG_SAMA5_PWM_CHAN0_OUTPUTH
#ifdef CONFIG_SAMA5_PWM_CHAN1_OUTPUTH
.ohpincfg = PIO_PWM1_H,
#endif
#ifdef CONFIG_SAMA5_PWM_CHAN0_OUTPUTL
#ifdef CONFIG_SAMA5_PWM_CHAN1_OUTPUTL
.olpincfg = PIO_PWM1_L,
#endif
#ifdef CONFIG_SAMA5_PWM_CHAN0_FAULTINPUT
#ifdef CONFIG_SAMA5_PWM_CHAN1_FAULTINPUT
.fipincfg = PIO_PWM1_FI,
#endif
};
@ -603,7 +608,9 @@ static struct sam_pwm_chan_s g_pwm_chan1 =
static struct sam_pwm_chan_s g_pwm_chan2 =
{
.ops = &g_pwmops,
#ifndef PWM_SINGLE
.pwm = &g_pwm,
#endif
.channel = 2,
.base = SAM_PWM_CHAN_BASE(2),
@ -618,13 +625,13 @@ static struct sam_pwm_chan_s g_pwm_chan2 =
# error No clock source for channel 0
#endif
#ifdef CONFIG_SAMA5_PWM_CHAN0_OUTPUTH
#ifdef CONFIG_SAMA5_PWM_CHAN2_OUTPUTH
.ohpincfg = PIO_PWM2_H,
#endif
#ifdef CONFIG_SAMA5_PWM_CHAN0_OUTPUTL
#ifdef CONFIG_SAMA5_PWM_CHAN2_OUTPUTL
.olpincfg = PIO_PWM2_L,
#endif
#ifdef CONFIG_SAMA5_PWM_CHAN0_FAULTINPUT
#ifdef CONFIG_SAMA5_PWM_CHAN2_FAULTINPUT
.fipincfg = PIO_PWM2_FI,
#endif
};
@ -636,8 +643,11 @@ static struct sam_pwm_chan_s g_pwm_chan2 =
static struct sam_pwm_chan_s g_pwm_chan3 =
{
.ops = &g_pwmops,
#ifndef PWM_SINGLE
.pwm = &g_pwm,
#endif
.channel = 3,
.base = SAM_PWM_CHAN_BASE(3),
#if defined(CONFIG_SAMA5_PWM_CHAN3_MCK)
.clksrc = PWM_CLKSRC_MCK,
@ -650,13 +660,13 @@ static struct sam_pwm_chan_s g_pwm_chan3 =
# error No clock source for channel 0
#endif
#ifdef CONFIG_SAMA5_PWM_CHAN0_OUTPUTH
#ifdef CONFIG_SAMA5_PWM_CHAN3_OUTPUTH
.ohpincfg = PIO_PWM3_H,
#endif
#ifdef CONFIG_SAMA5_PWM_CHAN0_OUTPUTL
#ifdef CONFIG_SAMA5_PWM_CHAN3_OUTPUTL
.olpincfg = PIO_PWM3_L,
#endif
#ifdef CONFIG_SAMA5_PWM_CHAN0_FAULTINPUT
#ifdef CONFIG_SAMA5_PWM_CHAN3_FAULTINPUT
.fipincfg = PIO_PWM3_FI,
#endif
};
@ -741,7 +751,7 @@ static uint32_t pwm_getreg(struct sam_pwm_chan_s *chan, int offset)
uint32_t regval;
#ifdef PWM_SINGLE
regaddr = SAM_PWMC_VBASE + offset
regaddr = SAM_PWMC_VBASE + offset;
#else
struct sam_pwm_chan_s *pwm = chan->pwm;
regaddr = pwm->base + offset;
@ -812,7 +822,7 @@ static void pwm_putreg(struct sam_pwm_chan_s *chan, int offset, uint32_t regval)
uintptr_t regaddr;
#ifdef PWM_SINGLE
regaddr = SAM_PWMC_VBASE + offset
regaddr = SAM_PWMC_VBASE + offset;
#else
struct sam_pwm_chan_s *pwm = chan->pwm;
regaddr = pwm->base + offset;
@ -995,7 +1005,6 @@ static int pwm_setup(FAR struct pwm_lowerhalf_s *dev)
(void)sam_configpio(chan->fipincfg);
}
pwm_dumpgpio(chan->pincfg, "PWM setup");
return OK;
}
@ -1018,9 +1027,8 @@ static int pwm_setup(FAR struct pwm_lowerhalf_s *dev)
static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev)
{
FAR struct sam_pwm_chan_s *chan = (FAR struct sam_pwm_chan_s *)dev;
uint32_t pincfg;
pwmvdbg("Channel %d pincfg: %08x\n", chan->channel, chan->pincfg);
pwmvdbg("Channel %d\n", chan->channel);
/* Make sure that the output has been stopped */
@ -1053,19 +1061,19 @@ static int pwm_start(FAR struct pwm_lowerhalf_s *dev,
FAR struct sam_pwm_chan_s *chan = (FAR struct sam_pwm_chan_s *)dev;
uint32_t regval;
uint32_t cprd;
uint32_t srcfreq;
uint32_t fsrc;
/* Disable the channel (should already be disabled) */
sam_putreg(priv, SAM_PWM_DIS_OFFSET, PWM_CHID(chan->channel));
pwm_putreg(chan, SAM_PWM_DIS_OFFSET, PWM_CHID(chan->channel));
/* Determine the clock source */
switch (chan->clksrc)
{
case PWM_CLKSRC_MCK:
regval = PWM_CMR_CPRE_MCKDIV(SAMA5_PWM_CHAN0_MCKDIV_LOG2);
fsrc = BOARD_MCK_FREQUENCY >> SAMA5_PWM_CHAN0_MCKDIV_LOG2;
regval = PWM_CMR_CPRE_MCKDIV(chan->divlog2);
fsrc = BOARD_MCK_FREQUENCY >> chan->divlog2;
break;
case PWM_CLKSRC_CLKA:
@ -1085,7 +1093,7 @@ static int pwm_start(FAR struct pwm_lowerhalf_s *dev,
/* Configure the channel */
sam_chan_putreg(priv, SAM_PWM_CMR_OFFSET, PWM_CMR_CPRE_CLKA);
pwm_chan_putreg(chan, SAM_PWM_CMR_OFFSET, PWM_CMR_CPRE_CLKA);
/* Set the PWM period.
*
@ -1107,7 +1115,7 @@ static int pwm_start(FAR struct pwm_lowerhalf_s *dev,
*/
cprd = (info->frequency + (fsrc >> 1)) / fsrc;
sam_chan_putreg(priv, SAM_PWM_CPRD_OFFSET, cprd);
pwm_chan_putreg(chan, SAM_PWM_CPRD_OFFSET, cprd);
/* Set the PWM duty. Since the PWM is disabled, we can write directly
* to the CTDY (vs. the CTDYUPD) register.
@ -1121,11 +1129,11 @@ static int pwm_start(FAR struct pwm_lowerhalf_s *dev,
regval = cprd;
}
sam_chan_putreg(priv, SAM_PWM_CDTY_OFFSET, regval);
pwm_chan_putreg(chan, SAM_PWM_CDTY_OFFSET, regval);
/* Enable the channel */
sam_putreg(priv, SAM_PWM_ENA_OFFSET, PWM_CHID(chan->channel));
pwm_putreg(chan, SAM_PWM_ENA_OFFSET, PWM_CHID(chan->channel));
return OK;
}
@ -1156,12 +1164,12 @@ static int pwm_stop(FAR struct pwm_lowerhalf_s *dev)
/* Disable further PWM interrupts from this channel */
sam_putreg(chan, SAM_PWM_IDR1_OFFSET,
pwm_putreg(chan, SAM_PWM_IDR1_OFFSET,
PWM_INT1_CHID(chan->channel) | PWM_INT1_FCHID(chan->channel));
/* Disable the channel */
sam_putreg(priv, SAM_PWM_DIS_OFFSET, PWM_CHID(chan->channel));
pwm_putreg(chan, SAM_PWM_DIS_OFFSET, PWM_CHID(chan->channel));
pwm_dumpregs(chan, "After stop");
return OK;
}
@ -1236,7 +1244,7 @@ static void pwm_resetpins(FAR struct sam_pwm_chan_s *chan)
* Name: sam_pwminitialize
*
* Description:
* Initialize one timer for use with the upper_level PWM driver.
* Initialize one PWM channel for use with the upper_level PWM driver.
*
* Input Parameters:
* channel - A number identifying the PWM channel use.
@ -1254,7 +1262,7 @@ FAR struct pwm_lowerhalf_s *sam_pwminitialize(int channel)
pwmvdbg("Channel %d\n", channel);
switch (timer)
switch (channel)
{
#ifdef CONFIG_SAMA5_PWM_CHAN0
case 0:
@ -1301,17 +1309,17 @@ FAR struct pwm_lowerhalf_s *sam_pwminitialize(int channel)
{
/* Enable the PWM peripheral clock */
sam_pwm_enableclks();
sam_pwm_enableclk();
/* Set clock A and clock B */
regval = PWM_CLK_PREA | PWM_CLK_DIVA | PWM_CLK_PREB | PWM_CLK_DIVB;
sam_putreg(chan, SAM_PWM_CLK_OFFSET, regval);
regval = (CLKA_PRE_BITS | CLKA_DIV_BITS | CLKB_PRE_BITS | CLKB_DIV_BITS);
pwm_putreg(chan, SAM_PWM_CLK_OFFSET, regval);
/* Disable all PWM interrupts at the PWM peripheral */
sam_putreg(chan, SAM_PWM_IDR1_OFFSET, PWM_INT1_ALL);
sam_putreg(chan, SAM_PWM_IDR2_OFFSET, PWM_INT2_ALL);
pwm_putreg(chan, SAM_PWM_IDR1_OFFSET, PWM_INT1_ALL);
pwm_putreg(chan, SAM_PWM_IDR2_OFFSET, PWM_INT2_ALL);
/* Attach the PWM interrupt handler */
@ -1327,8 +1335,8 @@ FAR struct pwm_lowerhalf_s *sam_pwminitialize(int channel)
/* Clear any pending PWM interrupts */
(void)sam_getreg(chan, SAM_PWM_ISR1_OFFSET);
(void)sam_getreg(chan, SAM_PWM_ISR2_OFFSET);
(void)pwm_getreg(chan, SAM_PWM_ISR1_OFFSET);
(void)pwm_getreg(chan, SAM_PWM_ISR2_OFFSET);
/* Enable PWM interrupts at the AIC */

View file

@ -43,6 +43,7 @@
#include <nuttx/config.h>
#include "chip.h"
#include "chip/sam_pwm.h"
#ifdef CONFIG_SAMA5_PWM

View file

@ -1215,6 +1215,7 @@ config STM32_TIM1_PWM
bool "TIM1 PWM"
default n
depends on STM32_TIM1
select ARCH_HAVE_PWM_PULSECOUNT
---help---
Reserve timer 1 for use by PWM
@ -1236,6 +1237,7 @@ config STM32_TIM2_PWM
bool "TIM2 PWM"
default n
depends on STM32_TIM2
select ARCH_HAVE_PWM_PULSECOUNT
---help---
Reserve timer 2 for use by PWM
@ -1257,6 +1259,7 @@ config STM32_TIM3_PWM
bool "TIM3 PWM"
default n
depends on STM32_TIM3
select ARCH_HAVE_PWM_PULSECOUNT
---help---
Reserve timer 3 for use by PWM
@ -1278,6 +1281,7 @@ config STM32_TIM4_PWM
bool "TIM4 PWM"
default n
depends on STM32_TIM4
select ARCH_HAVE_PWM_PULSECOUNT
---help---
Reserve timer 4 for use by PWM
@ -1299,6 +1303,7 @@ config STM32_TIM5_PWM
bool "TIM5 PWM"
default n
depends on STM32_TIM5
select ARCH_HAVE_PWM_PULSECOUNT
---help---
Reserve timer 5 for use by PWM
@ -1320,6 +1325,7 @@ config STM32_TIM8_PWM
bool "TIM8 PWM"
default n
depends on STM32_TIM8
select ARCH_HAVE_PWM_PULSECOUNT
---help---
Reserve timer 8 for use by PWM
@ -1341,6 +1347,7 @@ config STM32_TIM9_PWM
bool "TIM9 PWM"
default n
depends on STM32_TIM9
select ARCH_HAVE_PWM_PULSECOUNT
---help---
Reserve timer 9 for use by PWM
@ -1362,6 +1369,7 @@ config STM32_TIM10_PWM
bool "TIM10 PWM"
default n
depends on STM32_TIM10
select ARCH_HAVE_PWM_PULSECOUNT
---help---
Reserve timer 10 for use by PWM
@ -1383,6 +1391,7 @@ config STM32_TIM11_PWM
bool "TIM11 PWM"
default n
depends on STM32_TIM11
select ARCH_HAVE_PWM_PULSECOUNT
---help---
Reserve timer 11 for use by PWM
@ -1404,6 +1413,7 @@ config STM32_TIM12_PWM
bool "TIM12 PWM"
default n
depends on STM32_TIM12
select ARCH_HAVE_PWM_PULSECOUNT
---help---
Reserve timer 12 for use by PWM
@ -1425,6 +1435,7 @@ config STM32_TIM13_PWM
bool "TIM13 PWM"
default n
depends on STM32_TIM13
select ARCH_HAVE_PWM_PULSECOUNT
---help---
Reserve timer 13 for use by PWM
@ -1446,6 +1457,7 @@ config STM32_TIM14_PWM
bool "TIM14 PWM"
default n
depends on STM32_TIM14
select ARCH_HAVE_PWM_PULSECOUNT
---help---
Reserve timer 14 for use by PWM

View file

@ -80,6 +80,10 @@ config CAN_LOOPBACK
endif
config ARCH_HAVE_PWM_PULSECOUNT
bool
default n
menuconfig PWM
bool "PWM Driver Support"
default n
@ -91,6 +95,7 @@ if PWM
config PWM_PULSECOUNT
bool "PWM Pulse Count Support"
default n
depends on ARCH_HAVE_PWM_PULSECOUNT
---help---
Some hardware will support generation of a fixed number of pulses.
This might be used, for example to support a stepper motor. If the