ADC finalized and working

This commit is contained in:
philsson 2016-09-20 16:34:32 +02:00
parent 5716445448
commit c8440bd1a8
11 changed files with 630 additions and 865 deletions

View File

@ -1,5 +1,4 @@
"src/drivers/adc.o"
"src/drivers/dma.o"
"src/main.o"
"src/stm32f4xx_it.o"
"src/syscalls.o"

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@
*/
/**********************************************************************
* NAME: adc.h *
* AUTHOR: Philip Johansson *
* PURPOSE: Set up and read from ADC *
* INFORMATION: *
* How to use this driver is explained in page 107 of HAL driver *
@ -28,50 +29,29 @@
#include "stm32f4xx.h"
/***********************************************************************
* BRIEF: *
* INFORMATION: *
* BRIEF: Configuration of ADC *
* INFORMATION: Also initializes *
***********************************************************************/
void adc_configure();
/***********************************************************************
* BRIEF: *
* INFORMATION: *
* BRIEF: Add the wanted channels to a list *
* INFORMATION: Not initialized here but later *
***********************************************************************/
void adc_pin_add(uint32_t adc_channel);
/***********************************************************************
* BRIEF: *
* INFORMATION: *
* BRIEF: Read ADC channel *
* INFORMATION: Returns a mean value from "ADB_BUFFER_LENGTH" samples. *
***********************************************************************/
uint32_t adc_read(uint32_t adc_channel);
/***********************************************************************
* 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();
/***********************************************************************
* BRIEF: *
* INFORMATION: *
***********************************************************************/
uint32_t adc_read_int();
/***********************************************************************
* BRIEF: *
* INFORMATION: *
***********************************************************************/
//void HAL_ADC_ConvCpltCallback();
/***********************************************************************
* BRIEF: *
* INFORMATION: *
***********************************************************************/
//void D**MA2_Stream4_IRQHandler();
/***********************************************************************
* BRIEF: *
* INFORMATION: *
***********************************************************************/
void ADC_IRQHandler();
#endif /* DRIVERS_ADC_H_ */

View File

@ -1,16 +0,0 @@
/*
* dma.h
*
* Created on: 16 sep. 2016
* Author: Philip
*/
#ifndef DRIVERS_DMA_H_
#define DRIVERS_DMA_H_
#include "stm32f4xx.h"
#include "system_variables.h"
void configureDMA();
#endif /* DRIVERS_DMA_H_ */

View File

@ -1,43 +1,32 @@
/*
* system_variables.h
*
* Created on: 15 sep. 2016
* Author: Philip
*/
/**********************************************************************
* NAME: adc.h *
* AUTHOR: Philip Johansson *
* PURPOSE: Set up and read from ADC *
* INFORMATION: *
* Here we gather common variables for the system as a whole *
* *
* GLOBAL VARIABLES: *
* Variable Type Description *
* -------- ---- ----------- *
* *
**********************************************************************/
#ifndef SYSTEM_VARIABLES_H_
#define SYSTEM_VARIABLES_H_
#define ADC_STATE_POLL AS_DMA
#define ADC_STATE
#include "stm32f4xx.h"
enum ADC_STATES { AS_POLL, AS_IRQ, AS_DMA };
/* A buffer for the ADC to write with DMA */
enum{ ADC_BUFFER_LENGTH = 9 };
extern volatile uint32_t g_ADCBuffer[ADC_BUFFER_LENGTH];
/* Defining boolean - false = 0, true = 1 */
enum BOOLEAN { false,true };
/* Counter of ADC readings */
extern int g_MeasurementNumber;
/* ADC Rank - For each IO we increment the rank?? */
extern int adc_rank;
/* Last ADC reading (when polling) */
extern __IO uint32_t g_ADCValue;
/* ADC handler - OBS: Tried to use this as a pointer but it did not work */
extern ADC_HandleTypeDef g_AdcHandle;
/* DMA handler */
extern DMA_HandleTypeDef g_DmaHandle;
#endif /* SYSTEM_VARIABLES_H_ */

View File

@ -4,6 +4,18 @@
* 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 *
* -------- ---- ----------- *
* *
**********************************************************************/
#ifndef UTILITIES_H_
#define UTILITIES_H_
@ -11,7 +23,17 @@
#include <stdint.h>
#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_ */

View File

@ -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 <stdlib.h>
/* 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)
{
if (HAL_ADC_Start_DMA(&g_AdcHandle, (uint32_t*)&g_ADCBuffer, channel_counter * 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;
}
//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;
//}

View File

@ -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);
}

View File

@ -13,23 +13,16 @@
#include "drivers/adc.h"
#include "stm32f4xx.h"
#include "system_variables.h"
#include "drivers/dma.h"
#include "utilities.h"
#include <string.h>
/* 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
*/

View File

@ -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)