My PC is windows 7 64-bit. I use SDK16 with softdevice. I am porting CDC code to my application as follows. It has 2 issues. 1st: It will cause hardfault if I call the function of displayMainScreen in main function. (Just power on step). It will work fine if I remove displayMainScreen function in main function. If I send 5120 bytes from PC to nrf52840 and programming the data (5120 bytes) to my device, it is success. But I want to send 5120 bytes from PC to nrf52840 again. It will cause hardfault. 2nd: I cannot see the UART port if I open TeraTerm first (UART Rx/Tx application at PC) then power on the nrf52840. I can see the UART port if I open power on nrf52840 first then run the application of TeraTerm. How to solve these issues? Does Anyone can help me?
#define NRFX_USBD_EPSIZE 64
#define NRF_DRV_USBD_EPSIZE NRFX_USBD_EPSIZE
uint8_t m_tx_buffer[NRF_DRV_USBD_EPSIZE];
#define SEND_UART_STRING(a) \
do { \
size_t b = strlen((char*)m_tx_buffer); \
sysg_send_uart_string_to_device(a, b); \
}while(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:
{
//bsp_board_led_on(LED_CDC_ACM_OPEN);
NRF_LOG_INFO("APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN");
sysgApp_task.uart_connected = true;
/*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:
//bsp_board_led_off(LED_CDC_ACM_OPEN);
NRF_LOG_INFO("APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE");
sysgApp_task.uart_connected = false;
break;
case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
//bsp_board_led_invert(LED_CDC_ACM_TX);
NRF_LOG_INFO("APP_USBD_CDC_ACM_USER_EVT_TX_DONE");
break;
case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
{
NRF_LOG_INFO("APP_USBD_CDC_ACM_USER_EVT_RX_DONE");
ret_code_t ret;
do
{
uart_data_parse(m_rx_buffer[0]);
/* Fetch data until internal buffer is empty */
ret = app_usbd_cdc_acm_read(&m_app_cdc_acm, m_rx_buffer, 1);
} while (ret == NRF_SUCCESS);
break;
}
default:
break;
}
}
void displayMainScreen(void)
{
sprintf((char*)m_tx_buffer, "\033[2J"); //clear screen
SEND_UART_STRING(m_tx_buffer);
sprintf((char*)m_tx_buffer, "\033[H"); //move the cursor to home position
SEND_UART_STRING(m_tx_buffer);
sprintf((char*)m_tx_buffer, "MKW01 TPMS OTA Testing v%d.%02d \r\n", FW_VER_MAJOR, FW_VER_MINOR);
SEND_UART_STRING(m_tx_buffer);
sprintf((char*)m_tx_buffer, "Options: %3dMHz, Try %2d, flash size: 0x%4x, erase: 0xD400, LFID: 0x%4x\r\n"
,CARRIER_FREQ, TRY_TIMES, DEST_CODE_SIZE-4, LF_WAKEUP_ID_APP);
SEND_UART_STRING(m_tx_buffer);
sprintf((char*)m_tx_buffer, "entry_key: (%c%c%c%c%c%c%c%c%c%c) %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n",
BootEntryKey[4], BootEntryKey[5], BootEntryKey[6], BootEntryKey[7], BootEntryKey[8],
BootEntryKey[9], BootEntryKey[10],BootEntryKey[11],BootEntryKey[12],BootEntryKey[13],
BootEntryKey[4], BootEntryKey[5], BootEntryKey[6], BootEntryKey[7], BootEntryKey[8],
BootEntryKey[9], BootEntryKey[10],BootEntryKey[11],BootEntryKey[12],BootEntryKey[13]);
SEND_UART_STRING(m_tx_buffer);
sprintf((char*)m_tx_buffer, "TPMSID: 0xFF 0xFF 0xFF 0xFF\r\n");
SEND_UART_STRING(m_tx_buffer);
sprintf((char*)m_tx_buffer, ">>Press SW1 for FLASH PROGRAM command\r\n");
SEND_UART_STRING(m_tx_buffer);
sprintf((char*)m_tx_buffer, ">>Press SW2 for ERASE FLASH command\r\n");
SEND_UART_STRING(m_tx_buffer);
sprintf((char*)m_tx_buffer, "Please upload firmware(binary format) to kw01\r\n");
SEND_UART_STRING(m_tx_buffer);
}
void sysg_send_uart_string_to_device(uint8_t* pdata, uint8_t len)
{
ret_code_t ret;
if(sysgApp_task.system_setting.usb_mode == OUTPUT_USB)
{
if(sysgApp_task.uart_connected)
{
do {
ret = app_usbd_cdc_acm_write(&m_app_cdc_acm, pdata, len);
} while(ret == NRF_ERROR_BUSY);
}
}
}
int main(void)
{
...
displayMainScreen();
....
}