diff --git a/arch/arm/src/tiva/tiva_pwm.c b/arch/arm/src/tiva/tiva_pwm.c index 9e1f660be51..8ccaf73837e 100644 --- a/arch/arm/src/tiva/tiva_pwm.c +++ b/arch/arm/src/tiva/tiva_pwm.c @@ -1,49 +1,52 @@ /************************************************************************************ -* arch/arm/src/tiva/tiva_pwm.c -* -* Copyright (C) 2016 Young Mu. All rights reserved. -* Author: Young Mu -* -* The basic structure of this driver derives in spirit (if nothing more) from the -* NuttX SAM PWM driver which has: -* -* Copyright (C) 2013 Gregory Nutt. All rights reserved. -* Author: Gregory Nutt -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided with the -* distribution. -* 3. Neither the name NuttX nor the names of its contributors may be -* used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -* -************************************************************************************/ + * arch/arm/src/tiva/tiva_pwm.c + * + * Copyright (C) 2016 Young Mu. All rights reserved. + * Author: Young Mu + * + * The basic structure of this driver derives in spirit (if nothing more) from the + * NuttX SAM PWM driver which has: + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ /************************************************************************************ -* Included Files -************************************************************************************/ + * Included Files + ************************************************************************************/ + +#include #include +#include #include #include @@ -59,60 +62,39 @@ #include "chip/tm4c_memorymap.h" /************************************************************************************ -* Pre-processor Definitions -************************************************************************************/ - -#define pwmerr(fmt, args...) printf("%s(%d): " fmt, __FUNCTION__, __LINE__, ##args); - -#ifndef CONFIG_DEBUG -# undef CONFIG_DEBUG_PWM -#endif - -#ifdef CONFIG_DEBUG_PWM -# define pwmdbg dbg -# ifdef CONFIG_DEBUG_VERBOSE -# define pwmvdbg vdbg -# else -# define pwmvdbg(x...) -# endif -#else -# define pwmdbg(x...) -# define pwmvdbg(x...) -#endif - -/************************************************************************************ -* Private Types -************************************************************************************/ + * Private Types + ************************************************************************************/ uint32_t g_pwm_pinset[] = { - GPIO_M0_PWM0, - GPIO_M0_PWM1, - GPIO_M0_PWM2, - GPIO_M0_PWM3, - GPIO_M0_PWM4, - GPIO_M0_PWM5, - GPIO_M0_PWM6, - GPIO_M0_PWM7, + GPIO_M0_PWM0, + GPIO_M0_PWM1, + GPIO_M0_PWM2, + GPIO_M0_PWM3, + GPIO_M0_PWM4, + GPIO_M0_PWM5, + GPIO_M0_PWM6, + GPIO_M0_PWM7, }; struct tiva_pwm_chan_s { - const struct pwm_ops_s *ops; - uint8_t controller_id; - uintptr_t controller_base; - uint8_t generator_id; - uintptr_t generator_base; - uint8_t channel_id; + const struct pwm_ops_s *ops; + uint8_t controller_id; + uintptr_t controller_base; + uint8_t generator_id; + uintptr_t generator_base; + uint8_t channel_id; }; - /************************************************************************************ -* Private Function Prototypes -************************************************************************************/ + * Private Function Prototypes + ************************************************************************************/ -static inline void tiva_pwm_putreg(struct tiva_pwm_chan_s *chan, unsigned int offset, uint32_t regval); -static inline uint32_t tiva_pwm_getreg(struct tiva_pwm_chan_s *chan, unsigned int offset); +static inline void tiva_pwm_putreg(struct tiva_pwm_chan_s *chan, + unsigned int offset, uint32_t regval); +static inline uint32_t tiva_pwm_getreg(struct tiva_pwm_chan_s *chan, + unsigned int offset); static int tiva_pwm_setup(FAR struct pwm_lowerhalf_s *dev); static int tiva_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev); @@ -123,236 +105,246 @@ static int tiva_pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg); /************************************************************************************ -* Private Data -************************************************************************************/ + * Private Data + ************************************************************************************/ -uint32_t g_pwm_freq = 15000000; -uint32_t g_pwm_counter = (1 << 16); +static uint32_t g_pwm_freq = 15000000; +static uint32_t g_pwm_counter = (1 << 16); static const struct pwm_ops_s g_pwm_ops = { - .setup = tiva_pwm_setup, - .shutdown = tiva_pwm_shutdown, - .start = tiva_pwm_start, - .stop = tiva_pwm_stop, - .ioctl = tiva_pwm_ioctl, + .setup = tiva_pwm_setup, + .shutdown = tiva_pwm_shutdown, + .start = tiva_pwm_start, + .stop = tiva_pwm_stop, + .ioctl = tiva_pwm_ioctl, }; #ifdef CONFIG_TIVA_PWM0_CHAN0 static struct tiva_pwm_chan_s g_pwm_chan0 = { - .ops = &g_pwm_ops, - .controller_id = 0, - .controller_base = TIVA_PWM0_BASE, - .generator_id = 0, - .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 0, - .channel_id = 0, + .ops = &g_pwm_ops, + .controller_id = 0, + .controller_base = TIVA_PWM0_BASE, + .generator_id = 0, + .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 0, + .channel_id = 0, }; #endif #ifdef CONFIG_TIVA_PWM0_CHAN1 static struct tiva_pwm_chan_s g_pwm_chan1 = { - .ops = &g_pwm_ops, - .controller_id = 0, - .controller_base = TIVA_PWM0_BASE, - .generator_id = 0, - .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 0, - .channel_id = 1, + .ops = &g_pwm_ops, + .controller_id = 0, + .controller_base = TIVA_PWM0_BASE, + .generator_id = 0, + .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 0, + .channel_id = 1, }; #endif #ifdef CONFIG_TIVA_PWM0_CHAN2 static struct tiva_pwm_chan_s g_pwm_chan2 = { - .ops = &g_pwm_ops, - .controller_id = 0, - .controller_base = TIVA_PWM0_BASE, - .generator_id = 1, - .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 1, - .channel_id = 2, + .ops = &g_pwm_ops, + .controller_id = 0, + .controller_base = TIVA_PWM0_BASE, + .generator_id = 1, + .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 1, + .channel_id = 2, }; #endif #ifdef CONFIG_TIVA_PWM0_CHAN3 static struct tiva_pwm_chan_s g_pwm_chan3 = { - .ops = &g_pwm_ops, - .controller_id = 0, - .controller_base = TIVA_PWM0_BASE, - .generator_id = 1, - .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 1, - .channel_id = 3, + .ops = &g_pwm_ops, + .controller_id = 0, + .controller_base = TIVA_PWM0_BASE, + .generator_id = 1, + .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 1, + .channel_id = 3, }; #endif #ifdef CONFIG_TIVA_PWM0_CHAN4 static struct tiva_pwm_chan_s g_pwm_chan4 = { - .ops = &g_pwm_ops, - .controller_id = 0, - .controller_base = TIVA_PWM0_BASE, - .generator_id = 2, - .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 2, - .channel_id = 4, + .ops = &g_pwm_ops, + .controller_id = 0, + .controller_base = TIVA_PWM0_BASE, + .generator_id = 2, + .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 2, + .channel_id = 4, }; #endif #ifdef CONFIG_TIVA_PWM0_CHAN5 static struct tiva_pwm_chan_s g_pwm_chan5 = { - .ops = &g_pwm_ops, - .controller_id = 0, - .controller_base = TIVA_PWM0_BASE, - .generator_id = 2, - .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 2, - .channel_id = 5, + .ops = &g_pwm_ops, + .controller_id = 0, + .controller_base = TIVA_PWM0_BASE, + .generator_id = 2, + .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 2, + .channel_id = 5, }; #endif #ifdef CONFIG_TIVA_PWM0_CHAN6 static struct tiva_pwm_chan_s g_pwm_chan6 = { - .ops = &g_pwm_ops, - .controller_id = 0, - .controller_base = TIVA_PWM0_BASE, - .generator_id = 3, - .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 3, - .channel_id = 6, + .ops = &g_pwm_ops, + .controller_id = 0, + .controller_base = TIVA_PWM0_BASE, + .generator_id = 3, + .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 3, + .channel_id = 6, }; #endif #ifdef CONFIG_TIVA_PWM0_CHAN7 static struct tiva_pwm_chan_s g_pwm_chan7 = { - .ops = &g_pwm_ops, - .controller_id = 0, - .controller_base = TIVA_PWM0_BASE, - .generator_id = 3, - .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 3, - .channel_id = 7, + .ops = &g_pwm_ops, + .controller_id = 0, + .controller_base = TIVA_PWM0_BASE, + .generator_id = 3, + .generator_base = TIVA_PWM0_BASE + TIVA_PWMn_BASE + TIVA_PWMn_INTERVAL * 3, + .channel_id = 7, }; #endif /************************************************************************************ -* Private Functions -************************************************************************************/ + * Private Functions + ************************************************************************************/ /************************************************************************************ -* Name: tiva_pwm_getreg -* -* Description: -* Get a 32-bit register value by offset -* -************************************************************************************/ + * Name: tiva_pwm_getreg + * + * Description: + * Get a 32-bit register value by offset + * + ************************************************************************************/ -static inline uint32_t tiva_pwm_getreg(struct tiva_pwm_chan_s *chan, unsigned int offset) +static inline uint32_t tiva_pwm_getreg(struct tiva_pwm_chan_s *chan, + unsigned int offset) { uintptr_t regaddr = chan->generator_base + offset; return getreg32(regaddr); } /************************************************************************************ -* Name: tiva_pwm_putreg -* -* Description: -* Put a 32-bit register value by offset -* -************************************************************************************/ + * Name: tiva_pwm_putreg + * + * Description: + * Put a 32-bit register value by offset + * + ************************************************************************************/ -static inline void tiva_pwm_putreg(struct tiva_pwm_chan_s *chan, unsigned int offset, uint32_t regval) +static inline void tiva_pwm_putreg(struct tiva_pwm_chan_s *chan, + unsigned int offset, uint32_t regval) { uintptr_t regaddr = chan->generator_base + offset; putreg32(regval, regaddr); } /**************************************************************************** -* Name: pwm_setup -* -* Description: -* This method is called when the driver is opened. The lower half driver -* will be configured and initialized the device so that it is ready for -* use. It will not, however, output pulses until the start method is -* called. -* -* Input parameters: -* dev - A reference to the lower half PWM driver state structure -* -* Returned Value: -* Zero on success; a negated errno value on failure -* -****************************************************************************/ + * Name: pwm_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * will be configured and initialized the device so that it is ready for + * use. It will not, however, output pulses until the start method is + * called. + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ static int tiva_pwm_setup(FAR struct pwm_lowerhalf_s *dev) { FAR struct tiva_pwm_chan_s *chan = (FAR struct tiva_pwm_chan_s *)dev; - pwmdbg("setup PWM for channel %d\n", chan->channel_id); + pwminfo("setup PWM for channel %d\n", chan->channel_id); + + /* Enable GPIO port, GPIO pin type and GPIO alternate function (refer to + * TM4C1294NC 23.4.2-4) + */ - /* Enable GPIO port, GPIO pin type and GPIO alternate function (refer to TM4C1294NC 23.4.2-4) */ int ret = tiva_configgpio(g_pwm_pinset[chan->channel_id]); if (ret < 0) { - pwmerr("tiva_configgpio failed (%x)\n", g_pwm_pinset[chan->channel_id]); - return -1; + pwmerr("ERROR: tiva_configgpio failed (%x)\n", + g_pwm_pinset[chan->channel_id]); + return ret; } return OK; } /**************************************************************************** -* Name: pwm_shutdown -* -* Description: -* This method is called when the driver is closed. The lower half driver -* stop pulsed output, free any resources, disable the timer hardware, and -* put the system into the lowest possible power usage state -* -* Input parameters: -* dev - A reference to the lower half PWM driver state structure -* -* Returned Value: -* Zero on success; a negated errno value on failure -* -****************************************************************************/ + * Name: pwm_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * stop pulsed output, free any resources, disable the timer hardware, and + * put the system into the lowest possible power usage state + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ static int tiva_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev) { FAR struct tiva_pwm_chan_s *chan = (FAR struct tiva_pwm_chan_s *)dev; - pwmdbg("shutdown PWM for channel %d\n", chan->channel_id); + pwminfo("shutdown PWM for channel %d\n", chan->channel_id); /* Remove unused-variable warning */ + (void)chan; /* Ensure the PWM channel has been stopped */ + tiva_pwm_stop(dev); return OK; } /**************************************************************************** -* Name: pwm_start -* -* Description: -* (Re-)initialize the timer resources and start the pulsed output -* -* Input parameters: -* dev - A reference to the lower half PWM driver state structure -* info - A reference to the characteristics of the pulsed output -* -* Returned Value: -* Zero on success; a negated errno value on failure -* -****************************************************************************/ + * Name: pwm_start + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ -static int tiva_pwm_start(FAR struct pwm_lowerhalf_s *dev, FAR const struct pwm_info_s *info) +static int tiva_pwm_start(FAR struct pwm_lowerhalf_s *dev, + FAR const struct pwm_info_s *info) { FAR struct tiva_pwm_chan_s *chan = (FAR struct tiva_pwm_chan_s *)dev; - pwmdbg("start PWM for channel %d\n", chan->channel_id); + pwminfo("start PWM for channel %d\n", chan->channel_id); uint16_t duty = info->duty; uint32_t frequency = info->frequency; /* Configure PWM countdown mode (refer to TM4C1294NC 23.4.6) */ + tiva_pwm_putreg(chan, TIVA_PWMn_CTL_OFFSET, 0); if (chan->channel_id % 2 == 0) { @@ -366,20 +358,27 @@ static int tiva_pwm_start(FAR struct pwm_lowerhalf_s *dev, FAR const struct pwm_ } /* Set the PWM period (refer to TM4C1294NC 23.4.7) */ + uint32_t pwm_min_freq = (uint32_t)(g_pwm_freq / g_pwm_counter) + 1; uint32_t pwm_max_freq = g_pwm_freq; uint32_t load = (uint32_t)(g_pwm_freq / frequency); - pwmdbg("channel %d: load = %u (%08x)\n", chan->channel_id, load, load); + + pwminfo("channel %d: load = %u (%08x)\n", chan->channel_id, load, load); + if (load >= g_pwm_counter || load < 1) { - pwmerr("frequency should be in [%d, %d] Hz\n", pwm_min_freq, pwm_max_freq); - return -1; + pwmerr("ERROR: frequency should be in [%d, %d] Hz\n", + pwm_min_freq, pwm_max_freq); + return -ERANGE; } + tiva_pwm_putreg(chan, TIVA_PWMn_LOAD_OFFSET, load - 1); /* Configure PWM duty (refer to TM4C1294NC 23.4.8-9) */ + uint32_t comp = (uint32_t)((1 - (float)duty / g_pwm_counter) * load); - pwmdbg("channel %d: comp = %u (%08x)\n", chan->channel_id, comp, comp); + pwminfo("channel %d: comp = %u (%08x)\n", chan->channel_id, comp, comp); + if (chan->channel_id % 2 == 0) { tiva_pwm_putreg(chan, TIVA_PWMn_CMPA_OFFSET, comp - 1); @@ -390,39 +389,41 @@ static int tiva_pwm_start(FAR struct pwm_lowerhalf_s *dev, FAR const struct pwm_ } /* Enable the PWM generator (refer to TM4C1294NC 23.4.10) */ + tiva_pwm_putreg(chan, TIVA_PWMn_CTL_OFFSET, CTL_ENABLE << TIVA_PWMn_CTL_ENABLE); /* Enable PWM channel (refer to TM4C1294NC 23.4.11) */ - putreg32((1 << chan->channel_id), chan->controller_base + TIVA_PWM_ENABLE_OFFSET); + putreg32((1 << chan->channel_id), chan->controller_base + TIVA_PWM_ENABLE_OFFSET); return OK; } /**************************************************************************** -* Name: pwm_stop -* -* Description: -* Stop the pulsed output and reset the timer resources -* -* Input parameters: -* dev - A reference to the lower half PWM driver state structure -* -* Returned Value: -* Zero on success; a negated errno value on failure -* -* Assumptions: -* This function is called to stop the pulsed output at anytime. This -* method is also called from the timer interrupt handler when a repetition -* count expires... automatically stopping the timer. -* -****************************************************************************/ + * Name: pwm_stop + * + * Description: + * Stop the pulsed output and reset the timer resources + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * This function is called to stop the pulsed output at anytime. This + * method is also called from the timer interrupt handler when a repetition + * count expires... automatically stopping the timer. + * + ****************************************************************************/ static int tiva_pwm_stop(FAR struct pwm_lowerhalf_s *dev) { FAR struct tiva_pwm_chan_s *chan = (FAR struct tiva_pwm_chan_s *)dev; - pwmdbg("stop PWM for channel %d\n", chan->channel_id); + pwminfo("stop PWM for channel %d\n", chan->channel_id); /* Disable PWM channel */ + uint32_t value = getreg32(chan->controller_base + TIVA_PWM_ENABLE_OFFSET); value &= ~(1 << chan->channel_id); putreg32(value, chan->controller_base + TIVA_PWM_ENABLE_OFFSET); @@ -431,52 +432,54 @@ static int tiva_pwm_stop(FAR struct pwm_lowerhalf_s *dev) } /**************************************************************************** -* Name: pwm_ioctl -* -* Description: -* Lower-half logic may support platform-specific ioctl commands -* -* Input parameters: -* dev - A reference to the lower half PWM driver state structure -* cmd - The ioctl command -* arg - The argument accompanying the ioctl command -* -* Returned Value: -* Zero on success; a negated errno value on failure -* -****************************************************************************/ + * Name: pwm_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input parameters: + * dev - A reference to the lower half PWM driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ -static int tiva_pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, unsigned long arg) +static int tiva_pwm_ioctl(FAR struct pwm_lowerhalf_s *dev, int cmd, + unsigned long arg) { FAR struct tiva_pwm_chan_s *chan = (FAR struct tiva_pwm_chan_s *)dev; - pwmdbg("ioctl PWM for channel %d\n", chan->channel_id); + pwminfo("ioctl PWM for channel %d\n", chan->channel_id); /* Remove unused-variable warning */ + (void)chan; /* There are no platform-specific ioctl commands */ - return -1; + return -ENOTTY; } /**************************************************************************** -* Public Functions -****************************************************************************/ + * Public Functions + ****************************************************************************/ /**************************************************************************** -* Name: tiva_pwm_initialize -* -* Description: -* Initialize one PWM channel for use with the upper_level PWM driver. -* -* Input Parameters: -* channel - A number identifying the PWM channel use. -* -* Returned Value: -* On success, a pointer to the SAMA5 lower half PWM driver is returned. -* NULL is returned on any failure. -* -****************************************************************************/ + * Name: tiva_pwm_initialize + * + * Description: + * Initialize one PWM channel for use with the upper_level PWM driver. + * + * Input Parameters: + * channel - A number identifying the PWM channel use. + * + * Returned Value: + * On success, a pointer to the SAMA5 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ FAR struct pwm_lowerhalf_s *tiva_pwm_initialize(int channel) { @@ -538,39 +541,28 @@ FAR struct pwm_lowerhalf_s *tiva_pwm_initialize(int channel) return NULL; } - pwmvdbg("channel %d: channel_id=%d, ", channel, chan->channel_id); - pwmvdbg("controller_id=%d, controller_base=%08x, ", chan->controller_id, chan->controller_base); - pwmvdbg("generator_id=%d, generator_base=%08x\n", chan->generator_id, chan->generator_base); + pwminfo("channel %d: channel_id=%d, ", channel, chan->channel_id); + pwminfo("controller_id=%d, controller_base=%08x, ", + chan->controller_id, chan->controller_base); + pwminfo("generator_id=%d, generator_base=%08x\n", + chan->generator_id, chan->generator_base); /* Enable PWM controller (refer to TM4C1294NC 23.4.1) */ + assert(chan->controller_id == 0); tiva_pwm_enablepwr(chan->controller_id); tiva_pwm_enableclk(chan->controller_id); - /* Configure PWM Clock Configuration (refer to TM4C1294NC 23.4.5) */ - /* on TM4C1294NC, configure the PWM clock source as 15MHz (the system clock 120MHz divided by 8) */ - /* TODO: need an algorithm to choose the best divider and load value combo */ + /* Configure PWM Clock Configuration (refer to TM4C1294NC 23.4.5) + * + * On TM4C1294NC, configure the PWM clock source as 15MHz (the system + * clock 120MHz divided by 8) + * + * TODO: need an algorithm to choose the best divider and load value combo. + */ + putreg32(CC_USEPWM << TIVA_PWM_CC_USEPWM | CC_PWMDIV_8 << TIVA_PWM_CC_PWMDIV, chan->controller_base + TIVA_PWM_CC); return (FAR struct pwm_lowerhalf_s *)chan; } - -/**************************************************************************** -* Name: board_pwm_setup -* -* Description: -* No implementation for now, it's called by PWM tool. -* -* Input Parameters: -* None. -* -* Returned Value: -* Zero on Success. -* -****************************************************************************/ - -int board_pwm_setup(void) -{ - return OK; -} diff --git a/arch/arm/src/tiva/tiva_pwm.h b/arch/arm/src/tiva/tiva_pwm.h index d75e704c713..c60b37617b2 100644 --- a/arch/arm/src/tiva/tiva_pwm.h +++ b/arch/arm/src/tiva/tiva_pwm.h @@ -47,8 +47,6 @@ ****************************************************************************/ FAR struct pwm_lowerhalf_s *tiva_pwm_initialize(int channel); - void tm4c_pwm_register(int channel); -int board_pwm_setup(void); #endif /* __ARCH_ARM_SRC_TIVA_TIVA_PWM_H */ diff --git a/arch/sim/src/up_ioexpander.c b/arch/sim/src/up_ioexpander.c index ca2a3349100..4451e123cf3 100644 --- a/arch/sim/src/up_ioexpander.c +++ b/arch/sim/src/up_ioexpander.c @@ -701,7 +701,7 @@ static ioe_pinset_t sim_int_update(FAR struct sim_dev_s *priv) } else /* if (SIM_LEVEL_SENSITIVE(priv, pin)) */ { - /* Level triggered. Set intstat if imatch in level type. */ + /* Level triggered. Set intstat if match in level type. */ if ((pinval && SIM_LEVEL_HIGH(priv, pin)) || (!pinval && SIM_LEVEL_LOW(priv, pin))) diff --git a/configs/tm4c1294-launchpad/src/tm4c_bringup.c b/configs/tm4c1294-launchpad/src/tm4c_bringup.c index e19d9e693d9..194b06938fe 100644 --- a/configs/tm4c1294-launchpad/src/tm4c_bringup.c +++ b/configs/tm4c1294-launchpad/src/tm4c_bringup.c @@ -37,13 +37,13 @@ * Included Files ****************************************************************************/ -#include -#include - #include +#include +#include #include +#include #include #include @@ -54,7 +54,6 @@ #define PWM_PATH_FMT "/dev/pwm%d" #define PWM_PATH_FMTLEN (10) - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -171,7 +170,7 @@ void tm4c_pwm_register(int channel) dev = tiva_pwm_initialize(channel); if (dev == NULL) { - dbg("ERROR: Failed to get PWM%d interface\n", channel); + pwmerr("ERROR: Failed to get PWM%d interface\n", channel); } else { @@ -179,7 +178,8 @@ void tm4c_pwm_register(int channel) ret = pwm_register(pwm_path, dev); if (ret < 0) { - dbg("ERROR: Failed to register PWM%d driver: %d\n", channel, ret); + pwmerr("ERROR: Failed to register PWM%d driver: %d\n", + channel, ret); } } } @@ -193,7 +193,6 @@ void tm4c_pwm_register(int channel) ****************************************************************************/ #ifdef HAVE_PWM - static void tm4c_pwm(void) { #ifdef CONFIG_TIVA_PWM0_CHAN0 @@ -221,8 +220,7 @@ static void tm4c_pwm(void) tm4c_pwm_register(7); #endif } - -#endif +#endif # HAVE_PWM /**************************************************************************** * Public Functions @@ -246,9 +244,11 @@ int tm4c_bringup(void) tm4c_i2ctool(); +#ifdef HAVE_PWM /* Register PWM drivers */ tm4c_pwm(); +#endif #ifdef HAVE_TIMER /* Initialize the timer driver */ @@ -262,3 +262,26 @@ int tm4c_bringup(void) return OK; } + +/**************************************************************************** + * Name: board_pwm_setup + * + * Description: + * No implementation for now, it's called by PWM tool via boardctl.h. + * See include/nuttx/board.h + * + * Input Parameters: + * None. + * + * Returned Value: + * Zero on Success. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARDCTL_PWMTEST +int board_pwm_setup(void) +{ + return OK; +} +#endif +