Added one channel ADC through DMA

This commit is contained in:
eddyem 2014-07-24 12:22:26 +04:00
parent 7ebfa0fcb0
commit 103d9b2600
7 changed files with 80 additions and 11 deletions

View File

@ -195,9 +195,9 @@ static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *
switch (req->bRequest) { switch (req->bRequest) {
case SET_CONTROL_LINE_STATE:{ case SET_CONTROL_LINE_STATE:{
//P("SET_CONTROL_LINE_STATE\r\n", uart1_send); P("SET_CONTROL_LINE_STATE\r\n", uart1_send);
//print_int(req->wValue, uart1_send); print_int(req->wValue, uart1_send);
//newline(uart1_send); newline(uart1_send);
if(req->wValue){ // terminal is opened if(req->wValue){ // terminal is opened
USB_connected = 1; USB_connected = 1;
//P("\r\n\tUSB connected!\r\n", uart1_send); //P("\r\n\tUSB connected!\r\n", uart1_send);
@ -222,11 +222,11 @@ static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *
usbd_ep_write_packet(usbd_dev, 0x83, local_buf, 10); usbd_ep_write_packet(usbd_dev, 0x83, local_buf, 10);
}break; }break;
case SET_LINE_CODING: case SET_LINE_CODING:
//P("SET_LINE_CODING, len=", uart1_send); P("SET_LINE_CODING, len=", uart1_send);
if (!len || (*len != sizeof(struct usb_cdc_line_coding))) if (!len || (*len != sizeof(struct usb_cdc_line_coding)))
return 0; return 0;
//print_int(*len, uart1_send); print_int(*len, uart1_send);
//newline(uart1_send); newline(uart1_send);
memcpy((void *)&lc, (void *)*buf, *len); memcpy((void *)&lc, (void *)*buf, *len);
// Mark & Space parity don't support by hardware, check it // Mark & Space parity don't support by hardware, check it
if(lc.bParityType == USB_CDC_MARK_PARITY || lc.bParityType == USB_CDC_SPACE_PARITY){ if(lc.bParityType == USB_CDC_MARK_PARITY || lc.bParityType == USB_CDC_SPACE_PARITY){
@ -240,10 +240,10 @@ static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *
if(len && *len == sizeof(struct usb_cdc_line_coding)) if(len && *len == sizeof(struct usb_cdc_line_coding))
memcpy((void *)*buf, (void *)&linecoding, sizeof(struct usb_cdc_line_coding)); memcpy((void *)*buf, (void *)&linecoding, sizeof(struct usb_cdc_line_coding));
//usbd_ep_write_packet(usbd_dev, 0x83, (char*)&linecoding, sizeof(linecoding)); //usbd_ep_write_packet(usbd_dev, 0x83, (char*)&linecoding, sizeof(linecoding));
//P("GET_LINE_CODING\r\n", uart1_send); P("GET_LINE_CODING\r\n", uart1_send);
break; break;
default: default:
//P("UNKNOWN\r\n", uart1_send); P("UNKNOWN\r\n", uart1_send);
return 0; return 0;
} }
return 1; return 1;

View File

@ -22,6 +22,8 @@
#include "main.h" #include "main.h"
#include "hardware_ini.h" #include "hardware_ini.h"
volatile uint16_t ADC_value; // ADC DMA value
/** /**
* GPIO initialisaion: clocking + ports setup * GPIO initialisaion: clocking + ports setup
*/ */
@ -38,4 +40,54 @@ void SysTick_init(){
systick_counter_enable(); systick_counter_enable();
} }
void ADC_init(){
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); // enable clocking
rcc_periph_clock_enable(RCC_ADC1);
rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV4);
rcc_periph_clock_enable(RCC_GPIOB); // clocking for ADC port
gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0); // ADC8 - PB0
// Make sure the ADC doesn't run during config
adc_off(ADC1);
// first configure DMA1 Channel1 (ADC1)
rcc_periph_clock_enable(RCC_DMA1); // RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
dma_channel_reset(DMA1, DMA_CHANNEL1); //DMA_DeInit(DMA1_Channel1);
dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t) &(ADC_DR(ADC1))); // DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t)&ADC_value); // DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_value;
dma_set_number_of_data(DMA1, DMA_CHANNEL1, 1); // DMA_InitStructure.DMA_BufferSize = 1;
dma_set_read_from_peripheral(DMA1, DMA_CHANNEL1); // DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
dma_disable_memory_increment_mode(DMA1, DMA_CHANNEL1); // DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL1); // DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma_set_peripheral_size(DMA1, DMA_CHANNEL1, DMA_CCR_PSIZE_16BIT); // DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dma_set_memory_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_16BIT); // DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
dma_enable_circular_mode(DMA1, DMA_CHANNEL1); // DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
dma_set_priority(DMA1, DMA_CHANNEL1, DMA_CCR_PL_HIGH); // DMA_InitStructure.DMA_Priority = DMA_Priority_High;
dma_enable_channel(DMA1, DMA_CHANNEL1); // DMA_Cmd(DMA1_Channel1, ENABLE);
// Configure ADC as continuous scan mode with DMA
adc_set_dual_mode(ADC_CR1_DUALMOD_IND); // ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
adc_enable_scan_mode(ADC1); // ADC_InitStructure.ADC_ScanConvMode = ENABLE;
adc_set_continuous_conversion_mode(ADC1); // ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
adc_disable_external_trigger_regular(ADC1); // ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
adc_set_right_aligned(ADC1); // ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
//adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_239DOT5CYC); // ADC_SampleTime_239Cycles5
adc_set_sample_time(ADC1, ADC_CHANNEL8, ADC_SMPR_SMP_239DOT5CYC); // ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);
adc_enable_dma(ADC1); // ADC_DMACmd(ADC1, ENABLE);
adc_power_on(ADC1); // ADC_Cmd(ADC1, ENABLE);
}
/**
* Starts ADC calibration & after it runs ADC in continuous conversion mode
* First call ADC_init(), than wait a little and call this function
*/
void ADC_calibrate_and_start(){
uint8_t channel_array[16];
// adc_set_regular_sequence 1 channel -- 0 // ADC_InitStructure.ADC_NbrOfChannel = 1;
channel_array[0] = ADC_CHANNEL8;
adc_set_regular_sequence(ADC1, 1, channel_array);
adc_reset_calibration(ADC1);
adc_calibration(ADC1);
adc_start_conversion_regular(ADC1); // ADC_SoftwareStartConvCmd(ADC1, ENABLE);
adc_start_conversion_direct(ADC1);
}

View File

@ -23,7 +23,11 @@
#ifndef __HARDWARE_INI_H__ #ifndef __HARDWARE_INI_H__
#define __HARDWARE_INI_H__ #define __HARDWARE_INI_H__
extern volatile uint16_t ADC_value; // ADC DMA value
void GPIO_init(); void GPIO_init();
void SysTick_init(); void SysTick_init();
void ADC_init();
void ADC_calibrate_and_start();
#endif // __HARDWARE_INI_H__ #endif // __HARDWARE_INI_H__

Binary file not shown.

View File

@ -46,13 +46,17 @@ int main(){
// USB // USB
usbd_dev = USB_init(); usbd_dev = USB_init();
// init ADC
ADC_init();
// SysTick is a system timer with 1mc period
SysTick_init();
// wait a little and then turn on USB pullup // wait a little and then turn on USB pullup
for (i = 0; i < 0x800000; i++) for (i = 0; i < 0x800000; i++)
__asm__("nop"); __asm__("nop");
gpio_clear(GPIOC, GPIO11); gpio_clear(GPIOC, GPIO11);
ADC_calibrate_and_start();
// SysTick is a system timer with 1mc period
SysTick_init();
while(1){ while(1){
usbd_poll(usbd_dev); usbd_poll(usbd_dev);

View File

@ -33,6 +33,8 @@
#include <libopencm3/usb/usbd.h> #include <libopencm3/usb/usbd.h>
#include <libopencm3/cm3/systick.h> #include <libopencm3/cm3/systick.h>
#include <libopencm3/stm32/rcc.h> #include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/adc.h>
#include <libopencm3/stm32/dma.h>
#include "user_proto.h" #include "user_proto.h"

View File

@ -22,6 +22,7 @@
#include "cdcacm.h" #include "cdcacm.h"
#include "main.h" #include "main.h"
#include "uart.h" #include "uart.h"
#include "hardware_ini.h"
// integer value given by user // integer value given by user
static volatile int32_t User_value = 0; static volatile int32_t User_value = 0;
@ -60,6 +61,12 @@ void parce_incoming_buf(char *buf, int len, sendfun s){
command = buf[i]; command = buf[i];
if(!command) continue; // omit zero if(!command) continue; // omit zero
switch (command){ switch (command){
case 'A': // show ADC value
//adc_start_conversion_direct(ADC1);
P("\r\n ADC value: ", s);
print_int(ADC_value, s);
newline(s);
break;
case 'b': // turn LED off case 'b': // turn LED off
gpio_set(GPIOC, GPIO12); gpio_set(GPIOC, GPIO12);
break; break;