Multimodal-CV-FW-USB-ADS1298R/main.c

282 lines
8.3 KiB
C

// What I want is to be able to send logs ONLY in log mode, so I need to keep a buffer of strings
// String logs[64], pointing to different strings.
// I just fucking hate strlen for this kind of thing
// If only there's a way to precompute string lengths.
// Nordic drivers and application code:
#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 ****
#include "ads1298.h"
/**
* @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;
}
}
ads1298_info_t m_info;
static ble_exg_t m_exg;
// Global Data:
// Unfortunately I need to precompute these strlens manually :skull-emoji:
// String hello_string = {21, "Hello, I am a string\n"};
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;
}
int main(void) {
ret_code_t ret;
static const app_usbd_config_t usbd_config = {
.ev_state_proc = usbd_user_ev_handler
};
// #TODO: remove logging maybe?
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));
// TODO#: ads1298_init_gpio().
// TODO#: Push logs over USB.
JIIM_LOG("Hello, I am a string2");
JIIM_LOG("Hello, I am a string2");
JIIM_LOG("Hello, I am a string2");
JIIM_LOG("Hello, I am a string2");
JIIM_LOG("Hello, I am a string2");
JIIM_LOG("Hello, I am a string2");
// String hello_string = Create_String("Hello, I am a string2\n");
// add_to_log_buffer(hello_string);
// add_to_log_buffer(hello_string);
// add_to_log_buffer(hello_string);
ads1298_initialize(&m_exg, &m_info);
if (m_info.nChs > 0) {
// #TODO: replace with sprintf()...
JIIM_LOG("Number of channels available: %d", m_info.nChs);
} else {
JIIM_LOG("ERROR: ADS129x NOT DETECTED!");
}
//memset(m_tx_buffer, 0x41/*"A"*/, NRF_DRV_USBD_EPSIZE);
//size_t size = NRF_DRV_USBD_EPSIZE;
//s32 count = 0;
while (true) {
while (app_usbd_event_queue_process()) {/* Nothing to do */}
if (m_send_flag) {
}
if (m_send_logs) {
// 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;
Send_USB_Logs();
}
UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
/* Sleep CPU only if there was no interrupt since last loop processing */
__WFE();
}
}
/** @} */