mirror of https://github.com/ARMmbed/mbed-os.git
update nrf cordio ll files
parent
568d0a287e
commit
7f23b6df0f
|
|
@ -1,49 +0,0 @@
|
|||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Audio board definition.
|
||||
*
|
||||
* Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved.
|
||||
* Arm Ltd. confidential and proprietary.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#ifndef AUDIOBOARD_H
|
||||
#define AUDIOBOARD_H
|
||||
|
||||
#include "stack/platform/include/pal_types.h"
|
||||
#include "nrf_gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
#define AUDIO_LED_1 NRF_GPIO_PIN_MAP(1,1)
|
||||
#define AUDIO_LED_2 NRF_GPIO_PIN_MAP(1,2)
|
||||
#define AUDIO_LED_3 NRF_GPIO_PIN_MAP(1,3)
|
||||
#define AUDIO_LED_4 NRF_GPIO_PIN_MAP(1,4)
|
||||
#define AUDIO_LED_5 NRF_GPIO_PIN_MAP(1,5)
|
||||
#define AUDIO_LED_6 NRF_GPIO_PIN_MAP(1,6)
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* AUDIOBOARD_H */
|
||||
|
|
@ -7,6 +7,8 @@
|
|||
* Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved.
|
||||
* ARM confidential and proprietary.
|
||||
*
|
||||
* Copyright (c) 2019-2020 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
|
|
@ -21,8 +23,9 @@
|
|||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "stack/platform/include/pal_types.h"
|
||||
#include "stack/platform/include/pal_bb.h"
|
||||
#include "pal_types.h"
|
||||
#include "pal_bb.h"
|
||||
#include "pal_bb.h"
|
||||
#include "nrf.h"
|
||||
#include "nrf_timer.h"
|
||||
#include <string.h>
|
||||
|
|
@ -51,8 +54,6 @@ static bbDrvIrqCback_t palBbRadioIrqCbackTbl[BB_PROT_NUM];
|
|||
/*!
|
||||
* \brief Initialize the baseband driver.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* One-time initialization of baseband resources. This routine can be used to setup baseband
|
||||
* resources, load RF trim parameters and execute RF calibrations.
|
||||
*
|
||||
|
|
@ -63,6 +64,10 @@ void PalBbInit(void)
|
|||
{
|
||||
palBbEnableCnt = 0;
|
||||
|
||||
/* Cycle radio peripheral power to guarantee known radio state. */
|
||||
NRF_RADIO->POWER = 0;
|
||||
NRF_RADIO->POWER = 1;
|
||||
|
||||
memset(palBbTimerIrqCbackTbl, 0, sizeof(palBbTimerIrqCbackTbl));
|
||||
memset(palBbRadioIrqCbackTbl, 0, sizeof(palBbRadioIrqCbackTbl));
|
||||
}
|
||||
|
|
@ -71,8 +76,6 @@ void PalBbInit(void)
|
|||
/*!
|
||||
* \brief Enable the BB hardware.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* This routine brings the BB hardware out of low power (enable power and clocks) just before a
|
||||
* first BB operation is executed.
|
||||
*/
|
||||
|
|
@ -86,15 +89,13 @@ void PalBbEnable(void)
|
|||
/*!
|
||||
* \brief Disable the BB hardware.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* This routine signals the BB hardware to go into low power (disable power and clocks) after all
|
||||
* BB operations have been disabled.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalBbDisable(void)
|
||||
{
|
||||
if(palBbEnableCnt)
|
||||
if (palBbEnableCnt)
|
||||
{
|
||||
palBbEnableCnt--;
|
||||
}
|
||||
|
|
@ -105,8 +106,6 @@ void PalBbDisable(void)
|
|||
* \brief Load BB timing configuration.
|
||||
*
|
||||
* \param pCfg Return configuration values.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalBbLoadCfg(PalBbCfg_t *pCfg)
|
||||
|
|
@ -115,27 +114,34 @@ void PalBbLoadCfg(PalBbCfg_t *pCfg)
|
|||
pCfg->rfSetupDelayUsec = BB_RF_SETUP_DELAY_US;
|
||||
pCfg->maxScanPeriodMsec = BB_MAX_SCAN_PERIOD_MS;
|
||||
pCfg->schSetupDelayUsec = BB_SCH_SETUP_DELAY_US;
|
||||
#if (BB_CLK_RATE_HZ == 32768)
|
||||
pCfg->BbTimerBoundaryUsec = BB_RTC_MAX_VALUE_US;
|
||||
#elif (BB_CLK_RATE_HZ == 8000000)
|
||||
pCfg->BbTimerBoundaryUsec = BB_TIMER_8MHZ_MAX_VALUE_US;
|
||||
#elif (BB_CLK_RATE_HZ == 1000000)
|
||||
pCfg->BbTimerBoundaryUsec = BB_TIMER_1MHZ_MAX_VALUE_US;
|
||||
#else
|
||||
#error "Unsupported platform."
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get the current BB clock value.
|
||||
*
|
||||
* \param useRtcBBClk Use RTC BB clock.
|
||||
* \brief Get the current BB clock value in microseconds.
|
||||
*
|
||||
* \return Current BB clock value, units are microseconds.
|
||||
*
|
||||
* This routine reads the current value from the BB clock and returns its value.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint32_t PalBbGetCurrentTime(bool_t useRtcBBClk)
|
||||
uint32_t PalBbGetCurrentTime(void)
|
||||
{
|
||||
if (palBbEnableCnt > 0)
|
||||
{
|
||||
if (useRtcBBClk)
|
||||
if (USE_RTC_BB_CLK)
|
||||
{
|
||||
/* return the RTC counter value */
|
||||
return NRF_RTC0->COUNTER;
|
||||
return BB_TICKS_TO_US(NRF_RTC1->COUNTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -143,7 +149,7 @@ uint32_t PalBbGetCurrentTime(bool_t useRtcBBClk)
|
|||
nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3);
|
||||
|
||||
/* Read and return the captured count value from capture register 3 */
|
||||
return nrf_timer_cc_read(NRF_TIMER0, NRF_TIMER_CC_CHANNEL3);
|
||||
return BB_TICKS_TO_US(nrf_timer_cc_read(NRF_TIMER0, NRF_TIMER_CC_CHANNEL3));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -151,7 +157,7 @@ uint32_t PalBbGetCurrentTime(bool_t useRtcBBClk)
|
|||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get the current FRC time.
|
||||
* \brief Get the current FRC time tick.
|
||||
*
|
||||
* \param pTime Pointer to return the current time.
|
||||
*
|
||||
|
|
@ -167,11 +173,22 @@ bool_t PalBbGetTimestamp(uint32_t *pTime)
|
|||
{
|
||||
if (palBbEnableCnt == 0)
|
||||
{
|
||||
*pTime = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pTime = PalBbGetCurrentTime(USE_RTC_BB_CLK);
|
||||
if (USE_RTC_BB_CLK && pTime)
|
||||
{
|
||||
/* return the RTC counter value */
|
||||
*pTime = NRF_RTC1->COUNTER;
|
||||
}
|
||||
else if (pTime)
|
||||
{
|
||||
/* Capture current TIMER0 count to capture register 3 */
|
||||
nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3);
|
||||
|
||||
/* Read and return the captured count value from capture register 3 */
|
||||
*pTime = nrf_timer_cc_read(NRF_TIMER0, NRF_TIMER_CC_CHANNEL3);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -183,8 +200,6 @@ bool_t PalBbGetTimestamp(uint32_t *pTime)
|
|||
* \param protId Protocol ID.
|
||||
* \param timerCback Timer IRQ callback.
|
||||
* \param radioCback Timer IRQ callback.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalBbRegisterProtIrq(uint8_t protId, bbDrvIrqCback_t timerCback, bbDrvIrqCback_t radioCback)
|
||||
|
|
@ -198,8 +213,6 @@ void PalBbRegisterProtIrq(uint8_t protId, bbDrvIrqCback_t timerCback, bbDrvIrqCb
|
|||
* \brief Set protocol ID.
|
||||
*
|
||||
* \param protId Protocol ID.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalBbSetProtId(uint8_t protId)
|
||||
|
|
@ -210,8 +223,6 @@ void PalBbSetProtId(uint8_t protId)
|
|||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Combined BLE and 154 radio interrupt handler.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void RADIO_IRQHandler(void)
|
||||
|
|
@ -225,8 +236,6 @@ void RADIO_IRQHandler(void)
|
|||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Combined BLE and 154 timer interrupt handler.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TIMER0_IRQHandler(void)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -5,7 +5,8 @@
|
|||
* \brief BLE RF path compensation implementation file.
|
||||
*
|
||||
* Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved.
|
||||
* Arm Ltd. confidential and proprietary.
|
||||
*
|
||||
* Copyright (c) 2019-2020 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -21,7 +22,7 @@
|
|||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "stack/platform/include/pal_types.h"
|
||||
#include "pal_types.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
|
|
@ -45,18 +46,18 @@
|
|||
|
||||
#if defined(NRF52840_XXAA) || defined(NRF52832_XXAA)
|
||||
/* \brief Minimum Tx power level (expressed in 1dBm units). */
|
||||
static const int16_t bbBleMinTxPwr = -40; /* -40dBm */
|
||||
static const int8_t bbBleMinTxPwr = -40; /* -40dBm */
|
||||
#else
|
||||
/* \brief Minimum Tx power level (expressed in 1dBm units). */
|
||||
static const int16_t bbBleMinTxPwr = -30; /* -30dBm */
|
||||
static const int8_t bbBleMinTxPwr = -30; /* -30dBm */
|
||||
#endif
|
||||
|
||||
#if defined(NRF52840_XXAA)
|
||||
/* \brief Maximum Tx power level (expressed in 1dBm units). */
|
||||
static const int16_t bbBleMaxTxPwr = 9; /* +9dBm */
|
||||
static const int8_t bbBleMaxTxPwr = 9; /* +9dBm */
|
||||
#else
|
||||
/* \brief Maximum Tx power level (expressed in 1dBm units). */
|
||||
static const int16_t bbBleMaxTxPwr = 4; /* +4dBm */
|
||||
static const int8_t bbBleMaxTxPwr = 4; /* +4dBm */
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
|
|
@ -71,37 +72,21 @@ int16_t bbBleRxPathComp = -1280;
|
|||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get transmit RF path compensation.
|
||||
* \brief Get receive RF path compensation.
|
||||
*
|
||||
* \return Transmit RF path compensation (in 1-dBm units).
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
int8_t palBbBleRfGetTxRfPathComp(void)
|
||||
int8_t PalRadioGetRxRfPathComp(void)
|
||||
{
|
||||
uint16_t pathCompUnsigned = (uint16_t)(bbBleTxPathComp - BB_BLE_MIN_PATH_COMP);
|
||||
|
||||
return (int16_t)BB_BLE_MATH_DIV_10(pathCompUnsigned) + BB_BLE_MIN_PATH_COMP_DBM;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get receive RF path compensation.
|
||||
*
|
||||
* \return Transmit RF path compensation (in 1-dBm units).
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
int8_t PalRadioGetRxRfPathComp(void)
|
||||
{
|
||||
uint16_t pathCompUnsigned = (uint16_t)(bbBleRxPathComp - BB_BLE_MIN_PATH_COMP);
|
||||
|
||||
return (int16_t)BB_BLE_MATH_DIV_10(pathCompUnsigned) + BB_BLE_MIN_PATH_COMP_DBM;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Initialize RF path compensation.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalRadioInitPathComp(void)
|
||||
|
|
@ -116,8 +101,6 @@ void PalRadioInitPathComp(void)
|
|||
*
|
||||
* \param pMinTxPwr Return buffer for minimum transmit power (expressed in 1dBm units).
|
||||
* \param pMaxTxPwr Return buffer for maximum transmit power (expressed in 1dBm units).
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalRadioGetSupTxPower(int8_t *pMinTxPwr, int8_t *pMaxTxPwr)
|
||||
|
|
@ -132,8 +115,6 @@ void PalRadioGetSupTxPower(int8_t *pMinTxPwr, int8_t *pMaxTxPwr)
|
|||
*
|
||||
* \param pTxPathComp Return buffer for RF transmit path compensation value (expressed in 0.1dBm units).
|
||||
* \param pRxPathComp Return buffer for RF receive path compensation value (expressed in 0.1dBm units).
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalRadioReadRfPathComp(int16_t *pTxPathComp, int16_t *pRxPathComp)
|
||||
|
|
@ -214,8 +195,109 @@ int8_t PalRadioGetActualTxPower(int8_t txPwr, bool_t compFlag)
|
|||
|
||||
if (compFlag)
|
||||
{
|
||||
txPwr += palBbBleRfGetTxRfPathComp();
|
||||
txPwr += PalRadioGetRxRfPathComp();
|
||||
}
|
||||
|
||||
return txPwr;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Request an increase in power.
|
||||
|
||||
* \param reqPwr Requested Power.
|
||||
* \param delta Delta
|
||||
*
|
||||
* \return TxPower to be set
|
||||
*
|
||||
* If increasing power: the controller will increase one step if possible.
|
||||
* If decreasing power: the controller will only decrease to the ceiling step.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
int8_t PalRadioIncreasePower(int8_t reqPwr, int8_t delta)
|
||||
{
|
||||
/* An increase in power. The controller will always increase one step if possible. */
|
||||
if (delta > 0)
|
||||
{
|
||||
#if defined(NRF52840_XXAA)
|
||||
if (reqPwr > 8) { reqPwr = 9; }
|
||||
else if (reqPwr > 7) { reqPwr = 8; }
|
||||
else if (reqPwr > 6) { reqPwr = 7; }
|
||||
else if (reqPwr > 5) { reqPwr = 6; }
|
||||
else if (reqPwr > 4) { reqPwr = 5; }
|
||||
else if (reqPwr > 3) { reqPwr = 4; }
|
||||
else if (reqPwr > 2) { reqPwr = 3; }
|
||||
else if (reqPwr > 0) { reqPwr = 2; }
|
||||
else if (reqPwr > -4) { reqPwr = 0; }
|
||||
else if (reqPwr > -8) { reqPwr = -4; }
|
||||
else if (reqPwr > -12) { reqPwr = -8; }
|
||||
else if (reqPwr > -16) { reqPwr = -12; }
|
||||
else if (reqPwr > -20) { reqPwr = -16; }
|
||||
else { reqPwr = -20; }
|
||||
#elif defined(NRF52832_XXAA)
|
||||
if (reqPwr > 3) { reqPwr = 4; }
|
||||
else if (reqPwr > 2) { reqPwr = 3; }
|
||||
else if (reqPwr > 0) { reqPwr = 2; }
|
||||
else if (reqPwr > -4) { reqPwr = 0; }
|
||||
else if (reqPwr > -8) { reqPwr = -4; }
|
||||
else if (reqPwr > -12) { reqPwr = -8; }
|
||||
else if (reqPwr > -16) { reqPwr = -12; }
|
||||
else if (reqPwr > -20) { reqPwr = -16; }
|
||||
else { reqPwr = -20; }
|
||||
#else
|
||||
if (reqPwr > 0) { reqPwr = 4; }
|
||||
else if (reqPwr > -4) { reqPwr = 0; }
|
||||
else if (reqPwr > -8) { reqPwr = -4; }
|
||||
else if (reqPwr > -12) { reqPwr = -8; }
|
||||
else if (reqPwr > -16) { reqPwr = -12; }
|
||||
else if (reqPwr > -20) { reqPwr = -16; }
|
||||
else { reqPwr = -20; }
|
||||
#endif
|
||||
}
|
||||
/* A decrease in power. The controller will decrease to higher step if reqPwer is inbetween two steps. */
|
||||
else if (delta < 0)
|
||||
{
|
||||
#if defined(NRF52840_XXAA)
|
||||
if (reqPwr <= -40) { reqPwr = -40; }
|
||||
else if (reqPwr <= -20) { reqPwr = -20; }
|
||||
else if (reqPwr <= -16) { reqPwr = -16; }
|
||||
else if (reqPwr <= -12) { reqPwr = -12; }
|
||||
else if (reqPwr <= -8) { reqPwr = -8; }
|
||||
else if (reqPwr <= -4) { reqPwr = -4; }
|
||||
else if (reqPwr <= 0) { reqPwr = 0; }
|
||||
else if (reqPwr <= 2) { reqPwr = 2; }
|
||||
else if (reqPwr <= 3) { reqPwr = 3; }
|
||||
else if (reqPwr <= 4) { reqPwr = 4; }
|
||||
else if (reqPwr <= 5) { reqPwr = 5; }
|
||||
else if (reqPwr <= 6) { reqPwr = 6; }
|
||||
else if (reqPwr <= 7) { reqPwr = 7; }
|
||||
else if (reqPwr <= 8) { reqPwr = 8; }
|
||||
else { reqPwr = 9; }
|
||||
#elif defined(NRF52832_XXAA)
|
||||
if (reqPwr <= -40) { reqPwr = -40; }
|
||||
else if (reqPwr <= -20) {reqPwr = -20; }
|
||||
else if (reqPwr <= -16) {reqPwr = -16; }
|
||||
else if (reqPwr <= -12) {reqPwr = -12; }
|
||||
else if (reqPwr <= -8) {reqPwr = -8; }
|
||||
else if (reqPwr <= -4) {reqPwr = -4; }
|
||||
else if (reqPwr <= 0) {reqPwr = 0; }
|
||||
else if (reqPwr <= 3) {reqPwr = 3; }
|
||||
else {reqPwr = 4; }
|
||||
#else
|
||||
if (reqPwr <= -30) {reqPwr = -30; }
|
||||
else if (reqPwr <= -20) {reqPwr = -20; }
|
||||
else if (reqPwr <= -16) {reqPwr = -16; }
|
||||
else if (reqPwr <= -12) {reqPwr = -12; }
|
||||
else if (reqPwr <= -8) {reqPwr = -8; }
|
||||
else if (reqPwr <= -4) {reqPwr = -4; }
|
||||
else if (reqPwr <= 0) {reqPwr = 0; }
|
||||
else {reqPwr = 4; }
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No change. */
|
||||
}
|
||||
|
||||
return reqPwr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
* \brief System configuration definition.
|
||||
*
|
||||
* Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved.
|
||||
* Arm Ltd. confidential and proprietary.
|
||||
*
|
||||
* Copyright (c) 2019-2020 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -21,29 +22,9 @@
|
|||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "stack/platform/include/pal_cfg.h"
|
||||
#include "pal_cfg.h"
|
||||
#include "nrf.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef LL_MAX_CIG
|
||||
#define LL_MAX_CIG 2 /*!< Absolute maximum number of connected isochronous groups. */
|
||||
#endif
|
||||
|
||||
#ifndef LL_MAX_CIS
|
||||
#define LL_MAX_CIS 2 /*!< Absolute maximum number of connected isochronous streams per CIG. */
|
||||
#endif
|
||||
|
||||
#ifndef LL_MAX_ADV_DATA_LEN
|
||||
#define LL_MAX_ADV_DATA_LEN 1650 /*!< Maximum advertising data length. */
|
||||
#endif
|
||||
|
||||
#ifndef LL_MAX_ADV_SETS
|
||||
#define LL_MAX_ADV_SETS 6 /*!< Absolute maximum number of advertising sets. */
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Type Definitions
|
||||
**************************************************************************************************/
|
||||
|
|
@ -71,13 +52,17 @@ typedef struct
|
|||
/* ISO */
|
||||
uint8_t numIsoTxBuf; /*!< Default number of ISO transmit buffers. */
|
||||
uint8_t numIsoRxBuf; /*!< Default number of ISO receive buffers. */
|
||||
uint16_t maxIsoBufLen; /*!< Maximum ISO buffer size between host and controller. */
|
||||
uint16_t maxIsoSduLen; /*!< Maximum ISO buffer size between host and controller. */
|
||||
uint16_t maxIsoPduLen; /*!< Maximum ISO PDU size between controllers. */
|
||||
|
||||
/* CIS */
|
||||
uint8_t maxCig; /*!< Maximum number of CIG. */
|
||||
uint8_t maxCis; /*!< Maximum number of CIS. */
|
||||
uint16_t subEvtSpaceDelay; /*!< Subevent spacing above T_MSS. */
|
||||
uint8_t maxCis; /*!< Maximum number of CIS, it is shared by the CIGs. */
|
||||
uint16_t cisSubEvtSpaceDelay; /*!< Subevent spacing above T_MSS. */
|
||||
|
||||
/* BIS*/
|
||||
uint8_t maxBig; /*!< Maximum number of BIG. */
|
||||
uint8_t maxBis; /*!< Maximum number of BIS. */
|
||||
/* DTM */
|
||||
uint16_t dtmRxSyncMs; /*!< DTM Rx synchronization window in milliseconds. */
|
||||
} PalCfgLl_t;
|
||||
|
|
@ -102,14 +87,12 @@ typedef struct
|
|||
* \param phyCodedSup Coded PHY supported.
|
||||
* \param stableModIdxTxSup Tx stable modulation index supported.
|
||||
* \param stableModIdxRxSup Rx stable modulation index supported.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void palCfgGetBlePhyFeatures(uint8_t *pPhy2mSup, uint8_t *pPhyCodedSup,
|
||||
uint8_t *pStableModIdxTxSup, uint8_t *pStableModIdxRxSup)
|
||||
{
|
||||
#if defined(NRF52840_XXAA)
|
||||
#if defined(NRF52840_XXAA) || defined(NRF52832_XXAA)
|
||||
*pPhy2mSup = TRUE;
|
||||
*pPhyCodedSup = TRUE;
|
||||
#else
|
||||
|
|
@ -125,42 +108,55 @@ void palCfgGetBlePhyFeatures(uint8_t *pPhy2mSup, uint8_t *pPhyCodedSup,
|
|||
* \brief Load LL advertising configuration.
|
||||
*
|
||||
* \param pConfig Return configuration values.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void palCfgLoadLlParams(uint8_t *pConfig)
|
||||
{
|
||||
PalCfgLl_t *pCfg = (PalCfgLl_t *)pConfig;
|
||||
|
||||
#if !defined(NRF52840_XXAA)
|
||||
#if defined(BOARD_NRF6832)
|
||||
const uint16_t maxAdvSets = 1;
|
||||
const uint16_t advDataLen = 256;
|
||||
const uint16_t aclDataLen = 256;
|
||||
const uint16_t maxConn = 1;
|
||||
const uint16_t maxGroup = 1;
|
||||
const uint16_t maxStream = 2;
|
||||
#elif !defined(NRF52840_XXAA)
|
||||
const uint16_t maxAdvSets = 1;
|
||||
const uint16_t advDataLen = 512;
|
||||
const uint16_t connDataLen = 256;
|
||||
const uint16_t numTxBufs = 8;
|
||||
#else
|
||||
const uint16_t advDataLen = LL_MAX_ADV_DATA_LEN;
|
||||
const uint16_t connDataLen = 512;
|
||||
const uint16_t numTxBufs = 16;
|
||||
#endif
|
||||
const uint16_t aclDataLen = 512;
|
||||
const uint16_t maxConn = 1;
|
||||
const uint16_t maxGroup = 1;
|
||||
const uint16_t maxStream = 2;
|
||||
#else /* Default */
|
||||
const uint16_t maxAdvSets = 6;
|
||||
const uint16_t advDataLen = 1650;
|
||||
const uint16_t aclDataLen = 512;
|
||||
const uint16_t maxConn = 4;
|
||||
const uint16_t maxGroup = 2;
|
||||
const uint16_t maxStream = 6;
|
||||
#endif
|
||||
|
||||
pCfg->maxAdvSets = LL_MAX_ADV_SETS;
|
||||
pCfg->maxAdvReports = 16;
|
||||
pCfg->maxAdvSets = maxAdvSets;
|
||||
pCfg->maxAdvReports = 8;
|
||||
pCfg->maxExtAdvDataLen = advDataLen;
|
||||
/* pCfg->defExtAdvDataFragLen */ /* Use default. */
|
||||
pCfg->auxDelayUsec = 0;
|
||||
pCfg->maxScanReqRcvdEvt = 4;
|
||||
pCfg->maxExtScanDataLen = advDataLen;
|
||||
pCfg->maxConn = 4;
|
||||
pCfg->maxAclLen = connDataLen;
|
||||
pCfg->numTxBufs = numTxBufs;
|
||||
pCfg->maxConn = maxConn;
|
||||
pCfg->maxAclLen = aclDataLen;
|
||||
pCfg->numTxBufs = 16;
|
||||
pCfg->numRxBufs = 8;
|
||||
pCfg->numIsoTxBuf = 6;
|
||||
pCfg->numIsoRxBuf = 6;
|
||||
pCfg->maxIsoBufLen = 251;
|
||||
pCfg->maxIsoPduLen = 64;
|
||||
pCfg->maxCig = LL_MAX_CIG;
|
||||
pCfg->maxCis = LL_MAX_CIS;
|
||||
pCfg->subEvtSpaceDelay = 0;
|
||||
pCfg->numIsoTxBuf = 16;
|
||||
pCfg->numIsoRxBuf = 8;
|
||||
pCfg->maxIsoSduLen = aclDataLen;
|
||||
pCfg->maxIsoPduLen = 251;
|
||||
pCfg->maxCig = maxGroup;
|
||||
pCfg->maxCis = maxStream;
|
||||
pCfg->cisSubEvtSpaceDelay = 0;
|
||||
pCfg->maxBig = maxGroup;
|
||||
pCfg->maxBis = maxStream;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
|
@ -168,8 +164,6 @@ void palCfgLoadLlParams(uint8_t *pConfig)
|
|||
* \brief Load device address.
|
||||
*
|
||||
* \param pDevAddr device address.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void palCfgLoadBdAddress(uint8_t *pDevAddr)
|
||||
|
|
@ -195,8 +189,6 @@ void palCfgLoadBdAddress(uint8_t *pDevAddr)
|
|||
* \brief Load 15.4 address.
|
||||
*
|
||||
* \param pDevAddr device address.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void palCfgLoadExtMac154Address(uint8_t *pDevAddr)
|
||||
|
|
@ -220,13 +212,12 @@ void palCfgLoadExtMac154Address(uint8_t *pDevAddr)
|
|||
* \brief Set device UUID.
|
||||
*
|
||||
* \param pBuf Return device UUID.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalCfgSetDeviceUuid(uint8_t *pBuf)
|
||||
{
|
||||
/* Not used on this platform. */
|
||||
(void)pBuf;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
|
@ -234,8 +225,6 @@ void PalCfgSetDeviceUuid(uint8_t *pBuf)
|
|||
* \brief Load device UUID.
|
||||
*
|
||||
* \param pDevUuid Return device UUID.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void palCfgLoadDeviceUuid(uint8_t *pDevUuid)
|
||||
|
|
@ -263,12 +252,12 @@ void palCfgLoadDeviceUuid(uint8_t *pDevUuid)
|
|||
* \param cfgId Configuration ID.
|
||||
* \param pBuf Buffer.
|
||||
* \param len Buffer length.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalCfgLoadData(uint8_t cfgId, uint8_t *pBuf, uint32_t len)
|
||||
void PalCfgLoadData(uint8_t cfgId, void *pBuf, uint32_t len)
|
||||
{
|
||||
(void)len;
|
||||
|
||||
switch (cfgId)
|
||||
{
|
||||
case PAL_CFG_ID_BD_ADDR:
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
* \brief Crypto driver implementation.
|
||||
*
|
||||
* Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved.
|
||||
* Arm Ltd. confidential and proprietary.
|
||||
*
|
||||
* Copyright (c) 2019-2020 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -21,24 +22,25 @@
|
|||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "stack/platform/include/pal_types.h"
|
||||
#include "stack/platform/include/pal_bb_ble.h"
|
||||
#if defined(NRF52840_XXAA) && defined(FEATURE_CRYPTOCELL310) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION
|
||||
#include "crys_rsa_kg.h"
|
||||
#include "crys_dh.h"
|
||||
#include "ssi_pal_types.h"
|
||||
#include "ssi_aes.h"
|
||||
#include "sns_silib.h"
|
||||
#include "crys_aesccm.h"
|
||||
#endif
|
||||
#include "pal_crypto.h"
|
||||
#include "pal_bb_ble.h"
|
||||
#include <string.h>
|
||||
|
||||
/* Nordic specific definitions. */
|
||||
#include "nrf_ecb.h"
|
||||
#include "nrf.h"
|
||||
#if defined(NRF52840_XXAA) && defined(FEATURE_CRYPTOCELL310) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION
|
||||
|
||||
#if defined(NRF52840_XXAA)
|
||||
#include "nrf52840.h"
|
||||
/* Crypto Cell definitions */
|
||||
#include "crys_rsa_kg.h"
|
||||
#include "crys_dh.h"
|
||||
#include "crys_aesccm.h"
|
||||
#include "ssi_pal_types.h"
|
||||
//#include "ssi_pal_mem.h"
|
||||
#include "sns_silib.h"
|
||||
#include "ssi_aes.h"
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
|
|
@ -82,16 +84,8 @@ enum
|
|||
|
||||
#endif
|
||||
|
||||
#ifndef LL_MAX_CONN
|
||||
#define LL_MAX_CONN 4 /*!< Absolute maximum number of connections (maximum is 32). */
|
||||
#endif
|
||||
|
||||
#ifndef LL_MAX_CIG
|
||||
#define LL_MAX_CIG 2 /*!< Absolute maximum number of connected isochronous groups. */
|
||||
#endif
|
||||
|
||||
#ifndef LL_MAX_CIS
|
||||
#define LL_MAX_CIS 2 /*!< Absolute maximum number of connected isochronous streams per CIG. */
|
||||
#ifndef PAL_CRYPTO_MAX_ID
|
||||
#define PAL_CRYPTO_MAX_ID 14 /*!< Absolute maximum number of cipher blocks. */
|
||||
#endif
|
||||
|
||||
#ifndef BB_ENABLE_INLINE_ENC_TX
|
||||
|
|
@ -110,15 +104,13 @@ enum
|
|||
typedef union
|
||||
{
|
||||
uint8_t b[BB_AES_BLOCK_SIZE]; /*!< Byte access block. */
|
||||
uint32_t w[BB_AES_BLOCK_SIZE / sizeof(uint32_t)]; /*!< Word acess block. */
|
||||
uint32_t w[BB_AES_BLOCK_SIZE / sizeof(uint32_t)]; /*!< Word access block. */
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t flags[1]; /*!< Flags. */
|
||||
uint8_t pctr[5]; /*!< Control. */
|
||||
uint8_t iv[8]; /*!< iv. */
|
||||
uint8_t iMSO[1]; /*!< iMSO. */
|
||||
uint8_t iLSO[1]; /*!< iLSO. */
|
||||
uint8_t iv[8]; /*!< IV. */
|
||||
} f; /*!< Field access. */
|
||||
} palCryptoCipherBlk_t;
|
||||
|
||||
|
|
@ -144,7 +136,7 @@ typedef union
|
|||
**************************************************************************************************/
|
||||
|
||||
/*! \brief Cipher block context. */
|
||||
static palCryptoCipherBlk_t palCryptoCipherBlkTbl[LL_MAX_CONN+LL_MAX_CIS*LL_MAX_CIG][PAL_CRYPTO_MODE_TOTAL];
|
||||
static palCryptoCipherBlk_t palCryptoCipherBlkTbl[PAL_CRYPTO_MAX_ID][PAL_CRYPTO_MODE_TOTAL];
|
||||
|
||||
/*! \brief Nordic ECB encryption data block. */
|
||||
static palCryptoEcbData_t palCryptoEcb;
|
||||
|
|
@ -153,11 +145,104 @@ static palCryptoEcbData_t palCryptoEcb;
|
|||
Functions
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief XOR block.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void palXor128(const uint8_t *pInA, const uint8_t *pInB, uint8_t *pOut)
|
||||
{
|
||||
const uint32_t *pInA_w = (uint32_t *)pInA;
|
||||
const uint32_t *pInB_w = (uint32_t *)pInB;
|
||||
uint32_t *pOut_w = (uint32_t *)pOut;
|
||||
|
||||
pOut_w[0] = pInA_w[0] ^ pInB_w[0];
|
||||
pOut_w[1] = pInA_w[1] ^ pInB_w[1];
|
||||
pOut_w[2] = pInA_w[2] ^ pInB_w[2];
|
||||
pOut_w[3] = pInA_w[3] ^ pInB_w[3];
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Shift block left by 1 bit.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void palShiftLeft128(const uint8_t *pIn, uint8_t *pOut)
|
||||
{
|
||||
uint8_t of = 0;
|
||||
|
||||
for (int i = 15; i >= 0; i--)
|
||||
{
|
||||
pOut[i] = pIn[i] << 1;
|
||||
pOut[i] |= of;
|
||||
|
||||
of = pIn[i] >> 7;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Generate subkeys.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void palGenSubkey(const uint8_t *pKey, uint8_t *pK1, uint8_t *pK2)
|
||||
{
|
||||
static const uint8_t Rb[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 };
|
||||
|
||||
unsigned char L[16];
|
||||
unsigned char Z[16] = { 0 };
|
||||
unsigned char t[16];
|
||||
|
||||
while (nrf_ecb_crypt(L, Z) != TRUE);
|
||||
|
||||
if ((L[0] & 0x80) == 0)
|
||||
{
|
||||
palShiftLeft128(L, pK1);
|
||||
}
|
||||
else
|
||||
{
|
||||
palShiftLeft128(L, t);
|
||||
palXor128(t, Rb, pK1);
|
||||
}
|
||||
|
||||
if ((pK1[0] & 0x80) == 0)
|
||||
{
|
||||
palShiftLeft128(pK1, pK2);
|
||||
}
|
||||
else
|
||||
{
|
||||
palShiftLeft128(pK1, t);
|
||||
palXor128(t, Rb, pK2);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Pad block.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void palPadBlock(const uint8_t *pIn, uint8_t *pOut, uint8_t len)
|
||||
{
|
||||
for (size_t i = 0; i < BB_AES_BLOCK_SIZE; i++)
|
||||
{
|
||||
if (i < len)
|
||||
{
|
||||
pOut[i] = pIn[i];
|
||||
}
|
||||
else if (i == len)
|
||||
{
|
||||
pOut[i] = 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
pOut[i] = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Execute Nordic AES ECB.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static inline void palCryptoExecuteAesEcb(void)
|
||||
|
|
@ -184,8 +269,6 @@ static inline void palCryptoExecuteAesEcb(void)
|
|||
* \brief Load Nordic AES ECB data.
|
||||
*
|
||||
* \param pEnc Encryption parameters.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static inline void palCryptoLoadEcbData(PalCryptoEnc_t *pEnc)
|
||||
|
|
@ -207,11 +290,9 @@ static inline void palCryptoLoadEcbData(PalCryptoEnc_t *pEnc)
|
|||
* \param pMic Inplace MIC buffer.
|
||||
* \param pBuf Inplace cleartext/ciphertext buffer.
|
||||
* \param pldLen Length of buffer payload.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void PalCryptPdu(palCryptoCipherBlk_t *pAx, uint8_t *pMic, uint8_t *pBuf, uint16_t pldLen)
|
||||
static void palCryptoPdu(palCryptoCipherBlk_t *pAx, uint8_t *pMic, uint8_t *pBuf, uint16_t pldLen)
|
||||
{
|
||||
/* X_1 := ECB(K, A_0) */
|
||||
palCryptoEcb.w.clear[0] = pAx->w[0];
|
||||
|
|
@ -260,8 +341,6 @@ static void PalCryptPdu(palCryptoCipherBlk_t *pAx, uint8_t *pMic, uint8_t *pBuf,
|
|||
* \param pHdr Header buffer.
|
||||
* \param pBuf Inplace cleartext/ciphertext buffer.
|
||||
* \param pldLen Length of payload.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void palCryptoAuthPdu(uint8_t type, palCryptoCipherBlk_t *pBx, uint8_t *pMic, uint8_t *pHdr, uint8_t *pBuf, uint16_t pldLen)
|
||||
|
|
@ -334,8 +413,6 @@ static void palCryptoAuthPdu(uint8_t type, palCryptoCipherBlk_t *pBx, uint8_t *p
|
|||
* \brief Increment cipher block packet counter.
|
||||
*
|
||||
* \param pCb Cipher block.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static inline void palCryptoIncPktCnt(palCryptoCipherBlk_t *pCb)
|
||||
|
|
@ -367,8 +444,6 @@ static inline void palCryptoIncPktCnt(palCryptoCipherBlk_t *pCb)
|
|||
*
|
||||
* \param pCb Cipher block.
|
||||
* \param evtCnt Connection event counter.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static inline void palCryptoLoadPktCnt(palCryptoCipherBlk_t *pCb, uint16_t evtCnt)
|
||||
|
|
@ -389,11 +464,9 @@ static inline void palCryptoLoadPktCnt(palCryptoCipherBlk_t *pCb, uint16_t evtCn
|
|||
*
|
||||
* \param pCb Cipher block.
|
||||
* \param evtCnt Connection event counter.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static inline void palCryptoLoadCisPktCnt(palCryptoCipherBlk_t *pCb, uint64_t pktCnt)
|
||||
static inline void palCryptoLoadIsoPktCnt(palCryptoCipherBlk_t *pCb, uint64_t pktCnt)
|
||||
{
|
||||
/* Pack connEventCounter. */
|
||||
pCb->f.pctr[0] = pktCnt >> 0;
|
||||
|
|
@ -414,8 +487,6 @@ static inline void palCryptoLoadCisPktCnt(palCryptoCipherBlk_t *pCb, uint64_t pk
|
|||
* \param pOut Output data.
|
||||
* \param pIn Input data.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* \note Packet length is 16 bytes.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
|
@ -455,14 +526,86 @@ void PalCryptoAesEcb(const uint8_t *pKey, uint8_t *pOut, const uint8_t *pIn)
|
|||
memcpy(pOut, revOut, sizeof(revOut));
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \fn PalCryptoAesCmac
|
||||
*
|
||||
* \brief Calculate AES CMAC.
|
||||
*
|
||||
* \param pKey Encryption key.
|
||||
* \param pOut Output data.
|
||||
* \param pIn Input data.
|
||||
*
|
||||
* \note Packet length is 16 bytes.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalCryptoAesCmac(const uint8_t *pKey, uint8_t *pOut, const uint8_t *pIn, uint16_t len)
|
||||
{
|
||||
uint32_t alignKey[4];
|
||||
memcpy(alignKey, pKey, sizeof(alignKey));
|
||||
|
||||
uint32_t revKey[4];
|
||||
revKey[0] = __REV(alignKey[3]);
|
||||
revKey[1] = __REV(alignKey[2]);
|
||||
revKey[2] = __REV(alignKey[1]);
|
||||
revKey[3] = __REV(alignKey[0]);
|
||||
|
||||
uint32_t *pIn_w = (uint32_t *)pIn;
|
||||
uint32_t revIn[4];
|
||||
if (len == 16)
|
||||
{
|
||||
revIn[0] = __REV(pIn_w[3]);
|
||||
revIn[1] = __REV(pIn_w[2]);
|
||||
revIn[2] = __REV(pIn_w[1]);
|
||||
revIn[3] = __REV(pIn_w[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
revIn[0] = __REV(pIn_w[0]);
|
||||
}
|
||||
|
||||
nrf_ecb_init();
|
||||
nrf_ecb_set_key((uint8_t *)revKey);
|
||||
|
||||
uint8_t K1[BB_AES_BLOCK_SIZE], K2[BB_AES_BLOCK_SIZE];
|
||||
palGenSubkey(pKey, K1, K2);
|
||||
|
||||
uint32_t alignM[4];
|
||||
if (len == BB_AES_BLOCK_SIZE)
|
||||
{
|
||||
/* Complete block. */
|
||||
palXor128((uint8_t *)revIn, K1, (uint8_t *)alignM);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t alignInPad[4];
|
||||
/* Partial block. */
|
||||
palPadBlock((uint8_t *)revIn, (uint8_t *)alignInPad, len);
|
||||
palXor128((uint8_t *)alignInPad, K2, (uint8_t *)alignM);
|
||||
}
|
||||
|
||||
const uint32_t alignX[4] = { 0 };
|
||||
uint32_t alignY[4];
|
||||
palXor128((const uint8_t *)alignX, (uint8_t *)alignM, (uint8_t *)alignY);
|
||||
|
||||
uint32_t alignOut[4];
|
||||
while (nrf_ecb_crypt((uint8_t *)alignOut, (uint8_t *)alignY) != TRUE);
|
||||
|
||||
uint32_t revOut[4];
|
||||
revOut[0] = __REV(alignOut[3]);
|
||||
revOut[1] = __REV(alignOut[2]);
|
||||
revOut[2] = __REV(alignOut[1]);
|
||||
revOut[3] = __REV(alignOut[0]);
|
||||
|
||||
memcpy(pOut, revOut, sizeof(revOut));
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Generate cryptographic grade random number.
|
||||
*
|
||||
* \param pBuf Buffer to store random number.
|
||||
* \param len Number of bytes.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalCryptoGenerateRandomNumber(uint8_t *pBuf, uint8_t len)
|
||||
|
|
@ -488,17 +631,21 @@ void PalCryptoGenerateRandomNumber(uint8_t *pBuf, uint8_t len)
|
|||
* \param id Context ID.
|
||||
* \param localDir Direction bit of local device (0=slave, 1=master).
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* This routine completes the transformation in a blocking manner.
|
||||
*
|
||||
* \note Leave this implementation empty if inline hardware encryption is available.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalCryptoAesSetupCipherBlock(PalCryptoEnc_t *pEnc, uint8_t id, uint8_t localDir)
|
||||
void PalCryptoAesEnable(PalCryptoEnc_t *pEnc, uint8_t id, uint8_t localDir)
|
||||
{
|
||||
unsigned int mode;
|
||||
|
||||
if (id > PAL_CRYPTO_MAX_ID)
|
||||
{
|
||||
/* TODO handle error condition */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clear */
|
||||
memset(&palCryptoCipherBlkTbl[id], 0, sizeof(palCryptoCipherBlkTbl[id]));
|
||||
|
||||
|
|
@ -527,10 +674,6 @@ void PalCryptoAesSetupCipherBlock(PalCryptoEnc_t *pEnc, uint8_t id, uint8_t loca
|
|||
/* Store context. */
|
||||
pEnc->pEncryptCtx = &palCryptoCipherBlkTbl[id][PAL_CRYPTO_MODE_ENC];
|
||||
pEnc->pDecryptCtx = &palCryptoCipherBlkTbl[id][PAL_CRYPTO_MODE_DEC];
|
||||
|
||||
#if (BB_ENABLE_INLINE_ENC_TX || BB_ENABLE_INLINE_DEC_RX)
|
||||
PalBbBleInlineEncryptDecryptSetDirection(localDir);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
|
@ -571,16 +714,16 @@ bool_t PalCryptoAesCcmEncrypt(PalCryptoEnc_t *pEnc, uint8_t *pHdr, uint8_t *pBuf
|
|||
pHdr[BB_DATA_PDU_LEN_OFFSET] += PAL_CRYPTO_LL_DATA_MIC_LEN; /* Add length of MIC to payload. */
|
||||
}
|
||||
|
||||
if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EVT_CNTR) &&
|
||||
if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EXT16_CNTR) &&
|
||||
(pEnc->pEventCounter))
|
||||
{
|
||||
palCryptoLoadPktCnt(pCb, *pEnc->pEventCounter + 1);
|
||||
}
|
||||
|
||||
if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_CIS_CNTR) &&
|
||||
(pEnc->pCisTxPktCounter))
|
||||
if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EXT64_CNTR) &&
|
||||
(pEnc->pTxPktCounter))
|
||||
{
|
||||
palCryptoLoadCisPktCnt(pCb, *pEnc->pCisTxPktCounter);
|
||||
palCryptoLoadIsoPktCnt(pCb, *pEnc->pTxPktCounter);
|
||||
}
|
||||
|
||||
palCryptoLoadEcbData(pEnc);
|
||||
|
|
@ -590,7 +733,7 @@ bool_t PalCryptoAesCcmEncrypt(PalCryptoEnc_t *pEnc, uint8_t *pHdr, uint8_t *pBuf
|
|||
palCryptoAuthPdu(pEnc->type, pCb, pMic, pHdr, pBuf, pldLen);
|
||||
}
|
||||
|
||||
PalCryptPdu(pCb, pMic, pBuf, pldLen);
|
||||
palCryptoPdu(pCb, pMic, pBuf, pldLen);
|
||||
|
||||
if (pEnc->nonceMode == PAL_BB_NONCE_MODE_PKT_CNTR)
|
||||
{
|
||||
|
|
@ -646,7 +789,7 @@ bool_t PalCryptoAesCcmDecrypt(PalCryptoEnc_t *pEnc, uint8_t *pBuf)
|
|||
}
|
||||
|
||||
uint8_t *pMic = pBuf + pldLen;
|
||||
if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EVT_CNTR) &&
|
||||
if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EXT16_CNTR) &&
|
||||
(pEnc->pEventCounter))
|
||||
{
|
||||
/* Synchronized event counter stored in packet headroom. */
|
||||
|
|
@ -657,14 +800,14 @@ bool_t PalCryptoAesCcmDecrypt(PalCryptoEnc_t *pEnc, uint8_t *pBuf)
|
|||
palCryptoLoadPktCnt(pCb, eventCounter);
|
||||
}
|
||||
|
||||
if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_CIS_CNTR) &&
|
||||
(pEnc->pCisRxPktCounter))
|
||||
if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EXT64_CNTR) &&
|
||||
(pEnc->pRxPktCounter))
|
||||
{
|
||||
palCryptoLoadCisPktCnt(pCb, *pEnc->pCisRxPktCounter - 1); /* Rx counter is already incremented when packet is received in the LCTR layer. Need to decrement one here. */
|
||||
palCryptoLoadIsoPktCnt(pCb, *pEnc->pRxPktCounter);
|
||||
}
|
||||
|
||||
palCryptoLoadEcbData(pEnc);
|
||||
PalCryptPdu(pCb, pMic, pBuf, pldLen);
|
||||
palCryptoPdu(pCb, pMic, pBuf, pldLen);
|
||||
|
||||
if (pEnc->enaAuth)
|
||||
{
|
||||
|
|
@ -691,7 +834,7 @@ bool_t PalCryptoAesCcmDecrypt(PalCryptoEnc_t *pEnc, uint8_t *pBuf)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#if defined(NRF52840_XXAA) && defined(FEATURE_CRYPTOCELL310) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION
|
||||
#if defined(NRF52840_XXAA)
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Execute the CCM-Mode encryption algorithm.
|
||||
|
|
@ -719,6 +862,10 @@ void PalCryptoCcmEnc(const uint8_t *pKey, uint8_t *pNonce, uint8_t *pPlainText,
|
|||
|
||||
CRYS_AESCCM_Key_t key;
|
||||
|
||||
(void)handlerId;
|
||||
(void)param;
|
||||
(void)event;
|
||||
|
||||
/* Copy key */
|
||||
memcpy(key, pKey, SEC_CCM_KEY_LEN);
|
||||
|
||||
|
|
@ -756,6 +903,10 @@ uint32_t PalCryptoCcmDec(const uint8_t *pKey, uint8_t *pNonce, uint8_t *pCypherT
|
|||
|
||||
CRYS_AESCCM_Key_t key;
|
||||
|
||||
(void)handlerId;
|
||||
(void)param;
|
||||
(void)event;
|
||||
|
||||
/* Copy key */
|
||||
memcpy(key, pKey, SEC_CCM_KEY_LEN);
|
||||
|
||||
|
|
@ -773,8 +924,6 @@ uint32_t PalCryptoCcmDec(const uint8_t *pKey, uint8_t *pNonce, uint8_t *pCypherT
|
|||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Called to initialize CCM-Mode security.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalCryptoInit(void)
|
||||
|
|
@ -787,8 +936,6 @@ void PalCryptoInit(void)
|
|||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Called to De-initialize CCM-Mode security.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalCryptoDeInit(void)
|
||||
|
|
@ -806,8 +953,6 @@ void PalCryptoDeInit(void)
|
|||
*
|
||||
* \param pEnc Encryption parameters.
|
||||
* \param pktCnt Counter value.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#if (BB_ENABLE_INLINE_ENC_TX)
|
||||
|
|
@ -823,8 +968,6 @@ void PalCryptoSetEncryptPacketCount(PalCryptoEnc_t *pEnc, uint64_t pktCnt)
|
|||
*
|
||||
* \param pEnc Encryption parameters.
|
||||
* \param pktCnt Counter value.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#if (BB_ENABLE_INLINE_DEC_RX)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
* \brief LED driver implementation.
|
||||
*
|
||||
* Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved.
|
||||
* Arm Ltd. confidential and proprietary.
|
||||
*
|
||||
* Copyright (c) 2019-2020 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -21,207 +22,126 @@
|
|||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "stack/platform/include/pal_led.h"
|
||||
#include "pal_led.h"
|
||||
|
||||
#if defined(BOARD_PCA10056)
|
||||
#include "boards.h"
|
||||
#include "stack/platform/include/pal_types.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
#define PAL_LED0_MASK 0x00002000
|
||||
#define PAL_LED1_MASK 0x00004000
|
||||
#define PAL_LED2_MASK 0x00008000
|
||||
#define PAL_LED3_MASK 0x00010000
|
||||
|
||||
/*! \brief LED masks. */
|
||||
#if (AUDIO_CAPE == 1)
|
||||
|
||||
#define PAL_LED_AUDIO_LED1_MASK 0x00000002
|
||||
#define PAL_LED_AUDIO_LED2_MASK 0x00000004
|
||||
#define PAL_LED_AUDIO_LED3_MASK 0x00000008
|
||||
#define PAL_LED_AUDIO_LED4_MASK 0x00000010
|
||||
#define PAL_LED_AUDIO_LED5_MASK 0x00000020
|
||||
#define PAL_LED_AUDIO_LED6_MASK 0x00000040
|
||||
|
||||
#define PAL_LED_P0_MASK 0x01E000
|
||||
#define PAL_LED_P1_MASK 0x00007E
|
||||
|
||||
#else
|
||||
#define PAL_LED_P0_MASK 0x01E000
|
||||
#define PAL_LED_P1_MASK 0x000000
|
||||
|
||||
#include "nrfx_gpiote.h"
|
||||
#endif
|
||||
|
||||
/*! \brief Invalid LED mask. */
|
||||
#define PAL_LED_INVALID_MASK 0xFF
|
||||
|
||||
/*! \brief LED count using GPIO P0. */
|
||||
#define PAL_LED_COUNT_P0 0x04
|
||||
|
||||
/*! \brief I/O Expander definitions */
|
||||
enum
|
||||
{
|
||||
PAL_LED_IO_EXP_SUB_ADDR = 0x06 /*!< Lower 3 bit of I/O expander address connected with LEDs. */
|
||||
};
|
||||
|
||||
/*! \brief I/O Expander accessories */
|
||||
enum
|
||||
{
|
||||
PAL_LED_IO_EXP_CONFIG = 0x00 /*!< LED3 to LED10 are defined as outputs.*/
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
/*! \brief Parameter check. */
|
||||
#define PAL_LED_PARAM_CHECK(expr) { if (!(expr)) { return; } }
|
||||
|
||||
/*! \brief Parameter check, with return value. */
|
||||
#define PAL_LED_PARAM_CHECK_RET(expr, rv) { if (!(expr)) { return (rv); } }
|
||||
|
||||
#else
|
||||
|
||||
/*! \brief Parameter check (disabled). */
|
||||
#define PAL_LED_PARAM_CHECK(expr)
|
||||
|
||||
/*! \brief Parameter check, with return value (disabled). */
|
||||
#define PAL_LED_PARAM_CHECK_RET(expr, rv)
|
||||
|
||||
#if defined(BOARD_NRF6832)
|
||||
#include "lp5562.h"
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Functions: Initialization
|
||||
**************************************************************************************************/
|
||||
|
||||
#if defined(BOARD_NRF6832)
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get LED pin number from LED ID.
|
||||
* \brief Map LED ID to physical LED.
|
||||
*
|
||||
* \param ledId LED ID.
|
||||
*
|
||||
* \return LED pin mask.
|
||||
* \return Mapped physical LED.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint32_t palLedGetPinMask(uint8_t ledId)
|
||||
static int palLedMapId(uint8_t ledId)
|
||||
{
|
||||
uint32_t ledMask = PAL_LED_INVALID_MASK;
|
||||
|
||||
switch (ledId)
|
||||
{
|
||||
case PAL_LED_ID_CPU_ACTIVE:
|
||||
ledMask = PAL_LED1_MASK;
|
||||
break;
|
||||
|
||||
/* Predefined */
|
||||
case PAL_LED_ID_ERROR:
|
||||
ledMask = PAL_LED3_MASK;
|
||||
return LP5562_LED_W; /* bottom */
|
||||
break;
|
||||
|
||||
/* Application defined */
|
||||
case 0:
|
||||
ledMask = PAL_LED0_MASK;
|
||||
break;
|
||||
return LP5562_LED_R; /* top/left */
|
||||
case 1:
|
||||
ledMask = PAL_LED1_MASK;
|
||||
break;
|
||||
return LP5562_LED_G; /* top/middle */
|
||||
case 2:
|
||||
ledMask = PAL_LED2_MASK;
|
||||
break;
|
||||
case 3:
|
||||
ledMask = PAL_LED3_MASK;
|
||||
break;
|
||||
|
||||
#if (AUDIO_CAPE == 1)
|
||||
case 4:
|
||||
ledMask = PAL_LED_AUDIO_LED1_MASK;
|
||||
break;
|
||||
case 5:
|
||||
ledMask = PAL_LED_AUDIO_LED2_MASK;
|
||||
break;
|
||||
case 6:
|
||||
ledMask = PAL_LED_AUDIO_LED3_MASK;
|
||||
break;
|
||||
case 7:
|
||||
ledMask = PAL_LED_AUDIO_LED4_MASK;
|
||||
break;
|
||||
case 8:
|
||||
ledMask = PAL_LED_AUDIO_LED5_MASK;
|
||||
break;
|
||||
case 9:
|
||||
ledMask = PAL_LED_AUDIO_LED6_MASK;
|
||||
break;
|
||||
#endif
|
||||
return LP5562_LED_B; /* top/right */
|
||||
|
||||
/* Ignore */
|
||||
case PAL_LED_ID_CPU_ACTIVE:
|
||||
default:
|
||||
ledMask = PAL_LED_INVALID_MASK;
|
||||
break;
|
||||
}
|
||||
|
||||
return ledMask;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Initialize LEDs.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalLedInit(void)
|
||||
{
|
||||
nrf_gpio_port_dir_output_set(NRF_P0, PAL_LED_P0_MASK);
|
||||
nrf_gpio_port_out_set(NRF_P0, PAL_LED_P0_MASK);
|
||||
#if (GPIO_COUNT > 1)
|
||||
nrf_gpio_port_dir_output_set(NRF_P1, PAL_LED_P1_MASK);
|
||||
nrf_gpio_port_out_set(NRF_P1, PAL_LED_P1_MASK);
|
||||
#if defined(BOARD_PCA10056)
|
||||
nrfx_err_t err;
|
||||
|
||||
if (!nrfx_gpiote_is_init())
|
||||
{
|
||||
err = nrfx_gpiote_init();
|
||||
|
||||
if (err != NRFX_SUCCESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nrfx_gpiote_out_config_t cfg = NRFX_GPIOTE_CONFIG_OUT_SIMPLE(true);
|
||||
|
||||
nrfx_gpiote_out_init(LED_1, &cfg);
|
||||
nrfx_gpiote_out_init(LED_2, &cfg);
|
||||
nrfx_gpiote_out_init(LED_3, &cfg);
|
||||
nrfx_gpiote_out_init(LED_4, &cfg);
|
||||
#endif
|
||||
|
||||
#if AUDIO_CAPE
|
||||
nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 1), &cfg);
|
||||
nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 2), &cfg);
|
||||
nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 3), &cfg);
|
||||
nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 4), &cfg);
|
||||
nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 5), &cfg);
|
||||
nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 6), &cfg);
|
||||
#endif
|
||||
|
||||
#if defined(BOARD_NRF6832)
|
||||
lp5562_LedInit();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief De-initialize LEDs.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalLedDeInit(void)
|
||||
{
|
||||
nrf_gpio_port_dir_input_set(NRF_P0, PAL_LED_P0_MASK);
|
||||
#if (GPIO_COUNT > 1)
|
||||
nrf_gpio_port_dir_input_set(NRF_P1, PAL_LED_P1_MASK);
|
||||
#if defined(BOARD_PCA10056)
|
||||
nrfx_gpiote_out_uninit(LED_1);
|
||||
nrfx_gpiote_out_uninit(LED_2);
|
||||
nrfx_gpiote_out_uninit(LED_3);
|
||||
nrfx_gpiote_out_uninit(LED_4);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Set multiple LEDs on.
|
||||
*
|
||||
* \param mask LED mask.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalLedOnGroup(uint32_t mask)
|
||||
{
|
||||
PAL_LED_PARAM_CHECK(mask);
|
||||
#if defined(BOARD_NRF6832)
|
||||
lp5562_LedDeInit();
|
||||
#endif
|
||||
|
||||
nrf_gpio_port_out_clear(NRF_P0, mask);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Set multiple LEDs off.
|
||||
*
|
||||
* \param mask LED mask.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalLedOffGroup(uint32_t mask)
|
||||
{
|
||||
PAL_LED_PARAM_CHECK(mask);
|
||||
|
||||
nrf_gpio_port_out_set(NRF_P0, mask);
|
||||
#if AUDIO_CAPE
|
||||
nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 1));
|
||||
nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 2));
|
||||
nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 3));
|
||||
nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 4));
|
||||
nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 5));
|
||||
nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 6));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
|
@ -229,24 +149,61 @@ void PalLedOffGroup(uint32_t mask)
|
|||
* \brief Set LED on.
|
||||
*
|
||||
* \param ledId LED ID.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalLedOn(uint8_t ledId)
|
||||
{
|
||||
uint32_t ledMask = palLedGetPinMask(ledId);
|
||||
PAL_LED_PARAM_CHECK(ledMask != PAL_LED_INVALID_MASK);
|
||||
|
||||
if ((ledId < PAL_LED_COUNT_P0) || (ledId >= PAL_LED_ID_CPU_ACTIVE))
|
||||
#if defined(BOARD_PCA10056)
|
||||
switch (ledId)
|
||||
{
|
||||
nrf_gpio_port_out_clear(NRF_P0, ledMask);
|
||||
case PAL_LED_ID_CPU_ACTIVE:
|
||||
nrfx_gpiote_out_clear(LED_2);
|
||||
break;
|
||||
case PAL_LED_ID_ERROR:
|
||||
nrfx_gpiote_out_clear(LED_4);
|
||||
break;
|
||||
case 0:
|
||||
nrfx_gpiote_out_clear(LED_1);
|
||||
break;
|
||||
case 1:
|
||||
nrfx_gpiote_out_clear(LED_3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#if (GPIO_COUNT > 1)
|
||||
else
|
||||
#endif
|
||||
|
||||
#if defined(BOARD_NRF6832)
|
||||
int ledPin = palLedMapId(ledId);
|
||||
if (ledPin >= 0)
|
||||
{
|
||||
nrf_gpio_port_out_clear(NRF_P1, ledMask);
|
||||
lp5562_LedOn(ledPin);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if AUDIO_CAPE
|
||||
switch (ledId)
|
||||
{
|
||||
case 2:
|
||||
nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 1));
|
||||
break;
|
||||
case 3:
|
||||
nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 2));
|
||||
break;
|
||||
case 4:
|
||||
nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 3));
|
||||
break;
|
||||
case 5:
|
||||
nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 4));
|
||||
break;
|
||||
case 6:
|
||||
nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 5));
|
||||
break;
|
||||
case 7:
|
||||
nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 6));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -256,24 +213,61 @@ void PalLedOn(uint8_t ledId)
|
|||
* \brief Set LED off.
|
||||
*
|
||||
* \param ledId LED ID.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalLedOff(uint8_t ledId)
|
||||
{
|
||||
uint32_t ledMask = palLedGetPinMask(ledId);
|
||||
PAL_LED_PARAM_CHECK(ledMask != PAL_LED_INVALID_MASK);
|
||||
|
||||
if ((ledId < PAL_LED_COUNT_P0) || (ledId >= PAL_LED_ID_CPU_ACTIVE))
|
||||
#if defined(BOARD_PCA10056)
|
||||
switch (ledId)
|
||||
{
|
||||
nrf_gpio_port_out_set(NRF_P0, ledMask);
|
||||
case PAL_LED_ID_CPU_ACTIVE:
|
||||
nrfx_gpiote_out_set(LED_2);
|
||||
break;
|
||||
case PAL_LED_ID_ERROR:
|
||||
nrfx_gpiote_out_set(LED_4);
|
||||
break;
|
||||
case 0:
|
||||
nrfx_gpiote_out_set(LED_1);
|
||||
break;
|
||||
case 1:
|
||||
nrfx_gpiote_out_set(LED_3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#if (GPIO_COUNT > 1)
|
||||
else
|
||||
#endif
|
||||
|
||||
#if defined(BOARD_NRF6832)
|
||||
int ledPin = palLedMapId(ledId);
|
||||
if (ledPin >= 0)
|
||||
{
|
||||
nrf_gpio_port_out_set(NRF_P1, ledMask);
|
||||
lp5562_LedOff(ledPin);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if AUDIO_CAPE
|
||||
switch (ledId)
|
||||
{
|
||||
case 2:
|
||||
nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 1));
|
||||
break;
|
||||
case 3:
|
||||
nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 2));
|
||||
break;
|
||||
case 4:
|
||||
nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 3));
|
||||
break;
|
||||
case 5:
|
||||
nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 4));
|
||||
break;
|
||||
case 6:
|
||||
nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 5));
|
||||
break;
|
||||
case 7:
|
||||
nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 6));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
* \brief Tickless timer implementation.
|
||||
*
|
||||
* Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved.
|
||||
* Arm Ltd. confidential and proprietary.
|
||||
*
|
||||
* Copyright (c) 2019-2020 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -18,37 +19,125 @@
|
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* This is timer driver is used by wsf_timer.c and pal_timer.c.
|
||||
*
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "nrf.h"
|
||||
#include "stack/platform/include/pal_rtc.h"
|
||||
#include "pal_rtc.h"
|
||||
#include "pal_timer.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
/*! \brief Parameter and state check. */
|
||||
#define PAL_RTC_CHECK(expr) { if (!(expr)) { while(1); } }
|
||||
|
||||
#else
|
||||
|
||||
/*! \brief Parameter and state check (disabled). */
|
||||
#define PAL_RTC_CHECK(expr)
|
||||
|
||||
#endif
|
||||
|
||||
#define RTC_TIMER_TOTAL_CHANNEL 4
|
||||
|
||||
/**************************************************************************************************
|
||||
Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
static palRtcIrqCback_t palRtcTimerCback[RTC_TIMER_TOTAL_CHANNEL];
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Function for clearing rtc events.
|
||||
*
|
||||
* \param channelId Channel ID Number.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalRtcClearCompareEvents(uint8_t channelId)
|
||||
{
|
||||
PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
|
||||
|
||||
NRF_RTC1->EVENTS_COMPARE[channelId] = 0;
|
||||
(void)NRF_RTC1->EVENTS_COMPARE[channelId];
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Function for starting the RTC timer.
|
||||
*
|
||||
* \return None.
|
||||
* \param channelId Channel ID Number.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalRtcEnableCompareIrq(void)
|
||||
void PalRtcEnableCompareIrq(uint8_t channelId)
|
||||
{
|
||||
NRF_RTC0->EVENTS_COMPARE[0] = 0;
|
||||
NRF_RTC0->INTENSET = RTC_INTENSET_COMPARE0_Msk;
|
||||
NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
|
||||
PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
|
||||
|
||||
PalRtcClearCompareEvents(channelId);
|
||||
|
||||
switch (channelId)
|
||||
{
|
||||
case 0:
|
||||
NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk;
|
||||
NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
|
||||
break;
|
||||
case 1:
|
||||
NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE1_Msk;
|
||||
NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE1_Msk;
|
||||
break;
|
||||
case 2:
|
||||
NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE2_Msk;
|
||||
NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE2_Msk;
|
||||
break;
|
||||
case 3:
|
||||
NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE3_Msk;
|
||||
NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE3_Msk;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Function for stopping the RTC timer.
|
||||
*
|
||||
* \return None.
|
||||
* \param channelId Channel ID Number.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalRtcDisableCompareIrq(void)
|
||||
void PalRtcDisableCompareIrq(uint8_t channelId)
|
||||
{
|
||||
NRF_RTC0->INTENCLR = RTC_INTENCLR_COMPARE0_Msk;
|
||||
NRF_RTC0->EVTENCLR = RTC_EVTENCLR_COMPARE0_Msk;
|
||||
PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
|
||||
|
||||
switch (channelId)
|
||||
{
|
||||
case 0:
|
||||
NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE0_Msk;
|
||||
NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE0_Msk;
|
||||
break;
|
||||
case 1:
|
||||
NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE1_Msk;
|
||||
NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE1_Msk;
|
||||
break;
|
||||
case 2:
|
||||
NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE2_Msk;
|
||||
NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE2_Msk;
|
||||
break;
|
||||
case 3:
|
||||
NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE3_Msk;
|
||||
NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE3_Msk;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
|
@ -63,81 +152,109 @@ uint32_t PalRtcCounterGet(void)
|
|||
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1;
|
||||
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {}
|
||||
NRF_RTC0->TASKS_STOP = 0;
|
||||
NRF_RTC1->TASKS_STOP = 0;
|
||||
|
||||
return NRF_RTC0->COUNTER;
|
||||
return NRF_RTC1->COUNTER;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Set the RTC capture compare value.
|
||||
*
|
||||
* \param channelId Channel ID Number.
|
||||
* \param value Set new value for compare value.
|
||||
*
|
||||
* \return None
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalRtcCompareSet(uint32_t value)
|
||||
void PalRtcCompareSet(uint8_t channelId, uint32_t value)
|
||||
{
|
||||
NRF_RTC0->CC[0] = value;
|
||||
PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
|
||||
NRF_RTC1->CC[channelId] = value;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get the current value of the RTC capture compare.
|
||||
*
|
||||
* \param channelId Channel ID Number.
|
||||
*
|
||||
* \return Current value of the capture compare.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint32_t PalRtcCompareGet(void)
|
||||
uint32_t PalRtcCompareGet(uint8_t channelId)
|
||||
{
|
||||
return NRF_RTC0->CC[0];
|
||||
PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
|
||||
return NRF_RTC1->CC[channelId];
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief RTC interrupt handler.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* This handler stores the RTC start time which is used as a reference to compute the receive
|
||||
* packet timestamp using the HFCLK.
|
||||
*
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void RTC0_IRQHandler(void)
|
||||
void RTC1_IRQHandler(void)
|
||||
{
|
||||
if (NRF_RTC0->EVENTS_COMPARE[0])
|
||||
for (unsigned int channelId = 0; channelId < RTC_TIMER_TOTAL_CHANNEL; channelId++)
|
||||
{
|
||||
/* clear the interrupt */
|
||||
NRF_RTC0->EVENTS_COMPARE[0] = 0;
|
||||
(void)NRF_RTC0->EVENTS_COMPARE[0]; /* wait for write buffer to empty */
|
||||
if (NRF_RTC1->EVENTS_COMPARE[channelId])
|
||||
{
|
||||
PalRtcClearCompareEvents(channelId);
|
||||
|
||||
if (palRtcTimerCback[channelId])
|
||||
{
|
||||
palRtcTimerCback[channelId]();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Tickless timer initialization routine.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalRtcInit(void)
|
||||
{
|
||||
/* Stop RTC to prevent any running timers from expiring. */
|
||||
PalRtcDisableCompareIrq();
|
||||
for (unsigned int channelId = 0; channelId < RTC_TIMER_TOTAL_CHANNEL; channelId++)
|
||||
{
|
||||
PalRtcDisableCompareIrq(channelId);
|
||||
}
|
||||
|
||||
/* Configure low-frequency clock. */
|
||||
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
|
||||
|
||||
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1;
|
||||
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {}
|
||||
NRF_RTC0->TASKS_STOP = 0;
|
||||
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) { }
|
||||
NRF_RTC1->TASKS_STOP = 0;
|
||||
|
||||
NRF_RTC0->TASKS_STOP = 1;
|
||||
NRF_RTC0->TASKS_CLEAR = 1;
|
||||
NRF_RTC0->PRESCALER = 0; /* clear prescaler */
|
||||
NRF_RTC0->TASKS_START = 1;
|
||||
NRF_RTC1->TASKS_STOP = 1;
|
||||
NRF_RTC1->TASKS_CLEAR = 1;
|
||||
NRF_RTC1->PRESCALER = 0; /* clear prescaler */
|
||||
NRF_RTC1->TASKS_START = 1;
|
||||
|
||||
NVIC_SetPriority(RTC0_IRQn, 0x80); /* medium priority */
|
||||
NVIC_ClearPendingIRQ(RTC0_IRQn);
|
||||
NVIC_EnableIRQ(RTC0_IRQn);
|
||||
NVIC_SetPriority(RTC1_IRQn, 0x80); /* medium priority */
|
||||
NVIC_ClearPendingIRQ(RTC1_IRQn);
|
||||
NVIC_EnableIRQ(RTC1_IRQn);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Register rtc IRQ callback.
|
||||
*
|
||||
* \param channelId Channel ID Number.
|
||||
* \param cback Call back for ISR.
|
||||
*
|
||||
* This callback is dedicated for scheduler timer in low power code.
|
||||
*
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalRtcIrqRegister(uint8_t channelId, palRtcIrqCback_t cback)
|
||||
{
|
||||
PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
|
||||
palRtcTimerCback[channelId] = cback;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
* \brief System hooks.
|
||||
*
|
||||
* Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved.
|
||||
* Arm Ltd. confidential and proprietary.
|
||||
*
|
||||
* Copyright (c) 2019-2020 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -22,11 +23,12 @@
|
|||
/*************************************************************************************************/
|
||||
|
||||
#include "nrf.h"
|
||||
#include "stack/platform/include/pal_bb.h"
|
||||
#include "stack/platform/include/pal_rtc.h"
|
||||
#include "stack/platform/include/pal_sys.h"
|
||||
#include "stack/platform/include/pal_led.h"
|
||||
#include "platform/mbed_power_mgmt.h"
|
||||
#include "pal_rtc.h"
|
||||
#include "pal_sys.h"
|
||||
#include "pal_led.h"
|
||||
#include "pal_timer.h"
|
||||
#include "pal_bb.h"
|
||||
#include "pal_uart.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
|
@ -34,16 +36,37 @@
|
|||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
extern uint8_t *SystemHeapStart;
|
||||
extern uint32_t SystemHeapSize;
|
||||
|
||||
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
|
||||
#ifdef __GNUC__
|
||||
|
||||
/*! \brief Stack initial values. */
|
||||
#define INIT_STACK_VAL 0xAFAFAFAF
|
||||
|
||||
/*! \brief Starting memory location of free memory. */
|
||||
#define FREE_MEM_START ((uint8_t *)&__heap_start__)
|
||||
|
||||
/*! \brief Total size in bytes of free memory. */
|
||||
#define FREE_MEM_SIZE ((uint32_t)&__heap_end__ - (uint32_t)&__heap_start__)
|
||||
|
||||
extern uint8_t *SystemHeapStart;
|
||||
extern uint32_t SystemHeapSize;
|
||||
|
||||
extern unsigned long __text_end__;
|
||||
extern unsigned long __data_start__;
|
||||
extern unsigned long __data_end__;
|
||||
extern unsigned long __bss_start__;
|
||||
extern unsigned long __bss_end__;
|
||||
extern unsigned long __stack_top__;
|
||||
extern unsigned long __stack_limit__;
|
||||
extern unsigned long __heap_end__;
|
||||
extern unsigned long __heap_start__;
|
||||
|
||||
#else
|
||||
|
||||
/*! \brief Starting memory location of free memory. */
|
||||
#define FREE_MEM_START ((uint8_t *)palSysFreeMem)
|
||||
|
||||
/*! \brief Total size in bytes of free memory. */
|
||||
#define FREE_MEM_SIZE (1024 * 196)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -51,6 +74,21 @@ extern unsigned long __stack_limit__;
|
|||
Global Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
uint8_t *SystemHeapStart;
|
||||
uint32_t SystemHeapSize;
|
||||
|
||||
#else
|
||||
|
||||
/*! \brief Free memory for pool buffers (align to word boundary). */
|
||||
uint32_t palSysFreeMem[FREE_MEM_SIZE/sizeof(uint32_t)];
|
||||
|
||||
uint8_t *SystemHeapStart = (uint8_t *) palSysFreeMem;
|
||||
uint32_t SystemHeapSize = FREE_MEM_SIZE;
|
||||
|
||||
#endif
|
||||
|
||||
/*! \brief Number of assertions. */
|
||||
static uint32_t palSysAssertCount;
|
||||
|
||||
|
|
@ -66,19 +104,17 @@ static uint32_t palSysBusyCount;
|
|||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Enter a critical section.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static inline void palEnterCs(void)
|
||||
void PalEnterCs(void)
|
||||
{
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
__disable_interrupt();
|
||||
#endif
|
||||
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
|
||||
#ifdef __GNUC__
|
||||
__asm volatile ("cpsid i");
|
||||
#endif
|
||||
#if defined(__ARMCC_VERSION)
|
||||
#ifdef __CC_ARM
|
||||
__disable_irq();
|
||||
#endif
|
||||
}
|
||||
|
|
@ -86,19 +122,17 @@ static inline void palEnterCs(void)
|
|||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Exit a critical section.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static inline void palExitCs(void)
|
||||
void PalExitCs(void)
|
||||
{
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
__enable_interrupt();
|
||||
#endif
|
||||
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
|
||||
#ifdef __GNUC__
|
||||
__asm volatile ("cpsie i");
|
||||
#endif
|
||||
#if defined(__ARMCC_VERSION)
|
||||
#ifdef __CC_ARM
|
||||
__enable_irq();
|
||||
#endif
|
||||
}
|
||||
|
|
@ -106,34 +140,17 @@ static inline void palExitCs(void)
|
|||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Common platform initialization.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalSysInit(void)
|
||||
{
|
||||
/* enable Flash cache */
|
||||
/* Enable Flash cache */
|
||||
NRF_NVMC->ICACHECNF |= (NVMC_ICACHECNF_CACHEEN_Enabled << NVMC_ICACHECNF_CACHEEN_Pos);
|
||||
|
||||
/* switch to more accurate 16 MHz crystal oscillator (system starts up using 16MHz RC oscillator) */
|
||||
/* Use 16 MHz crystal oscillator (system starts up using 16MHz RC oscillator). */
|
||||
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_HFCLKSTART = 1;
|
||||
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* configure low-frequency clock */
|
||||
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
|
||||
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1;
|
||||
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
|
||||
{
|
||||
}
|
||||
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
|
||||
|
||||
/* cycle radio peripheral power to guarantee known radio state */
|
||||
NRF_RADIO->POWER = 0;
|
||||
NRF_RADIO->POWER = 1;
|
||||
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { }
|
||||
|
||||
palSysAssertCount = 0;
|
||||
PalSysAssertTrapEnable = TRUE;
|
||||
|
|
@ -141,6 +158,10 @@ void PalSysInit(void)
|
|||
|
||||
PalRtcInit();
|
||||
|
||||
PalLedInit();
|
||||
PalLedOff(PAL_LED_ID_ERROR);
|
||||
PalLedOn(PAL_LED_ID_CPU_ACTIVE);
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Reset free memory. */
|
||||
memset(SystemHeapStart, 0, SystemHeapSize);
|
||||
|
|
@ -150,12 +171,12 @@ void PalSysInit(void)
|
|||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief System fault trap.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalSysAssertTrap(void)
|
||||
{
|
||||
PalLedOn(PAL_LED_ID_ERROR);
|
||||
|
||||
palSysAssertCount++;
|
||||
|
||||
while (PalSysAssertTrapEnable);
|
||||
|
|
@ -166,8 +187,6 @@ void PalSysAssertTrap(void)
|
|||
* \brief Set system trap.
|
||||
*
|
||||
* \param enable Enable assert trap or not.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalSysSetTrap(bool_t enable)
|
||||
|
|
@ -178,8 +197,6 @@ void PalSysSetTrap(bool_t enable)
|
|||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get assert count.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint32_t PalSysGetAssertCount(void)
|
||||
|
|
@ -196,7 +213,7 @@ uint32_t PalSysGetAssertCount(void)
|
|||
/*************************************************************************************************/
|
||||
uint32_t PalSysGetStackUsage(void)
|
||||
{
|
||||
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
|
||||
#ifdef __GNUC__
|
||||
unsigned long *pUnused = &__stack_limit__;
|
||||
|
||||
while (pUnused < &__stack_top__)
|
||||
|
|
@ -219,28 +236,53 @@ uint32_t PalSysGetStackUsage(void)
|
|||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief System sleep.
|
||||
*
|
||||
* \return none.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalSysSleep(void)
|
||||
{
|
||||
sleep();
|
||||
/* Clock management for low power mode. */
|
||||
#if BB_CLK_RATE_HZ == 32768
|
||||
uint32_t rtcNow = NRF_RTC1->COUNTER;
|
||||
|
||||
if ((BbGetCurrentBod() == NULL) && PalUartGetState(PAL_UART_ID_CHCI) == PAL_UART_STATE_UNINIT)
|
||||
{
|
||||
if ((PalTimerGetState() == PAL_TIMER_STATE_BUSY &&
|
||||
((NRF_RTC1->CC[3] - rtcNow) & PAL_MAX_RTC_COUNTER_VAL) > PAL_HFCLK_OSC_SETTLE_TICKS) ||
|
||||
(PalTimerGetState() == PAL_TIMER_STATE_READY))
|
||||
{
|
||||
/* disable HFCLK */
|
||||
NRF_CLOCK->TASKS_HFCLKSTOP = 1;
|
||||
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
|
||||
(void)NRF_CLOCK->EVENTS_HFCLKSTARTED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* CPU sleep. */
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
__wait_for_interrupt();
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
__asm volatile ("wfi");
|
||||
#endif
|
||||
#ifdef __CC_ARM
|
||||
__wfi();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Check if system is busy.
|
||||
*
|
||||
* \return True if system is busy.
|
||||
* \return TRUE if system is busy.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
bool_t PalSysIsBusy(void)
|
||||
{
|
||||
bool_t sysIsBusy = FALSE;
|
||||
palEnterCs();
|
||||
PalEnterCs();
|
||||
sysIsBusy = ((palSysBusyCount == 0) ? FALSE : TRUE);
|
||||
palExitCs();
|
||||
PalExitCs();
|
||||
return sysIsBusy;
|
||||
}
|
||||
|
||||
|
|
@ -253,24 +295,22 @@ bool_t PalSysIsBusy(void)
|
|||
/*************************************************************************************************/
|
||||
void PalSysSetBusy(void)
|
||||
{
|
||||
palEnterCs();
|
||||
PalEnterCs();
|
||||
palSysBusyCount++;
|
||||
palExitCs();
|
||||
PalExitCs();
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Set system idle.
|
||||
*
|
||||
* \return none.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalSysSetIdle(void)
|
||||
{
|
||||
palEnterCs();
|
||||
PalEnterCs();
|
||||
if (palSysBusyCount)
|
||||
{
|
||||
palSysBusyCount--;
|
||||
}
|
||||
palExitCs();
|
||||
PalExitCs();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
* \brief Timer driver
|
||||
*
|
||||
* Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved.
|
||||
* Arm Ltd. confidential and proprietary.
|
||||
*
|
||||
* Copyright (c) 2019-2020 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -24,22 +25,56 @@
|
|||
/*
|
||||
* Notes:
|
||||
*
|
||||
* This is timer driver dedicated to scheduler, an interrupt will be triggered to do scheduler task
|
||||
* when timer hits compare value. TIMER2 is used here.
|
||||
* This is timer driver used for scheduler and other low power related tasks.
|
||||
* It has dependency on pal_rtc.c, and some scheduler and BB API due to the complexity explained below.
|
||||
* This is not ideal and should be fixed later.
|
||||
*
|
||||
* TIMER2's compare/capture registers are assigned specific uses:
|
||||
* CC[0] - Compare value for timer expiry interrupt
|
||||
* CC[1] - manual capture of current time
|
||||
* If SCH_TIMER_REQUIRED == FALSE:
|
||||
* No hardware timer is needed for scheduler.
|
||||
*
|
||||
* If SCH_TIMER_REQUIRED == TRUE and BB_CLK_RATE_HZ == 32768:
|
||||
* RTC1 timer(channel 3) is in use for scheduler.
|
||||
*
|
||||
* If SCH_TIMER_REQUIRED == TRUE and BB_CLK_RATE_HZ == 1MHz or 8MHz:
|
||||
* Timer1 is in used for scheduler.
|
||||
*
|
||||
* RTC1 timer(Channel 0) is required for wsf software timer no matter what options are chosen.
|
||||
*
|
||||
* RTC1 timer(Channel 1 and 2) are required as long as BB_CLK_RATE_HZ == 32768.
|
||||
*
|
||||
* NRF timer1's compare/capture registers are assigned specific uses:
|
||||
* CC[0] - Compare value for timer expiry interrupt.
|
||||
* CC[1] - manual capture of current time.
|
||||
*
|
||||
* NRF RTC1's compare/capture registers are assigned specific uses:
|
||||
* CC[0] - Compare value for wsf software timer interrupt.
|
||||
* CC[1] - Compare value for NRF timer0 start task.
|
||||
* CC[2] - Compare value for NRF HFCLK start task.
|
||||
* CC[3] - Compare value for scheduler load interrupt.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pal_timer.h"
|
||||
#include "pal_rtc.h"
|
||||
#include "sch_api.h"
|
||||
#include "bb_api.h"
|
||||
|
||||
#include "nrf.h"
|
||||
#include "stack/platform/include/pal_timer.h"
|
||||
#include "nrf_gpio.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief Ticks and microseconds conversion. */
|
||||
#if BB_CLK_RATE_HZ == 32768
|
||||
#define PAL_TIMER_US_TO_TICKS(us) ((uint32_t)(((uint64_t)(us) * (uint64_t)(70368745)) >> 31)) /* calculated value may be one tick low */
|
||||
#define PAL_TIMER_TICKS_TO_US(ticks) ((uint32_t)(((uint64_t)(ticks) * 15625) >> 9))
|
||||
#else
|
||||
#define PAL_TIMER_US_TO_TICKS(us) (us)
|
||||
#define PAL_TIMER_TICKS_TO_US(ticks) (ticks)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
/*! \brief Parameter and state check. */
|
||||
|
|
@ -59,6 +94,14 @@
|
|||
#define PAL_TIMER_DEBUG_0_PIN 35 /* P1.03 */
|
||||
#endif
|
||||
|
||||
/* Predefined channel ID for timer1 and rtc1. */
|
||||
#define TIMER_CHANNEL_START_BB 0
|
||||
#define TIMER_CHANNEL_READ_TICK 1
|
||||
|
||||
#define RTC_CHANNEL_START_HFCLK 2
|
||||
#define RTC_CHANNEL_START_BB 3
|
||||
|
||||
|
||||
/**************************************************************************************************
|
||||
Global Variables
|
||||
**************************************************************************************************/
|
||||
|
|
@ -71,6 +114,38 @@ static struct
|
|||
PalTimerCompCback_t expCback; /*!< Timer expiry call back function. */
|
||||
} palTimerCb;
|
||||
|
||||
/* Nordic specific internal functions. */
|
||||
extern void PalRtcIrqRegister(uint8_t channelId, palRtcIrqCback_t cback);
|
||||
extern void PalRtcClearCompareEvents(uint8_t channelId);
|
||||
|
||||
#if BB_CLK_RATE_HZ == 32768
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief scheduler callback handler from RTC interrupt.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void palTimerRtcIrqHandler(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nrf_gpio_pin_set(PAL_TIMER_DEBUG_0_PIN);
|
||||
#endif
|
||||
|
||||
PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_BUSY);
|
||||
|
||||
palTimerCb.state = PAL_TIMER_STATE_READY;
|
||||
|
||||
if (palTimerCb.expCback)
|
||||
{
|
||||
palTimerCb.expCback();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nrf_gpio_pin_clear(PAL_TIMER_DEBUG_0_PIN);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SCH_TIMER_REQUIRED
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get the current tick of the scheduler timer.
|
||||
|
|
@ -78,60 +153,69 @@ static struct
|
|||
* \return Current tick of the scheduler timer.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint32_t PalTimerGetCurrentTime(void)
|
||||
static uint32_t palTimerGetCurrentTime(void)
|
||||
{
|
||||
/* Only valid for initialized scheduler timer. */
|
||||
|
||||
if (palTimerCb.state)
|
||||
{
|
||||
/* Capture current TIMER2 count to capture register 1 */
|
||||
NRF_TIMER2->TASKS_CAPTURE[1] = 1;
|
||||
#if BB_CLK_RATE_HZ == 32768
|
||||
/* Read and return the captured count value from capture register 1 */
|
||||
return NRF_TIMER2->CC[1];
|
||||
return PalRtcCounterGet();
|
||||
#else
|
||||
/* Capture current TIMER1 count to capture register 1 */
|
||||
NRF_TIMER1->TASKS_CAPTURE[TIMER_CHANNEL_READ_TICK] = 1;
|
||||
/* Read and return the captured count value from capture register 1 */
|
||||
return NRF_TIMER1->CC[TIMER_CHANNEL_READ_TICK];
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Initialize the scheduler timer.
|
||||
*
|
||||
* \param expCback Timer expire call back function.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalTimerInit(PalTimerCompCback_t expCback)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG
|
||||
nrf_gpio_cfg_output(PAL_TIMER_DEBUG_0_PIN);
|
||||
#endif
|
||||
#endif
|
||||
PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_UNINIT);
|
||||
PAL_TIMER_CHECK(expCback != NULL);
|
||||
|
||||
#if SCH_TIMER_REQUIRED == TRUE
|
||||
#if BB_CLK_RATE_HZ == 32768
|
||||
PalRtcIrqRegister(RTC_CHANNEL_START_BB, palTimerRtcIrqHandler);
|
||||
#else
|
||||
/* Give scheduler timer the highest priority. */
|
||||
NVIC_SetPriority(TIMER2_IRQn, 0);
|
||||
NVIC_SetPriority(TIMER1_IRQn, 0); /* highest priority */
|
||||
NVIC_DisableIRQ(TIMER1_IRQn);
|
||||
|
||||
/* stop timer if it was somehow running (timer must be stopped for configuration) */
|
||||
NRF_TIMER2->TASKS_STOP = 1;
|
||||
NRF_TIMER1->TASKS_STOP = 1;
|
||||
|
||||
/* clear timer to zero count */
|
||||
NRF_TIMER2->TASKS_CLEAR = 1;
|
||||
NRF_TIMER1->TASKS_CLEAR = 1;
|
||||
|
||||
/* configure timer */
|
||||
NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer;
|
||||
NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_32Bit;
|
||||
NRF_TIMER2->PRESCALER = PAL_TIMER_1MHZ_PRESCALER; /* f = 16MHz / (2 ^ TIMER_PRESCALER) */
|
||||
NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
|
||||
NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_32Bit;
|
||||
NRF_TIMER1->PRESCALER = PAL_TIMER_1MHZ_PRESCALER; /* f = 16MHz / (2 ^ TIMER_PRESCALER) */
|
||||
|
||||
/* TIMER2 is a free running clock. */
|
||||
NRF_TIMER2->TASKS_START = 1;
|
||||
/* timer1 is a free running clock. */
|
||||
NRF_TIMER1->TASKS_START = 1;
|
||||
|
||||
/* Clear out and enable TIMER2 interrupt at system level. */
|
||||
NRF_TIMER2->INTENCLR = 0xFFFFFFFF;
|
||||
NRF_TIMER2->EVENTS_COMPARE[0] = 0;
|
||||
NVIC_ClearPendingIRQ(TIMER2_IRQn);
|
||||
NVIC_EnableIRQ(TIMER2_IRQn);
|
||||
/* Clear out and enable timer1 interrupt at system level. */
|
||||
NRF_TIMER1->INTENCLR = 0xFFFFFFFF;
|
||||
NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0;
|
||||
NVIC_ClearPendingIRQ(TIMER1_IRQn);
|
||||
NVIC_EnableIRQ(TIMER1_IRQn);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
palTimerCb.compareVal = 0;
|
||||
palTimerCb.expCback = expCback;
|
||||
|
|
@ -141,18 +225,18 @@ void PalTimerInit(PalTimerCompCback_t expCback)
|
|||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief De-initialize the scheduler timer.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalTimerDeInit(void)
|
||||
{
|
||||
|
||||
NVIC_DisableIRQ(TIMER2_IRQn);
|
||||
#if SCH_TIMER_REQUIRED == TRUE
|
||||
#if BB_CLK_RATE_HZ != 32768
|
||||
NVIC_DisableIRQ(TIMER1_IRQn);
|
||||
|
||||
/* stop timer */
|
||||
NRF_TIMER2->TASKS_STOP = 1;
|
||||
NRF_TIMER2->TASKS_SHUTDOWN = 1;
|
||||
NRF_TIMER1->TASKS_STOP = 1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
palTimerCb.state = PAL_TIMER_STATE_UNINIT;
|
||||
}
|
||||
|
|
@ -174,69 +258,95 @@ PalTimerState_t PalTimerGetState(void)
|
|||
* \brief Start the scheduler timer.
|
||||
*
|
||||
* \param expTimeUsec Set timer expiry in microseconds.
|
||||
*
|
||||
* \return None
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
void PalTimerStart(uint32_t expTimeUsec)
|
||||
{
|
||||
PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_READY);
|
||||
PAL_TIMER_CHECK(expTimeUsec != 0);
|
||||
|
||||
uint32_t startTimeTick = PalTimerGetCurrentTime() + PAL_TIMER_US_TO_TICKS(expTimeUsec);
|
||||
#if SCH_TIMER_REQUIRED == TRUE
|
||||
#if BB_CLK_RATE_HZ == 32768
|
||||
uint32_t startTimeTick = palTimerGetCurrentTime() + PAL_TIMER_US_TO_TICKS(expTimeUsec);
|
||||
|
||||
/* Set compare value to start BB. */
|
||||
PalRtcCompareSet(RTC_CHANNEL_START_BB, startTimeTick);
|
||||
/* Enable RTC interrupt source to start BB. */
|
||||
PalRtcEnableCompareIrq(RTC_CHANNEL_START_BB);
|
||||
|
||||
/* Set compare value to start HFCLK. */
|
||||
|
||||
uint32_t startHFCLKTick = (startTimeTick - PAL_HFCLK_OSC_SETTLE_TICKS) & PAL_MAX_RTC_COUNTER_VAL;
|
||||
|
||||
PalRtcClearCompareEvents(RTC_CHANNEL_START_HFCLK);
|
||||
PalRtcCompareSet(RTC_CHANNEL_START_HFCLK, startHFCLKTick);
|
||||
#else
|
||||
uint32_t startTimeTick = palTimerGetCurrentTime() + PAL_TIMER_US_TO_TICKS(expTimeUsec);
|
||||
|
||||
/* Clear pending events. */
|
||||
NRF_TIMER2->EVENTS_COMPARE[0] = 0;
|
||||
NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0;
|
||||
|
||||
/* Set compare value. */
|
||||
NRF_TIMER2->CC[0] = startTimeTick;
|
||||
NRF_TIMER1->CC[TIMER_CHANNEL_START_BB] = startTimeTick;
|
||||
|
||||
/* Enable TIMER2 interrupt source for CC[0]. */
|
||||
NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
|
||||
/* Enable timer1 interrupt source for CC[0]. */
|
||||
NRF_TIMER1->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
|
||||
#endif
|
||||
|
||||
palTimerCb.compareVal = startTimeTick;
|
||||
palTimerCb.state = PAL_TIMER_STATE_BUSY;
|
||||
#else
|
||||
(void)expTimeUsec;
|
||||
if (BbGetCurrentBod() == NULL)
|
||||
{
|
||||
SchLoadHandler();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Stop the scheduler timer.
|
||||
*
|
||||
* \return None
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalTimerStop()
|
||||
{
|
||||
#if SCH_TIMER_REQUIRED == TRUE
|
||||
#if BB_CLK_RATE_HZ == 32768
|
||||
/* Disable this interrupt */
|
||||
NRF_TIMER2->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk;
|
||||
PalRtcDisableCompareIrq(RTC_CHANNEL_START_BB);
|
||||
#else
|
||||
/* Disable this interrupt */
|
||||
NRF_TIMER1->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk;
|
||||
#endif
|
||||
|
||||
palTimerCb.state = PAL_TIMER_STATE_READY;
|
||||
#else
|
||||
BbCancelBod();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief TIMER2 interrupt handler dedicated to scheduler timer.
|
||||
*
|
||||
* \return None.
|
||||
* \brief TIMER1 interrupt handler dedicated to scheduler timer.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void TIMER2_IRQHandler_v(void)
|
||||
void TIMER1_IRQHandler(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG
|
||||
nrf_gpio_pin_set(PAL_TIMER_DEBUG_0_PIN);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_BUSY);
|
||||
/* Check hardware status */
|
||||
PAL_TIMER_CHECK(NRF_TIMER2->EVENTS_COMPARE[0]);
|
||||
PAL_TIMER_CHECK(NRF_TIMER2->CC[0] == palTimerCb.compareVal);
|
||||
PAL_TIMER_CHECK(NRF_TIMER2->INTENSET == TIMER_INTENSET_COMPARE0_Msk);
|
||||
PAL_TIMER_CHECK(NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB]);
|
||||
PAL_TIMER_CHECK(NRF_TIMER1->CC[TIMER_CHANNEL_START_BB] == palTimerCb.compareVal);
|
||||
PAL_TIMER_CHECK(NRF_TIMER1->INTENSET == TIMER_INTENSET_COMPARE0_Msk);
|
||||
|
||||
/* Callback function could restart TIMER2. However, we blindly stop TIMER2 first. */
|
||||
NRF_TIMER2->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk;
|
||||
/* Callback function could restart timer1. However, we blindly stop timer1 first. */
|
||||
NRF_TIMER1->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk;
|
||||
/* Clear event again just in case. */
|
||||
NRF_TIMER2->EVENTS_COMPARE[0] = 0;
|
||||
NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0;
|
||||
|
||||
palTimerCb.state = PAL_TIMER_STATE_READY;
|
||||
|
||||
|
|
@ -245,7 +355,7 @@ void TIMER2_IRQHandler_v(void)
|
|||
palTimerCb.expCback();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG
|
||||
nrf_gpio_pin_clear(PAL_TIMER_DEBUG_0_PIN);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@
|
|||
*
|
||||
* \brief TWI driver implementation.
|
||||
*
|
||||
* Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved.
|
||||
* Arm Ltd. confidential and proprietary.
|
||||
* Copyright (c) 2019-2020 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -21,11 +20,15 @@
|
|||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "stack/platform/include/pal_twi.h"
|
||||
#include "pal_twi.h"
|
||||
#include "nrfx_twim.h"
|
||||
#include "nrf_twim.h"
|
||||
#include "app_util_platform.h"
|
||||
#include <string.h>
|
||||
|
||||
#if defined(BOARD_PCA10056) | defined(BOARD_PCA10040)
|
||||
#include "boards.h"
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
|
|
@ -44,10 +47,10 @@
|
|||
#ifdef DEBUG
|
||||
|
||||
/*! \brief Parameter check. */
|
||||
#define PAL_TWI_PARAM_CHECK(expr) { if (!(expr)) { twiDevCb.drvState = PAL_TWI_STATE_ERROR; return; } }
|
||||
#define PAL_TWI_PARAM_CHECK(expr) { if (!(expr)) { palTwiCb.drvState = PAL_TWI_STATE_ERROR; return; } }
|
||||
|
||||
/*! \brief Parameter check, with return value. */
|
||||
#define PAL_TWI_PARAM_CHECK_RET(expr, rv) { if (!(expr)) { twiDevCb.drvState = PAL_TWI_STATE_ERROR; return (rv); } }
|
||||
#define PAL_TWI_PARAM_CHECK_RET(expr, rv) { if (!(expr)) { palTwiCb.drvState = PAL_TWI_STATE_ERROR; return (rv); } }
|
||||
|
||||
#else
|
||||
|
||||
|
|
@ -62,12 +65,15 @@
|
|||
/*! \brief TWI instance ID. */
|
||||
#define PAL_TWI_INSTANCE_ID 0
|
||||
|
||||
/*! \brief Pin number for SCL. */
|
||||
#define PAL_TWI_CLOCK_PIN_NUMBER (27U)
|
||||
|
||||
/*! \brief Pin number for SDA. */
|
||||
#define PAL_TWI_DATA_PIN_NUMBER (26U)
|
||||
#if defined(BOARD_PCA10056) | defined(BOARD_PCA10040)
|
||||
#define PAL_TWI_SCL_PIN ARDUINO_SCL_PIN /*!< Pin number for SCL. */
|
||||
#define PAL_TWI_SDA_PIN ARDUINO_SDA_PIN /*!< Pin number for SDA. */
|
||||
#endif
|
||||
|
||||
#if defined(BOARD_NRF6832)
|
||||
#define PAL_TWI_SCL_PIN (6U) /*!< Pin number for SCL. */
|
||||
#define PAL_TWI_SDA_PIN (7U) /*!< Pin number for SDA. */
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Type Definitions
|
||||
|
|
@ -88,8 +94,6 @@ typedef struct
|
|||
PalTwiDevConfig_t devCfg; /*!< Device configuration. */
|
||||
} PalTwiDevCtx_t;
|
||||
|
||||
#if NRFX_CHECK(NRFX_TWIM0_ENABLED)
|
||||
|
||||
/**************************************************************************************************
|
||||
Global Variables
|
||||
**************************************************************************************************/
|
||||
|
|
@ -100,8 +104,7 @@ static struct
|
|||
uint8_t curHandle; /*!< Current device handle. */
|
||||
PalTwiCmdState_t cmdState; /*!< Command transaction state, Tx or Rx. */
|
||||
PalTwiState_t drvState; /*!< Current state. */
|
||||
bool_t firstCmd; /*!< First command after operation start flag. */
|
||||
} twiDevCb;
|
||||
} palTwiCb = { 0 };
|
||||
|
||||
/*! \brief Device context table. */
|
||||
static PalTwiDevCtx_t twiDevCtx[PAL_TWI_MAX_DEVICE];
|
||||
|
|
@ -113,10 +116,10 @@ static const nrfx_twim_t twiId = NRFX_TWIM_INSTANCE(PAL_TWI_INSTANCE_ID);
|
|||
const nrfx_twim_config_t twiConfig =
|
||||
{
|
||||
.frequency = NRF_TWIM_FREQ_400K,
|
||||
.scl = PAL_TWI_CLOCK_PIN_NUMBER,
|
||||
.sda = PAL_TWI_DATA_PIN_NUMBER,
|
||||
.interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
|
||||
.hold_bus_uninit = false
|
||||
.scl = PAL_TWI_SCL_PIN,
|
||||
.sda = PAL_TWI_SDA_PIN,
|
||||
.interrupt_priority = APP_IRQ_PRIORITY_LOWEST, // TODO define in common platform BSP
|
||||
.hold_bus_uninit = FALSE
|
||||
};
|
||||
|
||||
/**************************************************************************************************
|
||||
|
|
@ -125,59 +128,59 @@ const nrfx_twim_config_t twiConfig =
|
|||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Control callback.
|
||||
* \brief Operation complete callback.
|
||||
*
|
||||
* \param event Event parameters.
|
||||
*
|
||||
* \return None.
|
||||
* \param pEvt Event parameters.
|
||||
* \param pContext Unused context.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void palTwiCallback(nrfx_twim_evt_t *event, void *pContext)
|
||||
static void palTwiCallback(nrfx_twim_evt_t *pEvt, void *pCtx)
|
||||
{
|
||||
(void)pCtx;
|
||||
|
||||
/* Pre-resolve device configuration. */
|
||||
PalTwiDevConfig_t *pCfg = &twiDevCtx[twiDevCb.curHandle].devCfg;
|
||||
PalTwiDevConfig_t *pCfg = &twiDevCtx[palTwiCb.curHandle].devCfg;
|
||||
bool_t success = FALSE;
|
||||
|
||||
twiDevCb.firstCmd = FALSE;
|
||||
|
||||
if ((event->type) == NRFX_TWIM_EVT_DONE)
|
||||
if ((pEvt->type) == NRFX_TWIM_EVT_DONE)
|
||||
{
|
||||
success = TRUE;
|
||||
}
|
||||
|
||||
if (twiDevCb.cmdState == PAL_TWI_CMD_TX_DATA)
|
||||
if (palTwiCb.cmdState == PAL_TWI_CMD_TX_DATA)
|
||||
{
|
||||
twiDevCb.cmdState = PAL_TWI_CMD_IDLE;
|
||||
palTwiCb.cmdState = PAL_TWI_CMD_IDLE;
|
||||
if (pCfg->wrCback)
|
||||
{
|
||||
pCfg->wrCback(twiDevCb.curHandle, success);
|
||||
pCfg->wrCback(palTwiCb.curHandle, success);
|
||||
}
|
||||
}
|
||||
else if (twiDevCb.cmdState == PAL_TWI_CMD_RX_DATA)
|
||||
else if (palTwiCb.cmdState == PAL_TWI_CMD_RX_DATA)
|
||||
{
|
||||
twiDevCb.cmdState = PAL_TWI_CMD_IDLE;
|
||||
palTwiCb.cmdState = PAL_TWI_CMD_IDLE;
|
||||
if (pCfg->rdCback)
|
||||
{
|
||||
pCfg->rdCback(twiDevCb.curHandle, success);
|
||||
pCfg->rdCback(palTwiCb.curHandle, success);
|
||||
}
|
||||
}
|
||||
|
||||
palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_PEND;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Initialize TWI resources.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalTwiInit(void)
|
||||
{
|
||||
if (twiDevCb.drvState != PAL_TWI_STATE_UNINIT)
|
||||
if (palTwiCb.drvState != PAL_TWI_STATE_UNINIT)
|
||||
{
|
||||
/* Only initialize once. */
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&twiDevCb, 0, sizeof(twiDevCb));
|
||||
memset(&palTwiCb, 0, sizeof(palTwiCb));
|
||||
|
||||
for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++)
|
||||
{
|
||||
|
|
@ -187,24 +190,20 @@ void PalTwiInit(void)
|
|||
twiDevCtx[handle].devCfg.wrCback = NULL;
|
||||
}
|
||||
|
||||
twiDevCb.drvState = PAL_TWI_STATE_READY;
|
||||
palTwiCb.drvState = PAL_TWI_STATE_READY;
|
||||
|
||||
nrfx_twim_init(&twiId, &twiConfig, (nrfx_twim_evt_handler_t)palTwiCallback, NULL);
|
||||
nrfx_twim_enable(&twiId);
|
||||
NVIC_ClearPendingIRQ(SPI0_TWI0_IRQn);
|
||||
NVIC_EnableIRQ(SPI0_TWI0_IRQn);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief De-Initialize the TWI resources.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalTwiDeInit(void)
|
||||
{
|
||||
PAL_TWI_PARAM_CHECK(twiDevCb.drvState != PAL_TWI_STATE_BUSY);
|
||||
PAL_TWI_PARAM_CHECK(palTwiCb.drvState == PAL_TWI_STATE_READY);
|
||||
|
||||
for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++)
|
||||
{
|
||||
|
|
@ -214,10 +213,10 @@ void PalTwiDeInit(void)
|
|||
twiDevCtx[handle].devCfg.wrCback = NULL;
|
||||
}
|
||||
|
||||
nrfx_twim_uninit(&twiId);
|
||||
nrfx_twim_disable(&twiId);
|
||||
nrfx_twim_uninit(&twiId);
|
||||
|
||||
twiDevCb.drvState = PAL_TWI_STATE_UNINIT;
|
||||
palTwiCb.drvState = PAL_TWI_STATE_UNINIT;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
|
@ -232,7 +231,6 @@ void PalTwiDeInit(void)
|
|||
uint8_t PalTwiRegisterDevice(PalTwiDevConfig_t *pDevCfg)
|
||||
{
|
||||
PAL_TWI_PARAM_CHECK_RET(pDevCfg != NULL, PAL_TWI_INVALID_ID);
|
||||
PAL_TWI_PARAM_CHECK_RET(pDevCfg->opReadyCback, PAL_TWI_INVALID_ID);
|
||||
|
||||
uint8_t retValue = PAL_TWI_INVALID_ID;
|
||||
|
||||
|
|
@ -263,7 +261,7 @@ uint8_t PalTwiRegisterDevice(PalTwiDevConfig_t *pDevCfg)
|
|||
/*************************************************************************************************/
|
||||
PalTwiState_t PalTwiGetState(void)
|
||||
{
|
||||
return twiDevCb.drvState;
|
||||
return palTwiCb.drvState;
|
||||
}
|
||||
|
||||
/**************************************************************************************************
|
||||
|
|
@ -275,28 +273,16 @@ PalTwiState_t PalTwiGetState(void)
|
|||
* \brief Always start an operation before reading or writing on TWI interface.
|
||||
*
|
||||
* \param handle Device handle.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalTwiStartOperation(uint8_t handle)
|
||||
{
|
||||
PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE);
|
||||
|
||||
if (twiDevCb.drvState != PAL_TWI_STATE_READY)
|
||||
if (palTwiCb.drvState == PAL_TWI_STATE_READY)
|
||||
{
|
||||
PAL_TWI_PARAM_CHECK(handle != twiDevCb.curHandle); /* Client operation already in progress. */
|
||||
PAL_TWI_PARAM_CHECK(twiDevCtx[handle].opPending == FALSE); /* Client already pended an operation. */
|
||||
}
|
||||
|
||||
__disable_irq();
|
||||
|
||||
if (twiDevCb.drvState == PAL_TWI_STATE_READY)
|
||||
{
|
||||
__enable_irq();
|
||||
twiDevCb.drvState = PAL_TWI_STATE_BUSY;
|
||||
twiDevCb.firstCmd = TRUE;
|
||||
twiDevCb.curHandle = handle;
|
||||
palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_PEND;
|
||||
palTwiCb.curHandle = handle;
|
||||
if (twiDevCtx[handle].devCfg.opReadyCback)
|
||||
{
|
||||
twiDevCtx[handle].devCfg.opReadyCback(handle);
|
||||
|
|
@ -304,9 +290,11 @@ void PalTwiStartOperation(uint8_t handle)
|
|||
}
|
||||
else
|
||||
{
|
||||
PAL_TWI_PARAM_CHECK(handle != palTwiCb.curHandle); /* Client operation already in progress. */
|
||||
PAL_TWI_PARAM_CHECK(twiDevCtx[handle].opPending == FALSE); /* Client already pended an operation. */
|
||||
|
||||
/* Pend the operation until current operation completes. */
|
||||
twiDevCtx[handle].opPending = TRUE;
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -315,29 +303,18 @@ void PalTwiStartOperation(uint8_t handle)
|
|||
* \brief Always stop an operation after reading or writing on TWI interface.
|
||||
*
|
||||
* \param handle Device handle.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalTwiStopOperation(uint8_t handle)
|
||||
{
|
||||
PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE);
|
||||
PAL_TWI_PARAM_CHECK(handle == twiDevCb.curHandle);
|
||||
PAL_TWI_PARAM_CHECK(twiDevCb.cmdState == PAL_TWI_CMD_IDLE);
|
||||
PAL_TWI_PARAM_CHECK(twiDevCb.drvState == PAL_TWI_STATE_BUSY);
|
||||
PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle);
|
||||
PAL_TWI_PARAM_CHECK(palTwiCb.cmdState == PAL_TWI_CMD_IDLE);
|
||||
PAL_TWI_PARAM_CHECK(palTwiCb.drvState == PAL_TWI_STATE_BUSY_DATA_PEND);
|
||||
|
||||
unsigned int nextHandle = PAL_TWI_GET_NEXT_HANDLE(handle);
|
||||
|
||||
twiDevCb.curHandle = PAL_TWI_INVALID_ID;
|
||||
|
||||
/* Only when address or command is sent, then issue stop. */
|
||||
if (!twiDevCb.firstCmd)
|
||||
{
|
||||
nrf_twim_event_clear(twiId.p_twim, NRF_TWIM_EVENT_STOPPED);
|
||||
nrf_twim_task_trigger(twiId.p_twim, NRF_TWIM_TASK_RESUME);
|
||||
nrf_twim_task_trigger(twiId.p_twim, NRF_TWIM_TASK_STOP);
|
||||
nrf_twim_int_disable(twiId.p_twim, 0xFFFFFFFF);
|
||||
}
|
||||
palTwiCb.curHandle = PAL_TWI_INVALID_ID;
|
||||
|
||||
while (nextHandle != handle)
|
||||
{
|
||||
|
|
@ -346,13 +323,13 @@ void PalTwiStopOperation(uint8_t handle)
|
|||
/* Set the operation pending to FALSE first in case of race condition. */
|
||||
twiDevCtx[nextHandle].opPending = FALSE;
|
||||
|
||||
twiDevCb.firstCmd = TRUE;
|
||||
twiDevCb.curHandle = nextHandle;
|
||||
palTwiCb.curHandle = nextHandle;
|
||||
if (twiDevCtx[nextHandle].devCfg.opReadyCback)
|
||||
{
|
||||
twiDevCtx[nextHandle].devCfg.opReadyCback(nextHandle);
|
||||
}
|
||||
|
||||
/* Remain in BUSY state. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -360,7 +337,32 @@ void PalTwiStopOperation(uint8_t handle)
|
|||
}
|
||||
|
||||
/* No pending operations. */
|
||||
twiDevCb.drvState = PAL_TWI_STATE_READY;
|
||||
palTwiCb.drvState = PAL_TWI_STATE_READY;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Read data from TWI interface.
|
||||
*
|
||||
* \param handle Device handle.
|
||||
* \param pData Read buffer.
|
||||
* \param len Number of bytes to write.
|
||||
*
|
||||
* Read \a len bytes from \a pData to the TWI device.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalTwiReadData(uint8_t handle, uint8_t *pData, uint8_t len)
|
||||
{
|
||||
PAL_TWI_PARAM_CHECK(len != 0);
|
||||
PAL_TWI_PARAM_CHECK(pData != NULL);
|
||||
PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE);
|
||||
PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle);
|
||||
|
||||
palTwiCb.curHandle =handle;
|
||||
palTwiCb.cmdState = PAL_TWI_CMD_RX_DATA;
|
||||
palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_XFER;
|
||||
|
||||
nrfx_twim_rx(&twiId, twiDevCtx[handle].devCfg.devAddr, pData, len);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
|
@ -371,8 +373,6 @@ void PalTwiStopOperation(uint8_t handle)
|
|||
* \param pData Write buffer.
|
||||
* \param len Number of bytes to write.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* Transfer \a len bytes from \a pData to the TWI device.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
|
@ -381,43 +381,15 @@ void PalTwiWriteData(uint8_t handle, const uint8_t *pData, uint8_t len)
|
|||
PAL_TWI_PARAM_CHECK(len != 0);
|
||||
PAL_TWI_PARAM_CHECK(pData != NULL);
|
||||
PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE);
|
||||
PAL_TWI_PARAM_CHECK(handle == twiDevCb.curHandle);
|
||||
PAL_TWI_PARAM_CHECK(twiDevCb.drvState == PAL_TWI_STATE_BUSY);
|
||||
PAL_TWI_PARAM_CHECK(twiDevCb.cmdState == PAL_TWI_CMD_IDLE);
|
||||
PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle);
|
||||
|
||||
twiDevCb.curHandle = handle;
|
||||
twiDevCb.cmdState = PAL_TWI_CMD_TX_DATA;
|
||||
palTwiCb.curHandle = handle;
|
||||
palTwiCb.cmdState = PAL_TWI_CMD_TX_DATA;
|
||||
palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_XFER;
|
||||
|
||||
nrfx_twim_tx(&twiId, twiDevCtx[handle].devCfg.devAddr, pData, len, NRFX_TWIM_FLAG_TX_NO_STOP);
|
||||
nrfx_err_t err = nrfx_twim_tx(&twiId, twiDevCtx[handle].devCfg.devAddr, pData, len, NRFX_TWIM_FLAG_TX_NO_STOP);
|
||||
PAL_TWI_PARAM_CHECK(err == NRFX_SUCCESS);
|
||||
#ifndef DEBUG
|
||||
(void)err;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Read data from TWI interface.
|
||||
*
|
||||
* \param handle Device handle.
|
||||
* \param pData Write buffer.
|
||||
* \param len Number of bytes to write.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* Read \a len bytes from \a pData to the TWI device.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalTwiReadData(uint8_t handle, uint8_t *pData, uint8_t len)
|
||||
{
|
||||
PAL_TWI_PARAM_CHECK(len != 0);
|
||||
PAL_TWI_PARAM_CHECK(pData != NULL);
|
||||
PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE);
|
||||
PAL_TWI_PARAM_CHECK(handle == twiDevCb.curHandle);
|
||||
PAL_TWI_PARAM_CHECK(twiDevCb.drvState == PAL_TWI_STATE_BUSY);
|
||||
PAL_TWI_PARAM_CHECK(twiDevCb.cmdState == PAL_TWI_CMD_IDLE);
|
||||
|
||||
twiDevCb.curHandle =handle;
|
||||
twiDevCb.cmdState = PAL_TWI_CMD_RX_DATA;
|
||||
|
||||
nrfx_twim_rx(&twiId, twiDevCtx[handle].devCfg.devAddr, pData, len);
|
||||
}
|
||||
|
||||
#endif // NRFX_CHECK(NRFX_TWIM0_ENABLED)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@
|
|||
*
|
||||
* \brief UART driver definition.
|
||||
*
|
||||
* Copyright (c) 2018-2019 ARM Ltd. All Rights Reserved.
|
||||
* ARM Ltd. confidential and proprietary.
|
||||
* Copyright (c) 2019-2020 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -21,237 +20,196 @@
|
|||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "stack/platform/include/pal_uart.h"
|
||||
#include "sdk_config.h"
|
||||
#include "pal_uart.h"
|
||||
#include "nrfx_uarte.h"
|
||||
#include "boards.h"
|
||||
|
||||
#if NRFX_CHECK(NRFX_UARTE0_ENABLED)
|
||||
#if defined(BOARD_NRF6832)
|
||||
#define RX_PIN_NUMBER 26
|
||||
#define TX_PIN_NUMBER 27
|
||||
#define CTS_PIN_NUMBER 0xFF
|
||||
#define RTS_PIN_NUMBER 0xFF
|
||||
#else
|
||||
#include "boards.h"
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
Type definitions
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief Control block. */
|
||||
typedef struct
|
||||
{
|
||||
PalUartState_t state; /*!< UART state. */
|
||||
PalUartConfig_t config; /*!< UART configuration. */
|
||||
nrfx_uarte_t inst; /*!< nRF UART driver instance. */
|
||||
} palUartCtrlBlk_t;
|
||||
|
||||
/**************************************************************************************************
|
||||
Local Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
#define PAL_UART_INVALID_INSTANCE_NUM 0xFF
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
/*! \brief Parameter check. */
|
||||
#define PAL_UART_PARAM_CHECK(num, expr) { if (!(expr)) { palUartCb[num].state = PAL_UART_STATE_ERROR; while(1){}; } }
|
||||
#define PAL_UART_PARAM_CHECK(p, expr) { if (!(expr)) { p->state = PAL_UART_STATE_ERROR; return; } }
|
||||
|
||||
#else
|
||||
|
||||
/*! \brief Parameter check (disabled). */
|
||||
#define PAL_UART_PARAM_CHECK(num, expr)
|
||||
#define PAL_UART_PARAM_CHECK(p, expr)
|
||||
|
||||
#endif
|
||||
|
||||
/*! \brief Control block. */
|
||||
static struct
|
||||
{
|
||||
PalUartId_t id; /*!< PAL UART id. */
|
||||
PalUartConfig_t config; /*!< PAL UART configuration. */
|
||||
PalUartState_t state; /*!< PAL UART state. */
|
||||
nrfx_uarte_t uart; /*!< NRF UART driver instance */
|
||||
} palUartCb[NRFX_UARTE0_ENABLED + NRFX_UARTE1_ENABLED] = {{0, {0}, 0, {NRF_UARTE0, NRFX_UARTE0_INST_IDX}}};
|
||||
static palUartCtrlBlk_t palUartCb[2];
|
||||
|
||||
/**************************************************************************************************
|
||||
Local Functions
|
||||
**************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get UART instance number from UART ID.
|
||||
*
|
||||
* \param uartId UART ID.
|
||||
* \param id UART ID.
|
||||
*
|
||||
* \return UART instance number.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t palUartGetNum(PalUartId_t uartId)
|
||||
static palUartCtrlBlk_t *palUartGetContext(PalUartId_t id)
|
||||
{
|
||||
uint8_t uartNum;
|
||||
/* Nordic platform has total two UART instances.
|
||||
* By default, only UART0 is enabled.
|
||||
*/
|
||||
switch (uartId)
|
||||
switch (id)
|
||||
{
|
||||
case PAL_UART_ID_CHCI:
|
||||
uartNum = 0;
|
||||
break;
|
||||
case PAL_UART_ID_TERMINAL:
|
||||
uartNum = 0;
|
||||
break;
|
||||
return &palUartCb[0];
|
||||
|
||||
case PAL_UART_ID_USER:
|
||||
uartNum = 0;
|
||||
break;
|
||||
return (NRFX_UARTE_ENABLED_COUNT > 1) ? &palUartCb[1] : &palUartCb[0];
|
||||
|
||||
default:
|
||||
uartNum = PAL_UART_INVALID_INSTANCE_NUM;
|
||||
break;
|
||||
}
|
||||
|
||||
return uartNum;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Set UART baud rate.
|
||||
*
|
||||
* \param baud Baud rate.
|
||||
*
|
||||
* \return nrf baud rate.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static nrf_uarte_baudrate_t palUartSetBaud(uint32_t baud)
|
||||
{
|
||||
nrf_uarte_baudrate_t baudRate;
|
||||
|
||||
switch (baud)
|
||||
{
|
||||
default:
|
||||
case 115200:
|
||||
baudRate = NRF_UARTE_BAUDRATE_115200;
|
||||
break;
|
||||
case 230400:
|
||||
baudRate = NRF_UARTE_BAUDRATE_230400;
|
||||
break;
|
||||
case 460800:
|
||||
baudRate = NRF_UARTE_BAUDRATE_460800;
|
||||
break;
|
||||
case 921600:
|
||||
baudRate = NRF_UARTE_BAUDRATE_921600;
|
||||
break;
|
||||
case 1000000:
|
||||
baudRate = NRF_UARTE_BAUDRATE_1000000;
|
||||
break;
|
||||
}
|
||||
|
||||
return baudRate;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief UART NRF event handler.
|
||||
*
|
||||
* \param pEvent Pointer to event.
|
||||
* \param pContext Pointer to event context.
|
||||
*
|
||||
* \return None.
|
||||
* \param pEvent UART event.
|
||||
* \param pContext Instance context.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void palUartEventHandler(nrfx_uarte_event_t *pEvent, void *pContext)
|
||||
static void palUartEventHandler(nrfx_uarte_event_t const *pEvent, void *pInstCtx)
|
||||
{
|
||||
uint8_t uartNum = palUartGetNum(*(PalUartId_t *)pContext);
|
||||
palUartCtrlBlk_t *pCtx = (palUartCtrlBlk_t *)pInstCtx;
|
||||
|
||||
switch (pEvent->type)
|
||||
{
|
||||
case NRFX_UARTE_EVT_RX_DONE:
|
||||
if (palUartCb[uartNum].config.rdCback != NULL)
|
||||
if (pCtx->config.rdCback != NULL)
|
||||
{
|
||||
palUartCb[uartNum].config.rdCback();
|
||||
pCtx->config.rdCback();
|
||||
}
|
||||
break;
|
||||
case NRFX_UARTE_EVT_TX_DONE:
|
||||
palUartCb[uartNum].state = PAL_UART_STATE_READY;
|
||||
if (palUartCb[uartNum].config.wrCback != NULL)
|
||||
pCtx->state = PAL_UART_STATE_READY;
|
||||
if (pCtx->config.wrCback != NULL)
|
||||
{
|
||||
palUartCb[uartNum].config.wrCback();
|
||||
pCtx->config.wrCback();
|
||||
}
|
||||
break;
|
||||
case NRFX_UARTE_EVT_ERROR:
|
||||
palUartCb[uartNum].state = PAL_UART_STATE_ERROR;
|
||||
pCtx->state = PAL_UART_STATE_ERROR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************************************
|
||||
Global Functions
|
||||
**************************************************************************************************/
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Initialize UART.
|
||||
*
|
||||
* \param id UART Id.
|
||||
* \param id UART ID.
|
||||
* \param pCfg Peripheral configuration.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* Initialize UART peripheral with \a pCfg values.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
void PalUartInit(PalUartId_t id, const PalUartConfig_t *pCfg)
|
||||
{
|
||||
uint8_t uartNum = palUartGetNum(id);
|
||||
palUartCtrlBlk_t *pCtx = palUartGetContext(id);
|
||||
PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL);
|
||||
PAL_UART_PARAM_CHECK(pCtx, pCfg != NULL);
|
||||
|
||||
if (uartNum == PAL_UART_INVALID_INSTANCE_NUM)
|
||||
pCtx->config = *pCfg;
|
||||
|
||||
/* Resolve instance. */
|
||||
switch (pCtx - palUartCb)
|
||||
{
|
||||
return;
|
||||
default:
|
||||
case 0:
|
||||
pCtx->inst.p_reg = NRF_UARTE0;
|
||||
pCtx->inst.drv_inst_idx = 0;
|
||||
break;
|
||||
#if (NRFX_UARTE1_ENABLED)
|
||||
case 1:
|
||||
pCtx->inst.p_reg = NRF_UARTE1;
|
||||
pCtx->inst.drv_inst_idx = 1;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
palUartCb[uartNum].id = id;
|
||||
nrfx_uarte_config_t nrfCfg = NRFX_UARTE_DEFAULT_CONFIG;
|
||||
nrfCfg.pselrxd = RX_PIN_NUMBER;
|
||||
nrfCfg.pseltxd = TX_PIN_NUMBER;
|
||||
nrfCfg.pselcts = CTS_PIN_NUMBER;
|
||||
nrfCfg.pselrts = RTS_PIN_NUMBER;
|
||||
nrfCfg.p_context = pCtx;
|
||||
nrfCfg.parity = NRF_UARTE_PARITY_EXCLUDED;
|
||||
nrfCfg.interrupt_priority = 0xFF; /* Lowest priority. */
|
||||
nrfCfg.hwfc = pCfg->hwFlow ? NRF_UARTE_HWFC_ENABLED : NRF_UARTE_HWFC_DISABLED;
|
||||
|
||||
PAL_UART_PARAM_CHECK(uartNum, pCfg != NULL);
|
||||
switch (pCfg->baud)
|
||||
{
|
||||
default:
|
||||
case 115200: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_115200; break;
|
||||
case 230400: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_230400; break;
|
||||
case 460800: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_460800; break;
|
||||
case 921600: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_921600; break;
|
||||
case 1000000: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_1000000; break;
|
||||
}
|
||||
|
||||
palUartCb[uartNum].config = *pCfg;
|
||||
|
||||
/* Configure UART. */
|
||||
nrfx_uarte_config_t nrfConfig = NRFX_UARTE_DEFAULT_CONFIG;
|
||||
nrfConfig.pselrxd = RX_PIN_NUMBER;
|
||||
nrfConfig.pseltxd = TX_PIN_NUMBER;
|
||||
nrfConfig.pselcts = CTS_PIN_NUMBER;
|
||||
nrfConfig.pselrts = RTS_PIN_NUMBER;
|
||||
nrfConfig.p_context = &(palUartCb[uartNum].id);
|
||||
nrfConfig.parity = NRF_UARTE_PARITY_EXCLUDED;
|
||||
nrfConfig.interrupt_priority = 0xFF; /* Lowest priority. */
|
||||
|
||||
nrfConfig.baudrate = palUartSetBaud(pCfg->baud);
|
||||
nrfConfig.hwfc = pCfg->hwFlow ? NRF_UARTE_HWFC_ENABLED : NRF_UARTE_HWFC_DISABLED;
|
||||
|
||||
/* Make sure UART is uninitialized. */
|
||||
nrfx_uarte_uninit(&(palUartCb[uartNum].uart));
|
||||
|
||||
/* Initialize UART. */
|
||||
nrfx_err_t err_code = nrfx_uarte_init(&(palUartCb[uartNum].uart), &nrfConfig, (nrfx_uarte_event_handler_t)palUartEventHandler);
|
||||
|
||||
//this is for uart only not for uarte
|
||||
//nrfx_uart_rx_enable(&palUartCb[uartNum].uart);
|
||||
nrfx_err_t err_code = nrfx_uarte_init(&(pCtx->inst), &nrfCfg, palUartEventHandler);
|
||||
|
||||
if (err_code != NRFX_SUCCESS)
|
||||
{
|
||||
palUartCb[uartNum].state = PAL_UART_STATE_ERROR;
|
||||
pCtx->state = PAL_UART_STATE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
palUartCb[uartNum].state = PAL_UART_STATE_READY;
|
||||
|
||||
NVIC_EnableIRQ(UART0_IRQn);
|
||||
pCtx->state = PAL_UART_STATE_READY;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief De-Initialize UART.
|
||||
*
|
||||
* \param id UART id.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* De-Initialize UART.
|
||||
* \param id UART ID.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalUartDeInit(PalUartId_t id)
|
||||
{
|
||||
uint8_t uartNum = palUartGetNum(id);
|
||||
palUartCtrlBlk_t *pCtx = palUartGetContext(id);
|
||||
PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL);
|
||||
PAL_UART_PARAM_CHECK(pCtx, pCtx->state == PAL_UART_STATE_READY);
|
||||
|
||||
if (uartNum == PAL_UART_INVALID_INSTANCE_NUM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
nrfx_uarte_uninit(&pCtx->inst);
|
||||
|
||||
nrfx_uarte_uninit(&(palUartCb[uartNum].uart));
|
||||
|
||||
palUartCb[uartNum].state = PAL_UART_STATE_UNINIT;
|
||||
pCtx->state = PAL_UART_STATE_UNINIT;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
|
@ -260,81 +218,62 @@ void PalUartDeInit(PalUartId_t id)
|
|||
*
|
||||
* \param id UART id.
|
||||
*
|
||||
* \return Current state.
|
||||
*
|
||||
* Return the current state.
|
||||
* \return Current state.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
PalUartState_t PalUartGetState(PalUartId_t id)
|
||||
{
|
||||
uint8_t uartNum = palUartGetNum(id);
|
||||
palUartCtrlBlk_t *pCtx = palUartGetContext(id);
|
||||
|
||||
if (uartNum == PAL_UART_INVALID_INSTANCE_NUM)
|
||||
if (pCtx == NULL)
|
||||
{
|
||||
return PAL_UART_STATE_ERROR;
|
||||
}
|
||||
|
||||
return palUartCb[uartNum].state;
|
||||
return pCtx->state;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Read data from Rx FIFO.
|
||||
*
|
||||
* \param id UART id.
|
||||
* \param id UART ID.
|
||||
* \param pData Read buffer.
|
||||
* \param len Number of bytes to read.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* Store \a len received bytes in \a pData. After \a len is transferred, call
|
||||
* \a UartInitInfo_t::rdCback to signal read completion. Alway call this function to setup buffer
|
||||
* when boot up or after a reading is done
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalUartReadData(PalUartId_t id, uint8_t *pData, uint16_t len)
|
||||
{
|
||||
uint8_t uartNum = palUartGetNum(id);
|
||||
palUartCtrlBlk_t *pCtx = palUartGetContext(id);
|
||||
PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL);
|
||||
PAL_UART_PARAM_CHECK(pCtx, pCtx->state != PAL_UART_STATE_UNINIT);
|
||||
PAL_UART_PARAM_CHECK(pCtx, pData != NULL);
|
||||
PAL_UART_PARAM_CHECK(pCtx, len > 0);
|
||||
|
||||
PAL_UART_PARAM_CHECK(uartNum, pData != NULL);
|
||||
PAL_UART_PARAM_CHECK(uartNum, len > 0);
|
||||
PAL_UART_PARAM_CHECK(uartNum, palUartCb[uartNum].state != PAL_UART_STATE_UNINIT);
|
||||
|
||||
if (uartNum == PAL_UART_INVALID_INSTANCE_NUM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
nrfx_uarte_rx(&(palUartCb[uartNum].uart), pData, (uint16_t)len);
|
||||
nrfx_err_t err = nrfx_uarte_rx(&pCtx->inst, pData, len);
|
||||
PAL_UART_PARAM_CHECK(pCtx, err == NRFX_SUCCESS);
|
||||
(void)err;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Write data to Tx FIFO.
|
||||
*
|
||||
* \param id UART id.
|
||||
* \param id UART ID.
|
||||
* \param pData Write buffer.
|
||||
* \param len Number of bytes to write.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
* Assign buffer and length and transmit data.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PalUartWriteData(PalUartId_t id, const uint8_t *pData, uint16_t len)
|
||||
{
|
||||
uint8_t uartNum = palUartGetNum(id);
|
||||
palUartCtrlBlk_t *pCtx = palUartGetContext(id);
|
||||
PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL);
|
||||
PAL_UART_PARAM_CHECK(pCtx, pCtx->state != PAL_UART_STATE_UNINIT);
|
||||
PAL_UART_PARAM_CHECK(pCtx, pData != NULL);
|
||||
PAL_UART_PARAM_CHECK(pCtx, len > 0);
|
||||
|
||||
PAL_UART_PARAM_CHECK(uartNum, pData != NULL);
|
||||
PAL_UART_PARAM_CHECK(uartNum, len > 0);
|
||||
PAL_UART_PARAM_CHECK(uartNum, palUartCb[uartNum].state == PAL_UART_STATE_READY);
|
||||
|
||||
if (uartNum == PAL_UART_INVALID_INSTANCE_NUM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
nrfx_uarte_tx(&(palUartCb[uartNum].uart), pData, (uint16_t)len);
|
||||
palUartCb[uartNum].state = PAL_UART_STATE_BUSY;
|
||||
pCtx->state = PAL_UART_STATE_BUSY;
|
||||
nrfx_err_t err = nrfx_uarte_tx(&pCtx->inst, pData, len);
|
||||
PAL_UART_PARAM_CHECK(pCtx, err == NRFX_SUCCESS);
|
||||
(void)err;
|
||||
}
|
||||
|
||||
#endif // NRFX_CHECK(NRFX_UARTE0_ENABLED)
|
||||
|
|
|
|||
Loading…
Reference in New Issue