modified DAC driver to be two channels for SM1000, not tested yet
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 11 Jul 2014 06:57:38 +0000 (06:57 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 11 Jul 2014 06:57:38 +0000 (06:57 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1756 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/stm32/src/dac_play.c
codec2-dev/stm32/src/dac_ut.c
codec2-dev/stm32/src/power_ut.c
codec2-dev/stm32/src/stm32f4_dac.c

index ba0ec1ab6aba434d269545f033d0125f82bacb92..afed3f8cc7c3c8b8a206775f796c34f40c435969 100644 (file)
@@ -4,7 +4,7 @@
   AUTHOR......: David Rowe\r
   DATE CREATED: 1 June 2013\r
 \r
-  Plays a 16 kHz sample rate raw file to the STM32F4 DAC.\r
+  Plays a 16 kHz sample rate raw file to the STM32F4 pin PA5.\r
 \r
 \*---------------------------------------------------------------------------*/\r
 \r
@@ -47,7 +47,7 @@ int main(void) {
         printf("Starting!\n");\r
 \r
         while(fread(buf, sizeof(short), N, fplay) == N) {\r
-            while(dac_write(buf, N) == -1);\r
+            while(dac2_write(buf, N) == -1);\r
         }  \r
 \r
         printf("Finished!\n");\r
index 139dc75918ec4e59949033d50898c1657b29ad0f..58f8ac4d4c6d8466675963b502d063d246f99de0 100644 (file)
@@ -4,7 +4,8 @@
   AUTHOR......: David Rowe\r
   DATE CREATED: May 31 2013\r
 \r
-  Plays a 500 Hz sine wave sampled at 16 kHz out of PA5 on a Discovery board.\r
+  Plays a 500 Hz sine wave sampled at 16 kHz out of PA5 on a Discovery board,\r
+  or the speaker output of the SM1000.\r
 \r
 \*---------------------------------------------------------------------------*/\r
 \r
@@ -43,18 +44,13 @@ short aSine[] = {
 };\r
 \r
 int main(void) {\r
-    int i;\r
-\r
-    //for(i=0; i<32; i++)\r
-    //    aSine[i] /= 2;\r
-\r
     dac_open();\r
 \r
     while (1) {\r
 \r
         /* keep DAC FIFO topped up */\r
 \r
-        dac_write((short*)aSine, SINE_SAMPLES);\r
+        dac1_write((short*)aSine, SINE_SAMPLES);\r
     }\r
    \r
 }\r
index c094aef87dc1f124cd1ff25146c293d3a8094d9f..fc45a8ea4ebac99e43dcf0f6f88c8709ba174b3c 100644 (file)
@@ -5,7 +5,7 @@
   DATE CREATED: 30 May 2014\r
 \r
   Runs Codec 2, ADC, and DAC, to fully exercise STM32C so we can a feel for\r
-  run-time power consumption for SmartMic and hence dimension regulators.\r
+  run-time power consumption for SM1000 and hence dimension regulators.\r
 \r
 \*---------------------------------------------------------------------------*/\r
 \r
@@ -51,7 +51,7 @@
 \r
 #define SPEED_TEST_SAMPLES 24000\r
 \r
-/* modifiaction of test used to measure codec2 execuation speed.  We read/write ADC/DAC\r
+/* modification of test used to measure codec2 execuation speed.  We read/write ADC/DAC\r
    but dont do anything with the samples, as they are at 16 kHz and codec needs 8 kHz.  Just\r
    trying to exercise everything to get a feel for power consumption */\r
 \r
@@ -101,7 +101,7 @@ static void c2speedtest(int mode, char inputfile[])
        codec2_decode(codec2, outbuf, bits);\r
         \r
         //printf("write to DAC\n");\r
-        while(dac_write(dummy_buf, nsam*2) == -1); /* runs at Fs = 16kHz */\r
+        while(dac1_write(dummy_buf, nsam*2) == -1); /* runs at Fs = 16kHz */\r
         //printf(".");\r
     }\r
 \r
index caa43ce3a8410eb9ee3dc2fad2eae952fdb76e0f..973dd5b87995129f4eb2f61bc77987ad548bfd85 100644 (file)
 \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
@@ -77,35 +73,36 @@ void dac_open(void) {
     /* 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
@@ -121,6 +118,7 @@ static void TIM6_Config(void)
   ----------------------------------------------------------- */\r
 \r
   /* Time base configuration */\r
+\r
   TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); \r
   TIM_TimeBaseStructure.TIM_Period = 5250;          \r
   TIM_TimeBaseStructure.TIM_Prescaler = 0;       \r
@@ -133,30 +131,86 @@ static void TIM6_Config(void)
   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
@@ -172,6 +226,7 @@ static void DAC_Ch2_Config(void)
   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
@@ -183,12 +238,15 @@ static void DAC_Ch2_Config(void)
   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
@@ -200,19 +258,72 @@ static void DAC_Ch2_Config(void)
 /******************************************************************************/\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
@@ -221,7 +332,7 @@ void DMA1_Stream6_IRQHandler(void) {
 \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
@@ -229,12 +340,12 @@ void DMA1_Stream6_IRQHandler(void) {
         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
@@ -243,7 +354,7 @@ void DMA1_Stream6_IRQHandler(void) {
 \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
@@ -251,3 +362,4 @@ void DMA1_Stream6_IRQHandler(void) {
         DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6);  \r
     }\r
 }\r
+\r