uint8_t findFreePPIChannel(uint8_t exclude_channel) { uint32_t err_code = NRF_SUCCESS, chen; uint8_t softdevice_enabled; uint8_t channelIndex = 0; /** Refer S110 Sift Device Specification 10.4 */ uint8_t nbAppPPIChannels = 0; err_code = sd_softdevice_is_enabled(&softdevice_enabled); APP_ERROR_CHECK(err_code); if(softdevice_enabled == 0) { chen = NRF_PPI->CHEN; nbAppPPIChannels = NB_PPI_APP_CHANNELS_SD_DISABLED; } else { err_code = sd_ppi_channel_enable_get(&chen); APP_ERROR_CHECK(err_code); nbAppPPIChannels = NB_PPI_APP_CHANNELS_SD_ENABLED; } for (; channelIndex < nbAppPPIChannels; channelIndex++) { if(! ( chen & (1 << channelIndex) ) ) { if (channelIndex != exclude_channel) { return channelIndex; } } } return UNAVAILABLE_PPI_CHANNEL; }
/********************************************************************** name : function : find free PPI channel **********************************************************************/ int find_free_PPI_channel(int exclude_channel) { uint32_t err_code = NRF_SUCCESS, chen; int start = 0; int end = 8; int i; err_code = sd_softdevice_is_enabled(&softdevice_enabled); APP_ERROR_CHECK(err_code); if(softdevice_enabled == 0) { chen = NRF_PPI->CHEN; } else { err_code = sd_ppi_channel_enable_get(&chen); APP_ERROR_CHECK(err_code); } for (i = start; i < end; i++) { //if (! (NRF_PPI->CHEN & (1 << i))) if(! ( chen & (1 << i) ) ) { if (i != exclude_channel) { return i; } } } return 255; }
/********************************************************************** name : function : called by wiring_digital.c **********************************************************************/ void PPI_ON_TIMER_GPIO(uint32_t gpiote_channel, NRF_TIMER_Type* Timer, uint32_t CC_channel) { uint32_t err_code = NRF_SUCCESS, chen; // Initialize Programmable Peripheral Interconnect int chan_0 = find_free_PPI_channel(255); int chan_1 = find_free_PPI_channel(chan_0); if ((chan_0 != 255) && (chan_1 != 255)) { err_code = sd_softdevice_is_enabled(&softdevice_enabled); APP_ERROR_CHECK(err_code); if (softdevice_enabled == 0) { // Enable PPI using registers NRF_PPI->CH[chan_0].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[CC_channel]) ); NRF_PPI->CH[chan_0].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] ); NRF_PPI->CHEN |= ( 1 << chan_0); // Save PPI channel number PPI_Channels_Occupied[gpiote_channel][0] = chan_0; // Configure PPI channel "chan_1" to toggle "ulPin" pin on every Timer COMPARE[3] match NRF_PPI->CH[chan_1].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[3]) ); NRF_PPI->CH[chan_1].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] ); NRF_PPI->CHEN |= ( 1 << chan_1); // Save PPI channel number PPI_Channels_Occupied[gpiote_channel][1] = chan_1; //simple_uart_printHEX(NRF_PPI->CHEN); } else { //Enable PPI using sd_ppi_x err_code = sd_ppi_channel_assign(chan_0, &((*Timer).EVENTS_COMPARE[CC_channel]), &NRF_GPIOTE->TASKS_OUT[gpiote_channel]); APP_ERROR_CHECK(err_code); err_code = sd_ppi_channel_enable_set(1 << chan_0); APP_ERROR_CHECK(err_code); //Save PPI channel number PPI_Channels_Occupied[gpiote_channel][0] = chan_0; err_code = sd_ppi_channel_assign(chan_1, &((*Timer).EVENTS_COMPARE[3]), &NRF_GPIOTE->TASKS_OUT[gpiote_channel]); APP_ERROR_CHECK(err_code); err_code = sd_ppi_channel_enable_set(1 << chan_1 ); APP_ERROR_CHECK(err_code); //Save PPI channel number PPI_Channels_Occupied[gpiote_channel][1] = chan_1; err_code = sd_ppi_channel_enable_get(&chen); APP_ERROR_CHECK(err_code); } } /* if(0 == gpiote_channel) { NRF_PPI->CH[9].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[CC_channel]) ); NRF_PPI->CH[9].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] ); NRF_PPI->CHEN |= ( 1 << 9); // Save PPI channel number PPI_Channels_Occupied[gpiote_channel][0] = 9; NRF_PPI->CH[10].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[3]) ); NRF_PPI->CH[10].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] ); NRF_PPI->CHEN |= ( 1 << 10); // Save PPI channel number PPI_Channels_Occupied[gpiote_channel][1] = 10; } else if(1 == gpiote_channel) { NRF_PPI->CH[11].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[CC_channel]) ); NRF_PPI->CH[11].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] ); NRF_PPI->CHEN |= ( 1 << 11); // Save PPI channel number PPI_Channels_Occupied[gpiote_channel][0] = 11; NRF_PPI->CH[12].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[3]) ); NRF_PPI->CH[12].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] ); NRF_PPI->CHEN |= ( 1 << 12); // Save PPI channel number PPI_Channels_Occupied[gpiote_channel][1] = 12; } else if(2 == gpiote_channel) { NRF_PPI->CH[13].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[CC_channel]) ); NRF_PPI->CH[13].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] ); NRF_PPI->CHEN |= ( 1 << 13); // Save PPI channel number PPI_Channels_Occupied[gpiote_channel][0] = 13; NRF_PPI->CH[14].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[3]) ); NRF_PPI->CH[14].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] ); NRF_PPI->CHEN |= ( 1 << 14); // Save PPI channel number PPI_Channels_Occupied[gpiote_channel][1] = 14; } */ }