|
13 | 13 | * See the License for the specific language governing permissions and
|
14 | 14 | * limitations under the License.
|
15 | 15 | */
|
| 16 | + |
16 | 17 | #include "mbed_assert.h"
|
17 | 18 | #include "analogin_api.h"
|
18 | 19 | #include "cmsis.h"
|
19 | 20 | #include "pinmap.h"
|
| 21 | +#include "app_util_platform.h" |
| 22 | +#include "nrf_drv_saadc.h" |
20 | 23 |
|
21 | 24 | #ifdef DEVICE_ANALOGIN
|
22 | 25 |
|
23 |
| -#define ANALOGIN_MEDIAN_FILTER 1 |
24 |
| -#define ADC_10BIT_RANGE 0x3FF |
25 |
| -#define ADC_RANGE ADC_10BIT_RANGE |
| 26 | +#define ADC_12BIT_RANGE 0xFFF |
| 27 | +#define ADC_RANGE ADC_12BIT_RANGE |
26 | 28 |
|
27 |
| -static const PinMap PinMap_ADC[] = { |
28 |
| - {p1, ADC0_0, 4}, |
29 |
| - {p2, ADC0_0, 8}, |
30 |
| - {p3, ADC0_0, 16}, |
31 |
| - {p4, ADC0_0, 32}, |
32 |
| - {p5, ADC0_0, 64}, |
33 |
| - {p6, ADC0_0, 128}, |
34 |
| - {NC, NC, 0} |
| 29 | +static void analog_in_event_handler(nrf_drv_saadc_evt_t const *p_event)// type of nrf_drv_saadc_event_handler_t |
| 30 | +{ |
| 31 | + (void) p_event; |
| 32 | +} |
| 33 | + |
| 34 | +static const nrf_drv_saadc_config_t saadc_config = |
| 35 | +{ |
| 36 | + .resolution = NRF_SAADC_RESOLUTION_12BIT, |
| 37 | + .oversample = NRF_SAADC_OVERSAMPLE_DISABLED, |
| 38 | + .interrupt_priority = APP_IRQ_PRIORITY_LOW |
35 | 39 | };
|
36 | 40 |
|
37 | 41 | void analogin_init(analogin_t *obj, PinName pin)
|
38 | 42 | {
|
39 |
| - // TODO: usage on nrf52 ? |
40 |
| -#if 0 |
41 |
| - int analogInputPin = 0; |
42 |
| - const PinMap *map = PinMap_ADC; |
43 |
| - |
44 |
| - obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); //(NRF_ADC_Type *) |
45 |
| - MBED_ASSERT(obj->adc != (ADCName)NC); |
46 |
| - |
47 |
| - while (map->pin != NC) { |
48 |
| - if (map->pin == pin) { |
49 |
| - analogInputPin = map->function; |
50 |
| - break; |
51 |
| - } |
52 |
| - map++; |
53 |
| - } |
54 |
| - obj->adc_pin = (uint8_t)analogInputPin; |
55 |
| - |
56 |
| - NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled; |
57 |
| - NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) | |
58 |
| - (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) | |
59 |
| - (ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling << ADC_CONFIG_REFSEL_Pos) | |
60 |
| - (analogInputPin << ADC_CONFIG_PSEL_Pos) | |
61 |
| - (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); |
62 |
| -#endif |
| 43 | + ret_code_t ret_code; |
| 44 | + |
| 45 | + ret_code = nrf_drv_saadc_init(&saadc_config, analog_in_event_handler); |
| 46 | + MBED_ASSERT(((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_INVALID_STATE))); //NRF_ERROR_INVALID_STATE expected for multiple channels used. |
| 47 | + |
| 48 | + uint8_t saadcIn = nrf_drv_saadc_gpio_to_ain(pin); |
| 49 | + MBED_ASSERT(saadcIn != NRF_SAADC_INPUT_DISABLED); |
| 50 | + |
| 51 | + obj->adc = ADC0_0; // only one instance of ADC in nRF52 SoC |
| 52 | + obj->adc_pin = saadcIn - 1; |
| 53 | + |
| 54 | + nrf_saadc_channel_config_t channel_config = |
| 55 | + NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(saadcIn); //Single ended, negative input to ADC shorted to GND. |
| 56 | + |
| 57 | + ret_code = nrf_drv_saadc_channel_init(obj->adc_pin, &channel_config); |
| 58 | + MBED_ASSERT(ret_code == NRF_SUCCESS); |
63 | 59 | }
|
64 | 60 |
|
| 61 | + |
65 | 62 | uint16_t analogin_read_u16(analogin_t *obj)
|
66 | 63 | {
|
67 |
| - // TODO: usage on nrf52 ? |
68 |
| -#if 0 |
69 |
| - NRF_ADC->CONFIG &= ~ADC_CONFIG_PSEL_Msk; |
70 |
| - NRF_ADC->CONFIG |= obj->adc_pin << ADC_CONFIG_PSEL_Pos; |
71 |
| - NRF_ADC->TASKS_START = 1; |
72 |
| - while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy) { |
| 64 | + int16_t adc_value; |
| 65 | + ret_code_t ret_code; |
| 66 | + |
| 67 | + ret_code = nrf_drv_saadc_sample_convert(obj->adc_pin, &adc_value); |
| 68 | + MBED_ASSERT(ret_code == NRF_SUCCESS); |
| 69 | + |
| 70 | + if (adc_value < 0) |
| 71 | + { |
| 72 | + // Even in the single ended mode measured value can be {-0}. Saturation for avoid casting to a big integer. |
| 73 | + return 0; |
| 74 | + } |
| 75 | + else |
| 76 | + { |
| 77 | + return (uint16_t) adc_value; |
73 | 78 | }
|
74 |
| - |
75 |
| - return (uint16_t)NRF_ADC->RESULT; // 10 bit |
76 |
| -#endif |
77 |
| - return 0; |
78 | 79 | }
|
79 | 80 |
|
80 | 81 | float analogin_read(analogin_t *obj)
|
|
0 commit comments