#include "nrf_drv_spi.h" #include "nrf_drv_twi.h" #include "nrf_gpio.h" #include "nrf_log.h" #include "FreeRTOS.h" #include "queue.h" #include "semphr.h" #include "edc20_pin_ctrl.h" //========================================================== // gpio //========================================================== void gpio_init(void) { nrf_gpio_pin_set(POWER_5V_EN_PIN); nrf_gpio_pin_set(POWER_12V_EN_PIN); nrf_gpio_pin_set(CS_SW_PIN); nrf_gpio_pin_set(CS_MEM_PIN); nrf_gpio_pin_set(CS_ADC_PIN); nrf_gpio_pin_set(CS_DAC_PIN); nrf_gpio_pin_set(OFF_PIN); nrf_gpio_pin_clear(Vout_FB_PIN); nrf_gpio_pin_clear(Vout_IN_PIN); nrf_gpio_pin_clear(Iin4_TEST_PIN); nrf_gpio_pin_clear(Iin3_SEL_PIN); nrf_gpio_pin_clear(Iin3_PIN); nrf_gpio_pin_clear(Iin2_PIN); nrf_gpio_pin_clear(Iin1_PIN); nrf_gpio_pin_clear(Vin2_PIN); nrf_gpio_pin_clear(Vin1_PIN); nrf_gpio_pin_clear(CV_CTRL_PIN); nrf_gpio_pin_clear(ADCA2_PIN); nrf_gpio_pin_clear(ADCA1_PIN); nrf_gpio_pin_clear(ADCA0_PIN); nrf_gpio_pin_clear(RST_SW_PIN); nrf_gpio_cfg_output(POWER_5V_EN_PIN); nrf_gpio_cfg_output(POWER_12V_EN_PIN); nrf_gpio_cfg_output(OFF_PIN); nrf_gpio_cfg_output(Vout_FB_PIN); nrf_gpio_cfg_output(Vout_IN_PIN); nrf_gpio_cfg_output(Iin4_TEST_PIN); nrf_gpio_cfg_output(Iin3_SEL_PIN); nrf_gpio_cfg_output(Iin3_PIN); nrf_gpio_cfg_output(Iin2_PIN); nrf_gpio_cfg_output(Iin1_PIN); nrf_gpio_cfg_output(Vin2_PIN); nrf_gpio_cfg_output(Vin1_PIN); nrf_gpio_cfg_output(CV_CTRL_PIN); nrf_gpio_cfg_output(ADCA2_PIN); nrf_gpio_cfg_output(ADCA1_PIN); nrf_gpio_cfg_output(ADCA0_PIN); nrf_gpio_cfg_output(RST_SW_PIN); nrf_gpio_cfg_output(CS_SW_PIN); nrf_gpio_cfg_output(CS_MEM_PIN); nrf_gpio_cfg_output(CS_ADC_PIN); nrf_gpio_cfg_output(CS_DAC_PIN); nrf_gpio_cfg_input(VBAT_PIN, NRF_GPIO_PIN_NOPULL); nrf_gpio_cfg_input(SHUT_DOWN_PIN, NRF_GPIO_PIN_NOPULL); nrf_gpio_cfg_input(INT9466_PIN, NRF_GPIO_PIN_NOPULL); } //========================================================== // i2c //========================================================== static const nrf_drv_twi_t twi0 = NRF_DRV_TWI_INSTANCE(0); static SemaphoreHandle_t i2c_sem = NULL; static SemaphoreHandle_t i2c_mutex = NULL; static QueueHandle_t i2c_evt_queue = NULL; static void nrf_drv_twi_evt_handler(nrf_drv_twi_evt_t const *p_event, void *p_context) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; xQueueSendFromISR(i2c_evt_queue, p_event, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } void twi_init(void) { ret_code_t err_code; i2c_sem = xSemaphoreCreateBinary(); i2c_mutex = xSemaphoreCreateMutex(); i2c_evt_queue = xQueueCreate(2, sizeof(nrf_drv_twi_evt_t)); const nrf_drv_twi_config_t twi0_config = { .scl = I2C0_SCL, .sda = I2C0_SDA, .frequency = NRF_DRV_TWI_FREQ_100K, .interrupt_priority = APP_IRQ_PRIORITY_HIGH, .clear_bus_init = true }; err_code = nrf_drv_twi_init(&twi0, &twi0_config, nrf_drv_twi_evt_handler, NULL); APP_ERROR_CHECK(err_code); nrf_drv_twi_enable(&twi0); } void twi0_write_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t data_len) { xSemaphoreTake(i2c_mutex, portMAX_DELAY); static uint8_t i2c_buf[255]; static nrf_drv_twi_evt_t evt; ret_code_t err_code; memcpy(i2c_buf, ®_addr, sizeof(reg_addr)); memcpy(i2c_buf + sizeof(reg_addr), data, data_len); err_code = nrf_drv_twi_tx(&twi0, slave_addr, i2c_buf, data_len + 1, false); APP_ERROR_CHECK(err_code); xQueueReceive(i2c_evt_queue, &evt, portMAX_DELAY); switch (evt.type) { /* Transfer completed event. */ case NRF_DRV_TWI_EVT_DONE: // TODO... break; /* Error event: NACK received after sending the address. */ case NRF_DRV_TWI_EVT_ADDRESS_NACK: // TODO... __BKPT(255); break; /* Error event: NACK received after sending a data byte. */ case NRF_DRV_TWI_EVT_DATA_NACK: // TODO... __BKPT(255); break; default: __BKPT(255); break; } xSemaphoreGive(i2c_mutex); NRF_LOG_INFO("i2c(W): slave_addr=0x%02x", slave_addr); NRF_LOG_HEXDUMP_INFO(i2c_buf, data_len + 1); } void twi0_read_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *p_rx_buf, uint8_t rx_buffer_length) { xSemaphoreTake(i2c_mutex, portMAX_DELAY); nrf_drv_twi_evt_t evt; ret_code_t err_code; err_code = nrf_drv_twi_tx(&twi0, slave_addr, ®_addr, sizeof(reg_addr), false); APP_ERROR_CHECK(err_code); xQueueReceive(i2c_evt_queue, &evt, portMAX_DELAY); switch (evt.type) { /* Transfer completed event. */ case NRF_DRV_TWI_EVT_DONE: // TODO... break; /* Error event: NACK received after sending the address. */ case NRF_DRV_TWI_EVT_ADDRESS_NACK: // TODO... __BKPT(255); break; /* Error event: NACK received after sending a data byte. */ case NRF_DRV_TWI_EVT_DATA_NACK: // TODO... __BKPT(255); break; default: break; } err_code = nrf_drv_twi_rx(&twi0, slave_addr, p_rx_buf, rx_buffer_length); APP_ERROR_CHECK(err_code); xQueueReceive(i2c_evt_queue, &evt, portMAX_DELAY); switch (evt.type) { /* Transfer completed event. */ case NRF_DRV_TWI_EVT_DONE: // TODO... break; /* Error event: NACK received after sending the address. */ case NRF_DRV_TWI_EVT_ADDRESS_NACK: // TODO... __BKPT(255); break; /* Error event: NACK received after sending a data byte. */ case NRF_DRV_TWI_EVT_DATA_NACK: // TODO... __BKPT(255); break; default: break; } xSemaphoreGive(i2c_mutex); NRF_LOG_INFO("i2c(R): slave_addr=0x%02x reg_addr=0x%02x", slave_addr, reg_addr); NRF_LOG_HEXDUMP_INFO(p_rx_buf, rx_buffer_length); } //========================================================== // spi //========================================================== static const nrf_drv_spi_t spim1 = NRF_DRV_SPI_INSTANCE(1); /**< SPI instance. */ static const nrf_drv_spi_t spim2 = NRF_DRV_SPI_INSTANCE(2); /**< SPI instance. */ static SemaphoreHandle_t spim1_sem = NULL; static SemaphoreHandle_t spim2_sem = NULL; static SemaphoreHandle_t spim2_mutex = NULL; static void nrf_drv_spim1_evt_handler(nrf_drv_spi_evt_t const *p_event, void *p_context) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; switch (p_event->type) { case NRF_DRV_SPI_EVENT_DONE: xSemaphoreGiveFromISR(spim1_sem, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); break; default: break; } } static void nrf_drv_spim2_evt_handler(nrf_drv_spi_evt_t const *p_event, void *p_context) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; switch (p_event->type) { case NRF_DRV_SPI_EVENT_DONE: xSemaphoreGiveFromISR(spim2_sem, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); break; default: break; } } void spi_init(void) { spim1_sem = xSemaphoreCreateBinary(); spim2_sem = xSemaphoreCreateBinary(); spim2_mutex = xSemaphoreCreateMutex(); nrf_drv_spi_config_t spi1_config = NRF_DRV_SPI_DEFAULT_CONFIG; spi1_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED; spi1_config.miso_pin = NRF_DRV_SPI_PIN_NOT_USED; spi1_config.mosi_pin = SPI1_MOSI_PIN; spi1_config.sck_pin = SPI1_CLK_PIN; spi1_config.mode = NRF_DRV_SPI_MODE_0; spi1_config.frequency = NRF_DRV_SPI_FREQ_8M; APP_ERROR_CHECK(nrf_drv_spi_init(&spim1, &spi1_config, nrf_drv_spim1_evt_handler, NULL)); nrf_drv_spi_config_t spi2_config = NRF_DRV_SPI_DEFAULT_CONFIG; spi2_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED; spi2_config.miso_pin = SPI2_MISO_PIN; spi2_config.mosi_pin = SPI2_MOSI_PIN; spi2_config.sck_pin = SPI2_CLK_PIN; spi2_config.mode = NRF_DRV_SPI_MODE_0; spi2_config.frequency = NRF_DRV_SPI_FREQ_8M; APP_ERROR_CHECK(nrf_drv_spi_init(&spim2, &spi2_config, nrf_drv_spim2_evt_handler, NULL)); } void spi1_write(uint8_t *p_tx_buffer, uint8_t tx_buffer_length) { APP_ERROR_CHECK(nrf_drv_spi_transfer(&spim1, p_tx_buffer, tx_buffer_length, NULL, 0)); xSemaphoreTake(spim1_sem, portMAX_DELAY); } void spi2_write(uint32_t cs_pin, uint8_t *p_tx_buffer, uint8_t tx_buffer_length, uint8_t *p_rx_buf, uint8_t rx_buffer_length) { xSemaphoreTake(spim2_mutex, portMAX_DELAY); nrf_gpio_pin_clear(cs_pin); APP_ERROR_CHECK(nrf_drv_spi_transfer(&spim2, p_tx_buffer, tx_buffer_length, p_rx_buf, rx_buffer_length)); if (xSemaphoreTake(spim2_sem, pdMS_TO_TICKS(100)) == pdFALSE) { // TODO... spi transfer timeout. } nrf_gpio_pin_set(cs_pin); xSemaphoreGive(spim2_mutex); NRF_LOG_INFO("spi2(W) cs_pin(%d)", cs_pin); NRF_LOG_HEXDUMP_INFO(p_tx_buffer, tx_buffer_length); if (rx_buffer_length > 0) { NRF_LOG_INFO("spi(R)"); NRF_LOG_HEXDUMP_INFO(p_rx_buf, rx_buffer_length); } }