|
| 1 | +// Copyright 2016-2022 Jean-Francois Poilpret |
| 2 | +// |
| 3 | +// Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +// you may not use this file except in compliance with the License. |
| 5 | +// You may obtain a copy of the License at |
| 6 | +// |
| 7 | +// http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +// |
| 9 | +// Unless required by applicable law or agreed to in writing, software |
| 10 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +// See the License for the specific language governing permissions and |
| 13 | +// limitations under the License. |
| 14 | + |
| 15 | +/* |
| 16 | + * Special check for ios dependencies and streams agnosticity (Future, async I2C, VL53L0X). |
| 17 | + * This is for compilation only (UNO only). |
| 18 | + * This program checks the following: |
| 19 | + * - all generic stream inserters defined in FastArduino library work whatever selected stream (real or null) |
| 20 | + * - DeviceStatus/DeviceError |
| 21 | + * - PowerMode |
| 22 | + * - GPIOSettings/GPIOFunction |
| 23 | + * - SequenceSteps/SequenceStepsTimeouts |
| 24 | + * - SPADInfo |
| 25 | + * - Status (i2c) |
| 26 | + * - DebugStatus (i2c) |
| 27 | + * - FutureStatus |
| 28 | + * - I2CCommand/I2CCommandType |
| 29 | + */ |
| 30 | + |
| 31 | +#ifndef ARDUINO_UNO |
| 32 | +#error "Current target is not yet supported!" |
| 33 | +#endif |
| 34 | + |
| 35 | +// Comment out for normal stream / uncomment for empty stream |
| 36 | +#define EMPTY_STREAM |
| 37 | + |
| 38 | +#ifndef EMPTY_STREAM |
| 39 | +#include <fastarduino/uart.h> |
| 40 | +#include <fastarduino/streams.h> |
| 41 | +#else |
| 42 | +#include <fastarduino/empty_streams.h> |
| 43 | +#endif |
| 44 | + |
| 45 | +#include <fastarduino/gpio.h> |
| 46 | +#include <fastarduino/i2c_handler.h> |
| 47 | +#include <fastarduino/i2c_debug.h> |
| 48 | +#include <fastarduino/i2c_status.h> |
| 49 | +#include <fastarduino/devices/vl53l0x.h> |
| 50 | + |
| 51 | +#ifndef EMPTY_STREAM |
| 52 | +static constexpr const board::USART UART = board::USART::USART0; |
| 53 | +static constexpr const uint8_t OUTPUT_BUFFER_SIZE = 128; |
| 54 | +static char output_buffer[OUTPUT_BUFFER_SIZE]; |
| 55 | +REGISTER_UATX_ISR(0) |
| 56 | +REGISTER_OSTREAMBUF_LISTENERS(serial::hard::UATX<UART>) |
| 57 | +#endif |
| 58 | + |
| 59 | +static constexpr const i2c::I2CMode MODE = i2c::I2CMode::FAST; |
| 60 | +static constexpr const uint8_t DEBUG_SIZE = 96; |
| 61 | +using DEBUGGER = i2c::debug::I2CDebugStatusRecorder<DEBUG_SIZE, DEBUG_SIZE>; |
| 62 | +#define DEBUG(OUT) debugger.trace(OUT, false) |
| 63 | +#define RESET_DEBUG() debugger.reset() |
| 64 | +using MANAGER = i2c::I2CAsyncStatusDebugManager< |
| 65 | + MODE, i2c::I2CErrorPolicy::CLEAR_ALL_COMMANDS, DEBUGGER&, DEBUGGER&>; |
| 66 | +static constexpr const uint8_t I2C_BUFFER_SIZE = 32; |
| 67 | +static MANAGER::I2CCOMMAND i2c_buffer[I2C_BUFFER_SIZE]; |
| 68 | + |
| 69 | +REGISTER_I2C_ISR(MANAGER) |
| 70 | + |
| 71 | +using namespace devices::vl53l0x; |
| 72 | +using TOF = VL53L0X<MANAGER>; |
| 73 | + |
| 74 | +REGISTER_FUTURE_STATUS_LISTENERS(MANAGER_FUTURE(MANAGER), i2c::I2CSameFutureGroup<MANAGER>, TOF::GetGPIOSettingsFuture) |
| 75 | +REGISTER_FUTURE_OUTPUT_NO_LISTENERS() |
| 76 | + |
| 77 | +void update_led(bool status) |
| 78 | +{ |
| 79 | + if (!status) |
| 80 | + gpio::FastPinType<board::DigitalPin::LED>::set(); |
| 81 | +} |
| 82 | + |
| 83 | +int main() |
| 84 | +{ |
| 85 | + board::init(); |
| 86 | + sei(); |
| 87 | + |
| 88 | + // Add LED init for visual info (useful with null stream) |
| 89 | + gpio::FastPinType<board::DigitalPin::LED>::set_mode(gpio::PinMode::OUTPUT, false); |
| 90 | + |
| 91 | +#ifndef EMPTY_STREAM |
| 92 | + // open UART for traces |
| 93 | + serial::hard::UATX<UART> uart{output_buffer}; |
| 94 | + streams::ostream out = uart.out(); |
| 95 | + uart.begin(115200); |
| 96 | + out << streams::boolalpha; |
| 97 | + // UNITBUF is necessary here because insert operators do not flush ostream themselves but may need much buffer! |
| 98 | + out << streams::unitbuf; |
| 99 | +#else |
| 100 | + streams::null_ostream out; |
| 101 | +#endif |
| 102 | + out << F("Start\n"); |
| 103 | + |
| 104 | + // Initialize I2C async handler |
| 105 | + DEBUGGER debugger; |
| 106 | + MANAGER manager{i2c_buffer, debugger, debugger}; |
| 107 | + |
| 108 | + out << F("Instantiate VL53L0X\n"); |
| 109 | + TOF tof{manager}; |
| 110 | + |
| 111 | + out << F("Start I2C manager\n"); |
| 112 | + manager.begin(); |
| 113 | + |
| 114 | + bool ok = false; |
| 115 | + |
| 116 | + { |
| 117 | + out << F("Reset VL53L0X device\n"); |
| 118 | + ok = tof.reset_device(); |
| 119 | + out << F("tof.reset_device() = ") << ok << '\n'; |
| 120 | + DEBUG(out); |
| 121 | + update_led(ok); |
| 122 | + } |
| 123 | + |
| 124 | + // Check PowerMode insert operator |
| 125 | + { |
| 126 | + PowerMode mode = PowerMode::STANDBY; |
| 127 | + ok = tof.get_power_mode(mode); |
| 128 | + out << F("tof.get_power_mode(mode) = ") << ok << F(", mode = ") << mode << '\n'; |
| 129 | + DEBUG(out); |
| 130 | + update_led(ok); |
| 131 | + } |
| 132 | + |
| 133 | + // Check DeviceStatus/DeviceError insert operator |
| 134 | + { |
| 135 | + DeviceStatus status; |
| 136 | + ok = tof.get_range_status(status); |
| 137 | + out << F("tof.get_range_status(status) = ") << ok |
| 138 | + << F(", status = ") << status << '\n'; |
| 139 | + DEBUG(out); |
| 140 | + update_led(ok); |
| 141 | + } |
| 142 | + |
| 143 | + // Check SequenceSteps/SequenceStepsTimeout insert operator |
| 144 | + { |
| 145 | + SequenceSteps steps; |
| 146 | + ok = tof.get_sequence_steps(steps); |
| 147 | + out << F("tof.get_sequence_steps(status) = ") << ok << F(", steps =") << steps << '\n'; |
| 148 | + DEBUG(out); |
| 149 | + update_led(ok); |
| 150 | + SequenceStepsTimeout timeouts; |
| 151 | + ok = tof.get_sequence_steps_timeout(timeouts); |
| 152 | + out << F("tof.get_sequence_steps_timeout() = ") << ok << F(", timeouts =") << timeouts << '\n'; |
| 153 | + DEBUG(out); |
| 154 | + update_led(ok); |
| 155 | + } |
| 156 | + |
| 157 | + // Check SPADInfo insert operator |
| 158 | + { |
| 159 | + SPADInfo SPAD_info; |
| 160 | + ok = tof.get_SPAD_info(SPAD_info); |
| 161 | + out << F("tof.get_SPAD_info() = ") << ok << '\n'; |
| 162 | + out << F("SPADInfo = ") << SPAD_info << '\n'; |
| 163 | + DEBUG(out); |
| 164 | + update_led(ok); |
| 165 | + } |
| 166 | + |
| 167 | + // Check GPIOSettings/GPIOFunction insert operator |
| 168 | + { |
| 169 | + GPIOSettings settings; |
| 170 | + ok = tof.get_GPIO_settings(settings); |
| 171 | + out << F("tof.get_GPIO_settings() = ") << ok << '\n'; |
| 172 | + out << F("GPIO setting=") << settings << '\n'; |
| 173 | + DEBUG(out); |
| 174 | + update_led(ok); |
| 175 | + } |
| 176 | + |
| 177 | + { |
| 178 | + // Check FutureStatus insert operator |
| 179 | + TOF::GetGPIOSettingsFuture future; |
| 180 | + out << F("GetGPIOSettingsFuture status = ") << future.status() << '\n'; |
| 181 | + int result = tof.get_GPIO_settings(future); |
| 182 | + |
| 183 | + // Check I2CCommand/I2CCommandType insert operator |
| 184 | + out << F("i2c_buffer[0]") << i2c_buffer[0] << '\n'; |
| 185 | + update_led(result == 0); |
| 186 | + |
| 187 | + future.await(); |
| 188 | + out << F("GetGPIOSettingsFuture status = ") << future.status() << '\n'; |
| 189 | + update_led(future.status() == future::FutureStatus::READY); |
| 190 | + } |
| 191 | + |
| 192 | + manager.end(); |
| 193 | +} |
0 commit comments