mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 05:12:57 +01:00
cc26x2_cc13x2: add function to change AUX opmode
This function is needed to setup the AUX operational mode at startup, also used for managing low-power states. Signed-off-by: Jean Pierre Dudey <jeandudey@hotmail.com>
This commit is contained in:
parent
549d7ff24f
commit
2921944c66
91
cpu/cc26x2_cc13x2/aux.c
Normal file
91
cpu/cc26x2_cc13x2/aux.c
Normal file
@ -0,0 +1,91 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 Locha Inc
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
/**
|
||||
* @ingroup cpu_cc26x2_cc13x2
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief CC26x2, CC13x2 AUX functions
|
||||
* @author Jean Pierre Dudey <jeandudey@hotmail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "cpu.h"
|
||||
|
||||
/**
|
||||
* @brief Order of operation modes
|
||||
*
|
||||
* This is to calculate which mode follows the other, to change step-by-step
|
||||
* the mode.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define OPMODE_PDA_ORDER (0)
|
||||
#define OPMODE_A_ORDER (1)
|
||||
#define OPMODE_LP_ORDER (2)
|
||||
#define OPMODE_PDLP_ORDER (3)
|
||||
/** @} */
|
||||
|
||||
/** Array to map an operation mode to it's order when changing it */
|
||||
static const uint8_t _opmode_to_order[4] = {
|
||||
OPMODE_A_ORDER,
|
||||
OPMODE_LP_ORDER,
|
||||
OPMODE_PDA_ORDER,
|
||||
OPMODE_PDLP_ORDER
|
||||
};
|
||||
/** Array to map an order to an operation mode, used to get the next operation
|
||||
* mode. This is because we need to change the operation in ordered steps */
|
||||
static const uint8_t _order_to_opmode[4] = {
|
||||
AUX_SYSIF_OPMODEREQ_REQ_PDA,
|
||||
AUX_SYSIF_OPMODEREQ_REQ_A,
|
||||
AUX_SYSIF_OPMODEREQ_REQ_LP,
|
||||
AUX_SYSIF_OPMODEREQ_REQ_PDLP
|
||||
};
|
||||
|
||||
void aux_sysif_opmode_change(uint32_t target_opmode)
|
||||
{
|
||||
assert((target_opmode == AUX_SYSIF_OPMODEREQ_REQ_PDLP) ||
|
||||
(target_opmode == AUX_SYSIF_OPMODEREQ_REQ_PDA) ||
|
||||
(target_opmode == AUX_SYSIF_OPMODEREQ_REQ_LP) ||
|
||||
(target_opmode == AUX_SYSIF_OPMODEREQ_REQ_A));
|
||||
|
||||
uint32_t current_opmode;
|
||||
uint32_t next_mode;
|
||||
|
||||
/* Change AUX operation mode following hardware rules, operation mode
|
||||
* change needs to be done in order, and one step at a time:
|
||||
*
|
||||
* PDA -> A -> LP -> PDLP
|
||||
*/
|
||||
do {
|
||||
current_opmode = AUX_SYSIF->OPMODEREQ;
|
||||
|
||||
/* Wait for change ACK */
|
||||
while (current_opmode != AUX_SYSIF->OPMODEACK) {}
|
||||
|
||||
if (current_opmode == target_opmode) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* At this point we aren't in the mode we want, now we calculate which
|
||||
* mode follows this and make the change to that mode, this is repeated
|
||||
* in this loop until we get to the desired mode */
|
||||
uint32_t current_order = _opmode_to_order[current_opmode];
|
||||
if (current_order < _opmode_to_order[target_opmode]) {
|
||||
next_mode = _order_to_opmode[current_order + 1];
|
||||
}
|
||||
else {
|
||||
next_mode = _order_to_opmode[current_order - 1];
|
||||
}
|
||||
|
||||
/* Request next mode */
|
||||
AUX_SYSIF->OPMODEREQ = next_mode;
|
||||
} while (current_opmode != target_opmode);
|
||||
}
|
@ -217,6 +217,17 @@ typedef struct {
|
||||
reg32_t SWPWRPROF; /**< Software Power Profiler */
|
||||
} aux_sysif_regs_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief AUX_SYSIF register values
|
||||
* @{
|
||||
*/
|
||||
#define AUX_SYSIF_OPMODEREQ_REQ_PDLP 0x00000003
|
||||
#define AUX_SYSIF_OPMODEREQ_REQ_PDA 0x00000002
|
||||
#define AUX_SYSIF_OPMODEREQ_REQ_LP 0x00000001
|
||||
#define AUX_SYSIF_OPMODEREQ_REQ_A 0x00000000
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @ingroup cpu_specific_peripheral_memory_map
|
||||
* @{
|
||||
@ -232,6 +243,21 @@ typedef struct {
|
||||
*/
|
||||
#define AUX_SYSIF ((aux_sysif_regs_t *) (AUX_SYSIF_BASE))
|
||||
|
||||
/**
|
||||
* @brief AUX_SYSIF functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Changes the AUX operational mode
|
||||
*
|
||||
* @note Only this function should be used to change the operational mode,
|
||||
* because it needs to be done in order.
|
||||
*
|
||||
* @param[in] target_opmode The opmode we want to change to.
|
||||
*/
|
||||
void aux_sysif_opmode_change(uint32_t target_opmode);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief AUX_TIMER01 registers
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user