Skip to content

Commit 0379ba3

Browse files
authored
Add files via upload
1 parent 1c9b086 commit 0379ba3

File tree

7 files changed

+204
-0
lines changed

7 files changed

+204
-0
lines changed

libraries/OPAMP/README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# OPAMP Libray for Uno R4 Minima & WiFi
2+
3+
## Description
4+
5+
The Arduino Uno R4 Minima and WiFi boards, both a featuring a Renesas R7FA4M1AB3CFM#AA0 microcontroller, do have a built-in OPAMP peripheral.
6+
7+
OMAMPs are very versatile. They can:
8+
* mirror an input voltage to its output ("voltage follower")
9+
* amplify a small analog voltage to its output pin, output voltage range from 0 to ~4.7V ("non-inverting amplifier")
10+
* compare two input voltages and give a binary "higher" or "lower" output ("comparator")
11+
* integrate and differentiate signals ("integrator", "differentiator")
12+
* many more
13+
14+
Electrical characteristics:
15+
* Input from 0.2V (low speed) / 0.3V (highspeed) to AVCC0 - 0.5V (lowspeed) to AVCC0 - 0.6V (high-speed)
16+
* Output from 0.1V to AVCC0 - 0.1V
17+
* Open gain: 120dB typical
18+
* Input offset voltage: -10 to 10mV
19+
* Gain-bandwidth product: 0.04MHz (low-speed) / 1.7 MHz (high-speed)
20+
* Load current: -100 to 100µA max.
21+
22+
## Usage
23+
24+
To startup the opamp, simply include the library and call `OPAMP.begin()`. You can optionally chose to use a low-speed (=lower power) or high-speed (default) mode.
25+
26+
```cpp
27+
#include <OPAMP.h>
28+
29+
void setup () {
30+
OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
31+
}
32+
33+
void loop() {}
34+
```
35+
36+
## Pinout
37+
38+
Both the Uno R4 Minima and WiFi feature their OPAMP channel 0 output on the same pins:
39+
* Analog A1: Plus
40+
* Analog A2: Minus
41+
* Analog A3: Output
42+
43+
![symbol](amp_symbol.png)
44+
45+
(Vs+ is fixed to about 5V, Vs- is fixed to GND.)
46+
## Testing
47+
48+
To test the OPAMP in the simplest possible "voltage follower" configuration, connect A2 to A3.
49+
Then, any voltage applied at A1 should be mirrored onto A3. For example, if you connect A1 to GND, the OPAMP output should be GND.
50+
Connect A1 to 3.3V, the output should be 3.3V.
51+
52+
For an amplifier circuit, see https://www.electronics-tutorials.ws/opamp/opamp_3.html. A simple 2x amplifier can be built by using e.g. two 10K resistors: Connect one resistor between "Minus" and GND. Then use the second resistor to connect the output and "Minus" together. Any signal input at the "Plus" will now appear with double the amplitude at the output pin. Of course, the input signal and the Arduino Uno R4 should share the same GND and the amplified output signal should not go above ~4.7V, otherwise clipping will appear.
53+
54+
Below is a capture of an oscilloscope in which a circa 2V square-wave (green, channel 2) is amplified to 4V square-wave (yellow, channel 1) with the aforementioned circuit.
55+
56+
![amp](amp_screenshot.png)

libraries/OPAMP/amp_screenshot.png

59.1 KB
Loading

libraries/OPAMP/amp_symbol.png

5.59 KB
Loading
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <Arduino.h>
2+
#include <OPAMP.h>
3+
4+
void setup () {
5+
Serial.begin(9600);
6+
delay(2000); // serial monitor delay
7+
// activate OPAMP
8+
if(!OPAMP.begin(OPAMP_SPEED_HIGHSPEED)) {
9+
Serial.println("Failed to start OPAMP!");
10+
}
11+
uint8_t status = OPAMP.getStatus();
12+
if(status & (1u << 0u)) {
13+
Serial.println("OPAMP running on channel 0!");
14+
} else {
15+
Serial.println("OPAMP channel 0 is not running!");
16+
}
17+
}
18+
19+
void loop() {
20+
delay(1000); // do nothing
21+
}

libraries/OPAMP/library.properties

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name=OPAMP
2+
version=1.0.0
3+
author=Maximilian Gerhardt
4+
maintainer=Maximilian Gerhardt <maximilian.gerhardt@rub.de>
5+
sentence=Library for using the OPAMP on Arduino Uno R4 boards.
6+
paragraph=Supports OPAMP on Arduino Uno R4 (Minima, WiFI).
7+
category=Signal Input/Output
8+
url=https://github.com/arduino/ArduinoCore-renesas/tree/master/libraries/OPAMP
9+
architectures=renesas
10+
includes=OPAMP.h

libraries/OPAMP/src/OPAMP.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include "OPAMP.h"
2+
#include <Arduino.h>
3+
4+
/* pin mode needed to activate OPAMP functionality */
5+
#define OPAMP_IN_PINCFG (IOPORT_CFG_PORT_DIRECTION_INPUT | IOPORT_CFG_PERIPHERAL_PIN | IOPORT_CFG_ANALOG_ENABLE)
6+
#define OPAMP_OUT_PINCFG (IOPORT_CFG_PORT_DIRECTION_OUTPUT | IOPORT_CFG_PERIPHERAL_PIN | IOPORT_CFG_ANALOG_ENABLE)
7+
#define FSP_CHECK(err) do { if( (err) != FSP_SUCCESS) return false; } while(0)
8+
9+
bool OpampClass::initPins() {
10+
fsp_err_t err;
11+
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
23+
// if we got here, none of the checks triggered an early return.
24+
return true;
25+
}
26+
27+
void OpampClass::initOpamp(OpampSpeedMode speed, uint8_t channel_mask) {
28+
uint8_t ampmc_val = 0U;
29+
/* setup amplifier speed mode within amplifier mode control */
30+
/* for all boards, this is at bit position 7 with either 0 (lowspeed) or 1 (highspeed) */
31+
ampmc_val = (uint8_t) ((uint8_t) speed << R_OPAMP_AMPMC_AMPSP_Pos) & R_OPAMP_AMPMC_AMPSP_Msk;
32+
/* reset opamp */
33+
R_OPAMP->AMPC = 0U;
34+
/* write prepared mode control value */
35+
R_OPAMP->AMPMC = ampmc_val;
36+
/* setup activation trigger select register */
37+
/* we only support "Software start & stop" for now, value 0. */
38+
R_OPAMP->AMPTRS = 0;
39+
R_OPAMP->AMPTRM = 0;
40+
/* set the bits for the activated channels */
41+
R_OPAMP->AMPC |= channel_mask;
42+
/* note: we don't have to activate the charge pump (AMPCPC) because here AVCC0 > 2.7V */
43+
/* delay for the wanted init time in microseconds */
44+
if (speed == OPAMP_SPEED_LOWSPEED) {
45+
delayMicroseconds(BSP_FEATURE_OPAMP_MIN_WAIT_TIME_LP_US);
46+
} else if (speed == OPAMP_SPEED_HIGHSPEED) {
47+
delayMicroseconds(BSP_FEATURE_OPAMP_MIN_WAIT_TIME_HS_US);
48+
}
49+
}
50+
51+
bool OpampClass::begin(OpampSpeedMode speed) {
52+
if(!initPins()) {
53+
return false;
54+
}
55+
initOpamp(speed, (1u << ARDUINO_USED_OPAMP_CHANNEL));
56+
return true;
57+
}
58+
59+
uint8_t OpampClass::getStatus() {
60+
return R_OPAMP->AMPMON;
61+
}
62+
63+
void OpampClass::end() {
64+
// clear the bit for the used channel
65+
R_OPAMP->AMPC &= (uint8_t) ~(1u << ARDUINO_USED_OPAMP_CHANNEL);
66+
}
67+
68+
/* global instance */
69+
OpampClass OPAMP;

libraries/OPAMP/src/OPAMP.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#ifndef _OPAMP_H_
2+
#define _OPAMP_H_
3+
4+
#include <stdint.h>
5+
6+
/* Available speed modes */
7+
/* Note: No middle speed mode on the Uno R4 boards */
8+
enum OpampSpeedMode {
9+
OPAMP_SPEED_LOWSPEED = 0,
10+
OPAMP_SPEED_HIGHSPEED = 1,
11+
};
12+
13+
/* The supported boards have 4 OPAMP channels, however, only channel 0 is accessible. */
14+
/* All other channels are connected to the LED matrix or not exposed. */
15+
#define ARDUINO_USED_OPAMP_CHANNEL 0
16+
17+
/**
18+
* Pin Mapping for OPAMP
19+
* Uno R4 (Minima, WiFi):
20+
* ~Channel 0~
21+
* Plus: Analog A1 (Renesas P0.00)
22+
* Minus: Analog A2 (Renesas P0.01)
23+
* Output: Analog A3 (Renesas P0.02)
24+
* ~Channel 1~ (Inaccessible)
25+
* +: P0.13, -: Renesas P0.12, Out: Renesas P0.03
26+
* ~Channel 2~ (Inaccessible)
27+
* +: P0.11, -: Renesas P0.10, Out: Renesas P0.04
28+
* ~Channel 3~ (Inaccessible)
29+
* +: P0.05, -: Renesas P0.06, Out: Renesas P0.07
30+
*/
31+
class OpampClass {
32+
public:
33+
/* startup the OPAMP on channel 0 */
34+
bool begin(OpampSpeedMode speed = OPAMP_SPEED_HIGHSPEED);
35+
/* stop the OPAMP on channel 0 */
36+
void end();
37+
/* i-th Bit: 0 if OPAMP channel is stopped, 1 if OPAMP channel is operating */
38+
uint8_t getStatus();
39+
private:
40+
/* initializes OPAMP pins */
41+
bool initPins();
42+
/* activates OPAMP for given speed and channel(s) */
43+
void initOpamp(OpampSpeedMode speed, uint8_t channel_mask);
44+
};
45+
46+
extern OpampClass OPAMP;
47+
48+
#endif /* _OPAMP_H_ */

0 commit comments

Comments
 (0)