* merged: nrf tree from unicore-mx * fixed: small changes to make merged code play with rest of locm3 again * added: linker script generator defines for nRF51/52 stubs * added: doxygen support This removes code and changes names and styles where relevant to be more inline with normal libopencm3. NRF52x library is built for hardfloat, M4F by default. The M4 no float variants are less common, and if needed, the library can be built manually for those variants. Unless some very common boards show up using those parts, we don't need an extra library build. Reviewed-by: Karl Palsson <karlp@tweak.net.au> Tested-by: Karl Palsson <karlp@tweak.net.au>
251 lines
6.3 KiB
C
251 lines
6.3 KiB
C
/** @addtogroup radio_file RADIO peripheral API
|
|
*
|
|
* @brief <b>Access functions for the 2.4 GHz Radio </b>
|
|
*
|
|
* @ingroup peripheral_apis
|
|
* LGPL License Terms @ref lgpl_license
|
|
* @author @htmlonly © @endhtmlonly 2016
|
|
* Maxim Sloyko <maxims@google.com>
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* This file is part of the libopencm3 project.
|
|
*
|
|
* Copyright (C) 2017-2018 Unicore MX project<dev(at)lists(dot)unicore-mx(dot)org>
|
|
* Copyright (C) 2021 Eduard Drusa <ventyl86(at)netkosice(dot)sk>
|
|
*
|
|
* This library is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <libopencm3/nrf/ficr.h>
|
|
#include <libopencm3/nrf/radio.h>
|
|
|
|
/**@{*/
|
|
|
|
/** @brief Set radio transmission power.
|
|
*
|
|
* @details Note, not all supported power levels are BLE compliant.
|
|
*
|
|
* @param[in] txpower enum radio_txpower
|
|
* */
|
|
void radio_set_txpower(enum radio_txpower txpower)
|
|
{
|
|
RADIO_TXPOWER = txpower;
|
|
}
|
|
|
|
/** @brief Set bit transmission order to LSB first. */
|
|
void radio_set_lsbfirst(void)
|
|
{
|
|
RADIO_PCNF1 &= ~RADIO_PCNF1_ENDIAN_BIG;
|
|
}
|
|
|
|
/** @brief Set bit transmission order to MSB first. */
|
|
void radio_set_msbfirst(void)
|
|
{
|
|
RADIO_PCNF1 |= RADIO_PCNF1_ENDIAN_BIG;
|
|
}
|
|
|
|
/** @brief Enable on the air data whitening
|
|
*
|
|
* @details the in-memory data will remain unwhitened.
|
|
* */
|
|
void radio_enable_whitening(void)
|
|
{
|
|
RADIO_PCNF1 |= RADIO_PCNF1_WHITEEN;
|
|
}
|
|
|
|
/** @brief Disable on the air data whitening. */
|
|
void radio_disable_whitening(void)
|
|
{
|
|
RADIO_PCNF1 &= ~RADIO_PCNF1_WHITEEN;
|
|
}
|
|
|
|
/** @brief Set CRC length in number of bytes.
|
|
*
|
|
* @param[in] crc_len uint8_t CRC length in number of bytes (1-3), 0 = CRC disabled.
|
|
*/
|
|
void radio_set_crclen(uint8_t crc_len)
|
|
{
|
|
uint32_t reg_crc = RADIO_CRCCNF;
|
|
reg_crc &= ~RADIO_CRCCNF_LEN_MASK;
|
|
RADIO_CRCCNF = reg_crc | RADIO_CRCCNF_LEN_MASKED(crc_len);
|
|
}
|
|
|
|
/** @brief Disable CRC calculation. */
|
|
void radio_disable_crc(void)
|
|
{
|
|
RADIO_CRCCNF &= ~RADIO_CRCCNF_LEN_MASK;
|
|
}
|
|
|
|
/** @brief Enable the peripheral. */
|
|
void radio_enable(void)
|
|
{
|
|
RADIO_POWER = RADIO_POWER_ENABLED;
|
|
}
|
|
|
|
/** @brief Disable the peripheral. */
|
|
void radio_disable(void)
|
|
{
|
|
RADIO_POWER = RADIO_POWER_DISABLED;
|
|
}
|
|
|
|
|
|
/** @brief Set Base Address length.
|
|
*
|
|
* @param[in] ba_len uint8_t Base Address length in number of bytes (2-4).
|
|
*/
|
|
void radio_set_balen(uint8_t ba_len)
|
|
{
|
|
uint32_t reg_pcnf1 = RADIO_PCNF1;
|
|
reg_pcnf1 &= ~RADIO_PCNF1_BALEN_MASK;
|
|
RADIO_PCNF1 = reg_pcnf1 | RADIO_PCNF1_BALEN_MASKED(ba_len);
|
|
}
|
|
|
|
/** @brief Set maximum transmission length in number of bytes.
|
|
*
|
|
* @param[in] maxlen uint8_t maximum transmission length.
|
|
*/
|
|
void radio_set_maxlen(uint8_t maxlen)
|
|
{
|
|
uint32_t reg_pcnf1 = RADIO_PCNF1;
|
|
reg_pcnf1 &= ~RADIO_PCNF1_MAXLEN_MASK;
|
|
RADIO_PCNF1 = reg_pcnf1 | RADIO_PCNF1_MAXLEN_MASKED(maxlen);
|
|
}
|
|
|
|
/** @brief Exclude access address from CRC calculation.
|
|
*
|
|
* @param[in] is_skip_addr bool If true, CRC will be calculated over PDU only,
|
|
* if false, it will also include the Access Address.
|
|
*/
|
|
void radio_set_crc_skipaddr(bool is_skip_addr)
|
|
{
|
|
if (is_skip_addr) {
|
|
RADIO_CRCCNF |= RADIO_CRCCNF_SKIPADDR;
|
|
} else {
|
|
RADIO_CRCCNF &= ~RADIO_CRCCNF_SKIPADDR;
|
|
}
|
|
}
|
|
|
|
/** @brief Configure the radio to be used in BLE mode.
|
|
*
|
|
* @details This needs to be called before the radio can be used in BLE mode.
|
|
* It will set som BLE standard parameters, like Inter-Frame Spacing time,
|
|
* LSB first, enable whitening, properly configure CRC (for advertising) and address length.
|
|
*/
|
|
void radio_configure_ble(void)
|
|
{
|
|
#ifdef NRF51
|
|
radio_set_mode(RADIO_MODE_BLE_1MBIT);
|
|
#endif
|
|
RADIO_TIFS = RADIO_BLE_TIFS;
|
|
radio_set_lsbfirst();
|
|
radio_enable_whitening();
|
|
|
|
radio_set_crclen(RADIO_BLE_CRCLEN);
|
|
RADIO_CRCPOLY = RADIO_BLE_CRCPOLY;
|
|
RADIO_CRCINIT = RADIO_BLE_CRCINIT;
|
|
radio_set_crc_skipaddr(true);
|
|
radio_set_balen(3);
|
|
}
|
|
|
|
/** @brief Configure the packet.
|
|
*
|
|
* @details See the data sheet for details.
|
|
*/
|
|
void radio_configure_packet(uint8_t lf_len_bits, uint8_t s0_len_bytes, uint8_t s1_len_bits)
|
|
{
|
|
RADIO_PCNF0 = RADIO_PCNF0_LFLEN_MASKED(lf_len_bits)
|
|
| RADIO_PCNF0_S0LEN_MASKED(s0_len_bytes)
|
|
| RADIO_PCNF0_S1LEN_MASKED(s1_len_bits);
|
|
}
|
|
|
|
/** @brief Set radio frequency.
|
|
*
|
|
* @param[in] freq uint8_t Frequency offset from 2.4GHz in MHz, for example "29" will
|
|
* tune the radio to 2429MHz
|
|
*/
|
|
void radio_set_frequency(uint8_t freq)
|
|
{
|
|
RADIO_FREQUENCY = freq;
|
|
}
|
|
|
|
/** @brief Set Data Whitening Initialization Vector.
|
|
*
|
|
* @param[in] iv uint8_t Initialization Vector. For BLE, this is channel index.
|
|
*/
|
|
void radio_set_datawhiteiv(uint8_t iv)
|
|
{
|
|
RADIO_DATAWHITEIV = iv;
|
|
}
|
|
|
|
/* @brief Set Address (base and prefix)
|
|
*
|
|
* @details Note that bases are shared between addresses 1-7,
|
|
* so changing one of them will change others too.
|
|
*
|
|
* @param[in] addr_index uint8_t address index (0-7)
|
|
* @param[in] base uint32_t base part of the address. If balen < 4, appropriate number
|
|
* of LSBs will be thrown away.
|
|
* @param[in] prefix uint8_t Address prefix.
|
|
*/
|
|
void radio_set_addr(uint8_t addr_index, uint32_t base, uint8_t prefix)
|
|
{
|
|
if (addr_index == 0) {
|
|
RADIO_BASE0 = base;
|
|
} else {
|
|
RADIO_BASE1 = base;
|
|
}
|
|
|
|
uint32_t reg_prefix = RADIO_PREFIX_AP(addr_index);
|
|
reg_prefix &= ~RADIO_PREFIX_AP_MASK(addr_index);
|
|
RADIO_PREFIX_AP_SET(addr_index, reg_prefix | RADIO_PREFIX_AP_MASKED(addr_index, prefix));
|
|
}
|
|
|
|
/* @brief Set TX address index
|
|
*
|
|
* @details The address needs to be previously configured with radio_set_addr()
|
|
*
|
|
* @param[in] address_index uint8_t address index (0-7)
|
|
*/
|
|
void radio_set_tx_address(uint8_t addr_index)
|
|
{
|
|
RADIO_TXADDRESS = addr_index;
|
|
}
|
|
|
|
/* @brief Set pointer for RX/TX data
|
|
*
|
|
* @param[in] packet_ptr uint8_t* packet buffer address.
|
|
*/
|
|
void radio_set_packet_ptr(uint8_t *packet_ptr)
|
|
{
|
|
RADIO_PACKETPTR = (uint32_t)packet_ptr;
|
|
}
|
|
|
|
/* @brief Enable radio Transmitter */
|
|
void radio_enable_tx(void)
|
|
{
|
|
PERIPH_TRIGGER_TASK(RADIO_TASK_TXEN);
|
|
}
|
|
|
|
/* @brief Enable radio Receiver */
|
|
void radio_enable_rx(void)
|
|
{
|
|
PERIPH_TRIGGER_TASK(RADIO_TASK_RXEN);
|
|
}
|
|
|
|
|
|
/**@}*/
|
|
|