This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

ADC + Softdevice

Hi,

Im trying to monitor the high voltage im generating with PWN using ADC. I also need to run BLE at the same time to provide results. So far I dont have any luck and it seems with Keil you cant even debug this things (please correct me if Im wrong, but when i start stepping through it gets hang on the first BLE command).

Im using ble_hrs example. And thats what i added:

//ADC initialization
static void adc_init(void)
{	
	/* Enable interrupt on ADC sample ready event*/		
	NRF_ADC->INTENSET = ADC_INTENSET_END_Msk;   
	sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);  
	sd_nvic_EnableIRQ(ADC_IRQn);

	NRF_ADC->CONFIG	= (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos) /* Bits 17..16 : ADC external reference pin selection. */
									| (ADC_CONFIG_PSEL_AnalogInput1 << ADC_CONFIG_PSEL_Pos)					/*!< Use analog input 2 as analog input. */
									| (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos)							/*!< Use internal 1.2V bandgap voltage as reference for conversion. */
									| (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) /*!< Analog input specified by PSEL with no prescaling used as input for the conversion. */
									| (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos);									/*!< 8bit ADC resolution. */ 

	/* Enable ADC*/
	NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
}

/* Interrupt handler for ADC data ready event */
void ADC_IRQHandler(void)
{
	/* Clear dataready event */
  NRF_ADC->EVENTS_END = 0;	

  /* Write ADC result to port 2 */
 	//nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT2, NRF_ADC->RESULT); 
	//nrf_gpio_pin_toggle(LED_3);
	
	ADCLEVEL=NRF_ADC->RESULT;

	//Use the STOP task to save current. Workaround for PAN_028 rev1.5 anomaly 1.
  NRF_ADC->TASKS_STOP = 1;

	//Release the external crystal
	//sd_clock_hfclk_release();
}

I also enable conversion on every battery timer expiration

NRF_ADC->EVENTS_END  = 0;    // Stop any running conversions.
 NRF_ADC->TASKS_START = 1;

and eventually write the ADCLEVEL value in the battery level on ble.

battery_level=ADCLEVEL;
    err_code = ble_bas_battery_level_update(&m_bas, battery_level);

Any idea what am i doing wrong and how i can test/debug this?

Thanks!

  • UPDATE: I added UART to print out ADC values. what im getting from ADC is always a value of 234 which is 3.3V and that is the voltage supply for the board. No matter what i try to supply on AIN1 i always get 234. Any ideas?

  • Hi Sergey

    If you use the adc-example-with-softdevice example which is available here then the application timer starts the adc conversion periodically, so the first step is to add code for the application timer and have the applicaton timer to run. Test that with putting a breakpoint in the ADC application timer handler to test that the program counter actually enters the handler.

    When you have your ADC applicaton timer up and running, you add the ADC configuration and start the ADC in your application timer handler, set a breakpoint in the ADC interrupt handler and test that you get a meaningful value from as output from the ADC.

    The last step is a matter of replacing the simulated battery level with the actual battery level, with calling the ble_bas_battery_level_update function, as you have suggested. However, this function just accepts your sampled value and transports it over the BLE link. Before calling this method, you should convert your sampled value to a meaningful battery level value. The battery_level_in_percent in app_util.h is an example conversion function which shows how this conversion could be performed from millivolts to battery percent level, but you need to create a conversion function that actually reflects the discharge curve of your chosen battery type. However, you need first to convert your sampled value to millivolts.

    The example is an addition to the ble_app_hrs example in nRF51 SDK v5.2.0, so if you want to see exactly what code is added to obtain the ADC functionality, then you can run a diff on the main file, with e.g. windiff.

  • Hi Stefan, Thanks a lot for the help! The problem with setting breakpoint was that it only executed once. After that it seems that application would be hanging on the soft device function for BLE. Not exactly sure if its a problem of Keil or SoftDevice.

    Regards, Sergey

Related