diff options
author | Martin Galvan <martin.galvan@tallertechnologies.com> | 2015-03-11 16:57:23 -0300 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-03-20 09:16:07 +0100 |
commit | 7b35a36fb16491dbdb98106ab39d35b8d19598e5 (patch) | |
tree | a5c23a33c3316623fa5fa5129f6669147f249bb0 /c/src/lib/libbsp/arm/lpc176x/pwmout/pwmout.c | |
parent | score: Fix _Thread_Change_priority() (diff) | |
download | rtems-7b35a36fb16491dbdb98106ab39d35b8d19598e5.tar.bz2 |
Add CAN, PWM, ADC and UART1/2/3 support to the LPC176x BSP.
This patch adds support for the following devices to the LPC176x BSP:
* CAN
* PWM
* ADC
It also adds the probe routines for UART1/2/3 to the console_device_table in console-config.c, and enables UART1 in configure.ac.
Diffstat (limited to '')
-rwxr-xr-x | c/src/lib/libbsp/arm/lpc176x/pwmout/pwmout.c | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/lpc176x/pwmout/pwmout.c b/c/src/lib/libbsp/arm/lpc176x/pwmout/pwmout.c new file mode 100755 index 0000000000..a3683869a5 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/pwmout/pwmout.c @@ -0,0 +1,210 @@ +/** + * @file pwmout.c + * + * @ingroup lpc176x + * + * @brief PWM-Out controller for the mbed lpc1768 board. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include <rtems/status-checks.h> +#include <bsp/pwmout.h> +#include <bsp/pwmout-defs.h> + +/** + * @brief The low level device. + */ +static lpc176x_pwm_device *const pwm_device = PWM1_BASE_ADDR; + +/** + * @brief The possible output pins for each PWM output. + */ +static const lpc176x_pwm_pin pwm_pins[ PWM_OUTPUT_NUMBER ][ PWM_NUMBER_OF_PINS +] = +{ + { { 50u, LPC176X_PIN_FUNCTION_10 }, { 64u, LPC176X_PIN_FUNCTION_01 } }, + { { 52u, LPC176X_PIN_FUNCTION_10 }, { 65u, LPC176X_PIN_FUNCTION_01 } }, + { { 53u, LPC176X_PIN_FUNCTION_10 }, { 66u, LPC176X_PIN_FUNCTION_01 } }, + { { 55u, LPC176X_PIN_FUNCTION_10 }, { 67u, LPC176X_PIN_FUNCTION_01 } }, + { { 56u, LPC176X_PIN_FUNCTION_10 }, { 68u, LPC176X_PIN_FUNCTION_01 } }, + { { 58u, LPC176X_PIN_FUNCTION_10 }, { 69u, LPC176X_PIN_FUNCTION_01 } }, +}; + +/** + * @brief The pointers to the low level match registers for each PWM output. + */ +static volatile uint32_t *const pwm_match[ PWM_OUTPUT_NUMBER ] = { + &PWM1MR1, + &PWM1MR2, + &PWM1MR3, + &PWM1MR4, + &PWM1MR5, + &PWM1MR6 +}; + +/** + * @brief Checks if a pin number is valid for the given PWM, + * and sets the corresponding pin function for that pin. + * + * @param pin_number The pin number to search. + * @param pwm In which PWM search for the pin number. + * @param pin_function If the pin number is found, here we return + * the pin function for that pin number. + * @return True if found, false otherwise. + */ +static inline bool is_found_in_this_pwm( + const lpc176x_pin_number pin_number, + const lpc176x_pwm_number pwm, + lpc176x_pin_function *const pin_function +) +{ + lpc176x_pwm_pin_number pnumber = PWM_FIRST_PIN; + bool found = false; + + while (!found && ( pnumber < PWM_NUMBER_OF_PINS )) + { + if ( pwm_pins[ pwm ][ pnumber ].pin_number == pin_number ) { + found = true; + *pin_function = pwm_pins[ pwm ][ pnumber ].pin_function; + }/*else implies that the pin number was not found. Keep looking.*/ + ++pnumber; + } + return found; +} + +/** + * @brief Checks if a pin number is valid for any PWM, + * and sets the corresponding pin function for that pin. + * + * @param pin_number The pin number to search. + * @param pwm If is found here we return in which PWM was found. + * @param pin_function If the pin number is found the pin function + * for this pin number one will be returned. + * @return True if found, false otherwise. + */ +static bool is_valid_pin_number( + const lpc176x_pin_number pin_number, + lpc176x_pwm_number *const pwm, + lpc176x_pin_function *const pin_function +) +{ + bool found = false; + lpc176x_pwm_number pwm_local = PWMO_1; + while(!found && ( pwm_local < PWM_OUTPUT_NUMBER )) + { + if ( is_found_in_this_pwm( pin_number, pwm_local, pin_function ) ) { + *pwm = pwm_local; + found = true; + } /*else implies that the pin number was not found. Keep looking.*/ + ++pwm_local; + } + + return found; +} + +/** + * @brief Sets the period for the given PWM. + * + * @param pwm The PWM output in which the period will be set. + * @param period The period to set. + */ +static void set_period( + const lpc176x_pwm_number pwm, + const lpc176x_microseconds period +) +{ + pwm_device->TCR = PWM_TCR_RESET; + pwm_device->MR0 = period * PWM_PRESCALER_USECOND; + pwm_device->LER |= PWM_LER_LATCH_MATCH_0; + pwm_device->TCR = PWM_TCR_PWM | PWM_TCR_ENABLE; +} + +/** + * @brief Sets the pulsewidth for the given PWM. + * + * @param pwm The PWM output in which the pulsewidth will be set. + * @param pwidth The pulse width to set. + */ +static void set_pulsewidth( + const lpc176x_pwm_number pwm, + lpc176x_microseconds pwidth +) +{ + pwidth *= PWM_PRESCALER_USECOND; + + if ( pwm_device->MR0 == pwidth ) { + ++pwidth; + } /* Not the same as the period, do nothing.*/ + + *( pwm_match[ pwm ] ) = pwidth; + pwm_device->LER |= PWM_LER_LATCH( pwm ); +} + +rtems_status_code pwm_init( const lpc176x_pin_number pin_number ) +{ + rtems_status_code sc = RTEMS_INVALID_NUMBER; + lpc176x_pin_function pin_function; + lpc176x_pwm_number pwm; + + if ( is_valid_pin_number( pin_number, &pwm, &pin_function ) ) { + sc = lpc176x_module_enable( LPC176X_MODULE_PWM_1, + LPC176X_MODULE_PCLK_DEFAULT ); + RTEMS_CHECK_SC( sc, "enable pwm module" ); + + pwm_device->PR = 0; + pwm_device->MCR = PWM_MCR_RESET_ON_MATCH0; + pwm_device->PCR |= PWM_PCR_ENABLE_PWM( pwm ); + + set_period( pwm, PWM_DEFAULT_PERIOD ); + set_pulsewidth( pwm, PWM_DEFAULT_PULSEWIDTH ); + + lpc176x_pin_select( pin_number, pin_function ); + } /* else implies that the pin number is not valid. + So, a RTEMS_INVALID_NUMBER will be returned.*/ + + return sc; +} + +rtems_status_code pwm_period( + const lpc176x_pin_number pin_number, + const lpc176x_microseconds period +) +{ + rtems_status_code sc = RTEMS_INVALID_NUMBER; + lpc176x_pin_function pin_function; + lpc176x_pwm_number pwm; + + if ( is_valid_pin_number( pin_number, &pwm, &pin_function ) ) { + sc = RTEMS_SUCCESSFUL; + set_period( pwm, period ); + } /* else implies that the pin number is not valid. + So, a RTEMS_INVALID_NUMBER will be returned.*/ + + return sc; +} + +rtems_status_code pwm_pulsewidth( + const lpc176x_pin_number pin_number, + const lpc176x_microseconds pwidth +) +{ + rtems_status_code sc = RTEMS_INVALID_NUMBER; + lpc176x_pin_function pin_function; + lpc176x_pwm_number pwm; + + if ( is_valid_pin_number( pin_number, &pwm, &pin_function ) ) { + sc = RTEMS_SUCCESSFUL; + set_pulsewidth( pwm, pwidth ); + } /* Else wrong pin_number return RTEMS_INVALID_NUMBER*/ + + return sc; +} |