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 #include <rtems/status-checks.h>
0019 #include <bsp/adc.h>
0020 #include <bsp/adc-defs.h>
0021
0022 static lpc176x_adc_device *const adc_device =
0023 (lpc176x_adc_device *) AD0_BASE_ADDR;
0024
0025 static const lpc176x_adc_pin_map adc_pinmap[ ADC_DEVICES_COUNT ] =
0026 {
0027 {
0028 .pin_number = 23u,
0029 .pin_function = LPC176X_PIN_FUNCTION_01
0030 },
0031 {
0032 .pin_number = 24u,
0033 .pin_function = LPC176X_PIN_FUNCTION_01
0034 },
0035 {
0036 .pin_number = 25u,
0037 .pin_function = LPC176X_PIN_FUNCTION_01
0038 },
0039 {
0040 .pin_number = 26u,
0041 .pin_function = LPC176X_PIN_FUNCTION_01
0042 },
0043 {
0044 .pin_number = 62u,
0045 .pin_function = LPC176X_PIN_FUNCTION_11
0046 },
0047 {
0048 .pin_number = 63u,
0049 .pin_function = LPC176X_PIN_FUNCTION_11
0050 },
0051 {
0052 .pin_number = 3u,
0053 .pin_function = LPC176X_PIN_FUNCTION_10
0054 },
0055 {
0056 .pin_number = 2u,
0057 .pin_function = LPC176X_PIN_FUNCTION_10
0058 }
0059 };
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 static bool valid_pin_number (
0070 const lpc176x_pin_number pin_number,
0071 lpc176x_adc_number *const adc_number
0072 )
0073 {
0074 bool found = false;
0075 lpc176x_adc_number adc_device = ADC_0;
0076
0077 while (!found && (adc_device < ADC_DEVICES_COUNT))
0078 {
0079 if (adc_pinmap[adc_device].pin_number == pin_number)
0080 {
0081 *adc_number = adc_device;
0082 found = true;
0083 }
0084 ++adc_device;
0085 }
0086
0087 return found;
0088 }
0089
0090
0091
0092
0093
0094 static void turn_on_and_set_clkdiv( void )
0095 {
0096 const uint32_t clkdiv = LPC176X_CCLK / ( LPC176X_PCLKDIV * MAX_ADC_CLK );
0097
0098 adc_device->ADCR = ADC_CR_PDN | ADC_CR_CLKDIV( clkdiv );
0099 }
0100
0101 rtems_status_code adc_open( const lpc176x_pin_number pin_number )
0102 {
0103 rtems_status_code sc = RTEMS_INVALID_NUMBER;
0104 lpc176x_adc_number adc_number = 0;
0105 if ( valid_pin_number( pin_number, &adc_number ) ) {
0106 sc =
0107 lpc176x_module_enable( LPC176X_MODULE_ADC, LPC176X_MODULE_PCLK_DEFAULT );
0108 RTEMS_CHECK_SC( sc, "enable adc module" );
0109
0110 turn_on_and_set_clkdiv();
0111 lpc176x_pin_select( adc_pinmap[ adc_number ].pin_number,
0112 adc_pinmap[ adc_number ].pin_function );
0113 lpc176x_pin_set_mode( adc_pinmap[ adc_number ].pin_number,
0114 LPC176X_PIN_MODE_NONE );
0115 }
0116
0117 return sc;
0118 }
0119
0120 rtems_status_code adc_close( void )
0121 {
0122 adc_device->ADCR &= ~ADC_CR_PDN;
0123
0124 return lpc176x_module_disable( LPC176X_MODULE_ADC );
0125 }
0126
0127
0128
0129
0130
0131
0132 static inline void start_conversion( const lpc176x_adc_number number )
0133 {
0134 adc_device->ADCR =
0135 ADC_CR_SEL_SET( adc_device->ADCR, ( 1 << number ) ) | ADC_CR_START_NOW;
0136 }
0137
0138
0139
0140
0141
0142 static inline void stop_conversion( void )
0143 {
0144 adc_device->ADCR &= ~ADC_CR_START_NOW;
0145 }
0146
0147
0148
0149
0150
0151
0152
0153 static inline float get_float( const uint32_t data )
0154 {
0155 return ( (float) data / (float) ADC_RANGE );
0156 }
0157
0158
0159
0160
0161
0162
0163
0164
0165 static uint32_t read( const lpc176x_adc_number adc_number )
0166 {
0167 uint32_t data;
0168
0169 start_conversion( adc_number );
0170
0171 do {
0172 data = adc_device->ADGDR;
0173 } while ( !ADC_DATA_CONVERSION_DONE( data ) );
0174
0175 stop_conversion();
0176
0177 return ADC_DR_VALUE( data );
0178 }
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189 static inline bool lowest_to_highest_ordered(
0190 const uint32_t a,
0191 const uint32_t b,
0192 const uint32_t c
0193 )
0194 {
0195 return ( ( a <= b ) && ( b <= c ) );
0196 }
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207 static uint32_t get_median(
0208 const uint32_t a,
0209 const uint32_t b,
0210 const uint32_t c
0211 )
0212 {
0213 uint32_t median;
0214
0215 if ( lowest_to_highest_ordered( a, b, c)
0216 || lowest_to_highest_ordered( c, b, a ) ) {
0217 median = b;
0218 } else if ( lowest_to_highest_ordered( b, a, c )
0219 || lowest_to_highest_ordered( c, a, b ) ) {
0220 median = a;
0221 } else {
0222 median = c;
0223 }
0224
0225 return median;
0226 }
0227
0228 rtems_status_code adc_read(
0229 const lpc176x_pin_number pin_number ,
0230 float *const result
0231 )
0232 {
0233 rtems_status_code sc = RTEMS_INVALID_NUMBER;
0234 lpc176x_adc_number adc_number = 0;
0235 if ( valid_pin_number( pin_number, &adc_number ) ) {
0236 const uint32_t first = read( adc_number );
0237 const uint32_t second = read( adc_number );
0238 const uint32_t third = read( adc_number );
0239 const uint32_t median = get_median( first, second, third );
0240 *result = get_float( median );
0241 sc = RTEMS_SUCCESSFUL;
0242 }
0243
0244 return sc;
0245 }