This brings in the new ADC api for STM32 parts. Update to new standardized ADC apis. Drops pointless channel definitions, uses common names for common functions. No functional changes. Based on work in: https://github.com/libopencm3/libopencm3-examples/pull/130
163 lines
4.1 KiB
C
163 lines
4.1 KiB
C
/*
|
|
* This file is part of the libopencm3 project.
|
|
*
|
|
* Copyright (C) 2014 Karl Palsson <karlp@tweak.net.au>
|
|
* Copyright (C) 2015 Piotr Esden-Tempski <piotr@esden.nety>
|
|
*
|
|
* This library is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <libopencm3/cm3/nvic.h>
|
|
#include <libopencm3/stm32/adc.h>
|
|
#include <libopencm3/stm32/dac.h>
|
|
#include <libopencm3/stm32/gpio.h>
|
|
#include <libopencm3/stm32/rcc.h>
|
|
#include <libopencm3/stm32/usart.h>
|
|
|
|
#define LED_DISCO_GREEN_PORT GPIOG
|
|
#define LED_DISCO_GREEN_PIN GPIO13
|
|
|
|
#define USART_CONSOLE USART1
|
|
|
|
int _write(int file, char *ptr, int len);
|
|
|
|
static void clock_setup(void)
|
|
{
|
|
rcc_clock_setup_hse_3v3(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
|
|
/* Enable GPIOD clock for LED & USARTs. */
|
|
rcc_periph_clock_enable(RCC_GPIOG);
|
|
rcc_periph_clock_enable(RCC_GPIOA);
|
|
|
|
/* Enable clocks for USART2 and dac */
|
|
rcc_periph_clock_enable(RCC_USART1);
|
|
rcc_periph_clock_enable(RCC_DAC);
|
|
|
|
/* And ADC*/
|
|
rcc_periph_clock_enable(RCC_ADC1);
|
|
}
|
|
|
|
static void usart_setup(void)
|
|
{
|
|
/* Setup GPIO pins for USART1 transmit. */
|
|
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9);
|
|
|
|
/* Setup USART1 TX pin as alternate function. */
|
|
gpio_set_af(GPIOA, GPIO_AF7, GPIO9);
|
|
|
|
usart_set_baudrate(USART_CONSOLE, 115200);
|
|
usart_set_databits(USART_CONSOLE, 8);
|
|
usart_set_stopbits(USART_CONSOLE, USART_STOPBITS_1);
|
|
usart_set_mode(USART_CONSOLE, USART_MODE_TX);
|
|
usart_set_parity(USART_CONSOLE, USART_PARITY_NONE);
|
|
usart_set_flow_control(USART_CONSOLE, USART_FLOWCONTROL_NONE);
|
|
|
|
/* Finally enable the USART. */
|
|
usart_enable(USART_CONSOLE);
|
|
}
|
|
|
|
/**
|
|
* Use USART_CONSOLE as a console.
|
|
* This is a syscall for newlib
|
|
* @param file
|
|
* @param ptr
|
|
* @param len
|
|
* @return
|
|
*/
|
|
int _write(int file, char *ptr, int len)
|
|
{
|
|
int i;
|
|
|
|
if (file == STDOUT_FILENO || file == STDERR_FILENO) {
|
|
for (i = 0; i < len; i++) {
|
|
if (ptr[i] == '\n') {
|
|
usart_send_blocking(USART_CONSOLE, '\r');
|
|
}
|
|
usart_send_blocking(USART_CONSOLE, ptr[i]);
|
|
}
|
|
return i;
|
|
}
|
|
errno = EIO;
|
|
return -1;
|
|
}
|
|
|
|
static void adc_setup(void)
|
|
{
|
|
gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO0);
|
|
gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1);
|
|
|
|
adc_power_off(ADC1);
|
|
adc_disable_scan_mode(ADC1);
|
|
adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_3CYC);
|
|
|
|
adc_power_on(ADC1);
|
|
|
|
}
|
|
|
|
static void dac_setup(void)
|
|
{
|
|
gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO5);
|
|
dac_disable(CHANNEL_2);
|
|
dac_disable_waveform_generation(CHANNEL_2);
|
|
dac_enable(CHANNEL_2);
|
|
dac_set_trigger_source(DAC_CR_TSEL2_SW);
|
|
}
|
|
|
|
static uint16_t read_adc_naiive(uint8_t channel)
|
|
{
|
|
uint8_t channel_array[16];
|
|
channel_array[0] = channel;
|
|
adc_set_regular_sequence(ADC1, 1, channel_array);
|
|
adc_start_conversion_regular(ADC1);
|
|
while (!adc_eoc(ADC1));
|
|
uint16_t reg16 = adc_read_regular(ADC1);
|
|
return reg16;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
int i;
|
|
int j = 0;
|
|
clock_setup();
|
|
usart_setup();
|
|
printf("hi guys!\n");
|
|
adc_setup();
|
|
dac_setup();
|
|
|
|
/* green led for ticking */
|
|
gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,
|
|
LED_DISCO_GREEN_PIN);
|
|
|
|
while (1) {
|
|
uint16_t input_adc0 = read_adc_naiive(0);
|
|
uint16_t target = input_adc0 / 2;
|
|
dac_load_data_buffer_single(target, RIGHT12, CHANNEL_2);
|
|
dac_software_trigger(CHANNEL_2);
|
|
uint16_t input_adc1 = read_adc_naiive(1);
|
|
printf("tick: %d: adc0= %u, target adc1=%d, adc1=%d\n",
|
|
j++, input_adc0, target, input_adc1);
|
|
|
|
/* LED on/off */
|
|
gpio_toggle(LED_DISCO_GREEN_PORT, LED_DISCO_GREEN_PIN);
|
|
|
|
for (i = 0; i < 1000000; i++) { /* Wait a bit. */
|
|
__asm__("NOP");
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|