332 lines
9.5 KiB
C
332 lines
9.5 KiB
C
// Nordic drivers and application code:
|
|
// Note: see throughput testing in musa_usbd_cdc_acm
|
|
|
|
#include "nrf.h"
|
|
#include "nrf_drv_usbd.h"
|
|
#include "nrf_drv_clock.h"
|
|
#include "nrf_gpio.h"
|
|
#include "nrf_delay.h"
|
|
#include "nrf_drv_power.h"
|
|
|
|
#include "app_error.h"
|
|
#include "app_util.h"
|
|
#include "app_usbd_core.h"
|
|
#include "app_usbd.h"
|
|
#include "app_usbd_string_desc.h"
|
|
#include "app_usbd_cdc_acm.h"
|
|
#include "app_usbd_serial_num.h"
|
|
|
|
#include "app_timer.h"
|
|
|
|
#include "nrf_log.h"
|
|
#include "nrf_log_ctrl.h"
|
|
#include "nrf_log_default_backends.h"
|
|
|
|
// **** jiim base code ****
|
|
#include "base/types.h"
|
|
#include "base/usb_logging.h"
|
|
|
|
// **** Sensor driver APIs ****
|
|
#define ADS1298 0
|
|
#define ADS1292 0
|
|
|
|
#if ADS1298
|
|
#include "ads1298.h"
|
|
#include "nrf_gpio.h"
|
|
#include "nrf_drv_gpiote.h"
|
|
#endif
|
|
|
|
#if ADS1292
|
|
#include "ads1292.c"
|
|
#endif
|
|
|
|
/**
|
|
* @brief Enable power USB detection
|
|
*
|
|
* Configure if example supports USB port connection
|
|
*/
|
|
#ifndef USBD_POWER_DETECTION
|
|
#define USBD_POWER_DETECTION true
|
|
#endif
|
|
|
|
|
|
static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
|
|
app_usbd_cdc_acm_user_event_t event);
|
|
|
|
#define CDC_ACM_COMM_INTERFACE 0
|
|
#define CDC_ACM_COMM_EPIN NRF_DRV_USBD_EPIN2
|
|
|
|
#define CDC_ACM_DATA_INTERFACE 1
|
|
#define CDC_ACM_DATA_EPIN NRF_DRV_USBD_EPIN1
|
|
#define CDC_ACM_DATA_EPOUT NRF_DRV_USBD_EPOUT1
|
|
|
|
|
|
/**
|
|
* @brief CDC_ACM class instance
|
|
* */
|
|
APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
|
|
cdc_acm_user_ev_handler,
|
|
CDC_ACM_COMM_INTERFACE,
|
|
CDC_ACM_DATA_INTERFACE,
|
|
CDC_ACM_COMM_EPIN,
|
|
CDC_ACM_DATA_EPIN,
|
|
CDC_ACM_DATA_EPOUT,
|
|
APP_USBD_CDC_COMM_PROTOCOL_AT_V250);
|
|
|
|
#define READ_SIZE 1
|
|
|
|
static char m_rx_buffer[READ_SIZE];
|
|
static char m_tx_buffer[NRF_DRV_USBD_EPSIZE];
|
|
static bool m_send_flag = 0;
|
|
|
|
/**
|
|
* @brief User event handler @ref app_usbd_cdc_acm_user_ev_handler_t (headphones)
|
|
* */
|
|
static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
|
|
app_usbd_cdc_acm_user_event_t event) {
|
|
app_usbd_cdc_acm_t const * p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);
|
|
|
|
switch (event) {
|
|
case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN: {
|
|
/*Setup first transfer*/
|
|
ret_code_t ret = app_usbd_cdc_acm_read(&m_app_cdc_acm,
|
|
m_rx_buffer,
|
|
READ_SIZE);
|
|
UNUSED_VARIABLE(ret);
|
|
break;
|
|
}
|
|
case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
|
|
break;
|
|
case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
|
|
tx_complete = true;
|
|
if (m_send_logs && full_tx_complete) { reset_log_buffer(); }
|
|
break;
|
|
case APP_USBD_CDC_ACM_USER_EVT_RX_DONE: {
|
|
ret_code_t ret;
|
|
NRF_LOG_INFO("Bytes waiting: %d", app_usbd_cdc_acm_bytes_stored(p_cdc_acm));
|
|
do {
|
|
/*Get amount of data transfered*/
|
|
size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm);
|
|
NRF_LOG_INFO("RX: size: %lu char: %c", size, m_rx_buffer[0]);
|
|
|
|
if (m_rx_buffer[0] == 0) {
|
|
m_send_flag = false;
|
|
m_send_logs = false;
|
|
}
|
|
if (m_rx_buffer[0] == 1) {
|
|
m_send_flag = true;
|
|
}
|
|
if (m_rx_buffer[0] == 2) {
|
|
m_send_logs = true;
|
|
}
|
|
|
|
/* Fetch data until internal buffer is empty */
|
|
ret = app_usbd_cdc_acm_read(&m_app_cdc_acm,
|
|
m_rx_buffer,
|
|
READ_SIZE);
|
|
} while (ret == NRF_SUCCESS);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void usbd_user_ev_handler(app_usbd_event_type_t event) {
|
|
switch (event) {
|
|
case APP_USBD_EVT_DRV_SUSPEND:
|
|
break;
|
|
case APP_USBD_EVT_DRV_RESUME:
|
|
break;
|
|
case APP_USBD_EVT_STARTED:
|
|
break;
|
|
case APP_USBD_EVT_STOPPED:
|
|
app_usbd_disable();
|
|
break;
|
|
case APP_USBD_EVT_POWER_DETECTED:
|
|
NRF_LOG_INFO("USB power detected");
|
|
|
|
if (!nrf_drv_usbd_is_enabled()) {
|
|
app_usbd_enable();
|
|
}
|
|
break;
|
|
case APP_USBD_EVT_POWER_REMOVED:
|
|
NRF_LOG_INFO("USB power removed");
|
|
app_usbd_stop();
|
|
break;
|
|
case APP_USBD_EVT_POWER_READY:
|
|
NRF_LOG_INFO("USB ready");
|
|
app_usbd_start();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Send_USB_Logs(void) {
|
|
if (!tx_complete) return;
|
|
// We should check that the USB data is
|
|
s32 bytes_remaining = m_log_usage - m_log_buffer_send_index;
|
|
if (bytes_remaining <= 0) {
|
|
full_tx_complete = true;
|
|
return;
|
|
}
|
|
|
|
app_usbd_cdc_acm_write(&m_app_cdc_acm, &log_buffer[m_log_buffer_send_index], 64);
|
|
m_log_buffer_send_index += 64;
|
|
tx_complete = false;
|
|
}
|
|
|
|
#if ADS1298 || ADS1292
|
|
void drdy_pin_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
|
|
UNUSED_PARAMETER(pin);
|
|
UNUSED_PARAMETER(action);
|
|
JIIM_LOG("drdy!");
|
|
// drdy_flag = true;
|
|
}
|
|
#endif
|
|
|
|
#if ADS1298
|
|
ads1298_info_t m_info;
|
|
|
|
void ads1298_init_gpio(void) {
|
|
nrf_gpio_cfg_output(ADS1298_PWDN_PIN);
|
|
nrf_gpio_pin_clear(ADS1298_PWDN_PIN);
|
|
nrf_gpio_cfg_input(ADS1298_DRDY_PIN, NRF_GPIO_PIN_PULLUP);
|
|
// Initialize GPIOTE:
|
|
ret_code_t err_code = NRF_SUCCESS;
|
|
if (!nrf_drv_gpiote_is_init())
|
|
{
|
|
err_code = nrf_drv_gpiote_init();
|
|
}
|
|
JIIM_LOG("GPIOTE error code: %d", err_code);
|
|
APP_ERROR_CHECK(err_code);
|
|
nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
|
|
in_config.is_watcher = true;
|
|
in_config.pull = NRF_GPIO_PIN_NOPULL;
|
|
err_code = nrf_drv_gpiote_in_init(ADS1298_DRDY_PIN, &in_config, drdy_pin_handler);
|
|
APP_ERROR_CHECK(err_code);
|
|
nrf_drv_gpiote_in_event_enable(ADS1298_DRDY_PIN, true);
|
|
ads1298_power_down();
|
|
}
|
|
#endif
|
|
|
|
#if ADS1292
|
|
ads129x_info_t m_info;
|
|
|
|
void ads1292_interrupt_setup(void) {
|
|
nrf_gpio_cfg_output(ADS1292_PWDN_PIN);
|
|
nrf_gpio_pin_clear(ADS1292_PWDN_PIN); // Powers down the ADS1292
|
|
nrf_gpio_cfg_input(ADS1292_DRDY_PIN, NRF_GPIO_PIN_PULLUP);
|
|
// Initialize GPIOTE:
|
|
ret_code_t err_code = NRF_SUCCESS;
|
|
if (!nrf_drv_gpiote_is_init()) {
|
|
err_code = nrf_drv_gpiote_init();
|
|
}
|
|
NRF_LOG_INFO("GPIOTE error code: %d", err_code);
|
|
APP_ERROR_CHECK(err_code);
|
|
nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
|
|
in_config.is_watcher = true;
|
|
in_config.pull = NRF_GPIO_PIN_NOPULL;
|
|
err_code = nrf_drv_gpiote_in_init(ADS1292_DRDY_PIN, &in_config, drdy_pin_handler);
|
|
APP_ERROR_CHECK(err_code);
|
|
nrf_drv_gpiote_in_event_enable(ADS1292_DRDY_PIN, true);
|
|
ads1292_power_down();
|
|
}
|
|
#endif
|
|
|
|
int main(void) {
|
|
ret_code_t ret;
|
|
static const app_usbd_config_t usbd_config = {
|
|
.ev_state_proc = usbd_user_ev_handler
|
|
};
|
|
|
|
ret = NRF_LOG_INIT(NULL);
|
|
APP_ERROR_CHECK(ret);
|
|
|
|
ret = nrf_drv_clock_init();
|
|
APP_ERROR_CHECK(ret);
|
|
|
|
nrf_drv_clock_lfclk_request(NULL);
|
|
|
|
// Wait for LFCLK to init.
|
|
while(!nrf_drv_clock_lfclk_is_running()) { }
|
|
|
|
ret = app_timer_init();
|
|
APP_ERROR_CHECK(ret);
|
|
|
|
app_usbd_serial_num_generate();
|
|
|
|
ret = app_usbd_init(&usbd_config);
|
|
APP_ERROR_CHECK(ret);
|
|
// NRF_LOG_INFO("USBD CDC ACM example started.");
|
|
|
|
app_usbd_class_inst_t const * class_cdc_acm = app_usbd_cdc_acm_class_inst_get(&m_app_cdc_acm);
|
|
ret = app_usbd_class_append(class_cdc_acm);
|
|
APP_ERROR_CHECK(ret);
|
|
|
|
if (USBD_POWER_DETECTION) {
|
|
ret = app_usbd_power_events_enable();
|
|
APP_ERROR_CHECK(ret);
|
|
} else {
|
|
JIIM_LOG("No USB power detection enabled\r\nStarting USB now");
|
|
|
|
app_usbd_enable();
|
|
app_usbd_start();
|
|
}
|
|
// Throughput testing:
|
|
reset_log_buffer(); // initialize log buffer with `A`
|
|
JIIM_LOG("Hello world!");
|
|
JIIM_LOG("HELLO WORLD %d FORMATTED", 2);
|
|
JIIM_LOG("sizeof(log_buffer): %d", sizeof(log_buffer));
|
|
|
|
JIIM_LOG("Hello, I am a string2");
|
|
|
|
#if ADS1292
|
|
ads1292_interrupt_setup();
|
|
|
|
ads1292_initialize(&m_info);
|
|
#endif
|
|
#if ADS1298
|
|
ads1298_init_gpio();
|
|
|
|
memset(&m_info, 0, sizeof(ads1298_info_t));
|
|
ads1298_initialize(&m_info);
|
|
#endif
|
|
|
|
#if ADS1292 || ADS1298
|
|
if (m_info.nChs > 0) {
|
|
JIIM_LOG("Number of channels available: %d", m_info.nChs);
|
|
} else {
|
|
JIIM_LOG("ERROR: ADS129x NOT DETECTED!");
|
|
}
|
|
#endif
|
|
|
|
while (true) {
|
|
while (app_usbd_event_queue_process()) {/* Nothing to do */}
|
|
|
|
//if (m_send_flag) {
|
|
// static int frame_counter;
|
|
|
|
// size_t size = sprintf(m_tx_buffer, "Hello USB CDC FA demo: %u\r\n", frame_counter);
|
|
|
|
// ret = app_usbd_cdc_acm_write(&m_app_cdc_acm, m_tx_buffer, size);
|
|
// if (ret == NRF_SUCCESS) { ++frame_counter; }
|
|
|
|
// app_usbd_cdc_acm_write(&m_app_cdc_acm, m_tx_buffer, size);
|
|
// send_usb_log(hello_string);
|
|
//log_usb("TestTestTest");
|
|
// count += 1;
|
|
//}
|
|
|
|
if (m_send_logs) { Send_USB_Logs(); }
|
|
|
|
UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
|
|
/* Sleep CPU only if there was no interrupt since last loop processing */
|
|
__WFE();
|
|
}
|
|
}
|
|
|
|
/** @} */
|