mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
168:9672193075cf
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 168:9672193075cf 1 /* mbed Microcontroller Library
AnnaBridge 168:9672193075cf 2 * Copyright (c) 2017 ARM Limited
AnnaBridge 168:9672193075cf 3 *
AnnaBridge 168:9672193075cf 4 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 168:9672193075cf 5 * you may not use this file except in compliance with the License.
AnnaBridge 168:9672193075cf 6 * You may obtain a copy of the License at
AnnaBridge 168:9672193075cf 7 *
AnnaBridge 168:9672193075cf 8 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 168:9672193075cf 9 *
AnnaBridge 168:9672193075cf 10 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 168:9672193075cf 11 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 168:9672193075cf 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 168:9672193075cf 13 * See the License for the specific language governing permissions and
AnnaBridge 168:9672193075cf 14 * limitations under the License.
AnnaBridge 168:9672193075cf 15 */
AnnaBridge 168:9672193075cf 16
AnnaBridge 168:9672193075cf 17 /*
AnnaBridge 168:9672193075cf 18 * This HAL implementation uses the AD7490 analog-to-digital converter
AnnaBridge 168:9672193075cf 19 * available on the MPS2 Adapter for Arduino shields.
AnnaBridge 168:9672193075cf 20 */
AnnaBridge 168:9672193075cf 21
AnnaBridge 168:9672193075cf 22 #include "analogin_api.h"
AnnaBridge 168:9672193075cf 23 #include "gpio_api.h"
AnnaBridge 168:9672193075cf 24 #include "spi_api.h"
AnnaBridge 168:9672193075cf 25 #include "mbed_error.h"
AnnaBridge 168:9672193075cf 26 #include "mbed_wait_api.h"
AnnaBridge 168:9672193075cf 27 #include "pinmap.h"
AnnaBridge 168:9672193075cf 28
AnnaBridge 168:9672193075cf 29 /*
AnnaBridge 168:9672193075cf 30 * There is only one AD7490 controller to read the analog pins in both shields.
AnnaBridge 168:9672193075cf 31 * The AD7490 documentation (AD7490.pdf, page 12) tells us the right control
AnnaBridge 168:9672193075cf 32 * register to send.
AnnaBridge 168:9672193075cf 33 */
AnnaBridge 168:9672193075cf 34
AnnaBridge 168:9672193075cf 35 /* Output conversion is straight binary */
AnnaBridge 168:9672193075cf 36 #define CODING (1 << 0)
AnnaBridge 168:9672193075cf 37 /* Analog input range from 0 to REF_IN volts */
AnnaBridge 168:9672193075cf 38 #define RANGE (1 << 1)
AnnaBridge 168:9672193075cf 39 /* DOUT line state, weakly driven or three-state */
AnnaBridge 168:9672193075cf 40 #define WEAK_TRI (1 << 2)
AnnaBridge 168:9672193075cf 41 /* Access to the shadow register */
AnnaBridge 168:9672193075cf 42 #define SHADOW (1 << 3)
AnnaBridge 168:9672193075cf 43 /* Normal operation power mode */
AnnaBridge 168:9672193075cf 44 #define PM0 (1 << 4)
AnnaBridge 168:9672193075cf 45 /* Normal operation power mode */
AnnaBridge 168:9672193075cf 46 #define PM1 (1 << 5)
AnnaBridge 168:9672193075cf 47 /* Write control register */
AnnaBridge 168:9672193075cf 48 #define WRITE (1 << 11)
AnnaBridge 168:9672193075cf 49 #define NORMAL_CONTROL_REGISTER (CODING | RANGE | PM0 | PM1 | WRITE)
AnnaBridge 168:9672193075cf 50 /* The ADC will ignore the write of this control register */
AnnaBridge 168:9672193075cf 51 #define NO_WRITE_CONTROL_REGISTER 0x000
AnnaBridge 168:9672193075cf 52 /* Bit position of the channel number in the control register */
AnnaBridge 168:9672193075cf 53 #define CHANNEL_NUMBER_POSITION 6
AnnaBridge 168:9672193075cf 54 /* CS signal of the ADC needs to be put low during transfers */
AnnaBridge 168:9672193075cf 55 #define CS_LOW 0
AnnaBridge 168:9672193075cf 56 #define CS_HIGH 1
AnnaBridge 168:9672193075cf 57 /* The ADC expects a 16 bits word but only read the 12 most significant bits */
AnnaBridge 168:9672193075cf 58 #define USELESS_ADC_BITS 4
AnnaBridge 168:9672193075cf 59 /* The ADC result is on the 12 least significant bits */
AnnaBridge 168:9672193075cf 60 #define OUTPUT_DATA_MASK 0xFFF
AnnaBridge 168:9672193075cf 61 /* The maximum value is the biggest value than can be coded on 12 bits */
AnnaBridge 168:9672193075cf 62 #define MAXIMUM_VALUE_12_BITS OUTPUT_DATA_MASK
AnnaBridge 168:9672193075cf 63 #define FRAME_16_BITS 16
AnnaBridge 168:9672193075cf 64 #define NO_POLARITY_NO_PHASE 0
AnnaBridge 168:9672193075cf 65 #define MASTER_MODE 0
AnnaBridge 168:9672193075cf 66 /* Maximal SPI frequency as written in the ADC documentation */
AnnaBridge 168:9672193075cf 67 #define MAXIMAL_SPI_FREQUENCY_HZ 12000000
AnnaBridge 168:9672193075cf 68
AnnaBridge 168:9672193075cf 69 /* The value of the peripheral constant linked with one analog pins is the
AnnaBridge 168:9672193075cf 70 * channel number of that pin on the ADC:
AnnaBridge 168:9672193075cf 71 * A0_0 is channel 0
AnnaBridge 168:9672193075cf 72 * ...
AnnaBridge 168:9672193075cf 73 * A0_5 is channel 5
AnnaBridge 168:9672193075cf 74 * A1_0 is channel 6
AnnaBridge 168:9672193075cf 75 * ...
AnnaBridge 168:9672193075cf 76 * A1_5 is channel 11
AnnaBridge 168:9672193075cf 77 */
AnnaBridge 168:9672193075cf 78 static const PinMap PinMap_ADC[] = {
AnnaBridge 168:9672193075cf 79 {A0_0, ADC0_0, 0},
AnnaBridge 168:9672193075cf 80 {A0_1, ADC0_1, 0},
AnnaBridge 168:9672193075cf 81 {A0_2, ADC0_2, 0},
AnnaBridge 168:9672193075cf 82 {A0_3, ADC0_3, 0},
AnnaBridge 168:9672193075cf 83 {A0_4, ADC0_4, 0},
AnnaBridge 168:9672193075cf 84 {A0_5, ADC0_5, 0},
AnnaBridge 168:9672193075cf 85 {A1_0, ADC0_6, 0},
AnnaBridge 168:9672193075cf 86 {A1_1, ADC0_7, 0},
AnnaBridge 168:9672193075cf 87 {A1_2, ADC0_8, 0},
AnnaBridge 168:9672193075cf 88 {A1_3, ADC0_9, 0},
AnnaBridge 168:9672193075cf 89 {A1_4, ADC0_10, 0},
AnnaBridge 168:9672193075cf 90 {A1_5, ADC0_11, 0},
AnnaBridge 168:9672193075cf 91 {NC , NC, 0}
AnnaBridge 168:9672193075cf 92 };
AnnaBridge 168:9672193075cf 93
AnnaBridge 168:9672193075cf 94 /* mbed OS gpio_t structure for the CS pin linked to the ADC */
AnnaBridge 168:9672193075cf 95 static gpio_t adc_cs;
AnnaBridge 168:9672193075cf 96
AnnaBridge 168:9672193075cf 97 /* mbed OS spi_t structure to communicate with the ADC */
AnnaBridge 168:9672193075cf 98 static spi_t adc_spi;
AnnaBridge 168:9672193075cf 99
AnnaBridge 168:9672193075cf 100 void analogin_init(analogin_t *obj, PinName pin)
AnnaBridge 168:9672193075cf 101 {
AnnaBridge 168:9672193075cf 102 uint16_t control_register = NORMAL_CONTROL_REGISTER;
AnnaBridge 168:9672193075cf 103 uint32_t channel_number = pinmap_peripheral(pin, PinMap_ADC);
AnnaBridge 168:9672193075cf 104
AnnaBridge 168:9672193075cf 105 if (channel_number == (uint32_t)NC) {
AnnaBridge 168:9672193075cf 106 error("pin %d is not connected to the ADC", pin);
AnnaBridge 168:9672193075cf 107 }
AnnaBridge 168:9672193075cf 108
AnnaBridge 168:9672193075cf 109 /* Add the channel number to the control register */
AnnaBridge 168:9672193075cf 110 control_register |= (channel_number << CHANNEL_NUMBER_POSITION);
AnnaBridge 168:9672193075cf 111 /* Only the 12 first bits are taken into account */
AnnaBridge 168:9672193075cf 112 control_register <<= USELESS_ADC_BITS;
AnnaBridge 168:9672193075cf 113 obj->ctrl_register = control_register;
AnnaBridge 168:9672193075cf 114
AnnaBridge 168:9672193075cf 115 spi_init(&adc_spi, ADC_MOSI, ADC_MISO, ADC_SCLK, NC);
AnnaBridge 168:9672193075cf 116 spi_format(&adc_spi, FRAME_16_BITS, NO_POLARITY_NO_PHASE, MASTER_MODE);
AnnaBridge 168:9672193075cf 117 spi_frequency(&adc_spi, MAXIMAL_SPI_FREQUENCY_HZ);
AnnaBridge 168:9672193075cf 118
AnnaBridge 168:9672193075cf 119 gpio_init_out(&adc_cs, ADC_SSEL);
AnnaBridge 168:9672193075cf 120 }
AnnaBridge 168:9672193075cf 121
AnnaBridge 168:9672193075cf 122 uint16_t analogin_read_u16(analogin_t *obj)
AnnaBridge 168:9672193075cf 123 {
AnnaBridge 168:9672193075cf 124 uint16_t result;
AnnaBridge 168:9672193075cf 125
AnnaBridge 168:9672193075cf 126 /* Request conversion */
AnnaBridge 168:9672193075cf 127 gpio_write(&adc_cs, CS_LOW);
AnnaBridge 168:9672193075cf 128 /* Only write the control register, ignore the previous results */
AnnaBridge 168:9672193075cf 129 (void)spi_master_write(&adc_spi, obj->ctrl_register);
AnnaBridge 168:9672193075cf 130 gpio_write(&adc_cs, CS_HIGH);
AnnaBridge 168:9672193075cf 131
AnnaBridge 168:9672193075cf 132 /*
AnnaBridge 168:9672193075cf 133 * According to the documentation, t_QUIET (50 ns) time needs to pass before
AnnaBridge 168:9672193075cf 134 * accessing to the SPI bus again. We wait here 1 us as we can not wait a
AnnaBridge 168:9672193075cf 135 * shorter time than that.
AnnaBridge 168:9672193075cf 136 */
AnnaBridge 168:9672193075cf 137 wait_us(1);
AnnaBridge 168:9672193075cf 138
AnnaBridge 168:9672193075cf 139 /* Read conversion result */
AnnaBridge 168:9672193075cf 140 gpio_write(&adc_cs, CS_LOW);
AnnaBridge 168:9672193075cf 141 /* Only read the results without writing the control register */
AnnaBridge 168:9672193075cf 142 result = spi_master_write(&adc_spi, NO_WRITE_CONTROL_REGISTER);
AnnaBridge 168:9672193075cf 143 gpio_write(&adc_cs, CS_HIGH);
AnnaBridge 168:9672193075cf 144
AnnaBridge 168:9672193075cf 145 return (result & OUTPUT_DATA_MASK);
AnnaBridge 168:9672193075cf 146 }
AnnaBridge 168:9672193075cf 147
AnnaBridge 168:9672193075cf 148 float analogin_read(analogin_t *obj)
AnnaBridge 168:9672193075cf 149 {
AnnaBridge 168:9672193075cf 150 uint16_t result = analogin_read_u16(obj);
AnnaBridge 168:9672193075cf 151
AnnaBridge 168:9672193075cf 152 return (result * (1. / MAXIMUM_VALUE_12_BITS));
AnnaBridge 168:9672193075cf 153 }