File indexing completed on 2025-05-11 08:23:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <rtems/status-checks.h>
0020 #include <bsp/pwmout.h>
0021 #include <bsp/pwmout-defs.h>
0022
0023
0024
0025
0026 static lpc176x_pwm_device *const pwm_device =
0027 (lpc176x_pwm_device *) PWM1_BASE_ADDR;
0028
0029
0030
0031
0032 static const lpc176x_pwm_pin pwm_pins[ PWM_OUTPUT_NUMBER ][ PWM_NUMBER_OF_PINS
0033 ] =
0034 {
0035 { { 50u, LPC176X_PIN_FUNCTION_10 }, { 64u, LPC176X_PIN_FUNCTION_01 } },
0036 { { 52u, LPC176X_PIN_FUNCTION_10 }, { 65u, LPC176X_PIN_FUNCTION_01 } },
0037 { { 53u, LPC176X_PIN_FUNCTION_10 }, { 66u, LPC176X_PIN_FUNCTION_01 } },
0038 { { 55u, LPC176X_PIN_FUNCTION_10 }, { 67u, LPC176X_PIN_FUNCTION_01 } },
0039 { { 56u, LPC176X_PIN_FUNCTION_10 }, { 68u, LPC176X_PIN_FUNCTION_01 } },
0040 { { 58u, LPC176X_PIN_FUNCTION_10 }, { 69u, LPC176X_PIN_FUNCTION_01 } },
0041 };
0042
0043
0044
0045
0046 static volatile uint32_t *const pwm_match[ PWM_OUTPUT_NUMBER ] = {
0047 &PWM1MR1,
0048 &PWM1MR2,
0049 &PWM1MR3,
0050 &PWM1MR4,
0051 &PWM1MR5,
0052 &PWM1MR6
0053 };
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 static inline bool is_found_in_this_pwm(
0066 const lpc176x_pin_number pin_number,
0067 const lpc176x_pwm_number pwm,
0068 lpc176x_pin_function *const pin_function
0069 )
0070 {
0071 lpc176x_pwm_pin_number pnumber = PWM_FIRST_PIN;
0072 bool found = false;
0073
0074 while (!found && ( pnumber < PWM_NUMBER_OF_PINS ))
0075 {
0076 if ( pwm_pins[ pwm ][ pnumber ].pin_number == pin_number ) {
0077 found = true;
0078 *pin_function = pwm_pins[ pwm ][ pnumber ].pin_function;
0079 }
0080 ++pnumber;
0081 }
0082 return found;
0083 }
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 static bool is_valid_pin_number(
0096 const lpc176x_pin_number pin_number,
0097 lpc176x_pwm_number *const pwm,
0098 lpc176x_pin_function *const pin_function
0099 )
0100 {
0101 bool found = false;
0102 lpc176x_pwm_number pwm_local = PWMO_1;
0103 while(!found && ( pwm_local < PWM_OUTPUT_NUMBER ))
0104 {
0105 if ( is_found_in_this_pwm( pin_number, pwm_local, pin_function ) ) {
0106 *pwm = pwm_local;
0107 found = true;
0108 }
0109 ++pwm_local;
0110 }
0111
0112 return found;
0113 }
0114
0115
0116
0117
0118
0119
0120
0121 static void set_period(
0122 const lpc176x_pwm_number pwm,
0123 const lpc176x_microseconds period
0124 )
0125 {
0126 pwm_device->TCR = PWM_TCR_RESET;
0127 pwm_device->MR0 = period * PWM_PRESCALER_USECOND;
0128 pwm_device->LER |= PWM_LER_LATCH_MATCH_0;
0129 pwm_device->TCR = PWM_TCR_PWM | PWM_TCR_ENABLE;
0130 }
0131
0132
0133
0134
0135
0136
0137
0138 static void set_pulsewidth(
0139 const lpc176x_pwm_number pwm,
0140 lpc176x_microseconds pwidth
0141 )
0142 {
0143 pwidth *= PWM_PRESCALER_USECOND;
0144
0145 if ( pwm_device->MR0 == pwidth ) {
0146 ++pwidth;
0147 }
0148
0149 *( pwm_match[ pwm ] ) = pwidth;
0150 pwm_device->LER |= PWM_LER_LATCH( pwm );
0151 }
0152
0153 rtems_status_code pwm_init( const lpc176x_pin_number pin_number )
0154 {
0155 rtems_status_code sc = RTEMS_INVALID_NUMBER;
0156 lpc176x_pin_function pin_function;
0157 lpc176x_pwm_number pwm;
0158
0159 if ( is_valid_pin_number( pin_number, &pwm, &pin_function ) ) {
0160 sc = lpc176x_module_enable( LPC176X_MODULE_PWM_1,
0161 LPC176X_MODULE_PCLK_DEFAULT );
0162 RTEMS_CHECK_SC( sc, "enable pwm module" );
0163
0164 pwm_device->PR = 0;
0165 pwm_device->MCR = PWM_MCR_RESET_ON_MATCH0;
0166 pwm_device->PCR |= PWM_PCR_ENABLE_PWM( pwm );
0167
0168 set_period( pwm, PWM_DEFAULT_PERIOD );
0169 set_pulsewidth( pwm, PWM_DEFAULT_PULSEWIDTH );
0170
0171 lpc176x_pin_select( pin_number, pin_function );
0172 }
0173
0174
0175 return sc;
0176 }
0177
0178 rtems_status_code pwm_period(
0179 const lpc176x_pin_number pin_number,
0180 const lpc176x_microseconds period
0181 )
0182 {
0183 rtems_status_code sc = RTEMS_INVALID_NUMBER;
0184 lpc176x_pin_function pin_function;
0185 lpc176x_pwm_number pwm;
0186
0187 if ( is_valid_pin_number( pin_number, &pwm, &pin_function ) ) {
0188 sc = RTEMS_SUCCESSFUL;
0189 set_period( pwm, period );
0190 }
0191
0192
0193 return sc;
0194 }
0195
0196 rtems_status_code pwm_pulsewidth(
0197 const lpc176x_pin_number pin_number,
0198 const lpc176x_microseconds pwidth
0199 )
0200 {
0201 rtems_status_code sc = RTEMS_INVALID_NUMBER;
0202 lpc176x_pin_function pin_function;
0203 lpc176x_pwm_number pwm;
0204
0205 if ( is_valid_pin_number( pin_number, &pwm, &pin_function ) ) {
0206 sc = RTEMS_SUCCESSFUL;
0207 set_pulsewidth( pwm, pwidth );
0208 }
0209
0210 return sc;
0211 }