From d14d0dd428eb324d7f0e734c17146e9e1a1b4fe9 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Sat, 1 Jun 2013 09:56:16 +0000 Subject: [PATCH] dac driver and first pass at play program, needs some work on buffer sizes git-svn-id: https://svn.code.sf.net/p/freetel/code@1302 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/stm32/Makefile | 21 ++- codec2-dev/stm32/inc/dac_it.h | 61 ------- codec2-dev/stm32/inc/stm32f4_dac.h | 34 ++++ codec2-dev/stm32/src/dac_it.c | 37 +++-- codec2-dev/stm32/src/dac_play.c | 68 ++++++++ codec2-dev/stm32/src/dac_ut.c | 199 +++-------------------- codec2-dev/stm32/src/stm32f4_dac.c | 246 +++++++++++++++++++++++++++++ 7 files changed, 417 insertions(+), 249 deletions(-) delete mode 100644 codec2-dev/stm32/inc/dac_it.h create mode 100644 codec2-dev/stm32/inc/stm32f4_dac.h create mode 100644 codec2-dev/stm32/src/dac_play.c create mode 100644 codec2-dev/stm32/src/stm32f4_dac.c diff --git a/codec2-dev/stm32/Makefile b/codec2-dev/stm32/Makefile index 9befea45..b5bc9801 100644 --- a/codec2-dev/stm32/Makefile +++ b/codec2-dev/stm32/Makefile @@ -110,7 +110,7 @@ OBJS = $(SRCS:.c=.o) ################################################### -all: libstm32f4.a $(PROJ_NAME).elf fft_test.elf dac_ut.elf +all: libstm32f4.a $(PROJ_NAME).elf fft_test.elf dac_ut.elf dac_play.elf dl/$(PERIPHLIBZIP): mkdir -p dl @@ -132,14 +132,27 @@ $(PROJ_NAME).elf: $(SRCS) fft_test.elf: $(FFT_TEST_SRCS) $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS) -DAC_TEST_SRCS=\ +DAC_UT_SRCS=\ src/dac_ut.c \ -src/dac_it.c \ +../src/fifo.c \ +src/stm32f4_dac.c \ src/system_stm32f4xx.c \ src/startup_stm32f4xx.s \ src/init.c -dac_ut.elf: $(DAC_TEST_SRCS) +dac_ut.elf: $(DAC_UT_SRCS) + $(CC) $(CFLAGS) -O0 $^ -o $@ $(LIBPATHS) $(LIBS) + +DAC_PLAY_SRCS=\ +src/dac_play.c \ +../src/fifo.c \ +gdb_stdio.c \ +src/stm32f4_dac.c \ +src/system_stm32f4xx.c \ +src/startup_stm32f4xx.s \ +src/init.c + +dac_play.elf: $(DAC_PLAY_SRCS) $(CC) $(CFLAGS) -O0 $^ -o $@ $(LIBPATHS) $(LIBS) clean: diff --git a/codec2-dev/stm32/inc/dac_it.h b/codec2-dev/stm32/inc/dac_it.h deleted file mode 100644 index e935feab..00000000 --- a/codec2-dev/stm32/inc/dac_it.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - ****************************************************************************** - * @file DMA/DMA_FLASHToRAM/stm32f4xx_it.h - * @author MCD Application Team - * @version V1.1.0 - * @date 18-January-2013 - * @brief This file contains the headers of the interrupt handlers. - ****************************************************************************** - * @attention - * - *

© COPYRIGHT 2013 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_IT_H -#define __STM32F4xx_IT_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_dma.h" - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ - -void NMI_Handler(void); -void HardFault_Handler(void); -void MemManage_Handler(void); -void BusFault_Handler(void); -void UsageFault_Handler(void); -void SVC_Handler(void); -void DebugMon_Handler(void); -void PendSV_Handler(void); -void SysTick_Handler(void); -void DMA_STREAM_IRQHANDLER(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_IT_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/codec2-dev/stm32/inc/stm32f4_dac.h b/codec2-dev/stm32/inc/stm32f4_dac.h new file mode 100644 index 00000000..3a298321 --- /dev/null +++ b/codec2-dev/stm32/inc/stm32f4_dac.h @@ -0,0 +1,34 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: stm32f4_dac.h + AUTHOR......: David Rowe + DATE CREATED: 1 June 2013 + + DAC driver module for STM32F4. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2013 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#ifndef __STM32F4_DAC__ +#define __STM32F4_DAC__ + +void dac_open(void); +int dac_write(short buf[], int n); + +#endif diff --git a/codec2-dev/stm32/src/dac_it.c b/codec2-dev/stm32/src/dac_it.c index 3d671ca8..2b614fc4 100644 --- a/codec2-dev/stm32/src/dac_it.c +++ b/codec2-dev/stm32/src/dac_it.c @@ -152,7 +152,7 @@ void SysTick_Handler(void) /* STM32F4xx Peripherals Interrupt Handlers */ /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ /* available peripheral interrupt handler's name please refer to the startup */ -/* file (startup_stm32f40xx.s/startup_stm32f427x.s). */ +/* file (startup_stm32f40xx.s/startup_stm32f427x.s). */ /******************************************************************************/ /** @@ -162,18 +162,35 @@ void SysTick_Handler(void) */ void DMA1_Stream6_IRQHandler(void) { - /* Test on DMA Stream Transfer Complete interrupt */ - if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_HTIF6)) + + /* Transfer half empty interrupt */ + + if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_HTIF6) != RESET)) { - /* Clear DMA Stream Transfer Complete interrupt pending bit */ - DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_HTIF6); - interrupts++; + /* fill first half from fifo */ + + fifo_read(DMA1_Stream6_fifo, dac_buf, DAC_BUF_SZ/2); + + /* Clear DMA Stream Transfer Complete interrupt pending bit */ + + DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_HTIF6); + + interrupts++; } - if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_TCIF6)) + + /* Transfer complete interrupt */ + + if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_TCIF6) != RESET)) { - /* Clear DMA Stream Transfer Complete interrupt pending bit */ - DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6); - interrupts++; + /* fill second half from fifo */ + + fifo_read(DMA1_Stream6_fifo, &dac_buf[DAC_BUF_SZ/2], DAC_BUF_SZ/2); + + /* Clear DMA Stream Transfer Complete interrupt pending bit */ + + DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6); + + interrupts++; } } diff --git a/codec2-dev/stm32/src/dac_play.c b/codec2-dev/stm32/src/dac_play.c new file mode 100644 index 00000000..43263ec7 --- /dev/null +++ b/codec2-dev/stm32/src/dac_play.c @@ -0,0 +1,68 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: dac_play.c + AUTHOR......: David Rowe + DATE CREATED: 1 June 2013 + + Plays a 16 kHz sample rate raw file to the Discovery DAC. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2013 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#include +#include "stm32f4_dac.h" +#include "gdb_stdio.h" + +#define printf gdb_stdio_printf +#define fopen gdb_stdio_fopen +#define fclose gdb_stdio_fclose +#define fread gdb_stdio_fread +#define fwrite gdb_stdio_fwrite + +#define N1 24000 +#define N2 320 + +int main(void) { + short *buf, *pbuf; + FILE *fin; + int i, nframes; + + buf = (short*)malloc(N1*sizeof(short)); + dac_open(); + + fin = fopen("stm_in.raw", "rb"); + if (fin == NULL) { + printf("Error opening input file: stm_in.raw\n\nTerminating....\n"); + exit(1); + } + fread(buf, sizeof(short), N1, fin); + fclose(fin); + + nframes = N1/N2; + while(1) { + printf("Starting!\n"); + pbuf = buf; + for(i=0; i. */ +#include +#include "stm32f4_dac.h" -/* Modfied version of the following: */ - -/** - ****************************************************************************** - * @file DAC/DAC_SignalsGeneration/main.c - * @author MCD Application Team - * @version V1.1.0 - * @date 18-January-2013 - * @brief Main program body. - ****************************************************************************** - * @attention - * - *

© COPYRIGHT 2013 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -#include "stm32f4xx.h" - -#define DAC_DHR12R2_ADDRESS 0x40007414 - -DAC_InitTypeDef DAC_InitStructure; - -/* 32 sample sine wave which at Fs=16kHz will be 500Hz. Note samples - are unsigned */ - -const uint16_t aSine12bit[32] = { - 2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056, - 3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909, - 599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647}; - -static void TIM6_Config(void); -static void DAC_Ch2_SineWaveConfig(void); - -/* Private functions ---------------------------------------------------------*/ - -int main(void) -{ - /*!< At this stage the microcontroller clock setting is already configured, - this is done through SystemInit() function which is called from startup - files (startup_stm32f40xx.s/startup_stm32f427x.s) before to branch to - application main. - To reconfigure the default setting of SystemInit() function, refer to - system_stm32f4xx.c file - */ - - /* Preconfiguration before using DAC----------------------------------------*/ - GPIO_InitTypeDef GPIO_InitStructure; - - /* DMA1 clock enable */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); - /* GPIOA clock enable (to be used with DAC) */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); - /* DAC Periph clock enable */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); - - /* DAC channel 1 & 2 (DAC_OUT1 = PA.4)(DAC_OUT2 = PA.5) configuration */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* TIM6 Configuration ------------------------------------------------------*/ - - TIM6_Config(); - - DAC_Ch2_SineWaveConfig(); - - while (1); -} +#define SINE_SAMPLES 32 -/** - * @brief TIM6 Configuration - * @note TIM6 configuration is based on APB1 frequency - * @note TIM6 Update event occurs each TIM6CLK/256 - * @param None - * @retval None - */ -static void TIM6_Config(void) -{ - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - /* TIM6 Periph clock enable */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); - - /* -------------------------------------------------------- - - TIM3 input clock (TIM6CLK) is set to 2 * APB1 clock (PCLK1), since - APB1 prescaler is different from 1 (see system_stm32f4xx.c and Fig - 13 clock tree figure in DM0031020.pdf). - - Sample rate Fs = 2*PCLK1/TIM_ClockDivision - = (HCLK/2)/TIM_ClockDivision - - ----------------------------------------------------------- */ - - /* Time base configuration */ - TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); - TIM_TimeBaseStructure.TIM_Period = 5250; - TIM_TimeBaseStructure.TIM_Prescaler = 0; - TIM_TimeBaseStructure.TIM_ClockDivision = 0; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); - - /* TIM6 TRGO selection */ - TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); - - /* TIM6 enable counter */ - TIM_Cmd(TIM6, ENABLE); -} -/** - * @brief DAC Channel2 SineWave Configuration - * @param None - * @retval None - */ -static void DAC_Ch2_SineWaveConfig(void) -{ - DMA_InitTypeDef DMA_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; - - /* DAC channel2 Configuration */ - DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO; - DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; - DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; - DAC_Init(DAC_Channel_2, &DAC_InitStructure); - - /* DMA1_Stream6 channel7 configuration **************************************/ - DMA_DeInit(DMA1_Stream6); - DMA_InitStructure.DMA_Channel = DMA_Channel_7; - DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12R2_ADDRESS; - DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&aSine12bit; - DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; - DMA_InitStructure.DMA_BufferSize = 32; - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; - DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; - DMA_InitStructure.DMA_Priority = DMA_Priority_High; - DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; - DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; - DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; - DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; - DMA_Init(DMA1_Stream6, &DMA_InitStructure); - - /* Enable DMA Half 7 Complete interrupts */ - DMA_ITConfig(DMA1_Stream6, DMA_IT_TC | DMA_IT_HT, ENABLE); - - /* Enable the DMA Stream IRQ Channel */ - - NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream6_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - - /* Enable DMA1_Stream6 */ - DMA_Cmd(DMA1_Stream6, ENABLE); - - /* Enable DAC Channel2 */ - DAC_Cmd(DAC_Channel_2, ENABLE); - - /* Enable DMA for DAC Channel2 */ - DAC_DMACmd(DAC_Channel_2, ENABLE); +/* 32 sample sine wave which at Fs=16kHz will be 500Hz. Not sampels + are 16 bit 2's complement, the DAC driver convertsto 12 bit + unsigned. */ + +const short aSine[] = { + -16, 6384, 12528, 18192, 23200, 27232, 30256, 32128, 32752, 32128, + 30256, 27232, 23152, 18192, 12528, 6384, -16, -6416, -12560, -18224, + -23184, -27264, -30288, -32160, -32768, -32160, -30288, -27264, -23184, -18224, + -12560, -6416 +}; + +int main(void) { + + dac_open(); + + while (1) { + + /* keep DAC FIFO topped up */ + + dac_write((short*)aSine, SINE_SAMPLES); + } + } diff --git a/codec2-dev/stm32/src/stm32f4_dac.c b/codec2-dev/stm32/src/stm32f4_dac.c new file mode 100644 index 00000000..b9b6df5c --- /dev/null +++ b/codec2-dev/stm32/src/stm32f4_dac.c @@ -0,0 +1,246 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: stm32f4_dac.c + AUTHOR......: David Rowe + DATE CREATED: 1 June 2013 + + DAC driver module for STM32F4. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2013 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#include +#include +#include +#include "stm32f4xx.h" +#include "codec2_fifo.h" +#include "stm32f4_dac.h" + +#define DAC_DHR12R2_ADDRESS 0x40007414 +#define DAC_DHR12L2_ADDRESS 0x40007418 + +#define DAC_BUF_SZ 320 +#define FIFO_SZ 2000 +#define DAC_MAX 4096 + +DAC_InitTypeDef DAC_InitStructure; +struct FIFO *DMA1_Stream6_fifo; + +unsigned short dac_buf[DAC_BUF_SZ]; + +static void TIM6_Config(void); +static void DAC_Ch2_Config(void); + +void dac_open(void) { + + memset(dac_buf, 32768, sizeof(short)*DAC_BUF_SZ); + + /* Create fifo */ + + DMA1_Stream6_fifo = fifo_create(FIFO_SZ); + assert(DMA1_Stream6_fifo != NULL); + + /*!< At this stage the microcontroller clock setting is already configured, + this is done through SystemInit() function which is called from startup + files (startup_stm32f40xx.s/startup_stm32f427x.s) before to branch to + application main. + To reconfigure the default setting of SystemInit() function, refer to + system_stm32f4xx.c file + */ + + /* Preconfiguration before using DAC----------------------------------------*/ + + GPIO_InitTypeDef GPIO_InitStructure; + + /* DMA1 clock enable */ + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); + /* GPIOA clock enable (to be used with DAC) */ + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + /* DAC Periph clock enable */ + RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); + + /* DAC channel 1 & 2 (DAC_OUT1 = PA.4)(DAC_OUT2 = PA.5) configuration */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + /* TIM6 Configuration ------------------------------------------------------*/ + + TIM6_Config(); + DAC_Ch2_Config(); + +} + +/* Accepts signed 16 bit samples */ + +int dac_write(short buf[], int n) { + return fifo_write(DMA1_Stream6_fifo, buf, n); +} + +/** + * @brief TIM6 Configuration + * @note TIM6 configuration is based on APB1 frequency + * @note TIM6 Update event occurs each TIM6CLK/256 + * @param None + * @retval None + */ +static void TIM6_Config(void) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + /* TIM6 Periph clock enable */ + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); + + /* -------------------------------------------------------- + + TIM3 input clock (TIM6CLK) is set to 2 * APB1 clock (PCLK1), since + APB1 prescaler is different from 1 (see system_stm32f4xx.c and Fig + 13 clock tree figure in DM0031020.pdf). + + Sample rate Fs = 2*PCLK1/TIM_ClockDivision + = (HCLK/2)/TIM_ClockDivision + + ----------------------------------------------------------- */ + + /* Time base configuration */ + TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); + TIM_TimeBaseStructure.TIM_Period = 5250; + TIM_TimeBaseStructure.TIM_Prescaler = 0; + TIM_TimeBaseStructure.TIM_ClockDivision = 0; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); + + /* TIM6 TRGO selection */ + TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); + + /* TIM6 enable counter */ + TIM_Cmd(TIM6, ENABLE); +} + +/** + * @brief DAC Channel2 SineWave Configuration + * @param None + * @retval None + */ +static void DAC_Ch2_Config(void) +{ + DMA_InitTypeDef DMA_InitStructure; + NVIC_InitTypeDef NVIC_InitStructure; + + /* DAC channel2 Configuration */ + DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO; + DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; + DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; + DAC_Init(DAC_Channel_2, &DAC_InitStructure); + + /* DMA1_Stream6 channel7 configuration **************************************/ + DMA_DeInit(DMA1_Stream6); + DMA_InitStructure.DMA_Channel = DMA_Channel_7; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12L2_ADDRESS; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dac_buf; + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + DMA_InitStructure.DMA_BufferSize = DAC_BUF_SZ; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(DMA1_Stream6, &DMA_InitStructure); + + /* Enable DMA Half 7 Complete interrupts */ + DMA_ITConfig(DMA1_Stream6, DMA_IT_TC | DMA_IT_HT, ENABLE); + + /* Enable the DMA Stream IRQ Channel */ + + NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream6_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + /* Enable DMA1_Stream6 */ + DMA_Cmd(DMA1_Stream6, ENABLE); + + /* Enable DAC Channel2 */ + DAC_Cmd(DAC_Channel_2, ENABLE); + + /* Enable DMA for DAC Channel2 */ + DAC_DMACmd(DAC_Channel_2, ENABLE); +} + +/******************************************************************************/ +/* STM32F4xx Peripherals Interrupt Handlers */ +/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ +/* available peripheral interrupt handler's name please refer to the startup */ +/* file (startup_stm32f40xx.s/startup_stm32f427x.s). */ +/******************************************************************************/ + +/* + This function handles DMA Stream interrupt request. +*/ + +void DMA1_Stream6_IRQHandler(void) { + int i, sam; + short signed_buf[DAC_BUF_SZ/2]; + + /* Transfer half empty interrupt */ + + if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_HTIF6) != RESET) { + /* fill first half from fifo */ + + if (fifo_read(DMA1_Stream6_fifo, signed_buf, DAC_BUF_SZ/2) == -1) + memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2); + + /* convert to unsigned */ + + for(i=0; i