\r
#define DAC_BUF_SZ 320\r
#define FIFO_SZ 4*DAC_BUF_SZ\r
-#define DAC_MAX 4096\r
+#define DAC_MAX 4096 /* maximum amplitude */\r
\r
DAC_InitTypeDef DAC_InitStructure;\r
-struct FIFO *DMA1_Stream6_fifo;\r
+struct FIFO *dac1_fifo;\r
+struct FIFO *dac2_fifo;\r
\r
-unsigned short dac_buf[DAC_BUF_SZ];\r
+unsigned short dac1_buf[DAC_BUF_SZ];\r
+unsigned short dac2_buf[DAC_BUF_SZ];\r
\r
-static void TIM6_Config(void);\r
-static void DAC_Ch2_Config(void);\r
+static void tim6_config(void);\r
+static void dac1_config(void);\r
+static void dac2_config(void);\r
\r
int dac_underflow;\r
\r
void dac_open(void) {\r
\r
- memset(dac_buf, 32768, sizeof(short)*DAC_BUF_SZ);\r
+ memset(dac1_buf, 32768, sizeof(short)*DAC_BUF_SZ);\r
+ memset(dac2_buf, 32768, sizeof(short)*DAC_BUF_SZ);\r
\r
- /* Create fifo */\r
+ /* Create fifos */\r
\r
- DMA1_Stream6_fifo = fifo_create(FIFO_SZ);\r
- assert(DMA1_Stream6_fifo != NULL);\r
+ dac1_fifo = fifo_create(FIFO_SZ);\r
+ dac2_fifo = fifo_create(FIFO_SZ);\r
+ assert(dac1_fifo != NULL);\r
+ assert(dac2_fifo != NULL);\r
\r
- /*!< At this stage the microcontroller clock setting is already configured, \r
- this is done through SystemInit() function which is called from startup\r
- files (startup_stm32f40xx.s/startup_stm32f427x.s) before to branch to \r
- application main. \r
- To reconfigure the default setting of SystemInit() function, refer to\r
- system_stm32f4xx.c file\r
- */ \r
-\r
- /* Preconfiguration before using DAC----------------------------------------*/\r
-\r
- GPIO_InitTypeDef GPIO_InitStructure;\r
+ /* Turn on the clocks we need -----------------------------------------------*/\r
\r
/* DMA1 clock enable */\r
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);\r
/* DAC Periph clock enable */\r
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);\r
\r
- /* DAC channel 1 & 2 (DAC_OUT1 = PA.4)(DAC_OUT2 = PA.5) configuration */\r
+ /* GPIO Pin configuration DAC1->PA.4, DAC2->PA.5 configuration --------------*/\r
+\r
+ GPIO_InitTypeDef GPIO_InitStructure;\r
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;\r
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;\r
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;\r
GPIO_Init(GPIOA, &GPIO_InitStructure);\r
\r
- /* TIM6 Configuration ------------------------------------------------------*/\r
+ /* Timer and DAC 1 & 2 Configuration ----------------------------------------*/\r
\r
- TIM6_Config(); \r
- DAC_Ch2_Config();\r
- \r
+ tim6_config(); \r
+ dac1_config();\r
+ dac2_config();\r
}\r
\r
-/* Accepts signed 16 bit samples */\r
+/* Call these puppies to send samples to the DACs. For your\r
+ convenience they accept signed 16 bit samples. */\r
+\r
+int dac1_write(short buf[], int n) { \r
+ return fifo_write(dac1_fifo, buf, n);\r
+}\r
\r
-int dac_write(short buf[], int n) { \r
- return fifo_write(DMA1_Stream6_fifo, buf, n);\r
+int dac2_write(short buf[], int n) { \r
+ return fifo_write(dac2_fifo, buf, n);\r
}\r
\r
-/** \r
- * @brief TIM6 Configuration\r
- * @note TIM6 configuration is based on APB1 frequency\r
- * @note TIM6 Update event occurs each TIM6CLK/256 \r
- * @param None\r
- * @retval None\r
- */\r
-static void TIM6_Config(void)\r
+static void tim6_config(void)\r
{\r
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;\r
+\r
/* TIM6 Periph clock enable */\r
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);\r
\r
----------------------------------------------------------- */\r
\r
/* Time base configuration */\r
+\r
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); \r
TIM_TimeBaseStructure.TIM_Period = 5250; \r
TIM_TimeBaseStructure.TIM_Prescaler = 0; \r
TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);\r
\r
/* TIM6 enable counter */\r
+\r
TIM_Cmd(TIM6, ENABLE);\r
}\r
\r
-/**\r
- * @brief DAC Channel2 SineWave Configuration\r
- * @param None\r
- * @retval None\r
- */\r
-static void DAC_Ch2_Config(void)\r
+static void dac1_config(void)\r
+{\r
+ DMA_InitTypeDef DMA_InitStructure;\r
+ NVIC_InitTypeDef NVIC_InitStructure;\r
+ \r
+ /* DAC channel11Configuration */\r
+\r
+ DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;\r
+ DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;\r
+ DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;\r
+ DAC_Init(DAC_Channel_1, &DAC_InitStructure);\r
+\r
+ /* DMA1_Stream5 channel7 configuration **************************************/\r
+ /* Table 35 page 219 of the monster data sheet */\r
+\r
+ DMA_DeInit(DMA1_Stream5);\r
+ DMA_InitStructure.DMA_Channel = DMA_Channel_7; \r
+ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12R2_ADDRESS;\r
+ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dac1_buf;\r
+ DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;\r
+ DMA_InitStructure.DMA_BufferSize = DAC_BUF_SZ;\r
+ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;\r
+ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;\r
+ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;\r
+ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;\r
+ DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;\r
+ DMA_InitStructure.DMA_Priority = DMA_Priority_High;\r
+ DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; \r
+ DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;\r
+ DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;\r
+ DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;\r
+ DMA_Init(DMA1_Stream6, &DMA_InitStructure);\r
+\r
+ /* Enable DMA Half & Complete interrupts */\r
+\r
+ DMA_ITConfig(DMA1_Stream5, DMA_IT_TC | DMA_IT_HT, ENABLE);\r
+\r
+ /* Enable the DMA Stream IRQ Channel */\r
+\r
+ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream5_IRQn;\r
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;\r
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;\r
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;\r
+ NVIC_Init(&NVIC_InitStructure); \r
+\r
+ /* Enable DMA1_Stream5 */\r
+\r
+ DMA_Cmd(DMA1_Stream5, ENABLE);\r
+\r
+ /* Enable DAC Channel 1 */\r
+\r
+ DAC_Cmd(DAC_Channel_1, ENABLE);\r
+\r
+ /* Enable DMA for DAC Channel 1 */\r
+\r
+ DAC_DMACmd(DAC_Channel_1, ENABLE);\r
+}\r
+\r
+static void dac2_config(void)\r
{\r
DMA_InitTypeDef DMA_InitStructure;\r
NVIC_InitTypeDef NVIC_InitStructure;\r
\r
/* DAC channel2 Configuration */\r
+\r
DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;\r
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;\r
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;\r
DAC_Init(DAC_Channel_2, &DAC_InitStructure);\r
\r
/* DMA1_Stream6 channel7 configuration **************************************/\r
+\r
DMA_DeInit(DMA1_Stream6);\r
DMA_InitStructure.DMA_Channel = DMA_Channel_7; \r
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12L2_ADDRESS;\r
- DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dac_buf;\r
+ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dac2_buf;\r
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;\r
DMA_InitStructure.DMA_BufferSize = DAC_BUF_SZ;\r
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;\r
DMA_Init(DMA1_Stream6, &DMA_InitStructure);\r
\r
/* Enable DMA Half & Complete interrupts */\r
+\r
DMA_ITConfig(DMA1_Stream6, DMA_IT_TC | DMA_IT_HT, ENABLE);\r
\r
/* Enable the DMA Stream IRQ Channel */\r
NVIC_Init(&NVIC_InitStructure); \r
\r
/* Enable DMA1_Stream6 */\r
+\r
DMA_Cmd(DMA1_Stream6, ENABLE);\r
\r
- /* Enable DAC Channel2 */\r
+ /* Enable DAC Channel 2 */\r
+\r
DAC_Cmd(DAC_Channel_2, ENABLE);\r
\r
- /* Enable DMA for DAC Channel2 */\r
+ /* Enable DMA for DAC Channel 2 */\r
+\r
DAC_DMACmd(DAC_Channel_2, ENABLE);\r
}\r
\r
/******************************************************************************/\r
\r
/*\r
- This function handles DMA Stream interrupt request.\r
+ This function handles DMA1 Stream 5 interrupt request for DAC1.\r
+*/\r
+\r
+void DMA1_Stream5_IRQHandler(void) {\r
+ int i, sam;\r
+ short signed_buf[DAC_BUF_SZ/2];\r
+\r
+ /* Transfer half empty interrupt - refill first half */\r
+\r
+ if(DMA_GetITStatus(DMA1_Stream5, DMA_IT_HTIF5) != RESET) {\r
+ /* fill first half from fifo */\r
+\r
+ if (fifo_read(dac1_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {\r
+ memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2);\r
+ dac_underflow++;\r
+ }\r
+\r
+ /* convert to unsigned */\r
+\r
+ for(i=0; i<DAC_BUF_SZ/2; i++) {\r
+ sam = (int)signed_buf[i] + 32768;\r
+ dac1_buf[i] = (unsigned short)(sam);\r
+ }\r
+\r
+ /* Clear DMA Stream Transfer Complete interrupt pending bit */\r
+\r
+ DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_HTIF5); \r
+ }\r
+\r
+ /* Transfer complete interrupt - refill 2nd half */\r
+\r
+ if(DMA_GetITStatus(DMA1_Stream5, DMA_IT_TCIF5) != RESET) {\r
+ /* fill second half from fifo */\r
+\r
+ if (fifo_read(dac1_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {\r
+ memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2);\r
+ dac_underflow++;\r
+ }\r
+\r
+ /* convert to unsigned */\r
+\r
+ for(i=0; i<DAC_BUF_SZ/2; i++) {\r
+ sam = (int)signed_buf[i] + 32768;\r
+ dac1_buf[i+DAC_BUF_SZ/2] = (unsigned short)(sam);\r
+ }\r
+\r
+ /* Clear DMA Stream Transfer Complete interrupt pending bit */\r
+\r
+ DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_TCIF5); \r
+ }\r
+}\r
+\r
+/*\r
+ This function handles DMA1 Stream 6 interrupt request for DAC2.\r
*/\r
\r
void DMA1_Stream6_IRQHandler(void) {\r
int i, sam;\r
short signed_buf[DAC_BUF_SZ/2];\r
\r
- /* Transfer half empty interrupt */\r
+ /* Transfer half empty interrupt - refill first half */\r
\r
if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_HTIF6) != RESET) {\r
/* fill first half from fifo */\r
\r
- if (fifo_read(DMA1_Stream6_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {\r
+ if (fifo_read(dac2_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {\r
memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2);\r
dac_underflow++;\r
}\r
\r
for(i=0; i<DAC_BUF_SZ/2; i++) {\r
sam = (int)signed_buf[i] + 32768;\r
- dac_buf[i] = (unsigned short)(sam);\r
+ dac2_buf[i] = (unsigned short)(sam);\r
}\r
\r
/* Clear DMA Stream Transfer Complete interrupt pending bit */\r
DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_HTIF6); \r
}\r
\r
- /* Transfer complete interrupt */\r
+ /* Transfer complete interrupt - refill 2nd half */\r
\r
if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_TCIF6) != RESET) {\r
/* fill second half from fifo */\r
\r
- if (fifo_read(DMA1_Stream6_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {\r
+ if (fifo_read(dac2_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {\r
memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2);\r
dac_underflow++;\r
}\r
\r
for(i=0; i<DAC_BUF_SZ/2; i++) {\r
sam = (int)signed_buf[i] + 32768;\r
- dac_buf[i+DAC_BUF_SZ/2] = (unsigned short)(sam);\r
+ dac2_buf[i+DAC_BUF_SZ/2] = (unsigned short)(sam);\r
}\r
\r
/* Clear DMA Stream Transfer Complete interrupt pending bit */\r
DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6); \r
}\r
}\r
+\r