Commit 656d598a authored by Sergi Hernandez's avatar Sergi Hernandez
Browse files

Added support for the 6 ADC channels and the temperature and Vref sensors.

parent d884d1d3
......@@ -9,6 +9,7 @@ TARGET_FILES+=src/stm32f4xx_hal_msp.c
TARGET_FILES+=src/gpio.c
TARGET_FILES+=src/eeprom.c
TARGET_FILES+=src/ram.c
TARGET_FILES+=src/adc_dma.c
TARGET_FILES+=src/bioloid_time.c
TARGET_FILES+=src/bioloid_dyn_slave.c
TARGET_FILES+=src/bioloid_dyn_master_sensors.c
......@@ -70,6 +71,8 @@ TARGET_FILES+=$(HAL_PATH)/src/stm32f4xx_hal_flash_ex.c
TARGET_FILES+=$(HAL_PATH)/src/stm32f4xx_hal_dma.c
TARGET_FILES+=$(HAL_PATH)/src/stm32f4xx_hal.c
TARGET_FILES+=$(HAL_PATH)/src/stm32f4xx_hal_uart.c
TARGET_FILES+=$(HAL_PATH)/src/stm32f4xx_hal_adc.c
TARGET_FILES+=$(HAL_PATH)/src/stm32f4xx_hal_adc_ex.c
TARGET_FILES+=$(USART_PATH)/src/usart3.c
TARGET_FILES+=$(USART_PATH)/src/usart2.c
......
......@@ -5,10 +5,12 @@
extern "C" {
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"
void adc_init(void);
uint16_t adc_get_temperature(void);
void adc_start(void);
void adc_set_period(uint8_t period_ms);
void adc_stop(void);
#ifdef __cplusplus
}
......
......@@ -46,6 +46,25 @@ typedef enum {
// | | | | interrupt flag | enable interrupt | value | internally used
BIOLOID_MODE_PB_CNTRL = 0x2F, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0
// | | | | interrupt flag | enable interrupt | value | internally used
BIOLOID_ADC_CNTRL = 0x30, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0
// | | | | | | | Enable
BIOLOID_ADC_PERIOD = 0x31,
BIOLOID_ADC_CH1_L = 0x32,
BIOLOID_ADC_CH1_H = 0x33,
BIOLOID_ADC_CH2_L = 0x34,
BIOLOID_ADC_CH2_H = 0x35,
BIOLOID_ADC_CH3_L = 0x36,
BIOLOID_ADC_CH3_H = 0x37,
BIOLOID_ADC_CH4_L = 0x38,
BIOLOID_ADC_CH4_H = 0x39,
BIOLOID_ADC_TEMP_L = 0x3A,
BIOLOID_ADC_TEMP_H = 0x3B,
BIOLOID_ADC_CH6_L = 0x3C,
BIOLOID_ADC_CH6_H = 0x3D,
BIOLOID_ADC_VREF_L = 0x3E,
BIOLOID_ADC_VREF_H = 0x3F,
BIOLOID_ADC_CH8_L = 0x40,
BIOLOID_ADC_CH8_H = 0x41
} bioloid_registers;
#define GPIO_BASE_ADDRESS 0x20
......
#include "adc_dma.h"
#include "ram.h"
#define ADC1_CH1 ADC_Channel_TempSensor
#define ADC1_CH2 ADC_Channel_8
#define ADC1_CH3 ADC_Channel_10
#define ADC1_CH4 ADC_Channel_12
#define ADC2_CH1 ADC_Channel_14
#define ADC2_CH2 ADC_Channel_9
#define ADC2_CH3 ADC_Channel_11
#define ADC2_CH4 ADC_Channel_13
#define ADC1_CH2_PIN GPIO_Pin_8
#define ADC1_CH2_PORT GPIOB
#define ADC1_CH2_PORT_CLK RCC_AHB1Periph_GPIOB
#define ADC1_CH3_PIN GPIO_Pin_0
#define ADC1_CH3_PORT GPIOC
#define ADC1_CH3_PORT_CLK RCC_AHB1Periph_GPIOC
#define ADC1_CH4_PIN GPIO_Pin_2
#define ADC1_CH4_PORT GPIOC
#define ADC1_CH4_PORT_CLK RCC_AHB1Periph_GPIOC
#define ADC2_CH1_PIN GPIO_Pin_4
#define ADC2_CH1_PORT GPIOC
#define ADC2_CH1_PORT_CLK RCC_AHB1Periph_GPIOC
#define ADC2_CH2_PIN GPIO_Pin_1
#define ADC2_CH2_PORT GPIOB
#define ADC2_CH2_PORT_CLK RCC_AHB1Periph_GPIOB
#define ADC2_CH3_PIN GPIO_Pin_1
#define ADC2_CH3_PORT GPIOC
#define ADC2_CH3_PORT_CLK RCC_AHB1Periph_GPIOC
#define ADC2_CH4_PIN GPIO_Pin_3
#define ADC2_CH4_PORT GPIOC
#define ADC2_CH4_PORT_CLK RCC_AHB1Periph_GPIOC
#define ADC_CCR_ADDRESS ((uint32_t)0x40012308)
#define ADC1_CH1 ADC_CHANNEL_6
#define ADC1_CH2 ADC_CHANNEL_8
#define ADC1_CH3 ADC_CHANNEL_TEMPSENSOR
#define ADC1_CH4 ADC_CHANNEL_VREFINT
#define ADC2_CH1 ADC_CHANNEL_7
#define ADC2_CH2 ADC_CHANNEL_9
#define ADC2_CH3 ADC_CHANNEL_14
#define ADC2_CH4 ADC_CHANNEL_15
#define ADC1_CH1_PIN GPIO_PIN_6
#define ADC1_CH1_PORT GPIOA
#define ADC1_CH1_ENABLE_PORT_CLK __HAL_RCC_GPIOA_CLK_ENABLE()
#define ADC1_CH2_PIN GPIO_PIN_0
#define ADC1_CH2_PORT GPIOB
#define ADC1_CH2_ENABLE_PORT_CLK __HAL_RCC_GPIOB_CLK_ENABLE()
#define ADC1_ENABLE_CLK __ADC1_CLK_ENABLE()
#define ADC2_CH1_PIN GPIO_PIN_7
#define ADC2_CH1_PORT GPIOA
#define ADC2_CH1_ENABLE_PORT_CLK __HAL_RCC_GPIOA_CLK_ENABLE()
#define ADC2_CH2_PIN GPIO_PIN_1
#define ADC2_CH2_PORT GPIOB
#define ADC2_CH2_ENABLE_PORT_CLK __HAL_RCC_GPIOB_CLK_ENABLE()
#define ADC2_CH3_PIN GPIO_PIN_4
#define ADC2_CH3_PORT GPIOC
#define ADC2_CH3_ENABLE_PORT_CLK __HAL_RCC_GPIOC_CLK_ENABLE()
#define ADC2_CH4_PIN GPIO_PIN_5
#define ADC2_CH4_PORT GPIOC
#define ADC2_CH4_ENABLE_PORT_CLK __HAL_RCC_GPIOC_CLK_ENABLE()
#define ADC2_ENABLE_CLK __ADC2_CLK_ENABLE()
#define ADC_DMA_CHANNEL DMA_CHANNEL_0
#define ADC_DMA_STREAM DMA2_Stream0
#define ADC_DMA_IRQn DMA2_Stream0_IRQn
#define ADC_DMA_IRQHandler DMA2_Stream0_IRQHandler
#define ADC_ENABLE_DMA_CLK __HAL_RCC_DMA2_CLK_ENABLE()
#define ADC_TIMER TIM4
#define ENABLE_ADC_TIMER_CLK __HAL_RCC_TIM4_CLK_ENABLE()
#define ADC_TIMER_IRQn TIM4_IRQn
#define ADC_TIMER_IRQHandler TIM4_IRQHandler
// temperature conversion functions
#define TEMP_V25 0.76// ADC voltage at 25 degrees in V
#define TEMP_INV_SLOPE 400.0// ADC slope in mV/degree
// general voltage conversion
#define VOLTAGE_DELTA 0.000805664
#define VOLTAGE_GAIN 1.529411765
// private variables
ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2;
DMA_HandleTypeDef hdma_adc1;
TIM_HandleTypeDef ADC_TIM_Handle;
uint32_t adc_data[4];// temporal buffer to store ADC data before conversion
uint16_t adc_period_ms;
// private functions
uint16_t adc_convert_temperature(uint16_t value)
{
float conv_value;
conv_value=(value*VOLTAGE_DELTA-TEMP_V25)*TEMP_INV_SLOPE+25.0;
return conv_value*(1<<10);// fixed point format 6 | 10
}
uint16_t adc_convert_vrefint(uint16_t value)
{
float conv_value;
conv_value=value*VOLTAGE_DELTA;
return conv_value*(1<<12);
}
uint16_t adc_convert_voltage(uint16_t value)
{
float conv_value;
conv_value=value*VOLTAGE_DELTA*VOLTAGE_GAIN;
return conv_value*(1<<12);
}
// interrupt handlers
void ADC_TIMER_IRQHandler(void)
{
uint32_t capture;
if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_CC4) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_CC4) !=RESET)
{
__HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_IT_CC4);
capture = HAL_TIM_ReadCapturedValue(&ADC_TIM_Handle, TIM_CHANNEL_4);
__HAL_TIM_SET_COMPARE(&ADC_TIM_Handle, TIM_CHANNEL_4, (capture + adc_period_ms));
}
}
/* TIM Update event */
if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_UPDATE) != RESET)
if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_UPDATE) !=RESET)
__HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_IT_UPDATE);
/* TIM Break input event */
if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_BREAK) != RESET)
if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_BREAK) !=RESET)
__HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_IT_BREAK);
/* TIM Trigger detection event */
if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_TRIGGER) != RESET)
if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_TRIGGER) !=RESET)
__HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_IT_TRIGGER);
/* TIM commutation event */
if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_COM) != RESET)
if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_COM) !=RESET)
__HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_FLAG_COM);
}
void ADC_DMA_IRQHandler(void)
{
uint16_t value;
/* Transfer Error Interrupt management ***************************************/
if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_adc1)) != RESET)
if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_TE) != RESET)
__HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_adc1));
/* FIFO Error Interrupt management ******************************************/
if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_FE_FLAG_INDEX(&hdma_adc1)) != RESET)
if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_FE) != RESET)
__HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_FE_FLAG_INDEX(&hdma_adc1));
/* Direct Mode Error Interrupt management ***********************************/
if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_DME_FLAG_INDEX(&hdma_adc1)) != RESET)
if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_DME) != RESET)
__HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_DME_FLAG_INDEX(&hdma_adc1));
/* Half Transfer Complete Interrupt management ******************************/
if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_HT_FLAG_INDEX(&hdma_adc1)) != RESET)
if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_HT) != RESET)
__HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_HT_FLAG_INDEX(&hdma_adc1));
/* Transfer Complete Interrupt management ***********************************/
if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_adc1)) != RESET)
if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_TC) != RESET)
{
__HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_adc1));
value=adc_convert_voltage(adc_data[0]&0x0000FFFF);
ram_data[BIOLOID_ADC_CH1_L]=value%256;
ram_data[BIOLOID_ADC_CH1_H]=value/256;
value=adc_convert_voltage((adc_data[0]&0xFFFF0000)>>16);
ram_data[BIOLOID_ADC_CH2_L]=value%256;
ram_data[BIOLOID_ADC_CH2_H]=value/256;
value=adc_convert_voltage(adc_data[1]&0x0000FFFF);
ram_data[BIOLOID_ADC_CH3_L]=value%256;
ram_data[BIOLOID_ADC_CH3_H]=value/256;
value=adc_convert_voltage((adc_data[1]&0xFFFF0000)>>16);
ram_data[BIOLOID_ADC_CH4_L]=value%256;
ram_data[BIOLOID_ADC_CH4_H]=value/256;
value=adc_convert_temperature(adc_data[2]&0x0000FFFF);
ram_data[BIOLOID_ADC_TEMP_L]=value%256;
ram_data[BIOLOID_ADC_TEMP_H]=value/256;
value=adc_convert_voltage((adc_data[2]&0xFFFF0000)>>16);
ram_data[BIOLOID_ADC_CH6_L]=value%256;
ram_data[BIOLOID_ADC_CH6_H]=value/256;
value=adc_convert_vrefint(adc_data[3]&0x0000FFFF);
ram_data[BIOLOID_ADC_VREF_L]=value%256;
ram_data[BIOLOID_ADC_VREF_H]=value/256;
value=adc_convert_voltage((adc_data[3]&0xFFFF0000)>>16);
ram_data[BIOLOID_ADC_CH8_L]=value%256;
ram_data[BIOLOID_ADC_CH8_H]=value/256;
}
}
// public functions
void adc_init(void)
{
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStruct;
ADC_MultiModeTypeDef multimode;
ADC_ChannelConfTypeDef sConfig;
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_OC_InitTypeDef TIM_OCInitStructure;
uint32_t capture;
/* initialize the internal variables */
adc_period_ms=840;// equivalent to 10 ms
ram_data[BIOLOID_ADC_PERIOD]=84;
/* enable clocks */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
RCC_AHB1PeriphClockCmd(ADC1_CH2_PORT_CLK | ADC1_CH3_PORT_CLK | ADC1_CH4_PORT_CLK, ENABLE);
RCC_AHB1PeriphClockCmd(ADC2_CH1_PORT_CLK | ADC2_CH2_PORT_CLK | ADC2_CH3_PORT_CLK | ADC2_CH4_PORT_CLK, ENABLE);
/* DMA Config */
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ram_data[50];
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CCR_ADDRESS;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 4;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
/* DMA2_Stream0 enable */
DMA_Cmd(DMA2_Stream0, ENABLE);
ADC1_CH1_ENABLE_PORT_CLK;
ADC1_CH2_ENABLE_PORT_CLK;
ADC2_CH1_ENABLE_PORT_CLK;
ADC2_CH2_ENABLE_PORT_CLK;
ADC2_CH3_ENABLE_PORT_CLK;
ADC2_CH4_ENABLE_PORT_CLK;
ADC_ENABLE_DMA_CLK;
ADC1_ENABLE_CLK;
/* configure ADC1 */
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV8;
hadc1.Init.Resolution = ADC_RESOLUTION12b;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE;// because it is triggered by a timer
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T4_CC4;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 4;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = EOC_SEQ_CONV;
HAL_ADC_Init(&hadc1);
multimode.Mode = ADC_DUALMODE_REGSIMULT;
multimode.DMAAccessMode = ADC_DMAACCESSMODE_2;
multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_20CYCLES;
HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode);
/* configure ADC1 channels */
sConfig.Channel = ADC1_CH1;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC1_CH2;
sConfig.Rank = 2;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC1_CH3;
sConfig.Rank = 3;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC1_CH4;
sConfig.Rank = 4;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
/* configure GPIO */
GPIO_InitStructure.GPIO_Pin = ADC1_CH2_PIN | ADC2_CH2_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(ADC1_CH2_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = ADC1_CH3_PIN | ADC1_CH4_PIN | ADC2_CH1_PIN | ADC2_CH3_PIN | ADC2_CH4_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(ADC2_CH1_PORT, &GPIO_InitStructure);
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 configuration */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 4;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels 10, 11 configuration */
ADC_RegularChannelConfig(ADC1, ADC1_CH1, 1, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC1_CH2, 2, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC1_CH3, 3, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC1, ADC1_CH4, 4, ADC_SampleTime_480Cycles);
/* ADC1 configuration */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 4;
ADC_Init(ADC2, &ADC_InitStructure);
/* ADC1 regular channels 10, 11 configuration */
ADC_RegularChannelConfig(ADC2, ADC2_CH1, 1, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC2, ADC2_CH2, 2, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC2, ADC2_CH3, 3, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC2, ADC2_CH4, 4, ADC_SampleTime_480Cycles);
/* Enable DMA request after last transfer (Multi-ADC mode) */
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC2 */
ADC_Cmd(ADC2, ENABLE);
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConv(ADC1);
GPIO_InitStruct.Pin = ADC1_CH1_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ADC1_CH1_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = ADC1_CH2_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ADC1_CH2_PORT, &GPIO_InitStruct);
ADC2_ENABLE_CLK;
/* configure ADC1 */
hadc2.Instance = ADC2;
hadc2.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV8;
hadc2.Init.Resolution = ADC_RESOLUTION12b;
hadc2.Init.ScanConvMode = ENABLE;
hadc2.Init.ContinuousConvMode = DISABLE;// because it is triggered by a timer
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = 4;
hadc2.Init.DMAContinuousRequests = ENABLE;
hadc2.Init.EOCSelection = EOC_SEQ_CONV;
HAL_ADC_Init(&hadc2);
multimode.Mode = ADC_DUALMODE_REGSIMULT;
multimode.DMAAccessMode = ADC_DMAACCESSMODE_2;
multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_20CYCLES;
HAL_ADCEx_MultiModeConfigChannel(&hadc2, &multimode);
/* configure ADC2 channels */
sConfig.Channel = ADC2_CH1;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
sConfig.Channel = ADC2_CH2;
sConfig.Rank = 2;
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
sConfig.Channel = ADC2_CH3;
sConfig.Rank = 3;
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
sConfig.Channel = ADC2_CH4;
sConfig.Rank = 4;
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
/* configure GPIO */
GPIO_InitStruct.Pin = ADC2_CH1_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ADC2_CH1_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = ADC2_CH2_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ADC2_CH2_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = ADC2_CH3_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ADC2_CH3_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = ADC2_CH4_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ADC2_CH4_PORT, &GPIO_InitStruct);
/* initialize DMA */
hdma_adc1.Instance = DMA2_Stream0;
hdma_adc1.Init.Channel = DMA_CHANNEL_0;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_adc1);
__HAL_LINKDMA(&hadc1,DMA_Handle,hdma_adc1);
HAL_NVIC_SetPriority(ADC_DMA_IRQn, 3, 1);
HAL_NVIC_EnableIRQ(ADC_DMA_IRQn);
/* configure the timer to generate the internal trigger */
ENABLE_ADC_TIMER_CLK;
ADC_TIM_Handle.Instance=ADC_TIMER;
ADC_TIM_Handle.Init.Period = 0xFFFF;
ADC_TIM_Handle.Init.Prescaler = 1000;
ADC_TIM_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
ADC_TIM_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_NVIC_SetPriority(ADC_TIMER_IRQn, 3, 1);
HAL_NVIC_EnableIRQ(ADC_TIMER_IRQn);
/* use the internal clock */
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
HAL_TIM_ConfigClockSource(&ADC_TIM_Handle, &sClockSourceConfig);
HAL_TIM_OC_Init(&ADC_TIM_Handle);
/* disable master/slave mode */
sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC4REF;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&ADC_TIM_Handle, &sMasterConfig);
/* configure ouptut counter channel 4 */
TIM_OCInitStructure.OCMode = TIM_OCMODE_TOGGLE;
TIM_OCInitStructure.OCPolarity = TIM_OCPOLARITY_HIGH;
TIM_OCInitStructure.OCFastMode = TIM_OCFAST_DISABLE;
capture = HAL_TIM_ReadCapturedValue(&ADC_TIM_Handle, TIM_CHANNEL_4);
TIM_OCInitStructure.Pulse = capture+adc_period_ms;
HAL_TIM_OC_ConfigChannel(&ADC_TIM_Handle, &TIM_OCInitStructure,TIM_CHANNEL_4);
/* start ADC operation */
HAL_ADC_Start(&hadc2);
HAL_ADCEx_MultiModeStart_DMA(&hadc1,adc_data,4);
adc_start();
}
uint16_t adc_get_temperature(void)
void adc_start(void)
{
return 0x0000;
ram_data[BIOLOID_ADC_CNTRL]|=0x01;
HAL_TIM_OC_Start_IT(&ADC_TIM_Handle, TIM_CHANNEL_4);
}
void adc_set_period(uint8_t period_ms)
{
adc_period_ms=period_ms*84;
}
void adc_stop(void)
{
ram_data[BIOLOID_ADC_CNTRL]&=0xFE;
HAL_TIM_OC_Stop_IT(&ADC_TIM_Handle, TIM_CHANNEL_4);
}
......@@ -75,9 +75,4 @@ void bioloid_dyn_master_sensors_init(void)
dyn_master_init(&bioloid_dyn_master_sensors,&bioloid_dyn_master_sensors_comm);
bioloid_dyn_master_sensors.set_rx_mode=bioloid_dyn_master_sensors_set_rx_mode;
bioloid_dyn_master_sensors.set_tx_mode=bioloid_dyn_master_sensors_set_tx_mode;
if(dyn_master_ping(&bioloid_dyn_master_sensors,0xC0)==DYN_SUCCESS)
gpio_set_led(RXD_LED);
else
gpio_clear_led(RXD_LED);
}
......@@ -2,6 +2,7 @@
#include "gpio.h"
#include "eeprom.h"
#include "ram.h"
#include "adc_dma.h"
#include "bioloid_time.h"
#include "bioloid_dyn_slave.h"
#include "bioloid_dyn_master_sensors.h"
......@@ -15,6 +16,8 @@ int32_t main(void)
EE_Init();
/* initialize the ram module */
ram_init();
/* initialize the ADC module */
adc_init();
/* initialize the time module */
bioloid_time_init();
/* initialize the dynamixel slave interface */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment