From c8440bd1a827f70ed5cb6fb55f94b8516d965893 Mon Sep 17 00:00:00 2001 From: philsson Date: Tue, 20 Sep 2016 16:34:32 +0200 Subject: [PATCH] ADC finalized and working --- UAV-ControlSystem/Debug/UAV-ControlSystem.bin | Bin 9268 -> 9444 bytes UAV-ControlSystem/Debug/objects.list | 1 - UAV-ControlSystem/Debug/output.map | 1005 +++++++---------- UAV-ControlSystem/inc/drivers/adc.h | 48 +- UAV-ControlSystem/inc/drivers/dma.h | 16 - UAV-ControlSystem/inc/system_variables.h | 45 +- UAV-ControlSystem/inc/utilities.h | 22 + UAV-ControlSystem/src/drivers/adc.c | 206 ++-- UAV-ControlSystem/src/drivers/dma.c | 41 - UAV-ControlSystem/src/main.c | 85 +- UAV-ControlSystem/src/utilities.c | 26 +- 11 files changed, 630 insertions(+), 865 deletions(-) delete mode 100644 UAV-ControlSystem/inc/drivers/dma.h delete mode 100644 UAV-ControlSystem/src/drivers/dma.c diff --git a/UAV-ControlSystem/Debug/UAV-ControlSystem.bin b/UAV-ControlSystem/Debug/UAV-ControlSystem.bin index 95160676ce35e44101ec0d7e735e06d1094f8eaa..c0852006870416371b9638d7547819fb8fad3299 100644 GIT binary patch delta 1106 zcma)5U1$_n6h8OP&dwypW_8q*HSWu)m z&|PfBJd|R4-y+x|7V}UrvYXO&8}^~#Q=yhtDyGm-q~e3=w6$cj(`I_^wh5>&9XRKH z-1GaLGq*N+FPj0N>~jTFqCPF~#JB1rt_6M`*2I^1@m~g7p zF3iC7H|;Gs-#gw+4TUzOd?)mXVL0m+Hs*{1-ZH*0D#KJ!AHE3kIfaW|0Bi=|?@~Y{MJf?L$50 z>ZtF!TZNC?Be30rP3q<*>#n1TnEVFRV@_fef?`WDVHddt!R=)vX?HEG&-rD+n)x0{ z_nHY4g2AT1z8%LjXT7Pz59gtwB9qFTXb>352o?#^Z0+s#f|=Oubh*91_mCb0yO&AI&qMG=6Iir#G$N?8Q5R}6ik22vAZ6G) zb33iRi5CJYY5C_6Nr((=p5bOls*V!c64EfX^_od6ydNWHBYy&ylNVXF70Il-BJ(qd zeAgD~I}jRfy%;)S;j2F@FV`J1z_uqwN$_P8i{_;TXc(Bn$PZ7{@vmK)2ehkb{{-!! zE9_yBq(iq=4BPgb_hBDSCPp*-9l1y<{8u?8S6UF<;XU!Re6uA3SU&Vh$F7%=r?~=kE=hE&Xe7sZcc!@J5fE@ zd8UI-vg)VW%}#oe@wfWTfoaSoWahtb%7 delta 948 zcma)5Ur1A76hGg0cX#iGHffgI1b5vf5DbwdQU*57rtSvzhaimL?rL#c5JD2-9-I$B z4;IK5JuEP(hoBdYX@qM`C<37%%0ToXsld0mhO+5}-OgR;L-f#v-|rm0^E;eB-*YMPtF%*W0QhtB6to&&ws#= z8hIb=lcQ^l7#+o=o>e_ctxj4hV_vlaJyR9ra2(`hT-X#je^kWIn7P;4`yI$PpU6d1 zIb3lBL>d{!F6~b3t++ybFOT|r`;*L}K9xJOubIF>!1%mFWOGadW20yl+ANT)!cB`H z->@o>bqmX@4Y3BL_QolLa^8U>=yB*JaR-u|RWThAj&u8M)?wLI%PPFK%misMHCKHA zPcH7zs9$+%Qu(sz!vSk>z_1ohyxC4&xMapjNUE>uA%?mGa#rKkA)m$MthSIauctc; zYk+YP<7Y9REXR`=PimuyaKer+Z9pq-!9gSTgl+e~w~nA?({#C^wj?TiEIr^*oXC*( z{aISxPFP0K&>)T2Yh%OC1es=EoiabY3r3L%LJR-42*v|;Qn=NAr+o2kD&WA_qv~GI z>W^Sl_jUzz6WLU=cz0QKK@aQcPGil~ebH(xb*1P?4t29xp}B6-BE~b*DjYABHXIU& z_<|+-DVM>sk}yS&@@z^xY@3&2jMkPi)b)+Ha|b}Y>H%@wllkes?V>Be%(d!wZn_?1 zO~GiWh`)ple57Sd74Hj*JLg{wbz=?Ku44~_O? #include "stm32f4xx_it.h" +/*********************************************************************** +* BRIEF: Sums elements of array until index of second arg * +* INFORMATION: Returns the sum * +***********************************************************************/ uint32_t accumulate(uint32_t list[], int length); + +/*********************************************************************** +* BRIEF: A function that can be called on exceptions * +* INFORMATION: If an exception happens its easier to find it in an * +* infinite loop * +***********************************************************************/ void Error_Handler(void); #endif /* UTILITIES_H_ */ diff --git a/UAV-ControlSystem/src/drivers/adc.c b/UAV-ControlSystem/src/drivers/adc.c index 4a1a9a0..4509f14 100644 --- a/UAV-ControlSystem/src/drivers/adc.c +++ b/UAV-ControlSystem/src/drivers/adc.c @@ -1,30 +1,122 @@ /* * ADC.c - * - * Created on: 13 sep. 2016 - * Author: Philip - */ + /********************************************************************** + * NAME: adc.c * + * AUTHOR: Philip Johansson * + * PURPOSE: Set up and read from ADC * + * INFORMATION: * + * How to use this driver is explained in page 107 of HAL driver * + * Enable the ADC clock * + * Enable the GPIO clock for the pin wanted * + * Configure the GPIO pin as analog input * + * Configure the ADC speed (prescaler/sampling time) * + * Enable continuous measurement mode * + * * + * Read more at: www.visualgdb.com/tutorials/arm/stm32/adc/ * + * * + * GLOBAL VARIABLES: * + * Variable Type Description * + * -------- ---- ----------- * + * * + **********************************************************************/ #include "drivers/adc.h" #include "system_variables.h" #include "utilities.h" +#include +/* A buffer for the ADC to write with DMA */ +enum{ ADC_BUFFER_LENGTH = 10 }; // TODO: Make this define instead of enum +uint32_t g_ADCBuffer[160] = {0}; // We allocate more than needed. Gives 10 readings on 16ch +/* Handler for the ADC */ ADC_HandleTypeDef g_AdcHandle; -volatile uint32_t g_ADCBuffer[ADC_BUFFER_LENGTH] = {0}; -int g_MeasurementNumber = 0; -int adc_rank = 0; -__IO uint32_t g_ADCValue = 0; -ADC_ChannelConfTypeDef sConfig; +/* DMA handler */ +DMA_HandleTypeDef g_DmaHandle; +/* Stores a list (in order) of the channels added + * OBS: Index/size defined by channel_counter */ +uint32_t channels_added[16]; +/* Increments when new ADC input is added */ +int channel_counter = 0; + +/* Stores the rank of every channel */ +uint32_t channel_ranks[16] = {0}; + + + +void adc_pin_conf(uint32_t adc_channel, int adc_rank); + + +/*********************************************************************** +* BRIEF: Read ADC channel * +* INFORMATION: Returns a mean value from "ADB_BUFFER_LENGTH" samples. * +***********************************************************************/ +uint32_t adc_read(uint32_t adc_channel) +{ + int rank = channel_ranks[adc_channel]; + int sum = 0; + for (int i = rank - 1; i < ADC_BUFFER_LENGTH * channel_counter; i += channel_counter ) + sum += g_ADCBuffer[i]; + + return (sum/ADC_BUFFER_LENGTH); +} + + +/*********************************************************************** +* BRIEF: DMA configuration * +* INFORMATION: Is triggered automatically, enables clocks * +***********************************************************************/ +void HAL_ADC_MspInit(ADC_HandleTypeDef * hadc) +{ + + //static DMA_HandleTypeDef g_DmaHandle; + + // Enable DMA, ADC and related GPIO ports clock + __DMA2_CLK_ENABLE(); + __ADC1_CLK_ENABLE(); + __GPIOA_CLK_ENABLE(); + __GPIOC_CLK_ENABLE(); + + // DMA2 Stream4 channel1 (physically mapped to ADC1) configuration + g_DmaHandle.Instance = DMA2_Stream4; + g_DmaHandle.Init.Channel = DMA_CHANNEL_0; + g_DmaHandle.Init.Direction = DMA_PERIPH_TO_MEMORY; + g_DmaHandle.Init.PeriphInc = DMA_PINC_DISABLE; + g_DmaHandle.Init.MemInc = DMA_MINC_ENABLE; + g_DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; + g_DmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; + g_DmaHandle.Init.Mode = DMA_CIRCULAR; + g_DmaHandle.Init.Priority = DMA_PRIORITY_HIGH; + g_DmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + g_DmaHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL; + g_DmaHandle.Init.MemBurst = DMA_MBURST_SINGLE; + g_DmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE; + HAL_DMA_Init(&g_DmaHandle); + + // Associate the initialized DMA handle to the the ADC handle + //__HAL_LINKDMA(adc_handler, DMA_Handle, g_DmaHandle); + __HAL_LINKDMA(&g_AdcHandle, DMA_Handle, g_DmaHandle); + + /* These are for interrupt which we are not using for ADC/DMA */ + //NVIC configuration for DMA transfer complete interrupt + //HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 15, 15); + //HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn); +} + + +/*********************************************************************** +* BRIEF: Configuration of ADC * +* INFORMATION: Also initializes * +***********************************************************************/ void adc_configure() { -// -// __ADC1_CLK_ENABLE(); -// -// HAL_NVIC_SetPriority(ADC_IRQn, 0,0); -// HAL_NVIC_EnableIRQ(ADC_IRQn); + /* Not using the IRQs but here is how they can be declared */ + // __ADC1_CLK_ENABLE(); + // + // HAL_NVIC_SetPriority(ADC_IRQn, 0,0); + // HAL_NVIC_EnableIRQ(ADC_IRQn); g_AdcHandle.Instance = ADC1; g_AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV8; @@ -36,17 +128,34 @@ void adc_configure() g_AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //ADC_EXTERNALTRIGCONV_T1_CC1; g_AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONVEDGE_NONE; g_AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; - g_AdcHandle.Init.NbrOfConversion = 3; //adc_rank; + g_AdcHandle.Init.NbrOfConversion = channel_counter; //adc_rank; g_AdcHandle.Init.DMAContinuousRequests = ENABLE;//DISABLE; g_AdcHandle.Init.EOCSelection = EOC_SINGLE_CONV; if (HAL_ADC_Init(&g_AdcHandle) != HAL_OK) Error_Handler(); + for (int i = 0; i < channel_counter; i++) + adc_pin_conf(channels_added[i], i + 1); } +/*********************************************************************** +* BRIEF: Add the wanted channels to a list * +* INFORMATION: Not initialized here but later * +***********************************************************************/ void adc_pin_add(uint32_t adc_channel) { + channels_added[channel_counter] = adc_channel; + channel_counter++; +} + +/*********************************************************************** +* BRIEF: Configures the ADC channel and ads it to the handler * +* INFORMATION: Each added channel gets an incrementing rank * +***********************************************************************/ +void adc_pin_conf(uint32_t adc_channel, int adc_rank) +{ + /* Variable used to initialize the GPIO */ GPIO_InitTypeDef gpioInit; /* Variable to assign the IO to its Port ex PA, PB etc */ @@ -93,79 +202,30 @@ void adc_pin_add(uint32_t adc_channel) gpioInit.Pull = GPIO_NOPULL; HAL_GPIO_Init(gpio_port,&gpioInit); - - ADC_ChannelConfTypeDef adc_channel_conf; - - - adc_channel_conf.Channel = adc_channel; // ex ADC_CHANNEL_12 - adc_rank++; adc_channel_conf.Rank = (uint32_t)adc_rank; adc_channel_conf.SamplingTime = ADC_SAMPLETIME_480CYCLES; adc_channel_conf.Offset = 0; + channel_ranks[adc_channel] = (uint32_t)adc_rank; + if (HAL_ADC_ConfigChannel(&g_AdcHandle, &adc_channel_conf) != HAL_OK) - { - //asm("bkpt 255"); Error_Handler(); - } - - - } + +/*********************************************************************** +* BRIEF: When ADC is configured this function starts the DMA sampling * +* INFORMATION: Third arg is size. When its full it starts over. * +***********************************************************************/ void adc_start() { - if (ADC_STATE_POLL == AS_POLL) - /* Polling */ - HAL_ADC_Start(&g_AdcHandle); - if (ADC_STATE_POLL == AS_IRQ) - /* Interrupt case */ - //g_AdcHandle.DMA_Handle->XferCpltCallback = &HAL_ADC_ConvCpltCallback; - HAL_ADC_Start_IT(&g_AdcHandle); - if (ADC_STATE_POLL == AS_DMA) - /* DMA case */ - //if (HAL_ADC_Start_DMA(&g_AdcHandle, g_ADCBuffer, ADC_BUFFER_LENGTH) != HAL_OK) - if (HAL_ADC_Start_DMA(&g_AdcHandle, (uint32_t*)&g_ADCBuffer, ADC_BUFFER_LENGTH) != HAL_OK) - { - Error_Handler(); - } -} - -uint32_t adc_read_int() -{ - uint32_t value = 0; - if (HAL_ADC_PollForConversion(&g_AdcHandle, 100) == HAL_OK) - { - value = HAL_ADC_GetValue(&g_AdcHandle); - } - return value; + if (HAL_ADC_Start_DMA(&g_AdcHandle, (uint32_t*)&g_ADCBuffer, channel_counter * ADC_BUFFER_LENGTH) != HAL_OK) + Error_Handler(); } -//void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef * AdcHandle) -//{ -// /* Interrupt case */ -// //g_ADCValue = HAL_ADC_GetValue(AdcHandle); -// -// -// /* DMA case */ -// /* -// g_ADCValue = accumulate(*g_ADCBuffer, ADC_BUFFER_LENGTH) / ADC_BUFFER_LENGTH; -// g_MeasurementNumber += ADC_BUFFER_LENGTH; -// */ -// -// -// // Test to see if this functions is ran at all -// //g_ADCValue = 2; -// -// int hej = g_ADCValue; -//} - - - - diff --git a/UAV-ControlSystem/src/drivers/dma.c b/UAV-ControlSystem/src/drivers/dma.c deleted file mode 100644 index bfc134c..0000000 --- a/UAV-ControlSystem/src/drivers/dma.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * dma.c - * - * Created on: 16 sep. 2016 - * Author: Philip - */ - -#include "drivers/dma.h" -#include "stm32_hal_legacy.h" - -DMA_HandleTypeDef g_DmaHandle; - -void configureDMA() -{ - //__DMA2_CLK_ENABLE(); - __HAL_RCC_DMA2_CLK_ENABLE(); - - g_DmaHandle.Instance = DMA2_Stream4; - - g_DmaHandle.Init.Channel = DMA_CHANNEL_0; - g_DmaHandle.Init.Direction = DMA_PERIPH_TO_MEMORY; - g_DmaHandle.Init.PeriphInc = DMA_PINC_DISABLE; - g_DmaHandle.Init.MemInc = DMA_MINC_ENABLE; - g_DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; - g_DmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; - g_DmaHandle.Init.Mode = DMA_CIRCULAR; - g_DmaHandle.Init.Priority = DMA_PRIORITY_HIGH; - g_DmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - g_DmaHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL; - g_DmaHandle.Init.MemBurst = DMA_MBURST_SINGLE; - g_DmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE; - - HAL_DMA_Init(&g_DmaHandle); - - __HAL_LINKDMA(&g_AdcHandle, DMA_Handle, g_DmaHandle); - -// HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);) - HAL_NVIC_SetPriority(DMA2_Stream4_IRQn,0,0); - HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn); -} - diff --git a/UAV-ControlSystem/src/main.c b/UAV-ControlSystem/src/main.c index 76a5d32..e9b440d 100644 --- a/UAV-ControlSystem/src/main.c +++ b/UAV-ControlSystem/src/main.c @@ -13,23 +13,16 @@ #include "drivers/adc.h" #include "stm32f4xx.h" #include "system_variables.h" -#include "drivers/dma.h" #include "utilities.h" #include -/* Private function prototypes -----------------------------------------------*/ + static void SystemClock_Config(void); -static void SystemClock_Config_Lennart(void); -ADC_HandleTypeDef adc_testinput_handle; // For example battery voltage -ADC_HandleTypeDef adc_test2input_handle; -uint32_t g_ADC2; -int g_MeasurementNumber; - int main(void) { @@ -44,12 +37,15 @@ int main(void) /* Configure the system clock to 100 MHz */ SystemClock_Config(); - adc_configure(); - adc_pin_add(ADC_CHANNEL_0); adc_pin_add(ADC_CHANNEL_1); adc_pin_add(ADC_CHANNEL_12); + + adc_configure(); + + + __GPIOB_CLK_ENABLE(); GPIO_InitTypeDef gpinit; @@ -66,8 +62,12 @@ int main(void) { i++; - g_ADCValue = accumulate(g_ADCBuffer,ADC_BUFFER_LENGTH) / ADC_BUFFER_LENGTH; + //g_ADCValue = accumulate(g_ADCBuffer,ADC_BUFFER_LENGTH) / ADC_BUFFER_LENGTH; //HAL_Delay(100); + int g_ADCValue = adc_read(ADC_CHANNEL_0); + int g_ADCValue1 = adc_read(ADC_CHANNEL_1); + int g_ADCValue12 = adc_read(ADC_CHANNEL_12); + int offTime = g_ADCValue; int onTime = 4096 - offTime; HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5,GPIO_PIN_SET); @@ -86,59 +86,11 @@ int main(void) for(;;); } -HAL_ADC_MspInit(ADC_HandleTypeDef * hadc) -{ - - //static DMA_HandleTypeDef g_DmaHandle; - - // Enable DMA, ADC and related GPIO ports clock - __DMA2_CLK_ENABLE(); - __ADC1_CLK_ENABLE(); - __GPIOA_CLK_ENABLE(); - __GPIOC_CLK_ENABLE(); - - // DMA2 Stream4 channel1 (physically mapped to ADC1) configuration - g_DmaHandle.Instance = DMA2_Stream4; - g_DmaHandle.Init.Channel = DMA_CHANNEL_0; - g_DmaHandle.Init.Direction = DMA_PERIPH_TO_MEMORY; - g_DmaHandle.Init.PeriphInc = DMA_PINC_DISABLE; - g_DmaHandle.Init.MemInc = DMA_MINC_ENABLE; - g_DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; - g_DmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; - g_DmaHandle.Init.Mode = DMA_CIRCULAR; - g_DmaHandle.Init.Priority = DMA_PRIORITY_HIGH; - g_DmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - g_DmaHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL; - g_DmaHandle.Init.MemBurst = DMA_MBURST_SINGLE; - g_DmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE; - HAL_DMA_Init(&g_DmaHandle); - - // Associate the initialized DMA handle to the the ADC handle - //__HAL_LINKDMA(adc_handler, DMA_Handle, g_DmaHandle); - __HAL_LINKDMA(&g_AdcHandle, DMA_Handle, g_DmaHandle); - - // NVIC configuration for DMA transfer complete interrupt - //HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 15, 15); - //HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn); -} - -//void DMA2_Stream4_IRQHandler(void) -//{ -// //HAL_DMA_IRQHandler(g_AdcHandle.DMA_Handle); -// HAL_DMA_IRQHandler(&g_DmaHandle); -//} -// -//void ADC_IRQHandler() -//{ -// HAL_ADC_IRQHandler(&g_AdcHandle); -//} -// -//void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef * AdcHandle) -//{ -// int i = 2; -//} - +/*********************************************************************** +* BRIEF: Starts the system clock * +* INFORMATION: In the current version it works with ADC and DMA * +***********************************************************************/ static void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; @@ -177,10 +129,3 @@ static void SystemClock_Config(void) } - -/** - * @brief This function is executed in case of error occurrence. - * @param None - * @retval None - */ - diff --git a/UAV-ControlSystem/src/utilities.c b/UAV-ControlSystem/src/utilities.c index f04d223..a125951 100644 --- a/UAV-ControlSystem/src/utilities.c +++ b/UAV-ControlSystem/src/utilities.c @@ -1,11 +1,24 @@ /* * utilities.c - * - * Created on: 16 sep. 2016 - * Author: Philip - */ + /********************************************************************** + * NAME: utilities.c * + * AUTHOR: Philip Johansson * + * PURPOSE: Set up and read from ADC * + * INFORMATION: * + * Here we gather usable functions by the whole system * + * * + * GLOBAL VARIABLES: * + * Variable Type Description * + * -------- ---- ----------- * + * * + **********************************************************************/ + #include "utilities.h" +/*********************************************************************** +* BRIEF: Sums elements of array until index of second arg * +* INFORMATION: Returns the sum * +***********************************************************************/ uint32_t accumulate(uint32_t * list, int length) { int value = 0; @@ -16,6 +29,11 @@ uint32_t accumulate(uint32_t * list, int length) return value; } +/*********************************************************************** +* BRIEF: A function that can be called on exceptions * +* INFORMATION: If an exception happens its easier to find it in an * +* infinite loop * +***********************************************************************/ void Error_Handler(void) { while(1)