diff --git a/README.md b/README.md index 3f8bee1e..19f1f355 100644 --- a/README.md +++ b/README.md @@ -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 ``, which provides much the same info as the original ``, 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. diff --git a/src/hal/hal.cpp b/src/hal/hal.cpp index 1e8f93b9..1cc2e200 100644 --- a/src/hal/hal.cpp +++ b/src/hal/hal.cpp @@ -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); } // ----------------------------------------------------------------------------- diff --git a/src/lmic/hal.h b/src/lmic/hal.h index 5a508c1d..35f0b846 100644 --- a/src/lmic/hal.h +++ b/src/lmic/hal.h @@ -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); @@ -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. diff --git a/src/lmic/radio.c b/src/lmic/radio.c index 8886e763..437d160b 100644 --- a/src/lmic/radio.c +++ b/src/lmic/radio.c @@ -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