Skip to content

Commit 61d21ea

Browse files
committed
Verified working packet rx at up to 100us clock period and 32 packets all separated by 2ms, both when all pacekts this addr and also when half other addr. 50us clock period working but drops a lot of packets, gets about 3-9 packets out of grouping of 16. Light valve opacity output and timer init/start commented out due to pin clusterfuck of rev 0
1 parent 45263ec commit 61d21ea

File tree

2 files changed

+77
-57
lines changed

2 files changed

+77
-57
lines changed

burner.ino

Lines changed: 0 additions & 1 deletion
This file was deleted.

light-valve-node-firmware.ino

Lines changed: 77 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#define GREEN_LED PIN_PA7 // GREEN LED
1414
#define RED_LED PIN_PA6 // RED LED
1515

16-
#define HEARTBEAT_PERIOD_DEFAULT_MS (1000)
16+
#define HEARTBEAT_PERIOD_DEFAULT_MS (2000)
1717
#define HEARTBEAT_PERIOD_ERROR_MS (60)
1818

1919
#define DEBUG_MODE 0
@@ -44,7 +44,7 @@ typedef enum {
4444

4545
// TODO :: non-linear opacity mapping here. Lowest values show no change (0 to 10, 10 to 20), then seems solid for a
4646
// bit, then highest values indistinguishable w/o light behind valve
47-
static const uint16_t pwm_counts_by_data_value[16] = {
47+
static const uint16_t pwm_counts_by_data_index[16] = {
4848
0,
4949
10,
5050
20,
@@ -77,19 +77,21 @@ static uint32_t clock_period_us;
7777
static uint32_t clock_period_padding_us;
7878
static uint8_t data_edges_counted;
7979
static uint8_t clock_edges_counted;
80+
static uint16_t edges = 0;
8081

81-
static uint8_t rx_start_bits;
82-
static uint8_t rx_data_bits;
83-
static uint8_t device_addr = 0x1; // TODO :: eventually this is set dynamically
84-
static uint16_t current_data_value = 0x0;
85-
static bool up = true; // TODO :: debug hack delete
82+
static uint8_t rx_start_bits;
83+
static uint8_t rx_data_bits;
84+
static uint8_t device_addr = 0x1; // TODO :: eventually this is set dynamically
85+
static uint8_t rx_data[16] = {0x0};
86+
static uint8_t rx_data_idx = 0;
8687

8788
/* #if DEBUG_MODE */
8889
static SoftwareSerial debug_serial(UART_RX, UART_TX);
8990
/* #endif */
9091

9192
void data_pin_isr(void) {
9293
data_transition_flag = true;
94+
edges++;
9395
}
9496

9597
ISR(TCA0_OVF_vect) {
@@ -102,9 +104,11 @@ ISR(TCA0_OVF_vect) {
102104
* Set up timer to expected timeout values and enabled interrupt. Does not start timer
103105
*/
104106
void timeout_timer_init(void) {
105-
// With prescaler of 16 @ 20MHz (aka 1.25MHz) this is ~6.5ms. Currently a full packet is 13 bits @ 500us/bit,
106-
// or 6.5ms total.
107-
TCA0.SINGLE.PER = 8125 - 1;
107+
// With prescaler of 16 @ 20MHz (aka 1.25MHz) 2000 tick period is 1.6ms. Should be se so if in worst case there's
108+
// one extra transition at the end of the packet,, timeout timer will still expire and reset state before next
109+
// packet starts.
110+
// TCA0.SINGLE.PER = 8125 - 1;
111+
TCA0.SINGLE.PER = 2000 - 1;
108112
TCA0.SINGLE.CNT = 0;
109113

110114
// Divide 20MHz down to 5MHz
@@ -189,9 +193,17 @@ void pwm_timer_sync(void) {
189193
TCD0.CTRLE = TCD_SYNCEOC_bm;
190194
}
191195

196+
void light_valve_set_opacity(uint8_t opacity_index) {
197+
TCD0.CMPACLR = 0x000 + pwm_counts_by_data_index[opacity_index];
198+
TCD0.CMPBSET = 0xFFF - pwm_counts_by_data_index[opacity_index];
199+
200+
// Values will never load into TCD buffers until re synced
201+
pwm_timer_sync();
202+
}
203+
192204
void setup() {
193205
timeout_timer_init();
194-
pwm_timer_init();
206+
/* pwm_timer_init(); */
195207

196208
// - set up data pin as input and 2 light valve pins + test GPIO as output and low
197209
// - start pwm for output valve pins at either fully clear or fully opaque (TODO :: run a fancy startup or bink to
@@ -203,24 +215,23 @@ void setup() {
203215
// - set up light valve pins as output w/ PWM support
204216
// - set up timer with no period, that will be set from second pair of transitions in
205217
/////////////////////////
206-
uint8_t bit = digitalPinToBitMask(DATA_PIN);
207-
PORTA.DIRSET = bit;
208-
bit = digitalPinToBitMask(PIN_PA4);
209-
PORTA.DIRSET = bit;
210-
/* PORTA.DIRCLR = bit; */
218+
219+
uint8_t bit = digitalPinToBitMask(DATA_PIN);
220+
/* PORTA.DIRSET = bit; */
221+
/* bit = digitalPinToBitMask(PIN_PA4); */
222+
/* PORTA.DIRSET = bit; */
223+
PORTA.DIRCLR = bit;
211224
/* DATA_PIN_INT_CTRL_REG |= 0x1; // interrupt on both edges - attiny 212 DS sec. 16.5.11 */
212-
/* attachInterrupt(DATA_PIN, data_pin_isr, CHANGE); */
225+
attachInterrupt(DATA_PIN, data_pin_isr, CHANGE);
213226

214227
bit = digitalPinToBitMask(RED_LED);
215228
PORTA.DIRSET = bit;
216229
bit = digitalPinToBitMask(GREEN_LED);
217230
PORTA.DIRSET = bit;
218231
PORTA.OUTCLR = 0xFF;
219232

220-
// TODO :: switch back to normal pindirs for PWM functionality
221233
bit = digitalPinToBitMask(UART_TX);
222234
PORTB.DIRSET = bit;
223-
PORTB.OUTCLR = 0xFF;
224235
bit = digitalPinToBitMask(UART_RX);
225236
PORTB.DIRCLR = bit;
226237
/* bit = digitalPinToBitMask(LIGHT_VALVE_PIN_1); */
@@ -229,27 +240,26 @@ void setup() {
229240
/* PORTB.DIRSET = bit; */
230241
/* PORTB.OUTCLR = 0xFF; */
231242

243+
// Init globals
232244
current_state = DECODE_STATE_IDLE;
233245
data_transition_flag = false;
246+
heartbeat_mode = HEARTBEAT_MODE_DEBUG;
247+
heartbeat_period_ms = HEARTBEAT_PERIOD_DEFAULT_MS;
248+
clock_rate_start_us = 0;
249+
clock_period_us = (uint32_t)100 * 1000;
250+
previous_time = millis();
251+
clock_edge_start = 0;
252+
data_edges_counted = 0;
253+
clock_edges_counted = 0;
254+
rx_data_idx = 0;
255+
memset(rx_data, 0, sizeof(rx_data));
234256

235-
// Default to toggle heartbeat ever half second. Transition to rapid blink indicates error.
236-
heartbeat_mode = HEARTBEAT_MODE_DEBUG;
237-
heartbeat_period_ms = HEARTBEAT_PERIOD_ERROR_MS;
238-
clock_rate_start_us = 0;
239-
clock_period_us = (uint32_t)500 * 1000;
240-
previous_time = millis();
241-
clock_edge_start = 0;
242-
data_edges_counted = 0;
243-
clock_edges_counted = 0;
244-
245-
/* #if DEBUG_MODE */
246257
debug_serial.begin(9600);
247-
debug_serial.println("Light valve node firmware");
248-
/* #endif */
258+
debug_serial.println("LVNF");
249259

250260
// Globally enable interupts
251261
sei();
252-
pwm_timer_start();
262+
/* pwm_timer_start(); */
253263
}
254264

255265
void loop() {
@@ -321,8 +331,13 @@ void loop() {
321331
break;
322332
}
323333
case DECODE_STATE_MEASURING_CLOCK_RATE: {
324-
clock_period_us = now_us - clock_rate_start_us;
325-
clock_period_padding_us = clock_period_us / 10;
334+
clock_period_us = now_us - clock_rate_start_us;
335+
uint8_t bit = digitalPinToBitMask(RED_LED);
336+
PORTA.OUTTGL = bit;
337+
338+
// TODO :: tune this. Can be tight as /10 when clock period >= 200us, but below that need to widen
339+
// envelop due to rise/fall time slew of signal at uC pin
340+
clock_period_padding_us = clock_period_us / 5;
326341

327342
LOG("clck per us: ");
328343
LOGLN(clock_period_us);
@@ -381,9 +396,8 @@ void loop() {
381396

382397
current_state = DECODE_STATE_READING_DATA;
383398
} else {
384-
debug_serial.println("err DSRS strtbts");
385-
debug_serial.print("start bits: 0b");
386-
debug_serial.println(rx_start_bits, BIN);
399+
LOG("err strtbts: 0b");
400+
LOGLN(rx_start_bits, BIN);
387401
current_state = DECODE_STATE_ERROR;
388402
}
389403
}
@@ -416,8 +430,8 @@ void loop() {
416430
break;
417431
}
418432
default:
419-
debug_serial.print("err DSRD");
420-
debug_serial.println(data_edges_counted);
433+
LOG("err DSRD");
434+
LOGLN(data_edges_counted);
421435
current_state = DECODE_STATE_ERROR;
422436
break;
423437
}
@@ -437,11 +451,15 @@ void loop() {
437451
timeout_timer_stop();
438452
uint8_t rx_addr_bits = (rx_data_bits & 0xF0) >> 4;
439453
if (rx_addr_bits == device_addr) {
440-
debug_serial.print("rx data: 0b");
441-
debug_serial.println((rx_data_bits & 0x0F), BIN);
454+
light_valve_set_opacity(rx_data_bits & 0x0F);
455+
456+
LOG("rx data: 0b");
457+
LOGLN((rx_data_bits & 0x0F), BIN);
458+
rx_data[rx_data_idx] = rx_data_bits & 0x0F;
459+
rx_data_idx++;
442460
} else {
443-
debug_serial.print("rx wrong addr: ");
444-
debug_serial.println(rx_addr_bits, BIN);
461+
LOG("rx wrong addr: ");
462+
LOGLN(rx_addr_bits, BIN);
445463
}
446464

447465
uint8_t bit = digitalPinToBitMask(RED_LED);
@@ -475,19 +493,22 @@ void loop() {
475493
/* PORTA.OUTTGL = bit; */
476494
}
477495

478-
if (current_data_value == 15) {
479-
up = false;
480-
} else if (current_data_value == 0) {
481-
up = true;
482-
}
483-
484-
current_data_value += up ? 1 : -1;
496+
debug_serial.println(rx_data_idx, DEC);
497+
/*
498+
* Uncomment to print all 16 debug opacity values saved to debug buffer
499+
*
500+
if (rx_data_idx > 0) {
501+
for (int i = 0; i < rx_data_idx; i++) {
502+
debug_serial.print(rx_data[i]);
503+
debug_serial.print(", ");
504+
rx_data[i] = 0x0;
505+
delay(50);
506+
}
485507
486-
TCD0.CMPACLR = 0x000 + pwm_counts_by_data_value[current_data_value];
487-
TCD0.CMPBSET = 0xFFF - pwm_counts_by_data_value[current_data_value];
488-
debug_serial.print("current_data_value: ");
489-
debug_serial.println(current_data_value);
490-
pwm_timer_sync();
508+
rx_data_idx = 0;
509+
}
510+
*/
511+
rx_data_idx = 0;
491512

492513
previous_time = now;
493514
}

0 commit comments

Comments
 (0)