Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manuelbl higher level spi #190

Merged
merged 5 commits into from
Nov 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,14 @@ function uflt122f(rawUflt12)

## Release History

- v2.3.0 introduces two important changes.

1. The pinmap is extended with an additional field `pConfig`, pointing to a C++ class instance. This instance, if provided, has extra methods for dealing with TCXO control and other fine details of operating the radio. It also gives a natural way for us to extend the behavior of the HAL.

2. Pinmaps can be pre-configured into the library, so that users don't have to do this in every sketch.

Accompanying this was a fairly large refactoring of inner header files. We now have top-level header file `<arduino_lmic_hal_configuration.h>`, which provides much the same info as the original `<hal/hal.h>`, without bringing most of the LMIC internal definitions into scope. We also changed the SPI API based on a suggestion from @manuelbl, making the HAL more friendly to structured BSPs (and also making the SPI API potentially faster).

- Interim bug fixes: added a new API (`radio_irq_handler_v2()`), which allows the caller to provide the timestamp of the interrupt. This allows for more accurate timing, because the knowledge of interrupt overhead can be moved to a platform-specific layer ([#148](https://github.com/mcci-catena/arduino-lmic/issues/148)). Fixed compile issues on ESP32 ([#140](https://github.com/mcci-catena/arduino-lmic/issues/140) and [#153](https://github.com/mcci-catena/arduino-lmic/issues/150)). We added ESP32 and 32u4 as targets in CI testing. We switched CI testing to Arduino IDE 1.8.7.
Fixed issue [#161](https://github.com/mcci-catena/arduino-lmic/issues/161) selecting the Japan version of as923 using `CFG_as923jp` (selecting via `CFG_as923` and `LMIC_COUNTRY_CODE=LMIC_COUNTRY_CODE_JP` worked).
Fixed [#38](https://github.com/mcci-catena/arduino-lmic/issues/38) -- now any call to hal_init() will put the NSS line in the idle (high/inactive) state. As a side effect, RXTX is initialized, and RESET code changed to set value before transitioning state. Likely no net effect, but certainly more correct.
Expand Down
45 changes: 24 additions & 21 deletions src/hal/hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,33 +156,36 @@ static void hal_spi_init () {
SPI.begin();
}

void hal_pin_nss (u1_t val) {
if (!val) {
uint32_t spi_freq;
static void hal_spi_trx(u1_t cmd, u1_t* buf, size_t len, bit_t is_read) {
uint32_t spi_freq;
u1_t nss = plmic_pins->nss;

if ((spi_freq = plmic_pins->spi_freq) == 0)
spi_freq = LMIC_SPI_FREQ;
if ((spi_freq = plmic_pins->spi_freq) == 0)
spi_freq = LMIC_SPI_FREQ;

SPISettings settings(spi_freq, MSBFIRST, SPI_MODE0);
SPI.beginTransaction(settings);
} else {
SPI.endTransaction();
SPISettings settings(spi_freq, MSBFIRST, SPI_MODE0);
SPI.beginTransaction(settings);
digitalWrite(nss, 0);

SPI.transfer(cmd);

for (; len > 0; --len, ++buf) {
u1_t data = is_read ? 0x00 : *buf;
data = SPI.transfer(data);
if (is_read)
*buf = data;
}

//Serial.println(val?">>":"<<");
digitalWrite(plmic_pins->nss, val);
digitalWrite(nss, 1);
SPI.endTransaction();
}

void hal_spi_write(u1_t cmd, const u1_t* buf, size_t len) {
hal_spi_trx(cmd, (u1_t*)buf, len, 0);
}

// perform SPI transaction with radio
u1_t hal_spi (u1_t out) {
u1_t res = SPI.transfer(out);
/*
Serial.print(">");
Serial.print(out, HEX);
Serial.print("<");
Serial.println(res, HEX);
*/
return res;
void hal_spi_read(u1_t cmd, u1_t* buf, size_t len) {
hal_spi_trx(cmd, buf, len, 1);
}

// -----------------------------------------------------------------------------
Expand Down
27 changes: 16 additions & 11 deletions src/lmic/hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,20 @@ extern "C"{

/*
* initialize hardware (IO, SPI, TIMER, IRQ).
* This API is deprecated as it uses the const global lmic_pins,
* which the platform can't control or change.
*/
void hal_init (void);

/*
* Initialize hardware, passing in platform-specific context
* This API is deprecated.
* The pointer is to a HalPinmap_t.
*/
void hal_init_ex (const void *pContext);

/*
* drive radio NSS pin (0=low, 1=high).
*/
void hal_pin_nss (u1_t val);

/*
* drive radio RX/TX pins (0=rx, 1=tx).
* drive radio RX/TX pins (0=rx, 1=tx). Actual polarity
* is determined by the value of HalPinmap_t::rxtx_rx_active.
*/
void hal_pin_rxtx (u1_t val);

Expand All @@ -64,11 +62,18 @@ void hal_pin_rxtx (u1_t val);
void hal_pin_rst (u1_t val);

/*
* perform 8-bit SPI transaction with radio.
* - write given byte 'outval'
* - read byte and return value
* Perform SPI write transaction with radio chip
* - write the command byte 'cmd'
* - write 'len' bytes out of 'buf'
*/
void hal_spi_write(u1_t cmd, const u1_t* buf, size_t len);

/*
* Perform SPI read transaction with radio chip
* - write the command byte 'cmd'
* - read 'len' bytes into 'buf'
*/
u1_t hal_spi (u1_t outval);
void hal_spi_read(u1_t cmd, u1_t* buf, size_t len);

/*
* disable all CPU interrupts.
Expand Down
27 changes: 6 additions & 21 deletions src/lmic/radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,36 +299,21 @@ static u1_t randbuf[16];


static void writeReg (u1_t addr, u1_t data ) {
hal_pin_nss(0);
hal_spi(addr | 0x80);
hal_spi(data);
hal_pin_nss(1);
hal_spi_write(addr | 0x80, &data, 1);
}

static u1_t readReg (u1_t addr) {
hal_pin_nss(0);
hal_spi(addr & 0x7F);
u1_t val = hal_spi(0x00);
hal_pin_nss(1);
return val;
u1_t buf[1];
hal_spi_read(addr & 0x7f, buf, 1);
return buf[0];
}

static void writeBuf (u1_t addr, xref2u1_t buf, u1_t len) {
hal_pin_nss(0);
hal_spi(addr | 0x80);
for (u1_t i=0; i<len; i++) {
hal_spi(buf[i]);
}
hal_pin_nss(1);
hal_spi_write(addr | 0x80, buf, len);
}

static void readBuf (u1_t addr, xref2u1_t buf, u1_t len) {
hal_pin_nss(0);
hal_spi(addr & 0x7F);
for (u1_t i=0; i<len; i++) {
buf[i] = hal_spi(0x00);
}
hal_pin_nss(1);
hal_spi_read(addr & 0x7f, buf, len);
}

static void requestTcxo(bit_t state) {
Expand Down