#include "board.h" #include "app_timer.h" #include "nrf_gpio.h" #include "sys.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("