/*
|
* Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and
|
* its subsidiaries and affiliates (collectly called MKSEMI).
|
*
|
* 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, except as embedded into an MKSEMI
|
* integrated circuit in a product or a software update for such product,
|
* 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 MKSEMI nor the names of its contributors may be used
|
* to endorse or promote products derived from this software without
|
* specific prior written permission.
|
*
|
* 4. This software, with or without modification, must only be used with a
|
* MKSEMI integrated circuit.
|
*
|
* 5. Any software provided in binary form under this license must not be
|
* reverse engineered, decompiled, modified and/or disassembled.
|
*
|
* THIS SOFTWARE IS PROVIDED BY MKSEMI "AS IS" AND ANY EXPRESS OR IMPLIED
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* DISCLAIMED. IN NO EVENT SHALL MKSEMI 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.
|
*/
|
|
#include "mk_uart.h"
|
#include "mk_trace.h"
|
#include "mk_reset.h"
|
#include "mk_calib.h"
|
#include "mk_wdt.h"
|
#include "mk_gpio.h"
|
#include "mk_dual_timer.h"
|
#include "mk_misc.h"
|
#include "mk_power.h"
|
#include "mk_io.h"
|
#include "mk_rtc.h"
|
#include "mk_uwb.h"
|
#include "mk_flash.h"
|
#include "libc_rom.h"
|
|
#include "board.h"
|
|
#define BUTTON_SWITCH_POWER_MODE_EN 1
|
#define CH_NUM 9
|
#define TX_POWER_LEVEL 28
|
|
static struct UWB_CONFIG_T uwb_config;
|
|
static uint8_t tx_payload[20];
|
static uint16_t tx_len = 20;
|
|
enum TEST_MODE_T
|
{
|
TEST_RF_CARRIER = 0,
|
TEST_UWB_TX,
|
TEST_UWB_RX,
|
TEST_MCU_ACTIVE,
|
TEST_MCU_SLEEP,
|
TEST_MCU_POWER_DOWN,
|
TEST_MCU_DEEP_POWER_DOWN,
|
TEST_MCU_SHELF_MODE,
|
};
|
|
static enum TEST_MODE_T test_mode = TEST_RF_CARRIER;
|
|
/*
|
MODE - LED1 LED2 LED3
|
0 - 1 1 1
|
1 - 1 1 0
|
2 - 1 0 1
|
3 - 1 0 0
|
4 - 0 1 1
|
5 - 0 1 0
|
6 - 0 0 1
|
7 - 0 0 0
|
*/
|
static void app_led_set(enum TEST_MODE_T pm)
|
{
|
uint8_t led = (uint8_t)pm;
|
#if BOARD_TYPE == MK8000_DK
|
if (led & 0x1)
|
{
|
board_led_off(BOARD_LED_3);
|
}
|
else
|
{
|
board_led_on(BOARD_LED_3);
|
}
|
#endif
|
if (led & 0x2)
|
{
|
board_led_off(BOARD_LED_2);
|
}
|
else
|
{
|
board_led_on(BOARD_LED_2);
|
}
|
if (led & 0x4)
|
{
|
board_led_off(BOARD_LED_1);
|
}
|
else
|
{
|
board_led_on(BOARD_LED_1);
|
}
|
}
|
|
static void app_power_mode_set(enum TEST_MODE_T pm)
|
{
|
enum POWER_MODE_T power_mode = POWER_MODE_ACTIVE;
|
|
switch (pm)
|
{
|
case TEST_RF_CARRIER:
|
power_mode = POWER_MODE_ACTIVE;
|
uwb_open();
|
power_on_radio(1, 0);
|
uwb_tx_carrier_only(1, CH_NUM, TX_POWER_LEVEL);
|
LOG_INFO(TRACE_MODULE_APP, "==== RF Single Carrier ====\r\n");
|
break;
|
case TEST_UWB_TX:
|
power_mode = POWER_MODE_ACTIVE;
|
uwb_tx_carrier_only(0, CH_NUM, TX_POWER_LEVEL);
|
uwb_configure(PHY_TX | PHY_RX, TX_POWER_LEVEL, &uwb_config);
|
LOG_INFO(TRACE_MODULE_APP, "==== UWB TX ====\r\n");
|
break;
|
case TEST_UWB_RX:
|
power_mode = POWER_MODE_ACTIVE;
|
uwb_blocking_trx_stop();
|
power_off_radio();
|
power_on_radio(0, 1);
|
LOG_INFO(TRACE_MODULE_APP, "==== UWB RX ====\r\n");
|
break;
|
case TEST_MCU_ACTIVE:
|
power_mode = POWER_MODE_ACTIVE;
|
uwb_blocking_trx_stop();
|
LOG_INFO(TRACE_MODULE_APP, "==== MCU Active ====\r\n");
|
break;
|
case TEST_MCU_SLEEP:
|
power_mode = POWER_MODE_SLEEP;
|
LOG_INFO(TRACE_MODULE_APP, "==== MCU Sleep ====\r\n");
|
break;
|
case TEST_MCU_POWER_DOWN:
|
power_mode = POWER_MODE_POWER_DOWN;
|
LOG_INFO(TRACE_MODULE_APP, "==== MCU Power-down ====\r\n");
|
break;
|
case TEST_MCU_DEEP_POWER_DOWN:
|
power_mode = POWER_MODE_DEEP_POWER_DOWN;
|
LOG_INFO(TRACE_MODULE_APP, "==== MCU Deep Power-down ====\r\n");
|
break;
|
case TEST_MCU_SHELF_MODE:
|
power_mode = POWER_MODE_SHELF;
|
LOG_INFO(TRACE_MODULE_APP, "==== MCU Shelf Mode ====\r\n");
|
break;
|
}
|
|
power_mode_request(POWER_UNIT_APP, power_mode);
|
app_led_set(pm);
|
}
|
|
#if BUTTON_SWITCH_POWER_MODE_EN == 0
|
static void rtc_tick_update(void *dev, uint32_t err)
|
{
|
struct RTC_TIME_T *time = (struct RTC_TIME_T *)dev;
|
LOG_INFO(TRACE_MODULE_APP, "%04d-%02d-%02d %02d:%02d:%02d\r\n", time->year, time->month, time->day, time->hour, time->minute, time->second);
|
|
switch (test_mode)
|
{
|
case TEST_RF_CARRIER:
|
test_mode = TEST_UWB_TX;
|
break;
|
case TEST_UWB_TX:
|
test_mode = TEST_UWB_RX;
|
break;
|
case TEST_UWB_RX:
|
test_mode = TEST_MCU_ACTIVE;
|
break;
|
case TEST_MCU_ACTIVE:
|
test_mode = TEST_MCU_SLEEP;
|
break;
|
case TEST_MCU_SLEEP:
|
test_mode = TEST_MCU_POWER_DOWN;
|
break;
|
case TEST_MCU_POWER_DOWN:
|
case TEST_MCU_DEEP_POWER_DOWN:
|
case TEST_MCU_SHELF_MODE:
|
test_mode = TEST_RF_CARRIER;
|
break;
|
}
|
|
app_power_mode_set(test_mode);
|
}
|
#else
|
static void button_debounce_timeout_handler(void *id, uint32_t count)
|
{
|
LOG_INFO(TRACE_MODULE_APP, "Debounce timer stop\r\n");
|
power_mode_clear(POWER_UNIT_TIMER);
|
if (gpio_pin_get_val(BOARD_SW_1))
|
{
|
return;
|
}
|
|
switch (test_mode)
|
{
|
case TEST_RF_CARRIER:
|
test_mode = TEST_UWB_TX;
|
break;
|
case TEST_UWB_TX:
|
test_mode = TEST_UWB_RX;
|
break;
|
case TEST_UWB_RX:
|
test_mode = TEST_MCU_ACTIVE;
|
break;
|
case TEST_MCU_ACTIVE:
|
test_mode = TEST_MCU_SLEEP;
|
break;
|
case TEST_MCU_SLEEP:
|
test_mode = TEST_MCU_POWER_DOWN;
|
break;
|
case TEST_MCU_POWER_DOWN:
|
test_mode = TEST_MCU_DEEP_POWER_DOWN;
|
break;
|
case TEST_MCU_DEEP_POWER_DOWN:
|
test_mode = TEST_MCU_SHELF_MODE;
|
break;
|
case TEST_MCU_SHELF_MODE:
|
test_mode = TEST_RF_CARRIER;
|
break;
|
}
|
|
app_power_mode_set(test_mode);
|
}
|
|
static void power_mode_Handler(enum IO_PIN_T pin)
|
{
|
if (pin == BOARD_SW_1)
|
{
|
// start a 10ms timer
|
mac_timer_open(button_debounce_timeout_handler);
|
mac_timer_start(__MS_TO_TICKS(10));
|
LOG_INFO(TRACE_MODULE_APP, "Debounce timer start\r\n");
|
power_mode_request(POWER_UNIT_TIMER, POWER_MODE_SLEEP);
|
}
|
}
|
#endif
|
|
int main(void)
|
{
|
board_clock_run();
|
board_pins_config();
|
board_debug_console_open(TRACE_PORT_UART0);
|
// Reset reason
|
reset_cause_get();
|
reset_cause_clear();
|
|
// Chip calibration
|
calib_chip();
|
|
// Disable watchdog timer
|
wdt_close(WDT_ID0);
|
|
#ifdef XIP_EN
|
LOG_INFO(TRACE_MODULE_APP, "XIP Power Cycling\r\n");
|
#else
|
flash_close(FLASH_ID0);
|
LOG_INFO(TRACE_MODULE_APP, "Power Cycling\r\n");
|
#endif
|
|
gpio_open();
|
board_led_init();
|
board_configure();
|
|
#if BUTTON_SWITCH_POWER_MODE_EN == 0
|
struct RTC_TIME_T time;
|
|
time.year = 2022;
|
time.month = 1;
|
time.day = 6;
|
time.hour = 12;
|
time.minute = 0;
|
time.second = 0;
|
|
rtc_open(RTC_ID0, rtc_tick_update);
|
rtc_set(RTC_ID0, &time);
|
power_wakeup_enable(POWER_WAKEUP_BY_RTC_TICK, POWER_WAKEUP_LEVEL_NONE);
|
|
#else
|
board_button_init(power_mode_Handler);
|
// for debounce detection
|
mac_timer_open(button_debounce_timeout_handler);
|
#endif
|
|
uwb_config.ch_num = CH_NUM;
|
uwb_config.code_index = 9;
|
uwb_config.mean_prf = MEAN_PRF_64M;
|
uwb_config.data_bit_rate = DATA_BR_6M8;
|
|
uwb_config.sync_sym = PREAM_LEN_64;
|
uwb_config.sfd_sym = BPRF_NSFD2_8;
|
uwb_config.ranging_bit = 0;
|
uwb_config.trx_mode = TRX_MODE_15_4Z_BPRF;
|
|
uwb_config.sts_pkt_cfg = STS_PKT_CFG_0;
|
uwb_config.sts_segnum = STS_SEGNUM_BPRF_1;
|
uwb_config.sts_seglen = STS_SEGLEN_BPRF_64;
|
uwb_config.rx_ant_id = UWB_RX_ANT_3;
|
|
uwb_rx_antenna_open(uwb_config.rx_ant_id);
|
|
for (uint32_t i = 0; i < sizeof(tx_payload); i++)
|
{
|
tx_payload[i] = 0x55;
|
}
|
|
power_init();
|
app_power_mode_set(test_mode);
|
|
while (1)
|
{
|
power_manage();
|
|
switch (test_mode)
|
{
|
case TEST_MCU_ACTIVE:
|
break;
|
case TEST_RF_CARRIER:
|
break;
|
case TEST_UWB_TX:
|
uwb_blocking_tx_start(tx_payload, tx_len, 0);
|
break;
|
case TEST_UWB_RX:
|
uwb_blocking_rx_start(0, NULL);
|
uwb_close();
|
break;
|
case TEST_MCU_SLEEP:
|
break;
|
case TEST_MCU_POWER_DOWN:
|
break;
|
case TEST_MCU_DEEP_POWER_DOWN:
|
break;
|
case TEST_MCU_SHELF_MODE:
|
break;
|
}
|
}
|
}
|