Example #1
0
static void StartConversion(Afec *afec)
{
	// Clear out any existing conversion complete bits in the status register
	for (uint32_t chan = 0; chan < 16; ++chan)
	{
		if ((afec_get_interrupt_status(afec) & (1 << chan)) != 0)
		{
			(void)afec_channel_get_value(afec, static_cast<afec_channel_num>(chan));
		}
	}
	afec_start_software_conversion(afec);
}
Example #2
0
/*
*	Coverts the temp sensor volatge to temp
*
*/
static void afec_temp_sensor_end_conversion(void)
{
	volatile uint32_t g_ul_value = 0;
	int32_t ul_vol;
	g_ul_value = afec_channel_get_value(AFEC0, AFEC_TEMPERATURE_SENSOR);
	ul_vol = g_ul_value * VOLT_REF / MAX_DIGITAL;
	/*
	* According to datasheet, The output voltage VT = 1.44V at 27C
	* and the temperature slope dVT/dT = 4.7 mV/C
	*/
	ul_temp = (ul_vol - 1440)  * 100 / 470 + 27;
}
Example #3
0
// Read the most recent 12-bit result from a channel
uint16_t AnalogInReadChannel(AnalogChannelNumber channel)
{
	if ((unsigned int)channel < numChannels)
	{
#if SAM3XA || SAM4S
		return adc_get_channel_value(ADC, GetAdcChannel(channel));
#elif SAM4E || SAME70
		return afec_channel_get_value(GetAfec(channel), GetAfecChannel(channel));
#endif
	}
	return 0;
}
Example #4
0
uint32_t getAnalog(int channel) {
	uint32_t result;
	
	if (channel == 0){
		afec_channel_enable(AFEC0, AFEC_CHANNEL_0);
		afec_start_software_conversion(AFEC0);
		
		while (!(afec_get_interrupt_status(AFEC0) & (1 << AFEC_CHANNEL_0)));
		//delay_ms(10);
		result = afec_channel_get_value(AFEC0, AFEC_CHANNEL_0);
		//afec_channel_disable(AFEC0, AFEC_CHANNEL_0);
	}
	else{
		afec_channel_enable(AFEC0, AFEC_CHANNEL_1);
		afec_start_software_conversion(AFEC0);
		
		while (!(afec_get_interrupt_status(AFEC0) & (1 << AFEC_CHANNEL_1)));
		//delay_ms(10);
		result = afec_channel_get_value(AFEC0, AFEC_CHANNEL_1);
		//afec_channel_disable(AFEC0, AFEC_CHANNEL_1);
		
	}
	return result;
}
Example #5
0
/**
 * \brief Send a JSON string representing the board status.
 *
 * \param name Not used.
 * \param recv_buf Receive buffer.
 * \param recv_len Receive buffer length.
 *
 * \return 0.
 */
static int cgi_status(const char *name, char *recv_buf, size_t recv_len)
{
	UNUSED(recv_buf);
	UNUSED(recv_len);
	UNUSED(name);

	volatile uint16_t volt;
	uint32_t length = 0;
	uint32_t i;
	status.tot_req++;

	volt = afec_channel_get_value(AFEC0, AFEC_CHANNEL_5);

	status.up_time = xTaskGetTickCount() / 1000;

	/* Update board status. */
	sprintf(status.last_connected_ip, "%d.%d.%d.%d",
			IP_ADDR_TO_INT_TUPLE(g_pcb->remote_ip.addr));
	sprintf(status.local_ip, "%d.%d.%d.%d",
			IP_ADDR_TO_INT_TUPLE(g_pcb->local_ip.addr));
	length += sprintf((char *)tx_buf,
			"{\"local_ip\":\"%s\",\"last_connected_ip\":\"%s\", \"temp\":%d.%d, \"mag\":\"",
			status.local_ip, status.last_connected_ip,
			status.internal_temp / 100, status.internal_temp % 100);

	/* Update magnitude graph (98 + 1). */
	for (i = 0; i < 98; ++i) {
		length += sprintf((char *)tx_buf + length, "%d|",
				mag_in_buffer_int[i]);
	}
	length
		+= sprintf((char *)tx_buf + length, "%d\"",
			mag_in_buffer_int[i]);

	/* Remaining board status. */
	length += sprintf((char *)tx_buf + length,
			",\"volt\":%d,\"up_time\":%ld,\"tot_req\":%d, \"leds\":{ \"0\":\"%d\", \"1\":\"%d\", \"2\":\"%d\"}}",
			volt, status.up_time, status.tot_req,
			GET_LED_STATUS(status.led_status, 0),
			GET_LED_STATUS(status.led_status, 1),
			GET_LED_STATUS(status.led_status, 2));

	/* Send answer. */
	http_sendOk(HTTP_CONTENT_JSON);
	http_write((char const *)tx_buf, strlen((char *)tx_buf));

	return 0;
}
Example #6
0
/**
 * \brief Send the potentiometer voltage.
 *
 * \param name Not used.
 * \param recv_buf Receive buffer.
 * \param recv_len Receive buffer length.
 *
 * \return 0.
 */
static int cgi_resistor(const char *name, char *recv_buf, size_t recv_len)
{
	UNUSED(recv_buf);
	UNUSED(recv_len);
	UNUSED(name);

	u16_t volt;

	volt = afec_channel_get_value(AFEC0, AFEC_CHANNEL_5) * 10000 / 4096;

	sprintf((char *)tx_buf, "[ \"%d.%dV\" ]", volt / 1000, volt % 1000);

	http_sendOk(HTTP_CONTENT_JSON);
	http_write((const char *)tx_buf, strlen((char *)tx_buf));

	return 0;
}
Example #7
0
/**
 *  \brief ACC example application entry point.
 *
 *  \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	uint32_t uc_key;
	int16_t s_volt = 0;
	uint32_t ul_value = 0;
	volatile uint32_t ul_status = 0x0;
	int32_t l_volt_dac0 = 0;

	/* Initialize the system */
	sysclk_init();
	board_init();

	/* Initialize debug console */
	configure_console();

	/* Output example information */
	puts(STRING_HEADER);

	/* Initialize DACC */
	/* Enable clock for DACC */
	pmc_enable_periph_clk(ID_DACC);
	/* Reset DACC registers */
	dacc_reset(DACC);
	/* External trigger mode disabled. DACC in free running mode. */
	dacc_disable_trigger(DACC, DACC_CHANNEL_0);
	/* Half word transfer mode */
	dacc_set_transfer_mode(DACC, 0);
#if (SAM3S) || (SAM3XA)
	/* Power save:
	 * sleep mode  - 0 (disabled)
	 * fast wakeup - 0 (disabled)
	 */
	dacc_set_power_save(DACC, 0, 0);
#endif

	/* Enable output channel DACC_CHANNEL */
	dacc_enable_channel(DACC, DACC_CHANNEL_0);
	/* Setup analog current */
	dacc_set_analog_control(DACC, DACC_ANALOG_CONTROL);

	/* Set DAC0 output at ADVREF/2. The DAC formula is:
	 *
	 * (5/6 * VOLT_REF) - (1/6 * VOLT_REF)     volt - (1/6 * VOLT_REF)
	 * ----------------------------------- = --------------------------
	 *              MAX_DIGITAL                       digit
	 *
	 * Here, digit = MAX_DIGITAL/2
	 */
	dacc_write_conversion_data(DACC, MAX_DIGITAL / 2, DACC_CHANNEL_0);
	l_volt_dac0 = (MAX_DIGITAL / 2) * (2 * VOLT_REF / 3) / MAX_DIGITAL +
			VOLT_REF / 6;

	/* Enable clock for AFEC */
	afec_enable(AFEC0);

	struct afec_config afec_cfg;

	afec_get_config_defaults(&afec_cfg);
	/* Initialize AFEC */
	afec_init(AFEC0, &afec_cfg);

	struct afec_ch_config afec_ch_cfg;
	afec_ch_get_config_defaults(&afec_ch_cfg);
	afec_ch_cfg.gain = AFEC_GAINVALUE_0;
	afec_ch_set_config(AFEC0, AFEC_CHANNEL_POTENTIOMETER, &afec_ch_cfg);
	/*
	 * Because the internal ADC offset is 0x200, it should cancel it and shift
	 * down to 0.
	 */
	afec_channel_set_analog_offset(AFEC0, AFEC_CHANNEL_POTENTIOMETER, 0x200);

	afec_set_trigger(AFEC0, AFEC_TRIG_SW);

	/* Enable channel for potentiometer. */
	afec_channel_enable(AFEC0, AFEC_CHANNEL_POTENTIOMETER);

	/* Enable clock for ACC */
	pmc_enable_periph_clk(ID_ACC);
	
	/* Initialize ACC */
	acc_init(ACC, ACC_MR_SELPLUS_AFE0_AD0, ACC_MR_SELMINUS_DAC0,
			ACC_MR_EDGETYP_ANY, ACC_MR_INV_DIS);

	/* Enable ACC interrupt */
	NVIC_EnableIRQ(ACC_IRQn);

	/* Enable */
	acc_enable_interrupt(ACC);

	dsplay_menu();

	while (1) {
		while (usart_read(CONSOLE_UART, &uc_key)) {
		}

		printf("input: %c\r\n", uc_key);

		switch (uc_key) {
		case 's':
		case 'S':
			printf("Input DAC0 output voltage (%d~%d mv): ",
					(VOLT_REF / 6), (VOLT_REF * 5 / 6));
			s_volt = get_input_voltage();
			puts("\r");

			if (s_volt > 0) {
				l_volt_dac0 = s_volt;
				/* The DAC formula is:
				 *
				 * (5/6 * VOLT_REF) - (1/6 * VOLT_REF)     volt - (1/6 * VOLT_REF)
				 * ----------------------------------- = --------------------------
				 *              MAX_DIGITAL                       digit
				 *
				 */
				ul_value = ((s_volt - (VOLT_REF / 6))
					* (MAX_DIGITAL * 6) / 4) / VOLT_REF;
				dacc_write_conversion_data(DACC, ul_value, DACC_CHANNEL_0);
				puts("-I- Set ok\r");
			} else {
				puts("-I- Input voltage is invalid\r");
			}
			break;
		case 'v':
		case 'V':
			/* Start conversion */
			afec_start_software_conversion(AFEC0);
			ul_status = afec_get_interrupt_status(AFEC0);
			while ((ul_status & AFEC_ISR_EOC0) != AFEC_ISR_EOC0) {
				ul_status = afec_get_interrupt_status(AFEC0);
			}
			/* Conversion is done */
			ul_value = afec_channel_get_value(AFEC0, AFEC_CHANNEL_POTENTIOMETER);

			/*
			 * Convert AFEC sample data to voltage value:
			 * voltage value = (sample data / max. resolution) * reference voltage
			 */
			s_volt = (ul_value * VOLT_REF) / MAX_DIGITAL;
			printf("-I- Voltage on potentiometer(AD0) is %d mv\n\r", s_volt);
			printf("-I- Voltage on DAC0 is %ld mv \n\r", (long)l_volt_dac0);
			break;
			
		case 'm':
		case 'M':
			dsplay_menu();
			break;
		}
	}
}
Example #8
0
/**
 * \brief DSP task core function.
 *
 * \param pvParameters Junk parameter.
 */
static void dsp_task(void *pvParameters)
{
	uint32_t i, j;
	uint32_t adc_potentiometer = 0;
	const float32_t display_factor = 700;
	float32_t bin;
	float32_t tmp;

	/* Just to avoid compiler warnings. */
	UNUSED(pvParameters);

	/* Wait for user to read instructions. */
	WAIT_FOR_TOUCH_EVENT;

	dsp_configure_button2();
	dsp_configure_tc();
	dsp_configure_adc();
	dsp_configure_dacc();
	dsp_sin_init();

	/* Enable PDC transfer. */
	dsp_clean_buffer(dacc_out_buffer[0], SAMPLE_BLOCK_SIZE);
	dsp_clean_buffer(dacc_out_buffer[1], SAMPLE_BLOCK_SIZE);
	dsp_clean_buffer(dacc_out_buffer[2], SAMPLE_BLOCK_SIZE);
	g_pdc_packet.ul_addr = (uint32_t) dacc_out_buffer[0];
	g_pdc_packet.ul_size = SAMPLE_BLOCK_SIZE;
	g_pdc_nextpacket.ul_addr = (uint32_t) dacc_out_buffer[1];
	g_pdc_nextpacket.ul_size = SAMPLE_BLOCK_SIZE;
	pdc_tx_init(dacc_pdc, &g_pdc_packet, &g_pdc_nextpacket);
	pdc_enable_transfer(dacc_pdc, PERIPH_PTCR_TXTEN);

	/* Start Timer counter 0 channel 0 for ADC-DACC trigger. */
	tc_start(TC0, 1);

	/** DSP task loop. */
	while (1) {
		/* Using input wave signal. */
		if (g_mode_select == 1) {
			if (xSemaphoreTake(dacc_notification_semaphore,
					max_block_time_ticks)) {
				/* Copy dsp_sfx into wav_in_buffer and prepare Q15 format. */
				for (i = 0, j = 0; i < 512; ++j) {
					tmp = (((dsp_sfx[offset] - (float) 128)) / 100);

					/* Store Audio sample real part in memory. */
					wav_in_buffer[i++] = tmp;

					/* Store Audio sample imaginary part in memory. */
					wav_in_buffer[i++] = 0;

					/* Prepare buffer for DACC. */
					dacc_out_buffer[cur_dac_buffer][j] = (uint16_t)((tmp * 100
							* sin_buffer[slider_pos][j]) + 128);

					/* Update the wave file offset pointer. */
					if (offset < dsp_sfx_size - 1) {
						offset++;
					} else {
						offset = WAVE_OFFSET;
					}
				}
			} else {
				/* Ensure we take the semaphore. */
				continue;
			}
		} else {
			/* Using generated input sinus signal. */
			if (xSemaphoreTake(dacc_notification_semaphore,
					max_block_time_ticks)) {
				/*
				 * Read potentiometer value and generate
				 * sinus signal accordingly.
				 */
				adc_potentiometer_old = adc_potentiometer;
				adc_potentiometer = (afec_channel_get_value(AFEC0,
						ADC_CHANNEL_POTENTIOMETER));
				adc_potentiometer = adc_potentiometer * 10000 / 4096;
				if (adc_potentiometer > adc_potentiometer_old &&
						adc_potentiometer -
						adc_potentiometer_old < ADC_POTENTIOMETER_NOISE) {
					adc_potentiometer = adc_potentiometer_old;
				} else if (adc_potentiometer_old > adc_potentiometer &&
						adc_potentiometer_old -
						adc_potentiometer < ADC_POTENTIOMETER_NOISE) {
					adc_potentiometer = adc_potentiometer_old;
				}

				/* Generate the sinus signal. */
				dsp_sin_input(adc_potentiometer);

				/* Prepare buffer for DACC. */
				for (i = 0, j = 0; i < 512; ++j, i += 2) {
					/*
					 * 2048 is the 0 position for DACC.
					 * 50 is an amplification factor.
					 */
					dacc_out_buffer[cur_dac_buffer][j] =
					(uint16_t)((wav_in_buffer[i] * sin_buffer[slider_pos][j])
							* 50 + 2048);
				}

			}
		}

		afec_start_software_conversion(AFEC0);

		/* Perform FFT and bin Magnitude calculation */
		arm_float_to_q15(wav_in_buffer, cfft_q15, SAMPLE_BLOCK_SIZE * 2);
		arm_cfft_radix4_init_q15(&cfft_instance, SAMPLE_BLOCK_SIZE, 0, 1);
		arm_cfft_radix4_q15(&cfft_instance, cfft_q15);
		arm_cmplx_mag_q15(cfft_q15, mag_in_buffer_q15, SAMPLE_BLOCK_SIZE);
		arm_q15_to_float(mag_in_buffer_q15, mag_in_buffer, 128);

		/*
		 * Prepare bins rendering for web page and display.
		 * Limit to 99, even if we got 128 magnitudes to display.
		 * Bins are printed using col, incremented by mean of 2 to keep
		 * a clean rendering. Hence we cannot render all the magnitudes,
		 * because of the screen width. It would require a 128*2 space.
		 */
		for (i = 0; i < 99; ++i) {
			bin = (mag_in_buffer[i] * display_factor);
			if (bin > 0) {
				if (bin > 98) {
					bin = 98;
				}
				mag_in_buffer_int[i] = (uint32_t)bin;
			} else {
				mag_in_buffer_int[i] = 0;
			}
		}

		/* Notify GFX task to start refreshing screen (if necessary). */
		if (g_mode_select == 1 || (g_mode_select == 0 &&
				adc_potentiometer != adc_potentiometer_old)) {
			xSemaphoreGive(gfx_notification_semaphore);
		}
	}
}
static void afec1_temp_adcRead_ch2(void)
{
	afec0_data = afec_channel_get_value(AFEC1, AFEC_CHANNEL_2);
	TempAdcRaw.signal[7].adcRaw = afec0_data;
	TempAdcRaw.signal[7].timestamp =  getSystemTimeMilliseconds();
}
static void afec0_temp_adcRead_tempSensor(void)
{
	afec0_data = afec_channel_get_value(AFEC0, AFEC_TEMPERATURE_SENSOR);
	TempAdcRaw.signal[8].adcRaw = afec0_data;
	TempAdcRaw.signal[8].timestamp =  getSystemTimeMilliseconds();
}
Example #11
0
/**
 * \brief AFEC0 EOC1 interrupt callback function.
 */
static void afec_eoc_1(void)
{
	g_afec1_sample_data = afec_channel_get_value(AFEC0, AFEC_CHANNEL_1);
	puts("AFEC0 Channel 1 Voltage:");
	print_float(g_afec1_sample_data * VOLT_REF / g_max_digital);
}
Example #12
0
/**
 * \brief AFEC interrupt callback function.
 */
static void afec_temp_sensor_end_conversion(void)
{
	g_ul_value = afec_channel_get_value(AFEC0, AFEC_TEMPERATURE_SENSOR);
	is_conversion_done = true;
}