Udate of Dialog SDK to 1_0_9 version. (#1250)

Platform Abstraction Layer files has been aligned.
DialogTools has been equiped with new cli_programmer tool.
This commit is contained in:
JakubBrachTieto
2017-02-06 08:45:47 -08:00
committed by Jonathan Hui
parent b293954a67
commit fa1c596fa2
81 changed files with 17141 additions and 5505 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ Flash Binaries:
2. Return to previous terminal window and execute a command in order to flash the board:
```bash
$ ./cli_programmer -b uartboot.bin gdbserver write_qspi 0x0 ../../../output/bin/arm-none-eabi-ot-cli-ftd.img
$ ./cli_programmer gdbserver write_qspi_exec ../../../output/bin/arm-none-eabi-ot-cli-ftd.bin
```
## Interact:
+14 -14
View File
@@ -38,21 +38,21 @@
#include "hw_gpio.h"
#include "platform-da15000.h"
static bool s_is_running = false;
static uint32_t s_alarm = 0;
static uint32_t s_counter;
volatile bool s_alarm_fired = false;
static bool sIsRunning = false;
static uint32_t sAlarm = 0;
static uint32_t sCounter;
volatile bool sAlarmFired = false;
static void timer0_interrupt_cb(void)
{
s_counter++;
sCounter++;
}
void da15000AlarmProcess(otInstance *aInstance)
{
if ((s_is_running) && (s_alarm <= s_counter))
if ((sIsRunning) && (sAlarm <= sCounter))
{
s_is_running = false;
sIsRunning = false;
otPlatAlarmFired(aInstance);
}
}
@@ -70,24 +70,24 @@ void da15000AlarmInit(void)
uint32_t otPlatAlarmGetNow(void)
{
return s_counter;
return sCounter;
}
void otPlatAlarmStartAt(otInstance *aInstance, uint32_t t0, uint32_t dt)
{
(void)aInstance;
s_alarm = t0 + dt;
s_is_running = true;
sAlarm = t0 + dt;
sIsRunning = true;
if (s_counter == 0)
if (sCounter == 0)
{
hw_timer0_enable();
}
if (s_is_running == false)
if (sIsRunning == false)
{
s_is_running = true;
sIsRunning = true;
}
hw_timer0_unfreeze();
@@ -96,7 +96,7 @@ void otPlatAlarmStartAt(otInstance *aInstance, uint32_t t0, uint32_t dt)
void otPlatAlarmStop(otInstance *aInstance)
{
(void)aInstance;
s_is_running = false;
sIsRunning = false;
hw_timer0_freeze();
}
+1 -1
View File
@@ -31,7 +31,7 @@
* Clock init for Dialog da15000.
*
*/
#include "global_io.h"
#include "sdk_defs.h"
#include "hw_cpm.h"
#include "hw_watchdog.h"
+1 -2
View File
@@ -37,8 +37,7 @@
* For Cortex-M cores, called from cpu/arm/cortex-m/boot/cstartup.c.
*/
#include "global_io.h"
#include "bsp/include/black_orca.h"
#include "sdk_defs.h"
#include "bsp/include/core_cm0.h"
void __cpu_startup(void)
@@ -36,6 +36,9 @@
#include "bsp_definitions.h"
#define dg_configBLACK_ORCA_IC_REV BLACK_ORCA_IC_REV_B
#define dg_configBLACK_ORCA_IC_STEP BLACK_ORCA_IC_STEP_A
#undef CONFIG_USE_BLE
#define CONFIG_USE_FTDF
@@ -45,8 +48,6 @@
#define CONFIG_RETARGET
#define CONFIG_RETARGET_UART HW_UART1
#define dg_configPOWER_CONFIG (POWER_CONFIGURATION_2)
#define dg_configUSE_LP_CLK LP_CLK_32768
#define dg_configEXEC_MODE MODE_IS_CACHED
#define dg_configCODE_LOCATION NON_VOLATILE_IS_FLASH
@@ -58,16 +59,15 @@
#define dg_configUSER_CAN_USE_TIMER1 (0)
#define dg_configMEM_RETENTION_MODE (0x1F)
#define dg_configMEM_RETENTION_MODE_PRESERVE_IMAGE (0x1F)
#define dg_configSHUFFLING_MODE (0x3)
#define dg_configUSE_WDOG (0)
#define dg_configUSE_DCDC (1)
#define dg_configPOWER_FLASH (1)
#define dg_configFLASH_CONNECTED_TO (FLASH_CONNECTED_TO_1V8)
#define dg_configFLASH_POWER_DOWN (0)
#define dg_configFLASH_POWER_OFF (0)
#define dg_configPOWER_1V8_ACTIVE (1)
#define dg_configPOWER_1V8_SLEEP (1)
#define dg_configBATTERY_TYPE (BATTERY_TYPE_LIMN2O4)
#define dg_configBATTERY_CHARGE_CURRENT 2 // 30mA
@@ -85,6 +85,8 @@
#define dg_configCACHEABLE_QSPI_AREA_LEN NVMS_PARAM_PART_start
#define dg_configFEM_DLG_REF_BOARD (1)
#define dg_configPOWER_1V8P (1)
#define dg_configUSE_HW_TRNG (1)
#define dg_configUSE_HW_TIMER0 (1)
+3 -11
View File
@@ -44,9 +44,7 @@
#define W25Q_STATUS1_BUSY_BIT 0
#define W25Q_STATUS1_BUSY_MASK (1 << W25Q_STATUS1_BUSY_BIT)
static uint32_t wait_status_timeout;
#define QSPI_SECTION __attribute__ ((section ("text_retained")))
static uint32_t sWaitStatusTimeout;
QSPI_SECTION static inline uint8_t qspi_get_erase_status(void)
{
@@ -85,9 +83,9 @@ uint32_t utilsFlashGetSize(void)
ThreadError utilsFlashStatusWait(uint32_t aTimeout)
{
wait_status_timeout = otPlatAlarmGetNow();
sWaitStatusTimeout = otPlatAlarmGetNow();
while (qspi_get_erase_status() && ((otPlatAlarmGetNow() - wait_status_timeout) < aTimeout));
while (qspi_get_erase_status() && ((otPlatAlarmGetNow() - sWaitStatusTimeout) < aTimeout));
if (qspi_get_erase_status())
{
@@ -97,18 +95,12 @@ ThreadError utilsFlashStatusWait(uint32_t aTimeout)
{
return kThreadError_None;
}
}
ThreadError utilsFlashInit(void)
{
qspi_automode_init();
qspi_automode_flash_power_up();
utilsFlashErasePage(0);
utilsFlashErasePage(0x1000);
if (utilsFlashStatusWait(1000) == kThreadError_Busy)
{
return kThreadError_Failed;
+1 -1
View File
@@ -28,7 +28,7 @@
#include <platform/misc.h>
#include <openthread-types.h>
#include "black_orca.h"
#include "sdk_defs.h"
void otPlatReset(otInstance *aInstance)
{
+10 -10
View File
@@ -38,16 +38,16 @@
#include "platform/alarm.h"
#include <openthread-types.h>
#include "platform-da15000.h"
#include "black_orca.h"
#include "sdk_defs.h"
#include "hw_cpm.h"
#include "hw_watchdog.h"
#include "ftdf.h"
#include "hw_gpio.h"
#include "platform/uart.h"
static bool blink = false;
static int mscounter_init;
static int mscounter;
static bool sBlink = false;
static int sMsCounterInit;
static int sMsCounter;
#define LEADER_BLINK_TIME (200)
#define ROUTER_BLINK_TIME (500)
@@ -95,13 +95,13 @@ void ExampleProcess(otInstance *aInstance)
devRole = otGetDeviceRole(aInstance);
if (blink == false && otPlatAlarmGetNow() != 0)
if (sBlink == false && otPlatAlarmGetNow() != 0)
{
mscounter_init = otPlatAlarmGetNow();
blink = true;
sMsCounterInit = otPlatAlarmGetNow();
sBlink = true;
}
mscounter = otPlatAlarmGetNow() - mscounter_init;
sMsCounter = otPlatAlarmGetNow() - sMsCounterInit;
switch (devRole)
{
@@ -121,10 +121,10 @@ void ExampleProcess(otInstance *aInstance)
thrValue = 0x00;
}
if ((thrValue != 0x00) && (mscounter >= thrValue))
if ((thrValue != 0x00) && (sMsCounter >= thrValue))
{
hw_gpio_toggle(HW_GPIO_PORT_1, HW_GPIO_PIN_5);
mscounter_init = otPlatAlarmGetNow();
sMsCounterInit = otPlatAlarmGetNow();
}
if (thrValue == 0)
+244 -428
View File
@@ -31,178 +31,35 @@
* Platform abstraction for radio communication.
*/
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <common/code_utils.hpp>
#include <platform/alarm.h>
#include <platform/radio.h>
#include <openthread.h>
#include "platform-da15000.h"
#define DEBUG_LOG_ENABLE (0)
#include <ftdf.h>
#include <ad_ftdf.h>
#include "ad_ftdf_phy_api.h"
#include "hw_rf.h"
#include <global_io.h>
#include <ad_ftdf_phy_api.h>
#include <hw_rf.h>
#include <internal.h>
#include <regmap.h>
#include "black_orca.h"
#include "core_cm0.h"
#include "internal.h"
#include <hw_uart.h>
typedef struct __attribute__((packed)) RadioMessage
{
uint8_t mChannel;
uint8_t mPsdu[kMaxPHYPacketSize];
} RadioMessage;
static PhyState s_state = kStateDisabled;
static RadioMessage s_receive_message;
static RadioMessage s_transmit_message;
static RadioMessage s_ack_message;
static RadioPacket s_receive_frame;
static RadioPacket s_transmit_frame;
static RadioPacket s_ack_frame;
static bool s_data_pending = false;
static bool SendFrameDone = false;
static uint8_t s_extended_address[OT_EXT_ADDRESS_SIZE];
static uint16_t s_short_address;
static uint16_t s_panid;
//static int s_sockfd;
static bool s_promiscuous = false;
static uint8_t sleep_init_delay = 0;
static bool SED = false;
static uint32_t sleep_const_delay;
static otInstance *First_Instace;
uint32_t NODE_ID = 1;
#define DEFAULT_CHANNEL (11)
#define FTDF_OFFSET_CHANNEL (11)
void disable_interrupt()
{
NVIC_DisableIRQ(FTDF_GEN_IRQn);
}
static otInstance *sThreadInstance;
void enable_interrupt()
{
NVIC_ClearPendingIRQ(FTDF_GEN_IRQn);
NVIC_EnableIRQ(FTDF_GEN_IRQn);
}
static PhyState sRadioState = kStateDisabled;
static uint8_t sChannel = DEFAULT_CHANNEL;
static uint8_t sTransmitPsdu[kMaxPHYPacketSize];
static RadioPacket sTransmitFrame;
static bool sSendFrameDone = false;
static bool sRadioPromiscuous = false;
void phy_power_init()
{
// Set the radio_ldo voltage to 1.4 Volts
REG_SETF(CRG_TOP, LDO_CTRL1_REG, LDO_RADIO_SETVDD, 2);
// Switch on the RF LDO
REG_SETF(CRG_TOP, LDO_CTRL1_REG, LDO_RADIO_ENABLE, 1);
hw_rf_poweron();
}
void ad_ftdf_init_phy_api_V2(void)
{
NVIC_ClearPendingIRQ(FTDF_WAKEUP_IRQn);
NVIC_EnableIRQ(FTDF_WAKEUP_IRQn);
NVIC_ClearPendingIRQ(FTDF_GEN_IRQn);
NVIC_EnableIRQ(FTDF_GEN_IRQn);
volatile uint32_t *lmacReset = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMACRESET);
*lmacReset = MSK_R_FTDF_ON_OFF_REGMAP_LMACRESET;
volatile uint32_t *controlStatus = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMAC_CONTROL_STATUS);
while ((*controlStatus & MSK_F_FTDF_ON_OFF_REGMAP_LMACREADY4SLEEP) == 0) {}
volatile uint32_t *wakeupTimerEnableStatus = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_WAKEUPTIMERENABLESTATUS);
FTDF_SET_FIELD(ALWAYS_ON_REGMAP_WAKEUPTIMERENABLE, 0);
while (*wakeupTimerEnableStatus & MSK_F_FTDF_ON_OFF_REGMAP_WAKEUPTIMERENABLESTATUS) {}
FTDF_SET_FIELD(ALWAYS_ON_REGMAP_WAKEUPTIMERENABLE, 1);
while ((*wakeupTimerEnableStatus & MSK_F_FTDF_ON_OFF_REGMAP_WAKEUPTIMERENABLESTATUS) == 0) {}
}
void ad_ftdf_init_lmac()
{
FTDF_SET_FIELD(ON_OFF_REGMAP_CCAIDLEWAIT, 192);
volatile uint32_t *txFlagClear = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_TX_FLAG_CLEAR);
*txFlagClear = MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR;
volatile uint32_t *phyParams = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_PHY_PARAMETERS_2);
*phyParams = (FTDF_PHYTXSTARTUP << OFF_F_FTDF_ON_OFF_REGMAP_PHYTXSTARTUP) |
(FTDF_PHYTXLATENCY << OFF_F_FTDF_ON_OFF_REGMAP_PHYTXLATENCY) |
(FTDF_PHYTXFINISH << OFF_F_FTDF_ON_OFF_REGMAP_PHYTXFINISH) |
(FTDF_PHYTRXWAIT << OFF_F_FTDF_ON_OFF_REGMAP_PHYTRXWAIT);
phyParams = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_PHY_PARAMETERS_3);
*phyParams = (FTDF_PHYRXSTARTUP << OFF_F_FTDF_ON_OFF_REGMAP_PHYRXSTARTUP) |
(FTDF_PHYRXLATENCY << OFF_F_FTDF_ON_OFF_REGMAP_PHYRXLATENCY) |
(FTDF_PHYENABLE << OFF_F_FTDF_ON_OFF_REGMAP_PHYENABLE);
volatile uint32_t *ftdfCm = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_FTDF_CM);
*ftdfCm = FTDF_MSK_TX_CE | FTDF_MSK_RX_CE | FTDF_MSK_SYMBOL_TMR_CE;
volatile uint32_t *rxMask = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_RX_MASK);
*rxMask = MSK_R_FTDF_ON_OFF_REGMAP_RX_MASK;
volatile uint32_t *lmacMask = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMAC_MASK);
*lmacMask = MSK_F_FTDF_ON_OFF_REGMAP_RXTIMEREXPIRED_M;
volatile uint32_t *lmacCtrlMask = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMAC_CONTROL_MASK);
*lmacCtrlMask = MSK_F_FTDF_ON_OFF_REGMAP_SYMBOLTIMETHR_M |
MSK_F_FTDF_ON_OFF_REGMAP_SYMBOLTIME2THR_M |
MSK_F_FTDF_ON_OFF_REGMAP_SYNCTIMESTAMP_M;
volatile uint32_t *txFlagClearM;
txFlagClearM = FTDF_GET_FIELD_ADDR_INDEXED(ON_OFF_REGMAP_TX_FLAG_CLEAR_M, FTDF_TX_DATA_BUFFER);
*txFlagClearM |= MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR_M;
txFlagClearM = FTDF_GET_FIELD_ADDR_INDEXED(ON_OFF_REGMAP_TX_FLAG_CLEAR_M, FTDF_TX_WAKEUP_BUFFER);
*txFlagClearM |= MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR_M;
}
void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid)
{
(void)aInstance;
s_panid = panid;
FTDF_setValue(FTDF_PIB_PAN_ID, &panid);
}
void otPlatRadioSetExtendedAddress(otInstance *aInstance, uint8_t *address)
{
(void)aInstance;
for (unsigned i = 0; i < sizeof(s_extended_address); i++)
{
s_extended_address[i] = address[i];
}
FTDF_setValue(FTDF_PIB_EXTENDED_ADDRESS, s_extended_address);
}
void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t address)
{
(void)aInstance;
s_short_address = address;
FTDF_setValue(FTDF_PIB_SHORT_ADDRESS, &address);
}
static uint32_t sSleepInitDelay = 0;
static uint32_t sSleepConstDelay;
static bool sSED = false;
uint32_t NODE_ID = 1;
void da15000RadioInit(void)
{
@@ -218,263 +75,19 @@ void da15000RadioInit(void)
REG_SETF(CRG_TOP, CLK_RADIO_REG, FTDF_MAC_ENABLE, 1);
REG_SETF(CRG_TOP, CLK_RADIO_REG, FTDF_MAC_DIV, 0);
phy_power_init();
hw_rf_poweron();
hw_rf_system_init();
hw_rf_set_recommended_settings();
hw_rf_iff_calibration();
hw_rf_modulation_gain_calibration(0); //RF MODE 0
hw_rf_dc_offset_calibration();
// ad_ftdf_init_phy_api();
FTDF_pib.CCAMode = 2;
ad_ftdf_init_phy_api_V2();
ad_ftdf_init_lmac();
}
ThreadError otPlatRadioEnable(otInstance *aInstance)
{
First_Instace = aInstance;
(void)aInstance;
ThreadError error = kThreadError_None;
uint16_t DefaultChannel = DEFAULT_CHANNEL;
uint8_t value = 1;
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &value); //Wake();
FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &DefaultChannel); //SetChannel(channel);
uint32_t max_retries = 0;
FTDF_setValue(FTDF_PIB_MAX_FRAME_RETRIES, &max_retries);
FTDF_Bitmap32 options = FTDF_TRANSPARENT_ENABLE_FCS_GENERATION;
options |= FTDF_TRANSPARENT_WAIT_FOR_ACK;
options |= FTDF_TRANSPARENT_AUTO_ACK;
FTDF_enableTransparentMode(FTDF_TRUE, options);
otPlatRadioSetPromiscuous(aInstance, false);
s_receive_frame.mPsdu = s_receive_message.mPsdu;
s_transmit_frame.mPsdu = s_transmit_message.mPsdu;
s_ack_frame.mPsdu = s_ack_message.mPsdu;
s_state = kStateReceive;
return error;
}
ThreadError otPlatRadioDisable(otInstance *aInstance)
{
(void)aInstance;
s_state = kStateDisabled;
return kThreadError_None;
}
bool otPlatRadioIsEnabled(otInstance *aInstance)
{
(void)aInstance;
return (s_state != kStateDisabled);
}
ThreadError otPlatRadioSleep(otInstance *aInstance)
{
ThreadError error = kThreadError_Busy;
(void)aInstance;
if (s_state == kStateReceive && sleep_init_delay == 0)
{
sleep_init_delay = otPlatAlarmGetNow();
return kThreadError_None; //error;
}
else if ((otPlatAlarmGetNow() - sleep_init_delay) < 3000)
{
return kThreadError_None; //error;
}
if (s_state == kStateSleep || s_state == kStateReceive)
{
error = kThreadError_None;
SED = true;
sleep_const_delay = otPlatAlarmGetNow();
}
return error;
}
ThreadError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
{
ThreadError error = kThreadError_None;
(void)aInstance;
#if DEBUG_LOG_ENABLE
hw_uart_write_buffer(HW_UART1, "\nR", 2);
#endif
VerifyOrExit(s_state != kStateDisabled, error = kThreadError_Busy);
s_state = kStateReceive;
s_receive_frame.mChannel = aChannel;
uint32_t phyAckAttr;
phyAckAttr = 0x08 | ((aChannel - FTDF_OFFSET_CHANNEL) & 0xf) << 4;
FTDF_SET_FIELD(ON_OFF_REGMAP_PHYRXATTR, (((aChannel - FTDF_OFFSET_CHANNEL) & 0xf) << 4));
FTDF_SET_FIELD(ON_OFF_REGMAP_PHYACKATTR, phyAckAttr);
FTDF_SET_FIELD(ON_OFF_REGMAP_RXALWAYSON, 1);
FTDF_SET_FIELD(ON_OFF_REGMAP_RXENABLE, 1);
exit:
return error;
}
RadioPacket *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
{
(void)aInstance;
return &s_transmit_frame;
}
ThreadError otPlatRadioTransmit(otInstance *aInstance, RadioPacket *aPacket)
{
ThreadError error = kThreadError_None;
(void)aInstance;
FTDF_Boolean csmaSuppress = 0;
VerifyOrExit(s_state == kStateReceive, error = kThreadError_Busy);
ad_ftdf_send_frame_simple(aPacket->mLength, aPacket->mPsdu, aPacket->mChannel, 0, csmaSuppress); //Prio 0 for all.
s_state = kStateTransmit;
s_data_pending = false;
#if DEBUG_LOG_ENABLE
hw_uart_write_buffer(HW_UART1, "\nT", 2);
#endif
exit:
return error;
}
int8_t otPlatRadioGetRssi(otInstance *aInstance)
{
(void)aInstance;
return 0;
}
otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
{
(void)aInstance;
return kRadioCapsNone;
}
void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
{
(void)aInstance;
uint8_t value;
value = aEnable;
FTDF_setValue(FTDF_PIB_PROMISCUOUS_MODE, &value);
s_promiscuous = aEnable;
}
bool otPlatRadioGetPromiscuous(otInstance *aInstance)
{
(void)aInstance;
return s_promiscuous;
}
ThreadError otPlatRadioHandleTransmitDone(bool *rxPending)
{
ThreadError error = kThreadError_None;
VerifyOrExit(s_state == kStateTransmit, error = kThreadError_InvalidState);
s_state = kStateReceive;
if (rxPending != NULL)
{
*rxPending = s_data_pending;
}
exit:
return error;
}
void FTDF_sendFrameTransparentConfirm(void *handle, FTDF_Bitmap32 status)
{
(void)handle;
(void)status;
volatile uint32_t *txStatus = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_RETURN_STATUS_1, FTDF_TX_DATA_BUFFER);
SendFrameDone = true;
#if DEBUG_LOG_ENABLE
hw_uart_write_buffer(HW_UART1, "\nTD", 3);
#endif
}
void da15000RadioProcess(otInstance *aInstance)
{
bool rxPending;
uint8_t bufferForFTDFconfigValue = 0;
if (SendFrameDone)
{
FTDF_SET_FIELD(ON_OFF_REGMAP_RXENABLE, 1);
otPlatRadioHandleTransmitDone(&rxPending);
otPlatRadioTransmitDone(aInstance, &s_transmit_frame, false, kThreadError_None);
SendFrameDone = false;
}
if ((SED) && ((otPlatAlarmGetNow() - sleep_const_delay) > 100))
{
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &bufferForFTDFconfigValue);
s_state = kStateSleep;
SED = false;
}
}
void FTDF_rcvFrameTransparent(FTDF_DataLength frameLength,
FTDF_Octet *frame,
FTDF_Bitmap32 status,
FTDF_LinkQuality lqi)
{
(void)status;
RadioPacket otRadioPacket;
#if DEBUG_LOG_ENABLE
char buff[10];
sprintf(buff, "\nlq:%d", lqi);
hw_uart_write_buffer(HW_UART1, buff, 5);
#endif
otRadioPacket.mPower = kPhyInvalidRssi;
otRadioPacket.mLqi = lqi;
if (s_receive_frame.mChannel == 0)
{
s_receive_frame.mChannel = DEFAULT_CHANNEL;
}
otRadioPacket.mChannel = s_receive_frame.mChannel;
otRadioPacket.mLength = frameLength;
otRadioPacket.mPsdu = frame;
otPlatRadioReceiveDone(First_Instace, &otRadioPacket, kThreadError_None);
if (s_state != kStateDisabled)
{
s_state = kStateReceive;
}
ad_ftdf_init_phy_api();
}
void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
{
(void)aInstance;
aIeeeEui64[0] = 0x80; //80-EA-CA is for Dialog Semiconductor
aIeeeEui64[1] = 0xEA;
aIeeeEui64[2] = 0xCA;
aIeeeEui64[0] = 0x18;
aIeeeEui64[1] = 0xb4;
aIeeeEui64[2] = 0x30;
aIeeeEui64[3] = 0x00;
aIeeeEui64[4] = (NODE_ID >> 24) & 0xff;
aIeeeEui64[5] = (NODE_ID >> 16) & 0xff;
@@ -482,77 +95,280 @@ void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
aIeeeEui64[7] = NODE_ID & 0xff;
}
ThreadError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid)
{
ThreadError error = kThreadError_NotImplemented;
(void)aInstance;
(void)aScanChannel;
(void)aScanDuration;
FTDF_setValue(FTDF_PIB_PAN_ID, &panid);
}
void otPlatRadioSetExtendedAddress(otInstance *aInstance, uint8_t *address)
{
(void)aInstance;
FTDF_setValue(FTDF_PIB_EXTENDED_ADDRESS, address);
}
void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t address)
{
(void)aInstance;
FTDF_setValue(FTDF_PIB_SHORT_ADDRESS, &address);
}
ThreadError otPlatRadioEnable(otInstance *aInstance)
{
uint8_t DefaultChannel;
uint8_t EnableRX;
uint8_t MaxRetries;
ThreadError error = kThreadError_None;
VerifyOrExit(sRadioState == kStateDisabled, error = kThreadError_InvalidState);
sThreadInstance = aInstance;
sTransmitFrame.mPsdu = sTransmitPsdu;
EnableRX = 1;
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &EnableRX);
DefaultChannel = DEFAULT_CHANNEL;
FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &DefaultChannel);
MaxRetries = 0;
FTDF_setValue(FTDF_PIB_MAX_FRAME_RETRIES, &MaxRetries);
FTDF_Bitmap32 options = FTDF_TRANSPARENT_ENABLE_FCS_GENERATION;
options |= FTDF_TRANSPARENT_WAIT_FOR_ACK;
options |= FTDF_TRANSPARENT_AUTO_ACK;
FTDF_enableTransparentMode(FTDF_TRUE, options);
otPlatRadioSetPromiscuous(aInstance, false);
sRadioState = kStateSleep;
exit:
return error;
}
ThreadError otPlatRadioDisable(otInstance *aInstance)
{
(void)aInstance;
sRadioState = kStateDisabled;
return kThreadError_None;
}
bool otPlatRadioIsEnabled(otInstance *aInstance)
{
(void)aInstance;
return (sRadioState != kStateDisabled) ? true : false;
}
ThreadError otPlatRadioSleep(otInstance *aInstance)
{
(void)aInstance;
if (sRadioState == kStateReceive && sSleepInitDelay == 0)
{
sSleepInitDelay = otPlatAlarmGetNow();
return kThreadError_None;
}
else if ((otPlatAlarmGetNow() - sSleepInitDelay) < 3000)
{
return kThreadError_None;
}
if (sRadioState == kStateSleep || sRadioState == kStateReceive)
{
sSED = true;
sSleepConstDelay = otPlatAlarmGetNow();
}
return kThreadError_None;
}
ThreadError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
{
(void)aInstance;
uint8_t EnableRX;
ThreadError error = kThreadError_None;
VerifyOrExit(sRadioState != kStateDisabled, error = kThreadError_InvalidState);
ad_ftdf_wake_up();
sChannel = aChannel;
FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &aChannel);
EnableRX = 1;
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &EnableRX);
sRadioState = kStateReceive;
exit:
return error;
}
void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
{
(void)aInstance;
(void)aEnable;
}
ThreadError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
ThreadError error = kThreadError_NotImplemented;
(void)aInstance;
(void)aShortAddress;
return error;
return kThreadError_NotImplemented;
}
ThreadError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
{
ThreadError error = kThreadError_NotImplemented;
(void)aInstance;
(void)aExtAddress;
return error;
return kThreadError_NotImplemented;
}
ThreadError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
ThreadError error = kThreadError_NotImplemented;
(void)aInstance;
(void)aShortAddress;
return error;
return kThreadError_NotImplemented;
}
ThreadError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
{
ThreadError error = kThreadError_NotImplemented;
(void)aExtAddress;
(void)aInstance;
return error;
return kThreadError_NotImplemented;
}
void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
{
(void)aInstance;
}
void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
{
(void)aInstance;
}
RadioPacket *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
{
(void)aInstance;
return &sTransmitFrame;
}
ThreadError otPlatRadioTransmit(otInstance *aInstance, RadioPacket *aPacket)
{
(void)aInstance;
uint8_t csmaSuppress;
ThreadError error = kThreadError_None;
VerifyOrExit(sRadioState != kStateDisabled, error = kThreadError_InvalidState);
csmaSuppress = 0;
ad_ftdf_send_frame_simple(aPacket->mLength, aPacket->mPsdu, aPacket->mChannel, 0, csmaSuppress); //Prio 0 for all.
sRadioState = kStateTransmit;
exit:
return error;
}
int8_t otPlatRadioGetRssi(otInstance *aInstance)
{
(void)aInstance;
return 0;
}
otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
{
(void)aInstance;
return kRadioCapsNone;
}
bool otPlatRadioGetPromiscuous(otInstance *aInstance)
{
(void)aInstance;
return sRadioPromiscuous;
}
void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
{
(void)aInstance;
FTDF_setValue(FTDF_PIB_PROMISCUOUS_MODE, &aEnable);
sRadioPromiscuous = aEnable;
}
ThreadError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
{
(void)aInstance;
(void)aScanChannel;
(void)aScanDuration;
return kThreadError_NotImplemented;
}
void da15000RadioProcess(otInstance *aInstance)
{
uint8_t EnableRX;
if (sSendFrameDone)
{
sRadioState = kStateReceive;
otPlatRadioTransmitDone(aInstance, &sTransmitFrame, false, kThreadError_None);
sSendFrameDone = false;
}
if (sSED)
{
if ((otPlatAlarmGetNow() - sSleepConstDelay) > 100)
{
EnableRX = 0;
FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &EnableRX);
ad_ftdf_sleep_when_possible(1);
sRadioState = kStateSleep;
sSED = false;
}
}
}
void FTDF_sendFrameTransparentConfirm(void *handle, FTDF_Bitmap32 status)
{
(void)handle;
(void)status;
sSendFrameDone = true;
}
void FTDF_rcvFrameTransparent(FTDF_DataLength frameLength,
FTDF_Octet *frame,
FTDF_Bitmap32 status,
FTDF_LinkQuality lqi)
{
(void)status;
RadioPacket otRadioPacket;
otRadioPacket.mPower = kPhyInvalidRssi;
otRadioPacket.mLqi = lqi;
otRadioPacket.mChannel = sChannel;
otRadioPacket.mLength = frameLength;
otRadioPacket.mPsdu = frame;
otPlatRadioReceiveDone(sThreadInstance, &otRadioPacket, kThreadError_None);
if (sRadioState != kStateDisabled)
{
sRadioState = kStateReceive;
}
}
+5 -5
View File
@@ -36,7 +36,7 @@
#include <platform/random.h>
#include "platform-da15000.h"
#include "black_orca.h"
#include "sdk_defs.h"
#include "hw_trng.h"
#include <string.h>
@@ -44,8 +44,8 @@
#define HW_TRNG_RAM (0x40040000)
static uint32_t s_state = 1;
static uint32_t seed;
static uint32_t sState = 1;
static uint32_t sSeed;
int zhal_get_entropy(uint8_t *outEntropy, size_t inSize)
{
@@ -82,8 +82,8 @@ int zhal_get_entropy(uint8_t *outEntropy, size_t inSize)
void da15000RandomInit(void)
{
zhal_get_entropy((uint8_t *)&seed, sizeof(seed));
s_state = seed;
zhal_get_entropy((uint8_t *)&sSeed, sizeof(sSeed));
sState = sSeed;
}
uint32_t otPlatRandomGet(void)
+4 -4
View File
@@ -37,8 +37,8 @@
#include "hw_gpio.h"
#include "platform-da15000.h"
static int s_in_fd;
static int s_out_fd;
static int sInFd;
static int sOutFd;
void UartBuffClear(void);
ThreadError otPlatUartEnable(void)
@@ -72,8 +72,8 @@ ThreadError otPlatUartDisable(void)
{
ThreadError error = kThreadError_None;
close(s_in_fd);
close(s_out_fd);
close(sInFd);
close(sOutFd);
return error;
}
+5 -14
View File
@@ -41,22 +41,23 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*****************************************************************************************
*/
#ifndef AD_RF_H_
#define AD_RF_H_
#if dg_configRF_ADAPTER
#include <stdbool.h>
#include <stdint.h>
//#include "platform_devices.h"
#include "hw_rf.h"
/**
* @brief Performs RF adapter initialization
*/
@@ -111,9 +112,7 @@ static inline void ad_rf_system_init()
*/
static inline void ad_rf_start_calibration()
{
// OS_ENTER_CRITICAL_SECTION();
ad_rf_start_and_check_calibration();
// OS_LEAVE_CRITICAL_SECTION();
}
/**
@@ -125,9 +124,7 @@ static inline void ad_rf_start_calibration()
*/
static inline void ad_rf_request_recommended_settings(void)
{
// OS_ENTER_CRITICAL_SECTION();
hw_rf_request_recommended_settings();
// OS_LEAVE_CRITICAL_SECTION();
}
/**
@@ -140,9 +137,7 @@ static inline void ad_rf_request_recommended_settings(void)
*/
static inline void ad_rf_request_on(bool mode_ble)
{
// OS_ENTER_CRITICAL_SECTION();
hw_rf_request_on(mode_ble);
// OS_LEAVE_CRITICAL_SECTION();
}
/**
@@ -157,11 +152,7 @@ static inline void ad_rf_request_on(bool mode_ble)
*/
static inline void ad_rf_request_off(bool mode_ble)
{
// ad_gpadc_acquire();
// OS_ENTER_CRITICAL_SECTION();
hw_rf_request_off(mode_ble);
// OS_LEAVE_CRITICAL_SECTION();
// ad_gpadc_release();
}
#endif /* dg_configRF_ADAPTER */
+25 -25
View File
@@ -1,26 +1,26 @@
/* Copyright (c) 2009 - 2013 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
/* Copyright (c) 2009 - 2013 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
+173 -3
View File
@@ -1,3 +1,16 @@
/**
* \addtogroup BSP
* \{
* \addtogroup BSP_CONFIG
* \{
* \addtogroup BSP_DEBUG
*
* \brief Doxygen documentation is not yet available for this module.
* Please check the source code file(s)
*
* \{
*/
/**
****************************************************************************************
*
@@ -28,7 +41,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
****************************************************************************************
*/
@@ -136,6 +150,10 @@
#define DEBUG_USB_CHARGER_FSM (0)
#endif
#ifndef DEBUG_USB_CHARGER_PRINT
#define DEBUG_USB_CHARGER_PRINT (0)
#endif
#ifndef USB_CHARGER_TIMING_DEBUG
#define USB_CHARGER_TIMING_DEBUG (0)
#endif
@@ -181,20 +199,36 @@
/* ---------------------------------------------------------------------------------------------- */
/* ------------------------------------------ Flash --------------------------------------------- */
#ifndef FLASH_DEBUG
#define FLASH_DEBUG (0) // Requires GPIO config.
#endif
#ifndef __DBG_QSPI_ENABLED
#define __DBG_QSPI_ENABLED (0)
#endif
/* ---------------------------------------------------------------------------------------------- */
/* ------------------------------------------ Common -------------------------------------------- */
#ifndef CMN_TIMING_DEBUG
#define CMN_TIMING_DEBUG (0) // Requires GPIO config.
#define CMN_TIMING_DEBUG (0) // Requires GPIO config.
#endif
/* ---------------------------------------------------------------------------------------------- */
/* -------------------------------------------- SPI --------------------------------------------- */
#ifndef SPI_TIMING_DEBUG
#define SPI_TIMING_DEBUG (0) // Requires GPIO config.
#endif
/* ---------------------------------------------------------------------------------------------- */
/* ------------------------------------ GPIO configuration -------------------------------------- */
/* Enable/Disable GPIO pin assignment conflict detection
*/
#define DEBUG_GPIO_ALLOC_MONITOR_ENABLED (0)
#define DEBUG_GPIO_ALLOC_MONITOR_ENABLED (0)
/* Exception handling debug configuration
@@ -447,6 +481,111 @@
#endif
/* Flash debug configuration
*
*/
#if (FLASH_DEBUG == 0)
// Write page (initial configuration: low)
#define FLASHDBG_PAGE_PROG_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_PIN (0)
// Program page wait loop (initial configuration: low)
#define FLASHDBG_PAGE_PROG_WL_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_WL_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_WL_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_WL_PIN (0)
// Program page wait loop - pending irq check (initial configuration: low)
#define FLASHDBG_PAGE_PROG_WL_IRQ_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_WL_IRQ_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_WL_IRQ_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_PAGE_PROG_WL_IRQ_PIN (0)
// Suspend op (initial configuration: low)
#define FLASHDBG_SUSPEND_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_SUSPEND_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_SUSPEND_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_SUSPEND_PIN (0)
// Erase sector cmd (initial configuration: low)
#define FLASHDBG_SECTOR_ERASE_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_SECTOR_ERASE_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_SECTOR_ERASE_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_SECTOR_ERASE_PIN (0)
// Notify task (initial configuration: low)
#define FLASHDBG_TASK_NOTIFY_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_TASK_NOTIFY_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_TASK_NOTIFY_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_TASK_NOTIFY_PIN (0)
// Suspend action (low level) (initial configuration: low)
#define FLASHDBG_SUSPEND_ACTION_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_SUSPEND_ACTION_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_SUSPEND_ACTION_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_SUSPEND_ACTION_PIN (0)
// Resume op (initial configuration: low)
#define FLASHDBG_RESUME_MODE_REG *(volatile int *)0x20000000
#define FLASHDBG_RESUME_SET_REG *(volatile int *)0x20000000
#define FLASHDBG_RESUME_RESET_REG *(volatile int *)0x20000000
#define FLASHDBG_RESUME_PIN (0)
#else
// Write page (initial configuration: low)
#define FLASHDBG_PAGE_PROG_MODE_REG GPIO->P30_MODE_REG
#define FLASHDBG_PAGE_PROG_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_PAGE_PROG_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_PAGE_PROG_PIN (1 << 0)
// Program page wait loop (initial configuration: low)
#define FLASHDBG_PAGE_PROG_WL_MODE_REG GPIO->P31_MODE_REG
#define FLASHDBG_PAGE_PROG_WL_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_PAGE_PROG_WL_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_PAGE_PROG_WL_PIN (1 << 1)
// Program page wait loop - pending irq check (initial configuration: low)
#define FLASHDBG_PAGE_PROG_WL_IRQ_MODE_REG GPIO->P32_MODE_REG
#define FLASHDBG_PAGE_PROG_WL_IRQ_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_PAGE_PROG_WL_IRQ_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_PAGE_PROG_WL_IRQ_PIN (1 << 2)
// Suspend op (initial configuration: low)
#define FLASHDBG_SUSPEND_MODE_REG GPIO->P33_MODE_REG
#define FLASHDBG_SUSPEND_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_SUSPEND_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_SUSPEND_PIN (1 << 3)
// Erase sector cmd (initial configuration: low)
#define FLASHDBG_SECTOR_ERASE_MODE_REG GPIO->P34_MODE_REG
#define FLASHDBG_SECTOR_ERASE_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_SECTOR_ERASE_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_SECTOR_ERASE_PIN (1 << 4)
// Notify task (initial configuration: low)
#define FLASHDBG_TASK_NOTIFY_MODE_REG GPIO->P35_MODE_REG
#define FLASHDBG_TASK_NOTIFY_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_TASK_NOTIFY_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_TASK_NOTIFY_PIN (1 << 5)
// Suspend action (low level) (initial configuration: low)
#define FLASHDBG_SUSPEND_ACTION_MODE_REG GPIO->P36_MODE_REG
#define FLASHDBG_SUSPEND_ACTION_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_SUSPEND_ACTION_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_SUSPEND_ACTION_PIN (1 << 6)
// Resume op (initial configuration: low)
#define FLASHDBG_RESUME_MODE_REG GPIO->P37_MODE_REG
#define FLASHDBG_RESUME_SET_REG GPIO->P3_SET_DATA_REG
#define FLASHDBG_RESUME_RESET_REG GPIO->P3_RESET_DATA_REG
#define FLASHDBG_RESUME_PIN (1 << 7)
#endif
/* Enables the logging of stack (RW) heap memories usage.
*
* The feature shall only be enabled in development/debug mode
@@ -455,6 +594,37 @@
#define dg_configLOG_BLE_STACK_MEM_USAGE (0)
#endif
/**
* \brief Enables BLE diagnostic signals.
*
* There are 4 diagnostic signal configurations that user can choose from. To enable a specific
* configuration, simply define dg_configBLE_DIAGN_CONFIG with the perspective configuration ID.
* Configuration ID 0 disables BLE diagnostics.
*
* ------------------------------------------------------------------------------------------------------
* | Signal | Pin | Config 1 | Config 2 | Config 3 | Config 4 |
* ------------------------------------------------------------------------------------------------------
* | ble_diag0 | P2_0 | - | - | - | - |
* ------------------------------------------------------------------------------------------------------
* | ble_diag1 | P2_1 | - | - | - | - |
* ------------------------------------------------------------------------------------------------------
* | ble_diag2 | P2_2 | - | - | - | - |
* ------------------------------------------------------------------------------------------------------
* | ble_diag3 | P1_0 | - | - | - | - |
* ------------------------------------------------------------------------------------------------------
* | ble_diag4 | P1_1 | ble_slp_irq | radcntl_txen | radcntl_txen | radcntl_txen |
* ------------------------------------------------------------------------------------------------------
* | ble_diag5 | P1_2 | ble_cscnt_irq | radcntl_rxen | rf_tx_en | radcntl_rxen |
* ------------------------------------------------------------------------------------------------------
* | ble_diag6 | P1_3 | ble_finetgtim_irq | rf_rx_en | rf_tx_data | ble_rx_irq |
* ------------------------------------------------------------------------------------------------------
* | ble_diag7 | P2_3 | ble_event_irq | rf_rx_data | rf_tx_data_valid | ble_event_irq |
* ------------------------------------------------------------------------------------------------------
*/
#ifndef dg_configBLE_DIAGN_CONFIG
#define dg_configBLE_DIAGN_CONFIG (0)
#endif
#endif /* BSP_DEBUG_H_ */
/**
+1567 -526
View File
File diff suppressed because it is too large Load Diff
+62 -14
View File
@@ -1,3 +1,16 @@
/**
* \addtogroup BSP
* \{
* \addtogroup BSP_CONFIG
* \{
* \addtogroup BSP_CONFIG_DEFINITIONS
*
* \brief Doxygen documentation is not yet available for this module.
* Please check the source code file(s)
*
*\{
*/
/**
****************************************************************************************
*
@@ -28,7 +41,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
****************************************************************************************
*/
@@ -38,17 +52,17 @@
/* ------------------------------------ Generic definitions ------------------------------------- */
#define POWER_CONFIGURATION_1 0
#define POWER_CONFIGURATION_2 1
#define POWER_CONFIGURATION_3 2
#define LP_CLK_32000 0
#define LP_CLK_32768 1
#define LP_CLK_RCX 2
#define LP_CLK_ANY 3
#define LP_CLK_IS_ANALOG 0
#define LP_CLK_IS_DIGITAL 1
#define MODE_IS_MIRRORED 0
#define MODE_IS_CACHED 1
#define MODE_IS_RAM MODE_IS_CACHED
#define MODE_IS_RAM MODE_IS_MIRRORED
#define NON_VOLATILE_IS_OTP 0 // Code is in OTP
#define NON_VOLATILE_IS_FLASH 1 // Code is in QSPI Flash
@@ -60,6 +74,10 @@
#define DEVELOPMENT_MODE 0 // Code is built for debugging
#define PRODUCTION_MODE 1 // Code is built for production
#define FLASH_IS_NOT_CONNECTED 0
#define FLASH_CONNECTED_TO_1V8 1
#define FLASH_CONNECTED_TO_1V8P 2
#define BATTERY_TYPE_2xNIMH 0
#define BATTERY_TYPE_3xNIMH 1
#define BATTERY_TYPE_LICOO2 2 // 2.5V discharge voltage, 4.20V charge voltage
@@ -71,33 +89,57 @@
#define BATTERY_TYPE_NO_RECHARGE 8
#define BATTERY_TYPE_NO_BATTERY 9
#define BATTERY_TYPE_2xNIMH_ADC_VOLTAGE (2784)
#define BATTERY_TYPE_2xNIMH_ADC_VOLTAGE (2785)
#define BATTERY_TYPE_3xNIMH_ADC_VOLTAGE (4013)
#define BATTERY_TYPE_LICOO2_ADC_VOLTAGE (3439)
#define BATTERY_TYPE_LIMN2O4_ADC_VOLTAGE (3439)
#define BATTERY_TYPE_NMC_ADC_VOLTAGE (3439)
#define BATTERY_TYPE_LIFEPO4_ADC_VOLTAGE (2947)
#define BATTERY_TYPE_LINICOAIO2_ADC_VOLTAGE (3439)
#define BATTERY_TYPE_LICOO2_ADC_VOLTAGE (3440)
#define BATTERY_TYPE_LIMN2O4_ADC_VOLTAGE (3440)
#define BATTERY_TYPE_NMC_ADC_VOLTAGE (3440)
#define BATTERY_TYPE_LIFEPO4_ADC_VOLTAGE (2989)
#define BATTERY_TYPE_LINICOAIO2_ADC_VOLTAGE (3440)
/*
* The supported chip revisions.
*/
#define BLACK_ORCA_IC_REV_AUTO (-1)
#define BLACK_ORCA_IC_REV_A 0
#define BLACK_ORCA_IC_REV_B 1
/*
* The supported chip steppings.
*/
#define BLACK_ORCA_IC_STEP_AUTO (-1)
#define BLACK_ORCA_IC_STEP_A 0
#define BLACK_ORCA_IC_STEP_B 1
#define BLACK_ORCA_IC_STEP_C 2
#define BLACK_ORCA_IC_STEP_D 3
#define BLACK_ORCA_IC_STEP_E 7
/*
* The supported DK motherboards.
* Legacy DK motherboards, which are not supported by the SDK.
* The definitions exist just so that we don't break compilation of old projects.
*/
#define BLACK_ORCA_MB_REV_A 0
#define BLACK_ORCA_MB_REV_B 1
/*
* The supported DK motherboards.
*/
#define BLACK_ORCA_MB_REV_D 2
/*
* The cache associtivity options.
*/
#define CACHE_ASSOC_AS_IS (-1) /// leave as set by the ROM booter
#define CACHE_ASSOC_DIRECT_MAP 0 /// direct-mapped
#define CACHE_ASSOC_2_WAY 1 /// 2-way set associative
#define CACHE_ASSOC_4_WAY 2 /// 4-way set associative
/*
* The cache line size options.
*/
#define CACHE_LINESZ_AS_IS (-1) /// leave as set by the ROM booter
#define CACHE_LINESZ_8_BYTES 0 /// 8 bytes
#define CACHE_LINESZ_16_BYTES 1 /// 16 bytes
#define CACHE_LINESZ_32_BYTES 2 /// 32 bytes
/*
* The supported RF Front-End Modules
@@ -105,6 +147,12 @@
#define FEM_NOFEM 0
#define FEM_SKY66112_11 1
/*
* The BLE event notification user hook types
*/
#define BLE_EVENT_NOTIF_USER_ISR 0 /// User-defined hooks directly from ISR context
#define BLE_EVENT_NOTIF_USER_TASK 1 /// Notification of the user task, using task notifications.
#endif /* BSP_DEFINITIONS_H_ */
/**
+28 -19
View File
@@ -1,5 +1,17 @@
/**
****************************************************************************************
/**
* \addtogroup BSP
* \{
* \addtogroup BSP_CONFIG
* \{
* \addtogroup RF_FEM
*
* \brief RF Front-End module confguration
*
*\{
*/
/**
***************************************************************************************
*
* @file bsp_fem.h
*
@@ -28,9 +40,10 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************************
*/
*
*
***************************************************************************************
*/
#ifndef BSP_FEM_H_
#define BSP_FEM_H_
@@ -39,16 +52,12 @@
#ifdef dg_configFEM_DLG_REF_BOARD
#undef dg_configBLACK_ORCA_IC_STEP
#define dg_configBLACK_ORCA_IC_STEP BLACK_ORCA_IC_STEP_D
#define dg_configFEM FEM_SKY66112_11
#ifndef dg_configPOWER_EXT_1V8_PERIPHERALS
#if dg_configPOWER_EXT_1V8_PERIPHERALS == 0
#warning Setting dg_configPOWER_EXT_1V8_PERIPHERALS to 1 for FEM to work
#define dg_configPOWER_EXT_1V8_PERIPHERALS 1
#endif
#if dg_configPOWER_1V8P == 0
#warning Setting dg_configPOWER_1V8P to 1 for FEM to work
#undef dg_configPOWER_1V8P
#define dg_configPOWER_1V8P 1
#endif
#define dg_configFEM_SKY66112_11_FEM_BIAS_V18P
@@ -59,7 +68,7 @@
#endif
#ifndef dg_configFEM_SKY66112_11_CSD_PIN
#define dg_configFEM_SKY66112_11_CSD_PIN HW_GPIO_PIN_2
#define dg_configFEM_SKY66112_11_CSD_PIN HW_GPIO_PIN_3
#endif
#ifndef dg_configFEM_SKY66112_11_CPS_PORT
@@ -67,7 +76,7 @@
#endif
#ifndef dg_configFEM_SKY66112_11_CPS_PIN
#define dg_configFEM_SKY66112_11_CPS_PIN HW_GPIO_PIN_7
#define dg_configFEM_SKY66112_11_CPS_PIN HW_GPIO_PIN_6
#endif
#ifndef dg_configFEM_SKY66112_11_CRX_PORT
@@ -75,7 +84,7 @@
#endif
#ifndef dg_configFEM_SKY66112_11_CRX_PIN
#define dg_configFEM_SKY66112_11_CRX_PIN HW_GPIO_PIN_4
#define dg_configFEM_SKY66112_11_CRX_PIN HW_GPIO_PIN_2
#endif
#ifndef dg_configFEM_SKY66112_11_CTX_PORT
@@ -83,7 +92,7 @@
#endif
#ifndef dg_configFEM_SKY66112_11_CTX_PIN
#define dg_configFEM_SKY66112_11_CTX_PIN HW_GPIO_PIN_6
#define dg_configFEM_SKY66112_11_CTX_PIN HW_GPIO_PIN_5
#endif
#ifndef dg_configFEM_SKY66112_11_CHL_PORT
@@ -91,7 +100,7 @@
#endif
#ifndef dg_configFEM_SKY66112_11_CHL_PIN
#define dg_configFEM_SKY66112_11_CHL_PIN HW_GPIO_PIN_5
#define dg_configFEM_SKY66112_11_CHL_PIN HW_GPIO_PIN_4
#endif
#ifndef dg_configFEM_SKY66112_11_ANTSEL_PORT
@@ -99,7 +108,7 @@
#endif
#ifndef dg_configFEM_SKY66112_11_ANTSEL_PIN
#define dg_configFEM_SKY66112_11_ANTSEL_PIN HW_GPIO_PIN_3
#define dg_configFEM_SKY66112_11_ANTSEL_PIN HW_GPIO_PIN_0
#endif
#endif /* dg_configFEM_DLG_REF_BOARD */
-57
View File
@@ -36,65 +36,8 @@
#ifndef ARMCM0_H
#define ARMCM0_H
#include "global_io.h"
/*
* ==========================================================================
* ---------- Interrupt Number Definition -----------------------------------
* ==========================================================================
*/
/*
* ==========================================================================
* ----------- Processor and Core Peripheral Section ------------------------
* ==========================================================================
*/
#include <core_cm0.h> /* Cortex-M0 processor and core peripherals */
#include "system_ARMCM0.h" /* System Header */
/******************************************************************************/
/* Device Specific Peripheral registers structures */
/******************************************************************************/
/*--------------------- General Purpose Input and Ouptut ---------------------*/
typedef union
{
__IO uint32_t WORD;
__IO uint8_t BYTE[4];
} GPIO_Data_TypeDef;
typedef struct
{
GPIO_Data_TypeDef DATA[256];
__O uint32_t DIR;
uint32_t RESERVED[3];
__O uint32_t IE;
} ARM_GPIO_TypeDef;
/******************************************************************************/
/* Peripheral memory map */
/******************************************************************************/
/* Peripheral and SRAM base address */
#define ARM_SRAM_BASE (( uint32_t)0x20000000UL)
#define ARM_PERIPH_BASE (( uint32_t)0x40000000UL)
/* Peripheral memory map */
#define ARM_GPIO_BASE ARM_PERIPH_BASE
#define ARM_GPIO0_BASE (ARM_GPIO_BASE)
#define ARM_GPIO1_BASE (ARM_GPIO_BASE + 0x0800UL)
#define ARM_GPIO2_BASE (ARM_GPIO_BASE + 0x1000UL)
/******************************************************************************/
/* Peripheral declaration */
/******************************************************************************/
#define ARM_GPIO0 ((ARM_GPIO_TypeDef *) ARM_GPIO0_BASE)
#define ARM_GPIO1 ((ARM_GPIO_TypeDef *) ARM_GPIO1_BASE)
#define ARM_GPIO2 ((ARM_GPIO_TypeDef *) ARM_GPIO2_BASE)
#endif /* ARMCM0_H */
File diff suppressed because it is too large Load Diff
-287
View File
@@ -1,287 +0,0 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup PLATFORM
*
* \brief Black Orca Platform definitions
*
* \{
*/
/**
*****************************************************************************************
*
* @file black_orca.h
*
* @brief Central include header file for the Dialog Black Orca platform.
*
* @version 1.0
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************************
*/
#ifndef __BLACK_ORCA_H__
#define __BLACK_ORCA_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __GNUC__
# define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
/* assert gcc version is at least 4.9.3 */
# if GCC_VERSION < 40903
# error "Please use gcc version 4.9.3 or newer!"
# endif
#endif
#include "global_io.h"
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
# if dg_configBLACK_ORCA_IC_STEP == BLACK_ORCA_IC_STEP_D
# include "DA14680AD.h"
# elif dg_configBLACK_ORCA_IC_STEP == BLACK_ORCA_IC_STEP_C
# include "DA14680AC.h"
# elif dg_configBLACK_ORCA_IC_STEP == BLACK_ORCA_IC_STEP_A
# include "DA14680AA.h"
# else
# error "Unknown chip stepping for revision A -- check the value of dg_configBLACK_ORCA_IC_STEP"
# endif
#else
# error "Unknown chip revision -- check the value of dg_configBLACK_ORCA_IC_REV"
#endif
#include "core_cm0.h" /* Cortex-M0 processor and core peripherals */
#include "system_DA14680.h" /* DA14680AA System */
/************************
* Black Orca Memory map
************************/
/**
* \brief Remapped device address range.
*/
#define MEMORY_REMAPPED_BASE 0x00000000
#define MEMORY_REMAPPED_END 0x04000000
/**
* \brief Remapped device memory size (64MiB).
*/
#define MEMORY_REMAPPED_SIZE (MEMORY_REMAPPED_END - MEMORY_REMAPPED_BASE)
/**
* \brief ROM address range.
*/
#define MEMORY_ROM_BASE 0x07F00000
#define MEMORY_ROM_END 0x07F40000
/**
* \brief ROM memory size (256KiB).
*/
#define MEMORY_ROM_SIZE (MEMORY_ROM_END - MEMORY_ROM_BASE)
/**
* \brief OTP Controller address range.
*/
#define MEMORY_OTPC_BASE 0x07F40000
#define MEMORY_OTPC_END 0x07F80000
/**
* \brief OTP memory address range.
*/
#define MEMORY_OTP_BASE 0x07F80000
#define MEMORY_OTP_END 0x07FC0000
/**
* \brief OTP memory size (256KiB).
*/
#define MEMORY_OTP_SIZE (MEMORY_OTP_END - MEMORY_OTP_BASE)
/**
* \brief SYSTEM RAM address range.
*/
#define MEMORY_SYSRAM_BASE 0x07FC0000
#define MEMORY_SYSRAM_END 0x07FE0000
/**
* \brief SYSTEM RAM size (128KiB).
*/
#define MEMORY_SYSRAM_SIZE (MEMORY_SYSRAM_END - MEMORY_SYSRAM_BASE)
/**
* \brief CACHE RAM address range.
*/
#define MEMORY_CACHERAM_BASE 0x07FE0000
#define MEMORY_CACHERAM_END 0x08000000
/**
* \brief CACHE RAM size (128KiB).
*/
#define MEMORY_CACHERAM_SIZE (MEMORY_CACHERAM_END - MEMORY_CACHERAM_BASE)
/**
* \brief QSPI Flash address range.
*/
#define MEMORY_QSPIF_BASE 0x08000000
#define MEMORY_QSPIF_END 0x0BF00000
/**
* \brief QSPI Flash memory size (63MiB).
*/
#define MEMORY_QSPIF_SIZE (MEMORY_QSPIF_END - MEMORY_QSPIF_BASE)
/**
* \brief QSPI Controller address range.
*/
#define MEMORY_QSPIC_BASE 0x0C000000
#define MEMORY_QSPIC_END 0x0C100000
#define WITHIN_RANGE(_a, _s, _e) (((uint32_t)(_a) >= (uint32_t)(_s)) && ((uint32_t)(_a) < (uint32_t)(_e)))
/**
* \brief Address is in the remapped memory region
*/
#define IS_REMAPPED_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_REMAPPED_BASE, MEMORY_REMAPPED_END)
/**
* \brief Address is in the ROM region
*/
#define IS_ROM_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_ROM_BASE, MEMORY_ROM_END)
/**
* \brief Address is in the OTP memory region
*/
#define IS_OTP_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_OTP_BASE, MEMORY_OTP_END)
/**
* \brief Address is in the OTP Controller memory region
*/
#define IS_OTPC_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_OTPC_BASE, MEMORY_OTPC_END)
/**
* \brief Address is in the SYSTEM RAM region
*/
#define IS_SYSRAM_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_SYSRAM_BASE, MEMORY_SYSRAM_END)
/**
* \brief Address is in the CACHE RAM region
*/
#define IS_CACHERAM_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_CACHERAM_BASE, MEMORY_CACHERAM_END)
/**
* \brief Address is in the QSPI Flash memory region
*/
#define IS_QSPIF_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_QSPIF_BASE, MEMORY_QSPIF_END)
/**
* \brief Address is in the QSPI Controller memory region
*/
#define IS_QSPIC_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_QSPIC_BASE, MEMORY_QSPIC_END)
#define _BLACK_ORCA_IC_VERSION(revision, stepping) \
((((uint32_t)(revision)) << 8) | ((uint32_t)(stepping)))
/**
* \brief Convenience macro to create the full chip version from revision and stepping.
* It takes letters as arguments.
*/
#define BLACK_ORCA_IC_VERSION(revision, stepping) \
_BLACK_ORCA_IC_VERSION(BLACK_ORCA_IC_REV_##revision, \
BLACK_ORCA_IC_STEP_##stepping)
/**
* \brief The chip version that we compile for.
*/
#define BLACK_ORCA_TARGET_IC \
_BLACK_ORCA_IC_VERSION(dg_configBLACK_ORCA_IC_REV, dg_configBLACK_ORCA_IC_STEP)
/**
* \brief Get the chip version of the system, at runtime.
*/
__STATIC_INLINE uint32_t black_orca_get_chip_version(void)
{
uint32_t rev = CHIP_VERSION->CHIP_REVISION_REG - 'A';
uint32_t step = CHIP_VERSION->CHIP_TEST1_REG;
return _BLACK_ORCA_IC_VERSION(rev, step);
}
// Forward declaration
__RETAINED_CODE void hw_cpm_assert_trigger_gpio(void);
#define ASSERT(a) { if (!(a)) while (1); }
#define ASSERT_WARNING(a) \
{ \
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_WDOG_Msk; \
hw_cpm_assert_trigger_gpio(); \
do {} while(1); \
} \
} \
}
#define ASSERT_ERROR(a) \
{ \
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_WDOG_Msk; \
hw_cpm_assert_trigger_gpio(); \
do {} while(1); \
} \
} \
else { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
__asm volatile ( " bkpt 2 " ); \
} \
} \
}
#ifdef __cplusplus
}
#endif
#endif /* __BLACK_ORCA_H__ */
/**
* \}
* \}
* \}
*/
File diff suppressed because it is too large Load Diff
+403 -296
View File
File diff suppressed because it is too large Load Diff
+42 -600
View File
@@ -1,17 +1,10 @@
/** \addtogroup ARM
* \{
*/
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V3.20
* @date 25. February 2013
*
* @note
*
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2013 ARM LIMITED
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -39,6 +32,12 @@
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
@@ -47,599 +46,42 @@
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i" : : : "memory");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i" : : : "memory");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f" : : : "memory");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f" : : : "memory");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
uint32_t result;
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
__ASM volatile ("");
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
__ASM volatile ("");
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */
/**
\} end of ARM group
*/
+40 -650
View File
@@ -1,17 +1,10 @@
/** \addtogroup ARM
* \{
*/
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V3.20
* @date 05. March 2013
*
* @note
*
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2013 ARM LIMITED
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -39,6 +32,12 @@
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
@@ -49,649 +48,40 @@
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/* Define macros for porting to both thumb1 and thumb2.
* For thumb1, use low register (r0-r7), specified by constrant "l"
* Otherwise, use general registers, specified by constrant "r" */
#if defined (__thumb__) && !defined (__thumb2__)
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
#define __CMSIS_GCC_USE_REG(r) "l" (r)
#else
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
#define __CMSIS_GCC_USE_REG(r) "r" (r)
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
return __builtin_bswap32(value);
#else
uint32_t result;
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
return (short)__builtin_bswap16(value);
#else
uint32_t result;
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
return (op1 >> op2) | (op1 << (32 - op2));
}
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __ASM volatile ("bkpt "#value)
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint8_t) result); /* Add explicit type cast here */
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint16_t) result); /* Add explicit type cast here */
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
{
__ASM volatile ("clrex" ::: "memory");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
{
uint32_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return ((uint8_t) result); /* Add explicit type cast here */
}
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */
/**
\} end of ARM group
*/
-362
View File
@@ -1,362 +0,0 @@
#ifndef IO_H_INCLUDED
#define IO_H_INCLUDED
/*
*----------------------------------------------------------------------------------------------------------------------------------------
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Description : IO, data type definitions and memory map selector.
*
* Remark(s) : None.
*
*----------------------------------------------------------------------------------------------------------------------------------------
*
* Synchronicity keywords:
*
* Id : $Id: global_io.h.rca 1.1 Wed Oct 24 09:42:42 2012 wroovers Experimental wroovers $
* Source : $Source: /services/syncdata/hazelaar/8500/server_vault/applab/14580/sw/keil/keil_full_emb_SWHL6V16LL6V32_24okt_crosstest_OK_fpga14b/src/inc/global_io.h.rca $
*
*----------------------------------------------------------------------------------------------------------------------------------------
*
* Synchronicity history:
*
* Log : $Log: global_io.h.rca $
* Log :
* Log : Revision: 1.1 Mon Oct 1 11:08:33 2012 wroovers
* Log : First Working set
* Log :
* Log : Revision: 1.2 Mon Mar 19 11:52:13 2012 snijders
* Log : Updated the '*int*' typedef's. Put the 'bool' (C++ only) typedef in comment, see comment.
* Log : Added typedef HWORD and updated the already existing WORD and DWORD (according to the ARM data type definitions).
* Log : Removed the IAR depending '__far' and 'inline' defines (obsolete).
* Log : Removed the CR16C_SW_V4 depending '__far' define (obsolete).
* Log : Removed the 'NULL' define (most probably also obsolete).
* Log :
* Log : Revision: 1.1 Tue Mar 6 11:00:42 2012 snijders
* Log : Initial check in for Project bbtester. Copied from "../sitel_io.h" and renamed to "global_io.h".
* Log : Updated the header, no further changes yet.
*
*----------------------------------------------------------------------------------------------------------------------------------------
*
* History:
*
* sc14580a
* --------
* 19-mar-2012/HS: Updated the '*int*' typedef's. Put the 'bool' (C++ only) typedef in comment, see comment.
* Added typedef HWORD and updated the already existing WORD and DWORD (according to the ARM data type definitions).
* Removed the IAR depending '__far' and 'inline' defines (obsolete).
* Removed the CR16C_SW_V4 depending '__far' define (obsolete).
* Removed the 'NULL' define (most probably also obsolete).
* 06-mar-2012/HS: Initial check in for Project bbtester. Copied from "../sitel_io.h" and renamed to "global_io.h".
* Updated the header, no further changes yet.
*
*----------------------------------------------------------------------------------------------------------------------------------------
*/
#include <stddef.h>
typedef unsigned char uint8; // 8 bits
typedef char int8; // 8 bits
typedef unsigned short uint16; // 16 bits
typedef short int16; // 16 bits
typedef unsigned long uint32; // 32 bits
typedef long int32; // 32 bits
typedef unsigned long long uint64; // 64 bits
typedef long long int64; // 64 bits
/* See also "Data Types" on pag. 21 of the (Doulos) Cortex-M0 / SoC 1.0 training documentation. */
typedef unsigned char BYTE; // 8 bits = Byte
typedef unsigned short HWORD; // 16 bits = Halfword
typedef unsigned long WORD; // 32 bits = Word
typedef long long DWORD; // 64 bits = Doubleword
// Retention memory attributes
#define __RETAINED __attribute__((section("retention_mem_zi")))
#define __RETAINED_RW __attribute__((section("retention_mem_rw")))
#define __RETAINED_UNINIT __attribute__((section("retention_mem_uninit")))
#if ((dg_configCODE_LOCATION == NON_VOLATILE_IS_FLASH) && (dg_configEXEC_MODE == MODE_IS_CACHED))
#define __RETAINED_CODE __attribute__((section("text_retained"))) __attribute__((noinline))
#else
#define __RETAINED_CODE
#endif
// Interrupt macros
#define GLOBAL_INT_DISABLE() \
do { \
uint32 __l_irq_rest = __get_PRIMASK(); \
__set_PRIMASK(1); \
DBG_CONFIGURE_HIGH(CMN_TIMING_DEBUG, CMNDBG_CRITICAL_SECTION);
#define GLOBAL_INT_RESTORE() \
if (__l_irq_rest == 0) { \
DBG_CONFIGURE_LOW(CMN_TIMING_DEBUG, CMNDBG_CRITICAL_SECTION); \
__set_PRIMASK(0); \
} \
else { \
__set_PRIMASK(1); \
} \
} while(0)
#ifndef offsetof
#if defined(__GNUC__)
#define offsetof(type, member) __builtin_offsetof(type, member)
#else
#define offsetof(type,member) ((size_t)(&((type *)0)->member))
#endif
#endif
#define containingoffset(address, type, field) ((type*)((uint8*)(address)-(size_t)(&((type*)0)->field)))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
#define BIT8 0x0100
#define BIT9 0x0200
#define BIT10 0x0400
#define BIT11 0x0800
#define BIT12 0x1000
#define BIT13 0x2000
#define BIT14 0x4000
#define BIT15 0x8000
#define BIT16 0x00010000
#define BIT17 0x00020000
#define BIT18 0x00040000
#define BIT19 0x00080000
#define BIT20 0x00100000
#define BIT21 0x00200000
#define BIT22 0x00400000
#define BIT23 0x00800000
#define BIT24 0x01000000
#define BIT25 0x02000000
#define BIT26 0x04000000
#define BIT27 0x08000000
#define BIT28 0x10000000
#define BIT29 0x20000000
#define BIT30 0x40000000
#define BIT31 0x80000000
#if defined(__GNUC__)
#define SWAP16(a) __builtin_bswap16(a)
#define SWAP32(a) __builtin_bswap32(a)
#else
#define SWAP16(a) ((a<<8) | (a>>8))
#define SWAP32(a) ((a>>24 & 0xff) | (a>>8 & 0xff00) | (a<<8 & 0xff0000) | (a<<24 & 0xff000000))
#endif
#if defined(__GNUC__)
#define DEPRECATED __attribute__ ((deprecated))
#define DEPRECATED_MSG(msg) __attribute__ ((deprecated(msg)))
#else
#warning Deprecated macro must be implemented for this compiler
#define DEPRECATED
#define DEPRECATED_MSG(msg)
#endif
/**
* \brief Access register field mask.
*
* Returns a register field mask (aimed to be used with local variables).
* e.g.
* \code
* uint16_t tmp;
*
* tmp = CRG_TOP->SYS_STAT_REG;
*
* if (tmp & REG_MSK(CRG_TOP, SYS_STAT_REG, XTAL16_TRIM_READY)) {
* ...
* \endcode
*/
#define REG_MSK(base, reg, field) \
(base ## _ ## reg ## _ ## field ## _Msk)
/**
* \brief Access register field position.
*
* Returns a register field position (aimed to be used with local variables).
*/
#define REG_POS(base, reg, field) \
(base ## _ ## reg ## _ ## field ## _Pos)
/**
* \brief Access register field value.
*
* Returns a register field value (aimed to be used with local variables).
* e.g.
* \code
* uint16_t tmp;
* int counter;
* tmp = CRG_TOP->TRIM_CTRL_REG;
* counter = REG_GET_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N, tmp);
* ...
* \endcode
*/
#define REG_GET_FIELD(base, reg, field, var) \
((var & (base ## _ ## reg ## _ ## field ## _Msk)) >> \
(base ## _ ## reg ## _ ## field ## _Pos))
/**
* \brief Set register field value.
*
* Sets a register field value (aimed to be used with local variables).
* e.g.
* \code
* uint16_t tmp;
*
* tmp = CRG_TOP->TRIM_CTRL_REG;
* REG_SET_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N, tmp, 10);
* REG_SET_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_TRIM_SELECT, tmp, 2);
* CRG_TOP->TRIM_CTRL_REG = tmp;
* ...
* \endcode
*/
#define REG_SET_FIELD(base, reg, field, var, val) \
var = ((var & ~((base ## _ ## reg ## _ ## field ## _Msk))) | \
((val << (base ## _ ## reg ## _ ## field ## _Pos)) & \
(base ## _ ## reg ## _ ## field ## _Msk)))
/**
* \brief Clear register field value.
*
* Clears a register field value (aimed to be used with local variables).
* e.g.
* \code
* uint16_t tmp;
*
* tmp = CRG_TOP->TRIM_CTRL_REG;
* REG_CLR_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N, tmp);
* REG_CLR_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_TRIM_SELECT, tmp);
* CRG_TOP->TRIM_CTRL_REG = tmp;
* ...
* \endcode
*/
#define REG_CLR_FIELD(base, reg, field, var) \
var &= ~(base ## _ ## reg ## _ ## field ## _Msk)
/**
* \brief Return the value of a register field.
*
* e.g.
* \code
* uint16_t val;
*
* val = REG_GETF(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N);
* ...
* \endcode
*/
#define REG_GETF(base, reg, field) \
(((base->reg) & (base##_##reg##_##field##_Msk)) >> (base##_##reg##_##field##_Pos))
/**
* \brief Set the value of a register field.
*
* e.g.
* \code
*
* REG_SETF(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N, new_value);
* ...
* \endcode
*/
#define REG_SETF(base, reg, field, new_val) \
base->reg = ((base->reg & ~(base##_##reg##_##field##_Msk)) | \
((base##_##reg##_##field##_Msk) & ((new_val) << (base##_##reg##_##field##_Pos))))
/**
* \brief Set a bit of a register.
*
* e.g.
* \code
*
* REG_SET_BIT(CRG_TOP, CLK_TMR_REG, TMR1_ENABLE);
* ...
* \endcode
*/
#define REG_SET_BIT(base, reg, field) \
do { \
base->reg |= (1 << (base##_##reg##_##field##_Pos)); \
} while (0)
/**
* \brief Clear a bit of a register.
*
* e.g.
* \code
*
* REG_CLR_BIT(CRG_TOP, CLK_TMR_REG, TMR1_ENABLE);
* ...
* \endcode
*/
#define REG_CLR_BIT(base, reg, field) \
do { \
base->reg &= ~(base##_##reg##_##field##_Msk); \
} while (0)
/**
* \brief Sets register bits, indicated by the mask, to a value.
*
* e.g.
* \code
* REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_5_REG, 0xFF00, 0x1818);
* \endcode
*/
#define REG_SET_MASKED(base, reg, mask, value) \
do { \
base->reg = (base->reg & ~(mask)) | ((value) & (mask)); \
} while (0)
#define ENABLE_DEBUGGER \
do { \
REG_SET_BIT(CRG_TOP, SYS_CTRL_REG, DEBUGGER_ENABLE); \
} while(0)
#define DISABLE_DEBUGGER \
do { \
REG_CLR_BIT(CRG_TOP, SYS_CTRL_REG, DEBUGGER_ENABLE); \
} while(0)
#define SWRESET \
do { \
REG_SET_BIT(GPREG, DEBUG_REG, SW_RESET); \
} while (0)
#endif
+15 -7
View File
@@ -40,7 +40,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
*****************************************************************************************
*/
@@ -118,20 +119,27 @@ static inline bool in_interrupt(void)
*/
extern const int8_t __dialog_interrupt_priorities[];
#if (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A) && (dg_configUSE_AUTO_CHIP_DETECTION != 1)
#define LAST_IRQn PLL_LOCK_IRQn
#else
#define LAST_IRQn RESERVED31_IRQn
#endif
/*
* Following macros allow easy way to build table with interrupt priorities.
* See example in set_interrupt_priorities function description.
*/
#define INTERRUPT_PRIORITY_CONFIG_START(name) const int8_t name[] = {
#define PRIORITY_0 (RESERVED31_IRQn + 1)
#define PRIORITY_1 (RESERVED31_IRQn + 2)
#define PRIORITY_2 (RESERVED31_IRQn + 3)
#define PRIORITY_3 (RESERVED31_IRQn + 4)
#define PRIORITY_TABLE_END (RESERVED31_IRQn + 5)
#define PRIORITY_0 (LAST_IRQn + 1)
#define PRIORITY_1 (LAST_IRQn + 2)
#define PRIORITY_2 (LAST_IRQn + 3)
#define PRIORITY_3 (LAST_IRQn + 4)
#define PRIORITY_TABLE_END (LAST_IRQn + 5)
#define INTERRUPT_PRIORITY_CONFIG_END PRIORITY_TABLE_END };
#ifdef __cplusplus
extern }
}
#endif
#endif /* INTERRUPTS_H_ */
+777
View File
@@ -0,0 +1,777 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup PLATFORM
*
* \brief Platform definitions
*
* \{
*/
/**
*****************************************************************************************
*
* @file sdk_defs.h
*
* @brief Central include header file with platform definitions.
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*****************************************************************************************
*/
#ifndef __SDK_DEFS_H__
#define __SDK_DEFS_H__
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __GNUC__
# define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
/* assert gcc version is at least 4.9.3 */
# if GCC_VERSION < 40903
# error "Please use gcc version 4.9.3 or newer!"
# endif
#endif
#if (dg_configUSE_AUTO_CHIP_DETECTION == 1)
/* use a register description that is generic enough for our needs */
# include "DA14680AE.h"
#else
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
# if dg_configBLACK_ORCA_IC_STEP == BLACK_ORCA_IC_STEP_E
# include "DA14680AE.h"
# else
# error "Unknown chip stepping for revision A -- check the value of dg_configBLACK_ORCA_IC_STEP"
# endif
#elif dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B
# if dg_configBLACK_ORCA_IC_STEP == BLACK_ORCA_IC_STEP_A
# include "DA14680BA.h"
# else
# error "Unknown chip stepping for revision B -- check the value of dg_configBLACK_ORCA_IC_STEP"
# endif
#else
# error "Unknown chip revision -- check the value of dg_configBLACK_ORCA_IC_REV"
#endif
#endif
#include "core_cm0.h" /* Cortex-M0 processor and core peripherals */
#include "system_DA14680.h" /* DA14680AA System */
/************************
* Memory map
************************/
/**
* \brief Remapped device base address.
*/
#define MEMORY_REMAPPED_BASE 0x00000000UL
#define MEMORY_REMAPPED_END 0x04000000UL
/**
* \brief Remapped device memory size (64MiB).
*/
#define MEMORY_REMAPPED_SIZE (MEMORY_REMAPPED_END - MEMORY_REMAPPED_BASE)
/**
* \brief ROM base address.
*/
#define MEMORY_ROM_BASE 0x07F00000UL
#define MEMORY_ROM_END 0x07F40000UL
/**
* \brief ROM memory size (256KiB).
*/
#define MEMORY_ROM_SIZE (MEMORY_ROM_END - MEMORY_ROM_BASE)
/**
* \brief OTP Controller base address.
*/
#define MEMORY_OTPC_BASE 0x07F40000UL
#define MEMORY_OTPC_END 0x07F80000UL
/**
* \brief OTP memory base address.
*/
#define MEMORY_OTP_BASE 0x07F80000UL
#define MEMORY_OTP_END 0x07FC0000UL
/**
* \brief OTP memory size (256KiB).
*/
#define MEMORY_OTP_SIZE (MEMORY_OTP_END - MEMORY_OTP_BASE)
/**
* \brief SYSTEM RAM base address.
*/
#define MEMORY_SYSRAM_BASE 0x07FC0000UL
#define MEMORY_SYSRAM_END 0x07FE0000UL
/**
* \brief SYSTEM RAM size (128KiB).
*/
#define MEMORY_SYSRAM_SIZE (MEMORY_SYSRAM_END - MEMORY_SYSRAM_BASE)
/**
* \brief CACHE RAM base address.
*/
#define MEMORY_CACHERAM_BASE 0x07FE0000UL
#define MEMORY_CACHERAM_END 0x08000000UL
/**
* \brief CACHE RAM size (128KiB).
*/
#define MEMORY_CACHERAM_SIZE (MEMORY_CACHERAM_END - MEMORY_CACHERAM_BASE)
/**
* \brief QSPI Flash base address.
*/
#define MEMORY_QSPIF_BASE 0x08000000UL
#define MEMORY_QSPIF_END 0x0BF00000UL
/**
* \brief QSPI Flash memory size (63MiB).
*/
#define MEMORY_QSPIF_SIZE (MEMORY_QSPIF_END - MEMORY_QSPIF_BASE)
/**
* \brief QSPI Controller base address.
*/
#define MEMORY_QSPIC_BASE 0x0C000000UL
#define MEMORY_QSPIC_END 0x0C100000UL
/**
* \brief ECC engine microcode base address.
*/
#define MEMORY_ECC_UCODE_BASE 0x40030000UL
/**
* \brief TRNG FIFO address
*/
#define MEMORY_TRNG_FIFO 0x40040000UL
#define WITHIN_RANGE(_a, _s, _e) (((uint32_t)(_a) >= (uint32_t)(_s)) && ((uint32_t)(_a) < (uint32_t)(_e)))
/**
* \brief Address is in the remapped memory region
*/
#define IS_REMAPPED_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_REMAPPED_BASE, MEMORY_REMAPPED_END)
/**
* \brief Address is in the ROM region
*/
#define IS_ROM_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_ROM_BASE, MEMORY_ROM_END)
/**
* \brief Address is in the OTP memory region
*/
#define IS_OTP_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_OTP_BASE, MEMORY_OTP_END)
/**
* \brief Address is in the OTP Controller memory region
*/
#define IS_OTPC_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_OTPC_BASE, MEMORY_OTPC_END)
/**
* \brief Address is in the SYSTEM RAM region
*/
#define IS_SYSRAM_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_SYSRAM_BASE, MEMORY_SYSRAM_END)
/**
* \brief Address is in the CACHE RAM region
*/
#define IS_CACHERAM_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_CACHERAM_BASE, MEMORY_CACHERAM_END)
/**
* \brief Address is in the QSPI Flash memory region
*/
#define IS_QSPIF_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_QSPIF_BASE, MEMORY_QSPIF_END)
/**
* \brief Address is in the QSPI Controller memory region
*/
#define IS_QSPIC_ADDRESS(_a) WITHIN_RANGE((_a), MEMORY_QSPIC_BASE, MEMORY_QSPIC_END)
#define _BLACK_ORCA_IC_VERSION(revision, stepping) \
(((revision) << 8) | (stepping))
/**
* \brief Convenience macro to create the full chip version from revision and stepping.
* It takes letters as arguments.
*/
#define BLACK_ORCA_IC_VERSION(revision, stepping) \
_BLACK_ORCA_IC_VERSION(BLACK_ORCA_IC_REV_##revision, \
BLACK_ORCA_IC_STEP_##stepping)
/**
* \brief The chip version that we compile for.
*/
#define BLACK_ORCA_TARGET_IC \
_BLACK_ORCA_IC_VERSION(dg_configBLACK_ORCA_IC_REV, dg_configBLACK_ORCA_IC_STEP)
/**
* \brief Zero-initialized data retained memory attribute
*/
#define __RETAINED __attribute__((section("retention_mem_zi"))) // RetRAM0
#define __RETAINED_1 __attribute__((section("retention_mem_1_zi"))) // RetRAM1
/**
* \brief Initialized data retained memory attribute
*/
#define __RETAINED_RW __attribute__((section("retention_mem_init")))
/**
* \brief Uninitialized data retained memory attribute
*/
#define __RETAINED_UNINIT __attribute__((section("retention_mem_uninit")))
/**
* \brief Constant data retained memory attribute
*/
#define __RETAINED_CONST_INIT __attribute__((section("retention_mem_const")))
/**
* \brief Text retained memory attribute
*/
#if ((dg_configCODE_LOCATION == NON_VOLATILE_IS_FLASH) && (dg_configEXEC_MODE == MODE_IS_CACHED))
#define __RETAINED_CODE __attribute__((section("text_retained"))) __attribute__((noinline)) __attribute__((optimize ("no-tree-switch-conversion")))
#else
#define __RETAINED_CODE
#endif
/**
* \brief Attribute to tell the compiler to consider a symbol as used
*/
#define __USED __attribute__((used))
/**
* \brief Attribute to tell the compiler to consider a symbol as externally visible (for LTO)
*/
#define __LTO_EXT __attribute__((externally_visible))
extern uint32_t black_orca_chip_version;
#define CHIP_IS_AE (black_orca_chip_version == BLACK_ORCA_IC_VERSION(A, E))
#define CHIP_IS_BA (black_orca_chip_version == BLACK_ORCA_IC_VERSION(B, A))
/**
* \brief Get the chip version of the system, at runtime.
*/
__STATIC_INLINE uint32_t black_orca_get_chip_version(void)
{
uint32_t rev = CHIP_VERSION->CHIP_REVISION_REG - 'A';
uint32_t step = CHIP_VERSION->CHIP_TEST1_REG;
return _BLACK_ORCA_IC_VERSION(rev, step);
}
// Forward declaration
__RETAINED_CODE void hw_cpm_assert_trigger_gpio(void);
/**
* \brief Assert as warning macro
*
* \note Active only while in development mode
*/
#define ASSERT_WARNING(a) \
{ \
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_WDOG_Msk; \
hw_cpm_assert_trigger_gpio(); \
do {} while(1); \
} \
} \
}
/**
* \brief Assert as error macro
*
*/
#define ASSERT_ERROR(a) \
{ \
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_WDOG_Msk; \
hw_cpm_assert_trigger_gpio(); \
do {} while(1); \
} \
} \
else { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
__asm volatile ( " bkpt 2 " ); \
} \
} \
}
/**
* \brief Assert as warning macro when the system is still uninitialized
*
* \note Active only while in development mode. The SW cursor is not activated.
*/
#define ASSERT_WARNING_UNINIT(a) \
{ \
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_WDOG_Msk; \
do {} while(1); \
} \
} \
}
/**
* \brief Assert as error macro when the system is still uninitialized
*
* \note The SW cursor is not activated.
*/
#define ASSERT_ERROR_UNINIT(a) \
{ \
if (dg_configIMAGE_SETUP == DEVELOPMENT_MODE) { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_WDOG_Msk; \
do {} while(1); \
} \
} \
else { \
if (!(a)) { \
__asm volatile ( " cpsid i " ); \
__asm volatile ( " bkpt 2 " ); \
} \
} \
}
/**
* \brief Macro to disable all interrupts
*
* This macro must always be used with GLOBAL_INT_RESTORE(). E.g.
*
* \code{.c}
* GLOBAL_INT_DISABLE();
* ... code to be executed with interrupts disabled ...
* GLOBAL_INT_RESTORE();
* \endcode
*
* \sa GLOBAL_INT_RESTORE
*/
#define GLOBAL_INT_DISABLE() \
do { \
unsigned int __l_irq_rest; \
__asm volatile ("mrs %0, primask \n\t" \
"mov r1, $1 \n\t" \
"msr primask, r1 \n\t" \
: "=r" (__l_irq_rest) \
: \
: "r1" \
); \
DBG_CONFIGURE_HIGH(CMN_TIMING_DEBUG, CMNDBG_CRITICAL_SECTION);
/**
* \brief Macro to restore all interrupts
*
* This macro must always be used after GLOBAL_INT_DISABLE(). E.g.
*
* \code{.c}
* GLOBAL_INT_DISABLE();
* ... code to be executed with interrupts disabled ...
* GLOBAL_INT_RESTORE();
* \endcode
*
* \sa GLOBAL_INT_DISABLE
*/
#define GLOBAL_INT_RESTORE() \
if (__l_irq_rest == 0) { \
DBG_CONFIGURE_LOW(CMN_TIMING_DEBUG, CMNDBG_CRITICAL_SECTION); \
} \
__asm volatile ("msr primask, %0 \n\t" \
: \
: "r" (__l_irq_rest) \
: \
); \
} while(0)
#define containingoffset(address, type, field) ((type*)((uint8*)(address)-(size_t)(&((type*)0)->field)))
/**
* \brief Macro the minimum of two values
*
* \param[in] a First value
* \param[in] b Second value
*/
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
/**
* \brief Macro the maximum of two values
*
* \param[in] a First value
* \param[in] b Second value
*/
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
/**
* \brief Macro to swap the bytes of a 16-bit variable
*
* \param[in] a The 16-bit variable
*/
#if defined(__GNUC__)
#define SWAP16(a) __builtin_bswap16(a)
#else
#define SWAP16(a) ((a<<8) | (a>>8))
#endif
/**
* \brief Macro to swap the bytes of a 32-bit variable
*
* \param[in] a The 32-bit variable
*/
#if defined(__GNUC__)
#define SWAP32(a) __builtin_bswap32(a)
#else
#define SWAP32(a) ((a>>24 & 0xff) | (a>>8 & 0xff00) | (a<<8 & 0xff0000) | (a<<24 & 0xff000000))
#endif
#if defined(__GNUC__)
#define DEPRECATED __attribute__ ((deprecated))
#else
#warning Deprecated macro must be implemented for this compiler
#define DEPRECATED
#endif
#if defined(__GNUC__)
#define DEPRECATED_MSG(msg) __attribute__ ((deprecated(msg)))
#else
#warning Deprecated macro must be implemented for this compiler
#define DEPRECATED_MSG(msg)
#endif
/* The following exist in ROM code */
void __aeabi_memcpy(void *dest, const void *src, size_t n);
void __aeabi_memmove(void *dest, const void *src, size_t n);
void __aeabi_memset(void *dest, size_t n, int c);
/**
* \brief Optimized memcpy
*/
#define OPT_MEMCPY __aeabi_memcpy
/**
* \brief Optimized memmove
*/
#define OPT_MEMMOVE __aeabi_memmove
/**
* \brief Optimized memset
*/
#define OPT_MEMSET(s, c, n) __aeabi_memset(s, n, c)
/**
* \brief Access register field mask.
*
* Returns a register field mask (aimed to be used with local variables).
* e.g.
* \code
* uint16_t tmp;
*
* tmp = CRG_TOP->SYS_STAT_REG;
*
* if (tmp & REG_MSK(CRG_TOP, SYS_STAT_REG, XTAL16_TRIM_READY)) {
* ...
* \endcode
*/
#define REG_MSK(base, reg, field) \
(base ## _ ## reg ## _ ## field ## _Msk)
/**
* \brief Access register field position.
*
* Returns a register field position (aimed to be used with local variables).
*/
#define REG_POS(base, reg, field) \
(base ## _ ## reg ## _ ## field ## _Pos)
/**
* \brief Access register field value.
*
* Returns a register field value (aimed to be used with local variables).
* e.g.
* \code
* uint16_t tmp;
* int counter;
* tmp = CRG_TOP->TRIM_CTRL_REG;
* counter = REG_GET_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N, tmp);
* ...
* \endcode
*/
#define REG_GET_FIELD(base, reg, field, var) \
((var & (base ## _ ## reg ## _ ## field ## _Msk)) >> \
(base ## _ ## reg ## _ ## field ## _Pos))
/**
* \brief Set register field value.
*
* Sets a register field value (aimed to be used with local variables).
* e.g.
* \code
* uint16_t tmp;
*
* tmp = CRG_TOP->TRIM_CTRL_REG;
* REG_SET_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N, tmp, 10);
* REG_SET_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_TRIM_SELECT, tmp, 2);
* CRG_TOP->TRIM_CTRL_REG = tmp;
* ...
* \endcode
*/
#define REG_SET_FIELD(base, reg, field, var, val) \
var = ((var & ~((base ## _ ## reg ## _ ## field ## _Msk))) | \
(((val) << (base ## _ ## reg ## _ ## field ## _Pos)) & \
(base ## _ ## reg ## _ ## field ## _Msk)))
/**
* \brief Clear register field value.
*
* Clears a register field value (aimed to be used with local variables).
* e.g.
* \code
* uint16_t tmp;
*
* tmp = CRG_TOP->TRIM_CTRL_REG;
* REG_CLR_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N, tmp);
* REG_CLR_FIELD(CRG_TOP, TRIM_CTRL_REG, XTAL_TRIM_SELECT, tmp);
* CRG_TOP->TRIM_CTRL_REG = tmp;
* ...
* \endcode
*/
#define REG_CLR_FIELD(base, reg, field, var) \
var &= ~(base ## _ ## reg ## _ ## field ## _Msk)
/**
* \brief Return the value of a register field.
*
* e.g.
* \code
* uint16_t val;
*
* val = REG_GETF(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N);
* ...
* \endcode
*/
#define REG_GETF(base, reg, field) \
(((base->reg) & (base##_##reg##_##field##_Msk)) >> (base##_##reg##_##field##_Pos))
/**
* \brief Set the value of a register field.
*
* e.g.
* \code
*
* REG_SETF(CRG_TOP, TRIM_CTRL_REG, XTAL_COUNT_N, new_value);
* ...
* \endcode
*/
#define REG_SETF(base, reg, field, new_val) \
base->reg = ((base->reg & ~(base##_##reg##_##field##_Msk)) | \
((base##_##reg##_##field##_Msk) & ((new_val) << (base##_##reg##_##field##_Pos))))
/**
* \brief Set a bit of a register.
*
* e.g.
* \code
*
* REG_SET_BIT(CRG_TOP, CLK_TMR_REG, TMR1_ENABLE);
* ...
* \endcode
*/
#define REG_SET_BIT(base, reg, field) \
do { \
base->reg |= (1 << (base##_##reg##_##field##_Pos)); \
} while (0)
/**
* \brief Clear a bit of a register.
*
* e.g.
* \code
*
* REG_CLR_BIT(CRG_TOP, CLK_TMR_REG, TMR1_ENABLE);
* ...
* \endcode
*/
#define REG_CLR_BIT(base, reg, field) \
do { \
base->reg &= ~(base##_##reg##_##field##_Msk); \
} while (0)
/**
* \brief Sets register bits, indicated by the mask, to a value.
*
* e.g.
* \code
* REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_5_REG, 0xFF00, 0x1818);
* \endcode
*/
#define REG_SET_MASKED(base, reg, mask, value) \
do { \
base->reg = (base->reg & ~(mask)) | ((value) & (mask)); \
} while (0)
/**
* \brief Sets 16-bit wide register bits, indicated by the field, to a value v.
*/
#define BITS16(base, reg, field, v) \
((uint16) (((uint16) (v) << (base ## _ ## reg ## _ ## field ## _Pos)) & \
(base ## _ ## reg ## _ ## field ## _Msk)))
/**
* \brief Sets 32-bit wide register bits, indicated by the field, to a value v.
*/
#define BITS32(base, reg, field, v) \
((uint32) (((uint32) (v) << (base ## _ ## reg ## _ ## field ## _Pos)) & \
(base ## _ ## reg ## _ ## field ## _Msk)))
/**
* \brief Reads 16-bit wide register bits, indicated by the field, to a variable v.
*/
#define GETBITS16(base, reg, v, field) \
((uint16) (((uint16) (v)) & (base ## _ ## reg ## _ ## field ## _Msk)) >> \
(base ## _ ## reg ## _ ## field ## _Pos))
/**
* \brief Reads 32-bit wide register bits, indicated by the field, to a variable v.
*/
#define GETBITS32(base, reg, v, field) \
((uint32) (((uint32) (v)) & (base ## _ ## reg ## _ ## field ## _Msk)) >> \
(base ## _ ## reg ## _ ## field ## _Pos))
/**
* \brief Macro to enable the debugger
*
*/
#define ENABLE_DEBUGGER \
do { \
REG_SET_BIT(CRG_TOP, SYS_CTRL_REG, DEBUGGER_ENABLE); \
} while(0)
/**
* \brief Macro to disable the debugger
*
*/
#define DISABLE_DEBUGGER \
do { \
REG_CLR_BIT(CRG_TOP, SYS_CTRL_REG, DEBUGGER_ENABLE); \
} while(0)
/**
* \brief Macro to cause a software reset
*
*/
#define SWRESET \
do { \
REG_SET_BIT(GPREG, DEBUG_REG, SW_RESET); \
} while (0)
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
#define BIT8 0x0100
#define BIT9 0x0200
#define BIT10 0x0400
#define BIT11 0x0800
#define BIT12 0x1000
#define BIT13 0x2000
#define BIT14 0x4000
#define BIT15 0x8000
#define BIT16 0x00010000
#define BIT17 0x00020000
#define BIT18 0x00040000
#define BIT19 0x00080000
#define BIT20 0x00100000
#define BIT21 0x00200000
#define BIT22 0x00400000
#define BIT23 0x00800000
#define BIT24 0x01000000
#define BIT25 0x02000000
#define BIT26 0x04000000
#define BIT27 0x08000000
#define BIT28 0x10000000
#define BIT29 0x20000000
#define BIT30 0x40000000
#define BIT31 0x80000000
typedef unsigned char uint8; // 8 bits
typedef char int8; // 8 bits
typedef unsigned short uint16; // 16 bits
typedef short int16; // 16 bits
typedef unsigned long uint32; // 32 bits
typedef long int32; // 32 bits
typedef unsigned long long uint64; // 64 bits
typedef long long int64; // 64 bits
/* See also "Data Types" on pag. 21 of the (Doulos) Cortex-M0 / SoC 1.0 training documentation. */
typedef unsigned char BYTE; // 8 bits = Byte
typedef unsigned short HWORD; // 16 bits = Halfword
typedef unsigned long WORD; // 32 bits = Word
typedef long long DWORD; // 64 bits = Doubleword
#ifdef __cplusplus
}
#endif
#endif /* __SDK_DEFS_H__ */
/**
* \}
* \}
* \}
*/
+14 -32
View File
@@ -41,6 +41,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*****************************************************************************************
*/
@@ -49,11 +50,16 @@
#include <stdint.h>
#define SUOTA_VERSION_1_0 10
#define SUOTA_VERSION_1_1 11
#define SUOTA_VERSION_1_2 12
#define SUOTA_VERSION_1_3 13
#ifndef SUOTA_VERSION
#define SUOTA_VERSION SUOTA_VERSION_1_1
#define SUOTA_VERSION SUOTA_VERSION_1_3
#endif
#if SUOTA_PSM && (SUOTA_VERSION < SUOTA_VERSION_1_2)
# error "SUOTA_PSM is only applicable to SUOTA_VERSION >= 1.2"
#endif
/**
@@ -61,6 +67,8 @@
*
* \brief SUOTA 1.1 product header as defined by Dialog SUOTA specification.
*
* \note the same header is used for any SUOTA version newer than 1.1
*
*/
typedef struct {
uint8_t signature[2];
@@ -68,37 +76,18 @@ typedef struct {
uint32_t current_image_location;
uint32_t update_image_location;
uint8_t reserved[8];
} suota_1_1_product_header_t;
} __attribute__((packed)) suota_1_1_product_header_t;
#define SUOTA_1_1_PRODUCT_HEADER_SIGNATURE_B1 0x70
#define SUOTA_1_1_PRODUCT_HEADER_SIGNATURE_B2 0x62
#define SUOTA_1_0_PRODUCT_HEADER_SIGNATURE_B1 0x70
#define SUOTA_1_0_PRODUCT_HEADER_SIGNATURE_B2 0x52
/**
* \struct suota_1_0_image_header_t
*
* \brief SUOTA 1.0 image header as defined by Dialog SUOTA specification.
*
*/
typedef struct {
uint8_t signature[2];
uint8_t valid_flag;
uint8_t image_id;
uint32_t code_size;
uint32_t crc;
uint8_t version[16];
uint32_t timestamp;
uint8_t encryption;
uint8_t reserved[31];
} suota_1_0_image_header_t;
/**
* \struct suota_1_1_image_header_t
*
* \brief SUOTA 1.1 image header as defined by Dialog SUOTA specification.
*
* \note the same header is used for any SUOTA version newer than 1.1
*
*/
typedef struct {
uint8_t signature[2];
@@ -108,24 +97,17 @@ typedef struct {
uint8_t version[16];
uint32_t timestamp;
uint32_t exec_location;
} suota_1_1_image_header_t;
} __attribute__((packed)) suota_1_1_image_header_t;
#define SUOTA_1_1_IMAGE_HEADER_SIGNATURE_B1 0x70
#define SUOTA_1_1_IMAGE_HEADER_SIGNATURE_B2 0x61
#define SUOTA_1_0_IMAGE_HEADER_SIGNATURE_B1 0x70
#define SUOTA_1_0_IMAGE_HEADER_SIGNATURE_B2 0x51
#define SUOTA_1_1_IMAGE_FLAG_FORCE_CRC 0x01
#define SUOTA_1_1_IMAGE_FLAG_VALID 0x02
#define SUOTA_1_1_IMAGE_FLAG_RETRY1 0x04
#define SUOTA_1_1_IMAGE_FLAG_RETRY2 0x08
#if (SUOTA_VERSION == SUOTA_VERSION_1_0)
typedef suota_1_0_image_header_t suota_image_header_t;
#else
typedef suota_1_1_image_header_t suota_image_header_t;
#endif
#endif /* SUOTA_H_ */
+171 -16
View File
@@ -4,8 +4,6 @@
* \addtogroup SYSTEM
* \{
* \addtogroup MEMORY
*
* \brief QSPI flash access when running in auto mode
*
* \{
*/
@@ -17,6 +15,14 @@
*
* @brief Access QSPI flash when running in auto mode
*
* The QSPI controller allows to execute code directly from QSPI flash.
* When code is executing from flash, it is not possible to reprogram the flash.
* To be able to modify the flash when it is used for code execution, it must me assured that
* for the time needed to erase/write, no code is running from flash.
* To achieve this, the code in this module is executed from the RAM.
* Code in this module will not access any other functions or constant variables that could reside
* in flash.
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
@@ -41,6 +47,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -50,21 +57,43 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <black_orca.h>
#include <sdk_defs.h>
#include <hw_qspi.h>
#include "hw_cpm.h"
/*
* Debug options
*/
#if __DBG_QSPI_ENABLED
#define __DBG_QSPI_VOLATILE__ volatile
#pragma message "Automode: Debugging is on!"
#else
#define __DBG_QSPI_VOLATILE__
#endif
/*
* Defines (generic)
*/
/* Macros to put functions that need to be copied to ram in one section (retained) */
#define QSPI_SECTION __attribute__((section ("text_retained"), optimize ("no-tree-switch-conversion")))
#define QSPI_SECTION_NO_INLINE __attribute__ ((section ("text_retained"))) __attribute__ ((noinline))
typedef struct qspi_ucode_s {
const uint32_t *code;
uint8_t size;
} qspi_ucode_t;
/*
* Flash specific defines
*/
/**
* QSPI controller allows to execute code directly from QSPI flash.
* When code is executing from flash there is no possibility to reprogram it.
* To be able to modify flash memory while it is used for code execution it must me assured that
* for time needed for erase/write no code is running from flash.
* To achieve this code in this file allows to copy programming functions to RAM and execute it
* from there.
* Great flexibility is achieved by putting all code needed for flash modification in one section
* that will be copied to RAM.
* Code in this section will not access any other functions or constant variables (that could reside
* in flash).
* \brief SUS bit delay after SUSPEND command (in μsec)
*
*/
#define FLASH_SUS_DELAY (20)
/**
* \brief Get size of RAM buffer needed for code to modify QSPI flash.
@@ -120,6 +149,11 @@ size_t qspi_automode_write_flash_page(uint32_t addr, const uint8_t *buf, size_t
*/
void qspi_automode_erase_flash_sector(uint32_t addr);
/**
* \brief Erase whole chip
*/
void qspi_automode_erase_chip(void);
/**
* \brief Read flash memory
*
@@ -138,6 +172,8 @@ size_t qspi_automode_read(uint32_t addr, uint8_t *buf, size_t len);
*
* \returns address in CPU address space where data is located
*/
static inline const void *qspi_automode_addr(uint32_t addr) __attribute__((always_inline));
static inline const void *qspi_automode_addr(uint32_t addr)
{
return (const void *) (MEMORY_QSPIF_BASE + addr);
@@ -146,15 +182,134 @@ static inline const void *qspi_automode_addr(uint32_t addr)
/**
* \brief Power up flash
*/
void qspi_automode_flash_power_up(void);
QSPI_SECTION void qspi_automode_flash_power_up(void);
/**
* \brief Set QSPI Flash into power down mode
*/
QSPI_SECTION void qspi_automode_flash_power_down(void);
/**
* \brief Init QSPI controller
*/
bool qspi_automode_init(void);
__RETAINED_CODE bool qspi_automode_init(void);
#if (dg_configDISABLE_BACKGROUND_FLASH_OPS == 0)
/**
* \brief Check if a program or sector erase operation is in progress
*
* \return bool True if the BUSY bit is set else false.
*
* \warning This function checks the value of the BUSY bit in the Status Register 1 of the Flash. It
* is the responsibility of the caller to call the function in the right context. The
* function must be called with interrupts disabled.
*
*/
__RETAINED_CODE bool qspi_check_program_erase_in_progress(void);
/**
* \brief Suspend a Flash program or erase operation
*
* \details This function will try to suspend an ongoing program or erase procedure. The SUS bit is
* checked and the actual status is returned to the caller. Note that the program or erase
* procedure may have been completed before the suspend command is processed by the Flash. In
* this case the SUS bit will be left to 0.
*
* \return bool True if the procedure has been suspended. False if the procedure was not suspended
* successfully or had finished before the suspend command was processed by the Flash.
*
* \warning After the call to this function, the QSPI controller is set to auto mode and the Flash
* access to quad mode (if QUAD_MODE is 1). The function must be called with interrupts
* disabled.
*
*/
__RETAINED_CODE bool qspi_check_and_suspend(void);
/**
* \brief Resume a Flash program or sector erase operation
*
* \warning After the call to this function, the QSPI controller is set to manual mode and the Flash
* access to single mode. The function must be called with interrupts disabled.
*
*/
__RETAINED_CODE void qspi_resume(void);
/**
* \brief Erase a sector of the Flash in manual mode
*
* \param[in] addr The address of the sector to be erased.
*
* \warning This function does not block until the Flash has processed the command! The QSPI
* controller is left to manual mode after the call to this function. The function must be
* called with interrupts disabled.
*
*/
__RETAINED_CODE void flash_erase_sector_manual_mode(uint32_t addr);
/**
* \brief Program data into a page of the Flash in manual mode
*
* \param[in] addr The address of the Flash where the data will be written. It may be anywhere in a
* page.
* \param[in] buf Pointer to the beginning of the buffer that contains the data to be written.
* \param[in] len The number of bytes to be written.
*
* \return size_t The number of bytes written.
*
* \warning The boundary of the page where addr belongs to, will not be crossed! The caller should
* issue another flash_program_page_manual_mode() call in order to write the remaining data
* to the next page. The QSPI controller is left to manual mode after the call to this
* function. The function must be called with interrupts disabled.
*
*/
__RETAINED_CODE size_t flash_program_page_manual_mode(uint32_t addr, const uint8_t *buf,
uint16_t len);
#endif
/**
* \brief Activate Flash command entry mode
*
* \note After the call to this function, the QSPI controller is set to manual mode and the Flash
* access to single mode.
*
* \warning The function must be called with interrupts disabled.
*
*/
__RETAINED_CODE void flash_activate_command_entry_mode(void);
/**
* \brief Deactivate Flash command entry mode
*
* \note After the call to this function, the QSPI controller is set to auto mode and the Flash
* access to quad mode (if QUAD_MODE is 1).
*
* \warning The function must be called with interrupts disabled.
*
*/
__RETAINED_CODE void flash_deactivate_command_entry_mode(void);
/**
* \brief Configure Flash and QSPI controller for system clock frequency
*
* This function is used to change the Flash configuration of the QSPI controller
* to work with the system clock frequency defined in sys_clk. Dummy clock
* cycles could be changed here to support higher clock frequencies.
* QSPI controller clock divider could also be changed if the Flash
* maximum frequency is smaller than the system clock frequency.
* This function must be called before changing system clock frequency.
*
* \param [in] sys_clk System clock frequency
*
*/
__RETAINED_CODE void qspi_automode_sys_clock_cfg(sys_clk_t sys_clk);
/**
* \brief Get ucode required for wake-up sequence
* \return qspi_ucode_t Pointer to the structure containing the ucode and ucode size
*/
const qspi_ucode_t *qspi_automode_get_ucode(void);
#endif /* QSPI_AUTOMODE_H_ */
/**
* \}
* \}
@@ -0,0 +1,173 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup MEMORY
*
* \brief QSPI flash driver framework
* \{
*/
/**
****************************************************************************************
*
* @file qspi_common.h
*
* @brief QSPI flash driver common definitions
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
#ifndef _QSPI_COMMON_H_
#define _QSPI_COMMON_H_
#include "qspi_automode.h"
/*
* Flash Commands
*
* Note: Default command issuing mode is single mode! If commands specific to other modes have to be
* issued then the mode must be changed!
*/
#define CMD_WRITE_STATUS_REGISTER 0x01
#define CMD_WRITE_DISABLE 0x04
#define CMD_READ_STATUS_REGISTER 0x05
#define CMD_WRITE_ENABLE 0x06
#define CMD_SECTOR_ERASE 0x20
#define CMD_QUAD_PAGE_PROGRAM 0x32
#define CMD_QUAD_IO_PAGE_PROGRAM 0x38
#define CMD_BLOCK_ERASE 0x52
#define CMD_CHIP_ERASE 0xC7
#define CMD_FAST_READ_QUAD 0xEB
#define CMD_READ_JEDEC_ID 0x9F
#define CMD_EXIT_CONTINUOUS_MODE 0xFF
#define CMD_RELEASE_POWER_DOWN 0xAB
#define CMD_ENTER_POWER_DOWN 0xB9
#define CMD_FAST_READ_QUAD_4B 0xEC
#define CMD_SECTOR_ERASE_4B 0x21
#define CMD_QUAD_PAGE_PROGRAM_4B 0x34
#define CMD_QUAD_IO_PAGE_PROGRAM_4B 0x3E
/* Erase/Write in progress */
#define FLASH_STATUS_BUSY_BIT 0
#define FLASH_STATUS_BUSY_MASK (1 << FLASH_STATUS_BUSY_BIT)
/* WE Latch bit */
#define FLASH_STATUS_WEL_BIT 1
#define FLASH_STATUS_WEL_MASK (1 << FLASH_STATUS_WEL_BIT)
typedef bool (*is_suspended_cb_t)(void);
typedef void (*initialize_cb_t)(uint8_t device_type, uint8_t device_density);
typedef void (*deactivate_command_entry_mode_cb_t)(void);
typedef void (*sys_clk_cfg_cb_t)(sys_clk_t type);
typedef uint8_t (*get_dummy_bytes_cb_t)(void);
/**
* \brief QSPI Flash configuration structure
*
* This struct is used to define a driver for a specific QSPI flash.
*
* \note The struct instance must be declared as static const for this to work
*/
typedef struct qspi_flash_config {
// Function pointers
initialize_cb_t initialize; /**< Flash-specific initialization */
is_suspended_cb_t is_suspended; /**< Check if flash is in erase/program
suspend state */
deactivate_command_entry_mode_cb_t
deactivate_command_entry_mode; /**< Perform extra steps needed when command
entry mode is deactivated */
sys_clk_cfg_cb_t sys_clk_cfg; /**< Perform Flash configuration when system clock
is changed (e.g. change dummy bytes or QSPIC
clock divider */
get_dummy_bytes_cb_t get_dummy_bytes; /**< Return the number of dummy bytes currently
needed (they may e.g. change when the clock
changes) */
uint8_t manufacturer_id; /**< The Flash JEDEC vendor ID (Cmd 0x9F, 1st byte)
This (and the device_type/device_density)
are needed for flash autodetection */
uint8_t device_type; /**< The Flash JEDEC device type (Cmd 0x9F, 2nd byte) */
uint8_t device_density; /**< The Flash JEDEC device type (Cmd 0x9F, 3rd byte) */
uint8_t erase_opcode; /**< The Flash erase opcode to use */
uint8_t erase_suspend_opcode; /**< The Flash erase suspend opcode to use */
uint8_t erase_resume_opcode; /**< The Flash erase resume opcode to use */
uint8_t page_program_opcode; /**< The Flash page program opcode to use */
bool quad_page_program_address; /**< If true, the address will be transmitted in
QUAD mode when writing a page. Otherwise, it
will be transmitted in single mode */
uint8_t read_erase_progress_opcode; /**< The opcode to use to check if erase is in progress
(Usually the Read Status Reg opcode (0x5)) */
uint8_t erase_in_progress_bit; /**< The bit to check when reading the erase progress */
bool erase_in_progress_bit_high_level; /**< The active state (true: high, false: low) of the bit
above */
uint8_t send_once; /**< If set to 1, the "Performance mode" (or burst, or
continuous; differs per vendor) will be used for read
accesses. In this mode, the read opcode is only sent
once, and subsequent accesses only transfer the address */
uint8_t extra_byte; /**< The extra byte to transmit, when in "Performance mode"
(send once is 1), that tells the flash that it should
stay in this continuous, performance mode */
HW_QSPI_ADDR_SIZE address_size; /**< Whether the flash works in 24- or 32-bit addressing mode */
HW_QSPI_BREAK_SEQ_SIZE break_seq_size; /**< Whether the break sequence, that puts flash out of the
continuous mode, is one or two bytes long (the break byte is
0xFF) */
qspi_ucode_t ucode_wakeup; /**< The QSPIC microcode to use to setup the flash on wakeup. This
is automatically used by the QSPI Controller after wakeup, and
before CPU starts code execution. This is different based on
whether flash was active, in deep power down or completely off
while the system was sleeping */
uint16_t power_down_delay; /**< This is the time, in usec, needed for the flash to go to power
down, after the Power Down command is issued */
uint16_t release_power_down_delay; /**< This is the time, in usec, needed for the flash to exit the power
down mode, after the Release Power Down command is issued */
} qspi_flash_config_t;
extern const qspi_flash_config_t* flash_config_init;
#if (FLASH_AUTODETECT == 1)
extern qspi_flash_config_t *flash_config;
#else
extern const qspi_flash_config_t * const flash_config;
#endif
static void qspi_write(const uint8_t *wbuf, size_t wlen);
static void qspi_transact(const uint8_t *wbuf, size_t wlen, uint8_t *rbuf, size_t rlen);
static uint8_t flash_read_status_register(void);
static void flash_write_status_register(uint8_t value);
static void flash_write_enable(void);
static void qspi_automode_set_dummy_bytes_count(uint8_t count);
static bool flash_is_busy(void);
static inline bool flash_erase_program_in_progress(void);
#endif /* _QSPI_COMMON_H_ */
/**
* \}
* \}
* \}
*/
@@ -0,0 +1,114 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup MEMORY
*
* \{
*/
/**
****************************************************************************************
*
* @file qspi_w25q80ew.h
*
* @brief QSPI flash driver for the Winbond W25Q80EW
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************************
*/
#ifndef _QSPI_W32Q80EW_H_
#define _QSPI_W32Q80EW_H_
#ifndef WINBOND_ID
#define WINBOND_ID 0xEF
#endif
// Device type using command 0x9F
#define W25Q80EW 0x60
#ifndef W25Q_8Mb_SIZE
#define W25Q_8Mb_SIZE 0x14
#endif
#if (FLASH_AUTODETECT == 1) || (dg_configFLASH_MANUFACTURER_ID == WINBOND_ID && \
dg_configFLASH_DEVICE_TYPE == W25Q80EW && dg_configFLASH_DENSITY == W25Q_8Mb_SIZE)
#include "qspi_common.h"
#include "qspi_winbond.h"
static void flash_w25q80ew_sys_clock_cfg(sys_clk_t sys_clk);
static uint8_t flash_w25q80ew_get_dummy_bytes(void);
static const qspi_flash_config_t flash_w25q80ew_config = {
.manufacturer_id = WINBOND_ID,
.device_type = W25Q80EW,
.device_density = W25Q_8Mb_SIZE,
.is_suspended = flash_w25q_is_suspended,
.initialize = flash_w25q_initialize,
.deactivate_command_entry_mode = flash_w25q_deactivate_command_entry_mode,
.sys_clk_cfg = flash_w25q80ew_sys_clock_cfg,
.get_dummy_bytes = flash_w25q80ew_get_dummy_bytes,
.break_seq_size = HW_QSPI_BREAK_SEQ_SIZE_1B,
.address_size = HW_QSPI_ADDR_SIZE_24,
.page_program_opcode = CMD_QUAD_PAGE_PROGRAM,
.quad_page_program_address = false,
.erase_opcode = CMD_SECTOR_ERASE,
.erase_suspend_opcode = W25Q_ERASE_PROGRAM_SUSPEND,
.erase_resume_opcode = W25Q_ERASE_PROGRAM_RESUME,
.read_erase_progress_opcode = CMD_READ_STATUS_REGISTER,
.erase_in_progress_bit = FLASH_STATUS_BUSY_BIT,
.erase_in_progress_bit_high_level = true,
.send_once = 1,
.extra_byte = 0xA0,
.ucode_wakeup = {w25q_ucode_wakeup, sizeof(w25q_ucode_wakeup)},
.power_down_delay = W25Q_POWER_DOWN_DELAY_US,
.release_power_down_delay = W25Q_RELEASE_POWER_DOWN_DELAY_US,
};
#if (FLASH_AUTODETECT == 0)
const qspi_flash_config_t* const flash_config = &flash_w25q80ew_config;
#endif
QSPI_SECTION static void flash_w25q80ew_sys_clock_cfg(sys_clk_t sys_clk)
{
}
QSPI_SECTION static uint8_t flash_w25q80ew_get_dummy_bytes(void)
{
return 2;
}
#endif
#endif /* _QSPI_W32Q80EW_H_ */
/**
* \}
* \}
* \}
*/
@@ -0,0 +1,236 @@
/**
* \addtogroup BSP
* \{
* \addtogroup SYSTEM
* \{
* \addtogroup MEMORY
*
* \{
*/
/**
****************************************************************************************
*
* @file qspi_winbond.h
*
* @brief QSPI flash driver for Winbond flashes - common code
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
#ifndef _QSPI_WINBOND_H_
#define _QSPI_WINBOND_H_
#define WINBOND_ID 0xEF
#if (FLASH_AUTODETECT == 1) || (dg_configFLASH_MANUFACTURER_ID == WINBOND_ID)
#include "qspi_common.h"
#define W25Q_ERASE_PROGRAM_SUSPEND 0x75
#define W25Q_ERASE_PROGRAM_RESUME 0x7A
#define W25Q_WRITE_STATUS_REGISTER2 0x31
#define W25Q_PAGE_PROGRAM 0x02
#define W25Q_WRITE_ENABLE_NON_VOL 0x50
#define W25Q_READ_STATUS_REGISTER2 0x35
#define W25Q_BLOCK_ERASE_64K 0xD8
#define W25Q_FAST_READ_QPI 0x0B
#define W25Q_READ_DEVICE_ID_SINGLE 0x90 // Requires single mode for the command entry!
#define W25Q_READ_DEVICE_ID_DUAL 0x92 // Requires dual mode for the command entry!
#define W25Q_READ_DEVICE_ID_QUAD 0x94
#define W25Q_READ_UNIQUE_ID 0x4B // Requires single mode for the command entry!
#define W25Q_READ_SFDP_REG 0x5A // Requires single mode for the command entry!
#define W25Q_ERASE_SECURITY_REGS 0x44 // Requires single mode for the command entry!
#define W25Q_PROGR_SECURITY_REGS 0x42 // Requires single mode for the command entry!
#define W25Q_READ_SECURITY_REGS 0x48 // Requires single mode for the command entry!
#define W25Q_ENTER_QPI_MODE 0x38 // Requires single mode for the command entry!
#define W25Q_EXIT_QPI_MODE 0xFF // Requires quad mode for the command entry!
/* Suspend */
#define W25Q_STATUS2_SUS_BIT 7
#define W25Q_STATUS2_SUS_MASK (1 << W25Q_STATUS2_SUS_BIT)
/* QPI Enable */
#define W25Q_STATUS2_QE_BIT 1
#define W25Q_STATUS2_QE_MASK (1 << W25Q_STATUS2_QE_BIT)
// Flash power up/down timings
#define W25Q_POWER_DOWN_DELAY_US 3
#define W25Q_RELEASE_POWER_DOWN_DELAY_US 3
#define W25Q_POWER_UP_DELAY_US 10
#if (dg_configFLASH_POWER_OFF == 1)
/**
* \brief uCode for handling the QSPI FLASH activation from power off.
*/
/*
* Should work with all Winbond flashes -- verified with W25Q80EW.
*
* Delay 10usec
* 0x01 // CMD_NBYTES = 0, CMD_TX_MD = 0 (Single), CMD_VALID = 1
* 0xA0 // CMD_WT_CNT_LS = 160 --> 10000 / 62.5 = 160 = 10usec
* 0x00 // CMD_WT_CNT_MS = 0
* Exit from Fast Read mode
* 0x09 // CMD_NBYTES = 1, CMD_TX_MD = 0 (Single), CMD_VALID = 1
* 0x00 // CMD_WT_CNT_LS = 0
* 0x00 // CMD_WT_CNT_MS = 0
* 0xFF // Enable Reset
* (up to 16 words)
*/
const uint32_t w25q_ucode_wakeup[] = {
0x09000001 | (((uint16_t)(W25Q_POWER_UP_DELAY_US*1000/62.5) & 0xFFFF) << 8),
0x00FF0000,
};
#elif (dg_configFLASH_POWER_DOWN == 1)
/**
* \brief uCode for handling the QSPI FLASH release from power-down.
*/
/*
* Should work with all Winbond flashes -- verified with W25Q80EW.
*
* 0x09 // CMD_NBYTES = 1, CMD_TX_MD = 0 (Single), CMD_VALID = 1
* 0x30 // CMD_WT_CNT_LS = 3000 / 62.5 = 48 // 3usec
* 0x00 // CMD_WT_CNT_MS = 0
* 0xAB // Release Power Down
* (up to 16 words)
*/
const uint32_t w25q_ucode_wakeup[] = {
0xAB000009 | (((uint16_t)(W25Q_RELEASE_POWER_DOWN_DELAY_US*1000/62.5) & 0xFFFF) << 8),
};
#else
/**
* \brief uCode for handling the QSPI FLASH exit from the "Continuous Read Mode".
*/
/*
* Should work with all Winbond flashes -- verified with W25Q80EW.
*
* 0x25 // CMD_NBYTES = 4, CMD_TX_MD = 2 (Quad), CMD_VALID = 1
* 0x00 // CMD_WT_CNT_LS = 0
* 0x00 // CMD_WT_CNT_MS = 0
* 0x55 // Clocks 0-1 (A23-16)
* 0x55 // Clocks 2-3 (A15-8)
* 0x55 // Clocks 4-5 (A7-0)
* 0x55 // Clocks 6-7 (M7-0) : M5-4 != '10' ==> Disable "Continuous Read Mode"
* (up to 16 words)
*/
const uint32_t w25q_ucode_wakeup[] = {
0x55000025,
0x00555555,
};
#endif
static bool flash_w25q_is_suspended(void);
static void flash_w25q_initialize(uint8_t device_type, uint8_t device_density);
static void flash_w25q_deactivate_command_entry_mode(void);
/**
* \brief Enable volatile writes to Status Register bits
* \details When this command is issued, any writes to any of the Status Registers of the Flash are
* done as volatile writes. This command is valid only when the Write Status Register command
* follows.
*
* \note This function blocks until the Flash has processed the command.
*/
QSPI_SECTION __attribute__((unused)) static inline void flash_w25q_wre_volatile(void)
{
uint8_t cmd[] = { W25Q_WRITE_ENABLE_NON_VOL };
qspi_write(cmd, 1);
/* Verify */
while (flash_is_busy());
}
QSPI_SECTION __attribute__((unused)) static inline uint8_t flash_w25q_read_status_register_2(void)
{
__DBG_QSPI_VOLATILE__ uint8_t status;
uint8_t cmd[] = { W25Q_READ_STATUS_REGISTER2 };
qspi_transact(cmd, 1, &status, 1);
return status;
}
/**
* \brief Write the Status Register 2 of the Flash
*
* \param[in] value The value to be written.
*
* \note This function blocks until the Flash has processed the command. No verification that the
* value has been actually written is done though. It is up to the caller to decide whether
* such verification is needed or not and execute it on its own.
*/
QSPI_SECTION __attribute__((unused)) static inline void flash_w25q_write_status_register_2(uint8_t value)
{
uint8_t cmd[] = { W25Q_WRITE_STATUS_REGISTER2, value };
qspi_write(cmd, 2);
/* Wait for the Flash to process the command */
while (flash_is_busy());
}
QSPI_SECTION static inline void flash_w25q_enable_quad_mode(void)
{
uint8_t status;
status = flash_w25q_read_status_register_2();
if (!(status & W25Q_STATUS2_QE_MASK)) {
flash_write_enable();
flash_w25q_write_status_register_2(status | W25Q_STATUS2_QE_MASK);
}
}
QSPI_SECTION static bool flash_w25q_is_suspended(void)
{
__DBG_QSPI_VOLATILE__ uint8_t status;
status = flash_w25q_read_status_register_2();
return (status & W25Q_STATUS2_SUS_MASK) != 0;
}
QSPI_SECTION static void flash_w25q_initialize(uint8_t device_type, uint8_t device_density)
{
flash_activate_command_entry_mode();
flash_w25q_enable_quad_mode();
flash_deactivate_command_entry_mode();
}
QSPI_SECTION static void flash_w25q_deactivate_command_entry_mode(void)
{
}
#endif
#endif /* _QSPI_WINBOND_H_ */
/**
* \}
* \}
* \}
*/
File diff suppressed because it is too large Load Diff
+204 -51
View File
@@ -5,15 +5,16 @@
\{
\addtogroup CPM
\{
\brief Clock and Power Manager
*/
/**
****************************************************************************************
*
* @file hw_cpm.h
*
* @brief Clock and Power Manager header file.
*
*
* @file hw_cpm.h
*
* @brief Clock and Power Manager header file.
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
@@ -38,6 +39,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -46,12 +48,7 @@
#if dg_configUSE_HW_CPM
#include "black_orca.h"
#define PRIVILEGED_DATA __attribute__((section("privileged_data_zi")))
#include "sdk_defs.h"
#define SYS_CLK_IS_XTAL16M (0)
#define SYS_CLK_IS_RC16 (1)
@@ -61,6 +58,7 @@
#define LP_CLK_IS_RC32K (0)
#define LP_CLK_IS_RCX (1)
#define LP_CLK_IS_XTAL32K (2)
#define LP_CLK_IS_EXTERNAL (3)
#define DCDC_IS_READY \
(REG_MSK(DCDC, DCDC_STATUS_1_REG, DCDC_VDD_AVAILABLE))
@@ -100,9 +98,9 @@ typedef enum ahbdiv_type {
ahb_div16, //!< Divide by 16
} ahb_div_t;
ahb_div_t cm_ahbclk;
sys_clk_t cm_sysclk;
/**
* \brief The AMBA Peripheral Bus (APB) clock divider
*
@@ -134,6 +132,14 @@ typedef enum cpu_clk_type {
} cpu_clk_t;
/**
* \brief The TCS setting for the BOD control.
* \details If it is zero then the hard-coded SDK code for the BOD setup is used. It it is not zero,
* this is the value that is written to the BOD_CTRL2_REG.
*/
extern uint16_t hw_cpm_bod_enabled_in_tcs;
/**
* \brief Turn on the 1.2V LDO.
*
@@ -165,13 +171,26 @@ __STATIC_INLINE void hw_cpm_set_cache_retained(void)
GLOBAL_INT_RESTORE();
}
/**
* \brief Enable ECC microcode RAM retainment.
*
*/
__STATIC_INLINE void hw_cpm_set_eccram_retained(void)
{
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, PMU_CTRL_REG, RETAIN_ECCRAM);
GLOBAL_INT_RESTORE();
}
/**
* \brief Enable QSPI initialization after wake-up.
*
*/
__STATIC_INLINE void hw_cpm_enable_qspi_init(void)
{
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, SYS_CTRL_REG, QSPI_INIT);
GLOBAL_INT_RESTORE();
}
/**
@@ -185,61 +204,50 @@ __STATIC_INLINE void hw_cpm_setup_retmem(void)
GLOBAL_INT_RESTORE();
}
/**
* \brief Setup the Retention Memory configuration when the image data have to be retained.
*
*/
__STATIC_INLINE void hw_cpm_setup_retmem_no_img_copy(void)
{
GLOBAL_INT_DISABLE();
REG_SETF(CRG_TOP, PMU_CTRL_REG, RETAIN_RAM, dg_configMEM_RETENTION_MODE_PRESERVE_IMAGE);
GLOBAL_INT_RESTORE();
}
/**
* \brief Disable memory retention.
*
* \warning Interrupts must be disabled by the caller!
*
*/
__STATIC_INLINE void hw_cpm_no_retmem(void)
{
CRG_TOP->PMU_CTRL_REG &= ~(REG_MSK(CRG_TOP, PMU_CTRL_REG, RETAIN_RAM) |
REG_MSK(CRG_TOP, PMU_CTRL_REG, RETAIN_CACHE) |
GLOBAL_INT_DISABLE();
CRG_TOP->PMU_CTRL_REG &= ~(REG_MSK(CRG_TOP, PMU_CTRL_REG, RETAIN_RAM) |
REG_MSK(CRG_TOP, PMU_CTRL_REG, RETAIN_CACHE) |
REG_MSK(CRG_TOP, PMU_CTRL_REG, RETAIN_ECCRAM));
GLOBAL_INT_RESTORE();
}
/**
* \brief Enable the clock-less sleep mode.
*
* \warning Interrupts must be disabled by the caller!
*
*/
__STATIC_INLINE void hw_cpm_enable_clockless(void)
{
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, PMU_CTRL_REG, ENABLE_CLKLESS);
GLOBAL_INT_RESTORE();
}
/**
* \brief Disable the clock-less sleep mode.
*
* \warning Interrupts must be disabled by the caller!
*
*/
__STATIC_INLINE void hw_cpm_disable_clockless(void)
{
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, ENABLE_CLKLESS);
GLOBAL_INT_RESTORE();
}
/**
* \brief Activate the "Reset on wake-up" functionality.
*
* \warning Interrupts must be disabled by the caller!
*
*/
__STATIC_INLINE void hw_cpm_enable_reset_on_wup(void)
{
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, PMU_CTRL_REG, RESET_ON_WAKEUP);
GLOBAL_INT_RESTORE();
}
/**
@@ -254,6 +262,14 @@ __RETAINED_CODE void hw_cpm_activate_bod_protection(void);
*/
void hw_cpm_activate_bod_protection_at_init(void);
/**
* \brief Configure BOD protection.
*
* \note Not applicable for DA14680/1-00 chips.
*
*/
void hw_cpm_configure_bod_protection(void);
/**
* \brief Deactivate BOD protection.
*
@@ -265,6 +281,32 @@ __STATIC_INLINE void hw_cpm_deactivate_bod_protection(void)
CRG_TOP->BOD_CTRL2_REG = 0;
}
/**
* \brief Activate BOD protection for 1V4 rail (only for DA14682/3-BA chips!).
*
*/
__STATIC_INLINE void hw_cpm_activate_1v4_bod_protection(void) __attribute__((always_inline));
__STATIC_INLINE void hw_cpm_activate_1v4_bod_protection(void)
{
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B)
REG_SET_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_V14_EN);
#endif
}
/**
* \brief Deactivate BOD protection for 1V4 rail (only for DA14682/3-BA chips!).
*
*/
__STATIC_INLINE void hw_cpm_deactivate_1v4_bod_protection(void) __attribute__((always_inline));
__STATIC_INLINE void hw_cpm_deactivate_1v4_bod_protection(void)
{
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B)
REG_CLR_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_V14_EN);
#endif
}
/**
* \brief Power down the Radio Power Domain.
*
@@ -279,14 +321,14 @@ __STATIC_INLINE void hw_cpm_power_down_radio(void)
/**
* \brief Power down the Peripheral Power Domain.
*
* \warning Interrupts must be disabled by the caller!
*
*/
__STATIC_INLINE void hw_cpm_power_down_periph_pd(void) __attribute__((always_inline));
__STATIC_INLINE void hw_cpm_power_down_periph_pd(void)
{
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, PMU_CTRL_REG, PERIPH_SLEEP);
GLOBAL_INT_RESTORE();
}
/**
@@ -314,14 +356,14 @@ __STATIC_INLINE void hw_cpm_wait_per_power_down(void)
/**
* \brief Power up the Peripherals Power Domain.
*
* \warning Interrupts must be disabled by the caller!
*
*/
__STATIC_INLINE void hw_cpm_power_up_per_pd(void) __attribute__((always_inline));
__STATIC_INLINE void hw_cpm_power_up_per_pd(void)
{
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, PERIPH_SLEEP);
GLOBAL_INT_RESTORE();
while ((CRG_TOP->SYS_STAT_REG & REG_MSK(CRG_TOP, SYS_STAT_REG, PER_IS_UP)) == 0);
}
@@ -381,7 +423,9 @@ __STATIC_INLINE void hw_cpm_activate_pad_latches(void) __attribute__((always_inl
__STATIC_INLINE void hw_cpm_activate_pad_latches(void)
{
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, SYS_CTRL_REG, PAD_LATCH_EN);
GLOBAL_INT_RESTORE();
}
/**
@@ -392,7 +436,9 @@ __STATIC_INLINE void hw_cpm_deactivate_pad_latches(void) __attribute__((always_i
__STATIC_INLINE void hw_cpm_deactivate_pad_latches(void)
{
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, SYS_CTRL_REG, PAD_LATCH_EN);
GLOBAL_INT_RESTORE();
}
/**
@@ -469,7 +515,10 @@ __STATIC_INLINE uint32_t hw_cpm_check_xtal16m_status(void)
*/
__STATIC_INLINE void hw_cpm_enable_xtal16m(void)
{
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, CLK_CTRL_REG, XTAL16M_DISABLE);
GLOBAL_INT_RESTORE();
}
/**
@@ -503,6 +552,18 @@ __STATIC_INLINE void hw_cpm_set_sleep_flag(void)
GPIO->GPIO_CLK_SEL = 1;
}
/**
* \brief Prepare RESET type tracking.
*/
__STATIC_INLINE void hw_cpm_track_reset_type(void) __attribute__((always_inline));
__STATIC_INLINE void hw_cpm_track_reset_type(void)
{
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B)
CRG_TOP->RESET_STAT_REG = 0;
#endif
}
/**
* \brief Check if the system entered sleep.
*
@@ -589,6 +650,8 @@ __STATIC_INLINE uint32_t hw_cpm_get_sysclk(void)
* \retval 3 Divide by 16
*
*/
__STATIC_INLINE uint32_t hw_cpm_get_hclk_div(void) __attribute__((always_inline));
__STATIC_INLINE uint32_t hw_cpm_get_hclk_div(void)
{
return REG_GETF(CRG_TOP, CLK_AMBA_REG, HCLK_DIV);
@@ -598,9 +661,13 @@ __STATIC_INLINE uint32_t hw_cpm_get_hclk_div(void)
* \brief Set the divider of the AMBA High Speed Bus.
*
*/
__STATIC_INLINE void hw_cpm_set_hclk_div(uint32_t div) __attribute__((always_inline));
__STATIC_INLINE void hw_cpm_set_hclk_div(uint32_t div)
{
GLOBAL_INT_DISABLE();
REG_SETF(CRG_TOP, CLK_AMBA_REG, HCLK_DIV, div);
GLOBAL_INT_RESTORE();
}
/**
@@ -621,9 +688,13 @@ __STATIC_INLINE uint32_t hw_cpm_get_pclk_div(void)
* \brief Set the divider of the AMBA Peripheral Bus.
*
*/
__STATIC_INLINE void hw_cpm_set_pclk_div(uint32_t div) __attribute__((always_inline));
__STATIC_INLINE void hw_cpm_set_pclk_div(uint32_t div)
{
GLOBAL_INT_DISABLE();
REG_SETF(CRG_TOP, CLK_AMBA_REG, PCLK_DIV, div);
GLOBAL_INT_RESTORE();
}
/**
@@ -689,7 +760,7 @@ __STATIC_INLINE bool hw_cpm_mac_is_active(void)
*/
__STATIC_INLINE bool hw_cpm_lp_is_rc32k(void)
{
return REG_GETF(CRG_TOP, CLK_32K_REG, RC32K_ENABLE) &&
return REG_GETF(CRG_TOP, CLK_32K_REG, RC32K_ENABLE) &&
(REG_GETF(CRG_TOP, CLK_CTRL_REG, CLK32K_SOURCE) == LP_CLK_IS_RC32K);
}
@@ -709,15 +780,35 @@ __STATIC_INLINE void hw_cpm_lp_set_rcx(void)
* \brief Set XTAL32K as the Low Power clock.
*
* \warning The XTAL32K must have been enabled before calling this function!
* Interrupts must have been disabled before calling this function!
*/
__STATIC_INLINE void hw_cpm_lp_set_xtal32k(void)
{
ASSERT_WARNING(__get_PRIMASK() == 1);
ASSERT_WARNING(REG_GETF(CRG_TOP, CLK_32K_REG, XTAL32K_ENABLE) == 1);
REG_SETF(CRG_TOP, CLK_CTRL_REG, CLK32K_SOURCE, LP_CLK_IS_XTAL32K);
}
/**
/**
* \brief Configure pin to connect an external digital clock.
*
*/
void hw_cpm_configure_ext32k_pins(void);
/**
* \brief Set an external digital clock as the Low Power clock.
*
* \warning Interrupts must have been disabled before calling this function!
*/
__STATIC_INLINE void hw_cpm_lp_set_ext32k(void)
{
ASSERT_WARNING(__get_PRIMASK() == 1);
REG_SETF(CRG_TOP, CLK_CTRL_REG, CLK32K_SOURCE, LP_CLK_IS_EXTERNAL);
}
/**
* \brief Enable RC32K.
*
*/
@@ -954,6 +1045,43 @@ __STATIC_INLINE void hw_cpm_3v3_clamp_off(void)
REG_CLR_BIT(CRG_TOP, AON_SPARE_REG, EN_BATSYS_RET);
}
/**
* \brief Enable OSC16M amplitude regulation
*/
__STATIC_INLINE void hw_cpm_enable_osc16m_amp_reg(void) __attribute__((always_inline));
__STATIC_INLINE void hw_cpm_enable_osc16m_amp_reg(void)
{
REG_CLR_BIT(CRG_TOP, AON_SPARE_REG, OSC16_HOLD_AMP_REG);
}
/**
* \brief Disable OSC16M amplitude regulation
*/
__STATIC_INLINE void hw_cpm_disable_osc16m_amp_reg(void) __attribute__((always_inline));
__STATIC_INLINE void hw_cpm_disable_osc16m_amp_reg(void)
{
REG_SET_BIT(CRG_TOP, AON_SPARE_REG, OSC16_HOLD_AMP_REG);
}
/**
* \brief Sets the state of the 1v8 rail.
*
* \param[in] state true, the 1v8 rail is controlled via dg_config macros
* false, the 1v8 rail is off
*
*/
void hw_cpm_set_1v8_state(bool state);
/**
* \brief Returns the state of the 1v8 rail.
*
* \return false if the 1v8 rail is off, true if it is controlled via dg_config macros
*
*/
__RETAINED_CODE bool hw_cpm_get_1v8_state(void);
/**
* \brief Enable the LDO_VBAT_RET.
*
@@ -982,11 +1110,17 @@ __STATIC_INLINE void hw_cpm_ldo_io_ret_off(void)
{
uint32_t reg = CRG_TOP->LDO_CTRL2_REG;
if (dg_configFLASH_POWER_OFF == 0) {
if (dg_configPOWER_1V8_SLEEP == 1) {
if (dg_configUSE_BOD == 1) {
REG_CLR_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_FLASH_EN);
}
REG_SET_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_RET_DISABLE, reg, 1);
}
if (dg_configPOWER_EXT_1V8_PERIPHERALS == 1) {
if (dg_configPOWER_1V8P == 1) {
if (dg_configUSE_BOD == 1) {
REG_CLR_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_PA_EN);
}
REG_SET_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_PA_RET_DISABLE, reg, 1);
}
@@ -1010,13 +1144,16 @@ __STATIC_INLINE void hw_cpm_start_ldos(void) __attribute__((always_inline));
__STATIC_INLINE void hw_cpm_start_ldos(void)
{
uint32_t reg = CRG_TOP->LDO_CTRL2_REG;
if ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B) &&
(dg_configBLACK_ORCA_IC_STEP == BLACK_ORCA_IC_STEP_A)) {
REG_SETF(CRG_TOP, LDO_CTRL1_REG, LDO_VBAT_RET_LEVEL, 0);
}
REG_SET_BIT(CRG_TOP, LDO_CTRL1_REG, LDO_RADIO_ENABLE);
REG_SET_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V2_ON, reg, 1);
if (dg_configPOWER_FLASH == 1) {
if ((dg_configPOWER_1V8_ACTIVE == 1) && hw_cpm_get_1v8_state()) {
REG_SET_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_ON, reg, 1);
if (dg_configFLASH_POWER_OFF == 1) {
if (dg_configPOWER_1V8_SLEEP == 0) {
REG_SET_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_RET_DISABLE, reg, 1);
}
else {
@@ -1028,7 +1165,7 @@ __STATIC_INLINE void hw_cpm_start_ldos(void)
REG_SET_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_RET_DISABLE, reg, 1);
}
if (dg_configPOWER_EXT_1V8_PERIPHERALS == 1) {
if (dg_configPOWER_1V8P == 1) {
REG_SET_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_PA_ON, reg, 1);
REG_CLR_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_PA_RET_DISABLE, reg);
}
@@ -1086,11 +1223,6 @@ __STATIC_INLINE void hw_cpm_dcdc_off(void)
// Enable the LDOs
hw_cpm_start_ldos();
// Turn off LDO_RADIO (newer chip versions do this automatically!)
if (BLACK_ORCA_TARGET_IC == BLACK_ORCA_IC_VERSION(A, A)) {
REG_CLR_BIT(CRG_TOP, LDO_CTRL1_REG, LDO_RADIO_ENABLE);
}
// Turn off DCDC
DCDC->DCDC_CTRL_0_REG &= ~REG_MSK(DCDC, DCDC_CTRL_0_REG, DCDC_MODE);
}
@@ -1174,7 +1306,9 @@ __STATIC_INLINE void hw_cpm_rfcu_clk_off(void) __attribute__((always_inline));
__STATIC_INLINE void hw_cpm_rfcu_clk_off(void)
{
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, CLK_RADIO_REG, RFCU_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
@@ -1185,7 +1319,9 @@ __STATIC_INLINE void hw_cpm_enable_debugger(void) __attribute__((always_inline))
__STATIC_INLINE void hw_cpm_enable_debugger(void)
{
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, SYS_CTRL_REG, DEBUGGER_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
@@ -1196,9 +1332,25 @@ __STATIC_INLINE void hw_cpm_disable_debugger(void) __attribute__((always_inline)
__STATIC_INLINE void hw_cpm_disable_debugger(void)
{
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, SYS_CTRL_REG, DEBUGGER_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
* \brief Check if the debugger is attached.
*
* \return true, if the debugger is attached, else false.
*
*/
__STATIC_INLINE bool hw_cpm_is_debugger_attached(void) __attribute__((always_inline));
__STATIC_INLINE bool hw_cpm_is_debugger_attached(void)
{
return (REG_GETF(CRG_TOP, SYS_STAT_REG, DBG_IS_ACTIVE) != 0);
}
/**
* \brief Check if any DMA channel is active.
*
@@ -1259,7 +1411,8 @@ __RETAINED_CODE void hw_cpm_reboot_system(void);
*/
__RETAINED_CODE void hw_cpm_delay_usec(uint32_t usec);
/** \brief Trigger a GPIO when ASSERT_WARNING() or ASSERT_ERROR() hits.
/**
* \brief Trigger a GPIO when ASSERT_WARNING() or ASSERT_ERROR() hits.
*
*/
__RETAINED_CODE void hw_cpm_assert_trigger_gpio(void);
+53 -1
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup DMA
* \{
* \brief DMA Controller
*/
/**
@@ -38,6 +39,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -47,7 +49,7 @@
#if dg_configUSE_HW_DMA
#include <stdint.h>
#include <black_orca.h>
#include <sdk_defs.h>
/*
* ENUMERATION DEFINITIONS
@@ -257,6 +259,56 @@ typedef struct {
*/
void hw_dma_channel_initialization(DMA_setup *channel_setup);
/**
* \brief Update DMA source address and length
*
* When DMA is configured for some peripheral, it could be enough to setup only source address
* and data length. Other parameters most likely do not change for same type of transmission
* for values that ware specified in \p hw_dma_channel_initialization().
* This function should speed up DMA start time when only address and size changes from previous
* transmission.
*
* \param [in] channel DMA channel number to modify
* \param [in] addr new source address
* \param [in] length new data transfer length
* \param [in] cb function to call after transmission finishes
*
*/
void hw_dma_channel_update_source(HW_DMA_CHANNEL channel, void* addr, uint16_t length,
hw_dma_transfer_cb cb);
/**
* \brief Update DMA destination address and length
*
* When DMA is configured for some peripheral, it could be enough to setup only destination address
* and data length. Other parameters most likely do not change for same type of transmission
* for values that ware specified in \p hw_dma_channel_initialization().
* This function should speed up DMA start time when only address and size changes from previous
* transmission.
*
* \param [in] channel DMA channel number to modify
* \param [in] addr new source address
* \param [in] length new data transfer length
* \param [in] cb function to call after transmission finishes
*
*/
void hw_dma_channel_update_destination(HW_DMA_CHANNEL channel, void *addr, uint16_t length,
hw_dma_transfer_cb cb);
/**
* \brief Update DMA interrupt trigger index
*
* DMA channel can trigger an interrupt after arbitrary transfer has finished.
* Usually interrupt is triggered after transmission finishes but for cyclic mode,
* where DMA never stops, it is convenient trigger interrupt at other times.
* This function allows to specify the number of transfers after which the interrupt is triggered.
*
* \param [in] channel DMA channel number to modify
* \param [in] int_ix Number of transfers until the interrupt is triggered
*
*/
void hw_dma_channel_update_int_ix(HW_DMA_CHANNEL channel, uint16_t int_ix);
/**
* \brief Enable or disable a DMA channel
*
+198 -17
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup FEM
* \{
* \brief Front End Module for SKYWORKS SKY66112-11
*/
/**
@@ -24,6 +25,16 @@
* CHL : dg_configFEM_SKY66112_11_CHL_PORT/PIN
* ANTSEL: dg_configFEM_SKY66112_11_ANTSEL_PORT/PIN
*
* In order to control an external PA, three GPIOs can be used. These are called RF_ANT_TRIMx, x=0,1,2. Each one of
* these bits is enabled if the corresponding PORT/PIN macros are set:
*
* RF_ANT_TRIM0 : dg_configFEM_SKY66112_11_ANT_TRIM_0_PORT/PIN
* RF_ANT_TRIM1 : dg_configFEM_SKY66112_11_ANT_TRIM_1_PORT/PIN
* RF_ANT_TRIM2 : dg_configFEM_SKY66112_11_ANT_TRIM_2_PORT/PIN
*
* The actual GPIO values for RF_ANT_TRIMx are set by the corresponding MAC, whenever it gains access by the arbiter
* to the RF. This driver only handles the GPIO initialization.
*
* FEM BIAS Voltage control is enabled by the following macros:
*
* V18 : dg_configFEM_SKY66112_11_FEM_BIAS_V18
@@ -31,6 +42,8 @@
*
* If none of them is set, FEM BIAS will not be controlled by this driver.
*
***************************************************************************************
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
@@ -54,7 +67,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
*****************************************************************************************
*/
@@ -70,13 +84,23 @@
/* Configuration/state structure (actually just a byte) */
typedef struct __attribute__ ((__packed__)) {
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
uint8_t tx_power: 1;
uint8_t tx_bypass: 1;
uint8_t rx_bypass: 1;
#else
uint8_t tx_power_ble: 1;
uint8_t tx_bypass_ble: 1;
uint8_t rx_bypass_ble: 1;
uint8_t tx_power_ftdf: 1;
uint8_t tx_bypass_ftdf: 1;
uint8_t rx_bypass_ftdf: 1;
#endif
uint8_t antsel: 1;
uint8_t started: 1;
} hw_fem_config;
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
/**
* \brief Configures FEM TX Power
*
@@ -85,14 +109,6 @@ typedef struct __attribute__ ((__packed__)) {
*/
void hw_fem_set_txpower(bool high);
/**
* \brief Configures FEM Antenna to use
*
* \param [in] one false: antenna 0, true: antenna 1
*
*/
void hw_fem_set_antenna(bool one);
/**
* \brief Configures FEM TX bypass mode
*
@@ -117,14 +133,6 @@ void hw_fem_set_rx_bypass(bool enable);
*/
bool hw_fem_get_txpower(void);
/**
* \brief Gets the selected antenna
*
* \return false: antenna 1, true: antenna 2
*
*/
bool hw_fem_get_antenna(void);
/**
* \brief Gets the TX bypass mode
*
@@ -141,6 +149,179 @@ bool hw_fem_get_tx_bypass(void);
*/
bool hw_fem_get_rx_bypass(void);
#else /* dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B */
#ifdef CONFIG_USE_BLE
/**
* \brief Configures FEM TX Power for BLE
*
* \param [in] high Set true to enable high TX power
*
*/
void hw_fem_set_txpower_ble(bool high);
/**
* \brief Configures FEM TX bypass mode for BLE
*
* \param [in] enable false: Use PA, true: bypass
*
*/
void hw_fem_set_tx_bypass_ble(bool enable);
/**
* \brief Configures FEM RX bypass mode for BLE
*
* \param [in] enable false: Use LNA, true: bypass
*
*/
void hw_fem_set_rx_bypass_ble(bool enable);
/**
* \brief Gets the TX Power setting for BLE
*
* \return true, if TX Power is high, false if low
*
*/
bool hw_fem_get_txpower_ble(void);
/**
* \brief Gets the TX bypass mode for BLE
*
* \return false: No TX bypass, true: TX bypass
*
*/
bool hw_fem_get_tx_bypass_ble(void);
/**
* \brief Gets the RX bypass mode for BLE
*
* \return false: No RX bypass, true: RX bypass
*
*/
bool hw_fem_get_rx_bypass_ble(void);
#endif /* CONFIG_USE_BLE */
#ifdef CONFIG_USE_FTDF
/**
* \brief Configures FEM TX Power for FTDF
*
* \param [in] high Set true to enable high TX power
*
*/
void hw_fem_set_txpower_ftdf(bool high);
/**
* \brief Configures FEM TX bypass mode for FTDF
*
* \param [in] enable false: Use PA, true: bypass
*
*/
void hw_fem_set_tx_bypass_ftdf(bool enable);
/**
* \brief Configures FEM RX bypass mode for FTDF
*
* \param [in] enable false: Use LNA, true: bypass
*
*/
void hw_fem_set_rx_bypass_ftdf(bool enable);
/**
* \brief Gets the TX Power setting for FTDF
*
* \return true, if TX Power is high, false if low
*
*/
bool hw_fem_get_txpower_ftdf(void);
/**
* \brief Gets the TX bypass mode for FTDF
*
* \return false: No TX bypass, true: TX bypass
*
*/
bool hw_fem_get_tx_bypass_ftdf(void);
/**
* \brief Gets the RX bypass mode for FTDF
*
* \return false: No RX bypass, true: RX bypass
*
*/
bool hw_fem_get_rx_bypass_ftdf(void);
#endif /* CONFIG_USE_FTDF */
/**
* \brief Configures FEM TX Power
*
* \param [in] high Set true to enable high TX power
*
* \deprecated Use the BLE/FTDF specific functions instead
*/
void hw_fem_set_txpower(bool high) DEPRECATED;
/**
* \brief Configures FEM TX bypass mode
*
* \param [in] enable false: Use PA, true: bypass
*
* \deprecated Use the BLE/FTDF specific functions instead
*/
void hw_fem_set_tx_bypass(bool enable) DEPRECATED;
/**
* \brief Configures FEM RX bypass mode
*
* \param [in] enable false: Use LNA, true: bypass
*
* \deprecated Use the BLE/FTDF specific functions instead
*/
void hw_fem_set_rx_bypass(bool enable) DEPRECATED;
/**
* \brief Gets the TX Power setting
*
* \return true, if TX Power is high, false if low
*
* \deprecated Use the BLE/FTDF specific functions instead
*/
bool hw_fem_get_txpower(void) DEPRECATED;
/**
* \brief Gets the TX bypass mode
*
* \return false: No TX bypass, true: TX bypass
*
* \deprecated Use the BLE/FTDF specific functions instead
*/
bool hw_fem_get_tx_bypass(void) DEPRECATED;
/**
* \brief Gets the RX bypass mode
*
* \return false: No RX bypass, true: RX bypass
*
* \deprecated Use the BLE/FTDF specific functions instead
*/
bool hw_fem_get_rx_bypass(void) DEPRECATED;
#endif /* dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B */
/**
* \brief Configures FEM Antenna to use
*
* \param [in] one false: antenna 0, true: antenna 1
*
*/
void hw_fem_set_antenna(bool one);
/**
* \brief Gets the selected antenna
*
* \return false: antenna 1, true: antenna 2
*
*/
bool hw_fem_get_antenna(void);
/**
* \brief Sets the FEM Bias
*
+60 -9
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup GPADC
* \{
* \brief General Purpose ADC
*/
/**
@@ -37,7 +38,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
*****************************************************************************************
*/
@@ -48,7 +50,10 @@
#include <stdbool.h>
#include <stdint.h>
#include <black_orca.h>
#include <sdk_defs.h>
extern int16_t hw_gpadc_differential_gain_error;
extern int16_t hw_gpadc_single_ended_gain_error;
/**
* \brief ADC input mode
@@ -310,7 +315,7 @@ static inline void hw_gpadc_set_input(HW_GPADC_INPUT input)
*/
static inline HW_GPADC_INPUT hw_gpadc_get_input(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_SEL);
return (HW_GPADC_INPUT) REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_SEL);
}
/**
@@ -332,7 +337,7 @@ static inline void hw_gpadc_set_input_mode(HW_GPADC_INPUT_MODE mode)
*/
static inline HW_GPADC_INPUT_MODE hw_gpadc_get_input_mode(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_SE);
return (HW_GPADC_INPUT_MODE) REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_SE);
}
/**
@@ -354,7 +359,7 @@ static inline void hw_gpadc_set_clock(HW_GPADC_CLOCK clock)
*/
static inline HW_GPADC_CLOCK hw_gpadc_get_clock(void)
{
return REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_CLK_SEL);
return (HW_GPADC_CLOCK) REG_GETF(GPADC, GP_ADC_CTRL_REG, GP_ADC_CLK_SEL);
}
/**
@@ -652,6 +657,43 @@ static inline uint16_t hw_gpadc_get_offset_negative(void)
return GPADC->GP_ADC_OFFN_REG & REG_MSK(GPADC, GP_ADC_OFFN_REG, GP_ADC_OFFN);
}
/**
* \brief Store Single Ended ADC Gain Error
*
* \param [in] single ADC Single Ended Gain Error
*
*/
static inline void hw_gpadc_store_se_gain_error(int16_t single)
{
hw_gpadc_single_ended_gain_error = single;
}
/**
* \brief Store Differential ADC Gain Error
*
* \param [in] diff ADC Differential Gain Error
*
*/
static inline void hw_gpadc_store_diff_gain_error(int16_t diff)
{
hw_gpadc_differential_gain_error = diff;
}
/**
* \brief Check the availability of ADC Gain Error
*
* \return ADC Gain Error availability
*
*/
static inline bool hw_gpadc_pre_check_for_gain_error(void)
{
if (dg_configUSE_ADC_GAIN_ERROR_CORRECTION == 1) {
return (hw_gpadc_single_ended_gain_error && hw_gpadc_differential_gain_error);
}
return false;
}
/**
* \brief Get raw conversion result value
*
@@ -664,10 +706,7 @@ static inline uint16_t hw_gpadc_get_offset_negative(void)
* \sa hw_gpadc_get_value
*
*/
static inline uint16_t hw_gpadc_get_raw_value(void)
{
return GPADC->GP_ADC_RESULT_REG;
}
uint16_t hw_gpadc_get_raw_value(void);
/**
* \brief Get conversion result value
@@ -686,6 +725,18 @@ static inline uint16_t hw_gpadc_get_value(void)
return hw_gpadc_get_raw_value() >> (6 - MIN(6, hw_gpadc_get_oversampling()));
}
/**
* \brief Get conversion result value without gain compensation and over sampling.
*
* \return conversion result value
*
*/
static inline uint16_t hw_gpadc_get_value_without_gain(void)
{
uint16_t adc_raw_res = GPADC->GP_ADC_RESULT_REG;
return adc_raw_res;
}
/**
* \brief Start a measurement and wait for the result.
*
+4 -2
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup GPIO
* \{
* \brief GPIO Control
*/
/**
@@ -37,7 +38,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
*****************************************************************************************
*/
@@ -48,7 +50,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <black_orca.h>
#include <sdk_defs.h>
/* GPIO layout definitions */
+5 -3
View File
@@ -1,10 +1,11 @@
/**
* \addtogroup BSP
* \{
* \addtogroup DEVICES
* \addtogroup SYSTEM
* \{
* \addtogroup Exception_Handlers
* \{
* \brief Generic Exception Handlers
*/
/**
@@ -37,7 +38,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
*****************************************************************************************
*/
@@ -47,7 +49,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <black_orca.h>
#include <sdk_defs.h>
#define HARDFAULT_MAGIC_NUMBER 0xBADC0FFE
+3 -1
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup LED
* \{
* \brief LED Controller
*/
/**
@@ -38,13 +39,14 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*****************************************************************************************
*/
#ifndef HW_LED_H_
#define HW_LED_H_
#include <black_orca.h>
#include <sdk_defs.h>
/**
* \brief Source for LED1
+24 -16
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup OTPC
* \{
* \brief OTP Memory Controller
*/
/**
@@ -38,6 +39,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -48,7 +50,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <black_orca.h>
#include <sdk_defs.h>
/**
@@ -191,25 +193,29 @@ __RETAINED_CODE HW_OTPC_SYS_CLK_FREQ hw_otpc_convert_sys_clk_mhz(uint32_t clk_fr
*/
static inline void hw_otpc_init(void)
{
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
/*
* Reset OTP controller
*/
OTPC->OTPC_MODE_REG = HW_OTPC_MODE_STBY; // Set OTPC to standby
REG_SET_BIT(CRG_TOP, SYS_CTRL_REG, OTPC_RESET_REQ); // Reset the OTP Controller
REG_CLR_BIT(CRG_TOP, SYS_CTRL_REG, OTPC_RESET_REQ);// Get the OTP Controller out of Reset
GLOBAL_INT_DISABLE();
if ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE))) {
/*
* Reset OTP controller
*/
OTPC->OTPC_MODE_REG = HW_OTPC_MODE_STBY; // Set OTPC to standby
REG_SET_BIT(CRG_TOP, SYS_CTRL_REG, OTPC_RESET_REQ); // Reset the OTPC
REG_CLR_BIT(CRG_TOP, SYS_CTRL_REG, OTPC_RESET_REQ); // Get the OTPC out of Reset
/*
* Initialize the POR registers
*/
OTPC->OTPC_NWORDS_REG = OTPC_NWORDS_REG_RESET;
OTPC->OTPC_TIM1_REG = OTPC_TIM1_REG_RESET;
OTPC->OTPC_TIM2_REG = OTPC_TIM2_REG_RESET;
}
/*
* Initialize the POR registers
*/
OTPC->OTPC_NWORDS_REG = OTPC_NWORDS_REG_RESET;
OTPC->OTPC_TIM1_REG = OTPC_TIM1_REG_RESET;
OTPC->OTPC_TIM2_REG = OTPC_TIM2_REG_RESET;
#endif
/*
* Enable OTPC clock
*/
CRG_TOP->CLK_AMBA_REG |= 1 << REG_POS(CRG_TOP, CLK_AMBA_REG, OTP_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
@@ -221,7 +227,9 @@ static inline void hw_otpc_close(void)
/*
* Disable OTPC clock
*/
GLOBAL_INT_DISABLE();
CRG_TOP->CLK_AMBA_REG &= ~REG_MSK(CRG_TOP, CLK_AMBA_REG, OTP_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
@@ -235,7 +243,7 @@ static inline uint32_t hw_otpc_is_active(void) __attribute__((always_inline));
static inline uint32_t hw_otpc_is_active(void)
{
/*
* Disable OTPC clock
* Check if the OTPC clock is enabled
*/
return !!(CRG_TOP->CLK_AMBA_REG & REG_MSK(CRG_TOP, CLK_AMBA_REG, OTP_ENABLE));
}
+237 -32
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup QSPI
* \{
* \brief QSPI Flash Memory Controller
*/
/**
@@ -37,7 +38,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
*****************************************************************************************
*/
@@ -48,7 +50,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <black_orca.h>
#include <sdk_defs.h>
/**
@@ -96,6 +98,8 @@
((QSPIC_QSPIC_##reg##_REG_##QSPIC_##field##_Msk) & ((new_val) << (QSPIC_QSPIC_##reg##_REG_##QSPIC_##field##_Pos))))
extern uint8_t dummy_num[];
/*
* ENUMERATION DEFINITIONS
*****************************************************************************************
@@ -216,9 +220,8 @@ typedef struct {
* Use this in manual mode.
*
*/
#if (dg_configFLASH_POWER_DOWN == 1)
__attribute__((section("text_retained")))
#endif
static inline void hw_qspi_cs_enable(void) __attribute__((always_inline));
static inline void hw_qspi_cs_enable(void)
{
QSPIC->QSPIC_CTRLBUS_REG = QSPIC_QSPIC_CTRLBUS_REG_QSPIC_EN_CS_Msk;
@@ -230,9 +233,8 @@ static inline void hw_qspi_cs_enable(void)
* Use this in manual mode.
*
*/
#if (dg_configFLASH_POWER_DOWN == 1)
__attribute__((section("text_retained")))
#endif
static inline void hw_qspi_cs_disable(void) __attribute__((always_inline));
static inline void hw_qspi_cs_disable(void)
{
QSPIC->QSPIC_CTRLBUS_REG = QSPIC_QSPIC_CTRLBUS_REG_QSPIC_DIS_CS_Msk;
@@ -257,6 +259,8 @@ void hw_qspi_set_bus_mode(HW_QSPI_BUS_MODE mode);
* 1 - SPI Bus is active. ReadData, WriteData or DummyData activity is in progress
*
*/
static inline uint8_t hw_qspi_is_busy(void) __attribute__((always_inline));
static inline uint8_t hw_qspi_is_busy(void)
{
return (uint8_t) QSPIC->QSPIC_STATUS_REG;
@@ -271,6 +275,8 @@ static inline uint8_t hw_qspi_is_busy(void)
* \return data read during read transfer
*
*/
static inline uint32_t hw_qspi_read32(void) __attribute__((always_inline));
static inline uint32_t hw_qspi_read32(void)
{
return QSPIC->QSPIC_READDATA_REG;
@@ -285,6 +291,8 @@ static inline uint32_t hw_qspi_read32(void)
* \return data read during read transfer
*
*/
static inline uint16_t hw_qspi_read16(void) __attribute__((always_inline));
static inline uint16_t hw_qspi_read16(void)
{
return *((volatile uint16_t *) &(QSPIC->QSPIC_READDATA_REG));
@@ -299,6 +307,8 @@ static inline uint16_t hw_qspi_read16(void)
* \return data read during read transfer
*
*/
static inline uint8_t hw_qspi_read8(void) __attribute__((always_inline));
static inline uint8_t hw_qspi_read8(void)
{
return *((volatile uint8_t *) &(QSPIC->QSPIC_READDATA_REG));
@@ -313,6 +323,8 @@ static inline uint8_t hw_qspi_read8(void)
* param [in] data data to transfer
*
*/
static inline void hw_qspi_write32(uint32_t data) __attribute__((always_inline));
static inline void hw_qspi_write32(uint32_t data)
{
QSPIC->QSPIC_WRITEDATA_REG = data;
@@ -327,6 +339,8 @@ static inline void hw_qspi_write32(uint32_t data)
* param [in] data data to transfer
*
*/
static inline void hw_qspi_write16(uint16_t data) __attribute__((always_inline));
static inline void hw_qspi_write16(uint16_t data)
{
*((volatile uint16_t *) &(QSPIC->QSPIC_WRITEDATA_REG)) = data;
@@ -341,9 +355,8 @@ static inline void hw_qspi_write16(uint16_t data)
* param [in] data data to transfer
*
*/
#if (dg_configFLASH_POWER_DOWN == 1)
__attribute__((section("text_retained")))
#endif
static inline void hw_qspi_write8(uint8_t data) __attribute__((always_inline));
static inline void hw_qspi_write8(uint8_t data)
{
*((volatile uint8_t *) &(QSPIC->QSPIC_WRITEDATA_REG)) = data;
@@ -356,6 +369,8 @@ static inline void hw_qspi_write8(uint8_t data)
* Number of pulses depends on selected mode of the SPI bus (SPI, Dual SPI, Quad SPI).
*
*/
static inline void hw_qspi_dummy32(void) __attribute__((always_inline));
static inline void hw_qspi_dummy32(void)
{
QSPIC->QSPIC_DUMMYDATA_REG = 0;
@@ -368,6 +383,8 @@ static inline void hw_qspi_dummy32(void)
* Number of pulses depends on selected mode of the SPI bus (SPI, Dual SPI, Quad SPI).
*
*/
static inline void hw_qspi_dummy16(void) __attribute__((always_inline));
static inline void hw_qspi_dummy16(void)
{
*((volatile uint16_t *) &(QSPIC->QSPIC_DUMMYDATA_REG)) = 0;
@@ -380,6 +397,8 @@ static inline void hw_qspi_dummy16(void)
* Number of pulses depends on selected mode of the SPI bus (SPI, Dual SPI, Quad SPI).
*
*/
static inline void hw_qspi_dummy8(void) __attribute__((always_inline));
static inline void hw_qspi_dummy8(void)
{
*((volatile uint8_t *) &(QSPIC->QSPIC_DUMMYDATA_REG)) = 0;
@@ -393,6 +412,8 @@ static inline void hw_qspi_dummy8(void)
* \param [in] size selects 32 or 24 address size
*
*/
static inline void hw_qspi_set_address_size(HW_QSPI_ADDR_SIZE size) __attribute__((always_inline));
static inline void hw_qspi_set_address_size(HW_QSPI_ADDR_SIZE size)
{
HW_QSPIC_REG_SETF(CTRLMODE, USE_32BA, (size == HW_QSPI_ADDR_SIZE_32 ? 1 : 0));
@@ -408,6 +429,8 @@ static inline void hw_qspi_set_address_size(HW_QSPI_ADDR_SIZE size)
* \sa hw_qspi_set_address_size
*
*/
static inline HW_QSPI_ADDR_SIZE hw_qspi_get_address_size(void) __attribute__((always_inline));
static inline HW_QSPI_ADDR_SIZE hw_qspi_get_address_size(void)
{
return (HW_QSPI_ADDR_SIZE) HW_QSPIC_REG_GETF(CTRLMODE, USE_32BA);
@@ -430,6 +453,8 @@ static inline HW_QSPI_ADDR_SIZE hw_qspi_get_address_size(void)
* respect to QSPIC_FORCENSEQ_EN=0 at cost of performance
*
*/
static inline void hw_qspi_force_nseq(uint8_t force) __attribute__((always_inline));
static inline void hw_qspi_force_nseq(uint8_t force)
{
HW_QSPIC_REG_SETF(CTRLMODE, FORCENSEQ_EN, force);
@@ -462,6 +487,8 @@ void hw_qspi_set_automode(bool automode);
* false manual mode is selected
*
*/
static inline bool hw_qspi_get_automode(void) __attribute__((always_inline));
static inline bool hw_qspi_get_automode(void)
{
return HW_QSPIC_REG_GETF(CTRLMODE, AUTO_MD);
@@ -473,6 +500,8 @@ static inline bool hw_qspi_get_automode(void)
* \return read pipe clock delay relative to the falling edge of QSPI_SCK
*
*/
static inline uint8_t hw_qspi_get_read_pipe_clock_delay(void) __attribute__((always_inline));
static inline uint8_t hw_qspi_get_read_pipe_clock_delay(void)
{
return HW_QSPIC_REG_GETF(CTRLMODE, PCLK_MD);
@@ -485,6 +514,8 @@ static inline uint8_t hw_qspi_get_read_pipe_clock_delay(void)
* value should be in range 0..7
*
*/
static inline void hw_qspi_set_read_pipe_clock_delay(uint8_t delay) __attribute__((always_inline));
static inline void hw_qspi_set_read_pipe_clock_delay(uint8_t delay)
{
HW_QSPIC_REG_SETF(CTRLMODE, PCLK_MD, delay);
@@ -496,6 +527,8 @@ static inline void hw_qspi_set_read_pipe_clock_delay(uint8_t delay)
* \return 1 if read pipe is enabled, 0 otherwise
*
*/
static inline uint8_t hw_qspi_is_read_pipe_clock_enabled(void) __attribute__((always_inline));
static inline uint8_t hw_qspi_is_read_pipe_clock_enabled(void)
{
return HW_QSPIC_REG_GETF(CTRLMODE, RPIPE_EN);
@@ -508,6 +541,8 @@ static inline uint8_t hw_qspi_is_read_pipe_clock_enabled(void)
* 0 disable read pipe
*
*/
static inline void hw_qspi_enable_readpipe(uint8_t enable) __attribute__((always_inline));
static inline void hw_qspi_enable_readpipe(uint8_t enable)
{
HW_QSPIC_REG_SETF(CTRLMODE, RPIPE_EN, enable);
@@ -519,6 +554,8 @@ static inline void hw_qspi_enable_readpipe(uint8_t enable)
* \return type of QSPI_CLK edge for sampling received data
*
*/
static inline HW_QSPI_SAMPLING_EDGE hw_qspi_get_read_sampling_edge(void) __attribute__((always_inline));
static inline HW_QSPI_SAMPLING_EDGE hw_qspi_get_read_sampling_edge(void)
{
return HW_QSPIC_REG_GETF(CTRLMODE, RXD_NEG);
@@ -531,6 +568,8 @@ static inline HW_QSPI_SAMPLING_EDGE hw_qspi_get_read_sampling_edge(void)
* of QSPI_SCK
*
*/
static inline void hw_qspi_set_read_sampling_edge(HW_QSPI_SAMPLING_EDGE edge) __attribute__((always_inline));
static inline void hw_qspi_set_read_sampling_edge(HW_QSPI_SAMPLING_EDGE edge)
{
HW_QSPIC_REG_SETF(CTRLMODE, RXD_NEG, edge);
@@ -547,6 +586,8 @@ static inline void hw_qspi_set_read_sampling_edge(HW_QSPI_SAMPLING_EDGE edge)
* activity at the SPI bus
*
*/
static inline uint8_t hw_qspi_is_hready_enabled(void) __attribute__((always_inline));
static inline uint8_t hw_qspi_is_hready_enabled(void)
{
return HW_QSPIC_REG_GETF(CTRLMODE, HRDY_MD);
@@ -559,6 +600,8 @@ static inline uint8_t hw_qspi_is_hready_enabled(void)
* QSPIC_WRITEDATA, QSPIC_READDATA and QSPIC_DUMMYDATA registers
*
*/
static inline void hw_qspi_enable_hready(uint8_t enable) __attribute__((always_inline));
static inline void hw_qspi_enable_hready(uint8_t enable)
{
HW_QSPIC_REG_SETF(CTRLMODE, HRDY_MD, enable);
@@ -571,6 +614,8 @@ static inline void hw_qspi_enable_hready(uint8_t enable)
* 1 - SPI mode 3 is used for QSPI_CLK, the QSPI_SCK is high when QSPI_CS is high (idle)
*
*/
static inline uint8_t hw_qspi_get_clock_mode(void) __attribute__((always_inline));
static inline uint8_t hw_qspi_get_clock_mode(void)
{
return HW_QSPIC_REG_GETF(CTRLMODE, CLK_MD);
@@ -585,6 +630,8 @@ static inline uint8_t hw_qspi_get_clock_mode(void)
* The QSPI_SCK is high when QSPI_CS is high (idle)
*
*/
static inline void hw_qspi_set_clock_mode(HW_QSPI_POL mode) __attribute__((always_inline));
static inline void hw_qspi_set_clock_mode(HW_QSPI_POL mode)
{
HW_QSPIC_REG_SETF(CTRLMODE, CLK_MD, mode);
@@ -603,6 +650,8 @@ static inline void hw_qspi_set_clock_mode(HW_QSPI_POL mode)
#if (dg_configFLASH_POWER_DOWN == 1)
__attribute__((section("text_retained")))
#endif
static inline void hw_qspi_set_io2_output(bool output) __attribute__((always_inline));
static inline void hw_qspi_set_io2_output(bool output)
{
HW_QSPIC_REG_SETF(CTRLMODE, IO2_OEN, output);
@@ -621,6 +670,8 @@ static inline void hw_qspi_set_io2_output(bool output)
#if (dg_configFLASH_POWER_DOWN == 1)
__attribute__((section("text_retained")))
#endif
static inline void hw_qspi_set_io3_output(bool output) __attribute__((always_inline));
static inline void hw_qspi_set_io3_output(bool output)
{
HW_QSPIC_REG_SETF(CTRLMODE, IO3_OEN, output);
@@ -634,6 +685,8 @@ static inline void hw_qspi_set_io3_output(bool output)
* \sa hw_qspi_set_io2_direction
*
*/
static inline void hw_qspi_set_io2(uint8_t val) __attribute__((always_inline));
static inline void hw_qspi_set_io2(uint8_t val)
{
HW_QSPIC_REG_SETF(CTRLMODE, IO2_DAT, val);
@@ -647,6 +700,8 @@ static inline void hw_qspi_set_io2(uint8_t val)
* \sa hw_qspi_set_io3_direction
*
*/
static inline void hw_qspi_set_io3(uint8_t val) __attribute__((always_inline));
static inline void hw_qspi_set_io3(uint8_t val)
{
HW_QSPIC_REG_SETF(CTRLMODE, IO3_DAT, val);
@@ -658,6 +713,8 @@ static inline void hw_qspi_set_io3(uint8_t val)
* \return value of IO2 pin (0 or 1)
*
*/
static inline uint8_t hw_qspi_get_io2(void) __attribute__((always_inline));
static inline uint8_t hw_qspi_get_io2(void)
{
return HW_QSPIC_REG_GETF(CTRLMODE, IO2_DAT);
@@ -669,6 +726,8 @@ static inline uint8_t hw_qspi_get_io2(void)
* \return value of IO3 pin (0 or 1)
*
*/
static inline uint8_t hw_qspi_get_io3(void) __attribute__((always_inline));
static inline uint8_t hw_qspi_get_io3(void)
{
return HW_QSPIC_REG_GETF(CTRLMODE, IO3_DAT);
@@ -697,11 +756,35 @@ static inline uint8_t hw_qspi_get_io3(void)
* \sa hw_qspi_set_wrapping_burst_instruction
*
*/
void hw_qspi_set_read_instruction(uint8_t inst, uint8_t send_once, uint8_t dummy_count,
HW_QSPI_BUS_MODE inst_phase,
HW_QSPI_BUS_MODE addr_phase,
HW_QSPI_BUS_MODE dummy_phase,
HW_QSPI_BUS_MODE data_phase);
static inline void hw_qspi_set_read_instruction(uint8_t inst,
uint8_t send_once,
uint8_t dummy_count,
HW_QSPI_BUS_MODE inst_phase,
HW_QSPI_BUS_MODE addr_phase,
HW_QSPI_BUS_MODE dummy_phase,
HW_QSPI_BUS_MODE data_phase)
__attribute((always_inline));
static inline void hw_qspi_set_read_instruction(uint8_t inst,
uint8_t send_once,
uint8_t dummy_count,
HW_QSPI_BUS_MODE inst_phase,
HW_QSPI_BUS_MODE addr_phase,
HW_QSPI_BUS_MODE dummy_phase,
HW_QSPI_BUS_MODE data_phase)
{
QSPIC->QSPIC_BURSTCMDA_REG =
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_INST, inst) |
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_INST_TX_MD, inst_phase) |
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_ADR_TX_MD, addr_phase) |
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_DMY_TX_MD, dummy_phase);
QSPIC->QSPIC_BURSTCMDB_REG =
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_DAT_RX_MD, data_phase) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_INST_MD, send_once) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_DMY_FORCE, (dummy_count == 3 ? 1 : 0)) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_DMY_NUM, dummy_num[dummy_count]);
}
/**
* \brief Set wrapping burst read instructions for QSPI flash
@@ -732,8 +815,26 @@ void hw_qspi_set_wrapping_burst_instruction(uint8_t inst, HW_QSPI_WRAP_LEN len,
* \sa hw_qspi_set_read_instruction
*
*/
void hw_qspi_set_extra_byte(uint8_t extra_byte, HW_QSPI_BUS_MODE bus_mode,
uint8_t half_disable_out);
static inline void hw_qspi_set_extra_byte(uint8_t extra_byte, HW_QSPI_BUS_MODE bus_mode,
uint8_t half_disable_out) __attribute__((always_inline));
static inline void hw_qspi_set_extra_byte(uint8_t extra_byte, HW_QSPI_BUS_MODE bus_mode,
uint8_t half_disable_out)
{
QSPIC->QSPIC_BURSTCMDA_REG =
(QSPIC->QSPIC_BURSTCMDA_REG &
~(REG_MSK(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_EXT_BYTE) |
REG_MSK(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_EXT_TX_MD))) |
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_EXT_BYTE, extra_byte) |
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_EXT_TX_MD, bus_mode);
QSPIC->QSPIC_BURSTCMDB_REG =
(QSPIC->QSPIC_BURSTCMDB_REG &
~(REG_MSK(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_EXT_BYTE_EN) |
REG_MSK(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_EXT_HF_DS))) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_EXT_BYTE_EN, 1) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_EXT_HF_DS, half_disable_out ? 1 : 0);
}
/**
* \brief Set dummy byte count
@@ -754,6 +855,8 @@ void hw_qspi_set_dummy_bytes_count(uint8_t count);
* register for an exception
*
*/
static inline void hw_qspi_set_min_cs_high(uint8_t clock_count) __attribute__((always_inline));
static inline void hw_qspi_set_min_cs_high(uint8_t clock_count)
{
HW_QSPIC_REG_SETF(BURSTCMDB, CS_HIGH_MIN, clock_count);
@@ -777,8 +880,25 @@ static inline void hw_qspi_set_min_cs_high(uint8_t clock_count)
* \sa hw_qspi_erase_block
*
*/
void hw_qspi_set_erase_instruction(uint8_t inst, HW_QSPI_BUS_MODE inst_phase,
HW_QSPI_BUS_MODE addr_phase, uint8_t hclk_cycles, uint8_t cs_hi_cycles);
static inline void hw_qspi_set_erase_instruction(uint8_t inst, HW_QSPI_BUS_MODE inst_phase,
HW_QSPI_BUS_MODE addr_phase, uint8_t hclk_cycles, uint8_t cs_hi_cycles)
__attribute__((always_inline));
static inline void hw_qspi_set_erase_instruction(uint8_t inst, HW_QSPI_BUS_MODE inst_phase,
HW_QSPI_BUS_MODE addr_phase, uint8_t hclk_cycles, uint8_t cs_hi_cycles)
{
HW_QSPIC_REG_SETF(ERASECMDA, ERS_INST, inst);
QSPIC->QSPIC_ERASECMDB_REG =
(QSPIC->QSPIC_ERASECMDB_REG &
~(REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERS_TX_MD) |
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_EAD_TX_MD) |
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERSRES_HLD) |
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERS_CS_HI))) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERS_TX_MD, inst_phase) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_EAD_TX_MD, addr_phase) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERSRES_HLD, hclk_cycles) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERS_CS_HI, cs_hi_cycles);
}
/**
* \brief Set up write enable instruction
@@ -792,7 +912,16 @@ void hw_qspi_set_erase_instruction(uint8_t inst, HW_QSPI_BUS_MODE inst_phase,
* \sa hw_qspi_set_erase_instruction
*
*/
void hw_qspi_set_write_enable_instruction(uint8_t write_enable, HW_QSPI_BUS_MODE inst_phase);
static inline void hw_qspi_set_write_enable_instruction(uint8_t write_enable,
HW_QSPI_BUS_MODE inst_phase)
__attribute((always_inline));
static inline void hw_qspi_set_write_enable_instruction(uint8_t write_enable,
HW_QSPI_BUS_MODE inst_phase)
{
HW_QSPIC_REG_SETF(ERASECMDA, WEN_INST, write_enable);
HW_QSPIC_REG_SETF(ERASECMDB, WEN_TX_MD, inst_phase);
}
/**
* \brief Set up erase suspend/resume instructions
@@ -813,11 +942,34 @@ void hw_qspi_set_write_enable_instruction(uint8_t write_enable, HW_QSPI_BUS_MODE
* the end of the previous erase resume
*
*/
void hw_qspi_set_suspend_resume_instructions(uint8_t erase_suspend_inst,
static inline void hw_qspi_set_suspend_resume_instructions(uint8_t erase_suspend_inst,
HW_QSPI_BUS_MODE suspend_inst_phase,
uint8_t erase_resume_inst,
HW_QSPI_BUS_MODE resume_inst_phase,
uint8_t minimum_delay);
uint8_t minimum_delay)
__attribute((always_inline));
static inline void hw_qspi_set_suspend_resume_instructions(uint8_t erase_suspend_inst,
HW_QSPI_BUS_MODE suspend_inst_phase,
uint8_t erase_resume_inst,
HW_QSPI_BUS_MODE resume_inst_phase,
uint8_t minimum_delay)
{
QSPIC->QSPIC_ERASECMDA_REG =
(QSPIC->QSPIC_ERASECMDA_REG &
~(REG_MSK(QSPIC, QSPIC_ERASECMDA_REG, QSPIC_SUS_INST) |
REG_MSK(QSPIC, QSPIC_ERASECMDA_REG, QSPIC_RES_INST))) |
BITS32(QSPIC, QSPIC_ERASECMDA_REG, QSPIC_SUS_INST, erase_suspend_inst) |
BITS32(QSPIC, QSPIC_ERASECMDA_REG, QSPIC_RES_INST, erase_resume_inst);
QSPIC->QSPIC_ERASECMDB_REG =
(QSPIC->QSPIC_ERASECMDB_REG &
~(REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_SUS_TX_MD) |
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_RES_TX_MD) |
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_RESSUS_DLY))) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_SUS_TX_MD, suspend_inst_phase) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_RES_TX_MD, resume_inst_phase) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_RESSUS_DLY, minimum_delay);
}
/**
* \brief Set status command
@@ -856,12 +1008,32 @@ void hw_qspi_set_suspend_resume_instructions(uint8_t erase_suspend_inst,
* \sa hw_qspi_get_erase_status
*
*/
void hw_qspi_set_read_status_instruction(uint8_t inst, HW_QSPI_BUS_MODE inst_phase,
HW_QSPI_BUS_MODE receive_phase,
uint8_t busy_pos,
uint8_t busy_val,
uint8_t read_delay,
uint8_t sts_delay);
static inline void hw_qspi_set_read_status_instruction(uint8_t inst,
HW_QSPI_BUS_MODE inst_phase,
HW_QSPI_BUS_MODE receive_phase,
uint8_t busy_pos,
uint8_t busy_val,
uint8_t read_delay,
uint8_t sts_delay)
__attribute((always_inline));
static inline void hw_qspi_set_read_status_instruction(uint8_t inst,
HW_QSPI_BUS_MODE inst_phase,
HW_QSPI_BUS_MODE receive_phase,
uint8_t busy_pos,
uint8_t busy_val,
uint8_t read_delay,
uint8_t sts_delay)
{
QSPIC->QSPIC_STATUSCMD_REG =
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_BUSY_VAL, busy_val) |
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_BUSY_POS , busy_pos) |
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_RSTAT_RX_MD, receive_phase) |
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_RSTAT_TX_MD, inst_phase) |
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_RSTAT_INST, inst) |
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_STSDLY_SEL, sts_delay) |
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_RESSTS_DLY, read_delay);
}
/**
* \brief Erase block/sector of flash memory
@@ -897,6 +1069,8 @@ void hw_qspi_erase_block(uint32_t addr);
* 4 = finishing the erase procedure
*
*/
static inline uint8_t hw_qspi_get_erase_status(void) __attribute__((always_inline));
static inline uint8_t hw_qspi_get_erase_status(void)
{
QSPIC->QSPIC_CHCKERASE_REG = 0;
@@ -917,13 +1091,27 @@ static inline uint8_t hw_qspi_get_erase_status(void)
* of the sequence[3:0]
*
*/
void hw_qspi_set_break_sequence(uint16_t sequence, HW_QSPI_BUS_MODE mode,
HW_QSPI_BREAK_SEQ_SIZE size, uint8_t dis_out);
static inline void hw_qspi_set_break_sequence(uint16_t sequence, HW_QSPI_BUS_MODE mode,
HW_QSPI_BREAK_SEQ_SIZE size, uint8_t dis_out)
__attribute__((always_inline));
static inline void hw_qspi_set_break_sequence(uint16_t sequence, HW_QSPI_BUS_MODE mode,
HW_QSPI_BREAK_SEQ_SIZE size, uint8_t dis_out)
{
QSPIC->QSPIC_BURSTBRK_REG =
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_SEC_HF_DS, dis_out) |
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_BRK_SZ, size) |
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_BRK_TX_MD, mode) |
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_BRK_EN, 1) |
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_BRK_WRD, sequence);
}
/**
* \brief Disable burst break sequence
*
*/
static inline void hw_qspi_disable_burst_break_sequence(void) __attribute__((always_inline));
static inline void hw_qspi_disable_burst_break_sequence(void)
{
HW_QSPIC_REG_SETF(BURSTBRK, BRK_EN, 0);
@@ -952,18 +1140,26 @@ void hw_qspi_init(const qspi_config *cfg);
* \brief Enable QSPI controller clock
*
*/
static inline void hw_qspi_enable_clock(void) __attribute__((always_inline));
static inline void hw_qspi_enable_clock(void)
{
GLOBAL_INT_DISABLE();
CRG_TOP->CLK_AMBA_REG |= 1 << REG_POS(CRG_TOP, CLK_AMBA_REG, QSPI_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
* \brief Disable QSPI controller clock
*
*/
static inline void hw_qspi_disable_clock(void) __attribute__((always_inline));
static inline void hw_qspi_disable_clock(void)
{
GLOBAL_INT_DISABLE();
CRG_TOP->CLK_AMBA_REG &= ~REG_MSK(CRG_TOP, CLK_AMBA_REG, QSPI_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
@@ -973,7 +1169,14 @@ static inline void hw_qspi_disable_clock(void)
*
* \sa HW_QSPI_DIV
*/
void hw_qspi_set_div(HW_QSPI_DIV div);
static inline void hw_qspi_set_div(HW_QSPI_DIV div) __attribute__((always_inline));
static inline void hw_qspi_set_div(HW_QSPI_DIV div)
{
GLOBAL_INT_DISABLE();
REG_SETF(CRG_TOP, CLK_AMBA_REG, QSPI_DIV, div);
GLOBAL_INT_RESTORE();
}
/**
* \brief Get the QSPI clock divider
@@ -982,6 +1185,8 @@ void hw_qspi_set_div(HW_QSPI_DIV div);
*
* \sa HW_QSPI_DIV
*/
static inline HW_QSPI_DIV hw_qspi_get_div(void) __attribute__((always_inline));
static inline HW_QSPI_DIV hw_qspi_get_div(void)
{
return REG_GETF(CRG_TOP, CLK_AMBA_REG, QSPI_DIV);
+121 -48
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup RF
* \{
* \brief Radio Control
*/
/**
@@ -58,14 +59,14 @@
*
* @note
* ~~~{.c}
* uint32_t hw_rf_get_start_iff_time(void)
* uint64_t hw_rf_get_start_iff_time(void)
* ~~~
*
* @note Called to get the time when IFF calibration starts
*
* @note
* ~~~{.c}
* bool hw_rf_check_iff_timeout(uint32_t start_time)
* bool hw_rf_check_iff_timeout(uint64_t start_time)
* ~~~
*
* @note Called to check if IFF calibration has timed-out (i.e. took too long). It takes argument the
@@ -97,7 +98,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
*****************************************************************************************
*/
#ifndef HW_RF_H_
@@ -106,7 +108,7 @@
#if dg_configUSE_HW_RF
#include <stdbool.h>
#include "black_orca.h"
#include "sdk_defs.h"
#include "hw_cpm.h"
@@ -114,6 +116,25 @@
#include "hw_fem_sky66112-11.h"
#endif
typedef struct __attribute__ ((__packed__)) {
uint8_t tx_power_ble: 4;
uint8_t tx_power_ftdf: 4;
} hw_rf_tx_power_luts_t;
extern hw_rf_tx_power_luts_t rf_tx_power_luts;
/**
* \brief Power LUT setting
*
*/
typedef enum {
HW_RF_PWR_LUT_0dbm = 0, /**< TX PWR attenuation 0 dbm */
HW_RF_PWR_LUT_m1dbm = 1, /**< TX PWR attenuation -1 dbm */
HW_RF_PWR_LUT_m2dbm = 2, /**< TX PWR attenuation -2 dbm */
HW_RF_PWR_LUT_m3dbm = 3, /**< TX PWR attenuation -3 dbm */
HW_RF_PWR_LUT_m4dbm = 4, /**< TX PWR attenuation -4 dbm */
} HW_RF_PWR_LUT_SETTING;
/**
* \brief Initializes RF system, and performs the initial calibration
*
@@ -122,17 +143,12 @@
* \return True, if iff calib is successful, false otherwise
*/
bool hw_rf_system_init(void);
/**
/**
* \brief Sets parameters according to their recommended values.
*/
void hw_rf_set_recommended_settings(void);
/**
* \brief (Re)calibrates Intermediate Frequency Filter (IFF).
*/
bool hw_rf_iff_calibration(void);
/**
* \brief (Re)calibrates RF DC offset.
*/
@@ -161,7 +177,70 @@ bool hw_rf_calibration(void);
* \return True if calibration was successful, false if not (i.e. iff calib hang)
*
*/
bool hw_rf_start_calibration();
bool hw_rf_start_calibration(void);
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
/**
* \brief Set TX Power
*
* This actually sets the index of the RF_TX_PWER_LUT_X_REG to use.
*
* \param [in] lut The TX power attenuation setting
*
* \warning Do not call this function before recommended settings are applied
*/
void hw_rf_set_tx_power(HW_RF_PWR_LUT_SETTING lut);
#else
#ifdef CONFIG_USE_BLE
/**
* \brief Set TX Power for BLE
*
* This actually sets the index of the RF_TX_PWR_LUT_X_REG to use.
*
* \param [in] lut The TX power attenuation setting
*
* \warning Do not call this function before recommended settings are applied
*/
void hw_rf_set_tx_power_ble(HW_RF_PWR_LUT_SETTING lut);
#endif
#ifdef CONFIG_USE_FTDF
/**
* \brief Set TX Power for FTDF
*
* This actually sets the index of the RF_TX_PWR_LUT_X_REG to use.
*
* \param [in] lut The TX power attenuation setting
*
* \warning Do not call this function before recommended settings are applied
*/
void hw_rf_set_tx_power_ftdf(HW_RF_PWR_LUT_SETTING lut);
#endif
/**
* \brief Set TX Power
*
* This actually sets the index of the RF_TX_PWR_LUT_X_REG to use.
*
* \param [in] lut The TX power attenuation setting
*
* \deprecated This function is deprecated since it can only set
* BLE and FTDF TX power with the same value. Use hw_rf_set_tx_power_ble()
* and hw_rf_set_tx_power_ftdf() instead.
*
* \warning Do not call this function before recommended settings are applied
*/
static inline void hw_rf_set_tx_power(HW_RF_PWR_LUT_SETTING lut)
{
#ifdef CONFIG_USE_BLE
hw_rf_set_tx_power_ble(lut);
#endif
#ifdef CONFIG_USE_FTDF
hw_rf_set_tx_power_ftdf(lut);
#endif
}
#endif
/**
* \brief Turns on RF module.
@@ -170,33 +249,39 @@ static inline void hw_rf_poweron(void) __attribute__((always_inline));
static inline void hw_rf_poweron(void)
{
#if ( (dg_configUSE_BOD == 1) && (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) \
&& (dg_configBLACK_ORCA_IC_STEP <= BLACK_ORCA_IC_STEP_D))
hw_cpm_deactivate_bod_protection();
#endif
if ((dg_configUSE_BOD == 1) && ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE)))) {
hw_cpm_deactivate_bod_protection();
}
/* If PD_RAD is up, make sure to power it down to issue a reset */
if (REG_GETF(CRG_TOP, SYS_STAT_REG, RAD_IS_UP)) {
#if ( (dg_configUSE_BOD == 1) && (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) \
&& (dg_configBLACK_ORCA_IC_STEP <= BLACK_ORCA_IC_STEP_D))
hw_cpm_delay_usec(30);
#endif
if ((dg_configUSE_BOD == 1) && ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE)))) {
hw_cpm_delay_usec(30);
}
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, PMU_CTRL_REG, RADIO_SLEEP);
GLOBAL_INT_RESTORE();
while (REG_GETF(CRG_TOP, SYS_STAT_REG, RAD_IS_DOWN) == 0x0);
}
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, RADIO_SLEEP);
GLOBAL_INT_RESTORE();
while (!REG_GETF(CRG_TOP, SYS_STAT_REG, RAD_IS_UP));
#if ( (dg_configUSE_BOD == 1) && (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) \
&& (dg_configBLACK_ORCA_IC_STEP <= BLACK_ORCA_IC_STEP_D))
if ((dg_configUSE_BOD == 1) && ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE)))) {
hw_cpm_delay_usec(30);
hw_cpm_activate_bod_protection();
#endif
}
// Enable the PLLdig/RFCU clock
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, CLK_RADIO_REG, RFCU_ENABLE);
REG_SETF(CRG_TOP, CLK_RADIO_REG, RFCU_DIV, 1);
GLOBAL_INT_RESTORE();
#if dg_configFEM == FEM_SKY66112_11
hw_fem_start();
@@ -212,20 +297,22 @@ static inline void hw_rf_poweroff()
hw_fem_stop();
#endif
#if ( (dg_configUSE_BOD == 1) && (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) \
&& (dg_configBLACK_ORCA_IC_STEP <= BLACK_ORCA_IC_STEP_D))
hw_cpm_deactivate_bod_protection();
hw_cpm_delay_usec(30);
#endif
if ((dg_configUSE_BOD == 1) && ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE)))) {
hw_cpm_deactivate_bod_protection();
hw_cpm_delay_usec(30);
}
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, PMU_CTRL_REG, RADIO_SLEEP);
GLOBAL_INT_RESTORE();
while (!REG_GETF(CRG_TOP, SYS_STAT_REG, RAD_IS_DOWN));
#if ( (dg_configUSE_BOD == 1) && (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) \
&& (dg_configBLACK_ORCA_IC_STEP <= BLACK_ORCA_IC_STEP_D))
hw_cpm_delay_usec(30);
hw_cpm_activate_bod_protection();
#endif
if ((dg_configUSE_BOD == 1) && ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
|| ((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE)))) {
hw_cpm_delay_usec(30);
hw_cpm_activate_bod_protection();
}
}
/**
@@ -260,7 +347,7 @@ __RETAINED_CODE void hw_rf_request_on(bool mode_ble);
*/
void hw_rf_request_off(bool mode_ble);
/*
/**
* \brief Start transmitting a continuous wave (unmodulated transmission)
*
* \param [in] mode is the mode to use. 1: BLE, 2 or 3: FTDF (0: Normal, use hw_rf_stop_*)
@@ -273,26 +360,12 @@ void hw_rf_request_off(bool mode_ble);
*/
void hw_rf_start_continuous_wave(uint8_t mode, uint8_t ch);
/*
/**
* \brief Stop transmitting a continuous wave (unmodulated transmission)
*
*/
void hw_rf_stop_continuous_wave(void);
/*
* \brief Set TX Power
*
* This actually sets the index of the RF_TX_PWER_LUT_X_REG to use.
*
* \param [in] lut The index of the LUT to use. 0 disables this functionality.
* 1: 0dbm, 2: -1dbm, 3: -2dbm, 4: -3dbm, 5: -4dbm
*/
static inline void hw_rf_set_tx_power(uint8_t lut)
{
RFCU->RF_TX_PWR_REG = lut;
}
#endif /* dg_configUSE_HW_RF */
#endif /* HW_RF_H_ */
+6 -2
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup Timer0
* \{
* \brief Timer0
*/
/**
@@ -37,7 +38,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
*****************************************************************************************
*/
@@ -48,7 +50,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <black_orca.h>
#include <sdk_defs.h>
/**
@@ -232,7 +234,9 @@ static inline HW_TIMER0_CLK_SRC hw_timer0_get_clock_source(void)
*/
static inline void hw_timer0_set_fast_clock_div(HW_TIMER0_FAST_CLK_DIV div)
{
GLOBAL_INT_DISABLE();
REG_SETF(CRG_TOP, CLK_TMR_REG, TMR0_DIV, div);
GLOBAL_INT_RESTORE();
}
/**
+126 -29
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup Timer1
* \{
* \brief Timer1
*/
/**
@@ -37,7 +38,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
*****************************************************************************************
*/
@@ -48,7 +50,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <black_orca.h>
#include <sdk_defs.h>
/**
@@ -268,9 +270,10 @@ typedef struct {
HW_TIMER1_CLK_SRC clk_src; /**< clock source */
uint16_t prescaler; /**< clock prescaler */
union {
timer1_config_timer_capture timer; /**< configuration for timer/capture mode */
timer1_config_oneshot oneshot; /**< configuration for oneshot mode */
};
timer1_config_pwm pwm; /**< PWM configuration */
} timer1_config;
@@ -323,6 +326,35 @@ void hw_timer1_configure_timer(const timer1_config_timer_capture *cfg);
*/
void hw_timer1_configure_oneshot(const timer1_config_oneshot *cfg);
/**
* \brief Freeze timer
*
*/
static inline void hw_timer1_freeze(void)
{
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_SWTIM1_Msk;
}
/**
* \brief Unfreeze timer
*
*/
static inline void hw_timer1_unfreeze(void)
{
GPREG->RESET_FREEZE_REG = GPREG_RESET_FREEZE_REG_FRZ_SWTIM1_Msk;
}
/**
* \brief Check if timer is frozen
*
* \return true if it is frozen else false
*
*/
static inline bool hw_timer1_frozen(void)
{
return GPREG->SET_FREEZE_REG & GPREG_SET_FREEZE_REG_FRZ_SWTIM1_Msk ? true : false;
}
/**
* \brief Set clock source of the timer
*
@@ -356,11 +388,24 @@ static inline void hw_timer1_set_prescaler(uint16_t value)
* \param [in] value reload value
*
* \sa hw_timer1_set_oneshot_delay
*
* \note For DA14682/3 chips, setting the reload value will also freeze the timer until both
* reload registers are set.
*/
static inline void hw_timer1_set_reload(uint32_t value)
{
#if (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A) && (dg_configUSE_AUTO_CHIP_DETECTION != 1)
bool timer1_frozen = hw_timer1_frozen();
if (!timer1_frozen) {
hw_timer1_freeze();
}
TIMER1->CAPTIM_RELOAD_REG = (uint16_t) value;
TIMER1->CAPTIM_RELOAD_HIGH_REG = (uint16_t) value >> 16;
if (!timer1_frozen) {
hw_timer1_unfreeze();
}
#else
TIMER1->CAPTIM_RELOAD_REG = (uint16_t) value;
#endif
}
/**
@@ -626,7 +671,18 @@ static inline HW_TIMER1_MODE hw_timer1_get_mode(void)
*/
static inline uint32_t hw_timer1_get_count(void)
{
#if (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A) && (dg_configUSE_AUTO_CHIP_DETECTION != 1)
uint32_t lo, hi;
GLOBAL_INT_DISABLE();
do {
lo = TIMER1->CAPTIM_TIMER_VAL_REG;
hi = TIMER1->CAPTIM_TIMER_HVAL_REG;
} while (lo != TIMER1->CAPTIM_TIMER_VAL_REG);
GLOBAL_INT_RESTORE();
return (hi << 16) | lo;
#else
return TIMER1->CAPTIM_TIMER_VAL_REG;
#endif
}
/**
@@ -695,32 +751,20 @@ void hw_timer1_register_int(hw_timer1_handler_cb handler);
*/
void hw_timer1_unregister_int(void);
/**
* \brief Freeze timer
*
*/
static inline void hw_timer1_freeze(void)
{
GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_SWTIM1_Msk;
}
/**
* \brief Unfreeze timer
*
*/
static inline void hw_timer1_unfreeze(void)
{
GPREG->RESET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_SWTIM1_Msk;
}
#else // (dg_configUSER_CAN_USE_TIMER1 == 0)
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
#define LP_CNT_REG_RANGE ( 16 )
#define LP_CNT_MAX_VALUE ( (1 << LP_CNT_REG_RANGE) - 1 )
#else
#define LP_CNT_REG_RANGE ( 32 )
#endif
#define LP_CNT_MAX_VALUE ( (1ULL << LP_CNT_REG_RANGE) - 1 )
#define LP_CNT_PRESCALED_MASK ( LP_CNT_MAX_VALUE )
#define LP_CNT_NATIVE_MASK ( (1 << (LP_CNT_REG_RANGE + dg_configTim1PrescalerBitRange)) - 1 )
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
#define LP_CNT_NATIVE_MASK ( (1ULL << (LP_CNT_REG_RANGE + dg_configTim1PrescalerBitRange)) - 1 )
#else
#define LP_CNT_NATIVE_MASK ( (1ULL << (LP_CNT_REG_RANGE)) - 1 )
#endif
/**
* \brief Configure timer as tick timer
@@ -745,6 +789,8 @@ void hw_timer1_lp_clk_init(void);
* \return void
*
*/
static inline void hw_timer1_int_enable(void) __attribute__((always_inline));
static inline void hw_timer1_int_enable(void)
{
HW_TIMER1_REG_SETF(CTRL, CAPTIM_IRQ_EN, 1);
@@ -759,6 +805,8 @@ static inline void hw_timer1_int_enable(void)
* \return void
*
*/
static inline void hw_timer1_int_disable(void) __attribute__((always_inline));
static inline void hw_timer1_int_disable(void)
{
NVIC_DisableIRQ(SWTIM1_IRQn);
@@ -776,7 +824,18 @@ static inline uint32_t hw_timer1_get_value(void) __attribute__((always_inline));
static inline uint32_t hw_timer1_get_value(void)
{
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
return TIMER1->CAPTIM_TIMER_VAL_REG;
#else
uint32_t lo, hi;
GLOBAL_INT_DISABLE();
do {
lo = TIMER1->CAPTIM_TIMER_VAL_REG;
hi = TIMER1->CAPTIM_TIMER_HVAL_REG;
} while (lo != TIMER1->CAPTIM_TIMER_VAL_REG);
GLOBAL_INT_RESTORE();
return (hi << 16) | lo;
#endif
}
@@ -795,8 +854,10 @@ static inline uint32_t hw_timer1_get_value(void)
* respectively), so the time becomes {1, 0}
* - the reading of the prescaler's value will give 0 but {0, 0} is earlier than {0, 3} (when
* the operation started) and this may result in errors in time computations.
* \note This macro should be used inside a critical section.
*
*/
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
#define HW_TIMER1_GET_INSTANT(prescaled, fine) \
do { \
if (dg_configTim1Prescaler != 0) { \
@@ -814,17 +875,45 @@ do {
fine = prescaled; \
} \
} while (0)
#else
#define HW_TIMER1_GET_INSTANT(prescaled, fine) \
do { \
uint32_t lo, hi; \
do { \
lo = TIMER1->CAPTIM_TIMER_VAL_REG; \
hi = TIMER1->CAPTIM_TIMER_HVAL_REG; \
} while (lo != TIMER1->CAPTIM_TIMER_VAL_REG); \
prescaled = fine = (hi << 16) | lo; \
} while (0)
#endif
/**
* \brief Macro to set the trigger value. The previous trigger value is returned to the caller.
*
* \note For DA14682/3 chips, this macro will disable timer1 interrupt until reload registers
* programmed so that false interrupts are avoided.
*/
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
#define HW_TIMER1_SET_TRIGGER(value, last_value) \
do { \
last_value = TIMER1->CAPTIM_RELOAD_REG; \
TIMER1->CAPTIM_RELOAD_REG = value; \
} while (0)
#else
#define HW_TIMER1_SET_TRIGGER(value, last_value) \
do { \
bool timer1_irq_en = \
TIMER1->CAPTIM_CTRL_REG & TIMER1_CAPTIM_CTRL_REG_CAPTIM_IRQ_EN_Msk ? true : false; \
last_value = TIMER1->CAPTIM_RELOAD_REG | \
((uint32_t) TIMER1->CAPTIM_RELOAD_HIGH_REG) << 16; \
if (timer1_irq_en) { \
TIMER1->CAPTIM_CTRL_REG &= ~TIMER1_CAPTIM_CTRL_REG_CAPTIM_IRQ_EN_Msk; \
} \
TIMER1->CAPTIM_RELOAD_REG = (uint16_t) value; \
TIMER1->CAPTIM_RELOAD_HIGH_REG = (uint16_t) ((value) >> 16); \
if (timer1_irq_en) { \
TIMER1->CAPTIM_CTRL_REG |= TIMER1_CAPTIM_CTRL_REG_CAPTIM_IRQ_EN_Msk; \
} \
} while (0)
#endif
/**
* \brief Get trigger value
@@ -834,7 +923,11 @@ do { \
*/
static inline uint32_t hw_timer1_get_trigger(void)
{
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
return TIMER1->CAPTIM_RELOAD_REG;
#else
return TIMER1->CAPTIM_RELOAD_REG | ((uint32_t) TIMER1->CAPTIM_RELOAD_HIGH_REG) << 16;
#endif
}
/**
@@ -865,7 +958,9 @@ static inline void hw_timer1_invalidate_trigger(void)
static inline void hw_timer1_enable(void)
{
HW_TIMER1_REG_SETF(CTRL, CAPTIM_EN, 1);
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, CLK_TMR_REG, TMR1_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
@@ -875,7 +970,9 @@ static inline void hw_timer1_enable(void)
static inline void hw_timer1_disable(void)
{
HW_TIMER1_REG_SETF(CTRL, CAPTIM_EN, 0);
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, CLK_TMR_REG, TMR1_ENABLE);
GLOBAL_INT_RESTORE();
}
/**
+52 -5
View File
@@ -29,12 +29,16 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*****************************************************************************************
*/
#ifndef HW_TRNG_H_
#define HW_TRNG_H_
#if dg_configUSE_HW_TRNG
#include <black_orca.h>
#include <sdk_defs.h>
/**
* \brief TRNG callback.
@@ -64,9 +68,24 @@ typedef void (*hw_trng_cb)(void);
void hw_trng_enable(hw_trng_cb callback);
/**
* \brief TRNG get numbers.
* \brief Get a random number from TRNG.
*
* This function reads the random number from the TRNG FIFO.
* This function reads a random number from the TRNG FIFO.
*
* \return A 32-bit unsigned random number.
*
* \warning This function does not check for number availability in the FIFO
*
*/
__attribute__((always_inline)) static inline uint32_t hw_trng_get_number(void)
{
return *((volatile uint32_t *)MEMORY_TRNG_FIFO);
}
/**
* \brief Get random numbers from TRNG.
*
* This function fills a buffer with random numbers read from the TRNG FIFO.
*
* \param [in] buffer The buffer to write the numbers to.
* \param [in] size The size of the buffer (max 32).
@@ -74,6 +93,8 @@ void hw_trng_enable(hw_trng_cb callback);
* \note Do not forget to disable the TRNG after reading the amount of numbers needed to save
* power.
*
* \warning This function does not check for number availability in the FIFO
*
*/
void hw_trng_get_numbers(uint32_t* buffer, uint8_t size);
@@ -85,14 +106,40 @@ void hw_trng_get_numbers(uint32_t* buffer, uint8_t size);
* \return The current level of the TRNG FIFO.
*
*/
uint8_t hw_trng_get_fifo_level(void);
__RETAINED_CODE uint8_t hw_trng_get_fifo_level(void);
/**
* \brief TRNG disable.
*
* This function disables the TRNG and its interrupt.
* This function stops TRNG, disables its clock and its interrupt.
*
*/
void hw_trng_disable(void);
/**
* \brief Stop TRNG operation.
*/
static inline void hw_trng_stop(void)
{
REG_CLR_BIT(TRNG, TRNG_CTRL_REG, TRNG_ENABLE);
}
/**
* \brief Disable TRNG clock.
*/
void hw_trng_disable_clk(void);
/**
* \brief Disable TRNG interrupt.
*/
void hw_trng_disable_interrupt(void);
/**
* \brief Clear TRNG pending interrupt.
*/
void hw_trng_clear_pending(void);
#endif /* dg_configUSE_HW_TRNG */
#endif /* HW_TRNG_H_ */
+82 -5
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup UART
* \{
* \brief UART Controller
*/
/**
@@ -37,7 +38,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
*****************************************************************************************
*/
@@ -48,7 +50,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <black_orca.h>
#include <sdk_defs.h>
#include "hw_dma.h"
#ifndef HW_UART_USE_DMA_SUPPORT
@@ -263,6 +265,18 @@ void hw_uart_set_isr(HW_UART_ID uart, hw_uart_interrupt_isr isr);
typedef void (*hw_uart_tx_callback)(void *user_data, uint16_t written);
typedef void (*hw_uart_rx_callback)(void *user_data, uint16_t read);
//======================= Status functions ====================================
/**
* \brief Check if a serial transfer is inprogress
*
* \return true or false
*/
static inline bool hw_uart_is_busy(HW_UART_ID uart)
{
return HW_UART_REG_GETF(uart, USR, UART_BUSY);
}
//===================== Read/Write functions ===================================
/**
@@ -300,8 +314,10 @@ void hw_uart_write(HW_UART_ID uart, uint8_t data);
*
* \param [in] uart identifies UART to use
*
* \return number of bytes actually received
*
*/
void hw_uart_abort_receive(HW_UART_ID uart);
uint16_t hw_uart_abort_receive(HW_UART_ID uart);
/**
* \brief Get number of bytes currently received by asynchronous read
@@ -398,8 +414,6 @@ void hw_uart_read_buffer(HW_UART_ID uart, void *data, uint16_t len);
void hw_uart_receive(HW_UART_ID uart, void *data, uint16_t len, hw_uart_rx_callback cb,
void *user_data);
void hw_uart_register_simple_rx_callback(void (*callback) (void), HW_UART_ID uart );
#if HW_UART_USE_DMA_SUPPORT
/**
@@ -504,6 +518,35 @@ static inline HW_UART_INT hw_uart_get_interrupt_id(HW_UART_ID uart)
return (HW_UART_INT) (UBA(uart)->UART2_IIR_FCR_REG & 0xF);
}
/**
* \brief Write Scratch pad register
*
* \param [in] uart identifies UART to use
* \param [in] value the value to be written
*
* /warning Reserved when retarget is used else it is free to use.
*
*/
static inline void hw_uart_write_scr(HW_UART_ID uart, uint8_t value)
{
UBA(uart)->UART2_SCR_REG = value;
}
/**
* \brief Read Scratch pad register
*
* \param [in] uart identifies UART to use
*
* \return register value
*
* \warning Reserved when retarget is used else it is free to use.
*
*/
static inline uint8_t hw_uart_read_scr(HW_UART_ID uart)
{
return UBA(uart)->UART2_SCR_REG;
}
//==================== Configuration functions =================================
/**
@@ -1162,6 +1205,40 @@ bool hw_uart_tx_in_progress(HW_UART_ID uart);
*/
bool hw_uart_rx_in_progress(HW_UART_ID uart);
#if dg_configUART_RX_CIRCULAR_DMA
/**
* \brief Enable circular RX DMA for UART
*
* This reconfigures RX DMA channel to use circular buffer for incoming data and enabled it
* immediately. Incoming data will be read by DMA to intermediate buffer. Subsequent calls to
* hw_uart_receive() will fire callback as soon as enough data are available in buffer to be read,
* but the actual read from intermediate buffer has to be done using hw_uart_copy_rx_circular_dma_buffer().
*
* Recommended way to move between DMA buffer and user buffer is to call hw_uart_abort_receive()
* that will copy the amount specified on read or the actual number of received bytes if
* hw_uart_abort_receive() was called before requested the amount was received.
*
* \note
* This can be only called for an UART which is configured using \p dg_configUARTx_RX_CIRCULAR_DMA_BUF_SIZE.
*
* \param [in] uart identifies UART to use
*
*/
void hw_uart_enable_rx_circular_dma(HW_UART_ID uart);
/**
* \brief Copy data from circular RX DMA buffer to user buffer
*
* \param [in] uart identifies UART to use
* \param [in] buf buffer to copy data to
* \param [in] len length of data to copy to buffer
*
*/
void hw_uart_copy_rx_circular_dma_buffer(HW_UART_ID uart, uint8_t *buf, uint16_t len);
#endif /* dg_configUART_RX_CIRCULAR_DMA */
#endif /* dg_configUSE_HW_UART */
#endif /* HW_UART_H_ */
+4 -2
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup Watchdog_Timer
* \{
* \brief Watchdog Timer
*/
/**
@@ -37,7 +38,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
*****************************************************************************************
*/
@@ -47,7 +49,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <black_orca.h>
#include <sdk_defs.h>
#define NMI_MAGIC_NUMBER 0xDEADBEEF
+161 -23
View File
@@ -5,6 +5,7 @@
* \{
* \addtogroup Wakeup_Timer
* \{
* \brief Wakeup Timer
*/
/**
@@ -37,21 +38,41 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
*****************************************************************************************
*/
#ifndef HW_WKUP_H_
#define HW_WKUP_H_
#if dg_configUSE_HW_USB_WKUP
#if dg_configUSE_HW_WKUP
#include <stdbool.h>
#include <stdint.h>
#include <black_orca.h>
#include <sdk_defs.h>
#include "hw_gpio.h"
#if (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
#define WKUP_SEL_P0_BASE_REG (volatile uint16_t *)(&WAKEUP->WKUP_SEL_GPIO_P0_REG)
#else
#define WKUP_SEL_P0_BASE_REG (volatile uint16_t *)(&WAKEUP->WKUP_SELECT_P0_REG)
#endif
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
/**
* \brief Wakeup timer configuration
*
*/
typedef struct {
uint8_t pin_state[HW_GPIO_NUM_PORTS]; /**< pin states in each port, 1: enabled, 0: disabled */
uint8_t pin_trigger[HW_GPIO_NUM_PORTS]; /**< pin triggers in each port, 1: low, 0: high */
} wkup_pin_config_t;
extern volatile wkup_pin_config_t wkup_pin_config; /**< stores wkup pin configuration */
extern volatile uint8_t wkup_status[HW_GPIO_NUM_PORTS]; /**< stores wakeup sources */
#endif
/**
* \brief Get the mask of a field of an WKUP register.
*
@@ -96,6 +117,7 @@
WAKEUP->WKUP_##reg##_REG = ((WAKEUP->WKUP_##reg##_REG & ~(WAKEUP_WKUP_##reg##_REG_##field##_Msk)) | \
((WAKEUP_WKUP_##reg##_REG_##field##_Msk) & ((new_val) << (WAKEUP_WKUP_##reg##_REG_##field##_Pos))))
/**
* \brief Pin state which increments event counter
*
@@ -110,9 +132,17 @@ typedef enum {
*
*/
typedef struct {
uint8_t threshold; /**< counter threshold */
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
/**
* counter threshold
*
* \warning Supported only in DA14680/1 chips
*/
uint8_t threshold;
#endif
#if !((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A))
uint8_t debounce; /**< debounce time in ms */
#endif
uint8_t pin_state[HW_GPIO_NUM_PORTS]; /**< pin states in each port, see hw_wkup_configure_port */
uint8_t pin_trigger[HW_GPIO_NUM_PORTS]; /**< pin triggers in each port, see hw_wkup_configure_port */
} wkup_config;
@@ -149,7 +179,7 @@ void hw_wkup_configure(const wkup_config *cfg);
* Callback function is called when interrupt is generated, i.e. event counter reaches configured
* value. Interrupt is automatically enabled after calling this function. Application should reset
* interrupt in callback function using hw_wkup_reset_interrupt(). If no callback is specified,
* interrupt will be automatically cleared by driver.
* interrupt will be automatically cleared by the driver.
*
* \param [in] cb callback function
* \param [in] prio the priority of the interrupt
@@ -187,23 +217,25 @@ static inline void hw_wkup_reset_interrupt(void)
*/
void hw_wkup_handler(void);
#if !((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A))
/**
* \brief Set debounce time
*
* Setting debounce time to 0 will disable hardware debouncing. Maximum debounce time is 63ms.
*
* \param [in] time_ms debounce time in miliseconds
* \param [in] time_ms debounce time in milliseconds
*
*/
static inline void hw_wkup_set_debounce_time(uint8_t time_ms)
{
HW_WKUP_REG_SETF(CTRL, WKUP_DEB_VALUE, time_ms);
}
#endif //!((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A))
/**
* \brief Get current debounce time
*
* \return debounce time in miliseconds
* \return debounce time in milliseconds
*
*/
static inline uint8_t hw_wkup_get_debounce_time(void)
@@ -211,6 +243,7 @@ static inline uint8_t hw_wkup_get_debounce_time(void)
return HW_WKUP_REG_GETF(CTRL, WKUP_DEB_VALUE);
}
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
/**
* \brief Set threshold for event counter
*
@@ -218,6 +251,7 @@ static inline uint8_t hw_wkup_get_debounce_time(void)
*
* \param [in] level number of events
*
* \warning Supported only in DA14680/1 chips
* \sa hw_wkup_register_interrupt
* \sa hw_wkup_get_counter
*
@@ -232,6 +266,7 @@ static inline void hw_wkup_set_counter_threshold(uint8_t level)
*
* \return number of events
*
* \warning Supported only in DA14680/1 chips
*/
static inline uint8_t hw_wkup_get_counter_threshold(void)
{
@@ -247,6 +282,8 @@ static inline uint8_t hw_wkup_get_counter_threshold(void)
*
* \note The counter is automatically reset by the hardware when the interrupt is generated.
*
* \warning Supported only in DA14680/1 chips
*
* \sa hw_wkup_reset_counter
*
*/
@@ -261,11 +298,13 @@ static inline uint8_t hw_wkup_get_counter(void)
* There is no need to reset counter manually in interrupt callback - it's reset automatically by
* hardware.
*
* \warning Supported only in DA14680/1 chips
*/
static inline void hw_wkup_reset_counter(void)
{
WAKEUP->WKUP_RESET_CNTR_REG = 1;
}
#endif
/**
* \brief Set GPIO pin event counting state
@@ -284,10 +323,14 @@ static inline void hw_wkup_reset_counter(void)
*/
static inline void hw_wkup_set_pin_state(HW_GPIO_PORT port, HW_GPIO_PIN pin, bool enabled)
{
uint16_t sel_rx_reg = *((volatile uint16_t *)WAKEUP_BASE + 5 + port);
sel_rx_reg &= ~(1 << pin);
sel_rx_reg |= (!!enabled) << pin;
*((volatile uint16_t *)WAKEUP_BASE + 5 + port) = sel_rx_reg;
volatile uint16_t *wkup_pin_enable_reg = WKUP_SEL_P0_BASE_REG + port;
uint16_t wkup_pin_enable_val = *wkup_pin_enable_reg;
wkup_pin_enable_val &= ~(1 << pin);
wkup_pin_enable_val |= (!!enabled) << pin;
*wkup_pin_enable_reg = wkup_pin_enable_val;
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
wkup_pin_config.pin_state[port] = wkup_pin_enable_val;
#endif
}
/** \brief Get GPIO pin event counting state
@@ -302,8 +345,8 @@ static inline void hw_wkup_set_pin_state(HW_GPIO_PORT port, HW_GPIO_PIN pin, boo
*/
static inline bool hw_wkup_get_pin_state(HW_GPIO_PORT port, HW_GPIO_PIN pin)
{
uint16_t sel_rx_reg = *((volatile uint16_t *)WAKEUP_BASE + 5 + port);
return (sel_rx_reg & (1 << pin)) >> pin;
uint16_t wkup_pin_enable_val = *(WKUP_SEL_P0_BASE_REG + port);
return (wkup_pin_enable_val & (1 << pin)) >> pin;
}
/**
@@ -323,10 +366,13 @@ static inline bool hw_wkup_get_pin_state(HW_GPIO_PORT port, HW_GPIO_PIN pin)
static inline void hw_wkup_set_pin_trigger(HW_GPIO_PORT port, HW_GPIO_PIN pin,
HW_WKUP_PIN_STATE state)
{
uint16_t pol_rx_reg = *((volatile uint16_t *)WAKEUP_BASE + 10 + port);
uint16_t pol_rx_reg = *((volatile uint16_t *)(&WAKEUP->WKUP_POL_P0_REG) + port);
pol_rx_reg &= ~(1 << pin);
pol_rx_reg |= (!!state) << pin;
*((volatile uint16_t *)WAKEUP_BASE + 10 + port) = pol_rx_reg;
*((volatile uint16_t *)(&WAKEUP->WKUP_POL_P0_REG) + port) = pol_rx_reg;
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
wkup_pin_config.pin_trigger[port] = pol_rx_reg;
#endif
}
/** \brief Get GPIO pin state which triggers event
@@ -341,7 +387,7 @@ static inline void hw_wkup_set_pin_trigger(HW_GPIO_PORT port, HW_GPIO_PIN pin,
*/
static inline HW_WKUP_PIN_STATE hw_wkup_get_pin_trigger(HW_GPIO_PORT port, HW_GPIO_PIN pin)
{
uint16_t pol_rx_reg = *((volatile uint16_t *)WAKEUP_BASE + 10 + port);
uint16_t pol_rx_reg = *((volatile uint16_t *)(&WAKEUP->WKUP_POL_P0_REG) + port);
return (pol_rx_reg & (1 << pin)) >> pin;
}
@@ -387,12 +433,16 @@ static inline void hw_wkup_configure_pin(HW_GPIO_PORT port, HW_GPIO_PIN pin, boo
*/
static inline void hw_wkup_configure_port(HW_GPIO_PORT port, uint8_t enabled, uint8_t state)
{
*((volatile uint16_t *)WAKEUP_BASE + 10 + port) = ~state; // register has inverted logic than state bitmask
*((volatile uint16_t *)WAKEUP_BASE + 5 + port) = enabled;
*((volatile uint16_t *)(&WAKEUP->WKUP_POL_P0_REG) + port) = ~state; // register has inverted logic than state bitmask
*(WKUP_SEL_P0_BASE_REG + port) = enabled;
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
wkup_pin_config.pin_state[port] = enabled;
wkup_pin_config.pin_trigger[port] = ~state;
#endif
}
/**
* \brief Get event counting state of all pins in GPIO port
* \brief Get state (enabled/disabled) of all pins in GPIO port
*
* Meaning of bits in returned bitmask is the same as in hw_wkup_configure_port().
*
@@ -403,7 +453,15 @@ static inline void hw_wkup_configure_port(HW_GPIO_PORT port, uint8_t enabled, ui
*/
static inline uint8_t hw_wkup_get_port_state(HW_GPIO_PORT port)
{
return *((volatile uint16_t *)WAKEUP_BASE + 5 + port);
#if dg_configLATCH_WKUP_SOURCE
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
return wkup_pin_config.pin_state[port];
#else
return *((volatile uint16_t *)(&WAKEUP->WKUP_SEL_GPIO_P0_REG) + port);
#endif
#else
return *((volatile uint16_t *)(&WAKEUP->WKUP_SELECT_P0_REG) + port);
#endif
}
/**
@@ -418,7 +476,11 @@ static inline uint8_t hw_wkup_get_port_state(HW_GPIO_PORT port)
*/
static inline uint8_t hw_wkup_get_port_trigger(HW_GPIO_PORT port)
{
return ~(*((volatile uint16_t *)WAKEUP_BASE + 10 + port)); // register has inverted logic that returned bitmask
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
return wkup_pin_config.pin_trigger[port];
#else
return ~(*((volatile uint16_t *)(&WAKEUP->WKUP_POL_P0_REG) + port)); // register has inverted logic that returned bitmask
#endif
}
/**
@@ -451,8 +513,84 @@ static inline void hw_wkup_unfreeze(void)
GPREG->RESET_FREEZE_REG = GPREG_RESET_FREEZE_REG_FRZ_WKUPTIM_Msk;
}
#endif /* dg_configUSE_HW_USB_WKUP */
/**
* \brief Get port status on last wake up
*
* Meaning of bits in returned bitmask is the same as in hw_wkup_configure_port().
*
* \return port pin event counter state bitmask
*
* \sa hw_wkup_configure_port
*
*/
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
static inline uint8_t hw_wkup_get_status(HW_GPIO_PORT port)
{
return wkup_status[port];
}
#elif dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
static inline uint8_t hw_wkup_get_status(HW_GPIO_PORT port)
{
switch (port) {
case HW_GPIO_PORT_0:
return HW_WKUP_REG_GETF(STATUS_0, WKUP_STAT_P0);
case HW_GPIO_PORT_1:
return HW_WKUP_REG_GETF(STATUS_0, WKUP_STAT_P1);
case HW_GPIO_PORT_2:
return HW_WKUP_REG_GETF(STATUS_1, WKUP_STAT_P2);
case HW_GPIO_PORT_3:
return HW_WKUP_REG_GETF(STATUS_2, WKUP_STAT_P3);
case HW_GPIO_PORT_4:
return HW_WKUP_REG_GETF(STATUS_2, WKUP_STAT_P4);
default:
ASSERT_WARNING(0);//Invalid argument
}
}
#endif
/**
* \brief Clear latch status
*
* This function MUST be called by any user-specified interrupt callback,
* to clear the interrupt latch status.
*
* \param [in] port port number
* \param [in] status pin status bitmask
*
* \sa hw_wkup_get_status
*/
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) && dg_configLATCH_WKUP_SOURCE
static inline void hw_wkup_clear_status(HW_GPIO_PORT port, uint8_t status)
{
ASSERT_WARNING((port>=HW_GPIO_PORT_0) && (port<=HW_GPIO_PORT_4))
wkup_status[port] &= ~status;
}
#elif dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
static inline void hw_wkup_clear_status(HW_GPIO_PORT port, uint8_t status)
{
switch (port) {
case HW_GPIO_PORT_0:
HW_WKUP_REG_SETF(CLEAR_0, WKUP_CLEAR_P0, status);
break;
case HW_GPIO_PORT_1:
HW_WKUP_REG_SETF(CLEAR_0, WKUP_CLEAR_P1, status);
break;
case HW_GPIO_PORT_2:
HW_WKUP_REG_SETF(CLEAR_1, WKUP_CLEAR_P2, status);
break;
case HW_GPIO_PORT_3:
HW_WKUP_REG_SETF(CLEAR_2, WKUP_CLEAR_P3, status);
break;
case HW_GPIO_PORT_4:
HW_WKUP_REG_SETF(CLEAR_2, WKUP_CLEAR_P4, status);
break;
default:
ASSERT_WARNING(0);//Invalid argument
}
}
#endif
#endif /* dg_configUSE_HW_WKUP */
#endif /* HW_WKUP_H_ */
/**
+39 -26
View File
@@ -17,30 +17,31 @@
*
* @brief TCS Handler header file.
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -48,7 +49,7 @@
#define SYS_TCS_H_
#include <stdint.h>
#include "black_orca.h"
#include "sdk_defs.h"
typedef enum sys_tcs_area_type {
#ifdef CONFIG_USE_BLE
@@ -63,8 +64,20 @@ typedef enum sys_tcs_area_type {
tcs_system, /* Last area. Add any missing areas above this! */
} sys_tcs_area_t;
extern bool is_calibrated_chip;
/**
* \brief Flag to check whether the TCS is written or not.
* \details true, the TCS is written (the BANDGAP_REG value exists in the TCS)
* false, the TCS is empty
*/
extern bool sys_tcs_is_calibrated_chip;
/**
* \brief The XTAL16M settling time (in TCS).
* \details XTAL32K, the settling time is expressed in clock cycles
* RCX, not applicable; the SDK hard-coded value is used
* If it is zero, the hard-coded value (dg_configXTAL16_SETTLE_TIME) is applied.
*/
extern uint16_t sys_tcs_xtal16m_settling_time;
/**
* \brief Initialize the variables used from the TCS handling module.
+222 -71
View File
@@ -14,30 +14,31 @@
*
* @brief Clock and Power Manager Driver
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -54,7 +55,19 @@
*/
extern sys_clk_t cm_sysclk;
extern ahb_div_t cm_ahbclk;
\
/*
* Global variables
*/
__RETAINED_UNINIT uint16_t hw_cpm_bod_enabled_in_tcs;
#if (dg_configPOWER_1V8_ACTIVE == 1)
__RETAINED_RW static bool cpm_1v8_state = true;
#else
static const bool cpm_1v8_state = false;
#endif
/*
* Local variables
@@ -117,7 +130,9 @@ void hw_cpm_set_divn(bool freq)
REG_SET_FIELD(CRG_TOP, CLK_CTRL_REG, DIVN_XTAL32M_MODE, regval, val);
REG_SET_FIELD(CRG_TOP, CLK_CTRL_REG, XTAL32M_MODE, regval, val);
CRG_TOP->CLK_CTRL_REG = regval;
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
CRG_TOP->DIVN_SYNC_REG = val;
#endif
}
@@ -329,7 +344,7 @@ void hw_cpm_pll_sys_off(void)
}
void hw_cpm_start_calibration(cal_clk_t clk_type, uint32_t cycles)
__RETAINED_CODE void hw_cpm_start_calibration(cal_clk_t clk_type, uint32_t cycles)
{
ASSERT_WARNING(REG_GETF(ANAMISC, CLK_REF_SEL_REG, REF_CAL_START) == 0); // Must be disabled
@@ -386,24 +401,25 @@ void hw_cpm_dcdc_config(void)
REG_MSK(DCDC, DCDC_VDD_0_REG, DCDC_VDD_FAST_RAMPING));
REG_SETF(DCDC, DCDC_VDD_1_REG, DCDC_VDD_CUR_LIM_MAX_LV, 0xD);
REG_SETF(DCDC, DCDC_V14_0_REG, DCDC_V14_VOLTAGE, 0x7);
if (dg_configPOWER_1V8_ACTIVE == 1)
{
REG_SETF(DCDC, DCDC_V18_0_REG, DCDC_V18_VOLTAGE, 0x16);
}
if (dg_configPOWER_1V8P == 1)
{
REG_SETF(DCDC, DCDC_V18P_0_REG, DCDC_V18P_VOLTAGE, 0x16);
}
// End of preferred settings
DCDC->DCDC_VDD_1_REG |= ((1 << REG_POS(DCDC, DCDC_VDD_1_REG, DCDC_VDD_ENABLE_HV)) |
(1 << REG_POS(DCDC, DCDC_VDD_1_REG, DCDC_VDD_ENABLE_LV)));
REG_SETF(DCDC, DCDC_V14_0_REG, DCDC_V14_VOLTAGE, 0x7);
if (dg_configPOWER_FLASH == 1)
{
REG_SETF(DCDC, DCDC_V18_0_REG, DCDC_V18_VOLTAGE, 0x16);
}
if (dg_configPOWER_EXT_1V8_PERIPHERALS == 1)
{
REG_SETF(DCDC, DCDC_V18P_0_REG, DCDC_V18P_VOLTAGE, 0x16);
}
if (dg_configPOWER_FLASH == 1)
if ((dg_configPOWER_1V8_ACTIVE == 1) && cpm_1v8_state)
{
DCDC->DCDC_V18_1_REG |= (1 << REG_POS(DCDC, DCDC_V18_1_REG, DCDC_V18_ENABLE_HV));
DCDC->DCDC_V18_1_REG &= ~REG_MSK(DCDC, DCDC_V18_1_REG, DCDC_V18_ENABLE_LV);
@@ -414,7 +430,7 @@ void hw_cpm_dcdc_config(void)
REG_MSK(DCDC, DCDC_V18_1_REG, DCDC_V18_ENABLE_LV));
}
if (dg_configPOWER_EXT_1V8_PERIPHERALS == 1)
if (dg_configPOWER_1V8P == 1)
{
DCDC->DCDC_V18P_1_REG |= (1 << REG_POS(DCDC, DCDC_V18P_1_REG, DCDC_V18P_ENABLE_HV));
DCDC->DCDC_V18P_1_REG &= ~REG_MSK(DCDC, DCDC_V18P_1_REG, DCDC_V18P_ENABLE_LV);
@@ -464,11 +480,9 @@ void hw_cpm_set_preferred_values(void)
CRG_TOP->CLK_16M_REG = reg;
REG_SETF(CRG_TOP, BANDGAP_REG, LDO_SLEEP_TRIM, 0x8);
if (BLACK_ORCA_TARGET_IC >= BLACK_ORCA_IC_VERSION(A, C))
{
REG_SETF(CRG_TOP, BANDGAP_REG, BYPASS_COLD_BOOT_DISABLE, 1); // Last review date: Feb 15, 2016 - 12:25:47
}
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
REG_SETF(CRG_TOP, BANDGAP_REG, BYPASS_COLD_BOOT_DISABLE, 1); // Last review date: Feb 15, 2016 - 12:25:47
#endif
}
void hw_cpm_configure_xtal32k_pins(void)
@@ -477,13 +491,16 @@ void hw_cpm_configure_xtal32k_pins(void)
GPIO->P21_MODE_REG = 0x26;
}
void hw_cpm_configure_ext32k_pins(void)
{
GPIO->P20_MODE_REG = 0x0;
}
void hw_cpm_trigger_sw_cursor(void)
{
volatile int i;
if (dg_configUSE_SW_CURSOR == 1)
{
if (dg_configBLACK_ORCA_MB_REV == BLACK_ORCA_MB_REV_B)
if (dg_configBLACK_ORCA_MB_REV == BLACK_ORCA_MB_REV_D)
{
SW_CURSOR_SET = 1 << SW_CURSOR_PIN;
}
@@ -494,11 +511,9 @@ void hw_cpm_trigger_sw_cursor(void)
SW_CURSOR_GPIO = 0x300;
for (i = 0; i < 100; i++)
{
}
hw_cpm_delay_usec(50);
if (dg_configBLACK_ORCA_MB_REV == BLACK_ORCA_MB_REV_B)
if (dg_configBLACK_ORCA_MB_REV == BLACK_ORCA_MB_REV_D)
{
SW_CURSOR_RESET = 1 << SW_CURSOR_PIN;
}
@@ -533,7 +548,12 @@ void hw_cpm_assert_trigger_gpio(void)
{
if (EXCEPTION_DEBUG == 1)
{
if (dg_configUSE_LP_CLK != LP_CLK_RCX)
if (dg_configLP_CLK_SOURCE == LP_CLK_IS_DIGITAL)
{
hw_cpm_configure_ext32k_pins();
}
else if ((dg_configUSE_LP_CLK == LP_CLK_32000)
|| (dg_configUSE_LP_CLK == LP_CLK_32768))
{
hw_cpm_configure_xtal32k_pins();
}
@@ -549,27 +569,27 @@ void hw_cpm_assert_trigger_gpio(void)
do { \
uint16_t val = 0; \
\
REG_SET_FIELD(CRG_TOP, BOD_CTRL_REG, BOD_VDD_LVL, val, 1); /* VDD Level (700mV) */ \
REG_SET_FIELD(CRG_TOP, BOD_CTRL_REG, BOD_V33_TRIM, val, 2); /* V33 trim */ \
REG_SET_FIELD(CRG_TOP, BOD_CTRL_REG, BOD_1V8_PA_TRIM, val, 2); /* 1V8P trim */ \
REG_SET_FIELD(CRG_TOP, BOD_CTRL_REG, BOD_1V8_FLASH_TRIM, val, 2); /* 1V8 trim */ \
REG_SET_FIELD(CRG_TOP, BOD_CTRL_REG, BOD_VDD_TRIM, val, 2); /* VDD trim */ \
CRG_TOP->BOD_CTRL_REG = val; \
REG_SETF(CRG_TOP, BOD_CTRL_REG, BOD_VDD_LVL, 1); /* VDD Level (700mV) */ \
\
val = 0; \
/* 1V8 Flash enable */ \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_VBAT_EN, val, 1); \
/* 1V8 Flash enable */ \
if ((dg_configPOWER_FLASH == 1) && (dg_configFLASH_POWER_OFF == 0)) { \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_FLASH_EN, val, 1); \
if (hw_cpm_bod_enabled_in_tcs == 0) { \
val = 0; \
/* VBAT enable */ \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_VBAT_EN, val, 1); \
/* 1V8 Flash enable */ \
if ((dg_configPOWER_1V8_ACTIVE == 1) && (dg_configPOWER_1V8_SLEEP == 1)) { \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_FLASH_EN, val, 1); \
} \
/* 1V8P enable */ \
if (dg_configPOWER_1V8P == 1) { \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_PA_EN, val, 1); \
} \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_VDD_EN, val, 1); /* VDD enable */ \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_RESET_EN, val, 1); /* Reset enable */\
CRG_TOP->BOD_CTRL2_REG = val; \
} \
/* 1V8P enable */ \
if (dg_configPOWER_EXT_1V8_PERIPHERALS == 1) { \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_PA_EN, val, 1); \
else { \
CRG_TOP->BOD_CTRL2_REG = hw_cpm_bod_enabled_in_tcs; \
} \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_VDD_EN, val, 1); /* VDD enable */ \
REG_SET_FIELD(CRG_TOP, BOD_CTRL2_REG, BOD_RESET_EN, val, 1); /* Reset enable */ \
CRG_TOP->BOD_CTRL2_REG = val; \
} while (0);
void hw_cpm_activate_bod_protection(void)
@@ -582,6 +602,137 @@ void hw_cpm_activate_bod_protection_at_init(void)
HW_CPM_ACTIVATE_BOD_PROTECTION
}
void hw_cpm_configure_bod_protection(void)
{
REG_SETF(CRG_TOP, BOD_CTRL_REG, BOD_VDD_LVL, 1); /* VDD Level (700mV) */
if (hw_cpm_bod_enabled_in_tcs == 0)
{
/* VBAT enable */
REG_SET_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_VBAT_EN);
/* 1V8 Flash enable */
if ((dg_configPOWER_1V8_ACTIVE == 1) && (dg_configPOWER_1V8_SLEEP == 1))
{
REG_SET_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_FLASH_EN);
}
else
{
REG_CLR_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_FLASH_EN);
}
/* 1V8P enable */
if (dg_configPOWER_1V8P == 1)
{
REG_SET_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_PA_EN);
}
else
{
REG_CLR_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_PA_EN);
}
/* Generate Reset on a BOD event */
REG_SET_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_RESET_EN);
}
else
{
CRG_TOP->BOD_CTRL2_REG = hw_cpm_bod_enabled_in_tcs;
}
}
void hw_cpm_set_1v8_state(bool state)
{
if ((dg_configPOWER_1V8_ACTIVE == 1) && (cpm_1v8_state != state))
{
uint32_t reg;
uint32_t dcdc_state;
GLOBAL_INT_DISABLE();
reg = CRG_TOP->LDO_CTRL2_REG;
dcdc_state = (uint32_t)REG_GETF(DCDC, DCDC_CTRL_0_REG, DCDC_MODE);
#if (dg_configPOWER_1V8_ACTIVE == 1)
cpm_1v8_state = state;
#endif
if (!cpm_1v8_state)
{
// Disable BOD for the 1V8 rail
if (dg_configUSE_BOD == 1)
{
REG_CLR_BIT(CRG_TOP, BOD_CTRL2_REG, BOD_1V8_FLASH_EN);
}
// Deactivate 1V8 rail in LDOs
REG_CLR_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_ON, reg);
if (dg_configPOWER_1V8_SLEEP == 1)
{
REG_SET_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_RET_DISABLE,
reg, 1);
}
CRG_TOP->LDO_CTRL2_REG = reg;
// Deactivate 1V8 rail in DCDC
if (dg_configUSE_DCDC == 1)
{
// Disable DCDC to apply change
REG_SETF(DCDC, DCDC_CTRL_0_REG, DCDC_MODE, 0);
DCDC->DCDC_V18_1_REG &=
~(REG_MSK(DCDC, DCDC_V18_1_REG, DCDC_V18_ENABLE_HV) |
REG_MSK(DCDC, DCDC_V18_1_REG, DCDC_V18_ENABLE_LV));
// Restore DCDC
REG_SETF(DCDC, DCDC_CTRL_0_REG, DCDC_MODE, dcdc_state);
}
}
else
{
// Restore 1V8 rail in LDOs
/* But not when DCDC is running... */
if (dcdc_state != 1)
{
REG_SET_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_ON,
reg, 1);
}
if (dg_configPOWER_1V8_SLEEP == 1)
{
REG_CLR_FIELD(CRG_TOP, LDO_CTRL2_REG, LDO_1V8_FLASH_RET_DISABLE,
reg);
}
CRG_TOP->LDO_CTRL2_REG = reg;
// Restore 1V8 rail in DCDC
if (dg_configUSE_DCDC == 1)
{
DCDC->DCDC_V18_1_REG |= (1 << REG_POS(DCDC, DCDC_V18_1_REG,
DCDC_V18_ENABLE_HV));
DCDC->DCDC_V18_1_REG &= ~REG_MSK(DCDC, DCDC_V18_1_REG,
DCDC_V18_ENABLE_LV);
}
// Restore BOD setup
if (dg_configUSE_BOD == 1)
{
hw_cpm_delay_usec(200);
hw_cpm_configure_bod_protection();
}
}
GLOBAL_INT_RESTORE();
}
}
bool hw_cpm_get_1v8_state(void)
{
return cpm_1v8_state;
}
void hw_cpm_delay_usec(uint32_t usec)
{
sys_clk_t sclk;
+135 -6
View File
@@ -12,6 +12,8 @@
*
* @file hw_dma.c
*
* @brief Implementation of the DMA Low Level Driver.
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
@@ -42,8 +44,6 @@
#if dg_configUSE_HW_DMA
#include <global_io.h>
#include <core_cm0.h>
#include <hw_gpio.h>
#include <hw_dma.h>
@@ -60,7 +60,7 @@ static struct hw_dma_callback_data
void *user_data;
} dma_callbacks_user_data[8];
#define DMA_CHN_REG(reg, chan) ((uint16 *) (((int) &(reg)) + ((chan) << 4)))
#define DMA_CHN_REG(reg, chan) ((volatile uint16 *)(&(reg)) + ((chan) * 8))
/**
* \brief Initialize DMA Channel
@@ -127,29 +127,95 @@ void hw_dma_channel_initialization(DMA_setup *channel_setup)
{
case HW_DMA_CHANNEL_0:
case HW_DMA_CHANNEL_1:
GLOBAL_INT_DISABLE();
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA01_SEL, channel_setup->dma_req_mux);
GLOBAL_INT_RESTORE();
break;
case HW_DMA_CHANNEL_2:
case HW_DMA_CHANNEL_3:
GLOBAL_INT_DISABLE();
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA23_SEL, channel_setup->dma_req_mux);
GLOBAL_INT_RESTORE();
break;
case HW_DMA_CHANNEL_4:
case HW_DMA_CHANNEL_5:
GLOBAL_INT_DISABLE();
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA45_SEL, channel_setup->dma_req_mux);
GLOBAL_INT_RESTORE();
break;
case HW_DMA_CHANNEL_6:
case HW_DMA_CHANNEL_7:
GLOBAL_INT_DISABLE();
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA67_SEL, channel_setup->dma_req_mux);
GLOBAL_INT_RESTORE();
break;
default:
break;
}
#if dg_configDMA_DYNAMIC_MUX || (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
/*
* When different DMA channels are used for same device it is important
* that only one trigger is set for specific device at a time.
* Having same trigger for different channels can cause unpredictable results.
* Following code also should help when SPI1 is assigned to non 0 channel.
*/
GLOBAL_INT_DISABLE();
switch (channel_setup->channel_number)
{
case HW_DMA_CHANNEL_6:
case HW_DMA_CHANNEL_7:
if (REG_GETF(DMA, DMA_REQ_MUX_REG, DMA45_SEL) == channel_setup->dma_req_mux)
{
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA45_SEL, HW_DMA_TRIG_NONE);
}
/* no break */
case HW_DMA_CHANNEL_4:
case HW_DMA_CHANNEL_5:
if (REG_GETF(DMA, DMA_REQ_MUX_REG, DMA23_SEL) == channel_setup->dma_req_mux)
{
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA23_SEL, HW_DMA_TRIG_NONE);
}
/* no break */
case HW_DMA_CHANNEL_2:
case HW_DMA_CHANNEL_3:
if (REG_GETF(DMA, DMA_REQ_MUX_REG, DMA01_SEL) == channel_setup->dma_req_mux)
{
REG_SETF(DMA, DMA_REQ_MUX_REG, DMA01_SEL, HW_DMA_TRIG_NONE);
}
break;
case HW_DMA_CHANNEL_0:
case HW_DMA_CHANNEL_1:
default:
break;
}
GLOBAL_INT_RESTORE();
#endif
}
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B)
//Set REQ_SENSE bit of i2c and Uart peripherals TX path
if (((channel_setup->dma_req_mux == HW_DMA_TRIG_UART_RXTX) ||
(channel_setup->dma_req_mux == HW_DMA_TRIG_UART2_RXTX) ||
(channel_setup->dma_req_mux == HW_DMA_TRIG_I2C_RXTX) ||
(channel_setup->dma_req_mux == HW_DMA_TRIG_I2C2_RXTX)) &&
(channel_setup->channel_number & 1)) //odd channels used for TX
{
REG_SET_FIELD(DMA, DMA0_CTRL_REG, REQ_SENSE, *dma_x_ctrl_reg, 1);
}
#endif
src_address = black_orca_phy_addr(channel_setup->src_address);
dest_address = black_orca_phy_addr(channel_setup->dest_address);
@@ -188,6 +254,69 @@ void hw_dma_channel_initialization(DMA_setup *channel_setup)
dma_callbacks_user_data[channel_setup->channel_number].user_data = channel_setup->user_data;
}
void hw_dma_channel_update_source(HW_DMA_CHANNEL channel, void *addr, uint16_t length,
hw_dma_transfer_cb cb)
{
uint32_t phy_addr = black_orca_phy_addr((uint32_t) addr);
dma_callbacks_user_data[channel].callback = cb;
// Look up DMAx_A_STARTL_REG address
volatile uint16 *dma_x_a_start_low_reg = DMA_CHN_REG(DMA->DMA0_A_STARTL_REG, channel);
// Look up DMAx_A_STARTH_REG address
volatile uint16 *dma_x_a_start_high_reg = DMA_CHN_REG(DMA->DMA0_A_STARTH_REG, channel);
// Look up DMAX_LEN_REG address
volatile uint16 *dma_x_len_reg = DMA_CHN_REG(DMA->DMA0_LEN_REG, channel);
volatile uint16 *dma_x_int_reg = DMA_CHN_REG(DMA->DMA0_INT_REG, channel);
// Set source address registers
*dma_x_a_start_low_reg = (phy_addr & 0xffff);
*dma_x_a_start_high_reg = (phy_addr >> 16);
*dma_x_int_reg = length - 1;
// Set the transfer length
*dma_x_len_reg = length - 1;
}
void hw_dma_channel_update_destination(HW_DMA_CHANNEL channel, void *addr, uint16_t length,
hw_dma_transfer_cb cb)
{
uint32_t phy_addr = black_orca_phy_addr((uint32_t) addr);
dma_callbacks_user_data[channel].callback = cb;
// Look up DMAx_B_STARTL_REG address
volatile uint16 *dma_x_b_start_low_reg = DMA_CHN_REG(DMA->DMA0_B_STARTL_REG, channel);
// Look up DMAx_B_STARTH_REG address
volatile uint16 *dma_x_b_start_high_reg = DMA_CHN_REG(DMA->DMA0_B_STARTH_REG, channel);
// Look up DMAX_LEN_REG address
volatile uint16 *dma_x_len_reg = DMA_CHN_REG(DMA->DMA0_LEN_REG, channel);
volatile uint16 *dma_x_int_reg = DMA_CHN_REG(DMA->DMA0_INT_REG, channel);
// Set destination address registers
*dma_x_b_start_low_reg = (phy_addr & 0xffff);
*dma_x_b_start_high_reg = (phy_addr >> 16);
*dma_x_int_reg = length - 1;
// Set the transfer length
*dma_x_len_reg = length - 1;
}
void hw_dma_channel_update_int_ix(HW_DMA_CHANNEL channel, uint16_t int_ix)
{
volatile uint16 *dma_x_int_reg = DMA_CHN_REG(DMA->DMA0_INT_REG, channel);
*dma_x_int_reg = int_ix;
}
/**
* \brief Enable or disable a DMA channel
*
@@ -264,7 +393,7 @@ bool hw_dma_channel_active(void)
}
/**
* \brief Capture Timer Interrupt Handler
* \brief Capture DMA Interrupt Handler
*
* Calls user interrupt handler
*
@@ -318,13 +447,13 @@ void DMA_Handler(void)
void hw_dma_channel_stop(HW_DMA_CHANNEL channel_number)
{
// Stopping DMA will clear DMAx_IDX_REG so read it before
uint16 *dma_x_idx_reg = DMA_CHN_REG(DMA->DMA0_IDX_REG, channel_number);
volatile uint16 *dma_x_idx_reg = DMA_CHN_REG(DMA->DMA0_IDX_REG, channel_number);
dma_helper(channel_number, *dma_x_idx_reg, true);
}
uint16_t hw_dma_transfered_bytes(HW_DMA_CHANNEL channel_number)
{
uint16 *dma_x_int_reg = dma_x_int_reg = DMA_CHN_REG(DMA->DMA0_IDX_REG, channel_number);
volatile uint16 *dma_x_int_reg = dma_x_int_reg = DMA_CHN_REG(DMA->DMA0_IDX_REG, channel_number);
return *dma_x_int_reg;
}
@@ -38,13 +38,14 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*****************************************************************************************
*/
#if dg_configFEM == FEM_SKY66112_11
#include "stdint.h"
#include "black_orca.h"
#include "sdk_defs.h"
#include "hw_gpio.h"
#include "hw_fem_sky66112-11.h"
@@ -70,10 +71,6 @@ int hw_fem_set_bias(uint16_t voltage)
value = (voltage - 1200) / 27.5;
// /* Value is actually one lower than computed */
// if (value > 0)
// value--;
#ifdef dg_configFEM_SKY66112_11_FEM_BIAS_V18P
REG_SETF(DCDC, DCDC_V18P_0_REG, DCDC_V18P_VOLTAGE, value);
return 0;
@@ -111,6 +108,7 @@ int hw_fem_set_bias2(uint16_t voltage)
return 0;
}
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
void hw_fem_set_txpower(bool high)
{
#if defined(dg_configFEM_SKY66112_11_CHL_PORT) && defined(dg_configFEM_SKY66112_11_CHL_PIN)
@@ -213,6 +211,260 @@ void hw_fem_set_rx_bypass(bool enable)
#endif
}
bool hw_fem_get_txpower(void)
{
return fem_config.tx_power;
}
bool hw_fem_get_tx_bypass(void)
{
return fem_config.tx_bypass;
}
bool hw_fem_get_rx_bypass(void)
{
return fem_config.rx_bypass;
}
#else /* dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B */
#ifdef CONFIG_USE_BLE
bool hw_fem_get_txpower_ble(void)
{
return fem_config.tx_power_ble;
}
bool hw_fem_get_tx_bypass_ble(void)
{
return fem_config.tx_bypass_ble;
}
bool hw_fem_get_rx_bypass_ble(void)
{
return fem_config.rx_bypass_ble;
}
#endif /* CONFIG_USE_BLE */
#ifdef CONFIG_USE_FTDF
bool hw_fem_get_txpower_ftdf(void)
{
return fem_config.tx_power_ftdf;
}
bool hw_fem_get_tx_bypass_ftdf(void)
{
return fem_config.tx_bypass_ftdf;
}
bool hw_fem_get_rx_bypass_ftdf(void)
{
return fem_config.rx_bypass_ftdf;
}
#endif /* CONFIG_USE_FTDF */
bool hw_fem_get_txpower(void)
{
return fem_config.tx_power_ble;
}
bool hw_fem_get_tx_bypass(void)
{
return fem_config.tx_bypass_ble;
}
bool hw_fem_get_rx_bypass(void)
{
return fem_config.rx_bypass_ble;
}
static void set_txpower(void)
{
if (!fem_config.started)
{
return;
}
/* CHL is always 0 on RX */
REG_CLR_BIT(RFCU_POWER, RF_PORT_EN_BLE_REG, RF_PORT4_RX);
REG_CLR_BIT(RFCU_POWER, RF_PORT_EN_FTDF_REG, RF_PORT4_RX);
if (fem_config.tx_power_ble)
{
REG_SET_BIT(RFCU_POWER, RF_PORT_EN_BLE_REG, RF_PORT4_TX);
}
if (fem_config.tx_power_ftdf)
{
REG_SET_BIT(RFCU_POWER, RF_PORT_EN_FTDF_REG, RF_PORT4_TX);
}
if (fem_config.tx_power_ble || fem_config.tx_power_ftdf)
{
/* TX Power high. Configure GPIO for DCF. Enable DCF on TX. */
hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_CHL_PORT,
dg_configFEM_SKY66112_11_CHL_PIN,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_PORT4_DCF);
}
else
{
/* TX Power low. Stop DCF, set GPIO to low */
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CHL_PORT,
dg_configFEM_SKY66112_11_CHL_PIN,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
}
}
void hw_fem_set_txpower_ble(bool high)
{
#if defined(dg_configFEM_SKY66112_11_CHL_PORT) && defined(dg_configFEM_SKY66112_11_CHL_PIN)
GLOBAL_INT_DISABLE();
fem_config.tx_power_ble = high;
set_txpower();
GLOBAL_INT_RESTORE();
#endif
}
void hw_fem_set_txpower_ftdf(bool high)
{
#if defined(dg_configFEM_SKY66112_11_CHL_PORT) && defined(dg_configFEM_SKY66112_11_CHL_PIN)
GLOBAL_INT_DISABLE();
fem_config.tx_power_ftdf = high;
set_txpower();
GLOBAL_INT_RESTORE();
#endif
}
void hw_fem_set_txpower(bool high)
{
hw_fem_set_txpower_ble(high);
}
static void set_bypass(void)
{
uint16_t m_ble = 0;
uint16_t m_ftdf = 0;
if (fem_config.tx_bypass_ble)
{
m_ble = RFCU_POWER_RF_PORT_EN_BLE_REG_RF_PORT3_TX_Msk;
}
if (fem_config.rx_bypass_ble)
{
m_ble |= RFCU_POWER_RF_PORT_EN_BLE_REG_RF_PORT3_RX_Msk;
}
if (fem_config.tx_bypass_ftdf)
{
m_ftdf = RFCU_POWER_RF_PORT_EN_FTDF_REG_RF_PORT3_TX_Msk;
}
if (fem_config.rx_bypass_ftdf)
{
m_ftdf |= RFCU_POWER_RF_PORT_EN_FTDF_REG_RF_PORT3_RX_Msk;
}
REG_SET_MASKED(RFCU_POWER, RF_PORT_EN_BLE_REG,
RFCU_POWER_RF_PORT_EN_BLE_REG_RF_PORT3_RX_Msk |
RFCU_POWER_RF_PORT_EN_BLE_REG_RF_PORT3_TX_Msk, m_ble);
REG_SET_MASKED(RFCU_POWER, RF_PORT_EN_FTDF_REG,
RFCU_POWER_RF_PORT_EN_FTDF_REG_RF_PORT3_RX_Msk |
RFCU_POWER_RF_PORT_EN_FTDF_REG_RF_PORT3_TX_Msk, m_ftdf);
if (m_ble == 0 && m_ftdf == 0)
{
/* No RX/TX bypass. Drive the interface line to low */
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CPS_PORT,
dg_configFEM_SKY66112_11_CPS_PIN,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
}
else
{
/* At least one of TX/RX needs bypass */
hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_CPS_PORT,
dg_configFEM_SKY66112_11_CPS_PIN,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_PORT3_DCF);
}
}
#ifdef CONFIG_USE_BLE
void hw_fem_set_tx_bypass_ble(bool enable)
{
#if defined(dg_configFEM_SKY66112_11_CPS_PORT) && defined(dg_configFEM_SKY66112_11_CPS_PIN)
GLOBAL_INT_DISABLE();
fem_config.tx_bypass_ble = enable;
if (fem_config.started)
{
set_bypass();
}
GLOBAL_INT_RESTORE();
#endif
}
void hw_fem_set_rx_bypass_ble(bool enable)
{
#if defined(dg_configFEM_SKY66112_11_CPS_PORT) && defined(dg_configFEM_SKY66112_11_CPS_PIN)
GLOBAL_INT_DISABLE();
fem_config.rx_bypass_ble = enable;
if (fem_config.started)
{
set_bypass();
}
GLOBAL_INT_RESTORE();
#endif
}
#endif /* CONFIG_USE_BLE */
#ifdef CONFIG_USE_FTDF
void hw_fem_set_tx_bypass_ftdf(bool enable)
{
#if defined(dg_configFEM_SKY66112_11_CPS_PORT) && defined(dg_configFEM_SKY66112_11_CPS_PIN)
GLOBAL_INT_DISABLE();
fem_config.tx_bypass_ftdf = enable;
if (fem_config.started)
{
set_bypass();
}
GLOBAL_INT_RESTORE();
#endif
}
void hw_fem_set_rx_bypass_ftdf(bool enable)
{
#if defined(dg_configFEM_SKY66112_11_CPS_PORT) && defined(dg_configFEM_SKY66112_11_CPS_PIN)
GLOBAL_INT_DISABLE();
fem_config.rx_bypass_ftdf = enable;
if (fem_config.started)
{
set_bypass();
}
GLOBAL_INT_RESTORE();
#endif
}
#endif /* CONFIG_USE_FTDF */
void hw_fem_set_tx_bypass(bool enable)
{
hw_fem_set_tx_bypass_ftdf(enable);
}
void hw_fem_set_rx_bypass(bool enable)
{
hw_fem_set_rx_bypass_ftdf(enable);
}
#endif /* dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B */
void hw_fem_set_antenna(bool one)
{
#if defined(dg_configFEM_SKY66112_11_ANTSEL_PORT) && defined(dg_configFEM_SKY66112_11_ANTSEL_PIN)
@@ -231,26 +483,11 @@ void hw_fem_set_antenna(bool one)
#endif
}
bool hw_fem_get_txpower(void)
{
return fem_config.tx_power;
}
bool hw_fem_get_antenna(void)
{
return fem_config.antsel;
}
bool hw_fem_get_tx_bypass(void)
{
return fem_config.tx_bypass;
}
bool hw_fem_get_rx_bypass(void)
{
return fem_config.rx_bypass;
}
void hw_fem_start(void)
{
GLOBAL_INT_DISABLE();
@@ -291,6 +528,28 @@ void hw_fem_start(void)
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, fem_config.antsel);
#endif
/******************************************************
* Setup RF_ANT_TRIM GPIOs
*/
/* RF_ANT_TRIM_0 Config */
#if defined(dg_configFEM_SKY66112_11_ANT_TRIM_0_PORT) && defined(dg_configFEM_SKY66112_11_ANT_TRIM_0_PIN)
hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_ANT_TRIM_0_PORT, dg_configFEM_SKY66112_11_ANT_TRIM_0_PIN,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_RF_ANT_TRIM0);
#endif
/* RF_ANT_TRIM_1 Config */
#if defined(dg_configFEM_SKY66112_11_ANT_TRIM_1_PORT) && defined(dg_configFEM_SKY66112_11_ANT_TRIM_1_PIN)
hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_ANT_TRIM_1_PORT, dg_configFEM_SKY66112_11_ANT_TRIM_1_PIN,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_RF_ANT_TRIM1);
#endif
/* RF_ANT_TRIM_2 Config */
#if defined(dg_configFEM_SKY66112_11_ANT_TRIM_2_PORT) && defined(dg_configFEM_SKY66112_11_ANT_TRIM_2_PIN)
hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_ANT_TRIM_2_PORT, dg_configFEM_SKY66112_11_ANT_TRIM_2_PIN,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_RF_ANT_TRIM2);
#endif
/******************************************************
* Setup DCFs
*/
@@ -339,9 +598,15 @@ void hw_fem_start(void)
REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_31_REG, RESET_OFFSET, dg_configFEM_SKY66112_11_TXRESET_DCF);
/* Enable DCFs */
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
RFCU_POWER->RF_PORT_EN_REG = rf_port_en;
hw_fem_set_txpower(fem_config.tx_power);
#else
RFCU_POWER->RF_PORT_EN_BLE_REG = rf_port_en;
RFCU_POWER->RF_PORT_EN_FTDF_REG = rf_port_en;
set_txpower();
#endif
set_bypass();
GLOBAL_INT_RESTORE();
@@ -353,7 +618,12 @@ void hw_fem_stop(void)
fem_config.started = false;
/* Stop DCF Timers */
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
RFCU_POWER->RF_PORT_EN_REG = 0x0;
#else
RFCU_POWER->RF_PORT_EN_BLE_REG = 0x0;
RFCU_POWER->RF_PORT_EN_FTDF_REG = 0x0;
#endif
/* Set all FEM interface outputs to GPIO mode, and value 0, in order to get the minimum
* possible power consumption from FEM
@@ -384,6 +654,21 @@ void hw_fem_stop(void)
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
#endif
#if defined(dg_configFEM_SKY66112_11_ANT_TRIM_0_PORT) && defined(dg_configFEM_SKY66112_11_ANT_TRIM_0_PIN)
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_ANT_TRIM_0_PORT, dg_configFEM_SKY66112_11_ANT_TRIM_0_PORT,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
#endif
#if defined(dg_configFEM_SKY66112_11_ANT_TRIM_1_PORT) && defined(dg_configFEM_SKY66112_11_ANT_TRIM_1_PIN)
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_ANT_TRIM_1_PORT, dg_configFEM_SKY66112_11_ANT_TRIM_1_PORT,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
#endif
#if defined(dg_configFEM_SKY66112_11_ANT_TRIM_2_PORT) && defined(dg_configFEM_SKY66112_11_ANT_TRIM_2_PIN)
hw_gpio_configure_pin(dg_configFEM_SKY66112_11_ANT_TRIM_2_PORT, dg_configFEM_SKY66112_11_ANT_TRIM_2_PORT,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false);
#endif
GLOBAL_INT_RESTORE();
}
#endif /* dg_configFEM == FEM_SKY66112_11 */
+7 -6
View File
@@ -38,6 +38,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -48,15 +49,15 @@
#include <hw_gpio.h>
/* Register adresses */
#define PX_DATA_REG_ADDR(_port) ((uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_DATA_REG)) + _port)
#define PX_DATA_REG_ADDR(_port) ((volatile uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_DATA_REG)) + _port)
#define PX_DATA_REG(_port) *PX_DATA_REG_ADDR(_port)
#define PX_SET_DATA_REG_ADDR(_port) ((uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_SET_DATA_REG)) + _port)
#define PX_SET_DATA_REG_ADDR(_port) ((volatile uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_SET_DATA_REG)) + _port)
#define PX_SET_DATA_REG(_port) *PX_SET_DATA_REG_ADDR(_port)
#define PX_RESET_DATA_REG_ADDR(_port) ((uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_RESET_DATA_REG)) + _port)
#define PX_RESET_DATA_REG_ADDR(_port) ((volatile uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_RESET_DATA_REG)) + _port)
#define PX_RESET_DATA_REG(_port) *PX_RESET_DATA_REG_ADDR(_port)
#define PXX_MODE_REG_ADDR(_port, _pin) ((uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P00_MODE_REG)) + (_port * 8) + _pin)
#define PXX_MODE_REG_ADDR(_port, _pin) ((volatile uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P00_MODE_REG)) + (_port * 8) + _pin)
#define PXX_MODE_REG(_port, _pin) *PXX_MODE_REG_ADDR(_port, _pin)
#define PX_PADPWR_CTRL_REG_ADDR(_port) ((uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_PADPWR_CTRL_REG)) + _port)
#define PX_PADPWR_CTRL_REG_ADDR(_port) ((volatile uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_PADPWR_CTRL_REG)) + _port)
#define PX_PADPWR_CTRL_REG(_port) *PX_PADPWR_CTRL_REG_ADDR(_port)
/* on FPGA we cannot read the state of an output GPIO */
@@ -87,7 +88,7 @@ void hw_gpio_configure(const gpio_config cfg[])
{
#if dg_configIMAGE_SETUP == DEVELOPMENT_MODE
int num_pins = 0;
uint8_t set_mask[HW_GPIO_NUM_PORTS]; // = { };
uint8_t set_mask[HW_GPIO_NUM_PORTS];
#endif
if (!cfg)
@@ -38,11 +38,12 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
#include <stdint.h>
#include <stdio.h>
#include "black_orca.h"
#include "sdk_defs.h"
#include "hw_hard_fault.h"
#include "hw_watchdog.h"
#include "hw_cpm.h"
@@ -125,15 +126,15 @@ void HardFault_HandlerC(unsigned long *hardfault_args)
if (VERBOSE_HARDFAULT)
{
printf("HardFault Handler:\n\r");
printf("- R0 = 0x%08lx\n\r", hardfault_args[0]);
printf("- R1 = 0x%08lx\n\r", hardfault_args[1]);
printf("- R2 = 0x%08lx\n\r", hardfault_args[2]);
printf("- R3 = 0x%08lx\n\r", hardfault_args[3]);
printf("- R12 = 0x%08lx\n\r", hardfault_args[4]);
printf("- LR = 0x%08lx\n\r", hardfault_args[5]);
printf("- PC = 0x%08lx\n\r", hardfault_args[6]);
printf("- xPSR= 0x%08lx\n\r", hardfault_args[7]);
printf("HardFault Handler:\r\n");
printf("- R0 = 0x%08lx\r\n", hardfault_args[0]);
printf("- R1 = 0x%08lx\r\n", hardfault_args[1]);
printf("- R2 = 0x%08lx\r\n", hardfault_args[2]);
printf("- R3 = 0x%08lx\r\n", hardfault_args[3]);
printf("- R12 = 0x%08lx\r\n", hardfault_args[4]);
printf("- LR = 0x%08lx\r\n", hardfault_args[5]);
printf("- PC = 0x%08lx\r\n", hardfault_args[6]);
printf("- xPSR= 0x%08lx\r\n", hardfault_args[7]);
}
hw_cpm_assert_trigger_gpio();
+23 -4
View File
@@ -38,6 +38,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -247,7 +248,7 @@ __STATIC_INLINE bool have_prog_error(void)
* Function definitions
*/
HW_OTPC_SYS_CLK_FREQ hw_otpc_convert_sys_clk_mhz(uint32_t clk_freq)
__RETAINED_CODE HW_OTPC_SYS_CLK_FREQ hw_otpc_convert_sys_clk_mhz(uint32_t clk_freq)
{
HW_OTPC_SYS_CLK_FREQ f;
@@ -376,7 +377,7 @@ void hw_otpc_disable(void)
}
void hw_otpc_set_speed(HW_OTPC_SYS_CLK_FREQ clk_speed)
__RETAINED_CODE void hw_otpc_set_speed(HW_OTPC_SYS_CLK_FREQ clk_speed)
{
ASSERT_WARNING_OTP_CLK_ENABLED;
@@ -757,10 +758,19 @@ bool hw_otpc_dma_prog(const uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD
(IS_REMAPPED_ADDRESS(p_data) && (remap_type == 0x3)))
{
OTPC->OTPC_AHBADR_REG = black_orca_phy_addr((uint32_t)p_data);
#if dg_configEXEC_MODE != MODE_IS_CACHED
}
else if (IS_CACHERAM_ADDRESS(p_data))
{
OTPC->OTPC_AHBADR_REG = black_orca_phy_addr((uint32_t)p_data);
#endif
}
else
{
/* Only RAM addresses are accepted */
/*
* Destination address can only reside in RAM or Cache RAM, but in case of remapped
* address, REMAP_ADR0 cannot be 0x6 (Cache Data RAM)
*/
ASSERT_WARNING(0);
}
@@ -822,10 +832,19 @@ void hw_otpc_dma_read(uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD cell_
(IS_REMAPPED_ADDRESS(p_data) && (remap_type == 0x3)))
{
OTPC->OTPC_AHBADR_REG = black_orca_phy_addr((uint32_t)p_data);
#if dg_configEXEC_MODE != MODE_IS_CACHED
}
else if (IS_CACHERAM_ADDRESS(p_data))
{
OTPC->OTPC_AHBADR_REG = black_orca_phy_addr((uint32_t)p_data);
#endif
}
else
{
/* Only RAM addresses are accepted */
/*
* Destination address can only reside in RAM or Cache RAM, but in case of remapped
* address, REMAP_ADR0 cannot be 0x6 (Cache Data RAM)
*/
ASSERT_WARNING(0);
}
+4 -138
View File
@@ -38,33 +38,16 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
#if dg_configUSE_HW_QSPI
#include <stdint.h>
#include <hw_qspi.h>
#include "hw_qspi.h"
#define BITS16(base, reg, field, v) \
((uint16) (((uint16) (v) << (base ## _ ## reg ## _ ## field ## _Pos)) & \
(base ## _ ## reg ## _ ## field ## _Msk)))
#define BITS32(base, reg, field, v) \
((uint32) (((uint32) (v) << (base ## _ ## reg ## _ ## field ## _Pos)) & \
(base ## _ ## reg ## _ ## field ## _Msk)))
#define GETBITS16(base, reg, v, field) \
((uint16) (((uint16) (v)) & (base ## _ ## reg ## _ ## field ## _Msk)) >> \
(base ## _ ## reg ## _ ## field ## _Pos))
#define GETBITS32(base, reg, v, field) \
((uint32) (((uint32) (v)) & (base ## _ ## reg ## _ ## field ## _Msk)) >> \
(base ## _ ## reg ## _ ## field ## _Pos))
static const uint8_t dummy_num[] = { 0, 1, 2, 0, 3 };
__RETAINED_RW uint8_t dummy_num[] = { 0, 1, 2, 0, 3 };
#if (dg_configFLASH_POWER_DOWN == 1)
__attribute__((section("text_retained")))
@@ -89,10 +72,7 @@ void hw_qspi_set_bus_mode(HW_QSPI_BUS_MODE mode)
}
}
#if (dg_configFLASH_POWER_DOWN == 1)
__attribute__((section("text_retained")))
#endif
void hw_qspi_set_automode(bool automode)
__attribute__((section("text_retained"))) void hw_qspi_set_automode(bool automode)
{
if (automode)
{
@@ -125,25 +105,6 @@ void hw_qspi_set_automode(bool automode)
HW_QSPIC_REG_SETF(CTRLMODE, AUTO_MD, automode);
}
void hw_qspi_set_read_instruction(uint8_t inst, uint8_t send_once, uint8_t dummy_count,
HW_QSPI_BUS_MODE inst_phase,
HW_QSPI_BUS_MODE addr_phase,
HW_QSPI_BUS_MODE dummy_phase,
HW_QSPI_BUS_MODE data_phase)
{
QSPIC->QSPIC_BURSTCMDA_REG =
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_INST, inst) |
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_INST_TX_MD, inst_phase) |
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_ADR_TX_MD, addr_phase) |
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_DMY_TX_MD, dummy_phase);
QSPIC->QSPIC_BURSTCMDB_REG =
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_DAT_RX_MD, data_phase) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_INST_MD, send_once) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_DMY_FORCE, (dummy_count == 3 ? 1 : 0)) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_DMY_NUM, dummy_num[dummy_count]);
}
void hw_qspi_set_wrapping_burst_instruction(uint8_t inst, HW_QSPI_WRAP_LEN len,
HW_QSPI_WRAP_SIZE size)
{
@@ -157,23 +118,6 @@ void hw_qspi_set_wrapping_burst_instruction(uint8_t inst, HW_QSPI_WRAP_LEN len,
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_WRAP_MD, 1);
}
void hw_qspi_set_extra_byte(uint8_t extra_byte, HW_QSPI_BUS_MODE bus_mode, uint8_t half_disable_out)
{
QSPIC->QSPIC_BURSTCMDA_REG =
(QSPIC->QSPIC_BURSTCMDA_REG &
~(REG_MSK(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_EXT_BYTE) |
REG_MSK(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_EXT_TX_MD))) |
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_EXT_BYTE, extra_byte) |
BITS32(QSPIC, QSPIC_BURSTCMDA_REG, QSPIC_EXT_TX_MD, bus_mode);
QSPIC->QSPIC_BURSTCMDB_REG =
(QSPIC->QSPIC_BURSTCMDB_REG &
~(REG_MSK(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_EXT_BYTE_EN) |
REG_MSK(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_EXT_HF_DS))) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_EXT_BYTE_EN, 1) |
BITS32(QSPIC, QSPIC_BURSTCMDB_REG, QSPIC_EXT_HF_DS, half_disable_out ? 1 : 0);
}
void hw_qspi_set_dummy_bytes_count(uint8_t count)
{
if (count == 3)
@@ -191,68 +135,6 @@ void hw_qspi_set_dummy_bytes_count(uint8_t count)
}
}
void hw_qspi_set_read_status_instruction(uint8_t inst, HW_QSPI_BUS_MODE inst_phase,
HW_QSPI_BUS_MODE receive_phase,
uint8_t busy_pos,
uint8_t busy_val,
uint8_t reset_delay,
uint8_t sts_delay)
{
QSPIC->QSPIC_STATUSCMD_REG =
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_BUSY_VAL, busy_val) |
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_BUSY_POS , busy_pos) |
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_RSTAT_RX_MD, receive_phase) |
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_RSTAT_TX_MD, inst_phase) |
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_RSTAT_INST, inst) |
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_STSDLY_SEL, sts_delay) |
BITS32(QSPIC, QSPIC_STATUSCMD_REG, QSPIC_RESSTS_DLY, reset_delay);
}
void hw_qspi_set_erase_instruction(uint8_t inst, HW_QSPI_BUS_MODE inst_phase,
HW_QSPI_BUS_MODE addr_phase, uint8_t hclk_cycles,
uint8_t cs_hi_cycles)
{
HW_QSPIC_REG_SETF(ERASECMDA, ERS_INST, inst);
QSPIC->QSPIC_ERASECMDB_REG =
(QSPIC->QSPIC_ERASECMDB_REG &
~(REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERS_TX_MD) |
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_EAD_TX_MD) |
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERSRES_HLD) |
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERS_CS_HI))) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERS_TX_MD, inst_phase) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_EAD_TX_MD, addr_phase) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERSRES_HLD, hclk_cycles) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_ERS_CS_HI, cs_hi_cycles);
}
void hw_qspi_set_write_enable_instruction(uint8_t write_enable, HW_QSPI_BUS_MODE inst_phase)
{
HW_QSPIC_REG_SETF(ERASECMDA, WEN_INST, write_enable);
HW_QSPIC_REG_SETF(ERASECMDB, WEN_TX_MD, inst_phase);
}
void hw_qspi_set_suspend_resume_instructions(uint8_t erase_suspend_inst,
HW_QSPI_BUS_MODE suspend_inst_phase,
uint8_t erase_resume_inst,
HW_QSPI_BUS_MODE resume_inst_phase,
uint8_t minimum_delay)
{
QSPIC->QSPIC_ERASECMDA_REG =
(QSPIC->QSPIC_ERASECMDA_REG &
~(REG_MSK(QSPIC, QSPIC_ERASECMDA_REG, QSPIC_SUS_INST) |
REG_MSK(QSPIC, QSPIC_ERASECMDA_REG, QSPIC_RES_INST))) |
BITS32(QSPIC, QSPIC_ERASECMDA_REG, QSPIC_SUS_INST, erase_suspend_inst) |
BITS32(QSPIC, QSPIC_ERASECMDA_REG, QSPIC_RES_INST, erase_resume_inst);
QSPIC->QSPIC_ERASECMDB_REG =
(QSPIC->QSPIC_ERASECMDB_REG &
~(REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_SUS_TX_MD) |
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_RES_TX_MD) |
REG_MSK(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_RESSUS_DLY))) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_SUS_TX_MD, suspend_inst_phase) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_RES_TX_MD, resume_inst_phase) |
BITS32(QSPIC, QSPIC_ERASECMDB_REG, QSPIC_RESSUS_DLY, minimum_delay);
}
void hw_qspi_erase_block(uint32_t addr)
{
if (!hw_qspi_get_automode())
@@ -280,17 +162,6 @@ void hw_qspi_erase_block(uint32_t addr)
HW_QSPIC_REG_SETF(ERASECTRL, ERASE_EN, 1);
}
void hw_qspi_set_break_sequence(uint16_t sequence, HW_QSPI_BUS_MODE mode,
HW_QSPI_BREAK_SEQ_SIZE size, uint8_t dis_out)
{
QSPIC->QSPIC_BURSTBRK_REG =
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_SEC_HF_DS, dis_out) |
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_BRK_SZ, size) |
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_BRK_TX_MD, mode) |
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_BRK_EN, 1) |
BITS32(QSPIC, QSPIC_BURSTBRK_REG, QSPIC_BRK_WRD, sequence);
}
void hw_qspi_set_pads(HW_QSPI_SLEW_RATE rate, HW_QSPI_DRIVE_CURRENT current)
{
QSPIC->QSPIC_GP_REG =
@@ -316,11 +187,6 @@ void hw_qspi_init(const qspi_config *cfg)
}
}
__RETAINED_CODE void hw_qspi_set_div(HW_QSPI_DIV div)
{
REG_SETF(CRG_TOP, CLK_AMBA_REG, QSPI_DIV, div);
}
#endif /* dg_configUSE_HW_QSPI */
/**
* \}
File diff suppressed because it is too large Load Diff
@@ -38,6 +38,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -45,7 +46,7 @@
#include <stdio.h>
#include <black_orca.h>
#include <sdk_defs.h>
#include <hw_timer0.h>
#if (dg_configSYSTEMVIEW)
+25 -18
View File
@@ -29,6 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -44,31 +45,26 @@
#endif
#define HW_TRNG_FIFO_DEPTH (32)
#define HW_TRNG_RAM (0x40040000)
static hw_trng_cb trng_cb;
static void hw_disable_trng(void)
{
REG_CLR_BIT(TRNG, TRNG_CTRL_REG, TRNG_ENABLE);
}
static void hw_disable_trng_clk(void)
void hw_trng_disable_clk(void)
{
GLOBAL_INT_DISABLE();
REG_CLR_BIT(CRG_TOP, CLK_AMBA_REG, TRNG_CLK_ENABLE);
GLOBAL_INT_RESTORE();
}
static void hw_trng_clear_pending(void)
void hw_trng_clear_pending(void)
{
// read TRNG_FIFOLVL_REG to clear level-sensitive source.
TRNG->TRNG_FIFOLVL_REG;
uint32_t dummy __attribute__((unused));
/* read TRNG_FIFOLVL_REG to clear level-sensitive source. */
dummy = TRNG->TRNG_FIFOLVL_REG;
NVIC_ClearPendingIRQ(TRNG_IRQn);
}
void hw_trng_enable(hw_trng_cb callback)
{
hw_trng_disable();
if (callback != NULL)
{
trng_cb = callback;
@@ -76,7 +72,9 @@ void hw_trng_enable(hw_trng_cb callback)
NVIC_EnableIRQ(TRNG_IRQn);
}
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, CLK_AMBA_REG, TRNG_CLK_ENABLE);
GLOBAL_INT_RESTORE();
REG_SET_BIT(TRNG, TRNG_CTRL_REG, TRNG_ENABLE);
}
@@ -89,26 +87,34 @@ void hw_trng_get_numbers(uint32_t *buffer, uint8_t size)
for (int i = 0; i < size ; i++)
{
buffer[i] = *((volatile uint32_t *)HW_TRNG_RAM);
buffer[i] = hw_trng_get_number();
}
}
uint8_t hw_trng_get_fifo_level(void)
__RETAINED_CODE uint8_t hw_trng_get_fifo_level(void)
{
return (TRNG->TRNG_FIFOLVL_REG) & (REG_MSK(TRNG, TRNG_FIFOLVL_REG, TRNG_FIFOLVL) |
REG_MSK(TRNG, TRNG_FIFOLVL_REG, TRNG_FIFOFULL));
}
void hw_trng_disable_interrupt(void)
{
NVIC_DisableIRQ(TRNG_IRQn);
trng_cb = NULL;
}
void hw_trng_disable(void)
{
hw_disable_trng();
NVIC_DisableIRQ(TRNG_IRQn);
hw_trng_stop();
hw_trng_disable_interrupt();
hw_trng_clear_pending();
hw_disable_trng_clk();
hw_trng_disable_clk();
}
void TRNG_Handler(void)
{
uint32_t dummy __attribute__((unused));
SEGGER_SYSTEMVIEW_ISR_ENTER();
if (trng_cb != NULL)
@@ -116,7 +122,8 @@ void TRNG_Handler(void)
trng_cb();
}
hw_trng_clear_pending();
/* read TRNG_FIFOLVL_REG to clear level-sensitive source. */
dummy = TRNG->TRNG_FIFOLVL_REG;
SEGGER_SYSTEMVIEW_ISR_EXIT();
}
+398 -84
View File
@@ -38,6 +38,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -45,7 +46,7 @@
#include <stdint.h>
#include <global_io.h>
#include <string.h>
#include <core_cm0.h>
#include <hw_uart.h>
@@ -56,6 +57,56 @@
# define SEGGER_SYSTEMVIEW_ISR_EXIT()
#endif
#if (dg_configUART1_SOFTWARE_FIFO_SIZE && dg_configUART_SOFTWARE_FIFO)
#if dg_configUART_RX_CIRCULAR_DMA && (dg_configUART1_RX_CIRCULAR_DMA_BUF_SIZE > 0)
#error UART1 can not be configured to use software FIFO and circular DMA FIFO at the same time
#endif
__RETAINED static uint8_t uart1_sw_fifo[dg_configUART1_SOFTWARE_FIFO_SIZE];
#else
#define uart1_sw_fifo (NULL)
#endif
#if (dg_configUART2_SOFTWARE_FIFO_SIZE && dg_configUART_SOFTWARE_FIFO)
#if dg_configUART_RX_CIRCULAR_DMA && (dg_configUART2_RX_CIRCULAR_DMA_BUF_SIZE > 0)
#error UART2 can not be configured to use software FIFO and circular DMA FIFO at the same time
#endif
__RETAINED static uint8_t uart2_sw_fifo[dg_configUART2_SOFTWARE_FIFO_SIZE];
#else
#define uart2_sw_fifo (NULL)
#endif
#if dg_configUART1_SOFTWARE_FIFO_SIZE > 255 || dg_configUART2_SOFTWARE_FIFO_SIZE > 255
typedef uint16_t fifo_size_t;
#else
typedef uint8_t fifo_size_t;
#endif
#if dg_configUART1_SOFTWARE_FIFO_SIZE > 256 || dg_configUART2_SOFTWARE_FIFO_SIZE > 256
typedef uint16_t fifo_ptr_t;
#else
typedef uint8_t fifo_ptr_t;
#endif
#if dg_configUART_RX_CIRCULAR_DMA
#if !HW_UART_USE_DMA_SUPPORT
# error "dg_configUART_RX_CIRCULAR_DMA requires HW_UART_USE_DMA_SUPPORT to be enabled!"
#endif
#if dg_configUART1_RX_CIRCULAR_DMA_BUF_SIZE > 0
__RETAINED static uint8_t uart1_rx_dma_buf[dg_configUART1_RX_CIRCULAR_DMA_BUF_SIZE];
#else
#define uart1_rx_dma_buf (NULL)
#endif
#if dg_configUART2_RX_CIRCULAR_DMA_BUF_SIZE > 0
__RETAINED static uint8_t uart2_rx_dma_buf[dg_configUART2_RX_CIRCULAR_DMA_BUF_SIZE];
#else
#define uart2_rx_dma_buf (NULL)
#endif
#endif /* dg_configUART_RX_CIRCULAR_DMA */
typedef struct
{
#ifdef HW_UART_ENABLE_USER_ISR
@@ -79,18 +130,24 @@ typedef struct
uint8_t rx_fifo_level: 2;
#if dg_configUART_SOFTWARE_FIFO
uint8_t *rx_soft_fifo;
uint8_t rx_soft_fifo_size;
uint8_t rx_soft_fifo_rd_ptr;
uint8_t rx_soft_fifo_wr_ptr;
fifo_size_t rx_soft_fifo_size;
fifo_ptr_t rx_soft_fifo_rd_ptr;
fifo_ptr_t rx_soft_fifo_wr_ptr;
#endif
#if HW_UART_USE_DMA_SUPPORT
uint8_t use_dma: 1;
DMA_setup tx_dma;
DMA_setup rx_dma;
#endif
#if dg_configUART_RX_CIRCULAR_DMA
bool rx_dma_active;
uint8_t *rx_dma_buf;
uint16_t rx_dma_buf_size;
uint16_t rx_dma_head;
#endif /* dg_configUART_RX_CIRCULAR_DMA */
#endif /* HW_UART_USE_DMA_SUPPORT */
} UART_Data;
static UART_Data uart_data[2];
__RETAINED_RW static UART_Data uart_data[2];
#define UART_INT(id) ((id) == HW_UART1 ? (UART_IRQn) : (UART2_IRQn))
#define UARTIX(id) ((id) == HW_UART1 ? 0 : 1)
@@ -189,44 +246,124 @@ static inline void hw_uart_enable_rx_int(HW_UART_ID uart, bool enable)
#define SOFTWARE_FIFO_PRESENT(ud) ((ud)->rx_soft_fifo != NULL)
/*
* Copy bytes from software FIFO to user provided buffer.
* This function allows software FIFO interrupts to read more data while copy takes place.
*
* Function returns true if all requested data is already in user buffer.
*/
static bool hw_uart_drain_rx(HW_UART_ID uart, UART_Data *ud, int len)
{
/*
* This function is called with RX interrupt disabled.
*
* Get current software FIFO pointers before enabling interrupt again.
* ud->rx_len is still set to 0, so interrupt will not try to copy data to
* application buffer till all data from software FIFO is drained to user buffer.
*/
fifo_ptr_t rd_ptr = ud->rx_soft_fifo_rd_ptr;
fifo_ptr_t wr_ptr = ud->rx_soft_fifo_wr_ptr;
int idx = 0;
/*
* ud->rx_ix is 0, set ud->rx_len to 0 to prevent interrupt from using it
* before all data from software FIFO is moved to application buffer.
*/
ud->rx_len = 0;
hw_uart_enable_rx_int(uart, true);
while (idx < len)
{
if (wr_ptr == rd_ptr)
{
/*
* No more data in software FIFO, at least from state before
* interrupt was enabled.
* Disable interrupt and update read pointer to reflect position
* of already copied data.
*/
hw_uart_enable_rx_int(uart, false);
ud->rx_soft_fifo_rd_ptr = rd_ptr;
/*
* Check if write pointer moved, if so interrupt put some more data
* in buffer. Remember current write position and try again with
* interrupts enabled.
*/
if (ud->rx_soft_fifo_wr_ptr != wr_ptr)
{
wr_ptr = ud->rx_soft_fifo_wr_ptr;
hw_uart_enable_rx_int(uart, true);
continue;
}
/*
* All was copied from software FIFO.
* Setup user transaction ix and len so when interrupts are enabled
* again (not in this function) interrupt or DMA can continue.
*/
ud->rx_ix = idx;
ud->rx_len = len;
return false;
}
/* Copy from software FIFO to user provided buffer */
ud->rx_buffer[idx++] = ud->rx_soft_fifo[rd_ptr++];
if (rd_ptr >= ud->rx_soft_fifo_size)
{
rd_ptr = 0;
}
}
/*
* User buffer is filled, block interrupt so end of transmission callback will not be
* called from interrupt.
*/
hw_uart_enable_rx_int(uart, false);
ud->rx_soft_fifo_rd_ptr = rd_ptr;
ud->rx_len = len;
ud->rx_ix = len;
return true;
}
void hw_uart_read_buffer(HW_UART_ID uart, void *data, uint16_t len)
{
UART_Data *ud = UARTDATA(uart);
uint8_t *p = data;
/*
* Disable RX interrupt before draining software FIFO.
*/
hw_uart_enable_rx_int(uart, false);
if (SOFTWARE_FIFO_PRESENT(ud))
{
/*
* Drain uses ud fields so setup them accordingly.
*/
ud->rx_buffer = data;
hw_uart_drain_rx(uart, ud, len);
len -= ud->rx_ix;
p += ud->rx_ix;
}
/*
* Read all remaining bytes with RX interrupt still disabled.
*/
while (len > 0)
{
uint8_t rd_ptr = ud->rx_soft_fifo_rd_ptr;
/*
* rd_ptr != rx_soft_fifo_wr_ptr --> data is in software FIFO
* rd_ptr == rx_soft_fifo_wr_ptr --> nothing in software FIFO, or software FIFO
* is not in use
*/
if (rd_ptr != ud->rx_soft_fifo_wr_ptr)
{
*p++ = ud->rx_soft_fifo[rd_ptr++];
if (rd_ptr >= ud->rx_soft_fifo_size)
{
ud->rx_soft_fifo_rd_ptr = 0;
}
else
{
ud->rx_soft_fifo_rd_ptr = rd_ptr;
}
}
else
{
/* Software FIFO drained or no software FIFO, just read from hardware */
*p++ = hw_uart_read(uart);
}
*p++ = hw_uart_read(uart);
len--;
}
ud->rx_ix = 0;
ud->rx_len = 0;
hw_uart_enable_rx_int(uart, SOFTWARE_FIFO_PRESENT(ud));
}
@@ -244,32 +381,6 @@ void hw_uart_set_soft_fifo(HW_UART_ID uart, uint8_t *buf, uint8_t size)
hw_uart_enable_rx_int(uart, buf != NULL);
}
static bool hw_uart_drain_rx(UART_Data *ud)
{
while (ud->rx_ix < ud->rx_len)
{
uint8_t rd_ptr = ud->rx_soft_fifo_rd_ptr;
if (rd_ptr == ud->rx_soft_fifo_wr_ptr)
{
return false;
}
ud->rx_buffer[ud->rx_ix++] = ud->rx_soft_fifo[rd_ptr++];
if (rd_ptr >= ud->rx_soft_fifo_size)
{
ud->rx_soft_fifo_rd_ptr = 0;
}
else
{
ud->rx_soft_fifo_rd_ptr = rd_ptr;
}
}
return true;
}
#else
#define SOFTWARE_FIFO_PRESENT(ud) false
@@ -295,7 +406,7 @@ static void hw_uart_fire_callback(UART_Data *ud)
if (cb)
{
cb(ud->rx_user_data, ud->rx_ix);
cb(ud->rx_user_data, ud->rx_len);
}
}
@@ -320,7 +431,7 @@ void hw_uart_receive(HW_UART_ID uart, void *data, uint16_t len, hw_uart_rx_callb
ud->rx_cb = cb;
#if dg_configUART_SOFTWARE_FIFO
if (hw_uart_drain_rx(ud))
if (hw_uart_drain_rx(uart, ud, len))
{
hw_uart_fire_callback(ud);
return;
@@ -328,6 +439,61 @@ void hw_uart_receive(HW_UART_ID uart, void *data, uint16_t len, hw_uart_rx_callb
#endif
#if dg_configUART_RX_CIRCULAR_DMA
if (ud->rx_dma_buf_size > 0)
{
ASSERT_ERROR(len < ud->rx_dma_buf_size);
uint16_t new_int, cur_idx;
bool data_ready = false;
ASSERT_ERROR(ud->rx_dma_active == false);
/* Calculate index of end of requested data (do not wrap it!) */
new_int = ud->rx_dma_head + ud->rx_len - 1;
/* Freeze DMA so it does not move pointers while we try to update them */
hw_dma_freeze();
cur_idx = hw_dma_transfered_bytes(ud->rx_dma.channel_number);
/* cur_idx is lower than rx_head only if it wrapped-around - fix it */
if (cur_idx < ud->rx_dma_head)
{
cur_idx += ud->rx_dma_buf_size;
}
/*
* If DMA has not read past the calculated index, we can set it and just wait for an
* interrupt. In other case, data are ready immediately in buffer.
*/
if (cur_idx <= new_int)
{
new_int %= ud->rx_dma_buf_size;
hw_dma_channel_update_int_ix(ud->rx_dma.channel_number, new_int);
ud->rx_dma_active = true;
}
else
{
hw_dma_channel_update_int_ix(ud->rx_dma.channel_number, cur_idx - 1);
data_ready = true;
}
/* Unfreeze DMA now, it can start reading */
hw_dma_unfreeze();
/* Fire callback immediately if data already available in buffer */
if (data_ready)
{
hw_uart_fire_callback(ud);
}
return;
}
#endif
#if HW_UART_USE_DMA_SUPPORT
if (ud->rx_dma.channel_number != HW_DMA_CHANNEL_INVALID && (ud->rx_len - ud->rx_ix > 1))
@@ -354,10 +520,67 @@ static void hw_uart_irq_stop_receive(HW_UART_ID uart)
// Disable RX interrupt
hw_uart_enable_rx_int(uart, false);
ud->rx_len = ud->rx_ix;
hw_uart_fire_callback(ud);
}
void hw_uart_abort_receive(HW_UART_ID uart)
#if dg_configUART_RX_CIRCULAR_DMA
static void hw_uart_copy_dma_rx_to_user_buffer(HW_UART_ID uart)
{
UART_Data *ud = &uart_data[UARTIX(uart)];
uint16_t cur_idx;
uint16_t to_copy;
hw_uart_rx_callback cb;
ud->rx_dma_active = false;
cb = ud->rx_cb;
if (cb)
{
ud->rx_cb = NULL;
/*
* User callback was not fired, since rx_dma_active is false it will not
* fire even if requested number of bytes was received when abort was initiated.
*/
cur_idx = hw_dma_transfered_bytes(ud->rx_dma.channel_number);
if (ud->rx_ix < ud->rx_len)
{
if (cur_idx < ud->rx_dma_head)
{
cur_idx += ud->rx_dma_buf_size;
}
to_copy = cur_idx - ud->rx_dma_head;
if (to_copy >= ud->rx_len - ud->rx_ix)
{
to_copy = ud->rx_len - ud->rx_ix;
}
}
}
else
{
/*
* Callback already fired, circular buffer holds enough data.
*/
to_copy = ud->rx_len - ud->rx_ix;
}
hw_uart_copy_rx_circular_dma_buffer(uart, ud->rx_buffer + ud->rx_ix, to_copy);
ud->rx_ix += to_copy;
ud->rx_len = ud->rx_ix;
if (cb)
{
cb(ud->rx_user_data, ud->rx_len);
}
}
#endif
uint16_t hw_uart_abort_receive(HW_UART_ID uart)
{
UART_Data *ud = &uart_data[UARTIX(uart)];
@@ -365,11 +588,24 @@ void hw_uart_abort_receive(HW_UART_ID uart)
if (ud->rx_dma.channel_number != HW_DMA_CHANNEL_INVALID)
{
#if dg_configUART_RX_CIRCULAR_DMA
if (ud->rx_dma_buf_size > 0)
{
hw_uart_copy_dma_rx_to_user_buffer(uart);
return ud->rx_ix;
}
#else
/* No DMA circular buffer, stop DMA */
hw_dma_channel_stop(ud->rx_dma.channel_number);
#endif
}
else
#endif
hw_uart_irq_stop_receive(uart);
return ud->rx_ix;
}
uint16_t hw_uart_peek_received(HW_UART_ID uart)
@@ -428,35 +664,17 @@ static inline void hw_uart_tx_isr(HW_UART_ID uart)
}
}
void (*hw_uart_simple_rx_callback)(void) = NULL;
void hw_uart_register_simple_rx_callback(void (*callback)(void), HW_UART_ID uart)
{
hw_uart_simple_rx_callback = callback;
hw_uart_enable_rx_int(uart, 1);
}
static inline void hw_uart_rx_isr(HW_UART_ID uart)
{
UART_Data *ud = UARTDATA(uart);
if (hw_uart_simple_rx_callback != NULL)
{
//Simple callback defined
hw_uart_simple_rx_callback();
return;
}
if (SOFTWARE_FIFO_PRESENT(ud))
{
#if dg_configUART_SOFTWARE_FIFO
for (;;)
{
uint8_t wr_ptr = ud->rx_soft_fifo_wr_ptr + 1;
fifo_ptr_t wr_ptr = ud->rx_soft_fifo_wr_ptr + 1;
if (wr_ptr >= ud->rx_soft_fifo_size)
{
@@ -476,9 +694,23 @@ static inline void hw_uart_rx_isr(HW_UART_ID uart)
}
ud->rx_soft_fifo[ud->rx_soft_fifo_wr_ptr] = hw_uart_rxdata_getf(uart);
ud->rx_soft_fifo_wr_ptr = wr_ptr;
hw_uart_drain_rx(ud);
/*
* Application read is in progress. Copy data from software FIFO to
* user provided buffer.
*/
if (ud->rx_ix < ud->rx_len)
{
ud->rx_buffer[ud->rx_ix++] = ud->rx_soft_fifo[ud->rx_soft_fifo_wr_ptr];
/*
* When application read is in progress, rx_ix < rx_len
* This interrupt is enabled only if all data was already copied from
* FIFO to user buffer. It is safe to modify rx_soft_fifo_rd_ptr.
*/
ud->rx_soft_fifo_rd_ptr = wr_ptr;
}
ud->rx_soft_fifo_wr_ptr = wr_ptr;
}
#endif
@@ -499,11 +731,12 @@ static inline void hw_uart_rx_isr(HW_UART_ID uart)
}
// Everything read?
if (ud->rx_ix >= ud->rx_len)
if (ud->rx_len > 0 && ud->rx_ix >= ud->rx_len)
{
// Disable RX interrupts, fire callback if present
hw_uart_irq_stop_receive(uart);
}
}
static inline void hw_uart_rx_timeout_isr(HW_UART_ID uart)
@@ -677,6 +910,7 @@ uint8_t hw_uart_fifo_en_getf(HW_UART_ID uart)
default:
ASSERT_ERROR(0);
return 255; // To satisfy the compiler
}
}
@@ -703,6 +937,7 @@ static void hw_uart_rx_dma_callback(void *user_data, uint16_t len)
if (cb)
{
ud->rx_len = ud->rx_ix;
hw_uart_enable_rx_int(UARTID(ud), SOFTWARE_FIFO_PRESENT(ud));
cb(ud->rx_user_data, ud->rx_ix);
}
@@ -861,7 +1096,78 @@ void hw_uart_set_dma_channels_ex(HW_UART_ID uart, int8_t tx_channel, int8_t rx_c
ud->tx_dma.user_data = ud;
}
}
#endif
#if dg_configUART_RX_CIRCULAR_DMA
static void hw_uart_rx_circular_dma_callback(void *user_data, uint16_t len)
{
UART_Data *ud = user_data;
hw_uart_rx_callback cb = ud->rx_cb;
if (!ud->rx_dma_active)
{
return;
}
ud->rx_cb = NULL;
ud->rx_dma_active = false;
if (cb)
{
cb(ud->rx_user_data, ud->rx_len);
}
}
void hw_uart_enable_rx_circular_dma(HW_UART_ID uart)
{
UART_Data *ud = UARTDATA(uart);
ASSERT_ERROR(ud->rx_dma_buf_size > 0);
hw_dma_channel_enable(ud->rx_dma.channel_number, HW_DMA_STATE_DISABLED);
/* Need to reconfigure few things for circular operation... */
ud->rx_dma.circular = HW_DMA_MODE_CIRCULAR;
ud->rx_dma.dest_address = (uint32_t) ud->rx_dma_buf;
ud->rx_dma.length = ud->rx_dma_buf_size;
ud->rx_dma.callback = hw_uart_rx_circular_dma_callback;
ud->rx_dma.user_data = ud;
/* Reset DMA buffer read pointer */
ud->rx_dma_head = 0;
/* Start DMA now since it should be always-running */
hw_uart_clear_dma_request(uart);
hw_dma_channel_initialization(&ud->rx_dma);
hw_dma_channel_enable(ud->rx_dma.channel_number, HW_DMA_STATE_ENABLED);
}
void hw_uart_copy_rx_circular_dma_buffer(HW_UART_ID uart, uint8_t *buf, uint16_t len)
{
UART_Data *ud = UARTDATA(uart);
ASSERT_ERROR(len < ud->rx_dma_buf_size);
if (ud->rx_dma_head + len <= ud->rx_dma_buf_size)
{
memcpy(buf, &ud->rx_dma_buf[ud->rx_dma_head], len);
}
else
{
uint16_t chunk_len = ud->rx_dma_buf_size - ud->rx_dma_head;
memcpy(buf, &ud->rx_dma_buf[ud->rx_dma_head], chunk_len);
memcpy(buf + chunk_len, &ud->rx_dma_buf[0], len - chunk_len);
}
/* This should be protected so ISR does not try to read rx_dma_head while we update it */
GLOBAL_INT_DISABLE();
ud->rx_dma_head = (ud->rx_dma_head + len) % ud->rx_dma_buf_size;
GLOBAL_INT_RESTORE();
}
#endif /* dg_configUART_RX_CIRCULAR_DMA */
#endif /* HW_UART_USE_DMA_SUPPORT */
//=========================== Line control functions ============================
void hw_uart_init_ex(HW_UART_ID uart, const uart_config_ex *uart_init)
@@ -901,7 +1207,9 @@ void hw_uart_init_ex(HW_UART_ID uart, const uart_config_ex *uart_init)
}
}
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_PER, CLK_PER_REG, UART_ENABLE);
GLOBAL_INT_RESTORE();
// Set Divisor Latch Access Bit in LCR register to access DLL & DLH registers
HW_UART_REG_SETF(uart, LCR, UART_DLAB, 1);
@@ -943,7 +1251,9 @@ void hw_uart_reinit_ex(HW_UART_ID uart, const uart_config_ex *uart_init)
{
UART_Data *ud = UARTDATA(uart);
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_PER, CLK_PER_REG, UART_ENABLE);
GLOBAL_INT_RESTORE();
/*
* Read UART_USR_REG to clear any pending busy interrupt.
@@ -1032,7 +1342,9 @@ void hw_uart_init(HW_UART_ID uart, const uart_config *uart_init)
}
}
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_PER, CLK_PER_REG, UART_ENABLE);
GLOBAL_INT_RESTORE();
// Set Divisor Latch Access Bit in LCR register to access DLL & DLH registers
HW_UART_REG_SETF(uart, LCR, UART_DLAB, 1);
@@ -1074,7 +1386,9 @@ void hw_uart_reinit(HW_UART_ID uart, const uart_config *uart_init)
{
UART_Data *ud = UARTDATA(uart);
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_PER, CLK_PER_REG, UART_ENABLE);
GLOBAL_INT_RESTORE();
/*
* Read UART_USR_REG to clear any pending busy interrupt.
@@ -38,6 +38,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
#include <stdio.h>
@@ -131,7 +132,7 @@ __RETAINED_CODE void hw_watchdog_handle_int(unsigned long *exception_args)
if (REG_GETF(CRG_TOP, SYS_STAT_REG, DBG_IS_ACTIVE))
{
__asm("BKPT #0\n");
__BKPT(0);
}
else
{
+91 -13
View File
@@ -37,11 +37,12 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
****************************************************************************************
*/
#if dg_configUSE_HW_USB_WKUP
#if dg_configUSE_HW_WKUP
#include <stdio.h>
@@ -50,22 +51,84 @@
static hw_wkup_interrupt_cb intr_cb __RETAINED /* = NULL*/;
#if ((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A))
#define PX_DATA_REG_ADDR(_port) ((uint16_t *)(GPIO_BASE + offsetof(GPIO_Type, P0_DATA_REG)) + _port)
#define PX_DATA_REG(_port) *PX_DATA_REG_ADDR(_port)
#define BF_GET(_var, _pos) ((_var>>_pos) & 1)
__RETAINED volatile wkup_pin_config_t wkup_pin_config;
volatile uint8_t wkup_status[HW_GPIO_NUM_PORTS];
static bool hw_wkup_update_status(void)
{
uint8_t i, j, enable_loop_cnt = 0;
uint8_t pol_rx_reg;
bool wkup_status_updated = false;
uint8_t cur_port_data[HW_GPIO_NUM_PORTS];
for (i = 0; i < HW_GPIO_NUM_PORTS; i++) {
wkup_status[i] = 0;
if (wkup_pin_config.pin_state[i]) {
//read port status
cur_port_data[i] = PX_DATA_REG(i);
//read trigger polarity
pol_rx_reg = *((volatile uint16_t *)WAKEUP_BASE + 10 + i);
for (j = 0; j < 8; j++) {
if ((wkup_pin_config.pin_state[i] & (1 << j)) &&
(BF_GET(pol_rx_reg, j)
== BF_GET(~cur_port_data[i], j))) {
//invert trigger polarity
pol_rx_reg ^= (1 << j);
if (BF_GET(wkup_pin_config.pin_trigger[i], j)
== BF_GET(~cur_port_data[i], j)) {
wkup_status[i] |= (1 << j);
wkup_status_updated = true;
}
}
}
//update trigger polarity
*((volatile uint16_t *)WAKEUP_BASE + 10 + i) = pol_rx_reg;
}
}
return wkup_status_updated;
}
#endif /* dg_configLATCH_WKUP_SOURCE */
void hw_wkup_init(const wkup_config *cfg)
{
unsigned int i;
GLOBAL_INT_DISABLE();
REG_SET_BIT(CRG_TOP, CLK_TMR_REG, WAKEUPCT_ENABLE);
GLOBAL_INT_RESTORE();
/* reset configuration */
WAKEUP->WKUP_CTRL_REG = 0;
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
WAKEUP->WKUP_COMPARE_REG = 0;
#endif
/* disable all pins */
for (i = 0; i < 5; i++) {
*((volatile uint16_t *)WAKEUP_BASE + 5 + i) = 0;
*((volatile uint16_t *)WAKEUP_BASE + 10 + i) = 0;
for (i = 0; i < HW_GPIO_NUM_PORTS; i++) {
*((volatile uint16_t *)(&WAKEUP->WKUP_POL_P0_REG) + i) = 0;
*((volatile uint16_t *)(&WAKEUP->WKUP_SELECT_P0_REG) + i) = 0;
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
*((volatile uint16_t *)(&WAKEUP-> WKUP_SEL_GPIO_P0_REG) + i) = 0;
#endif
#if dg_configLATCH_WKUP_SOURCE
#if (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A)
wkup_pin_config.pin_state[i] = 0;
wkup_pin_config.pin_trigger[i] = 0;
wkup_status[i] = 0;
hw_wkup_clear_status(i, 0xFF);
#endif
#endif //dg_configLATCH_WKUP_SOURCE
}
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
WAKEUP->WKUP_CLEAR_0_REG = WAKEUP->WKUP_CLEAR_1_REG = WAKEUP->WKUP_CLEAR_2_REG = 0xFFFF;
#endif
NVIC_DisableIRQ(WKUP_GPIO_IRQn);
hw_wkup_configure(cfg);
@@ -79,9 +142,12 @@ void hw_wkup_configure(const wkup_config *cfg)
return;
}
#if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A
hw_wkup_set_counter_threshold(cfg->threshold);
#endif
#if !((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A))
hw_wkup_set_debounce_time(cfg->debounce);
#endif
for (i = 0; i < HW_GPIO_NUM_PORTS; i++) {
hw_wkup_configure_port(i, cfg->pin_state[i], cfg->pin_trigger[i]);
}
@@ -90,9 +156,9 @@ void hw_wkup_configure(const wkup_config *cfg)
void hw_wkup_register_interrupt(hw_wkup_interrupt_cb cb, uint32_t prio)
{
intr_cb = cb;
#if !((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A))
HW_WKUP_REG_SETF(CTRL, WKUP_ENABLE_IRQ, 1);
#endif
NVIC_ClearPendingIRQ(WKUP_GPIO_IRQn);
NVIC_SetPriority(WKUP_GPIO_IRQn, prio);
NVIC_EnableIRQ(WKUP_GPIO_IRQn);
@@ -101,18 +167,30 @@ void hw_wkup_register_interrupt(hw_wkup_interrupt_cb cb, uint32_t prio)
void hw_wkup_unregister_interrupt(void)
{
intr_cb = NULL;
#if !((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A))
HW_WKUP_REG_SETF(CTRL, WKUP_ENABLE_IRQ, 0);
#endif
NVIC_DisableIRQ(WKUP_GPIO_IRQn);
}
void hw_wkup_handler(void)
{
#if ((dg_configLATCH_WKUP_SOURCE) && (dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A))
if (intr_cb && hw_wkup_update_status()) {
#else
if (intr_cb) {
#endif
intr_cb();
} else {
}
else {
hw_wkup_reset_interrupt();
#if dg_configLATCH_WKUP_SOURCE
hw_wkup_clear_status(HW_GPIO_PORT_0, 0xFF);
hw_wkup_clear_status(HW_GPIO_PORT_1, 0xFF);
hw_wkup_clear_status(HW_GPIO_PORT_2, 0xFF);
hw_wkup_clear_status(HW_GPIO_PORT_3, 0xFF);
hw_wkup_clear_status(HW_GPIO_PORT_4, 0xFF);
#endif
}
}
@@ -123,7 +201,7 @@ void WKUP_GPIO_Handler(void)
}
#endif
#endif /* dg_configUSE_HW_USB_WKUP */
#endif /* dg_configUSE_HW_WKUP */
/**
* \}
* \}
+51 -18
View File
@@ -9,11 +9,11 @@
/**
****************************************************************************************
*
* @file sys_tcs.c
*
* @brief TCS HAndler
*
*
* @file sys_tcs.c
*
* @brief TCS HAndler
*
* Copyright (c) 2016, Dialog Semiconductor
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
@@ -38,11 +38,15 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
#include <stdint.h>
#include "hw_cpm.h"
#include "sys_tcs.h"
#include "hw_gpadc.h"
#include "hw_gpio.h"
#define APPEND_TCS_LENGTH (0)
@@ -51,6 +55,9 @@
#define IS_IN_AREA(addr, base, size) ((addr >= base) && (addr <= (base + size)))
#define ADC_SE_GAIN_ERROR(value) ((value) & 0x0000FFFF)
#define ADC_DIFF_GAIN_ERROR(value) (((value) & 0xFFFF0000) >> 16)
/*
* Global and / or retained variables
*/
@@ -60,10 +67,12 @@ uint8_t tcs_length __RETAINED_UNINIT;
uint8_t area_offset[tcs_system + 1] __RETAINED;
uint8_t area_size_global[tcs_system + 1] __RETAINED;
uint16_t sys_tcs_xtal16m_settling_time __RETAINED;
const uint32_t *tcs_ptr __RETAINED;
bool is_calibrated_chip __RETAINED_UNINIT; // Initial value: false
bool sys_tcs_is_calibrated_chip __RETAINED_UNINIT; // Initial value: false
/*
* Local variables
@@ -251,13 +260,13 @@ static void swap_entries(uint32_t first_pos, uint32_t second_pos)
*/
static int sys_tcs_sort_area(uint32_t area_base, uint32_t area_size, uint32_t array_ptr, uint8_t *ptr, uint8_t *size)
{
int i = array_ptr;
int sort_start;
int sort_end;
uint32_t i = array_ptr;
uint32_t sort_start;
uint32_t sort_end;
if (array_ptr == tcs_length)
{
return array_ptr; // Nothing else is left in the array
return array_ptr; // Nothing else is left in the array or tcs_length is zero
}
sort_start = array_ptr;
@@ -266,7 +275,7 @@ static int sys_tcs_sort_area(uint32_t area_base, uint32_t area_size, uint32_t ar
/* Make sure that the values in TCS don't overflow the allocated array */
ASSERT_WARNING(tcs_length <= sizeof(tcs_data) / sizeof(tcs_data[0]));
while (i < tcs_length)
while (i < (tcs_length - 1))
{
if (IS_IN_AREA(tcs_data[i], area_base, area_size))
{
@@ -302,7 +311,8 @@ static int sys_tcs_sort_area(uint32_t area_base, uint32_t area_size, uint32_t ar
void sys_tcs_init(void)
{
tcs_length = 0;
is_calibrated_chip = false;
sys_tcs_is_calibrated_chip = false;
hw_cpm_bod_enabled_in_tcs = 0;
}
bool sys_tcs_store_pair(uint32_t address, uint32_t value)
@@ -321,12 +331,35 @@ bool sys_tcs_store_pair(uint32_t address, uint32_t value)
{
if (address == (uint32_t)&CRG_TOP->BANDGAP_REG)
{
is_calibrated_chip = true;
sys_tcs_is_calibrated_chip = true;
}
if (address == (uint32_t)&CRG_TOP->CLK_16M_REG)
else if (address == (uint32_t)&CRG_TOP->CLK_16M_REG)
{
value |= 1; // Make sure that RC16 is enabled!
value |= CRG_TOP_CLK_16M_REG_RC16M_ENABLE_Msk; // Make sure that RC16 is enabled!
}
else if (address == (uint32_t)&CRG_TOP->XTALRDY_CTRL_REG)
{
sys_tcs_xtal16m_settling_time = value;
}
else if (address == (uint32_t)&CRG_TOP->BOD_CTRL2_REG)
{
hw_cpm_bod_enabled_in_tcs = value;
/*
* Read the ADC Gain Error. Given that the Chip Configuration Section
* (CCS) of OTP is out of space, the values are stored in the TCS section
* using as address the read-only register SYS_STAT_REG.
* The 16 LSB of the 32bit data-value is the single ended gain error.
* The 16 MSB of the 32bit data-value is the differential gain error.
* Both gain error values should be interpreted as signed 16bit integers.
*/
}
else if (dg_configUSE_ADC_GAIN_ERROR_CORRECTION == 1)
{
if (address == (uint32_t)&CRG_TOP->SYS_STAT_REG)
{
hw_gpadc_store_se_gain_error(ADC_SE_GAIN_ERROR(value));
hw_gpadc_store_diff_gain_error(ADC_DIFF_GAIN_ERROR(value));
}
}
apply_pair(address, value);
@@ -336,7 +369,7 @@ bool sys_tcs_store_pair(uint32_t address, uint32_t value)
store_in_array(address, value);
}
return is_calibrated_chip;
return sys_tcs_is_calibrated_chip;
}
void sys_tcs_sort_array(void)
@@ -354,7 +387,7 @@ void sys_tcs_sort_array(void)
CRG_TOP->CLK_FREQ_TRIM_REG = 0x0460;
}
if (is_calibrated_chip)
if (sys_tcs_is_calibrated_chip)
{
#ifdef CONFIG_USE_BLE
entry_ptr = sys_tcs_sort_area(BLE_BASE, sizeof(BLE_Type), entry_ptr,
+1 -2
View File
@@ -1,8 +1,6 @@
/**
\addtogroup INTERFACES
\{
\addtogroup RADIO
\{
\addtogroup FTDF
\{
*/
@@ -37,6 +35,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
+2 -3
View File
@@ -1,8 +1,6 @@
/**
\addtogroup INTERFACES
\{
\addtogroup RADIO
\{
\addtogroup FTDF
\{
*/
@@ -36,7 +34,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
****************************************************************************************
*/
+334 -5
View File
@@ -1,10 +1,9 @@
/**
\addtogroup INTERFACES
\{
\addtogroup RADIO
\{
\addtogroup FTDF
\{
\brief IEEE 802.15.4 Wireless
*/
/**
****************************************************************************************
@@ -36,7 +35,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
****************************************************************************************
*/
@@ -164,7 +164,9 @@ typedef uint8_t FTDF_MsgId;
#if FTDF_DBG_BUS_ENABLE
#define FTDF_DBG_MODE_SET_REQUEST 54
#endif /* FTDF_DBG_BUS_ENABLE */
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
#define FTDF_FPPR_MODE_SET_REQUEST 55
#endif /* dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */
/**
* \brief Request status
* \remark Valid statuses:
@@ -369,6 +371,8 @@ typedef uint64_t FTDF_PSec;
typedef uint32_t FTDF_NrLowPowerClockCycles;
typedef uint8_t FTDF_NrBackoffPeriods;
/**
* \brief Period of time
* \remark Range 0..65535
@@ -651,8 +655,23 @@ typedef uint8_t FTDF_PIBAttribute;
#define FTDF_PIB_TSCH_CAPABLE 103
#define FTDF_PIB_TS_SYNC_CORRECT_THRESHOLD 104
/* Proprietary PIB. */
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
#define FTDF_PIB_BO_IRQ_THRESHOLD 105
#define FTDF_PIB_PTI_CONFIG 106
#endif /* dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */
// Total number of PIB attributes
#define FTDF_NR_OF_PIB_ATTRIBUTES 104
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
#define FTDF_NR_OF_PIB_ATTRIBUTES 106
#else /* dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */
#define FTDF_NR_OF_PIB_ATTRIBUTES 104
#endif /* dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */
/* Default values */
#ifndef FTDF_BO_IRQ_THRESHOLD
#define FTDF_BO_IRQ_THRESHOLD 0xff
#endif
#if FTDF_DBG_BUS_ENABLE
/**
@@ -1247,6 +1266,27 @@ typedef uint8_t FTDF_ChannelNumber;
*/
typedef uint8_t FTDF_PTI;
enum
{
/* PTI index for explicit Rx. */
FTDF_PTI_CONFIG_RX,
/* PTI index for Tx. */
FTDF_PTI_CONFIG_TX,
FTDF_PTI_CONFIG_RESERVED0,
FTDF_PTI_CONFIG_RESERVED1,
FTDF_PTI_CONFIG_RESERVED2,
FTDF_PTI_CONFIG_RESERVED3,
FTDF_PTI_CONFIG_RESERVED4,
FTDF_PTI_CONFIG_RESERVED5,
/* Enumeration end. */
FTDF_PTIS,
};
typedef struct
{
FTDF_PTI ptis[FTDF_PTIS];
} FTDF_PtiConfig;
/**
* \brief Channel page
* \remark Supported values: 0
@@ -1440,6 +1480,8 @@ typedef struct
FTDF_Count duplicateFrameCount;
FTDF_Count RXSuccessCount;
FTDF_Count NACKCount;
FTDF_Count RxExpiredCount;
FTDF_Count BOIrqCount;
} FTDF_PerformanceMetrics;
typedef struct
@@ -2703,6 +2745,19 @@ typedef struct
} FTDF_DbgModeSetRequest;
#endif /* FTDF_DBG_BUS_ENABLE */
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
typedef struct
{
/** \brief Message ID = FTDF_FPPR_MODE_SET_REQUEST */
FTDF_MsgId msgId;
/** \brief fp bit value to set when src address matches*/
FTDF_Bitmap8 matchFp;
/** \brief When set, fp_force_value will be applied to fp bit for all src addresses*/
FTDF_Bitmap8 fpOverride;
/** \brief The value will be set to fp bit for all src addresses when fp_override is set*/
FTDF_Bitmap8 fpForce;
} FTDF_FpprModeSetRequest;
#endif /* dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */
/**
* \brief FTDF_getReleaseInfo - gets the LMAC (FPGA) and UMAC (FTDF SW driver) release info
* \param[out] lmacRelName: LMAC release name
@@ -3062,7 +3117,13 @@ void FTDF_reset(int setDefaultPIB);
FTDF_PTI FTDF_getRxPti( void );
#if FTDF_USE_PTI
void FTDF_setRxPti( FTDF_PTI rx_pti );
#if FTDF_USE_AUTO_PTI
void FTDF_restoreRxPti(void);
#endif
#endif
#ifdef FTDF_PHY_API
FTDF_Status FTDF_sendFrameSimple( FTDF_DataLength frameLength,
FTDF_Octet* frame,
@@ -3092,6 +3153,274 @@ void FTDF_setDbgMode(FTDF_DbgMode dbgMode);
void FTDF_DBG_BUS_GPIO_CONFIG(void);
#endif /* FTDF_DBG_BUS_ENABLE */
#if dg_configUSE_FTDF_DDPHY == 1
void FTDF_ddphySet(uint16_t ccaReg);
#endif /* dg_configUSE_FTDF_DDPHY == 1 */
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
#if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO
#ifndef FTDF_LITE
/**
* \brief Controls when the FPPR address invalidation will be performed.
*
* If set to 0 (recommended), address invalidation in FPPR occurs right after the frame is passed to
* LMAC for direct transmission. If set to 1, address invalidation occurs after the associated
* confirm message is received.
*/
#define FTDF_FPPR_DEFER_INVALIDATION 0
/**
* \brief Adds a new short address to FPPR, initializing the corresponding FSM.
*
* A short address FP FSM accepts the following notifications (events):
*
* - New address (initialize) by calling @ref FTDF_fpFsmShortAddressNew()
* - Last frame pending (passed to direct sending) by calling @ref
* FTDF_fpFsmShortAddressLastFramePending()
* - Last pending frame sent by calling @ref FTDF_fpFsmClearPending()
*
* A new address may be rejected if there is no adequate space left in FPPR.
*
* \param [in] panId Destination PAN ID.
* \param [in] shortAddress Destination short address.
*
* \return \ref FTDF_TRUE on success.
*/
FTDF_Boolean FTDF_fpFsmShortAddressNew(FTDF_PANId panId, FTDF_ShortAddress shortAddress);
/**
* \brief Adds a new extended address to FPPR, initializing the corresponding FSM.
*
* An extended address FP FSM accepts the following notifications (events):
*
* - New address (initialize) by calling @ref FTDF_fpFsmExtAddressNew()
* - Last frame pending (passed to direct sending) by calling @ref
* FTDF_fpFsmExtAddressLastFramePending()
* - Last pending frame sent by calling @ref FTDF_fpFsmClearPending()
*
* A new address may be rejected if there is no adequate space left in FPPR.
*
* \param [in] panId Destination PAN ID.
* \param [in] extAddress Destination extended address.
*
* \return \ref FTDF_TRUE on success.
*/
FTDF_Boolean FTDF_fpFsmExtAddressNew(FTDF_PANId panId, FTDF_ExtAddress extAddress);
/**
* \brief Notifies FP FSM that the last packet for the associated destination has been passed for
* direct transmission.
*
* \param [in] panId Destination PAN ID.
* \param [in] shortAddress Destination short address.
*/
void FTDF_fpFsmShortAddressLastFramePending(FTDF_PANId panId, FTDF_ShortAddress shortAddress);
/**
* \brief Notifies FP FSM that the last packet for the associated destination has been passed for
* direct transmission.
*
* \param [in] panId Destination PAN ID.
* \param [in] shortAddress Destination extended address.
*/
void FTDF_fpFsmExtAddressLastFramePending(FTDF_PANId panId, FTDF_ExtAddress extAddress);
/**
* \brief Notifies FP FSM that the last pending packet has been transmitted (UMAC state machine
* closed).
*/
void FTDF_fpFsmClearPending(void);
#endif /* #ifndef FTDF_LITE */
/**
* \brief Number of FPPR table entries.
*/
#define FTDF_FPPR_TABLE_ENTRIES 24
/**
* \brief Number of extended address table entries.
*/
#define FTDF_FPPR_TABLE_EXT_ADDRESS_ENTRIES FTDF_FPPR_TABLE_ENTRIES
/**
* \brief Number of short address table entries.
*/
#define FTDF_FPPR_TABLE_SHORT_ADDRESS_ENTRIES (FTDF_FPPR_TABLE_ENTRIES * 4)
/**
* \brief Resets FPPR table, invalidating all addresses.
*/
void FTDF_fpprReset(void);
/**
* \brief Gets the short address programmed at the specified FPPR table position.
*
* \param [in] entry FPPR table entry (0 to \ref FTDF_FPPR_TABLE_ENTRIES - 1).
* \param [in] shortAddrIdx Short address position within the entry (0 to 3).
*
* \return Requested short address
*/
FTDF_ShortAddress FTDF_fpprGetShortAddress(uint8_t entry, uint8_t shortAddrIdx);
/**
* \brief Programs a short address programmed at the specified FPPR table position.
*
* \param [in] entry FPPR table entry (0 to \ref FTDF_FPPR_TABLE_ENTRIES - 1).
* \param [in] shortAddrIdx Short address position within the entry (0 to 3).
* \param [in] Associated short address.
*/
void FTDF_fpprSetShortAddress(uint8_t entry, uint8_t shortAddrIdx,
FTDF_ShortAddress shortAddress);
/**
* \brief Determines validity of a short address programmed at the specified FPPR table position.
*
* \param [in] entry FPPR table entry (0 to \ref FTDF_FPPR_TABLE_ENTRIES - 1).
* \param [in] shortAddrIdx Short address position within the entry (0 to 3).
*
* \return FTDF_TRUE if the address is valid.
*/
FTDF_Boolean FTDF_fpprGetShortAddressValid(uint8_t entry, uint8_t shortAddrIdx);
/**
* \brief Sets validity of a short address programmed at the specified FPPR table position.
*
* \param [in] entry FPPR table entry (0 to \ref FTDF_FPPR_TABLE_ENTRIES - 1).
* \param [in] shortAddrIdx Short address position within the entry (0 to 3).
* \param [in] valid Associated validity.
*/
void FTDF_fpprSetShortAddressValid(uint8_t entry, uint8_t shortAddrIdx,
FTDF_Boolean valid);
/**
* \brief Gets the extended address programmed at the specified FPPR table position.
*
* \param [in] entry FPPR table entry (0 to \ref FTDF_FPPR_TABLE_ENTRIES - 1).
*
* \return Requested extended address
*/
FTDF_ExtAddress FTDF_fpprGetExtAddress(uint8_t entry);
/**
* \brief Programs an extended address programmed at the specified FPPR table position.
*
* \param [in] entry FPPR table entry (0 to \ref FTDF_FPPR_TABLE_ENTRIES - 1).
* \param [in] Associated extended address.
*/
void FTDF_fpprSetExtAddress(uint8_t entry, FTDF_ExtAddress extAddress);
/**
* \brief Determines validity of an extended address programmed at the specified FPPR table
* position.
*
* \param [in] entry FPPR table entry (0 to \ref FTDF_FPPR_TABLE_ENTRIES - 1).
*
* \return \ref FTDF_TRUE if the address is valid.
*/
FTDF_Boolean FTDF_fpprGetExtAddressValid(uint8_t entry);
/**
* \brief Sets validity of an extended address programmed at the specified FPPR table position.
*
* \param [in] entry FPPR table entry (0 to \ref FTDF_FPPR_TABLE_ENTRIES - 1).
* \param [in] valid Associated validity.
*/
void FTDF_fpprSetExtAddressValid(uint8_t entry, FTDF_Boolean valid);
/**
* \brief Gets a free (invalid) short address position in the FPPR table.
*
* \param [out] entry Reference to the FPPR table entry.
* \param [out] shortAddrIdx Reference to the short address position within the entry.
*
* \return \ref FTDF_TRUE if a free position was found.
*/
FTDF_Boolean FTDF_fpprGetFreeShortAddress(uint8_t * entry,
uint8_t * shortAddrIdx);
/**
* \brief Gets a free (invalid) extended address position in the FPPR table.
*
* \param [out] entry Reference to the FPPR table entry.
*
* \return \ref FTDF_TRUE if a free position was found.
*/
FTDF_Boolean FTDF_fpprGetFreeExtAddress(uint8_t * entry);
/**
* \brief Looks up a short address within the FPPR table.
*
* \param [in] shortAddr Associated short address.
* \param [out] entry Reference to the FPPR table entry.
* \param [out] shortAddrIdx Reference to the short address position within the entry.
*
* * \return \ref FTDF_TRUE if the address was found.
*/
FTDF_Boolean FTDF_fpprLookupShortAddress(FTDF_ShortAddress shortAddr, uint8_t * entry,
uint8_t * shortAddrIdx);
/**
* \brief Looks up an extended address within the FPPR table.
*
* \param [in] extAddr Associated extended address.
* \param [out] entry Reference to the FPPR table entry.
*
* * \return \ref FTDF_TRUE if the address was found.
*/
FTDF_Boolean FTDF_fpprLookupExtAddress(FTDF_ExtAddress extAddr, uint8_t * entry);
#endif /* FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO */
/**
* \brief Sets FPPR mode.
*
* \param [in] matchFp Specifies the value of the FP bit when acknowledging a received frame with a
* source address that matches a valid a address in the FPPR table. The opposite value is set if the
* source address does not match. Ignored if \a fpOverride is \ref FTDF_TRUE.
*
* \param [in] fpOverride If \ref FTDF_TRUE, the value of \a fpForce is used for setting the FP bit,
* regardless of the address table matching result.
*
* \param [in] fpForce FP bit value when fpOverride is \ref FTDF_TRUE. Ignored otherwise.
*/
void FTDF_fpprSetMode(FTDF_Boolean matchFp, FTDF_Boolean fpOverride, FTDF_Boolean fpForce);
#if FTDF_FP_BIT_TEST_MODE
/**
* \brief Gets FPPR mode.
*
* \param [out] matchFp Reference to the returned value. \see FTDF_fpprRamSetMode
*
* \param [out] fpOverride Reference to the returned value. \see FTDF_fpprRamSetMode
*
* \param [out] fpForce FP Reference to the returned value. \see FTDF_fpprRamSetMode
*/
void FTDF_fpprGetMode(FTDF_Boolean * matchFp, FTDF_Boolean * fpOverride, FTDF_Boolean * fpForce);
#endif //FTDF_FP_BIT_TEST_MODE
#if FTDF_USE_LPDP == 1
/**
* \brief Enable or disable LPDP.
*
* \param [in] enable if FTDF_TRUE, LPDP functionality is enabled.
*/
void FTDF_lpdpEnable(FTDF_Boolean enable);
#if FTDF_FP_BIT_TEST_MODE
/**
* \brief Checks whether LPDP is enabled.
*
* \return FTDF_TRUE, if LPDP functionality is enabled.
*/
FTDF_Boolean FTDF_lpdpIsEnabled(void);
#endif
#endif /* #if FTDF_USE_LPDP == 1 */
#endif /* dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */
#endif /* FTDF_H_ */
/**
+17 -5
View File
@@ -28,25 +28,24 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
****************************************************************************************
*/
#ifndef FTDF_CONFIG_PHY_API_H_
#define FTDF_CONFIG_PHY_API_H_
//#include "osal.h" // OS_FREERTOS macro is checked within the header file.
/**
* \remark phy configuration values in microseconds
*/
#define FTDF_PHYTXSTARTUP 0x4c
#define FTDF_PHYTXLATENCY 0x01
#define FTDF_PHYTXFINISH 0x00
#define FTDF_PHYTRXWAIT 0x0f
#define FTDF_PHYTRXWAIT 0x20
#define FTDF_PHYRXSTARTUP 0
#define FTDF_PHYRXLATENCY 0
#define FTDF_PHYENABLE 0
#define FTDF_PHYENABLE 0x21
#ifndef FTDF_LITE
#define FTDF_LITE
@@ -146,5 +145,18 @@ void vPortExitCritical( void );
#define FTDF_DBG_BUS_GPIO_CONFIG ad_ftdf_dbgBusGpioConfig
#endif /* FTDF_DBG_BUS_ENABLE */
#ifndef FTDF_USE_FP_PROCESSING_RAM
/**
* \brief Whether to use HW acceleration for indirect sending.
*
* Feature is supported as of IC revision 14683-00.
*/
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
#define FTDF_USE_FP_PROCESSING_RAM 1
#else
#define FTDF_USE_FP_PROCESSING_RAM 0
#endif
#endif /* FTDF_USE_FP_PROCESSING_RAM */
#endif /* FTDF_CONFIG_PHY_API_H_ */
+52 -24
View File
@@ -29,8 +29,10 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
#ifdef CONFIG_USE_FTDF
#include <string.h>
#include <stdbool.h>
@@ -45,15 +47,22 @@
#include "sys_tcs.h"
#include "black_orca.h"
#include "sdk_defs.h"
#include "ad_ftdf.h"
#include "ad_rf.h"
#include "internal.h"
#include "regmap.h"
#if FTDF_DBG_BUS_ENABLE
#include "hw_gpio.h"
#endif /* FTDF_DBG_BUS_ENABLE */
#if FTDF_DBG_BLOCK_SLEEP_ENABLE
#include "hw_gpio.h"
#endif
#if dg_configUSE_FTDF_DDPHY == 1
#include "radio.h"
#endif
#define WUP_LATENCY (AD_FTDF_LP_CLOCK_CYCLE * AD_FTDF_WUP_LATENCY)
#ifdef FTDF_PHY_API
@@ -61,7 +70,7 @@
#define PRIVILEGED_DATA __attribute__((section("privileged_data_zi")))
#endif
#ifndef INITIALIZED_PRIVILEGED_DATA
#define INITIALIZED_PRIVILEGED_DATA __attribute__((section("privileged_data_rw")))
#define INITIALIZED_PRIVILEGED_DATA __attribute__((section("privileged_data_init")))
#endif
#endif
@@ -70,7 +79,6 @@ PRIVILEGED_DATA eSleepStatus sleep_status;
PRIVILEGED_DATA FTDF_ExtAddress uExtAddress;
static void ad_ftdf_sleep(void)
{
@@ -82,6 +90,10 @@ static void ad_ftdf_sleep(void)
while (REG_GETF(CRG_TOP, SYS_STAT_REG, FTDF_IS_DOWN) == 0x0) // don't go-go before I sleep
{
}
#if FTDF_DBG_BLOCK_SLEEP_ENABLE
hw_gpio_set_inactive(FTDF_DBG_BLOCK_SLEEP_GPIO_PORT, FTDF_DBG_BLOCK_SLEEP_GPIO_PIN);
#endif
}
void ad_ftdf_wake_up_internal(bool sync)
@@ -101,25 +113,18 @@ void ad_ftdf_wake_up_internal(bool sync)
{
}
/* Power on and configure RF */
#if dg_configRF_ADAPTER
ad_rf_request_on(false);
#else
vPortEnterCritical();
hw_rf_request_on(false);
vPortExitCritical();
#if FTDF_DBG_BLOCK_SLEEP_ENABLE
hw_gpio_configure_pin(FTDF_DBG_BLOCK_SLEEP_GPIO_PORT, FTDF_DBG_BLOCK_SLEEP_GPIO_PIN,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, true);
#endif
/* Power on and configure RF */
ad_rf_request_on(false);
/* Apply trim values */
sys_tcs_apply(tcs_ftdf);
// sys_tcs_apply(tcs_ftdf);
#if dg_configRF_ADAPTER
ad_rf_request_recommended_settings();
#else
vPortEnterCritical();
hw_rf_request_recommended_settings();
vPortExitCritical();
#endif
if (sync)
{
@@ -207,21 +212,27 @@ void sleep_when_possible(uint8_t explicit_request, uint32_t sleepTime)
// FTDF ready to sleep, disable clocks
sleep_status = BLOCK_SLEEPING;
explicit_sleep = explicit_request;
#if FTDF_USE_SLEEP_DURING_BACKOFF
FTDF_sdbFsmSleep();
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
#if dg_configUSE_FTDF_DDPHY == 1
FTDF_ddphySave();
#endif /* dg_configUSE_FTDF_DDPHY */
ad_ftdf_sleep();
}
else
{
#if FTDF_USE_SLEEP_DURING_BACKOFF
FTDF_sdbFsmAbortSleep();
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
}
}
FTDF_exitCritical();
if (blockSleep)
{
#if dg_configRF_ADAPTER
ad_rf_request_off(false);
#else
vPortEnterCritical();
hw_rf_request_off(false);
vPortExitCritical();
#endif
}
}
@@ -237,6 +248,10 @@ void ad_ftdf_init(void)
{
}
#if FTDF_DBG_BLOCK_SLEEP_ENABLE
hw_gpio_configure_pin(FTDF_DBG_BLOCK_SLEEP_GPIO_PORT, FTDF_DBG_BLOCK_SLEEP_GPIO_PIN,
HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, true);
#endif
REG_SET_BIT(CRG_TOP, CLK_RADIO_REG, FTDF_MAC_ENABLE); // on
REG_SETF(CRG_TOP, CLK_RADIO_REG, FTDF_MAC_DIV, 0); // divide by 1
@@ -276,13 +291,26 @@ void ad_ftdf_dbgBusGpioConfig(void)
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_7, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
#if FTDF_DBG_BUS_USE_SWDIO_PIN
/*
* Note that this pin has a conflict with SWD. Disable the debugger in order to use this
* pin.
*/
hw_gpio_set_pin_function(HW_GPIO_PORT_0, HW_GPIO_PIN_6, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
#endif
hw_gpio_set_pin_function(HW_GPIO_PORT_0, HW_GPIO_PIN_7, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
#if FTDF_DBG_BUS_USE_GPIO_P1_3_P2_2
/*
* Note that these pins have a conflict with the pins used for UART by default. Configure
* UART on different pins if you would like to use the pins below for diagnostics.
*/
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
hw_gpio_set_pin_function(HW_GPIO_PORT_2, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT,
HW_GPIO_FUNC_FTDF_DIAG);
#endif
}
#endif /* FTDF_DBG_BUS_ENABLE */
#endif
+2 -3
View File
@@ -1,8 +1,6 @@
/**
\addtogroup INTERFACES
\{
\addtogroup RADIO
\{
\addtogroup FTDF
\{
*/
@@ -36,7 +34,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
****************************************************************************************
*/
@@ -28,19 +28,27 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
#ifdef CONFIG_USE_FTDF
#ifdef FTDF_PHY_API
#include <string.h>
#include <stdbool.h>
#include "black_orca.h"
#include "sdk_defs.h"
#include "ad_ftdf.h"
#include "ad_ftdf_phy_api.h"
#include "internal.h"
#if FTDF_DBG_BUS_ENABLE
#include "hw_gpio.h"
#endif /* FTDF_DBG_BUS_ENABLE */
#ifndef OS_FREERTOS
static unsigned long uxCriticalNesting = 0x0 ;//0xaaaaaaaa;
static unsigned long uxCriticalNesting = 0xaaaaaaaa;
void vPortEnterCritical(void)
{
@@ -116,6 +124,9 @@ FTDF_Status ad_ftdf_send_frame_simple(FTDF_DataLength frameLength,
{
/* Wake-up the block */
ad_ftdf_wake_up_async();
#if FTDF_DBG_BUS_ENABLE
FTDF_checkDbgMode();
#endif /* FTDF_DBG_BUS_ENABLE */
sleep_status = BLOCK_ACTIVE;
}
@@ -134,6 +145,9 @@ void ad_ftdf_wake_up(void)
{
/* Wake-up the block */
ad_ftdf_wake_up_async();
#if FTDF_DBG_BUS_ENABLE
FTDF_checkDbgMode();
#endif /* FTDF_DBG_BUS_ENABLE */
sleep_status = BLOCK_ACTIVE;
}
@@ -151,5 +165,7 @@ void ad_ftdf_init_phy_api(void)
uxCriticalNesting = 0;
#endif
FTDF_reset(0);
FTDF_reset(1);
}
#endif /* FTDF_PHY_API */
#endif
File diff suppressed because it is too large Load Diff
+75 -2
View File
@@ -29,6 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -128,7 +129,7 @@ void FTDF_processDataRequest(FTDF_DataRequest *dataRequest)
if (status != FTDF_SUCCESS)
{
// Queueing of indirect transfer was successful
// Queueing of indirect transfer was not successful
FTDF_sendDataConfirm(dataRequest,
status,
0,
@@ -139,6 +140,30 @@ void FTDF_processDataRequest(FTDF_DataRequest *dataRequest)
return;
}
#if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO
uint8_t entry, shortAddrIdx;
if (dstAddrMode == FTDF_SHORT_ADDRESS)
{
if (FTDF_fpprGetFreeShortAddress(&entry, &shortAddrIdx) == FTDF_FALSE)
{
goto transaction_overflow;
}
}
else if (dstAddrMode == FTDF_EXTENDED_ADDRESS)
{
if (FTDF_fpprGetFreeExtAddress(&entry) == FTDF_FALSE)
{
goto transaction_overflow;
}
}
else
{
status = FTDF_INVALID_PARAMETER;
}
#endif
// Search for an empty indirect queue
for (queue = 0; queue < FTDF_NR_OF_REQ_BUFFERS; queue++)
{
@@ -153,6 +178,24 @@ void FTDF_processDataRequest(FTDF_DataRequest *dataRequest)
if (status == FTDF_SUCCESS)
{
#if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO
if (dstAddrMode == FTDF_SHORT_ADDRESS)
{
FTDF_fpprSetShortAddress(entry, shortAddrIdx, dstAddr.shortAddress);
FTDF_fpprSetShortAddressValid(entry, shortAddrIdx, FTDF_TRUE);
}
else if (dstAddrMode == FTDF_EXTENDED_ADDRESS)
{
FTDF_fpprSetExtAddress(entry, dstAddr.shortAddress);
FTDF_fpprSetExtAddressValid(entry, FTDF_TRUE);
}
else
{
ASSERT_WARNING(0);
}
#endif /* FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO */
FTDF_addTxPendingTimer((FTDF_MsgBuffer *) dataRequest,
queue,
FTDF_pib.transactionPersistenceTime * FTDF_BASE_SUPERFRAME_DURATION,
@@ -167,6 +210,9 @@ void FTDF_processDataRequest(FTDF_DataRequest *dataRequest)
}
// Did not find an existing or an empty queue
#if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO
transaction_overflow:
#endif
FTDF_sendDataConfirm(dataRequest, FTDF_TRANSACTION_OVERFLOW,
0,
0,
@@ -331,7 +377,9 @@ void FTDF_sendDataConfirm(FTDF_DataRequest *dataRequest,
FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) dataRequest);
FTDF_RCV_MSG((FTDF_MsgBuffer *) dataConfirm);
#if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO
FTDF_fpFsmClearPending();
#endif /* FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO */
FTDF_processNextRequest();
}
@@ -506,6 +554,31 @@ void FTDF_processPurgeRequest(FTDF_PurgeRequest *purgeRequest)
if (dataRequest->indirectTX == FTDF_TRUE)
{
FTDF_removeTxPendingTimer(request);
#if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO
if (FTDF_txPendingList[ n ].addrMode == FTDF_SHORT_ADDRESS)
{
uint8_t entry, shortAddrIdx;
FTDF_Boolean found = FTDF_fpprLookupShortAddress(
FTDF_txPendingList[ n ].addr.shortAddress, &entry,
&shortAddrIdx);
ASSERT_WARNING(found);
FTDF_fpprSetShortAddressValid(entry, shortAddrIdx, FTDF_FALSE);
}
else if (FTDF_txPendingList[ n ].addrMode == FTDF_EXTENDED_ADDRESS)
{
uint8_t entry;
FTDF_Boolean found = FTDF_fpprLookupExtAddress(
FTDF_txPendingList[ n ].addr.extAddress, &entry);
ASSERT_WARNING(found);
FTDF_fpprSetExtAddressValid(entry, FTDF_FALSE);
}
else
{
ASSERT_WARNING(0);
}
#endif /* FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO */
if (FTDF_isQueueEmpty(&FTDF_txPendingList[ n ].queue))
{
+72 -1
View File
@@ -29,6 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -36,7 +37,9 @@
#define FTDF_FCS_LENGTH 2
#define FTDF_BUFFER_LENGTH 128
#define FTDF_NR_OF_REQ_BUFFERS 16
#ifndef FTDF_NR_OF_REQ_BUFFERS
#define FTDF_NR_OF_REQ_BUFFERS 96
#endif
#define FTDF_NR_OF_RX_BUFFERS 8
#define FTDF_NR_OF_CHANNELS 16
#define FTDF_NR_OF_SCAN_RESULTS 16
@@ -94,6 +97,14 @@
} \
while ( 0 )
#define FTDF_SET_FIELD_INDEXED( fieldName, value, index ) do { \
uint32_t tmp = *FTDF_GET_FIELD_ADDR_INDEXED( fieldName, index ) & ~MSK_F_FTDF_ ## fieldName; \
*FTDF_GET_FIELD_ADDR_INDEXED( fieldName, index ) = tmp | \
( ( ( value ) << OFF_F_FTDF_ ## fieldName ) & MSK_F_FTDF_ ## fieldName ); \
} \
while ( 0 )
#define FTDF_processRequest FTDF_sndMsg
struct FTDF_Pib
@@ -219,6 +230,10 @@ struct FTDF_Pib
FTDF_Boolean tschCapable;
FTDF_Period tsSyncCorrectThreshold;
#endif /* !FTDF_LITE */
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
FTDF_NrBackoffPeriods boIrqThreshold;
FTDF_PtiConfig ptiConfig;
#endif
};
typedef uint8_t FTDF_FrameVersion;
@@ -600,6 +615,7 @@ void FTDF_getPANId( void );
void FTDF_setPANId( void );
void FTDF_getCurrentChannel( void );
void FTDF_setCurrentChannel( void );
void FTDF_setTXPower( void );
void FTDF_getMaxFrameTotalWaitTime( void );
void FTDF_setMaxFrameTotalWaitTime( void );
#ifndef FTDF_NO_CSL
@@ -614,6 +630,12 @@ void FTDF_setMaxBE( void );
void FTDF_setMinBE( void );
void FTDF_getKeepPhyEnabled( void );
void FTDF_setKeepPhyEnabled( void );
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
void FTDF_setBoIrqThreshold( void );
void FTDF_getBoIrqThreshold( void );
void FTDF_setPtiConfig( void );
#endif /* dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */
#ifndef FTDF_NO_TSCH
void FTDF_setTimeslotTemplate( void );
#endif /* FTDF_NO_TSCH */
@@ -639,6 +661,9 @@ void FTDF_processKeepAliveTimerExp( FTDF_PendingTL* ptr );
void FTDF_resetKeepAliveTimer( FTDF_ShortAddress dstAddr );
#endif /* FTDF_NO_TSCH */
void FTDF_processTxPending(FTDF_FrameHeader* frameHeader,
FTDF_SecurityHeader* securityHeader );
void FTDF_processCommandFrame( FTDF_Octet* rxBuffer,
FTDF_FrameHeader* frameHeader,
FTDF_SecurityHeader* securityHeader,
@@ -671,3 +696,49 @@ FTDF_SN FTDF_processTschSN( FTDF_MsgBuffer* msg, FTDF_SN sn, uint8_t*
FTDF_Time64 FTDF_getCurTime64( void );
void FTDF_initCurTime64( void );
#if FTDF_USE_SLEEP_DURING_BACKOFF
typedef enum
{
FTDF_SDB_STATE_INIT = 0,
FTDF_SDB_STATE_BACKING_OFF,
FTDF_SDB_STATE_WAITING_WAKE_UP_IRQ,
FTDF_SDB_STATE_RESUMING,
} FTDF_SdbState;
typedef struct
{
FTDF_SdbState state;
FTDF_Size nrOfBackoffs;
FTDF_Time ccaRetryTime;
FTDF_Octet buffer[FTDF_BUFFER_LENGTH];
uint32_t metadata0;
uint32_t metadata1;
uint32_t phyCsmaCaAttr;
} FTDF_Sdb;
void FTDF_sdbFsmReset(void);
void FTDF_sdbFsmBackoffIRQ(void);
void FTDF_sdbFsmSleep(void);
void FTDF_sdbFsmAbortSleep(void);
void FTDF_sdbFsmWakeUpIRQ(void);
void FTDF_sdbFsmWakeUp(void);
void FTDF_sdbFsmTxIRQ(void);
FTDF_USec FTDF_sdbGetSleepTime(void);
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
#if dg_configUSE_FTDF_DDPHY == 1
void FTDF_ddphyRestore(void);
void FTDF_ddphySave(void);
#endif
+10
View File
@@ -29,6 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
****************************************************************************************
*/
@@ -282,6 +283,15 @@ void FTDF_sndMsg(FTDF_MsgBuffer *msgBuf)
FTDF_REL_MSG_BUFFER(msgBuf);
break;
#endif /* FTDF_DBG_BUS_ENABLE */
#if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A
case FTDF_FPPR_MODE_SET_REQUEST:
FTDF_fpprSetMode(((FTDF_FpprModeSetRequest *) msgBuf)->matchFp,
((FTDF_FpprModeSetRequest *) msgBuf)->fpOverride,
((FTDF_FpprModeSetRequest *) msgBuf)->fpForce);
FTDF_REL_MSG_BUFFER(msgBuf);
break;
#endif /* dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */
default:
// Silenty release the message buffer
+54 -2
View File
@@ -79,16 +79,24 @@ FTDF_USec FTDF_canSleep(void)
}
#else
#if FTDF_USE_SLEEP_DURING_BACKOFF
if (FTDF_pib.keepPhyEnabled)
#else
if (FTDF_reqCurrent || FTDF_pib.keepPhyEnabled)
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
{
return 0;
}
#endif
#if FTDF_USE_SLEEP_DURING_BACKOFF
if (FTDF_GET_FIELD(ON_OFF_REGMAP_SECBUSY) == 1)
#else /* FTDF_USE_SLEEP_DURING_BACKOFF */
if (FTDF_GET_FIELD(ON_OFF_REGMAP_LMACREADY4SLEEP) == 0 ||
FTDF_GET_FIELD(ON_OFF_REGMAP_SECBUSY) == 1)
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
{
return 0;
}
@@ -97,6 +105,16 @@ FTDF_USec FTDF_canSleep(void)
if (FTDF_pib.leEnabled)
{
#if FTDF_USE_SLEEP_DURING_BACKOFF
/* Abort sleep when LMAC is busy. */
if (FTDF_GET_FIELD(ON_OFF_REGMAP_LMACREADY4SLEEP) == 0)
{
return 0;
}
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
if (FTDF_txInProgress == FTDF_FALSE)
{
FTDF_Time curTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL);
@@ -123,6 +141,15 @@ FTDF_USec FTDF_canSleep(void)
if (FTDF_pib.tschEnabled)
{
#if FTDF_USE_SLEEP_DURING_BACKOFF
/* Abort sleep when LMAC is busy. */
if (FTDF_GET_FIELD(ON_OFF_REGMAP_LMACREADY4SLEEP) == 0)
{
return 0;
}
#endif
FTDF_Time64 curTime64 = FTDF_getCurTime64();
FTDF_Time64 delta = curTime64 - FTDF_tschSlotTime;
@@ -179,7 +206,12 @@ FTDF_USec FTDF_canSleep(void)
}
#endif /* !FTDF_LITE */
#if FTDF_USE_SLEEP_DURING_BACKOFF
return FTDF_sdbGetSleepTime();
#else /* FTDF_USE_SLEEP_DURING_BACKOFF */
return 0xffffffff;
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
}
FTDF_Boolean FTDF_prepareForSleep(FTDF_USec sleepTime)
@@ -235,6 +267,10 @@ FTDF_Boolean FTDF_prepareForSleep(FTDF_USec sleepTime)
*getGeneratorValE = MSK_F_FTDF_ON_OFF_REGMAP_GETGENERATORVAL_E;
#endif
uint64_t nextWakeUpThr;
#if FTDF_USE_SLEEP_DURING_BACKOFF
uint64_t picoSleepTime = (uint64_t)sleepTime * 1000000;
nextWakeUpThr = (picoSleepTime - FTDF_wakeUpLatency) / FTDF_lowPowerClockCycle;
#else /* FTDF_USE_SLEEP_DURING_BACKOFF */
if (FTDF_pib.leEnabled || FTDF_pib.tschEnabled)
{
@@ -246,9 +282,11 @@ FTDF_Boolean FTDF_prepareForSleep(FTDF_USec sleepTime)
nextWakeUpThr = FTDF_csmacaWakeupThr;
}
#endif /* FTDF_USE_SLEEP_DURING_BACKOFF */
// Set wake up threshold
uint32_t wakeUpIntThr = FTDF_eventCurrVal + nextWakeUpThr;
// Note that for IC revs other than A the size of WAKEUPINTTHR is 25 bits.
FTDF_SET_FIELD(ALWAYS_ON_REGMAP_WAKEUPINTTHR, wakeUpIntThr);
FTDF_SET_FIELD(ALWAYS_ON_REGMAP_WAKEUPENABLE, 1);
#endif
@@ -285,7 +323,21 @@ void FTDF_wakeUp(void)
#endif
// Backward calculate the time slept
FTDF_PSec sleepTime = ((uint64_t)(eventNewCurrVal - FTDF_eventCurrVal) * FTDF_lowPowerClockCycle) + FTDF_wakeUpLatency;
//FTDF_PSec sleepTime = ( (uint64_t)( eventNewCurrVal - FTDF_eventCurrVal ) * FTDF_lowPowerClockCycle ) + FTDF_wakeUpLatency;
FTDF_PSec sleepTime;
if (eventNewCurrVal >= FTDF_eventCurrVal) /* Check for wraps. */
{
sleepTime = (eventNewCurrVal - FTDF_eventCurrVal) * FTDF_lowPowerClockCycle +
FTDF_wakeUpLatency;
}
else
{
sleepTime = (eventNewCurrVal +
(MSK_R_FTDF_ON_OFF_REGMAP_EVENTCURRVAL - FTDF_eventCurrVal)) *
FTDF_lowPowerClockCycle + FTDF_wakeUpLatency;
}
// Calculate sync values
uint64_t newSyncVals = ((uint64_t)FTDF_timeStampCurrVal << 8) | (FTDF_timeStampCurrPhaseVal & 0xff);
+4509 -3
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1,4 +1,4 @@
arm-none-eabi-objcopy -O binary ../../../output/bin/arm-none-eabi-ot-cli-ftd ../../../output/bin/arm-none-eabi-ot-cli-ftd.bin
./bin2image qspi_cached ../../../output/bin/arm-none-eabi-ot-cli-ftd.bin ../../../output/bin/arm-none-eabi-ot-cli-ftd.img AD enable_uart
Binary file not shown.