Skip to content

Commit a736750

Browse files
author
clawpi
committed
Remove thin wrapper functions, use BusIO directly
1 parent 3781d74 commit a736750

File tree

3 files changed

+176
-61
lines changed

3 files changed

+176
-61
lines changed

Adafruit_AS7331.cpp

Lines changed: 16 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -243,29 +243,26 @@ as7331_clock_t Adafruit_AS7331::getClockFrequency(void) {
243243
* @return UVA measurement counts
244244
*/
245245
uint16_t Adafruit_AS7331::readUVA(void) {
246-
uint16_t value = 0;
247-
readRegister(AS7331_REG_MRES1, &value);
248-
return value;
246+
Adafruit_BusIO_Register mres1(_i2c_dev, AS7331_REG_MRES1, 2, LSBFIRST);
247+
return mres1.read();
249248
}
250249

251250
/**
252251
* @brief Read the UVB channel counts
253252
* @return UVB measurement counts
254253
*/
255254
uint16_t Adafruit_AS7331::readUVB(void) {
256-
uint16_t value = 0;
257-
readRegister(AS7331_REG_MRES2, &value);
258-
return value;
255+
Adafruit_BusIO_Register mres2(_i2c_dev, AS7331_REG_MRES2, 2, LSBFIRST);
256+
return mres2.read();
259257
}
260258

261259
/**
262260
* @brief Read the UVC channel counts
263261
* @return UVC measurement counts
264262
*/
265263
uint16_t Adafruit_AS7331::readUVC(void) {
266-
uint16_t value = 0;
267-
readRegister(AS7331_REG_MRES3, &value);
268-
return value;
264+
Adafruit_BusIO_Register mres3(_i2c_dev, AS7331_REG_MRES3, 2, LSBFIRST);
265+
return mres3.read();
269266
}
270267

271268
/**
@@ -277,7 +274,8 @@ uint16_t Adafruit_AS7331::readUVC(void) {
277274
*/
278275
bool Adafruit_AS7331::readAllUV(uint16_t *uva, uint16_t *uvb, uint16_t *uvc) {
279276
uint8_t buffer[6] = {0};
280-
if (!readRegisters(AS7331_REG_MRES1, buffer, sizeof(buffer))) {
277+
uint8_t reg = AS7331_REG_MRES1;
278+
if (!_i2c_dev->write_then_read(&reg, 1, buffer, sizeof(buffer))) {
281279
return false;
282280
}
283281

@@ -445,9 +443,8 @@ bool Adafruit_AS7331::oneShot_uWcm2(float *uva, float *uvb, float *uvc) {
445443
* @return Temperature in degrees Celsius
446444
*/
447445
float Adafruit_AS7331::readTemperature(void) {
448-
uint16_t raw = 0;
449-
readRegister(AS7331_REG_TEMP, &raw);
450-
raw &= 0x0FFF;
446+
Adafruit_BusIO_Register temp_reg(_i2c_dev, AS7331_REG_TEMP, 2, LSBFIRST);
447+
uint16_t raw = temp_reg.read() & 0x0FFF;
451448
return (raw * 0.05f) - 66.9f;
452449
}
453450

@@ -456,23 +453,19 @@ float Adafruit_AS7331::readTemperature(void) {
456453
* @return true if data is ready, false otherwise
457454
*/
458455
bool Adafruit_AS7331::isDataReady(void) {
459-
uint16_t status = 0;
460-
if (!readRegister(AS7331_REG_OSR, &status)) {
461-
return false;
462-
}
463-
464-
bool not_ready = (status >> 10) & 0x1;
465-
return !not_ready;
456+
Adafruit_BusIO_Register osr(_i2c_dev, AS7331_REG_OSR, 2, LSBFIRST);
457+
Adafruit_BusIO_RegisterBits nready(&osr, 1, 10);
458+
return !nready.read();
466459
}
467460

468461
/**
469462
* @brief Read the status register byte
470463
* @return Status register value
471464
*/
472465
uint8_t Adafruit_AS7331::getStatus(void) {
473-
uint16_t val = 0;
474-
readRegister(AS7331_REG_OSR, &val);
475-
return (val >> 8) & 0xFF; // STATUS is high byte
466+
Adafruit_BusIO_Register osr(_i2c_dev, AS7331_REG_OSR, 2, LSBFIRST);
467+
Adafruit_BusIO_RegisterBits status_bits(&osr, 8, 8);
468+
return status_bits.read();
476469
}
477470

478471
/**
@@ -641,37 +634,3 @@ bool Adafruit_AS7331::getStandby(void) {
641634
Adafruit_BusIO_RegisterBits sb(&creg3, 1, 4);
642635
return sb.read();
643636
}
644-
645-
/**
646-
* @brief Read an 8-bit register
647-
* @param reg Register address
648-
* @param value Pointer to storage for the read value
649-
* @return true if the operation succeeded, false otherwise
650-
*/
651-
bool Adafruit_AS7331::readRegister(uint8_t reg, uint8_t *value) {
652-
Adafruit_BusIO_Register bus_reg(_i2c_dev, reg);
653-
return bus_reg.read(value);
654-
}
655-
656-
/**
657-
* @brief Read a 16-bit register
658-
* @param reg Register address
659-
* @param value Pointer to storage for the read value
660-
* @return true if the operation succeeded, false otherwise
661-
*/
662-
bool Adafruit_AS7331::readRegister(uint8_t reg, uint16_t *value) {
663-
Adafruit_BusIO_Register bus_reg(_i2c_dev, reg, 2, LSBFIRST);
664-
return bus_reg.read(value);
665-
}
666-
667-
/**
668-
* @brief Read multiple bytes starting at a register address
669-
* @param reg Starting register address
670-
* @param buffer Buffer to fill with data
671-
* @param len Number of bytes to read
672-
* @return true if the operation succeeded, false otherwise
673-
*/
674-
bool Adafruit_AS7331::readRegisters(uint8_t reg, uint8_t *buffer, uint8_t len) {
675-
Adafruit_BusIO_Register bus_reg(_i2c_dev, reg, len, LSBFIRST);
676-
return bus_reg.read(buffer, len);
677-
}

Adafruit_AS7331.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,6 @@ class Adafruit_AS7331 {
160160
bool getStandby(void);
161161

162162
private:
163-
bool readRegister(uint8_t reg, uint8_t *value);
164-
bool readRegister(uint8_t reg, uint16_t *value);
165-
bool readRegisters(uint8_t reg, uint8_t *buffer, uint8_t len);
166-
167163
float _countsToIrradiance(uint16_t counts, float baseSensitivity);
168164

169165
Adafruit_I2CDevice *_i2c_dev = nullptr; ///< Pointer to I2C device

hw_tests/pwm_demo/pwm_demo.ino

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
/**
2+
* PWM Demo for Metro Mini Oscilloscope Testing
3+
*
4+
* Generates three different PWM frequencies using direct timer register manipulation:
5+
* - Timer2: ~245 Hz on pins 3 and 11
6+
* - Timer1: 1000 Hz on pins 9 and 10
7+
* - Timer0: 5000 Hz on pins 5 and 6
8+
*
9+
* Each frequency pair has:
10+
* - One pin with fixed 50% duty cycle (square wave reference)
11+
* - One pin with sweeping duty cycle (0% → 100% → 0% over ~5 seconds)
12+
*
13+
* WARNING: Timer0 modification breaks millis()/delay() - uses _delay_ms() instead
14+
*
15+
* Hardware: Metro Mini (ATmega328P @ 16 MHz)
16+
*/
17+
18+
#include <util/delay.h>
19+
20+
// Pin assignments (fixed by ATmega328P hardware)
21+
#define PIN_245HZ_FIXED 11 // OC2A - 50% duty
22+
#define PIN_245HZ_SWEEP 3 // OC2B - sweeping duty
23+
#define PIN_1KHZ_FIXED 9 // OC1A - 50% duty
24+
#define PIN_1KHZ_SWEEP 10 // OC1B - sweeping duty
25+
#define PIN_5KHZ_FIXED 6 // OC0A - 50% duty (toggle mode)
26+
#define PIN_5KHZ_SWEEP 5 // OC0B - sweeping duty
27+
28+
// Timer1 TOP value for 1000 Hz (16-bit timer allows exact frequency)
29+
// f = f_clk / (2 * N * TOP) for Phase Correct PWM
30+
// 1000 = 16000000 / (2 * 1 * 8000)
31+
#define TIMER1_TOP 8000
32+
33+
// Timer0 TOP value for 5000 Hz
34+
// f = f_clk / (2 * N * TOP) for Phase Correct PWM
35+
// 5000 = 16000000 / (2 * 8 * 200)
36+
#define TIMER0_TOP 200
37+
38+
// Sweep timing
39+
#define SWEEP_STEPS 100 // Steps in one direction
40+
#define SWEEP_DELAY_MS 25 // Delay per step (~5 sec full cycle)
41+
42+
void setup() {
43+
Serial.begin(115200);
44+
while (!Serial) { ; }
45+
46+
Serial.println(F("\n=== PWM Demo for Oscilloscope Testing ==="));
47+
Serial.println(F("Metro Mini (ATmega328P @ 16 MHz)\n"));
48+
49+
// Configure all PWM pins as outputs
50+
pinMode(PIN_245HZ_FIXED, OUTPUT);
51+
pinMode(PIN_245HZ_SWEEP, OUTPUT);
52+
pinMode(PIN_1KHZ_FIXED, OUTPUT);
53+
pinMode(PIN_1KHZ_SWEEP, OUTPUT);
54+
pinMode(PIN_5KHZ_FIXED, OUTPUT);
55+
pinMode(PIN_5KHZ_SWEEP, OUTPUT);
56+
57+
// ========================================
58+
// Timer2: ~245 Hz (pins 3, 11)
59+
// Phase Correct PWM, prescaler 128
60+
// f = 16MHz / (128 * 510) = 245.1 Hz
61+
// ========================================
62+
TCCR2A = (1 << COM2A1) | // Clear OC2A on up-count match, set on down-count
63+
(1 << COM2B1) | // Clear OC2B on up-count match, set on down-count
64+
(1 << WGM20); // Phase Correct PWM, TOP = 0xFF
65+
TCCR2B = (1 << CS22) | // Prescaler = 128 (CS22:CS20 = 101)
66+
(0 << CS21) |
67+
(1 << CS20);
68+
OCR2A = 127; // Pin 11: 50% duty (127/255)
69+
OCR2B = 0; // Pin 3: start at 0%
70+
71+
float freq2 = 16000000.0 / (128.0 * 510.0);
72+
Serial.println(F("Timer2 (~245 Hz):"));
73+
Serial.print(F(" Pin 11 (OC2A): 50% fixed - "));
74+
Serial.print(freq2, 1);
75+
Serial.println(F(" Hz"));
76+
Serial.print(F(" Pin 3 (OC2B): sweeping - "));
77+
Serial.print(freq2, 1);
78+
Serial.println(F(" Hz\n"));
79+
80+
// ========================================
81+
// Timer1: 1000 Hz exact (pins 9, 10)
82+
// Phase & Freq Correct PWM, ICR1 = TOP
83+
// f = 16MHz / (2 * 1 * 8000) = 1000 Hz
84+
// ========================================
85+
TCCR1A = (1 << COM1A1) | // Clear OC1A on up-count match, set on down-count
86+
(1 << COM1B1); // Clear OC1B on up-count match, set on down-count
87+
TCCR1B = (1 << WGM13) | // Phase & Freq Correct PWM, TOP = ICR1
88+
(1 << CS10); // Prescaler = 1
89+
ICR1 = TIMER1_TOP; // TOP = 8000 for 1000 Hz
90+
OCR1A = TIMER1_TOP / 2; // Pin 9: 50% duty (4000/8000)
91+
OCR1B = 0; // Pin 10: start at 0%
92+
93+
uint32_t freq1 = 16000000UL / (2UL * 1UL * TIMER1_TOP);
94+
Serial.println(F("Timer1 (1000 Hz):"));
95+
Serial.print(F(" Pin 9 (OC1A): 50% fixed - "));
96+
Serial.print(freq1);
97+
Serial.println(F(" Hz"));
98+
Serial.print(F(" Pin 10 (OC1B): sweeping - "));
99+
Serial.print(freq1);
100+
Serial.println(F(" Hz\n"));
101+
102+
// ========================================
103+
// Timer0: 5000 Hz (pins 5, 6)
104+
// Phase Correct PWM with OCRA as TOP
105+
// f = 16MHz / (2 * 8 * 200) = 5000 Hz
106+
// WARNING: This breaks millis()/delay()!
107+
// ========================================
108+
TCCR0A = (1 << COM0A0) | // Toggle OC0A on compare match (50% square wave)
109+
(1 << COM0B1) | // Clear OC0B on up-count match, set on down-count
110+
(1 << WGM00); // Phase Correct PWM (WGM = 101 with WGM02)
111+
TCCR0B = (1 << WGM02) | // Phase Correct PWM, TOP = OCRA
112+
(1 << CS01); // Prescaler = 8
113+
OCR0A = TIMER0_TOP; // TOP = 200, Pin 6 toggles = 50% square wave
114+
OCR0B = 0; // Pin 5: start at 0%
115+
116+
uint32_t freq0 = 16000000UL / (2UL * 8UL * TIMER0_TOP);
117+
Serial.println(F("Timer0 (5000 Hz):"));
118+
Serial.print(F(" Pin 6 (OC0A): 50% fixed - "));
119+
Serial.print(freq0);
120+
Serial.println(F(" Hz"));
121+
Serial.print(F(" Pin 5 (OC0B): sweeping - "));
122+
Serial.print(freq0);
123+
Serial.println(F(" Hz\n"));
124+
125+
Serial.println(F("WARNING: millis()/delay() broken (Timer0 modified)"));
126+
Serial.println(F("Using _delay_ms() for timing.\n"));
127+
Serial.println(F("Sweep cycle: ~5 seconds (0% -> 100% -> 0%)"));
128+
Serial.println(F("Probe pins with oscilloscope to see waveforms!"));
129+
Serial.println(F("==========================================\n"));
130+
}
131+
132+
void loop() {
133+
// Sweep duty cycle up: 0% -> 100%
134+
for (uint8_t i = 0; i <= SWEEP_STEPS; i++) {
135+
// Timer2 sweep (8-bit, max 255)
136+
OCR2B = (uint8_t)(((uint32_t)i * 255) / SWEEP_STEPS);
137+
138+
// Timer1 sweep (16-bit, max = TIMER1_TOP)
139+
OCR1B = (uint16_t)(((uint32_t)i * TIMER1_TOP) / SWEEP_STEPS);
140+
141+
// Timer0 sweep (8-bit, max = TIMER0_TOP)
142+
OCR0B = (uint8_t)(((uint32_t)i * TIMER0_TOP) / SWEEP_STEPS);
143+
144+
_delay_ms(SWEEP_DELAY_MS);
145+
}
146+
147+
// Sweep duty cycle down: 100% -> 0%
148+
for (uint8_t i = SWEEP_STEPS; i > 0; i--) {
149+
// Timer2 sweep
150+
OCR2B = (uint8_t)(((uint32_t)i * 255) / SWEEP_STEPS);
151+
152+
// Timer1 sweep
153+
OCR1B = (uint16_t)(((uint32_t)i * TIMER1_TOP) / SWEEP_STEPS);
154+
155+
// Timer0 sweep
156+
OCR0B = (uint8_t)(((uint32_t)i * TIMER0_TOP) / SWEEP_STEPS);
157+
158+
_delay_ms(SWEEP_DELAY_MS);
159+
}
160+
}

0 commit comments

Comments
 (0)