You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

350 lines
13 KiB

#include "board.h"
#include "app_timer.h"
#include "nrf_gpio.h"
#include "znordic.h"
//
#include "diskio_blkdev.h"
#include "ff.h"
#include "nrf_block_dev_sdc.h"
#include "nrf_delay.h"
#include "nrf_drv_pwm.h"
#include "nrf_drv_wdt.h"
static int16_t adc_channel_read_val(uint16_t channel) {
nrf_saadc_value_t value;
ret_code_t err_code;
err_code = nrfx_saadc_sample_convert(channel, &value);
if (err_code != NRF_SUCCESS) {
ZLOGE("nrfx_saadc_sample_convert(%d) fail err_code:%d", channel, err_code);
return 0;
}
return value;
}
/*******************************************************************************
* DEBUG_LIGHT *
*******************************************************************************/
APP_TIMER_DEF(m_debug_light_tmr);
static int32_t m_debug_light_io_index;
static void debug_light_tmr_cb_handler(void* p_context) {
static bool state = false;
if (state) {
nrf_gpio_pin_set(m_debug_light_io_index);
} else {
nrf_gpio_pin_clear(m_debug_light_io_index);
}
state = !state;
}
void debug_light_init(int io_index) {
m_debug_light_io_index = io_index;
nrf_gpio_cfg(m_debug_light_io_index, //
NRF_GPIO_PIN_DIR_OUTPUT, //
NRF_GPIO_PIN_INPUT_DISCONNECT, //
NRF_GPIO_PIN_PULLUP, //
NRF_GPIO_PIN_S0S1, //
NRF_GPIO_PIN_NOSENSE);
ret_code_t err_code;
err_code = app_timer_create(&m_debug_light_tmr, APP_TIMER_MODE_REPEATED, debug_light_tmr_cb_handler);
APP_ERROR_CHECK(err_code);
app_timer_start(m_debug_light_tmr, APP_TIMER_TICKS(100), NULL);
}
/*******************************************************************************
* zbsp_enter_sleep *
*******************************************************************************/
APP_TIMER_DEF(enter_sleep_mode_tmr);
static int32_t m_wakeup_io_index;
static bool m_wakeup_io_mirror;
static void enter_sleep_tmr_cb(void* p_context) {
ZLOGI("enter sleep mode, wakeup io index: %d", m_wakeup_io_index);
if (m_wakeup_io_mirror) {
nrf_gpio_cfg_sense_input(m_wakeup_io_index, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_set(m_wakeup_io_index, NRF_GPIO_PIN_SENSE_LOW);
} else {
nrf_gpio_cfg_sense_input(m_wakeup_io_index, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_HIGH);
nrf_gpio_cfg_sense_set(m_wakeup_io_index, NRF_GPIO_PIN_SENSE_HIGH);
}
// Go to system-off mode (this function will not return; wakeup will cause a reset).
ret_code_t err_code;
err_code = sd_power_system_off();
if (err_code != NRF_SUCCESS) {
ZLOGE("sd_power_system_off err_code: %x", err_code);
}
}
void zbsp_enter_sleep(int32_t after_ms, int32_t wakeup_io_index, bool mirror) {
m_wakeup_io_index = wakeup_io_index;
m_wakeup_io_mirror = mirror;
ret_code_t err_code;
APP_ERROR_CHECK(app_timer_create(&enter_sleep_mode_tmr, APP_TIMER_MODE_SINGLE_SHOT, enter_sleep_tmr_cb));
APP_ERROR_CHECK(app_timer_start(enter_sleep_mode_tmr, APP_TIMER_TICKS(after_ms), NULL));
ZLOGI("enter sleep mode after %d ms", after_ms);
}
/*******************************************************************************
* gpio_io_state_monitor *
*******************************************************************************/
APP_TIMER_DEF(gpio_io_state_monitor_tmr);
static uint8_t* m_io_index;
static int32_t m_nio;
static void gpio_io_state_monitor_tmr_cb(void* p_context) {
// ioindex:state ioindex:state ioindex:state
if (m_nio == 1) {
ZLOGI("iostate %d:%d ", m_io_index[0], nrf_gpio_pin_read(m_io_index[0]));
} else if (m_nio == 2) {
ZLOGI("iostate %d:%d %d:%d", m_io_index[0], nrf_gpio_pin_read(m_io_index[0]), //
m_io_index[1], nrf_gpio_pin_read(m_io_index[1]));
} else if (m_nio >= 3) {
ZLOGI("iostate %d:%d %d:%d %d:%d", m_io_index[0], nrf_gpio_pin_read(m_io_index[0]), //
m_io_index[1], nrf_gpio_pin_read(m_io_index[1]), //
m_io_index[2], nrf_gpio_pin_read(m_io_index[2]));
}
}
void zbsp_gpio_state_monitor_without_initio(int dumpstate_period, uint8_t* io_index, int32_t nio) {
m_io_index = io_index;
m_nio = nio;
APP_ERROR_CHECK(app_timer_create(&gpio_io_state_monitor_tmr, APP_TIMER_MODE_REPEATED, gpio_io_state_monitor_tmr_cb));
APP_ERROR_CHECK(app_timer_start(gpio_io_state_monitor_tmr, APP_TIMER_TICKS(dumpstate_period), NULL));
}
void zbsp_gpio_state_monitor(int dumpstate_period, uint8_t* io_index, int32_t nio) {
m_io_index = io_index;
m_nio = nio;
for (int i = 0; i < nio; i++) {
nrf_gpio_cfg_input(io_index[i], NRF_GPIO_PIN_PULLUP);
}
zbsp_gpio_state_monitor_without_initio(dumpstate_period, io_index, nio);
}
void board_init() {}
/*******************************************************************************
* ADC *
*******************************************************************************/
static void saadc_callback(nrf_drv_saadc_evt_t const* p_event) {
if (p_event->type == NRF_DRV_SAADC_EVT_DONE) {
}
}
void adc_module_init() {
nrf_drv_saadc_config_t adccfg = NRFX_SAADC_DEFAULT_CONFIG;
adccfg.resolution = NRF_SAADC_RESOLUTION_12BIT; // 4096 等于满采样率
ZERROR_CHECK(nrf_drv_saadc_init(&adccfg, saadc_callback));
}
void adc_module_battery_channel_init(nrf_saadc_input_t channelpin) {
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(channelpin);
ZERROR_CHECK(nrfx_saadc_channel_init(0, &channel_config));
}
int16_t adc_module_battery_channel_read_val() { return adc_channel_read_val(0); }
void adc_module_heart_elect_channel_init(nrf_saadc_input_t channelpin) {
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(channelpin);
channel_config.acq_time = NRF_SAADC_ACQTIME_40US;
ZERROR_CHECK(nrfx_saadc_channel_init(1, &channel_config));
}
int16_t adc_module_heart_elect_channel_read_val() { return adc_channel_read_val(1); }
/*******************************************************************************
* SPI *
*******************************************************************************/
#define SPI_MISO_PIN 31
#define SPI_SS_PIN 20
#define SPI_SCK_PIN 29
#define SPI_MOSI_PIN 30
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(0); /**< SPI instance. */
// static volatile bool m_spi_translate_done = false;
// static void spi_event_handler(nrf_drv_spi_evt_t const* p_event, void* p_context) { m_spi_translate_done = true; }
void board_spi_init() {
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
spi_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED; // NRF_DRV_SPI_PIN_NOT_USED
spi_config.miso_pin = SPI_MISO_PIN;
spi_config.mosi_pin = SPI_MOSI_PIN;
spi_config.sck_pin = SPI_SCK_PIN;
spi_config.frequency = NRF_DRV_SPI_FREQ_1M;
ZERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, NULL, NULL));
}
ret_code_t board_spi_transfer(uint8_t const* p_tx_buffer, uint8_t tx_buffer_length, uint8_t* p_rx_buffer, uint8_t rx_buffer_length) {
// m_spi_translate_done = false;
ZERROR_CHECK(nrf_drv_spi_transfer(&spi, p_tx_buffer, tx_buffer_length, p_rx_buffer, rx_buffer_length));
// while (!m_spi_translate_done)
// ;
return NRF_SUCCESS;
}
ret_code_t board_spi_transfer_test() {
uint8_t tx_data[] = {0x01, 0x02, 0x03};
uint8_t rx_data[3];
ZERROR_CHECK(board_spi_transfer(tx_data, 3, rx_data, 3));
}
void screen_init() {}
void screen_spi_translate_onebyte() {}
static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0);
static nrf_pwm_values_individual_t m_demo1_seq_values;
void pwm_trigger() {
nrf_drv_pwm_config_t const config0 = {
.output_pins = {11},
.irq_priority = APP_IRQ_PRIORITY_LOWEST,
.base_clock = NRF_PWM_CLK_125kHz,
.count_mode = NRF_PWM_MODE_UP,
.top_value = 10,
.load_mode = NRF_PWM_LOAD_INDIVIDUAL,
.step_mode = NRF_PWM_STEP_AUTO,
};
APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL));
static nrf_pwm_sequence_t const m_demo1_seq = {
.values.p_individual = &m_demo1_seq_values,
.length = NRF_PWM_VALUES_LENGTH(m_demo1_seq_values),
.repeats = 0,
.end_delay = 0,
};
m_demo1_seq_values.channel_0 = 8;
m_demo1_seq_values.channel_1 = 0;
m_demo1_seq_values.channel_2 = 0;
m_demo1_seq_values.channel_3 = 0;
(void)nrf_drv_pwm_simple_playback(&m_pwm0, &m_demo1_seq, 1, NRF_DRV_PWM_FLAG_LOOP);
}
/*******************************************************************************
* I2C *
*******************************************************************************/
#define TWI_SCL_M 30 // I2C SCL引脚
#define TWI_SDA_M 31 // I2C SDA引脚
static const nrf_drv_twi_t m_twi_master = NRF_DRV_TWI_INSTANCE(1);
void board_i2c_init() {
const nrf_drv_twi_config_t config = {
.scl = TWI_SCL_M,
.sda = TWI_SDA_M,
.frequency = NRF_DRV_TWI_FREQ_100K,
.interrupt_priority = APP_IRQ_PRIORITY_HIGH,
.clear_bus_init = false,
};
ZERROR_CHECK(nrf_drv_twi_init(&m_twi_master, &config, NULL, NULL));
nrf_drv_twi_enable(&m_twi_master);
}
void board_i2c_write(uint8_t addr, uint8_t* data, uint8_t len) { nrf_drv_twi_tx(&m_twi_master, addr, data, len, false); }
#define FILE_NAME "NORDIC.TXT"
#define TEST_STRING "SD card example."
// #define SPI_MISO_PIN 31
// #define SPI_SS_PIN 20
// #define SPI_SCK_PIN 29
// #define SPI_MOSI_PIN 30
#define SDC_SCK_PIN 29 ///< SDC serial clock (SCK) pin.
#define SDC_MOSI_PIN 30 ///< SDC serial data in (DI) pin.
#define SDC_MISO_PIN 31 ///< SDC serial data out (DO) pin.
#define SDC_CS_PIN 20 ///< SDC chip select (CS) pin.
NRF_BLOCK_DEV_SDC_DEFINE(m_block_dev_sdc, NRF_BLOCK_DEV_SDC_CONFIG(SDC_SECTOR_SIZE, APP_SDCARD_CONFIG(SDC_MOSI_PIN, SDC_MISO_PIN, SDC_SCK_PIN, SDC_CS_PIN)), NFR_BLOCK_DEV_INFO_CONFIG("Nordic", "SDC", "1.00"));
void fatfs_init() {
// // Initialize FATFS disk I/O interface by providing the block device.
static diskio_blkdev_t drives[] = {DISKIO_BLOCKDEV_CONFIG(NRF_BLOCKDEV_BASE_ADDR(m_block_dev_sdc, block_dev), NULL)};
diskio_blockdev_register(drives, ARRAY_SIZE(drives));
fatfs_test_write();
}
void fatfs_test_write() {
static FATFS fs;
static DIR dir;
static FILINFO fno;
static FIL file;
uint32_t bytes_written;
FRESULT ff_result;
DSTATUS disk_state = STA_NOINIT;
for (uint32_t retries = 3; retries && disk_state; --retries) {
disk_state = disk_initialize(0);
}
if (disk_state) {
NRF_LOG_INFO("Disk initialization failed. %d", disk_state);
return;
}
return;
// NRF_LOG_INFO("Initializing disk 0 (SDC)...");
uint32_t blocks_per_mb = (1024uL * 1024uL) / m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_size;
uint32_t capacity = m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_count / blocks_per_mb;
NRF_LOG_INFO("Capacity: %d MB", capacity);
NRF_LOG_INFO("Mounting volume...");
ff_result = f_mount(&fs, "", 1);
if (ff_result) {
NRF_LOG_INFO("Mount failed.");
return;
}
NRF_LOG_INFO("\r\n Listing directory: /");
ff_result = f_opendir(&dir, "/");
if (ff_result) {
NRF_LOG_INFO("Directory listing failed!");
return;
}
do {
ff_result = f_readdir(&dir, &fno);
if (ff_result != FR_OK) {
NRF_LOG_INFO("Directory read failed.");
return;
}
if (fno.fname[0]) {
if (fno.fattrib & AM_DIR) {
NRF_LOG_RAW_INFO(" <DIR> %s", (uint32_t)fno.fname);
} else {
NRF_LOG_RAW_INFO("%9lu %s", fno.fsize, (uint32_t)fno.fname);
}
}
} while (fno.fname[0]);
NRF_LOG_RAW_INFO("");
NRF_LOG_INFO("Writing to file " FILE_NAME "...");
ff_result = f_open(&file, FILE_NAME, FA_READ | FA_WRITE | FA_OPEN_APPEND);
if (ff_result != FR_OK) {
NRF_LOG_INFO("Unable to open or create file: " FILE_NAME ".");
return;
}
ff_result = f_write(&file, TEST_STRING, sizeof(TEST_STRING) - 1, (UINT*)&bytes_written);
if (ff_result != FR_OK) {
NRF_LOG_INFO("Write failed\r\n.");
} else {
NRF_LOG_INFO("%d bytes written.", bytes_written);
}
(void)f_close(&file);
return;
}
nrf_drv_wdt_channel_id m_channel_id;
void wd_init() {
// WDT_CONFIG_RELOAD_VALUE 修改这个数值修改喂狗周期,单位ms
nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG;
config.reload_value = WDT_CONFIG_RELOAD_VALUE;
ret_code_t err_code = nrf_drv_wdt_init(&config, NULL);
ZERROR_CHECK(err_code);
err_code = nrf_drv_wdt_channel_alloc(&m_channel_id);
ZERROR_CHECK(err_code);
nrf_drv_wdt_enable();
}
void wd_feed() { nrfx_wdt_feed(); }