summaryrefslogtreecommitdiff
path: root/src/app/lora32u4ii/main.cc
blob: b44652b3f8e10c453f0df8b1027012e282ae0f3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * Copyright 2021 Daniel Friesel
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */
#include "arch.h"
#include "driver/gpio.h"
#include "driver/stdout.h"
#include "driver/uptime.h"
#include "driver/adc.h"
#include "driver/spi.h"

#define CFG_eu868 1
#define CFG_sx1276_radio 1

#include "radio.h"
#include "oslmic.h"

unsigned char txbuf[4];
unsigned char rxbuf[4];

// DIYMall BSFrance LoRa32u4 II v1.3
// See also: arduino packages/adafruit/hardware/avr/1.4.13/variants/feather32u4/pins_arduino.h
// PB0 -> Charger enable and Vbat/2 measurement voltage divider enable
// PB0 is also the !SS pin, so it must be configured as output in order to use SPI.
// PB5 "D9" <- Vbat/2 via voltage divider. Appears to also have a connection to the user LED
// PC7 "D13" -> User LED
const GPIO::Pin rstpin = GPIO::pd4; // "D4" -> RST
const GPIO::Pin  cspin = GPIO::pb4; // "D8" -> NSS
const GPIO::Pin dio0pin = GPIO::pe6; // "D7" <- DIO0 / IRQ
const GPIO::Pin dio1pin = GPIO::pc6; // "D5" <- DIO1

static void writeReg (u1_t addr, u1_t data) {
	txbuf[0] = addr | 0x80;
	txbuf[1] = data;
	gpio.write(cspin, 0);
	spi.xmit(2, txbuf, 0, rxbuf);
	gpio.write(cspin, 1);
}

static u1_t readReg (u1_t addr) {
	txbuf[0] = addr & 0x7f;
	gpio.write(cspin, 0);
	spi.xmit(1, txbuf, 2, rxbuf);
	gpio.write(cspin, 1);
	return rxbuf[1];
}
/*
static void writeBuf (u1_t addr, xref2u1_t buf, u1_t len) {
	txbuf[0] = addr | 0x80;
	for (uint8_t i = 0; i < len; i++) {
		txbuf[i+1] = buf[i];
	}
	spi.xmit(len+1, txbuf, 0, rxbuf);
}

static void readBuf (u1_t addr, xref2u1_t buf, u1_t len) {
	txbuf[0] = addr & 0x7f;
	spi.xmit(1, txbuf, len, buf);
}
*/

static void writeOpmode(u1_t mode) {
	u1_t const maskedMode = mode & OPMODE_MASK;
	writeReg(RegOpMode, mode);
}

static void opmode (u1_t mode) {
	writeOpmode((readReg(RegOpMode) & ~OPMODE_MASK) | mode);
}



bool radio_init()
{
	// requestModuleActive(1); not required for sx yadayada
	gpio.output(cspin, 1);
#ifdef CFG_sx1276_radio
	gpio.output(rstpin, 0);
#else
	gpio.output(rstpin, 1);
#endif
	arch.delay_ms(1);
	gpio.input(rstpin);
	gpio.write(rstpin, 0); // disable pull-up
	arch.delay_ms(5);
	opmode(OPMODE_SLEEP);

	u1_t v = readReg(RegVersion);
#ifdef CFG_sx1276_radio
	if(v != 0x12 ) {
		kout << "Radio version mismatch: expected " << hex << 0x12 << ", got " << v << endl;
		return false;
	}
#elif CFG_sx1272_radio
	if(v != 0x22) {
		kout << "Radio version mismatch: expected " << hex << 0x22 << ", got " << v << endl;
		return false;
	}
#else
#error Missing CFG_sx1272_radio/CFG_sx1276_radio
#endif
	return true;
}

void loop(void)
{
	//gpio.led_toggle(1);
#ifdef TIMER_S
	kout << dec << uptime.get_s() << endl;
#else
	kout << "beep boop" << endl;
#endif
	kout << "VCC  = " << adc.getVCC_mV() << " mV" << endl;
	kout << "Vbat = " << adc.getVBat_mV(false) << " mV" << endl;
	gpio.led_toggle(0);
}

int main(void)
{
	arch.setup();
	gpio.setup();
	kout.setup();
	spi.setup();
	gpio.input(GPIO::pb5);

	radio_init();

	kout << "Hello, World!" << endl;
	kout << "Test, World!" << endl;

	arch.idle_loop();

	return 0;
}