A collection of Analog Devices drivers for the mbed platform

For additional information check out the mbed page of the Analog Devices wiki: https://wiki.analog.com/resources/tools-software/mbed-drivers-all

Committer:
Adrian Suciu
Date:
Mon Nov 07 16:27:12 2016 +0200
Revision:
33:c3ec596a29c2
Added CN0391, CN0396 and CN0397 shields

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Adrian Suciu 33:c3ec596a29c2 1 /**
Adrian Suciu 33:c3ec596a29c2 2 * @file CN0397.cpp
Adrian Suciu 33:c3ec596a29c2 3 * @brief Source file for the CN0397
Adrian Suciu 33:c3ec596a29c2 4 * @author Analog Devices Inc.
Adrian Suciu 33:c3ec596a29c2 5 *
Adrian Suciu 33:c3ec596a29c2 6 * For support please go to:
Adrian Suciu 33:c3ec596a29c2 7 * Github: https://github.com/analogdevicesinc/mbed-adi
Adrian Suciu 33:c3ec596a29c2 8 * Support: https://ez.analog.com/community/linux-device-drivers/microcontroller-no-os-drivers
Adrian Suciu 33:c3ec596a29c2 9 * Product: www.analog.com/EVAL-CN0397-ARDZ
Adrian Suciu 33:c3ec596a29c2 10 * More: https://wiki.analog.com/resources/tools-software/mbed-drivers-all
Adrian Suciu 33:c3ec596a29c2 11
Adrian Suciu 33:c3ec596a29c2 12 ********************************************************************************
Adrian Suciu 33:c3ec596a29c2 13 * Copyright 2016(c) Analog Devices, Inc.
Adrian Suciu 33:c3ec596a29c2 14 *
Adrian Suciu 33:c3ec596a29c2 15 * All rights reserved.
Adrian Suciu 33:c3ec596a29c2 16 *
Adrian Suciu 33:c3ec596a29c2 17 * Redistribution and use in source and binary forms, with or without
Adrian Suciu 33:c3ec596a29c2 18 * modification, are permitted provided that the following conditions are met:
Adrian Suciu 33:c3ec596a29c2 19 * - Redistributions of source code must retain the above copyright
Adrian Suciu 33:c3ec596a29c2 20 * notice, this list of conditions and the following disclaimer.
Adrian Suciu 33:c3ec596a29c2 21 * - Redistributions in binary form must reproduce the above copyright
Adrian Suciu 33:c3ec596a29c2 22 * notice, this list of conditions and the following disclaimer in
Adrian Suciu 33:c3ec596a29c2 23 * the documentation and/or other materials provided with the
Adrian Suciu 33:c3ec596a29c2 24 * distribution.
Adrian Suciu 33:c3ec596a29c2 25 * - Neither the name of Analog Devices, Inc. nor the names of its
Adrian Suciu 33:c3ec596a29c2 26 * contributors may be used to endorse or promote products derived
Adrian Suciu 33:c3ec596a29c2 27 * from this software without specific prior written permission.
Adrian Suciu 33:c3ec596a29c2 28 * - The use of this software may or may not infringe the patent rights
Adrian Suciu 33:c3ec596a29c2 29 * of one or more patent holders. This license does not release you
Adrian Suciu 33:c3ec596a29c2 30 * from the requirement that you obtain separate licenses from these
Adrian Suciu 33:c3ec596a29c2 31 * patent holders to use this software.
Adrian Suciu 33:c3ec596a29c2 32 * - Use of the software either in source or binary form, must be run
Adrian Suciu 33:c3ec596a29c2 33 * on or directly connected to an Analog Devices Inc. component.
Adrian Suciu 33:c3ec596a29c2 34 *
Adrian Suciu 33:c3ec596a29c2 35 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
Adrian Suciu 33:c3ec596a29c2 36 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
Adrian Suciu 33:c3ec596a29c2 37 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
Adrian Suciu 33:c3ec596a29c2 38 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
Adrian Suciu 33:c3ec596a29c2 39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Adrian Suciu 33:c3ec596a29c2 40 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
Adrian Suciu 33:c3ec596a29c2 41 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Adrian Suciu 33:c3ec596a29c2 42 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Adrian Suciu 33:c3ec596a29c2 43 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Adrian Suciu 33:c3ec596a29c2 44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Adrian Suciu 33:c3ec596a29c2 45 *
Adrian Suciu 33:c3ec596a29c2 46 ********************************************************************************/
Adrian Suciu 33:c3ec596a29c2 47
Adrian Suciu 33:c3ec596a29c2 48 #include "CN0397.h"
Adrian Suciu 33:c3ec596a29c2 49 #include "AD7798.h"
Adrian Suciu 33:c3ec596a29c2 50 #include "Timer.h"
Adrian Suciu 33:c3ec596a29c2 51 #include <stdio.h>
Adrian Suciu 33:c3ec596a29c2 52 #include <math.h>
Adrian Suciu 33:c3ec596a29c2 53 #include <mbed.h>
Adrian Suciu 33:c3ec596a29c2 54
Adrian Suciu 33:c3ec596a29c2 55 extern Serial pc;
Adrian Suciu 33:c3ec596a29c2 56
Adrian Suciu 33:c3ec596a29c2 57
Adrian Suciu 33:c3ec596a29c2 58 void flush_serial()
Adrian Suciu 33:c3ec596a29c2 59 {
Adrian Suciu 33:c3ec596a29c2 60 wait_ms(10); // wait for all data to come through
Adrian Suciu 33:c3ec596a29c2 61 while (pc.readable()) pc.getc();
Adrian Suciu 33:c3ec596a29c2 62 }
Adrian Suciu 33:c3ec596a29c2 63
Adrian Suciu 33:c3ec596a29c2 64
Adrian Suciu 33:c3ec596a29c2 65 CN0397::CN0397(PinName cs) : ad7798(cs)
Adrian Suciu 33:c3ec596a29c2 66 {
Adrian Suciu 33:c3ec596a29c2 67
Adrian Suciu 33:c3ec596a29c2 68 }
Adrian Suciu 33:c3ec596a29c2 69 void CN0397::display_data(void)
Adrian Suciu 33:c3ec596a29c2 70 {
Adrian Suciu 33:c3ec596a29c2 71
Adrian Suciu 33:c3ec596a29c2 72 uint8_t channel = 0, i;
Adrian Suciu 33:c3ec596a29c2 73
Adrian Suciu 33:c3ec596a29c2 74 /* for(channel = 0; channel < CHANNELS; channel++){
Adrian Suciu 33:c3ec596a29c2 75
Adrian Suciu 33:c3ec596a29c2 76 pc.printf("%s (channel %d):\n", colour[channel], (channel + 1));
Adrian Suciu 33:c3ec596a29c2 77 pc.printf("\tADC output = %u (%#06x)\n", adcValue[channel], adcValue[channel]);
Adrian Suciu 33:c3ec596a29c2 78 pc.printf("\tVoltage = %f mV\n", voltageValue[channel]);
Adrian Suciu 33:c3ec596a29c2 79 pc.printf("\tLight Intensity = %.2f lux\n", intensityValue[channel]);
Adrian Suciu 33:c3ec596a29c2 80 pc.printf("\tLight Concentration = %.2f%c\n", lightConcentration[channel], 37);
Adrian Suciu 33:c3ec596a29c2 81
Adrian Suciu 33:c3ec596a29c2 82 }*/
Adrian Suciu 33:c3ec596a29c2 83
Adrian Suciu 33:c3ec596a29c2 84
Adrian Suciu 33:c3ec596a29c2 85 for(channel = 0; channel < CHANNELS; channel++) {
Adrian Suciu 33:c3ec596a29c2 86
Adrian Suciu 33:c3ec596a29c2 87 pc.printf("\t\t\033[2;%dm%s\033[0m channel:\t\t", ColorPrint[channel], colour[channel]);
Adrian Suciu 33:c3ec596a29c2 88 }
Adrian Suciu 33:c3ec596a29c2 89
Adrian Suciu 33:c3ec596a29c2 90 pc.printf("\n");
Adrian Suciu 33:c3ec596a29c2 91 pc.printf("\t");
Adrian Suciu 33:c3ec596a29c2 92
Adrian Suciu 33:c3ec596a29c2 93 /*
Adrian Suciu 33:c3ec596a29c2 94 for(channel = 0; channel < CHANNELS; channel++) {
Adrian Suciu 33:c3ec596a29c2 95
Adrian Suciu 33:c3ec596a29c2 96 pc.printf("\t\t\tADC output = %u (%#06x)", adcValue[channel], adcValue[channel]);
Adrian Suciu 33:c3ec596a29c2 97 }
Adrian Suciu 33:c3ec596a29c2 98
Adrian Suciu 33:c3ec596a29c2 99 pc.printf("\n");
Adrian Suciu 33:c3ec596a29c2 100 pc.printf("\t");
Adrian Suciu 33:c3ec596a29c2 101
Adrian Suciu 33:c3ec596a29c2 102 */
Adrian Suciu 33:c3ec596a29c2 103 for(channel = 0; channel < CHANNELS; channel++) {
Adrian Suciu 33:c3ec596a29c2 104
Adrian Suciu 33:c3ec596a29c2 105 pc.printf("\t\tLight Intensity = %.2f lux", intensityValue[channel]);
Adrian Suciu 33:c3ec596a29c2 106 }
Adrian Suciu 33:c3ec596a29c2 107
Adrian Suciu 33:c3ec596a29c2 108 pc.printf("\n");
Adrian Suciu 33:c3ec596a29c2 109 pc.printf("\t");
Adrian Suciu 33:c3ec596a29c2 110
Adrian Suciu 33:c3ec596a29c2 111
Adrian Suciu 33:c3ec596a29c2 112 for(channel = 0; channel < CHANNELS; channel++) {
Adrian Suciu 33:c3ec596a29c2 113
Adrian Suciu 33:c3ec596a29c2 114 pc.printf("\t\tLight Concentration = %.2f%c", lightConcentration[channel], 37);
Adrian Suciu 33:c3ec596a29c2 115 }
Adrian Suciu 33:c3ec596a29c2 116
Adrian Suciu 33:c3ec596a29c2 117 pc.printf("\n");/*pc.printf("\t");
Adrian Suciu 33:c3ec596a29c2 118
Adrian Suciu 33:c3ec596a29c2 119 for(channel = 0; channel < CHANNELS; channel++) {
Adrian Suciu 33:c3ec596a29c2 120
Adrian Suciu 33:c3ec596a29c2 121 pc.printf("\t\t\tLight Concentration = %.2f%c", lightConcentration[channel], 37);
Adrian Suciu 33:c3ec596a29c2 122 }
Adrian Suciu 33:c3ec596a29c2 123
Adrian Suciu 33:c3ec596a29c2 124 pc.printf("\n");pc.printf("\t");
Adrian Suciu 33:c3ec596a29c2 125
Adrian Suciu 33:c3ec596a29c2 126 /* for(channel = 0; channel < CHANNELS; channel++){
Adrian Suciu 33:c3ec596a29c2 127
Adrian Suciu 33:c3ec596a29c2 128 pc.printf("\t\t\t\033[2;%dm|\033[0m\t", ColorPrint[channel]);
Adrian Suciu 33:c3ec596a29c2 129
Adrian Suciu 33:c3ec596a29c2 130 }*/
Adrian Suciu 33:c3ec596a29c2 131
Adrian Suciu 33:c3ec596a29c2 132 for(channel = 0; channel < 5; channel++) {
Adrian Suciu 33:c3ec596a29c2 133 pc.printf("\n");
Adrian Suciu 33:c3ec596a29c2 134 }
Adrian Suciu 33:c3ec596a29c2 135
Adrian Suciu 33:c3ec596a29c2 136 // pc.printf("\n");
Adrian Suciu 33:c3ec596a29c2 137 // pc.printf("\n");
Adrian Suciu 33:c3ec596a29c2 138 pc.printf("\n");
Adrian Suciu 33:c3ec596a29c2 139 }
Adrian Suciu 33:c3ec596a29c2 140
Adrian Suciu 33:c3ec596a29c2 141
Adrian Suciu 33:c3ec596a29c2 142 void CN0397::data_to_voltage(uint16_t adcValue, float *voltage)
Adrian Suciu 33:c3ec596a29c2 143 {
Adrian Suciu 33:c3ec596a29c2 144
Adrian Suciu 33:c3ec596a29c2 145 *voltage = (float)(adcValue * V_REF) / (float)(_2_16 * gainAdc);
Adrian Suciu 33:c3ec596a29c2 146
Adrian Suciu 33:c3ec596a29c2 147 }
Adrian Suciu 33:c3ec596a29c2 148
Adrian Suciu 33:c3ec596a29c2 149 void CN0397::init(void)
Adrian Suciu 33:c3ec596a29c2 150 {
Adrian Suciu 33:c3ec596a29c2 151 ad7798.reset();
Adrian Suciu 33:c3ec596a29c2 152 uint8_t channel;
Adrian Suciu 33:c3ec596a29c2 153
Adrian Suciu 33:c3ec596a29c2 154 if(ad7798.init()) {
Adrian Suciu 33:c3ec596a29c2 155
Adrian Suciu 33:c3ec596a29c2 156 ad7798.set_coding_mode(AD7798_UNIPOLAR);
Adrian Suciu 33:c3ec596a29c2 157 ad7798.set_mode(AD7798_MODE_SINGLE);
Adrian Suciu 33:c3ec596a29c2 158 ad7798.set_gain(ADC_GAIN);
Adrian Suciu 33:c3ec596a29c2 159 ad7798.set_filter(ADC_SPS);
Adrian Suciu 33:c3ec596a29c2 160 ad7798.set_reference(AD7798_REFDET_ENA);
Adrian Suciu 33:c3ec596a29c2 161
Adrian Suciu 33:c3ec596a29c2 162 }
Adrian Suciu 33:c3ec596a29c2 163
Adrian Suciu 33:c3ec596a29c2 164 gainAdc = Gain[ADC_GAIN];
Adrian Suciu 33:c3ec596a29c2 165 #ifdef USE_CALIBRATION
Adrian Suciu 33:c3ec596a29c2 166 pc.printf("Calibrate the system:\n");
Adrian Suciu 33:c3ec596a29c2 167 pc.printf("\n");
Adrian Suciu 33:c3ec596a29c2 168
Adrian Suciu 33:c3ec596a29c2 169 for(channel = 0; channel < CHANNELS; channel++) {
Adrian Suciu 33:c3ec596a29c2 170
Adrian Suciu 33:c3ec596a29c2 171 pc.printf("\tCalibrate channel %d: be sure that %s photodiode is cover and press <ENTER>.\n", (Channels[channel] + 1), colour[channel]);
Adrian Suciu 33:c3ec596a29c2 172 pc.getc();
Adrian Suciu 33:c3ec596a29c2 173 flush_serial();
Adrian Suciu 33:c3ec596a29c2 174 calibration(Channels[channel]);
Adrian Suciu 33:c3ec596a29c2 175 pc.printf("\t\tChannel %d is calibrated!\n", (Channels[channel] + 1));
Adrian Suciu 33:c3ec596a29c2 176 pc.printf("\n");
Adrian Suciu 33:c3ec596a29c2 177
Adrian Suciu 33:c3ec596a29c2 178 }
Adrian Suciu 33:c3ec596a29c2 179
Adrian Suciu 33:c3ec596a29c2 180 printf("System calibration complete!\n");
Adrian Suciu 33:c3ec596a29c2 181 printf("\n");
Adrian Suciu 33:c3ec596a29c2 182 printf("\n");
Adrian Suciu 33:c3ec596a29c2 183
Adrian Suciu 33:c3ec596a29c2 184 #endif
Adrian Suciu 33:c3ec596a29c2 185 }
Adrian Suciu 33:c3ec596a29c2 186
Adrian Suciu 33:c3ec596a29c2 187 void CN0397::calc_light_intensity(uint8_t channel, uint16_t adcValue, float *intensity)
Adrian Suciu 33:c3ec596a29c2 188 {
Adrian Suciu 33:c3ec596a29c2 189
Adrian Suciu 33:c3ec596a29c2 190 *intensity = adcValue * Lux_LSB[channel];
Adrian Suciu 33:c3ec596a29c2 191
Adrian Suciu 33:c3ec596a29c2 192 }
Adrian Suciu 33:c3ec596a29c2 193
Adrian Suciu 33:c3ec596a29c2 194 void CN0397::calc_light_concentration(uint8_t channel, float intensity, float *conc)
Adrian Suciu 33:c3ec596a29c2 195 {
Adrian Suciu 33:c3ec596a29c2 196
Adrian Suciu 33:c3ec596a29c2 197 *conc = (intensity * 100) / Optimal_Levels[channel];
Adrian Suciu 33:c3ec596a29c2 198
Adrian Suciu 33:c3ec596a29c2 199 }
Adrian Suciu 33:c3ec596a29c2 200
Adrian Suciu 33:c3ec596a29c2 201 void CN0397::set_app_data(void)
Adrian Suciu 33:c3ec596a29c2 202 {
Adrian Suciu 33:c3ec596a29c2 203 uint8_t channel, rgbChannel;
Adrian Suciu 33:c3ec596a29c2 204 uint16_t *adcData = &adcValue[0];
Adrian Suciu 33:c3ec596a29c2 205 float *voltageData = &voltageValue[0], *intensityData = &intensityValue[0];
Adrian Suciu 33:c3ec596a29c2 206 float *concData = &lightConcentration[0];
Adrian Suciu 33:c3ec596a29c2 207
Adrian Suciu 33:c3ec596a29c2 208 for(channel = 0; channel < CHANNELS; channel++) {
Adrian Suciu 33:c3ec596a29c2 209
Adrian Suciu 33:c3ec596a29c2 210 rgbChannel = Channels[channel];
Adrian Suciu 33:c3ec596a29c2 211
Adrian Suciu 33:c3ec596a29c2 212 ad7798.set_channel(channel);
Adrian Suciu 33:c3ec596a29c2 213
Adrian Suciu 33:c3ec596a29c2 214 adcData = &adcValue[rgbChannel];
Adrian Suciu 33:c3ec596a29c2 215 voltageData = &voltageValue[rgbChannel];
Adrian Suciu 33:c3ec596a29c2 216 intensityData = &intensityValue[rgbChannel];
Adrian Suciu 33:c3ec596a29c2 217 concData = &lightConcentration[rgbChannel];
Adrian Suciu 33:c3ec596a29c2 218 ad7798.read_data(channel, adcData);
Adrian Suciu 33:c3ec596a29c2 219 data_to_voltage(*adcData, voltageData);
Adrian Suciu 33:c3ec596a29c2 220 calc_light_intensity(rgbChannel, *adcData, intensityData);
Adrian Suciu 33:c3ec596a29c2 221 calc_light_concentration(rgbChannel, *intensityData, concData);
Adrian Suciu 33:c3ec596a29c2 222
Adrian Suciu 33:c3ec596a29c2 223 /* adcData++;
Adrian Suciu 33:c3ec596a29c2 224 voltageData++;
Adrian Suciu 33:c3ec596a29c2 225 intensityData++;
Adrian Suciu 33:c3ec596a29c2 226 concData++;*/
Adrian Suciu 33:c3ec596a29c2 227
Adrian Suciu 33:c3ec596a29c2 228 }
Adrian Suciu 33:c3ec596a29c2 229 }
Adrian Suciu 33:c3ec596a29c2 230
Adrian Suciu 33:c3ec596a29c2 231 void CN0397::calibration(uint8_t channel)
Adrian Suciu 33:c3ec596a29c2 232 {
Adrian Suciu 33:c3ec596a29c2 233
Adrian Suciu 33:c3ec596a29c2 234 uint16_t setValue;
Adrian Suciu 33:c3ec596a29c2 235
Adrian Suciu 33:c3ec596a29c2 236 ad7798.set_channel(channel); //select channel to calibrate
Adrian Suciu 33:c3ec596a29c2 237
Adrian Suciu 33:c3ec596a29c2 238 // Perform system zero-scale calibration
Adrian Suciu 33:c3ec596a29c2 239 setValue = ad7798.get_register_value(AD7798_REG_MODE, 2);
Adrian Suciu 33:c3ec596a29c2 240 setValue &= ~(AD7798_MODE_SEL(0x07));
Adrian Suciu 33:c3ec596a29c2 241 setValue |= AD7798_MODE_SEL(AD7798_MODE_CAL_SYS_ZERO);
Adrian Suciu 33:c3ec596a29c2 242 ad7798.set_register_value(AD7798_REG_MODE, setValue, 2);
Adrian Suciu 33:c3ec596a29c2 243
Adrian Suciu 33:c3ec596a29c2 244 while((ad7798.get_register_value( AD7798_REG_STAT, 1) & channel) != channel); // wait for RDY bit to go low
Adrian Suciu 33:c3ec596a29c2 245
Adrian Suciu 33:c3ec596a29c2 246 while(ad7798.get_register_value(AD7798_REG_MODE, 2) != 0x4005); // wait for ADC to go in idle mode
Adrian Suciu 33:c3ec596a29c2 247
Adrian Suciu 33:c3ec596a29c2 248
Adrian Suciu 33:c3ec596a29c2 249 }
Adrian Suciu 33:c3ec596a29c2 250
Adrian Suciu 33:c3ec596a29c2 251
Adrian Suciu 33:c3ec596a29c2 252
Adrian Suciu 33:c3ec596a29c2 253