|
1 | 1 | #include "OPAMP.h"
|
2 | 2 | #include <Arduino.h>
|
3 | 3 |
|
| 4 | +/* Make sure this library fails to compile for unsupported boards. */ |
| 5 | +#if !defined(ARDUINO_UNOWIFIR4) && !defined(ARDUINO_MINIMA) |
| 6 | +#error "Unsupported board for OPAMP library." |
| 7 | +#endif |
| 8 | + |
4 | 9 | /* pin mode needed to activate OPAMP functionality */
|
5 | 10 | #define OPAMP_IN_PINCFG (IOPORT_CFG_PORT_DIRECTION_INPUT | IOPORT_CFG_PERIPHERAL_PIN | IOPORT_CFG_ANALOG_ENABLE)
|
6 | 11 | #define OPAMP_OUT_PINCFG (IOPORT_CFG_PORT_DIRECTION_OUTPUT | IOPORT_CFG_PERIPHERAL_PIN | IOPORT_CFG_ANALOG_ENABLE)
|
7 | 12 | #define FSP_CHECK(err) do { if( (err) != FSP_SUCCESS) return false; } while(0)
|
8 | 13 |
|
9 |
| -bool OpampClass::initPins() { |
| 14 | +// Compact structure for OPAMP channel pins |
| 15 | +struct opamp_channel_pins_t { |
| 16 | + bsp_io_port_pin_t plus; |
| 17 | + bsp_io_port_pin_t minus; |
| 18 | + bsp_io_port_pin_t output; |
| 19 | +}; |
| 20 | + |
| 21 | +// See Renesas RA4M1 Group Datasheet |
| 22 | +// Note: Channel 0 is the only accessible one one the Arduino Minima boards. |
| 23 | +static const opamp_channel_pins_t opamp_channels[] = { |
| 24 | + {BSP_IO_PORT_00_PIN_00, BSP_IO_PORT_00_PIN_01, BSP_IO_PORT_00_PIN_02}, /* CH0 */ |
| 25 | + {BSP_IO_PORT_00_PIN_13, BSP_IO_PORT_00_PIN_12, BSP_IO_PORT_00_PIN_03}, /* CH1 */ |
| 26 | + {BSP_IO_PORT_00_PIN_11, BSP_IO_PORT_00_PIN_10, BSP_IO_PORT_00_PIN_04}, /* CH2 */ |
| 27 | + {BSP_IO_PORT_00_PIN_05, BSP_IO_PORT_00_PIN_06, BSP_IO_PORT_00_PIN_07}, /* CH3 */ |
| 28 | +}; |
| 29 | + |
| 30 | +bool OpampClass::initPins(uint8_t channel_mask) { |
10 | 31 | fsp_err_t err;
|
11 | 32 | ioport_instance_ctrl_t ioport_ctrl {};
|
12 |
| -#if defined(ARDUINO_UNOWIFIR4) || defined(ARDUINO_MINIMA) |
13 |
| - /* channel 0 pins. Only accessible ones. */ |
14 |
| - err = R_IOPORT_PinCfg(&ioport_ctrl, BSP_IO_PORT_00_PIN_00, OPAMP_IN_PINCFG); |
15 |
| - FSP_CHECK(err); |
16 |
| - err = R_IOPORT_PinCfg(&ioport_ctrl, BSP_IO_PORT_00_PIN_01, OPAMP_IN_PINCFG); |
17 |
| - FSP_CHECK(err); |
18 |
| - err = R_IOPORT_PinCfg(&ioport_ctrl, BSP_IO_PORT_00_PIN_02, OPAMP_OUT_PINCFG); |
19 |
| - FSP_CHECK(err); |
20 |
| -#else |
21 |
| -#error "Unsupported board." |
22 |
| -#endif |
| 33 | + // Make sure to return false if nothing was given to initialize |
| 34 | + // or a too high channel bit is in there |
| 35 | + if (channel_mask == 0 || channel_mask > 0b1111) { |
| 36 | + return false; |
| 37 | + } |
| 38 | + // Check the 4 possible channels |
| 39 | + for(uint8_t i = 0; i < 4; i++) { |
| 40 | + // was this channel selected? |
| 41 | + if (!(channel_mask & (1u << i))) { |
| 42 | + continue; |
| 43 | + } |
| 44 | + opamp_channel_pins_t pins = opamp_channels[i]; |
| 45 | + err = R_IOPORT_PinCfg(&ioport_ctrl, pins.plus, OPAMP_IN_PINCFG); |
| 46 | + FSP_CHECK(err); |
| 47 | + err = R_IOPORT_PinCfg(&ioport_ctrl, pins.minus, OPAMP_IN_PINCFG); |
| 48 | + FSP_CHECK(err); |
| 49 | + err = R_IOPORT_PinCfg(&ioport_ctrl, pins.output, OPAMP_OUT_PINCFG); |
| 50 | + FSP_CHECK(err); |
| 51 | + } |
23 | 52 | // if we got here, none of the checks triggered an early return.
|
24 | 53 | return true;
|
25 | 54 | }
|
@@ -49,20 +78,29 @@ void OpampClass::initOpamp(OpampSpeedMode speed, uint8_t channel_mask) {
|
49 | 78 | }
|
50 | 79 |
|
51 | 80 | bool OpampClass::begin(OpampSpeedMode speed) {
|
52 |
| - if(!initPins()) { |
| 81 | + return this->begin(1u << ARDUINO_DEFAULT_OPAMP_CHANNEL, speed); |
| 82 | +} |
| 83 | + |
| 84 | +bool OpampClass::begin(uint8_t channel_mask, OpampSpeedMode speed) { |
| 85 | + if(!initPins(channel_mask)) { |
53 | 86 | return false;
|
54 | 87 | }
|
55 |
| - initOpamp(speed, (1u << ARDUINO_USED_OPAMP_CHANNEL)); |
| 88 | + initOpamp(speed, channel_mask); |
56 | 89 | return true;
|
57 | 90 | }
|
58 | 91 |
|
59 |
| -uint8_t OpampClass::getStatus() { |
60 |
| - return R_OPAMP->AMPMON; |
| 92 | +bool OpampClass::isRunning(uint8_t const channel) { |
| 93 | + return (R_OPAMP->AMPMON & (1u << channel)) != 0; |
61 | 94 | }
|
62 | 95 |
|
63 | 96 | void OpampClass::end() {
|
64 |
| - // clear the bit for the used channel |
65 |
| - R_OPAMP->AMPC &= (uint8_t) ~(1u << ARDUINO_USED_OPAMP_CHANNEL); |
| 97 | + // deactivate all channels. |
| 98 | + R_OPAMP->AMPC = 0; |
| 99 | +} |
| 100 | + |
| 101 | +void OpampClass::end(uint8_t channel_mask) { |
| 102 | + // deactivate given channels |
| 103 | + R_OPAMP->AMPC &= ~channel_mask; |
66 | 104 | }
|
67 | 105 |
|
68 | 106 | /* global instance */
|
|
0 commit comments