Hi Experts,
I use TIMER_1 and PPI to driver a 'H' style bridge for our motor. Unexpected system reset will happen if I trigger the 'H' bridge PWM with ble connected. It works fine if ble is not connected. Seems there is something conflicted between ble and pwm (ppi, or timer)? Blow is my motor driver code:
motor_conf m_conf[3] = { { 50, 100, 159, 200}, // 15: 8 { 75, 100, 175, 200}, // 15: 8 { 25, 100, 125, 200}, // 15: 8 };
static motor_mode m_mode = IDLE;
__STATIC_INLINE void mode_set(int level) { NRF_TIMER1->CC[0] = m_conf[level].l_en; NRF_TIMER1->CC[1] = m_conf[level].l_dis; NRF_TIMER1->CC[2] = m_conf[level].r_en; NRF_TIMER1->CC[3] = m_conf[level].r_dis; }
static void timer1_cc01_init(void) {
uint32_t crystal_is_running = 0;
sd_clock_hfclk_request();
while(!crystal_is_running){
sd_clock_hfclk_is_running(&crystal_is_running);
}
NRF_TIMER1->MODE =TIMER_MODE_MODE_Timer; NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit<<TIMER_BITMODE_BITMODE_Pos; NRF_TIMER1->PRESCALER = 8; NRF_TIMER1->TASKS_CLEAR = 1; mode_set(MOTOR_LOW); NRF_TIMER1->SHORTS=(TIMER_SHORTS_COMPARE3_CLEAR_Enabled<<TIMER_SHORTS_COMPARE3_CLEAR_Pos);
}
static void ppi_init(void) { nrf_ppi_channel_t ppi_ch[8]; ret_code_t err_code;
nrf_drv_ppi_init();
/* PPI setup: */ for (uint8_t i = 0; i < 8; ++i) { err_code = nrf_drv_ppi_channel_alloc(&ppi_ch[i]); if (err_code != NRF_SUCCESS) { goto error; // Resource deallocation is done by callee. } nrf_drv_ppi_channel_disable(ppi_ch[i]); }
nrf_drv_ppi_channel_assign(ppi_ch[0], (uint32_t)&NRF_TIMER1->EVENTS_COMPARE[0], nrf_drv_gpiote_out_task_addr_get(M1)); nrf_drv_ppi_channel_assign(ppi_ch[1], (uint32_t)&NRF_TIMER1->EVENTS_COMPARE[0], nrf_drv_gpiote_out_task_addr_get(M4)); nrf_drv_ppi_channel_assign(ppi_ch[2], (uint32_t)&NRF_TIMER1->EVENTS_COMPARE[1], nrf_drv_gpiote_out_task_addr_get(M1)); nrf_drv_ppi_channel_assign(ppi_ch[3], (uint32_t)&NRF_TIMER1->EVENTS_COMPARE[1], nrf_drv_gpiote_out_task_addr_get(M4));
nrf_drv_ppi_channel_assign(ppi_ch[4],
(uint32_t)&NRF_TIMER1->EVENTS_COMPARE[2],
nrf_drv_gpiote_out_task_addr_get(M3));
nrf_drv_ppi_channel_assign(ppi_ch[5],
(uint32_t)&NRF_TIMER1->EVENTS_COMPARE[2],
nrf_drv_gpiote_out_task_addr_get(M2));
nrf_drv_ppi_channel_assign(ppi_ch[6],
(uint32_t)&NRF_TIMER1->EVENTS_COMPARE[3],
nrf_drv_gpiote_out_task_addr_get(M3));
nrf_drv_ppi_channel_assign(ppi_ch[7],
(uint32_t)&NRF_TIMER1->EVENTS_COMPARE[3],
nrf_drv_gpiote_out_task_addr_get(M2));
for (uint8_t i = 0; i < 8; ++i) { nrf_drv_ppi_channel_enable(ppi_ch[i]); }
error: APP_ERROR_CHECK(err_code); }
static void gpiote_init(void) { ret_code_t err_code; nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(NRF_GPIOTE_INITIAL_VALUE_HIGH);
err_code = nrf_drv_gpiote_out_init(M1, &out_config); APP_ERROR_CHECK(err_code); err_code = nrf_drv_gpiote_out_init(M3, &out_config); APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_out_config_t low_config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(NRF_GPIOTE_INITIAL_VALUE_LOW);
err_code = nrf_drv_gpiote_out_init(M2, &low_config); APP_ERROR_CHECK(err_code); err_code = nrf_drv_gpiote_out_init(M4, &low_config); APP_ERROR_CHECK(err_code); }
void motor_stop(void) { NRF_TIMER1->TASKS_CLEAR = 1; *(uint32_t *)0x40009C0C = 0; NRF_TIMER1->TASKS_STOP = 1;
nrf_drv_gpiote_out_task_force(M1, NRF_GPIOTE_INITIAL_VALUE_HIGH);
nrf_drv_gpiote_out_task_force(M3, NRF_GPIOTE_INITIAL_VALUE_HIGH);
nrf_drv_gpiote_out_task_force(M2, NRF_GPIOTE_INITIAL_VALUE_LOW);
nrf_drv_gpiote_out_task_force(M4, NRF_GPIOTE_INITIAL_VALUE_LOW);
nrf_drv_gpiote_out_task_disable(M1);
nrf_drv_gpiote_out_task_disable(M3);
nrf_drv_gpiote_out_task_disable(M2);
nrf_drv_gpiote_out_task_disable(M4);
m_motor_left = true; m_mode = IDLE; }
void motor_tune(motor_mode level) { m_motor_left = true; *(uint32_t *)0x40009C0C = 0;
nrf_drv_gpiote_out_task_force(M1, NRF_GPIOTE_INITIAL_VALUE_HIGH);
nrf_drv_gpiote_out_task_force(M3, NRF_GPIOTE_INITIAL_VALUE_HIGH);
nrf_drv_gpiote_out_task_force(M2, NRF_GPIOTE_INITIAL_VALUE_LOW);
nrf_drv_gpiote_out_task_force(M4, NRF_GPIOTE_INITIAL_VALUE_LOW);
nrf_drv_gpiote_out_task_enable(M1);
nrf_drv_gpiote_out_task_enable(M4);
nrf_drv_gpiote_out_task_enable(M3);
nrf_drv_gpiote_out_task_enable(M2);
mode_set(level);
NRF_TIMER1->TASKS_CLEAR = 1; *(uint32_t *)0x40009C0C = 1; NRF_TIMER1->TASKS_START = 1;
m_mode = level; }
I defined SOFTDEVICE_PRESENT and modified SD_PPI_RESTRICTED as 1, so the nrf_drv_ppi.c will call functions with sd_ prefix.
The chip is nrf51822 and my sdk is v9.0 and softdevice is s110-v8.0. Please help have a look.