update nrf cordio ll files

pull/13228/head
Paul Szczeanek 2020-06-10 13:16:21 +01:00 committed by Vincent Coubard
parent 568d0a287e
commit 7f23b6df0f
12 changed files with 1852 additions and 1316 deletions

View File

@ -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 */

View File

@ -7,6 +7,8 @@
* Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved.
* ARM confidential and proprietary. * ARM confidential and proprietary.
* *
* Copyright (c) 2019-2020 Packetcraft, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
@ -21,8 +23,9 @@
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
#include "stack/platform/include/pal_types.h" #include "pal_types.h"
#include "stack/platform/include/pal_bb.h" #include "pal_bb.h"
#include "pal_bb.h"
#include "nrf.h" #include "nrf.h"
#include "nrf_timer.h" #include "nrf_timer.h"
#include <string.h> #include <string.h>
@ -51,8 +54,6 @@ static bbDrvIrqCback_t palBbRadioIrqCbackTbl[BB_PROT_NUM];
/*! /*!
* \brief Initialize the baseband driver. * \brief Initialize the baseband driver.
* *
* \return None.
*
* One-time initialization of baseband resources. This routine can be used to setup baseband * One-time initialization of baseband resources. This routine can be used to setup baseband
* resources, load RF trim parameters and execute RF calibrations. * resources, load RF trim parameters and execute RF calibrations.
* *
@ -63,6 +64,10 @@ void PalBbInit(void)
{ {
palBbEnableCnt = 0; 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(palBbTimerIrqCbackTbl, 0, sizeof(palBbTimerIrqCbackTbl));
memset(palBbRadioIrqCbackTbl, 0, sizeof(palBbRadioIrqCbackTbl)); memset(palBbRadioIrqCbackTbl, 0, sizeof(palBbRadioIrqCbackTbl));
} }
@ -71,8 +76,6 @@ void PalBbInit(void)
/*! /*!
* \brief Enable the BB hardware. * \brief Enable the BB hardware.
* *
* \return None.
*
* This routine brings the BB hardware out of low power (enable power and clocks) just before a * This routine brings the BB hardware out of low power (enable power and clocks) just before a
* first BB operation is executed. * first BB operation is executed.
*/ */
@ -86,15 +89,13 @@ void PalBbEnable(void)
/*! /*!
* \brief Disable the BB hardware. * \brief Disable the BB hardware.
* *
* \return None.
*
* This routine signals the BB hardware to go into low power (disable power and clocks) after all * This routine signals the BB hardware to go into low power (disable power and clocks) after all
* BB operations have been disabled. * BB operations have been disabled.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalBbDisable(void) void PalBbDisable(void)
{ {
if(palBbEnableCnt) if (palBbEnableCnt)
{ {
palBbEnableCnt--; palBbEnableCnt--;
} }
@ -105,8 +106,6 @@ void PalBbDisable(void)
* \brief Load BB timing configuration. * \brief Load BB timing configuration.
* *
* \param pCfg Return configuration values. * \param pCfg Return configuration values.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalBbLoadCfg(PalBbCfg_t *pCfg) void PalBbLoadCfg(PalBbCfg_t *pCfg)
@ -115,27 +114,34 @@ void PalBbLoadCfg(PalBbCfg_t *pCfg)
pCfg->rfSetupDelayUsec = BB_RF_SETUP_DELAY_US; pCfg->rfSetupDelayUsec = BB_RF_SETUP_DELAY_US;
pCfg->maxScanPeriodMsec = BB_MAX_SCAN_PERIOD_MS; pCfg->maxScanPeriodMsec = BB_MAX_SCAN_PERIOD_MS;
pCfg->schSetupDelayUsec = BB_SCH_SETUP_DELAY_US; 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. * \brief Get the current BB clock value in microseconds.
*
* \param useRtcBBClk Use RTC BB clock.
* *
* \return Current BB clock value, units are microseconds. * \return Current BB clock value, units are microseconds.
* *
* This routine reads the current value from the BB clock and returns its value. * 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 (palBbEnableCnt > 0)
{ {
if (useRtcBBClk) if (USE_RTC_BB_CLK)
{ {
/* return the RTC counter value */ /* return the RTC counter value */
return NRF_RTC0->COUNTER; return BB_TICKS_TO_US(NRF_RTC1->COUNTER);
} }
else else
{ {
@ -143,7 +149,7 @@ uint32_t PalBbGetCurrentTime(bool_t useRtcBBClk)
nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3);
/* Read and return the captured count value from capture register 3 */ /* 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; 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. * \param pTime Pointer to return the current time.
* *
@ -167,11 +173,22 @@ bool_t PalBbGetTimestamp(uint32_t *pTime)
{ {
if (palBbEnableCnt == 0) if (palBbEnableCnt == 0)
{ {
*pTime = 0;
return FALSE; 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; return TRUE;
} }
@ -183,8 +200,6 @@ bool_t PalBbGetTimestamp(uint32_t *pTime)
* \param protId Protocol ID. * \param protId Protocol ID.
* \param timerCback Timer IRQ callback. * \param timerCback Timer IRQ callback.
* \param radioCback Timer IRQ callback. * \param radioCback Timer IRQ callback.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalBbRegisterProtIrq(uint8_t protId, bbDrvIrqCback_t timerCback, bbDrvIrqCback_t radioCback) 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. * \brief Set protocol ID.
* *
* \param protId Protocol ID. * \param protId Protocol ID.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalBbSetProtId(uint8_t protId) void PalBbSetProtId(uint8_t protId)
@ -210,8 +223,6 @@ void PalBbSetProtId(uint8_t protId)
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Combined BLE and 154 radio interrupt handler. * \brief Combined BLE and 154 radio interrupt handler.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void RADIO_IRQHandler(void) void RADIO_IRQHandler(void)
@ -225,8 +236,6 @@ void RADIO_IRQHandler(void)
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Combined BLE and 154 timer interrupt handler. * \brief Combined BLE and 154 timer interrupt handler.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void TIMER0_IRQHandler(void) void TIMER0_IRQHandler(void)

View File

@ -5,7 +5,8 @@
* \brief BLE RF path compensation implementation file. * \brief BLE RF path compensation implementation file.
* *
* Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 Macros
@ -45,18 +46,18 @@
#if defined(NRF52840_XXAA) || defined(NRF52832_XXAA) #if defined(NRF52840_XXAA) || defined(NRF52832_XXAA)
/* \brief Minimum Tx power level (expressed in 1dBm units). */ /* \brief Minimum Tx power level (expressed in 1dBm units). */
static const int16_t bbBleMinTxPwr = -40; /* -40dBm */ static const int8_t bbBleMinTxPwr = -40; /* -40dBm */
#else #else
/* \brief Minimum Tx power level (expressed in 1dBm units). */ /* \brief Minimum Tx power level (expressed in 1dBm units). */
static const int16_t bbBleMinTxPwr = -30; /* -30dBm */ static const int8_t bbBleMinTxPwr = -30; /* -30dBm */
#endif #endif
#if defined(NRF52840_XXAA) #if defined(NRF52840_XXAA)
/* \brief Maximum Tx power level (expressed in 1dBm units). */ /* \brief Maximum Tx power level (expressed in 1dBm units). */
static const int16_t bbBleMaxTxPwr = 9; /* +9dBm */ static const int8_t bbBleMaxTxPwr = 9; /* +9dBm */
#else #else
/* \brief Maximum Tx power level (expressed in 1dBm units). */ /* \brief Maximum Tx power level (expressed in 1dBm units). */
static const int16_t bbBleMaxTxPwr = 4; /* +4dBm */ static const int8_t bbBleMaxTxPwr = 4; /* +4dBm */
#endif #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). * \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); 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; 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. * \brief Initialize RF path compensation.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalRadioInitPathComp(void) void PalRadioInitPathComp(void)
@ -116,8 +101,6 @@ void PalRadioInitPathComp(void)
* *
* \param pMinTxPwr Return buffer for minimum transmit power (expressed in 1dBm units). * \param pMinTxPwr Return buffer for minimum transmit power (expressed in 1dBm units).
* \param pMaxTxPwr Return buffer for maximum 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) 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 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). * \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) void PalRadioReadRfPathComp(int16_t *pTxPathComp, int16_t *pRxPathComp)
@ -214,8 +195,109 @@ int8_t PalRadioGetActualTxPower(int8_t txPwr, bool_t compFlag)
if (compFlag) if (compFlag)
{ {
txPwr += palBbBleRfGetTxRfPathComp(); txPwr += PalRadioGetRxRfPathComp();
} }
return txPwr; 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;
}

View File

@ -5,7 +5,8 @@
* \brief System configuration definition. * \brief System configuration definition.
* *
* Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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" #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 Type Definitions
**************************************************************************************************/ **************************************************************************************************/
@ -71,13 +52,17 @@ typedef struct
/* ISO */ /* ISO */
uint8_t numIsoTxBuf; /*!< Default number of ISO transmit buffers. */ uint8_t numIsoTxBuf; /*!< Default number of ISO transmit buffers. */
uint8_t numIsoRxBuf; /*!< Default number of ISO receive 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. */ uint16_t maxIsoPduLen; /*!< Maximum ISO PDU size between controllers. */
/* CIS */ /* CIS */
uint8_t maxCig; /*!< Maximum number of CIG. */ uint8_t maxCig; /*!< Maximum number of CIG. */
uint8_t maxCis; /*!< Maximum number of CIS. */ uint8_t maxCis; /*!< Maximum number of CIS, it is shared by the CIGs. */
uint16_t subEvtSpaceDelay; /*!< Subevent spacing above T_MSS. */ uint16_t cisSubEvtSpaceDelay; /*!< Subevent spacing above T_MSS. */
/* BIS*/
uint8_t maxBig; /*!< Maximum number of BIG. */
uint8_t maxBis; /*!< Maximum number of BIS. */
/* DTM */ /* DTM */
uint16_t dtmRxSyncMs; /*!< DTM Rx synchronization window in milliseconds. */ uint16_t dtmRxSyncMs; /*!< DTM Rx synchronization window in milliseconds. */
} PalCfgLl_t; } PalCfgLl_t;
@ -102,14 +87,12 @@ typedef struct
* \param phyCodedSup Coded PHY supported. * \param phyCodedSup Coded PHY supported.
* \param stableModIdxTxSup Tx stable modulation index supported. * \param stableModIdxTxSup Tx stable modulation index supported.
* \param stableModIdxRxSup Rx stable modulation index supported. * \param stableModIdxRxSup Rx stable modulation index supported.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void palCfgGetBlePhyFeatures(uint8_t *pPhy2mSup, uint8_t *pPhyCodedSup, void palCfgGetBlePhyFeatures(uint8_t *pPhy2mSup, uint8_t *pPhyCodedSup,
uint8_t *pStableModIdxTxSup, uint8_t *pStableModIdxRxSup) uint8_t *pStableModIdxTxSup, uint8_t *pStableModIdxRxSup)
{ {
#if defined(NRF52840_XXAA) #if defined(NRF52840_XXAA) || defined(NRF52832_XXAA)
*pPhy2mSup = TRUE; *pPhy2mSup = TRUE;
*pPhyCodedSup = TRUE; *pPhyCodedSup = TRUE;
#else #else
@ -125,42 +108,55 @@ void palCfgGetBlePhyFeatures(uint8_t *pPhy2mSup, uint8_t *pPhyCodedSup,
* \brief Load LL advertising configuration. * \brief Load LL advertising configuration.
* *
* \param pConfig Return configuration values. * \param pConfig Return configuration values.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void palCfgLoadLlParams(uint8_t *pConfig) void palCfgLoadLlParams(uint8_t *pConfig)
{ {
PalCfgLl_t *pCfg = (PalCfgLl_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 advDataLen = 512;
const uint16_t connDataLen = 256; const uint16_t aclDataLen = 512;
const uint16_t numTxBufs = 8; const uint16_t maxConn = 1;
#else const uint16_t maxGroup = 1;
const uint16_t advDataLen = LL_MAX_ADV_DATA_LEN; const uint16_t maxStream = 2;
const uint16_t connDataLen = 512; #else /* Default */
const uint16_t numTxBufs = 16; const uint16_t maxAdvSets = 6;
#endif 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->maxAdvSets = maxAdvSets;
pCfg->maxAdvReports = 16; pCfg->maxAdvReports = 8;
pCfg->maxExtAdvDataLen = advDataLen; pCfg->maxExtAdvDataLen = advDataLen;
/* pCfg->defExtAdvDataFragLen */ /* Use default. */ /* pCfg->defExtAdvDataFragLen */ /* Use default. */
pCfg->auxDelayUsec = 0; pCfg->auxDelayUsec = 0;
pCfg->maxScanReqRcvdEvt = 4; pCfg->maxScanReqRcvdEvt = 4;
pCfg->maxExtScanDataLen = advDataLen; pCfg->maxExtScanDataLen = advDataLen;
pCfg->maxConn = 4; pCfg->maxConn = maxConn;
pCfg->maxAclLen = connDataLen; pCfg->maxAclLen = aclDataLen;
pCfg->numTxBufs = numTxBufs; pCfg->numTxBufs = 16;
pCfg->numRxBufs = 8; pCfg->numRxBufs = 8;
pCfg->numIsoTxBuf = 6; pCfg->numIsoTxBuf = 16;
pCfg->numIsoRxBuf = 6; pCfg->numIsoRxBuf = 8;
pCfg->maxIsoBufLen = 251; pCfg->maxIsoSduLen = aclDataLen;
pCfg->maxIsoPduLen = 64; pCfg->maxIsoPduLen = 251;
pCfg->maxCig = LL_MAX_CIG; pCfg->maxCig = maxGroup;
pCfg->maxCis = LL_MAX_CIS; pCfg->maxCis = maxStream;
pCfg->subEvtSpaceDelay = 0; pCfg->cisSubEvtSpaceDelay = 0;
pCfg->maxBig = maxGroup;
pCfg->maxBis = maxStream;
} }
/*************************************************************************************************/ /*************************************************************************************************/
@ -168,8 +164,6 @@ void palCfgLoadLlParams(uint8_t *pConfig)
* \brief Load device address. * \brief Load device address.
* *
* \param pDevAddr device address. * \param pDevAddr device address.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void palCfgLoadBdAddress(uint8_t *pDevAddr) void palCfgLoadBdAddress(uint8_t *pDevAddr)
@ -195,8 +189,6 @@ void palCfgLoadBdAddress(uint8_t *pDevAddr)
* \brief Load 15.4 address. * \brief Load 15.4 address.
* *
* \param pDevAddr device address. * \param pDevAddr device address.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void palCfgLoadExtMac154Address(uint8_t *pDevAddr) void palCfgLoadExtMac154Address(uint8_t *pDevAddr)
@ -220,13 +212,12 @@ void palCfgLoadExtMac154Address(uint8_t *pDevAddr)
* \brief Set device UUID. * \brief Set device UUID.
* *
* \param pBuf Return device UUID. * \param pBuf Return device UUID.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalCfgSetDeviceUuid(uint8_t *pBuf) void PalCfgSetDeviceUuid(uint8_t *pBuf)
{ {
/* Not used on this platform. */ /* Not used on this platform. */
(void)pBuf;
} }
/*************************************************************************************************/ /*************************************************************************************************/
@ -234,8 +225,6 @@ void PalCfgSetDeviceUuid(uint8_t *pBuf)
* \brief Load device UUID. * \brief Load device UUID.
* *
* \param pDevUuid Return device UUID. * \param pDevUuid Return device UUID.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void palCfgLoadDeviceUuid(uint8_t *pDevUuid) void palCfgLoadDeviceUuid(uint8_t *pDevUuid)
@ -263,12 +252,12 @@ void palCfgLoadDeviceUuid(uint8_t *pDevUuid)
* \param cfgId Configuration ID. * \param cfgId Configuration ID.
* \param pBuf Buffer. * \param pBuf Buffer.
* \param len Buffer length. * \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) switch (cfgId)
{ {
case PAL_CFG_ID_BD_ADDR: case PAL_CFG_ID_BD_ADDR:

View File

@ -5,7 +5,8 @@
* \brief Crypto driver implementation. * \brief Crypto driver implementation.
* *
* Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 "pal_crypto.h"
#include "stack/platform/include/pal_bb_ble.h" #include "pal_bb_ble.h"
#if defined(NRF52840_XXAA) && defined(FEATURE_CRYPTOCELL310) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION #include <string.h>
#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
/* Nordic specific definitions. */ /* Nordic specific definitions. */
#include "nrf_ecb.h" #include "nrf_ecb.h"
#include "nrf.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" #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 #endif
#include <string.h>
/************************************************************************************************** /**************************************************************************************************
Macros Macros
@ -82,16 +84,8 @@ enum
#endif #endif
#ifndef LL_MAX_CONN #ifndef PAL_CRYPTO_MAX_ID
#define LL_MAX_CONN 4 /*!< Absolute maximum number of connections (maximum is 32). */ #define PAL_CRYPTO_MAX_ID 14 /*!< Absolute maximum number of cipher blocks. */
#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. */
#endif #endif
#ifndef BB_ENABLE_INLINE_ENC_TX #ifndef BB_ENABLE_INLINE_ENC_TX
@ -110,15 +104,13 @@ enum
typedef union typedef union
{ {
uint8_t b[BB_AES_BLOCK_SIZE]; /*!< Byte access block. */ 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 struct
{ {
uint8_t flags[1]; /*!< Flags. */ uint8_t flags[1]; /*!< Flags. */
uint8_t pctr[5]; /*!< Control. */ uint8_t pctr[5]; /*!< Control. */
uint8_t iv[8]; /*!< iv. */ uint8_t iv[8]; /*!< IV. */
uint8_t iMSO[1]; /*!< iMSO. */
uint8_t iLSO[1]; /*!< iLSO. */
} f; /*!< Field access. */ } f; /*!< Field access. */
} palCryptoCipherBlk_t; } palCryptoCipherBlk_t;
@ -144,7 +136,7 @@ typedef union
**************************************************************************************************/ **************************************************************************************************/
/*! \brief Cipher block context. */ /*! \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. */ /*! \brief Nordic ECB encryption data block. */
static palCryptoEcbData_t palCryptoEcb; static palCryptoEcbData_t palCryptoEcb;
@ -153,11 +145,104 @@ static palCryptoEcbData_t palCryptoEcb;
Functions 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. * \brief Execute Nordic AES ECB.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
static inline void palCryptoExecuteAesEcb(void) static inline void palCryptoExecuteAesEcb(void)
@ -184,8 +269,6 @@ static inline void palCryptoExecuteAesEcb(void)
* \brief Load Nordic AES ECB data. * \brief Load Nordic AES ECB data.
* *
* \param pEnc Encryption parameters. * \param pEnc Encryption parameters.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
static inline void palCryptoLoadEcbData(PalCryptoEnc_t *pEnc) static inline void palCryptoLoadEcbData(PalCryptoEnc_t *pEnc)
@ -207,11 +290,9 @@ static inline void palCryptoLoadEcbData(PalCryptoEnc_t *pEnc)
* \param pMic Inplace MIC buffer. * \param pMic Inplace MIC buffer.
* \param pBuf Inplace cleartext/ciphertext buffer. * \param pBuf Inplace cleartext/ciphertext buffer.
* \param pldLen Length of buffer payload. * \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) */ /* X_1 := ECB(K, A_0) */
palCryptoEcb.w.clear[0] = pAx->w[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 pHdr Header buffer.
* \param pBuf Inplace cleartext/ciphertext buffer. * \param pBuf Inplace cleartext/ciphertext buffer.
* \param pldLen Length of payload. * \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) 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. * \brief Increment cipher block packet counter.
* *
* \param pCb Cipher block. * \param pCb Cipher block.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
static inline void palCryptoIncPktCnt(palCryptoCipherBlk_t *pCb) static inline void palCryptoIncPktCnt(palCryptoCipherBlk_t *pCb)
@ -367,8 +444,6 @@ static inline void palCryptoIncPktCnt(palCryptoCipherBlk_t *pCb)
* *
* \param pCb Cipher block. * \param pCb Cipher block.
* \param evtCnt Connection event counter. * \param evtCnt Connection event counter.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
static inline void palCryptoLoadPktCnt(palCryptoCipherBlk_t *pCb, uint16_t evtCnt) 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 pCb Cipher block.
* \param evtCnt Connection event counter. * \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. */ /* Pack connEventCounter. */
pCb->f.pctr[0] = pktCnt >> 0; 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 pOut Output data.
* \param pIn Input data. * \param pIn Input data.
* *
* \return None.
*
* \note Packet length is 16 bytes. * \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)); 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. * \brief Generate cryptographic grade random number.
* *
* \param pBuf Buffer to store random number. * \param pBuf Buffer to store random number.
* \param len Number of bytes. * \param len Number of bytes.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalCryptoGenerateRandomNumber(uint8_t *pBuf, uint8_t len) 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 id Context ID.
* \param localDir Direction bit of local device (0=slave, 1=master). * \param localDir Direction bit of local device (0=slave, 1=master).
* *
* \return None.
*
* This routine completes the transformation in a blocking manner. * This routine completes the transformation in a blocking manner.
* *
* \note Leave this implementation empty if inline hardware encryption is available. * \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; unsigned int mode;
if (id > PAL_CRYPTO_MAX_ID)
{
/* TODO handle error condition */
return;
}
/* Clear */ /* Clear */
memset(&palCryptoCipherBlkTbl[id], 0, sizeof(palCryptoCipherBlkTbl[id])); memset(&palCryptoCipherBlkTbl[id], 0, sizeof(palCryptoCipherBlkTbl[id]));
@ -527,10 +674,6 @@ void PalCryptoAesSetupCipherBlock(PalCryptoEnc_t *pEnc, uint8_t id, uint8_t loca
/* Store context. */ /* Store context. */
pEnc->pEncryptCtx = &palCryptoCipherBlkTbl[id][PAL_CRYPTO_MODE_ENC]; pEnc->pEncryptCtx = &palCryptoCipherBlkTbl[id][PAL_CRYPTO_MODE_ENC];
pEnc->pDecryptCtx = &palCryptoCipherBlkTbl[id][PAL_CRYPTO_MODE_DEC]; 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. */ 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)) (pEnc->pEventCounter))
{ {
palCryptoLoadPktCnt(pCb, *pEnc->pEventCounter + 1); palCryptoLoadPktCnt(pCb, *pEnc->pEventCounter + 1);
} }
if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_CIS_CNTR) && if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EXT64_CNTR) &&
(pEnc->pCisTxPktCounter)) (pEnc->pTxPktCounter))
{ {
palCryptoLoadCisPktCnt(pCb, *pEnc->pCisTxPktCounter); palCryptoLoadIsoPktCnt(pCb, *pEnc->pTxPktCounter);
} }
palCryptoLoadEcbData(pEnc); 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); 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) 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; 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)) (pEnc->pEventCounter))
{ {
/* Synchronized event counter stored in packet headroom. */ /* Synchronized event counter stored in packet headroom. */
@ -657,14 +800,14 @@ bool_t PalCryptoAesCcmDecrypt(PalCryptoEnc_t *pEnc, uint8_t *pBuf)
palCryptoLoadPktCnt(pCb, eventCounter); palCryptoLoadPktCnt(pCb, eventCounter);
} }
if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_CIS_CNTR) && if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EXT64_CNTR) &&
(pEnc->pCisRxPktCounter)) (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); palCryptoLoadEcbData(pEnc);
PalCryptPdu(pCb, pMic, pBuf, pldLen); palCryptoPdu(pCb, pMic, pBuf, pldLen);
if (pEnc->enaAuth) if (pEnc->enaAuth)
{ {
@ -691,7 +834,7 @@ bool_t PalCryptoAesCcmDecrypt(PalCryptoEnc_t *pEnc, uint8_t *pBuf)
return TRUE; 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. * \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; CRYS_AESCCM_Key_t key;
(void)handlerId;
(void)param;
(void)event;
/* Copy key */ /* Copy key */
memcpy(key, pKey, SEC_CCM_KEY_LEN); 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; CRYS_AESCCM_Key_t key;
(void)handlerId;
(void)param;
(void)event;
/* Copy key */ /* Copy key */
memcpy(key, pKey, SEC_CCM_KEY_LEN); 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. * \brief Called to initialize CCM-Mode security.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalCryptoInit(void) void PalCryptoInit(void)
@ -787,8 +936,6 @@ void PalCryptoInit(void)
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Called to De-initialize CCM-Mode security. * \brief Called to De-initialize CCM-Mode security.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalCryptoDeInit(void) void PalCryptoDeInit(void)
@ -806,8 +953,6 @@ void PalCryptoDeInit(void)
* *
* \param pEnc Encryption parameters. * \param pEnc Encryption parameters.
* \param pktCnt Counter value. * \param pktCnt Counter value.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
#if (BB_ENABLE_INLINE_ENC_TX) #if (BB_ENABLE_INLINE_ENC_TX)
@ -823,8 +968,6 @@ void PalCryptoSetEncryptPacketCount(PalCryptoEnc_t *pEnc, uint64_t pktCnt)
* *
* \param pEnc Encryption parameters. * \param pEnc Encryption parameters.
* \param pktCnt Counter value. * \param pktCnt Counter value.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
#if (BB_ENABLE_INLINE_DEC_RX) #if (BB_ENABLE_INLINE_DEC_RX)

View File

@ -5,7 +5,8 @@
* \brief LED driver implementation. * \brief LED driver implementation.
* *
* Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 "boards.h"
#include "stack/platform/include/pal_types.h" #include "nrfx_gpiote.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
#endif #endif
/*! \brief Invalid LED mask. */ #if defined(BOARD_NRF6832)
#define PAL_LED_INVALID_MASK 0xFF #include "lp5562.h"
/*! \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)
#endif #endif
/************************************************************************************************** /**************************************************************************************************
Functions: Initialization 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. * \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) switch (ledId)
{ {
case PAL_LED_ID_CPU_ACTIVE: /* Predefined */
ledMask = PAL_LED1_MASK;
break;
case PAL_LED_ID_ERROR: case PAL_LED_ID_ERROR:
ledMask = PAL_LED3_MASK; return LP5562_LED_W; /* bottom */
break; break;
/* Application defined */
case 0: case 0:
ledMask = PAL_LED0_MASK; return LP5562_LED_R; /* top/left */
break;
case 1: case 1:
ledMask = PAL_LED1_MASK; return LP5562_LED_G; /* top/middle */
break;
case 2: case 2:
ledMask = PAL_LED2_MASK; return LP5562_LED_B; /* top/right */
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
/* Ignore */
case PAL_LED_ID_CPU_ACTIVE:
default: default:
ledMask = PAL_LED_INVALID_MASK;
break; break;
} }
return ledMask; return -1;
} }
#endif
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Initialize LEDs. * \brief Initialize LEDs.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalLedInit(void) void PalLedInit(void)
{ {
nrf_gpio_port_dir_output_set(NRF_P0, PAL_LED_P0_MASK); #if defined(BOARD_PCA10056)
nrf_gpio_port_out_set(NRF_P0, PAL_LED_P0_MASK); nrfx_err_t err;
#if (GPIO_COUNT > 1)
nrf_gpio_port_dir_output_set(NRF_P1, PAL_LED_P1_MASK); if (!nrfx_gpiote_is_init())
nrf_gpio_port_out_set(NRF_P1, PAL_LED_P1_MASK); {
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 #endif
} }
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief De-initialize LEDs. * \brief De-initialize LEDs.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalLedDeInit(void) void PalLedDeInit(void)
{ {
nrf_gpio_port_dir_input_set(NRF_P0, PAL_LED_P0_MASK); #if defined(BOARD_PCA10056)
#if (GPIO_COUNT > 1) nrfx_gpiote_out_uninit(LED_1);
nrf_gpio_port_dir_input_set(NRF_P1, PAL_LED_P1_MASK); nrfx_gpiote_out_uninit(LED_2);
nrfx_gpiote_out_uninit(LED_3);
nrfx_gpiote_out_uninit(LED_4);
#endif #endif
}
/*************************************************************************************************/ #if defined(BOARD_NRF6832)
/*! lp5562_LedDeInit();
* \brief Set multiple LEDs on. #endif
*
* \param mask LED mask.
*
* \return None.
*
*/
/*************************************************************************************************/
void PalLedOnGroup(uint32_t mask)
{
PAL_LED_PARAM_CHECK(mask);
nrf_gpio_port_out_clear(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));
* \brief Set multiple LEDs off. nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 5));
* nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 6));
* \param mask LED mask. #endif
*
* \return None.
*
*/
/*************************************************************************************************/
void PalLedOffGroup(uint32_t mask)
{
PAL_LED_PARAM_CHECK(mask);
nrf_gpio_port_out_set(NRF_P0, mask);
} }
/*************************************************************************************************/ /*************************************************************************************************/
@ -229,24 +149,61 @@ void PalLedOffGroup(uint32_t mask)
* \brief Set LED on. * \brief Set LED on.
* *
* \param ledId LED ID. * \param ledId LED ID.
*
* \return None.
*
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalLedOn(uint8_t ledId) void PalLedOn(uint8_t ledId)
{ {
uint32_t ledMask = palLedGetPinMask(ledId); #if defined(BOARD_PCA10056)
PAL_LED_PARAM_CHECK(ledMask != PAL_LED_INVALID_MASK); switch (ledId)
if ((ledId < PAL_LED_COUNT_P0) || (ledId >= PAL_LED_ID_CPU_ACTIVE))
{ {
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) #endif
else
#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 #endif
} }
@ -256,24 +213,61 @@ void PalLedOn(uint8_t ledId)
* \brief Set LED off. * \brief Set LED off.
* *
* \param ledId LED ID. * \param ledId LED ID.
*
* \return None.
*
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalLedOff(uint8_t ledId) void PalLedOff(uint8_t ledId)
{ {
uint32_t ledMask = palLedGetPinMask(ledId); #if defined(BOARD_PCA10056)
PAL_LED_PARAM_CHECK(ledMask != PAL_LED_INVALID_MASK); switch (ledId)
if ((ledId < PAL_LED_COUNT_P0) || (ledId >= PAL_LED_ID_CPU_ACTIVE))
{ {
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) #endif
else
#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 #endif
} }

View File

@ -5,7 +5,8 @@
* \brief Tickless timer implementation. * \brief Tickless timer implementation.
* *
* Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*
* Notes:
*
* This is timer driver is used by wsf_timer.c and pal_timer.c.
*
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
#include "nrf.h" #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. * \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; PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
NRF_RTC0->INTENSET = RTC_INTENSET_COMPARE0_Msk;
NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; 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. * \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; PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
NRF_RTC0->EVTENCLR = RTC_EVTENCLR_COMPARE0_Msk;
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->EVENTS_LFCLKSTARTED = 0;
NRF_CLOCK->TASKS_LFCLKSTART = 1; NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {} 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. * \brief Set the RTC capture compare value.
* *
* \param channelId Channel ID Number.
* \param value Set new value for compare value. * \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. * \brief Get the current value of the RTC capture compare.
* *
* \param channelId Channel ID Number.
*
* \return Current value of the capture compare. * \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. * \brief RTC interrupt handler.
* *
* \return None.
*
* This handler stores the RTC start time which is used as a reference to compute the receive * This handler stores the RTC start time which is used as a reference to compute the receive
* packet timestamp using the HFCLK. * 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 */ if (NRF_RTC1->EVENTS_COMPARE[channelId])
NRF_RTC0->EVENTS_COMPARE[0] = 0; {
(void)NRF_RTC0->EVENTS_COMPARE[0]; /* wait for write buffer to empty */ PalRtcClearCompareEvents(channelId);
if (palRtcTimerCback[channelId])
{
palRtcTimerCback[channelId]();
}
}
} }
} }
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Tickless timer initialization routine. * \brief Tickless timer initialization routine.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalRtcInit(void) void PalRtcInit(void)
{ {
/* Stop RTC to prevent any running timers from expiring. */ /* 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->EVENTS_LFCLKSTARTED = 0;
NRF_CLOCK->TASKS_LFCLKSTART = 1; NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {} while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) { }
NRF_RTC0->TASKS_STOP = 0; NRF_RTC1->TASKS_STOP = 0;
NRF_RTC0->TASKS_STOP = 1; NRF_RTC1->TASKS_STOP = 1;
NRF_RTC0->TASKS_CLEAR = 1; NRF_RTC1->TASKS_CLEAR = 1;
NRF_RTC0->PRESCALER = 0; /* clear prescaler */ NRF_RTC1->PRESCALER = 0; /* clear prescaler */
NRF_RTC0->TASKS_START = 1; NRF_RTC1->TASKS_START = 1;
NVIC_SetPriority(RTC0_IRQn, 0x80); /* medium priority */ NVIC_SetPriority(RTC1_IRQn, 0x80); /* medium priority */
NVIC_ClearPendingIRQ(RTC0_IRQn); NVIC_ClearPendingIRQ(RTC1_IRQn);
NVIC_EnableIRQ(RTC0_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;
} }

View File

@ -5,7 +5,8 @@
* \brief System hooks. * \brief System hooks.
* *
* Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,11 +23,12 @@
/*************************************************************************************************/ /*************************************************************************************************/
#include "nrf.h" #include "nrf.h"
#include "stack/platform/include/pal_bb.h" #include "pal_rtc.h"
#include "stack/platform/include/pal_rtc.h" #include "pal_sys.h"
#include "stack/platform/include/pal_sys.h" #include "pal_led.h"
#include "stack/platform/include/pal_led.h" #include "pal_timer.h"
#include "platform/mbed_power_mgmt.h" #include "pal_bb.h"
#include "pal_uart.h"
#include <string.h> #include <string.h>
@ -34,16 +36,37 @@
Macros Macros
**************************************************************************************************/ **************************************************************************************************/
extern uint8_t *SystemHeapStart; #ifdef __GNUC__
extern uint32_t SystemHeapSize;
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
/*! \brief Stack initial values. */ /*! \brief Stack initial values. */
#define INIT_STACK_VAL 0xAFAFAFAF #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_top__;
extern unsigned long __stack_limit__; 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 #endif
@ -51,6 +74,21 @@ extern unsigned long __stack_limit__;
Global Variables 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. */ /*! \brief Number of assertions. */
static uint32_t palSysAssertCount; static uint32_t palSysAssertCount;
@ -66,19 +104,17 @@ static uint32_t palSysBusyCount;
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Enter a critical section. * \brief Enter a critical section.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
static inline void palEnterCs(void) void PalEnterCs(void)
{ {
#ifdef __IAR_SYSTEMS_ICC__ #ifdef __IAR_SYSTEMS_ICC__
__disable_interrupt(); __disable_interrupt();
#endif #endif
#if defined(__GNUC__) && !defined(__ARMCC_VERSION) #ifdef __GNUC__
__asm volatile ("cpsid i"); __asm volatile ("cpsid i");
#endif #endif
#if defined(__ARMCC_VERSION) #ifdef __CC_ARM
__disable_irq(); __disable_irq();
#endif #endif
} }
@ -86,19 +122,17 @@ static inline void palEnterCs(void)
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Exit a critical section. * \brief Exit a critical section.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
static inline void palExitCs(void) void PalExitCs(void)
{ {
#ifdef __IAR_SYSTEMS_ICC__ #ifdef __IAR_SYSTEMS_ICC__
__enable_interrupt(); __enable_interrupt();
#endif #endif
#if defined(__GNUC__) && !defined(__ARMCC_VERSION) #ifdef __GNUC__
__asm volatile ("cpsie i"); __asm volatile ("cpsie i");
#endif #endif
#if defined(__ARMCC_VERSION) #ifdef __CC_ARM
__enable_irq(); __enable_irq();
#endif #endif
} }
@ -106,34 +140,17 @@ static inline void palExitCs(void)
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Common platform initialization. * \brief Common platform initialization.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalSysInit(void) void PalSysInit(void)
{ {
/* enable Flash cache */ /* Enable Flash cache */
NRF_NVMC->ICACHECNF |= (NVMC_ICACHECNF_CACHEEN_Enabled << NVMC_ICACHECNF_CACHEEN_Pos); 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->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1; NRF_CLOCK->TASKS_HFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) 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;
palSysAssertCount = 0; palSysAssertCount = 0;
PalSysAssertTrapEnable = TRUE; PalSysAssertTrapEnable = TRUE;
@ -141,6 +158,10 @@ void PalSysInit(void)
PalRtcInit(); PalRtcInit();
PalLedInit();
PalLedOff(PAL_LED_ID_ERROR);
PalLedOn(PAL_LED_ID_CPU_ACTIVE);
#ifdef DEBUG #ifdef DEBUG
/* Reset free memory. */ /* Reset free memory. */
memset(SystemHeapStart, 0, SystemHeapSize); memset(SystemHeapStart, 0, SystemHeapSize);
@ -150,12 +171,12 @@ void PalSysInit(void)
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief System fault trap. * \brief System fault trap.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalSysAssertTrap(void) void PalSysAssertTrap(void)
{ {
PalLedOn(PAL_LED_ID_ERROR);
palSysAssertCount++; palSysAssertCount++;
while (PalSysAssertTrapEnable); while (PalSysAssertTrapEnable);
@ -166,8 +187,6 @@ void PalSysAssertTrap(void)
* \brief Set system trap. * \brief Set system trap.
* *
* \param enable Enable assert trap or not. * \param enable Enable assert trap or not.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalSysSetTrap(bool_t enable) void PalSysSetTrap(bool_t enable)
@ -178,8 +197,6 @@ void PalSysSetTrap(bool_t enable)
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Get assert count. * \brief Get assert count.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
uint32_t PalSysGetAssertCount(void) uint32_t PalSysGetAssertCount(void)
@ -196,7 +213,7 @@ uint32_t PalSysGetAssertCount(void)
/*************************************************************************************************/ /*************************************************************************************************/
uint32_t PalSysGetStackUsage(void) uint32_t PalSysGetStackUsage(void)
{ {
#if defined(__GNUC__) && !defined(__ARMCC_VERSION) #ifdef __GNUC__
unsigned long *pUnused = &__stack_limit__; unsigned long *pUnused = &__stack_limit__;
while (pUnused < &__stack_top__) while (pUnused < &__stack_top__)
@ -219,28 +236,53 @@ uint32_t PalSysGetStackUsage(void)
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief System sleep. * \brief System sleep.
*
* \return none.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalSysSleep(void) 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. * \brief Check if system is busy.
* *
* \return True if system is busy. * \return TRUE if system is busy.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
bool_t PalSysIsBusy(void) bool_t PalSysIsBusy(void)
{ {
bool_t sysIsBusy = FALSE; bool_t sysIsBusy = FALSE;
palEnterCs(); PalEnterCs();
sysIsBusy = ((palSysBusyCount == 0) ? FALSE : TRUE); sysIsBusy = ((palSysBusyCount == 0) ? FALSE : TRUE);
palExitCs(); PalExitCs();
return sysIsBusy; return sysIsBusy;
} }
@ -253,24 +295,22 @@ bool_t PalSysIsBusy(void)
/*************************************************************************************************/ /*************************************************************************************************/
void PalSysSetBusy(void) void PalSysSetBusy(void)
{ {
palEnterCs(); PalEnterCs();
palSysBusyCount++; palSysBusyCount++;
palExitCs(); PalExitCs();
} }
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Set system idle. * \brief Set system idle.
*
* \return none.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalSysSetIdle(void) void PalSysSetIdle(void)
{ {
palEnterCs(); PalEnterCs();
if (palSysBusyCount) if (palSysBusyCount)
{ {
palSysBusyCount--; palSysBusyCount--;
} }
palExitCs(); PalExitCs();
} }

View File

@ -5,7 +5,8 @@
* \brief Timer driver * \brief Timer driver
* *
* Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,22 +25,56 @@
/* /*
* Notes: * Notes:
* *
* This is timer driver dedicated to scheduler, an interrupt will be triggered to do scheduler task * This is timer driver used for scheduler and other low power related tasks.
* when timer hits compare value. TIMER2 is used here. * 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: * If SCH_TIMER_REQUIRED == FALSE:
* CC[0] - Compare value for timer expiry interrupt * No hardware timer is needed for scheduler.
* CC[1] - manual capture of current time *
* 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 "nrf.h"
#include "stack/platform/include/pal_timer.h"
#include "nrf_gpio.h" #include "nrf_gpio.h"
/************************************************************************************************** /**************************************************************************************************
Macros 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 #ifdef DEBUG
/*! \brief Parameter and state check. */ /*! \brief Parameter and state check. */
@ -59,6 +94,14 @@
#define PAL_TIMER_DEBUG_0_PIN 35 /* P1.03 */ #define PAL_TIMER_DEBUG_0_PIN 35 /* P1.03 */
#endif #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 Global Variables
**************************************************************************************************/ **************************************************************************************************/
@ -71,6 +114,38 @@ static struct
PalTimerCompCback_t expCback; /*!< Timer expiry call back function. */ PalTimerCompCback_t expCback; /*!< Timer expiry call back function. */
} palTimerCb; } 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. * \brief Get the current tick of the scheduler timer.
@ -78,60 +153,69 @@ static struct
* \return Current tick of the scheduler timer. * \return Current tick of the scheduler timer.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
uint32_t PalTimerGetCurrentTime(void) static uint32_t palTimerGetCurrentTime(void)
{ {
/* Only valid for initialized scheduler timer. */ /* Only valid for initialized scheduler timer. */
if (palTimerCb.state) if (palTimerCb.state)
{ {
/* Capture current TIMER2 count to capture register 1 */ #if BB_CLK_RATE_HZ == 32768
NRF_TIMER2->TASKS_CAPTURE[1] = 1;
/* Read and return the captured count value from capture register 1 */ /* 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; return 0;
} }
#endif
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Initialize the scheduler timer. * \brief Initialize the scheduler timer.
* *
* \param expCback Timer expire call back function. * \param expCback Timer expire call back function.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalTimerInit(PalTimerCompCback_t expCback) void PalTimerInit(PalTimerCompCback_t expCback)
{ {
#ifdef DEBUG #ifdef DEBUG
nrf_gpio_cfg_output(PAL_TIMER_DEBUG_0_PIN); nrf_gpio_cfg_output(PAL_TIMER_DEBUG_0_PIN);
#endif #endif
PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_UNINIT); PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_UNINIT);
PAL_TIMER_CHECK(expCback != NULL); 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. */ /* 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) */ /* 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 */ /* clear timer to zero count */
NRF_TIMER2->TASKS_CLEAR = 1; NRF_TIMER1->TASKS_CLEAR = 1;
/* configure timer */ /* configure timer */
NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer; NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_32Bit; NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_32Bit;
NRF_TIMER2->PRESCALER = PAL_TIMER_1MHZ_PRESCALER; /* f = 16MHz / (2 ^ TIMER_PRESCALER) */ NRF_TIMER1->PRESCALER = PAL_TIMER_1MHZ_PRESCALER; /* f = 16MHz / (2 ^ TIMER_PRESCALER) */
/* TIMER2 is a free running clock. */ /* timer1 is a free running clock. */
NRF_TIMER2->TASKS_START = 1; NRF_TIMER1->TASKS_START = 1;
/* Clear out and enable TIMER2 interrupt at system level. */ /* Clear out and enable timer1 interrupt at system level. */
NRF_TIMER2->INTENCLR = 0xFFFFFFFF; NRF_TIMER1->INTENCLR = 0xFFFFFFFF;
NRF_TIMER2->EVENTS_COMPARE[0] = 0; NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0;
NVIC_ClearPendingIRQ(TIMER2_IRQn); NVIC_ClearPendingIRQ(TIMER1_IRQn);
NVIC_EnableIRQ(TIMER2_IRQn); NVIC_EnableIRQ(TIMER1_IRQn);
#endif
#endif
palTimerCb.compareVal = 0; palTimerCb.compareVal = 0;
palTimerCb.expCback = expCback; palTimerCb.expCback = expCback;
@ -141,18 +225,18 @@ void PalTimerInit(PalTimerCompCback_t expCback)
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief De-initialize the scheduler timer. * \brief De-initialize the scheduler timer.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalTimerDeInit(void) void PalTimerDeInit(void)
{ {
#if SCH_TIMER_REQUIRED == TRUE
NVIC_DisableIRQ(TIMER2_IRQn); #if BB_CLK_RATE_HZ != 32768
NVIC_DisableIRQ(TIMER1_IRQn);
/* stop timer */ /* stop timer */
NRF_TIMER2->TASKS_STOP = 1; NRF_TIMER1->TASKS_STOP = 1;
NRF_TIMER2->TASKS_SHUTDOWN = 1; #endif
#endif
palTimerCb.state = PAL_TIMER_STATE_UNINIT; palTimerCb.state = PAL_TIMER_STATE_UNINIT;
} }
@ -174,69 +258,95 @@ PalTimerState_t PalTimerGetState(void)
* \brief Start the scheduler timer. * \brief Start the scheduler timer.
* *
* \param expTimeUsec Set timer expiry in microseconds. * \param expTimeUsec Set timer expiry in microseconds.
*
* \return None
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalTimerStart(uint32_t expTimeUsec) void PalTimerStart(uint32_t expTimeUsec)
{ {
PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_READY); PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_READY);
PAL_TIMER_CHECK(expTimeUsec != 0); 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. */ /* Clear pending events. */
NRF_TIMER2->EVENTS_COMPARE[0] = 0; NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0;
/* Set compare value. */ /* Set compare value. */
NRF_TIMER2->CC[0] = startTimeTick; NRF_TIMER1->CC[TIMER_CHANNEL_START_BB] = startTimeTick;
/* Enable TIMER2 interrupt source for CC[0]. */ /* Enable timer1 interrupt source for CC[0]. */
NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE0_Msk; NRF_TIMER1->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
#endif
palTimerCb.compareVal = startTimeTick; palTimerCb.compareVal = startTimeTick;
palTimerCb.state = PAL_TIMER_STATE_BUSY; palTimerCb.state = PAL_TIMER_STATE_BUSY;
#else
(void)expTimeUsec;
if (BbGetCurrentBod() == NULL)
{
SchLoadHandler();
}
#endif
} }
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Stop the scheduler timer. * \brief Stop the scheduler timer.
*
* \return None
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalTimerStop() void PalTimerStop()
{ {
#if SCH_TIMER_REQUIRED == TRUE
#if BB_CLK_RATE_HZ == 32768
/* Disable this interrupt */ /* 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; palTimerCb.state = PAL_TIMER_STATE_READY;
#else
BbCancelBod();
#endif
} }
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief TIMER2 interrupt handler dedicated to scheduler timer. * \brief TIMER1 interrupt handler dedicated to scheduler timer.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void TIMER2_IRQHandler_v(void) void TIMER1_IRQHandler(void)
{ {
#ifdef DEBUG #ifdef DEBUG
nrf_gpio_pin_set(PAL_TIMER_DEBUG_0_PIN); nrf_gpio_pin_set(PAL_TIMER_DEBUG_0_PIN);
#endif #endif
PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_BUSY); PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_BUSY);
/* Check hardware status */ /* Check hardware status */
PAL_TIMER_CHECK(NRF_TIMER2->EVENTS_COMPARE[0]); PAL_TIMER_CHECK(NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB]);
PAL_TIMER_CHECK(NRF_TIMER2->CC[0] == palTimerCb.compareVal); PAL_TIMER_CHECK(NRF_TIMER1->CC[TIMER_CHANNEL_START_BB] == palTimerCb.compareVal);
PAL_TIMER_CHECK(NRF_TIMER2->INTENSET == TIMER_INTENSET_COMPARE0_Msk); PAL_TIMER_CHECK(NRF_TIMER1->INTENSET == TIMER_INTENSET_COMPARE0_Msk);
/* Callback function could restart TIMER2. However, we blindly stop TIMER2 first. */ /* Callback function could restart timer1. However, we blindly stop timer1 first. */
NRF_TIMER2->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk; NRF_TIMER1->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk;
/* Clear event again just in case. */ /* 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; palTimerCb.state = PAL_TIMER_STATE_READY;
@ -245,7 +355,7 @@ void TIMER2_IRQHandler_v(void)
palTimerCb.expCback(); palTimerCb.expCback();
} }
#ifdef DEBUG #ifdef DEBUG
nrf_gpio_pin_clear(PAL_TIMER_DEBUG_0_PIN); nrf_gpio_pin_clear(PAL_TIMER_DEBUG_0_PIN);
#endif #endif
} }

View File

@ -4,8 +4,7 @@
* *
* \brief TWI driver implementation. * \brief TWI driver implementation.
* *
* Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. * Copyright (c) 2019-2020 Packetcraft, Inc.
* Arm Ltd. confidential and proprietary.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,11 +20,15 @@
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
#include <string.h> #include "pal_twi.h"
#include "stack/platform/include/pal_twi.h"
#include "nrfx_twim.h" #include "nrfx_twim.h"
#include "nrf_twim.h" #include "nrf_twim.h"
#include "app_util_platform.h" #include "app_util_platform.h"
#include <string.h>
#if defined(BOARD_PCA10056) | defined(BOARD_PCA10040)
#include "boards.h"
#endif
/************************************************************************************************** /**************************************************************************************************
Macros Macros
@ -44,10 +47,10 @@
#ifdef DEBUG #ifdef DEBUG
/*! \brief Parameter check. */ /*! \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. */ /*! \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 #else
@ -62,12 +65,15 @@
/*! \brief TWI instance ID. */ /*! \brief TWI instance ID. */
#define PAL_TWI_INSTANCE_ID 0 #define PAL_TWI_INSTANCE_ID 0
/*! \brief Pin number for SCL. */ #if defined(BOARD_PCA10056) | defined(BOARD_PCA10040)
#define PAL_TWI_CLOCK_PIN_NUMBER (27U) #define PAL_TWI_SCL_PIN ARDUINO_SCL_PIN /*!< Pin number for SCL. */
#define PAL_TWI_SDA_PIN ARDUINO_SDA_PIN /*!< Pin number for SDA. */
/*! \brief Pin number for SDA. */ #endif
#define PAL_TWI_DATA_PIN_NUMBER (26U)
#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 Type Definitions
@ -88,8 +94,6 @@ typedef struct
PalTwiDevConfig_t devCfg; /*!< Device configuration. */ PalTwiDevConfig_t devCfg; /*!< Device configuration. */
} PalTwiDevCtx_t; } PalTwiDevCtx_t;
#if NRFX_CHECK(NRFX_TWIM0_ENABLED)
/************************************************************************************************** /**************************************************************************************************
Global Variables Global Variables
**************************************************************************************************/ **************************************************************************************************/
@ -100,8 +104,7 @@ static struct
uint8_t curHandle; /*!< Current device handle. */ uint8_t curHandle; /*!< Current device handle. */
PalTwiCmdState_t cmdState; /*!< Command transaction state, Tx or Rx. */ PalTwiCmdState_t cmdState; /*!< Command transaction state, Tx or Rx. */
PalTwiState_t drvState; /*!< Current state. */ PalTwiState_t drvState; /*!< Current state. */
bool_t firstCmd; /*!< First command after operation start flag. */ } palTwiCb = { 0 };
} twiDevCb;
/*! \brief Device context table. */ /*! \brief Device context table. */
static PalTwiDevCtx_t twiDevCtx[PAL_TWI_MAX_DEVICE]; 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 = const nrfx_twim_config_t twiConfig =
{ {
.frequency = NRF_TWIM_FREQ_400K, .frequency = NRF_TWIM_FREQ_400K,
.scl = PAL_TWI_CLOCK_PIN_NUMBER, .scl = PAL_TWI_SCL_PIN,
.sda = PAL_TWI_DATA_PIN_NUMBER, .sda = PAL_TWI_SDA_PIN,
.interrupt_priority = APP_IRQ_PRIORITY_LOWEST, .interrupt_priority = APP_IRQ_PRIORITY_LOWEST, // TODO define in common platform BSP
.hold_bus_uninit = false .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. * \param pEvt Event parameters.
* * \param pContext Unused context.
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
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. */ /* Pre-resolve device configuration. */
PalTwiDevConfig_t *pCfg = &twiDevCtx[twiDevCb.curHandle].devCfg; PalTwiDevConfig_t *pCfg = &twiDevCtx[palTwiCb.curHandle].devCfg;
bool_t success = FALSE; bool_t success = FALSE;
twiDevCb.firstCmd = FALSE; if ((pEvt->type) == NRFX_TWIM_EVT_DONE)
if ((event->type) == NRFX_TWIM_EVT_DONE)
{ {
success = TRUE; 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) 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) 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. * \brief Initialize TWI resources.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalTwiInit(void) void PalTwiInit(void)
{ {
if (twiDevCb.drvState != PAL_TWI_STATE_UNINIT) if (palTwiCb.drvState != PAL_TWI_STATE_UNINIT)
{ {
/* Only initialize once. */
return; return;
} }
memset(&twiDevCb, 0, sizeof(twiDevCb)); memset(&palTwiCb, 0, sizeof(palTwiCb));
for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++) for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++)
{ {
@ -187,24 +190,20 @@ void PalTwiInit(void)
twiDevCtx[handle].devCfg.wrCback = NULL; 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_init(&twiId, &twiConfig, (nrfx_twim_evt_handler_t)palTwiCallback, NULL);
nrfx_twim_enable(&twiId); nrfx_twim_enable(&twiId);
NVIC_ClearPendingIRQ(SPI0_TWI0_IRQn);
NVIC_EnableIRQ(SPI0_TWI0_IRQn);
} }
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief De-Initialize the TWI resources. * \brief De-Initialize the TWI resources.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalTwiDeInit(void) 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++) for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++)
{ {
@ -214,10 +213,10 @@ void PalTwiDeInit(void)
twiDevCtx[handle].devCfg.wrCback = NULL; twiDevCtx[handle].devCfg.wrCback = NULL;
} }
nrfx_twim_uninit(&twiId);
nrfx_twim_disable(&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) uint8_t PalTwiRegisterDevice(PalTwiDevConfig_t *pDevCfg)
{ {
PAL_TWI_PARAM_CHECK_RET(pDevCfg != NULL, PAL_TWI_INVALID_ID); 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; uint8_t retValue = PAL_TWI_INVALID_ID;
@ -263,7 +261,7 @@ uint8_t PalTwiRegisterDevice(PalTwiDevConfig_t *pDevCfg)
/*************************************************************************************************/ /*************************************************************************************************/
PalTwiState_t PalTwiGetState(void) 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. * \brief Always start an operation before reading or writing on TWI interface.
* *
* \param handle Device handle. * \param handle Device handle.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalTwiStartOperation(uint8_t handle) void PalTwiStartOperation(uint8_t handle)
{ {
PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE); 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. */ palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_PEND;
PAL_TWI_PARAM_CHECK(twiDevCtx[handle].opPending == FALSE); /* Client already pended an operation. */ palTwiCb.curHandle = handle;
}
__disable_irq();
if (twiDevCb.drvState == PAL_TWI_STATE_READY)
{
__enable_irq();
twiDevCb.drvState = PAL_TWI_STATE_BUSY;
twiDevCb.firstCmd = TRUE;
twiDevCb.curHandle = handle;
if (twiDevCtx[handle].devCfg.opReadyCback) if (twiDevCtx[handle].devCfg.opReadyCback)
{ {
twiDevCtx[handle].devCfg.opReadyCback(handle); twiDevCtx[handle].devCfg.opReadyCback(handle);
@ -304,9 +290,11 @@ void PalTwiStartOperation(uint8_t handle)
} }
else 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. */ /* Pend the operation until current operation completes. */
twiDevCtx[handle].opPending = TRUE; 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. * \brief Always stop an operation after reading or writing on TWI interface.
* *
* \param handle Device handle. * \param handle Device handle.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalTwiStopOperation(uint8_t handle) void PalTwiStopOperation(uint8_t handle)
{ {
PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE); PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE);
PAL_TWI_PARAM_CHECK(handle == twiDevCb.curHandle); PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle);
PAL_TWI_PARAM_CHECK(twiDevCb.cmdState == PAL_TWI_CMD_IDLE); PAL_TWI_PARAM_CHECK(palTwiCb.cmdState == PAL_TWI_CMD_IDLE);
PAL_TWI_PARAM_CHECK(twiDevCb.drvState == PAL_TWI_STATE_BUSY); PAL_TWI_PARAM_CHECK(palTwiCb.drvState == PAL_TWI_STATE_BUSY_DATA_PEND);
unsigned int nextHandle = PAL_TWI_GET_NEXT_HANDLE(handle); unsigned int nextHandle = PAL_TWI_GET_NEXT_HANDLE(handle);
twiDevCb.curHandle = PAL_TWI_INVALID_ID; palTwiCb.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);
}
while (nextHandle != handle) while (nextHandle != handle)
{ {
@ -346,13 +323,13 @@ void PalTwiStopOperation(uint8_t handle)
/* Set the operation pending to FALSE first in case of race condition. */ /* Set the operation pending to FALSE first in case of race condition. */
twiDevCtx[nextHandle].opPending = FALSE; twiDevCtx[nextHandle].opPending = FALSE;
twiDevCb.firstCmd = TRUE; palTwiCb.curHandle = nextHandle;
twiDevCb.curHandle = nextHandle;
if (twiDevCtx[nextHandle].devCfg.opReadyCback) if (twiDevCtx[nextHandle].devCfg.opReadyCback)
{ {
twiDevCtx[nextHandle].devCfg.opReadyCback(nextHandle); twiDevCtx[nextHandle].devCfg.opReadyCback(nextHandle);
} }
/* Remain in BUSY state. */
return; return;
} }
@ -360,7 +337,32 @@ void PalTwiStopOperation(uint8_t handle)
} }
/* No pending operations. */ /* 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 pData Write buffer.
* \param len Number of bytes to write. * \param len Number of bytes to write.
* *
* \return None.
*
* Transfer \a len bytes from \a pData to the TWI device. * 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(len != 0);
PAL_TWI_PARAM_CHECK(pData != NULL); PAL_TWI_PARAM_CHECK(pData != NULL);
PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE); PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE);
PAL_TWI_PARAM_CHECK(handle == twiDevCb.curHandle); PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle);
PAL_TWI_PARAM_CHECK(twiDevCb.drvState == PAL_TWI_STATE_BUSY);
PAL_TWI_PARAM_CHECK(twiDevCb.cmdState == PAL_TWI_CMD_IDLE);
twiDevCb.curHandle = handle; palTwiCb.curHandle = handle;
twiDevCb.cmdState = PAL_TWI_CMD_TX_DATA; 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)

View File

@ -4,8 +4,7 @@
* *
* \brief UART driver definition. * \brief UART driver definition.
* *
* Copyright (c) 2018-2019 ARM Ltd. All Rights Reserved. * Copyright (c) 2019-2020 Packetcraft, Inc.
* ARM Ltd. confidential and proprietary.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 "pal_uart.h"
#include "sdk_config.h"
#include "nrfx_uarte.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 Local Variables
**************************************************************************************************/ **************************************************************************************************/
#define PAL_UART_INVALID_INSTANCE_NUM 0xFF #define PAL_UART_INVALID_INSTANCE_NUM 0xFF
#ifdef DEBUG #ifdef DEBUG
/*! \brief Parameter check. */ /*! \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 #else
/*! \brief Parameter check (disabled). */ /*! \brief Parameter check (disabled). */
#define PAL_UART_PARAM_CHECK(num, expr) #define PAL_UART_PARAM_CHECK(p, expr)
#endif #endif
/*! \brief Control block. */ /*! \brief Control block. */
static struct static palUartCtrlBlk_t palUartCb[2];
{
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}}};
/************************************************************************************************** /**************************************************************************************************
Local Functions Local Functions
**************************************************************************************************/ **************************************************************************************************/
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Get UART instance number from UART ID. * \brief Get UART instance number from UART ID.
* *
* \param uartId UART ID. * \param id UART ID.
* *
* \return UART instance number. * \return UART instance number.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
static uint8_t palUartGetNum(PalUartId_t uartId) static palUartCtrlBlk_t *palUartGetContext(PalUartId_t id)
{ {
uint8_t uartNum; switch (id)
/* Nordic platform has total two UART instances.
* By default, only UART0 is enabled.
*/
switch (uartId)
{ {
case PAL_UART_ID_CHCI: case PAL_UART_ID_CHCI:
uartNum = 0;
break;
case PAL_UART_ID_TERMINAL: case PAL_UART_ID_TERMINAL:
uartNum = 0; return &palUartCb[0];
break;
case PAL_UART_ID_USER: case PAL_UART_ID_USER:
uartNum = 0; return (NRFX_UARTE_ENABLED_COUNT > 1) ? &palUartCb[1] : &palUartCb[0];
break;
default: default:
uartNum = PAL_UART_INVALID_INSTANCE_NUM;
break; break;
} }
return uartNum; return NULL;
}
/*************************************************************************************************/
/*!
* \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;
} }
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief UART NRF event handler. * \brief UART NRF event handler.
* *
* \param pEvent Pointer to event. * \param pEvent UART event.
* \param pContext Pointer to event context. * \param pContext Instance context.
*
* \return None.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
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) switch (pEvent->type)
{ {
case NRFX_UARTE_EVT_RX_DONE: 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; break;
case NRFX_UARTE_EVT_TX_DONE: case NRFX_UARTE_EVT_TX_DONE:
palUartCb[uartNum].state = PAL_UART_STATE_READY; pCtx->state = PAL_UART_STATE_READY;
if (palUartCb[uartNum].config.wrCback != NULL) if (pCtx->config.wrCback != NULL)
{ {
palUartCb[uartNum].config.wrCback(); pCtx->config.wrCback();
} }
break; break;
case NRFX_UARTE_EVT_ERROR: case NRFX_UARTE_EVT_ERROR:
palUartCb[uartNum].state = PAL_UART_STATE_ERROR; pCtx->state = PAL_UART_STATE_ERROR;
break; break;
default: default:
break; break;
} }
} }
/**************************************************************************************************
Global Functions
**************************************************************************************************/
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Initialize UART. * \brief Initialize UART.
* *
* \param id UART Id. * \param id UART ID.
* \param pCfg Peripheral configuration. * \param pCfg Peripheral configuration.
*
* \return None.
*
* Initialize UART peripheral with \a pCfg values.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalUartInit(PalUartId_t id, const PalUartConfig_t *pCfg) 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; nrfx_err_t err_code = nrfx_uarte_init(&(pCtx->inst), &nrfCfg, palUartEventHandler);
/* 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);
if (err_code != NRFX_SUCCESS) if (err_code != NRFX_SUCCESS)
{ {
palUartCb[uartNum].state = PAL_UART_STATE_ERROR; pCtx->state = PAL_UART_STATE_ERROR;
return; return;
} }
palUartCb[uartNum].state = PAL_UART_STATE_READY; pCtx->state = PAL_UART_STATE_READY;
NVIC_EnableIRQ(UART0_IRQn);
} }
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief De-Initialize UART. * \brief De-Initialize UART.
* *
* \param id UART id. * \param id UART ID.
*
* \return None.
*
* De-Initialize UART.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
void PalUartDeInit(PalUartId_t 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) nrfx_uarte_uninit(&pCtx->inst);
{
return;
}
nrfx_uarte_uninit(&(palUartCb[uartNum].uart)); pCtx->state = PAL_UART_STATE_UNINIT;
palUartCb[uartNum].state = PAL_UART_STATE_UNINIT;
} }
/*************************************************************************************************/ /*************************************************************************************************/
@ -260,81 +218,62 @@ void PalUartDeInit(PalUartId_t id)
* *
* \param id UART id. * \param id UART id.
* *
* \return Current state. * \return Current state.
*
* Return the current state.
*/ */
/*************************************************************************************************/ /*************************************************************************************************/
PalUartState_t PalUartGetState(PalUartId_t id) 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 PAL_UART_STATE_ERROR;
} }
return palUartCb[uartNum].state; return pCtx->state;
} }
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Read data from Rx FIFO. * \brief Read data from Rx FIFO.
* *
* \param id UART id. * \param id UART ID.
* \param pData Read buffer. * \param pData Read buffer.
* \param len Number of bytes to read. * \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) 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); nrfx_err_t err = nrfx_uarte_rx(&pCtx->inst, pData, len);
PAL_UART_PARAM_CHECK(uartNum, len > 0); PAL_UART_PARAM_CHECK(pCtx, err == NRFX_SUCCESS);
PAL_UART_PARAM_CHECK(uartNum, palUartCb[uartNum].state != PAL_UART_STATE_UNINIT); (void)err;
if (uartNum == PAL_UART_INVALID_INSTANCE_NUM)
{
return;
}
nrfx_uarte_rx(&(palUartCb[uartNum].uart), pData, (uint16_t)len);
} }
/*************************************************************************************************/ /*************************************************************************************************/
/*! /*!
* \brief Write data to Tx FIFO. * \brief Write data to Tx FIFO.
* *
* \param id UART id. * \param id UART ID.
* \param pData Write buffer. * \param pData Write buffer.
* \param len Number of bytes to write. * \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) 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); pCtx->state = PAL_UART_STATE_BUSY;
PAL_UART_PARAM_CHECK(uartNum, len > 0); nrfx_err_t err = nrfx_uarte_tx(&pCtx->inst, pData, len);
PAL_UART_PARAM_CHECK(uartNum, palUartCb[uartNum].state == PAL_UART_STATE_READY); PAL_UART_PARAM_CHECK(pCtx, err == NRFX_SUCCESS);
(void)err;
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;
} }
#endif // NRFX_CHECK(NRFX_UARTE0_ENABLED)