Statistics
| Branch: | Tag: | Revision:

amiro-os / test / lld / adc / aos_test_adc.c @ a3ac2400

History | View | Annotate | Download (6.367 KB)

1 e545e620 Thomas Schöpping
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3 84f0ce9e Thomas Schöpping
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 e545e620 Thomas Schöpping

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19 3940ba8a Thomas Schöpping
#include <amiroos.h>
20 4c72a54c Thomas Schöpping
#include <aos_test_adc.h>
21 e545e620 Thomas Schöpping
22 4c72a54c Thomas Schöpping
#if (AMIROOS_CFG_TESTS_ENABLE == TRUE) || defined(__DOXYGEN__)
23 e545e620 Thomas Schöpping
24 f3ac1c96 Thomas Schöpping
/******************************************************************************/
25
/* LOCAL DEFINITIONS                                                          */
26
/******************************************************************************/
27 e545e620 Thomas Schöpping
28
/**
29
 * @brief   Event mask of the ADC analog watchdog event.
30
 */
31
#define _adcWdgEventmask                        EVENT_MASK(31)
32
33
/**
34
 * @brief   ADC analog watchdog threshold (9.0V).
35
 */
36
#define _adcWdgThreshold                        (uint16_t)(9.0f / 5.0f / 3.3f * ((1 << 12) - 1) + 0.5f)
37
38 f3ac1c96 Thomas Schöpping
/******************************************************************************/
39
/* EXPORTED VARIABLES                                                         */
40
/******************************************************************************/
41
42
/******************************************************************************/
43
/* LOCAL TYPES                                                                */
44
/******************************************************************************/
45
46
/******************************************************************************/
47
/* LOCAL VARIABLES                                                            */
48
/******************************************************************************/
49
50 e545e620 Thomas Schöpping
/**
51
 * @brief   Pointer to the thread listening for an ADC analog watchdog event.
52
 */
53
static thread_t* _listener;
54
55 f3ac1c96 Thomas Schöpping
/******************************************************************************/
56
/* LOCAL FUNCTIONS                                                            */
57
/******************************************************************************/
58
59 e545e620 Thomas Schöpping
/**
60
 * @brief   Helper function to convert ADC sample value to volts.
61
 *
62
 * @param[in] adc   ADC sample value.
63
 *
64
 * @return          Converted value in volts.
65
 */
66
static inline float _adc2volt(adcsample_t adc) {
67
  return (float)adc / ((1 << 12) - 1) * 3.3f * 5.0f;
68
}
69
70
/**
71
 * @brief   ADC analog watchdog callback function.
72
 *
73
 * @param[in] adcp  ADC driver.
74
 * @param[in] err   ADC error value.
75
 */
76
static void _adcAwdCb(ADCDriver* adcp, adcerror_t err)
77
{
78
  (void)adcp;
79
80
  if (err == ADC_ERR_WATCHDOG) {
81
    chSysLockFromISR();
82
    if (_listener != NULL) {
83
      chEvtSignalI(_listener, _adcWdgEventmask);
84
      _listener = NULL;
85
    }
86
    chSysUnlockFromISR();
87
  }
88
89
  return;
90
}
91
92 f3ac1c96 Thomas Schöpping
/******************************************************************************/
93
/* EXPORTED FUNCTIONS                                                         */
94
/******************************************************************************/
95
96 e545e620 Thomas Schöpping
/**
97 4c72a54c Thomas Schöpping
 * @brief   ADC test function.
98 e545e620 Thomas Schöpping
 *
99
 * @param[in] stream  Stream for input/output.
100 4c72a54c Thomas Schöpping
 * @param[in] test    Test object.
101 e545e620 Thomas Schöpping
 *
102 4c72a54c Thomas Schöpping
 * @return            Test result value.
103 e545e620 Thomas Schöpping
 */
104 4c72a54c Thomas Schöpping
aos_testresult_t aosTestAdcFunc(BaseSequentialStream* stream, const aos_test_t* test)
105 e545e620 Thomas Schöpping
{
106 4c72a54c Thomas Schöpping
  aosDbgCheck(test->data != NULL && ((aos_test_adcdata_t*)(test->data))->driver != NULL && ((aos_test_adcdata_t*)(test->data))->convgroup != NULL);
107 e545e620 Thomas Schöpping
108
  // local variables
109 4c72a54c Thomas Schöpping
  aos_testresult_t result = {0, 0};
110 e545e620 Thomas Schöpping
  adcsample_t buffer[1] = {0};
111
  bool wdgpassed = false;
112
  eventmask_t eventmask = 0;
113 4c72a54c Thomas Schöpping
  ADCConversionGroup conversionGroup = *(((aos_test_adcdata_t*)(test->data))->convgroup);
114 e545e620 Thomas Schöpping
  conversionGroup.circular = true;
115
  conversionGroup.end_cb = NULL;
116
  conversionGroup.end_cb = NULL;
117
  conversionGroup.htr = ADC_HTR_HT;
118
  conversionGroup.ltr = 0;
119
120
  chprintf(stream, "reading voltage for five seconds...\n");
121 4c72a54c Thomas Schöpping
  adcStartConversion(((aos_test_adcdata_t*)(test->data))->driver, &conversionGroup, buffer, 1);
122 e545e620 Thomas Schöpping
  for (uint8_t s = 0; s < 5; ++s) {
123
    aosThdSSleep(1);
124
    chprintf(stream, "\tVSYS = %fV\n", _adc2volt(buffer[0]));
125
  }
126 4c72a54c Thomas Schöpping
  adcStopConversion(((aos_test_adcdata_t*)(test->data))->driver);
127 e545e620 Thomas Schöpping
  if (buffer[0] != 0) {
128 4c72a54c Thomas Schöpping
    aosTestPassed(stream, &result);
129 e545e620 Thomas Schöpping
  } else {
130 4c72a54c Thomas Schöpping
    aosTestFailed(stream, &result);
131 e545e620 Thomas Schöpping
  }
132
133
  chprintf(stream, "detecting external power...\n");
134
  conversionGroup.error_cb = _adcAwdCb;
135
  conversionGroup.htr = _adcWdgThreshold;
136
  conversionGroup.ltr = _adcWdgThreshold;
137
  _listener = chThdGetSelfX();
138 4c72a54c Thomas Schöpping
  adcStartConversion(((aos_test_adcdata_t*)(test->data))->driver, &conversionGroup, buffer, 1);
139 1e5f7648 Thomas Schöpping
  eventmask = chEvtWaitOneTimeout(_adcWdgEventmask, chTimeS2I(5));
140 e545e620 Thomas Schöpping
  if (eventmask == _adcWdgEventmask) {
141 4c72a54c Thomas Schöpping
    aosTestPassedMsg(stream, &result, "%fV %c 9V\n", _adc2volt(buffer[0]), (buffer[0] > _adcWdgThreshold) ? '>' : '<');
142 e545e620 Thomas Schöpping
    wdgpassed = true;
143
  } else {
144 4c72a54c Thomas Schöpping
    adcStopConversion(((aos_test_adcdata_t*)(test->data))->driver);
145
    aosTestFailed(stream, &result);
146 e545e620 Thomas Schöpping
    wdgpassed = false;
147
  }
148
149
  if (wdgpassed) {
150
    for (uint8_t i = 0; i < 2; ++i) {
151
      if (buffer[0] > _adcWdgThreshold) {
152
        chprintf(stream, "Remove external power within ten seconds.\n");
153
        conversionGroup.htr = ADC_HTR_HT;
154
        conversionGroup.ltr = _adcWdgThreshold;
155
      } else {
156
        chprintf(stream, "Connect external power within ten seconds.\n");
157
        conversionGroup.htr = _adcWdgThreshold;
158
        conversionGroup.ltr = 0;
159
      }
160
      aosThdMSleep(100); // wait some time so the ADC wil trigger again immediately due to noise
161
      _listener = chThdGetSelfX();
162 4c72a54c Thomas Schöpping
      adcStartConversion(((aos_test_adcdata_t*)(test->data))->driver, &conversionGroup, buffer, 1);
163 1e5f7648 Thomas Schöpping
      eventmask = chEvtWaitOneTimeout(_adcWdgEventmask, chTimeS2I(10));
164 e545e620 Thomas Schöpping
      if (eventmask == _adcWdgEventmask) {
165 4c72a54c Thomas Schöpping
        aosTestPassedMsg(stream, &result, "%fV %c 9V\n", _adc2volt(buffer[0]), (buffer[0] > _adcWdgThreshold) ? '>' : '<');
166 e545e620 Thomas Schöpping
      } else {
167 4c72a54c Thomas Schöpping
        adcStopConversion(((aos_test_adcdata_t*)(test->data))->driver);
168
        aosTestFailed(stream, &result);
169 e545e620 Thomas Schöpping
        break;
170
      }
171
    }
172
  }
173
174
  return result;
175
}
176
177 4c72a54c Thomas Schöpping
#endif /* (AMIROOS_CFG_TESTS_ENABLE == TRUE) */