remove unneeded pal

pull/13228/head
Paul Szczeanek 2020-06-12 08:21:45 +01:00 committed by Vincent Coubard
parent ebd4aed9b1
commit dbd58bfd02
7 changed files with 15 additions and 1875 deletions

View File

@ -113,6 +113,21 @@ MBED_WEAK void PalSysSleep()
MBED_ERROR(function_not_implemented, "Provide implementation of PalSysSleep");
}
MBED_WEAK void PalSysSetTrap(bool_t enable)
{
(void)enable;
}
MBED_WEAK uint32_t PalSysGetAssertCount()
{
return 0;
}
MBED_WEAK uint32_t PalSysGetStackUsage()
{
return 0;
}
/* CS */
MBED_WEAK void PalEnterCs(void)

View File

@ -1,273 +0,0 @@
/*************************************************************************************************/
/*!
* \file
*
* \brief LED driver implementation.
*
* Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved.
*
* Copyright (c) 2019-2020 Packetcraft, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
*/
/*************************************************************************************************/
#include "pal_led.h"
#if defined(BOARD_PCA10056)
#include "boards.h"
#include "nrfx_gpiote.h"
#endif
#if defined(BOARD_NRF6832)
#include "lp5562.h"
#endif
/**************************************************************************************************
Functions: Initialization
**************************************************************************************************/
#if defined(BOARD_NRF6832)
/*************************************************************************************************/
/*!
* \brief Map LED ID to physical LED.
*
* \param ledId LED ID.
*
* \return Mapped physical LED.
*/
/*************************************************************************************************/
static int palLedMapId(uint8_t ledId)
{
switch (ledId)
{
/* Predefined */
case PAL_LED_ID_ERROR:
return LP5562_LED_W; /* bottom */
break;
/* Application defined */
case 0:
return LP5562_LED_R; /* top/left */
case 1:
return LP5562_LED_G; /* top/middle */
case 2:
return LP5562_LED_B; /* top/right */
/* Ignore */
case PAL_LED_ID_CPU_ACTIVE:
default:
break;
}
return -1;
}
#endif
/*************************************************************************************************/
/*!
* \brief Initialize LEDs.
*/
/*************************************************************************************************/
void PalLedInit(void)
{
#if defined(BOARD_PCA10056)
nrfx_err_t err;
if (!nrfx_gpiote_is_init())
{
err = nrfx_gpiote_init();
if (err != NRFX_SUCCESS)
{
return;
}
}
nrfx_gpiote_out_config_t cfg = NRFX_GPIOTE_CONFIG_OUT_SIMPLE(true);
nrfx_gpiote_out_init(LED_1, &cfg);
nrfx_gpiote_out_init(LED_2, &cfg);
nrfx_gpiote_out_init(LED_3, &cfg);
nrfx_gpiote_out_init(LED_4, &cfg);
#endif
#if AUDIO_CAPE
nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 1), &cfg);
nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 2), &cfg);
nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 3), &cfg);
nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 4), &cfg);
nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 5), &cfg);
nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 6), &cfg);
#endif
#if defined(BOARD_NRF6832)
lp5562_LedInit();
#endif
}
/*************************************************************************************************/
/*!
* \brief De-initialize LEDs.
*/
/*************************************************************************************************/
void PalLedDeInit(void)
{
#if defined(BOARD_PCA10056)
nrfx_gpiote_out_uninit(LED_1);
nrfx_gpiote_out_uninit(LED_2);
nrfx_gpiote_out_uninit(LED_3);
nrfx_gpiote_out_uninit(LED_4);
#endif
#if defined(BOARD_NRF6832)
lp5562_LedDeInit();
#endif
#if AUDIO_CAPE
nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 1));
nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 2));
nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 3));
nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 4));
nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 5));
nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 6));
#endif
}
/*************************************************************************************************/
/*!
* \brief Set LED on.
*
* \param ledId LED ID.
*/
/*************************************************************************************************/
void PalLedOn(uint8_t ledId)
{
#if defined(BOARD_PCA10056)
switch (ledId)
{
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;
}
#endif
#if defined(BOARD_NRF6832)
int ledPin = palLedMapId(ledId);
if (ledPin >= 0)
{
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
}
/*************************************************************************************************/
/*!
* \brief Set LED off.
*
* \param ledId LED ID.
*/
/*************************************************************************************************/
void PalLedOff(uint8_t ledId)
{
#if defined(BOARD_PCA10056)
switch (ledId)
{
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;
}
#endif
#if defined(BOARD_NRF6832)
int ledPin = palLedMapId(ledId);
if (ledPin >= 0)
{
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
}

View File

@ -1,357 +0,0 @@
/*************************************************************************************************/
/*!
* \file
*
* \brief PAL NVM driver.
*
* 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.
*/
/*************************************************************************************************/
#include <string.h>
#include "stack/platform/include/pal_nvm.h"
#include "sdk_config.h"
#if defined(NRF52840_XXAA)
#include "nrfx_qspi.h"
#include "boards.h"
#endif
/**************************************************************************************************
Macros
**************************************************************************************************/
/*! NVM block size. */
#define PAL_NVM_SECTOR64K_SIZE 0x10000
/*! NVM internal cache buffer size. Note: should be at least 2. */
#define PAL_NVM_CACHE_BUF_SIZE 11
/*! Aligns a value to word size. */
#define PAL_NVM_WORD_ALIGN(value) (((value) + (PAL_NVM_WORD_SIZE - 1)) & \
~(PAL_NVM_WORD_SIZE - 1))
/*! Validates if a value is aligned to word. */
#define PAL_NVM_IS_WORD_ALIGNED(value) (((uint32_t)(value) & \
(PAL_NVM_WORD_SIZE - 1)) == 0)
/*! QSPI flash commands. */
#define QSPI_STD_CMD_WRSR 0x01
#define QSPI_STD_CMD_RSTEN 0x66
#define QSPI_STD_CMD_RST 0x99
#ifdef DEBUG
/*! \brief Parameter check. */
#define PAL_NVM_PARAM_CHECK(expr) { \
if (!(expr)) \
{ \
palNvmCb.state = PAL_NVM_STATE_ERROR; \
return; \
} \
}
#else
/*! \brief Parameter check (disabled). */
#define PAL_NVM_PARAM_CHECK(expr)
#endif
/**************************************************************************************************
Local Variables
**************************************************************************************************/
/*! NVM cache buffer. */
static uint32_t palNvmCacheBuf[PAL_NVM_CACHE_BUF_SIZE];
/*! \brief Control block. */
struct
{
PalNvmState_t state; /*!< State. */
uint32_t writeAddr; /*!< Write address. */
} palNvmCb;
/**************************************************************************************************
Global Functions
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \brief Initialize the platform NVM.
*
* \param[in] actCback Callback function.
*
* \return None.
*/
/*************************************************************************************************/
void PalNvmInit(PalNvmCback_t actCback)
{
#if defined(NRF52840_XXAA)
uint32_t status;
uint8_t temp = 0x40;
nrfx_qspi_config_t config =
{ \
.xip_offset = NRFX_QSPI_CONFIG_XIP_OFFSET, \
.pins = { \
.sck_pin = BSP_QSPI_SCK_PIN, \
.csn_pin = BSP_QSPI_CSN_PIN, \
.io0_pin = BSP_QSPI_IO0_PIN, \
.io1_pin = BSP_QSPI_IO1_PIN, \
.io2_pin = BSP_QSPI_IO2_PIN, \
.io3_pin = BSP_QSPI_IO3_PIN, \
}, \
.irq_priority = (uint8_t)NRFX_QSPI_CONFIG_IRQ_PRIORITY, \
.prot_if = { \
.readoc = (nrf_qspi_readoc_t)NRFX_QSPI_CONFIG_READOC, \
.writeoc = (nrf_qspi_writeoc_t)NRFX_QSPI_CONFIG_WRITEOC, \
.addrmode = (nrf_qspi_addrmode_t)NRFX_QSPI_CONFIG_ADDRMODE, \
.dpmconfig = false, \
}, \
.phy_if = { \
.sck_freq = (nrf_qspi_frequency_t)NRFX_QSPI_CONFIG_FREQUENCY, \
.sck_delay = (uint8_t)NRFX_QSPI_CONFIG_SCK_DELAY, \
.spi_mode = (nrf_qspi_spi_mode_t)NRFX_QSPI_CONFIG_MODE, \
.dpmen = false \
}, \
}
;
/* Verify palNvmCacheBuf size is at least 2. */
PAL_NVM_PARAM_CHECK(PAL_NVM_CACHE_BUF_SIZE >= 2);
status = nrfx_qspi_init(&config, NULL, NULL);
PAL_NVM_PARAM_CHECK(status == NRFX_SUCCESS);
nrf_qspi_cinstr_conf_t cinstr_cfg = {
.opcode = QSPI_STD_CMD_RSTEN,
.length = NRF_QSPI_CINSTR_LEN_1B,
.io2_level = 1,
.io3_level = 1,
.wipwait = 1,
.wren = 1
};
/* Send reset enable. */
status = nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
/* Send reset command */
cinstr_cfg.opcode = QSPI_STD_CMD_RST;
status = nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
PAL_NVM_PARAM_CHECK(status == NRFX_SUCCESS);
/* Switch to qspi mode */
cinstr_cfg.opcode = QSPI_STD_CMD_WRSR;
cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_2B;
status = nrfx_qspi_cinstr_xfer(&cinstr_cfg, &temp, NULL);
PAL_NVM_PARAM_CHECK(status == NRFX_SUCCESS);
memset(&palNvmCb, 0, sizeof(palNvmCb));
palNvmCb.state = PAL_NVM_STATE_READY;
(void)status;
#else
(void)palNvmCacheBuf;
#endif
}
/*************************************************************************************************/
/*!
* \brief De-initialize the platform NVM.
*
* \return None.
*/
/*************************************************************************************************/
void PalNvmDeInit(void)
{
#if defined(NRF52840_XXAA)
nrfx_qspi_uninit();
#else
#endif
}
/*************************************************************************************************/
/*!
* \brief Reads data from NVM storage.
*
* \param[in] pBuf Pointer to memory buffer where data will be stored.
* \param[in] size Data size in bytes to be read.
* \param[in] srcAddr Word aligned address from where data is read.
*
* \return None.
*/
/*************************************************************************************************/
void PalNvmRead(void *pBuf, uint32_t size, uint32_t srcAddr)
{
#if defined(NRF52840_XXAA)
uint32_t readSize = PAL_NVM_WORD_ALIGN(size);
uint32_t actualSize = size;
uint32_t status;
uint16_t addrOffset = 0;
PAL_NVM_PARAM_CHECK(palNvmCb.state == PAL_NVM_STATE_READY);
PAL_NVM_PARAM_CHECK(pBuf != NULL);
PAL_NVM_PARAM_CHECK(size != 0);
do
{
if (readSize <= sizeof(palNvmCacheBuf))
{
/* Read data. */
status = nrfx_qspi_read(palNvmCacheBuf, readSize, srcAddr + addrOffset);
PAL_NVM_PARAM_CHECK(status == NRFX_SUCCESS);
memcpy((uint8_t*)pBuf + addrOffset, palNvmCacheBuf, actualSize);
readSize = 0;
}
else
{
/* Read data. */
status = nrfx_qspi_read(palNvmCacheBuf, sizeof(palNvmCacheBuf), srcAddr + addrOffset);
PAL_NVM_PARAM_CHECK (status == NRFX_SUCCESS);
memcpy((uint8_t*)pBuf + addrOffset, palNvmCacheBuf, sizeof(palNvmCacheBuf));
addrOffset += sizeof(palNvmCacheBuf);
readSize -= sizeof(palNvmCacheBuf);
actualSize -= sizeof(palNvmCacheBuf);
}
} while (readSize != 0);
(void)status;
#else
memset(pBuf, 0xFF, size);
#endif
}
/*************************************************************************************************/
/*!
* \brief Writes data to NVM storage.
*
* \param[in] pBuf Pointer to memory buffer from where data will be written.
* \param[in] size Data size in bytes to be written.
* \param[in] dstAddr Word aligned address to write data.
*
* \return None.
*/
/*************************************************************************************************/
void PalNvmWrite(void *pBuf, uint32_t size, uint32_t dstAddr)
{
#if defined(NRF52840_XXAA)
uint32_t writeSize = PAL_NVM_WORD_ALIGN(size);
uint32_t actualSize = size;
uint32_t status;
uint16_t addrOffset = 0;
PAL_NVM_PARAM_CHECK(palNvmCb.state == PAL_NVM_STATE_READY);
PAL_NVM_PARAM_CHECK(pBuf != NULL);
PAL_NVM_PARAM_CHECK(size != 0);
do
{
if (writeSize <= sizeof(palNvmCacheBuf))
{
memcpy(palNvmCacheBuf, (uint8_t*)pBuf + addrOffset, actualSize);
memset((uint8_t*)palNvmCacheBuf + actualSize, 0xFF, sizeof(palNvmCacheBuf) - actualSize);
/* Write data. */
status = nrfx_qspi_write(palNvmCacheBuf, writeSize, dstAddr + addrOffset);
PAL_NVM_PARAM_CHECK(status == NRFX_SUCCESS);
writeSize = 0;
}
else
{
memcpy(palNvmCacheBuf, (uint8_t*)pBuf + addrOffset, sizeof(palNvmCacheBuf));
/* Write data. */
status = nrfx_qspi_write(palNvmCacheBuf, sizeof(palNvmCacheBuf), dstAddr + addrOffset);
PAL_NVM_PARAM_CHECK(status == NRFX_SUCCESS);
addrOffset += sizeof(palNvmCacheBuf);
writeSize -= sizeof(palNvmCacheBuf);
actualSize -= sizeof(palNvmCacheBuf);
}
} while (writeSize != 0);
(void)status;
#else
#endif
}
/*************************************************************************************************/
/*!
* \brief Erase sector.
*
* \param[in] size Data size in bytes to be erased.
* \param[in] startAddr Word aligned address.
*
* \return None.
*/
/*************************************************************************************************/
void PalNvmEraseSector(uint32_t size, uint32_t startAddr)
{
#if defined(NRF52840_XXAA)
nrf_qspi_erase_len_t eSize = QSPI_ERASE_LEN_LEN_4KB;
if (size > PAL_NVM_SECTOR_SIZE)
{
eSize = QSPI_ERASE_LEN_LEN_64KB;
}
if (size > PAL_NVM_SECTOR64K_SIZE)
{
eSize = QSPI_ERASE_LEN_LEN_All;
}
nrfx_qspi_erase(eSize, startAddr);
#endif
}
/*************************************************************************************************/
/*!
* \brief Erase chip. It is not recommended to use since it takes up to 240s.
*
* \return None.
*/
/*************************************************************************************************/
void PalNvmEraseChip(void)
{
#if defined(NRF52840_XXAA)
nrfx_qspi_chip_erase();
#endif
}
/*************************************************************************************************/
/*!
* \brief Get NVM state.
*
* \return NVM state.
*/
/*************************************************************************************************/
PalNvmState_t PalNvmGetState(void)
{
return palNvmCb.state;
}

View File

@ -1,260 +0,0 @@
/*************************************************************************************************/
/*!
* \file
*
* \brief Tickless timer implementation.
*
* Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved.
*
* Copyright (c) 2019-2020 Packetcraft, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
*
* Notes:
*
* This is timer driver is used by wsf_timer.c and pal_timer.c.
*
*/
/*************************************************************************************************/
#include "nrf.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.
*
* \param channelId Channel ID Number.
*/
/*************************************************************************************************/
void PalRtcEnableCompareIrq(uint8_t channelId)
{
PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
PalRtcClearCompareEvents(channelId);
switch (channelId)
{
case 0:
NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk;
NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
break;
case 1:
NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE1_Msk;
NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE1_Msk;
break;
case 2:
NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE2_Msk;
NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE2_Msk;
break;
case 3:
NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE3_Msk;
NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE3_Msk;
break;
default:
break;
}
}
/*************************************************************************************************/
/*!
* \brief Function for stopping the RTC timer.
*
* \param channelId Channel ID Number.
*/
/*************************************************************************************************/
void PalRtcDisableCompareIrq(uint8_t channelId)
{
PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
switch (channelId)
{
case 0:
NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE0_Msk;
NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE0_Msk;
break;
case 1:
NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE1_Msk;
NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE1_Msk;
break;
case 2:
NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE2_Msk;
NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE2_Msk;
break;
case 3:
NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE3_Msk;
NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE3_Msk;
break;
default:
break;
}
}
/*************************************************************************************************/
/*!
* \brief Get the current value of the RTC counter.
*
* \return Current value of the RTC counter.
*/
/*************************************************************************************************/
uint32_t PalRtcCounterGet(void)
{
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {}
NRF_RTC1->TASKS_STOP = 0;
return NRF_RTC1->COUNTER;
}
/*************************************************************************************************/
/*!
* \brief Set the RTC capture compare value.
*
* \param channelId Channel ID Number.
* \param value Set new value for compare value.
*/
/*************************************************************************************************/
void PalRtcCompareSet(uint8_t channelId, uint32_t value)
{
PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
NRF_RTC1->CC[channelId] = value;
}
/*************************************************************************************************/
/*!
* \brief Get the current value of the RTC capture compare.
*
* \param channelId Channel ID Number.
*
* \return Current value of the capture compare.
*/
/*************************************************************************************************/
uint32_t PalRtcCompareGet(uint8_t channelId)
{
PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
return NRF_RTC1->CC[channelId];
}
/*************************************************************************************************/
/*!
* \brief RTC interrupt handler.
*
* This handler stores the RTC start time which is used as a reference to compute the receive
* packet timestamp using the HFCLK.
*
*/
/*************************************************************************************************/
void RTC1_IRQHandler(void)
{
for (unsigned int channelId = 0; channelId < RTC_TIMER_TOTAL_CHANNEL; channelId++)
{
if (NRF_RTC1->EVENTS_COMPARE[channelId])
{
PalRtcClearCompareEvents(channelId);
if (palRtcTimerCback[channelId])
{
palRtcTimerCback[channelId]();
}
}
}
}
/*************************************************************************************************/
/*!
* \brief Tickless timer initialization routine.
*/
/*************************************************************************************************/
void PalRtcInit(void)
{
/* Stop RTC to prevent any running timers from expiring. */
for (unsigned int channelId = 0; channelId < RTC_TIMER_TOTAL_CHANNEL; channelId++)
{
PalRtcDisableCompareIrq(channelId);
}
/* Configure low-frequency clock. */
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) { }
NRF_RTC1->TASKS_STOP = 0;
NRF_RTC1->TASKS_STOP = 1;
NRF_RTC1->TASKS_CLEAR = 1;
NRF_RTC1->PRESCALER = 0; /* clear prescaler */
NRF_RTC1->TASKS_START = 1;
NVIC_SetPriority(RTC1_IRQn, 0x80); /* medium priority */
NVIC_ClearPendingIRQ(RTC1_IRQn);
NVIC_EnableIRQ(RTC1_IRQn);
}
/*************************************************************************************************/
/*!
* \brief Register rtc IRQ callback.
*
* \param channelId Channel ID Number.
* \param cback Call back for ISR.
*
* This callback is dedicated for scheduler timer in low power code.
*
*/
/*************************************************************************************************/
void PalRtcIrqRegister(uint8_t channelId, palRtcIrqCback_t cback)
{
PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL);
palRtcTimerCback[channelId] = cback;
}

View File

@ -1,311 +0,0 @@
/*************************************************************************************************/
/*!
* \file
*
* \brief System hooks.
*
* Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved.
*
* Copyright (c) 2019-2020 Packetcraft, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
*/
/*************************************************************************************************/
#include "nrf.h"
#include "pal_rtc.h"
#include "pal_sys.h"
#include "pal_led.h"
#include "pal_timer.h"
#include "pal_bb.h"
#include "pal_uart.h"
#include <string.h>
/**************************************************************************************************
Macros
**************************************************************************************************/
#ifdef __GNUC__
/*! \brief Stack initial values. */
#define INIT_STACK_VAL 0xAFAFAFAF
/*! \brief Starting memory location of free memory. */
#define FREE_MEM_START ((uint8_t *)&__heap_start__)
/*! \brief Total size in bytes of free memory. */
#define FREE_MEM_SIZE ((uint32_t)&__heap_end__ - (uint32_t)&__heap_start__)
extern uint8_t *SystemHeapStart;
extern uint32_t SystemHeapSize;
extern unsigned long __text_end__;
extern unsigned long __data_start__;
extern unsigned long __data_end__;
extern unsigned long __bss_start__;
extern unsigned long __bss_end__;
extern unsigned long __stack_top__;
extern unsigned long __stack_limit__;
extern unsigned long __heap_end__;
extern unsigned long __heap_start__;
#else
/*! \brief Starting memory location of free memory. */
#define FREE_MEM_START ((uint8_t *)palSysFreeMem)
/*! \brief Total size in bytes of free memory. */
#define FREE_MEM_SIZE (1024 * 196)
#endif
/**************************************************************************************************
Global Variables
**************************************************************************************************/
#ifdef __GNUC__
uint8_t *SystemHeapStart;
uint32_t SystemHeapSize;
#else
/*! \brief Free memory for pool buffers (align to word boundary). */
uint32_t palSysFreeMem[FREE_MEM_SIZE/sizeof(uint32_t)];
uint8_t *SystemHeapStart = (uint8_t *) palSysFreeMem;
uint32_t SystemHeapSize = FREE_MEM_SIZE;
#endif
/*! \brief Number of assertions. */
static uint32_t palSysAssertCount;
/*! \brief Trap enabled flag. */
static volatile bool_t PalSysAssertTrapEnable;
static uint32_t palSysBusyCount;
/**************************************************************************************************
Functions
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \brief Enter a critical section.
*/
/*************************************************************************************************/
void PalEnterCs(void)
{
#ifdef __IAR_SYSTEMS_ICC__
__disable_interrupt();
#endif
#ifdef __GNUC__
__asm volatile ("cpsid i");
#endif
#ifdef __CC_ARM
__disable_irq();
#endif
}
/*************************************************************************************************/
/*!
* \brief Exit a critical section.
*/
/*************************************************************************************************/
void PalExitCs(void)
{
#ifdef __IAR_SYSTEMS_ICC__
__enable_interrupt();
#endif
#ifdef __GNUC__
__asm volatile ("cpsie i");
#endif
#ifdef __CC_ARM
__enable_irq();
#endif
}
/*************************************************************************************************/
/*!
* \brief Common platform initialization.
*/
/*************************************************************************************************/
void PalSysInit(void)
{
/* Enable Flash cache */
NRF_NVMC->ICACHECNF |= (NVMC_ICACHECNF_CACHEEN_Enabled << NVMC_ICACHECNF_CACHEEN_Pos);
/* Use 16 MHz crystal oscillator (system starts up using 16MHz RC oscillator). */
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { }
palSysAssertCount = 0;
PalSysAssertTrapEnable = TRUE;
palSysBusyCount = 0;
PalRtcInit();
#ifdef DEBUG
/* Reset free memory. */
memset(SystemHeapStart, 0, SystemHeapSize);
#endif
}
/*************************************************************************************************/
/*!
* \brief System fault trap.
*/
/*************************************************************************************************/
void PalSysAssertTrap(void)
{
palSysAssertCount++;
while (PalSysAssertTrapEnable);
}
/*************************************************************************************************/
/*!
* \brief Set system trap.
*
* \param enable Enable assert trap or not.
*/
/*************************************************************************************************/
void PalSysSetTrap(bool_t enable)
{
PalSysAssertTrapEnable = enable;
}
/*************************************************************************************************/
/*!
* \brief Get assert count.
*/
/*************************************************************************************************/
uint32_t PalSysGetAssertCount(void)
{
return palSysAssertCount;
}
/*************************************************************************************************/
/*!
* \brief Count stack usage.
*
* \return Number of bytes used by the stack.
*/
/*************************************************************************************************/
uint32_t PalSysGetStackUsage(void)
{
#ifdef __GNUC__
unsigned long *pUnused = &__stack_limit__;
while (pUnused < &__stack_top__)
{
if (*pUnused != INIT_STACK_VAL)
{
break;
}
pUnused++;
}
return (uint32_t)(&__stack_top__ - pUnused) * sizeof(*pUnused);
#else
/* Not available; stub routine. */
return 0;
#endif
}
/*************************************************************************************************/
/*!
* \brief System sleep.
*/
/*************************************************************************************************/
void PalSysSleep(void)
{
/* Clock management for low power mode. */
#if BB_CLK_RATE_HZ == 32768
uint32_t rtcNow = NRF_RTC1->COUNTER;
if ((BbGetCurrentBod() == NULL) && PalUartGetState(PAL_UART_ID_CHCI) == PAL_UART_STATE_UNINIT)
{
if ((PalTimerGetState() == PAL_TIMER_STATE_BUSY &&
((NRF_RTC1->CC[3] - rtcNow) & PAL_MAX_RTC_COUNTER_VAL) > PAL_HFCLK_OSC_SETTLE_TICKS) ||
(PalTimerGetState() == PAL_TIMER_STATE_READY))
{
/* disable HFCLK */
NRF_CLOCK->TASKS_HFCLKSTOP = 1;
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
(void)NRF_CLOCK->EVENTS_HFCLKSTARTED;
}
}
#endif
/* CPU sleep. */
#ifdef __IAR_SYSTEMS_ICC__
__wait_for_interrupt();
#endif
#ifdef __GNUC__
__asm volatile ("wfi");
#endif
#ifdef __CC_ARM
__wfi();
#endif
}
/*************************************************************************************************/
/*!
* \brief Check if system is busy.
*
* \return TRUE if system is busy.
*/
/*************************************************************************************************/
bool_t PalSysIsBusy(void)
{
bool_t sysIsBusy = FALSE;
PalEnterCs();
sysIsBusy = ((palSysBusyCount == 0) ? FALSE : TRUE);
PalExitCs();
return sysIsBusy;
}
/*************************************************************************************************/
/*!
* \brief Set system busy.
*
* \return none.
*/
/*************************************************************************************************/
void PalSysSetBusy(void)
{
PalEnterCs();
palSysBusyCount++;
PalExitCs();
}
/*************************************************************************************************/
/*!
* \brief Set system idle.
*/
/*************************************************************************************************/
void PalSysSetIdle(void)
{
PalEnterCs();
if (palSysBusyCount)
{
palSysBusyCount--;
}
PalExitCs();
}

View File

@ -1,395 +0,0 @@
/*************************************************************************************************/
/*!
* \file
*
* \brief TWI driver implementation.
*
* Copyright (c) 2019-2020 Packetcraft, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
*/
/*************************************************************************************************/
#include "pal_twi.h"
#include "nrfx_twim.h"
#include "nrf_twim.h"
#include "app_util_platform.h"
#include <string.h>
#if defined(BOARD_PCA10056) | defined(BOARD_PCA10040)
#include "boards.h"
#endif
/**************************************************************************************************
Macros
**************************************************************************************************/
/* Allow compiler directive override. */
#ifndef PAL_TWI_MAX_DEVICE
/*! \brief Maximum device count (must be an even multiple of 2^N). */
#define PAL_TWI_MAX_DEVICE 4
#endif
/*! \brief Get next handle value, includes wrap around. */
#define PAL_TWI_GET_NEXT_HANDLE(h) (((h) + 1) & (PAL_TWI_MAX_DEVICE - 1))
#ifdef DEBUG
/*! \brief Parameter check. */
#define PAL_TWI_PARAM_CHECK(expr) { if (!(expr)) { palTwiCb.drvState = PAL_TWI_STATE_ERROR; return; } }
/*! \brief Parameter check, with return value. */
#define PAL_TWI_PARAM_CHECK_RET(expr, rv) { if (!(expr)) { palTwiCb.drvState = PAL_TWI_STATE_ERROR; return (rv); } }
#else
/*! \brief Parameter check (disabled). */
#define PAL_TWI_PARAM_CHECK(expr)
/*! \brief Parameter check, with return value (disabled). */
#define PAL_TWI_PARAM_CHECK_RET(expr, rv)
#endif
/*! \brief TWI instance ID. */
#define PAL_TWI_INSTANCE_ID 0
#if defined(BOARD_PCA10056) | defined(BOARD_PCA10040)
#define PAL_TWI_SCL_PIN ARDUINO_SCL_PIN /*!< Pin number for SCL. */
#define PAL_TWI_SDA_PIN ARDUINO_SDA_PIN /*!< Pin number for SDA. */
#endif
#if defined(BOARD_NRF6832)
#define PAL_TWI_SCL_PIN (6U) /*!< Pin number for SCL. */
#define PAL_TWI_SDA_PIN (7U) /*!< Pin number for SDA. */
#endif
/**************************************************************************************************
Type Definitions
**************************************************************************************************/
/*! \brief Commands state. */
typedef enum
{
PAL_TWI_CMD_IDLE, /*!< Idle state. */
PAL_TWI_CMD_TX_DATA, /*!< Write data state. */
PAL_TWI_CMD_RX_DATA /*!< Read data state. */
} PalTwiCmdState_t;
/*! \brief Device configuration. */
typedef struct
{
bool_t opPending; /*!< Operation pending flag. */
PalTwiDevConfig_t devCfg; /*!< Device configuration. */
} PalTwiDevCtx_t;
/**************************************************************************************************
Global Variables
**************************************************************************************************/
/*! \brief Driver control block. */
static struct
{
uint8_t curHandle; /*!< Current device handle. */
PalTwiCmdState_t cmdState; /*!< Command transaction state, Tx or Rx. */
PalTwiState_t drvState; /*!< Current state. */
} palTwiCb = { 0 };
/*! \brief Device context table. */
static PalTwiDevCtx_t twiDevCtx[PAL_TWI_MAX_DEVICE];
/*! \brief TWI instance. */
static const nrfx_twim_t twiId = NRFX_TWIM_INSTANCE(PAL_TWI_INSTANCE_ID);
/*! \brief TWI config. */
const nrfx_twim_config_t twiConfig =
{
.frequency = NRF_TWIM_FREQ_400K,
.scl = PAL_TWI_SCL_PIN,
.sda = PAL_TWI_SDA_PIN,
.interrupt_priority = APP_IRQ_PRIORITY_LOWEST, // TODO define in common platform BSP
.hold_bus_uninit = FALSE
};
/**************************************************************************************************
Functions: Initialization
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \brief Operation complete callback.
*
* \param pEvt Event parameters.
* \param pContext Unused context.
*/
/*************************************************************************************************/
static void palTwiCallback(nrfx_twim_evt_t *pEvt, void *pCtx)
{
(void)pCtx;
/* Pre-resolve device configuration. */
PalTwiDevConfig_t *pCfg = &twiDevCtx[palTwiCb.curHandle].devCfg;
bool_t success = FALSE;
if ((pEvt->type) == NRFX_TWIM_EVT_DONE)
{
success = TRUE;
}
if (palTwiCb.cmdState == PAL_TWI_CMD_TX_DATA)
{
palTwiCb.cmdState = PAL_TWI_CMD_IDLE;
if (pCfg->wrCback)
{
pCfg->wrCback(palTwiCb.curHandle, success);
}
}
else if (palTwiCb.cmdState == PAL_TWI_CMD_RX_DATA)
{
palTwiCb.cmdState = PAL_TWI_CMD_IDLE;
if (pCfg->rdCback)
{
pCfg->rdCback(palTwiCb.curHandle, success);
}
}
palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_PEND;
}
/*************************************************************************************************/
/*!
* \brief Initialize TWI resources.
*/
/*************************************************************************************************/
void PalTwiInit(void)
{
if (palTwiCb.drvState != PAL_TWI_STATE_UNINIT)
{
/* Only initialize once. */
return;
}
memset(&palTwiCb, 0, sizeof(palTwiCb));
for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++)
{
twiDevCtx[handle].devCfg.devAddr = PAL_TWI_INVALID_ID;
twiDevCtx[handle].devCfg.opReadyCback = NULL;
twiDevCtx[handle].devCfg.rdCback = NULL;
twiDevCtx[handle].devCfg.wrCback = NULL;
}
palTwiCb.drvState = PAL_TWI_STATE_READY;
nrfx_twim_init(&twiId, &twiConfig, (nrfx_twim_evt_handler_t)palTwiCallback, NULL);
nrfx_twim_enable(&twiId);
}
/*************************************************************************************************/
/*!
* \brief De-Initialize the TWI resources.
*/
/*************************************************************************************************/
void PalTwiDeInit(void)
{
PAL_TWI_PARAM_CHECK(palTwiCb.drvState == PAL_TWI_STATE_READY);
for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++)
{
twiDevCtx[handle].devCfg.devAddr = PAL_TWI_INVALID_ID;
twiDevCtx[handle].devCfg.opReadyCback = NULL;
twiDevCtx[handle].devCfg.rdCback = NULL;
twiDevCtx[handle].devCfg.wrCback = NULL;
}
nrfx_twim_disable(&twiId);
nrfx_twim_uninit(&twiId);
palTwiCb.drvState = PAL_TWI_STATE_UNINIT;
}
/*************************************************************************************************/
/*!
* \brief Register a device on the TWI bus.
*
* \param pDevCfg Device configuration.
*
* \return Device handle.
*/
/*************************************************************************************************/
uint8_t PalTwiRegisterDevice(PalTwiDevConfig_t *pDevCfg)
{
PAL_TWI_PARAM_CHECK_RET(pDevCfg != NULL, PAL_TWI_INVALID_ID);
uint8_t retValue = PAL_TWI_INVALID_ID;
for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++)
{
if ((twiDevCtx[handle].devCfg.devAddr == PAL_TWI_INVALID_ID) && (pDevCfg->devAddr != PAL_TWI_INVALID_ID))
{
twiDevCtx[handle].devCfg = *pDevCfg;
return (uint8_t)handle;
}
}
return retValue;
}
/**************************************************************************************************
Functions: Control and Status
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \brief Get the current state.
*
* \return Current state.
*
* Return the current state of the TWI.
*/
/*************************************************************************************************/
PalTwiState_t PalTwiGetState(void)
{
return palTwiCb.drvState;
}
/**************************************************************************************************
Functions: Data Transfer
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \brief Always start an operation before reading or writing on TWI interface.
*
* \param handle Device handle.
*/
/*************************************************************************************************/
void PalTwiStartOperation(uint8_t handle)
{
PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE);
if (palTwiCb.drvState == PAL_TWI_STATE_READY)
{
palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_PEND;
palTwiCb.curHandle = handle;
if (twiDevCtx[handle].devCfg.opReadyCback)
{
twiDevCtx[handle].devCfg.opReadyCback(handle);
}
}
else
{
PAL_TWI_PARAM_CHECK(handle != palTwiCb.curHandle); /* Client operation already in progress. */
PAL_TWI_PARAM_CHECK(twiDevCtx[handle].opPending == FALSE); /* Client already pended an operation. */
/* Pend the operation until current operation completes. */
twiDevCtx[handle].opPending = TRUE;
}
}
/*************************************************************************************************/
/*!
* \brief Always stop an operation after reading or writing on TWI interface.
*
* \param handle Device handle.
*/
/*************************************************************************************************/
void PalTwiStopOperation(uint8_t handle)
{
PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE);
PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle);
PAL_TWI_PARAM_CHECK(palTwiCb.cmdState == PAL_TWI_CMD_IDLE);
PAL_TWI_PARAM_CHECK(palTwiCb.drvState == PAL_TWI_STATE_BUSY_DATA_PEND);
unsigned int nextHandle = PAL_TWI_GET_NEXT_HANDLE(handle);
palTwiCb.curHandle = PAL_TWI_INVALID_ID;
while (nextHandle != handle)
{
if (twiDevCtx[nextHandle].opPending)
{
/* Set the operation pending to FALSE first in case of race condition. */
twiDevCtx[nextHandle].opPending = FALSE;
palTwiCb.curHandle = nextHandle;
if (twiDevCtx[nextHandle].devCfg.opReadyCback)
{
twiDevCtx[nextHandle].devCfg.opReadyCback(nextHandle);
}
/* Remain in BUSY state. */
return;
}
nextHandle = PAL_TWI_GET_NEXT_HANDLE(nextHandle);
}
/* No pending operations. */
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);
}
/*************************************************************************************************/
/*!
* \brief Write data to TWI interface.
*
* \param handle Device handle.
* \param pData Write buffer.
* \param len Number of bytes to write.
*
* Transfer \a len bytes from \a pData to the TWI device.
*/
/*************************************************************************************************/
void PalTwiWriteData(uint8_t handle, const uint8_t *pData, uint8_t len)
{
PAL_TWI_PARAM_CHECK(len != 0);
PAL_TWI_PARAM_CHECK(pData != NULL);
PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE);
PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle);
palTwiCb.curHandle = handle;
palTwiCb.cmdState = PAL_TWI_CMD_TX_DATA;
palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_XFER;
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
}

View File

@ -1,279 +0,0 @@
/*************************************************************************************************/
/*!
* \file
*
* \brief UART driver definition.
*
* Copyright (c) 2019-2020 Packetcraft, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
*/
/*************************************************************************************************/
#include "pal_uart.h"
#include "nrfx_uarte.h"
#if defined(BOARD_NRF6832)
#define RX_PIN_NUMBER 26
#define TX_PIN_NUMBER 27
#define CTS_PIN_NUMBER 0xFF
#define RTS_PIN_NUMBER 0xFF
#else
#include "boards.h"
#endif
/**************************************************************************************************
Type definitions
**************************************************************************************************/
/*! \brief Control block. */
typedef struct
{
PalUartState_t state; /*!< UART state. */
PalUartConfig_t config; /*!< UART configuration. */
nrfx_uarte_t inst; /*!< nRF UART driver instance. */
} palUartCtrlBlk_t;
/**************************************************************************************************
Local Variables
**************************************************************************************************/
#define PAL_UART_INVALID_INSTANCE_NUM 0xFF
#ifdef DEBUG
/*! \brief Parameter check. */
#define PAL_UART_PARAM_CHECK(p, expr) { if (!(expr)) { p->state = PAL_UART_STATE_ERROR; return; } }
#else
/*! \brief Parameter check (disabled). */
#define PAL_UART_PARAM_CHECK(p, expr)
#endif
/*! \brief Control block. */
static palUartCtrlBlk_t palUartCb[2];
/**************************************************************************************************
Local Functions
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \brief Get UART instance number from UART ID.
*
* \param id UART ID.
*
* \return UART instance number.
*/
/*************************************************************************************************/
static palUartCtrlBlk_t *palUartGetContext(PalUartId_t id)
{
switch (id)
{
case PAL_UART_ID_CHCI:
case PAL_UART_ID_TERMINAL:
return &palUartCb[0];
case PAL_UART_ID_USER:
return (NRFX_UARTE_ENABLED_COUNT > 1) ? &palUartCb[1] : &palUartCb[0];
default:
break;
}
return NULL;
}
/*************************************************************************************************/
/*!
* \brief UART NRF event handler.
*
* \param pEvent UART event.
* \param pContext Instance context.
*/
/*************************************************************************************************/
static void palUartEventHandler(nrfx_uarte_event_t const *pEvent, void *pInstCtx)
{
palUartCtrlBlk_t *pCtx = (palUartCtrlBlk_t *)pInstCtx;
switch (pEvent->type)
{
case NRFX_UARTE_EVT_RX_DONE:
if (pCtx->config.rdCback != NULL)
{
pCtx->config.rdCback();
}
break;
case NRFX_UARTE_EVT_TX_DONE:
pCtx->state = PAL_UART_STATE_READY;
if (pCtx->config.wrCback != NULL)
{
pCtx->config.wrCback();
}
break;
case NRFX_UARTE_EVT_ERROR:
pCtx->state = PAL_UART_STATE_ERROR;
break;
default:
break;
}
}
/*************************************************************************************************/
/*!
* \brief Initialize UART.
*
* \param id UART ID.
* \param pCfg Peripheral configuration.
*/
/*************************************************************************************************/
void PalUartInit(PalUartId_t id, const PalUartConfig_t *pCfg)
{
palUartCtrlBlk_t *pCtx = palUartGetContext(id);
PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL);
PAL_UART_PARAM_CHECK(pCtx, pCfg != NULL);
pCtx->config = *pCfg;
/* Resolve instance. */
switch (pCtx - palUartCb)
{
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
}
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;
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;
}
nrfx_err_t err_code = nrfx_uarte_init(&(pCtx->inst), &nrfCfg, palUartEventHandler);
if (err_code != NRFX_SUCCESS)
{
pCtx->state = PAL_UART_STATE_ERROR;
return;
}
pCtx->state = PAL_UART_STATE_READY;
}
/*************************************************************************************************/
/*!
* \brief De-Initialize UART.
*
* \param id UART ID.
*/
/*************************************************************************************************/
void PalUartDeInit(PalUartId_t id)
{
palUartCtrlBlk_t *pCtx = palUartGetContext(id);
PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL);
PAL_UART_PARAM_CHECK(pCtx, pCtx->state == PAL_UART_STATE_READY);
nrfx_uarte_uninit(&pCtx->inst);
pCtx->state = PAL_UART_STATE_UNINIT;
}
/*************************************************************************************************/
/*!
* \brief Get the current state.
*
* \param id UART id.
*
* \return Current state.
*/
/*************************************************************************************************/
PalUartState_t PalUartGetState(PalUartId_t id)
{
palUartCtrlBlk_t *pCtx = palUartGetContext(id);
if (pCtx == NULL)
{
return PAL_UART_STATE_ERROR;
}
return pCtx->state;
}
/*************************************************************************************************/
/*!
* \brief Read data from Rx FIFO.
*
* \param id UART ID.
* \param pData Read buffer.
* \param len Number of bytes to read.
*/
/*************************************************************************************************/
void PalUartReadData(PalUartId_t id, uint8_t *pData, uint16_t len)
{
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);
nrfx_err_t err = nrfx_uarte_rx(&pCtx->inst, pData, len);
PAL_UART_PARAM_CHECK(pCtx, err == NRFX_SUCCESS);
(void)err;
}
/*************************************************************************************************/
/*!
* \brief Write data to Tx FIFO.
*
* \param id UART ID.
* \param pData Write buffer.
* \param len Number of bytes to write.
*/
/*************************************************************************************************/
void PalUartWriteData(PalUartId_t id, const uint8_t *pData, uint16_t len)
{
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);
pCtx->state = PAL_UART_STATE_BUSY;
nrfx_err_t err = nrfx_uarte_tx(&pCtx->inst, pData, len);
PAL_UART_PARAM_CHECK(pCtx, err == NRFX_SUCCESS);
(void)err;
}