mco unittest, used when debugging USB DFU
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 18 Jun 2016 00:14:48 +0000 (00:14 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 18 Jun 2016 00:14:48 +0000 (00:14 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2826 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/stm32/src/tm_stm32f4_gpio.c [new file with mode: 0644]
codec2-dev/stm32/src/tm_stm32f4_mco_output.c [new file with mode: 0644]

diff --git a/codec2-dev/stm32/src/tm_stm32f4_gpio.c b/codec2-dev/stm32/src/tm_stm32f4_gpio.c
new file mode 100644 (file)
index 0000000..7089632
--- /dev/null
@@ -0,0 +1,238 @@
+/**    
+ * |----------------------------------------------------------------------
+ * | Copyright (C) Tilen Majerle, 2015
+ * | 
+ * | This program is free software: you can redistribute it and/or modify
+ * | it under the terms of the GNU General Public License as published by
+ * | the Free Software Foundation, either version 3 of the License, or
+ * | any later version.
+ * |  
+ * | 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 General Public License
+ * | along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * |----------------------------------------------------------------------
+ */
+#include "tm_stm32f4_gpio.h"
+
+/* Private function */
+static uint16_t GPIO_UsedPins[11] = {0,0,0,0,0,0,0,0,0,0,0};
+
+/* Private functions */
+void TM_GPIO_INT_EnableClock(GPIO_TypeDef* GPIOx);
+void TM_GPIO_INT_DisableClock(GPIO_TypeDef* GPIOx);
+void TM_GPIO_INT_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_Mode_t GPIO_Mode, TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd, TM_GPIO_Speed_t GPIO_Speed);
+
+void TM_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_Mode_t GPIO_Mode, TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd, TM_GPIO_Speed_t GPIO_Speed) {        
+       /* Check input */
+       if (GPIO_Pin == 0x00) {
+               return;
+       }
+       
+       /* Enable clock for GPIO */
+       TM_GPIO_INT_EnableClock(GPIOx);
+       
+       /* Do initialization */
+       TM_GPIO_INT_Init(GPIOx, GPIO_Pin, GPIO_Mode, GPIO_OType, GPIO_PuPd, GPIO_Speed);
+}
+
+void TM_GPIO_InitAlternate(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd, TM_GPIO_Speed_t GPIO_Speed, uint8_t Alternate) {
+       uint32_t pinpos;
+
+       /* Check input */
+       if (GPIO_Pin == 0x00) {
+               return;
+       }
+       
+       /* Enable GPIOx clock */
+       TM_GPIO_INT_EnableClock(GPIOx);
+       
+       /* Set alternate functions for all pins */
+       for (pinpos = 0; pinpos < 0x10; pinpos++) {
+               /* Check pin */
+               if ((GPIO_Pin & (1 << pinpos)) == 0) {
+                       continue;
+               }
+               
+               /* Set alternate function */
+               GPIOx->AFR[pinpos >> 0x03] = (GPIOx->AFR[pinpos >> 0x03] & ~(0x0F << (4 * (pinpos & 0x07)))) | (Alternate << (4 * (pinpos & 0x07)));
+       }
+       
+       /* Do initialization */
+       TM_GPIO_INT_Init(GPIOx, GPIO_Pin, TM_GPIO_Mode_AF, GPIO_OType, GPIO_PuPd, GPIO_Speed);
+}
+
+void TM_GPIO_DeInit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
+       uint8_t i;
+       uint8_t ptr = TM_GPIO_GetPortSource(GPIOx);
+       
+       /* Go through all pins */
+       for (i = 0x00; i < 0x10; i++) {
+               /* Pin is set */
+               if (GPIO_Pin & (1 << i)) {
+                       /* Set 11 bits combination for analog mode */
+                       GPIOx->MODER |= (0x03 << (2 * i));
+                       
+                       /* Pin is not used */
+                       GPIO_UsedPins[ptr] &= ~(1 << i);
+               }
+       }
+}
+
+void TM_GPIO_SetPinAsInput(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
+       uint8_t i;
+       /* Go through all pins */
+       for (i = 0x00; i < 0x10; i++) {
+               /* Pin is set */
+               if (GPIO_Pin & (1 << i)) {
+                       /* Set 00 bits combination for input */
+                       GPIOx->MODER &= ~(0x03 << (2 * i));
+               }
+       }
+}
+
+void TM_GPIO_SetPinAsOutput(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
+       uint8_t i;
+       /* Go through all pins */
+       for (i = 0x00; i < 0x10; i++) {
+               /* Pin is set */
+               if (GPIO_Pin & (1 << i)) {
+                       /* Set 01 bits combination for output */
+                       GPIOx->MODER = (GPIOx->MODER & ~(0x03 << (2 * i))) | (0x01 << (2 * i));
+               }
+       }
+}
+
+void TM_GPIO_SetPinAsAnalog(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
+       uint8_t i;
+       /* Go through all pins */
+       for (i = 0x00; i < 0x10; i++) {
+               /* Pin is set */
+               if (GPIO_Pin & (1 << i)) {
+                       /* Set 11 bits combination for analog mode */
+                       GPIOx->MODER |= (0x03 << (2 * i));
+               }
+       }
+}
+
+void TM_GPIO_SetPinAsAlternate(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
+       uint8_t i;
+       
+       /* Set alternate functions for all pins */
+       for (i = 0; i < 0x10; i++) {
+               /* Check pin */
+               if ((GPIO_Pin & (1 << i)) == 0) {
+                       continue;
+               }
+               
+               /* Set alternate mode */
+               GPIOx->MODER = (GPIOx->MODER & ~(0x03 << (2 * i))) | (0x02 << (2 * i));
+       }
+}
+
+void TM_GPIO_SetPullResistor(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_PuPd_t GPIO_PuPd) {
+       uint8_t pinpos;
+       
+       /* Go through all pins */
+       for (pinpos = 0; pinpos < 0x10; pinpos++) {
+               /* Check if pin available */
+               if ((GPIO_Pin & (1 << pinpos)) == 0) {
+                       continue;
+               }
+
+               /* Set GPIO PUPD register */
+               GPIOx->PUPDR = (GPIOx->PUPDR & ~(0x03 << (2 * pinpos))) | ((uint32_t)(GPIO_PuPd << (2 * pinpos)));
+       }
+}
+
+void TM_GPIO_Lock(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
+       uint32_t d;
+       
+       /* Set GPIO pin with 16th bit set to 1 */
+       d = 0x00010000 | GPIO_Pin;
+       
+       /* Write to LCKR register */
+       GPIOx->LCKR = d;
+       GPIOx->LCKR = GPIO_Pin;
+       GPIOx->LCKR = d;
+       
+       /* Read twice */
+       (void)GPIOx->LCKR;
+       (void)GPIOx->LCKR;
+}
+
+uint16_t TM_GPIO_GetPinSource(uint16_t GPIO_Pin) {
+       uint16_t pinsource = 0;
+       
+       /* Get pinsource */
+       while (GPIO_Pin > 1) {
+               /* Increase pinsource */
+               pinsource++;
+               /* Shift right */
+               GPIO_Pin >>= 1;
+       }
+       
+       /* Return source */
+       return pinsource;
+}
+
+uint16_t TM_GPIO_GetPortSource(GPIO_TypeDef* GPIOx) {
+       /* Get port source number */
+       /* Offset from GPIOA                       Difference between 2 GPIO addresses */
+       return ((uint32_t)GPIOx - (GPIOA_BASE)) / ((GPIOB_BASE) - (GPIOA_BASE));
+}
+
+/* Private functions */
+void TM_GPIO_INT_EnableClock(GPIO_TypeDef* GPIOx) {
+       /* Set bit according to the 1 << portsourcenumber */
+       RCC->AHB1ENR |= (1 << TM_GPIO_GetPortSource(GPIOx));
+}
+
+void TM_GPIO_INT_DisableClock(GPIO_TypeDef* GPIOx) {
+       /* Clear bit according to the 1 << portsourcenumber */
+       RCC->AHB1ENR &= ~(1 << TM_GPIO_GetPortSource(GPIOx));
+}
+
+void TM_GPIO_INT_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_Mode_t GPIO_Mode, TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd, TM_GPIO_Speed_t GPIO_Speed) {
+       uint8_t pinpos;
+       uint8_t ptr = TM_GPIO_GetPortSource(GPIOx);
+       
+       /* Go through all pins */
+       for (pinpos = 0; pinpos < 0x10; pinpos++) {
+               /* Check if pin available */
+               if ((GPIO_Pin & (1 << pinpos)) == 0) {
+                       continue;
+               }
+               
+               /* Pin is used */
+               GPIO_UsedPins[ptr] |= 1 << pinpos;
+               
+               /* Set GPIO PUPD register */
+               GPIOx->PUPDR = (GPIOx->PUPDR & ~(0x03 << (2 * pinpos))) | ((uint32_t)(GPIO_PuPd << (2 * pinpos)));
+               
+               /* Set GPIO MODE register */
+               GPIOx->MODER = (GPIOx->MODER & ~((uint32_t)(0x03 << (2 * pinpos)))) | ((uint32_t)(GPIO_Mode << (2 * pinpos)));
+               
+               /* Set only if output or alternate functions */
+               if (GPIO_Mode == TM_GPIO_Mode_OUT || GPIO_Mode == TM_GPIO_Mode_AF) {            
+                       /* Set GPIO OTYPE register */
+                       GPIOx->OTYPER = (GPIOx->OTYPER & ~(uint16_t)(0x01 << pinpos)) | ((uint16_t)(GPIO_OType << pinpos));
+                       
+                       /* Set GPIO OSPEED register */
+                       GPIOx->OSPEEDR = (GPIOx->OSPEEDR & ~((uint32_t)(0x03 << (2 * pinpos)))) | ((uint32_t)(GPIO_Speed << (2 * pinpos)));
+               }
+       }
+}
+
+uint16_t TM_GPIO_GetUsedPins(GPIO_TypeDef* GPIOx) {
+       /* Return used */
+       return GPIO_UsedPins[TM_GPIO_GetPortSource(GPIOx)];
+}
+
+uint16_t TM_GPIO_GetFreePins(GPIO_TypeDef* GPIOx) {
+       /* Return free pins */
+       return ~GPIO_UsedPins[TM_GPIO_GetPortSource(GPIOx)];
+}
diff --git a/codec2-dev/stm32/src/tm_stm32f4_mco_output.c b/codec2-dev/stm32/src/tm_stm32f4_mco_output.c
new file mode 100644 (file)
index 0000000..3261bda
--- /dev/null
@@ -0,0 +1,128 @@
+/**    \r
+ * |----------------------------------------------------------------------\r
+ * | Copyright (C) Tilen Majerle, 2014\r
+ * | \r
+ * | This program is free software: you can redistribute it and/or modify\r
+ * | it under the terms of the GNU General Public License as published by\r
+ * | the Free Software Foundation, either version 3 of the License, or\r
+ * | any later version.\r
+ * |  \r
+ * | This program is distributed in the hope that it will be useful,\r
+ * | but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * | GNU General Public License for more details.\r
+ * | \r
+ * | You should have received a copy of the GNU General Public License\r
+ * | along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * |----------------------------------------------------------------------\r
+ */\r
+#include "tm_stm32f4_mco_output.h"\r
+\r
+void TM_MCOOUTPUT_InitMCO1(void) {\r
+       /* Enable PA8 */\r
+       TM_GPIO_Init(GPIOA, GPIO_PIN_8, TM_GPIO_Mode_AF, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);\r
+}\r
+\r
+void TM_MCOOUTPUT_InitMCO2(void) {\r
+       /* Enable PC9 */\r
+       TM_GPIO_Init(GPIOC, GPIO_PIN_9, TM_GPIO_Mode_AF, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);\r
+}\r
+\r
+void TM_MCOOUTPUT_SetOutput1(TM_MCOOUTPUT1_Source_t Source, TM_MCOOUTPUT_Prescaler_t Prescaler) {\r
+       uint32_t presc = 0, src = 0;\r
+       \r
+       /* Get prescaler */\r
+       switch (Prescaler) {\r
+               case TM_MCOOUTPUT_Prescaler_1:\r
+                       presc = RCC_MCO1Div_1;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_2:\r
+                       presc = RCC_MCO1Div_2;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_3:\r
+                       presc = RCC_MCO1Div_3;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_4:\r
+                       presc = RCC_MCO1Div_4;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_5:\r
+                       presc = RCC_MCO1Div_5;\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
+       \r
+       /* Get source */\r
+       switch (Source) {\r
+               case TM_MCOOUTPUT1_Source_HSE:\r
+                       src = RCC_MCO1Source_HSE;\r
+               \r
+                       /* Enable RCC HSE oscillator */\r
+                       RCC_HSEConfig(RCC_HSE_ON);\r
+                       break;\r
+               case TM_MCOOUTPUT1_Source_HSI:\r
+                       src = RCC_MCO1Source_HSI;\r
+                       break;\r
+               case TM_MCOOUTPUT1_Source_PLLCLK:\r
+                       src = RCC_MCO1Source_PLLCLK;\r
+                       break;\r
+               case TM_MCOOUTPUT1_Source_LSE:          \r
+                       src = RCC_MCO1Source_LSE;\r
+               \r
+                       /* Start LSE clock if available */\r
+                       RCC_LSEConfig(RCC_LSE_ON);\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
+       \r
+       \r
+       /* Set source and prescaler  */\r
+       RCC_MCO1Config(src, presc);\r
+}\r
+\r
+void TM_MCOOUTPUT_SetOutput2(TM_MCOOUTPUT2_Source_t Source, TM_MCOOUTPUT_Prescaler_t Prescaler) {\r
+       uint32_t presc, src;\r
+       \r
+       /* Get prescaler */\r
+       switch (Prescaler) {\r
+               case TM_MCOOUTPUT_Prescaler_1:\r
+                       presc = RCC_MCO2Div_1;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_2:\r
+                       presc = RCC_MCO2Div_2;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_3:\r
+                       presc = RCC_MCO2Div_3;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_4:\r
+                       presc = RCC_MCO2Div_4;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_5:\r
+                       presc = RCC_MCO2Div_5;\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
+       \r
+       /* Get clock source */\r
+       switch (Source) {\r
+               case TM_MCOOUTPUT2_Source_SYSCLK:\r
+                       src = RCC_MCO2Source_SYSCLK;\r
+                       break;\r
+               case TM_MCOOUTPUT2_Source_PLLI2SCLK:\r
+                       src = RCC_MCO2Source_PLLI2SCLK;\r
+                       break;\r
+               case TM_MCOOUTPUT2_Source_HSE:\r
+                       src = RCC_MCO2Source_HSE;\r
+                       break;\r
+               case TM_MCOOUTPUT2_Source_PLLCLK:\r
+                       src = RCC_MCO2Source_PLLCLK;\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
+       \r
+       /* Set source and prescaler  */\r
+       RCC_MCO2Config(src, presc);\r
+}\r