Determine the device parameters explicit after running
[fw/stlink] / example / 32l_dac / main.c
1 /* base headers */
2 #include "stdint.h"
3
4 /* libstm32l_discovery headers */
5 #include "stm32l1xx_gpio.h"
6 #include "stm32l1xx_adc.h"
7 #include "stm32l1xx_dac.h"
8 #include "stm32l1xx_lcd.h"
9 #include "stm32l1xx_rcc.h"
10 #include "stm32l1xx_rtc.h"
11 #include "stm32l1xx_exti.h"
12 #include "stm32l1xx_pwr.h"
13 #include "stm32l1xx_flash.h"
14 #include "stm32l1xx_syscfg.h"
15 #include "stm32l1xx_dbgmcu.h"
16
17 /* board specific macros */
18 #include "discover_board.h"
19
20
21 /* hardware configuration */
22
23 #if CONFIG_STM32VL_DISCOVERY
24
25 # define GPIOC 0x40011000 /* port C */
26 # define GPIOC_CRH (GPIOC + 0x04) /* port configuration register high */
27 # define GPIOC_ODR (GPIOC + 0x0c) /* port output data register */
28
29 # define LED_BLUE (1 << 8) /* port C, pin 8 */
30 # define LED_GREEN (1 << 9) /* port C, pin 9 */
31
32 static inline void setup_leds(void)
33 {
34   *(volatile uint32_t*)GPIOC_CRH = 0x44444411;
35 }
36
37 static inline void switch_leds_on(void)
38 {
39   *(volatile uint32_t*)GPIOC_ODR = LED_BLUE | LED_GREEN;
40 }
41
42 static inline void switch_leds_off(void)
43 {
44   *(volatile uint32_t*)GPIOC_ODR = 0;
45 }
46
47 #elif CONFIG_STM32L_DISCOVERY
48
49 # define GPIOB_MODER (GPIOB + 0x00) /* port mode register */
50 # define GPIOB_ODR (GPIOB + 0x14) /* port output data register */
51
52 # define LED_BLUE (1 << 6) /* port B, pin 6 */
53 # define LED_GREEN (1 << 7) /* port B, pin 7 */
54
55 static inline void setup_leds(void)
56 {
57   /* configure port 6 and 7 as output */
58   *(volatile uint32_t*)GPIOB_MODER |= (1 << (7 * 2)) | (1 << (6 * 2));
59 }
60
61 static inline void switch_leds_on(void)
62 {
63   GPIO_HIGH(LD_GPIO_PORT, LD_GREEN_GPIO_PIN);   
64   GPIO_HIGH(LD_GPIO_PORT, LD_BLUE_GPIO_PIN);
65 }
66
67 static inline void switch_leds_off(void)
68 {
69   GPIO_LOW(LD_GPIO_PORT, LD_GREEN_GPIO_PIN);    
70   GPIO_LOW(LD_GPIO_PORT, LD_BLUE_GPIO_PIN);
71 }
72
73 #endif /* otherwise, error */
74
75
76 #define delay()                                         \
77 do {                                                    \
78   volatile unsigned int i;                              \
79   for (i = 0; i < 1000000; ++i)                         \
80     __asm__ __volatile__ ("nop\n\t":::"memory");        \
81 } while (0)
82
83
84 static void RCC_Configuration(void)
85 {
86   /* HSI is 16mhz RC clock directly fed to SYSCLK (rm00038, figure 9) */
87
88   /* enable the HSI clock (high speed internal) */
89   RCC_HSICmd(ENABLE);
90   
91   /* wail til HSI ready */
92   while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET)
93   {}
94
95   /* at startup, SYSCLK driven by MSI. set to HSI */
96   RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
97   
98   /* set MSI to 4mhz */
99   RCC_MSIRangeConfig(RCC_MSIRange_6);
100
101   /* turn HSE off */
102   RCC_HSEConfig(RCC_HSE_OFF);  
103   if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET)
104   {
105     while (1) ;
106   }
107 }
108
109
110 static void RTC_Configuration(void)
111 {
112   /* Allow access to the RTC */
113   PWR_RTCAccessCmd(ENABLE);
114
115   /* Reset Backup Domain */
116   RCC_RTCResetCmd(ENABLE);
117   RCC_RTCResetCmd(DISABLE);
118
119   /* LSE Enable */
120   RCC_LSEConfig(RCC_LSE_ON);
121
122   /* Wait till LSE is ready */
123   while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
124   {}
125   
126   RCC_RTCCLKCmd(ENABLE);
127    
128   /* LCD Clock Source Selection */
129   RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
130
131 }
132
133 static void setup_dac1(void)
134 {
135   /* see 10.2 notes */
136
137   static GPIO_InitTypeDef GPIO_InitStructure;
138   static DAC_InitTypeDef DAC_InitStructure;
139
140   /* DAC clock path:
141      HSI (16mhz) -> SYSCLK -> HCLK(/1) -> PCLK1(/1)
142    */
143
144   /* set the AHB clock (HCLK) prescaler to 1 */
145   RCC_HCLKConfig(RCC_SYSCLK_Div1);
146
147   /* set the low speed APB clock (APB1, ie. PCLK1) prescaler to 1 */
148   RCC_PCLK1Config(RCC_HCLK_Div1);
149
150   /* enable DAC APB1 clock */
151   /* signal connections: HSI(16mhz) -> SYSCLK -> AHB */
152   RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
153
154   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; /* GPIO_Pin_5 for channel 2 */
155   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
156   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
157   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
158   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
159   GPIO_Init(GPIOA, &GPIO_InitStructure);
160
161   DAC_StructInit(&DAC_InitStructure);
162   DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
163 #if 0 /* triangle waveform generation */
164   DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_Triangle;
165   DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1;
166 #else
167   DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
168   DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
169 #endif
170   DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
171   DAC_Init(DAC_Channel_1, &DAC_InitStructure);
172
173   /* enable dac channel */
174   DAC_Cmd(DAC_Channel_1, ENABLE);
175 }
176
177 static inline void set_dac1_mv(unsigned int mv)
178 {
179   /* mv the millivolts */
180
181   /* vref in millivolts */
182   /* #define CONFIG_VREF 5000 */
183 #define CONFIG_VREF 3000
184
185   /* resolution in bits */
186 #define CONFIG_DAC_RES 12
187
188   const uint16_t n = (mv * (1 << (CONFIG_DAC_RES - 1))) / CONFIG_VREF;
189   DAC_SetChannel1Data(DAC_Align_12b_R, n);
190 }
191
192 void main(void)
193 {
194   static RCC_ClocksTypeDef RCC_Clocks;
195   static GPIO_InitTypeDef GPIO_InitStructure;
196   static uint16_t dac_value;
197   static unsigned int led_state = 0;
198
199   /* Configure Clocks for Application need */
200   RCC_Configuration();
201   
202   /* Configure RTC Clocks */
203   RTC_Configuration();
204
205 #if 0
206   /* Set internal voltage regulator to 1.8v */
207   PWR_VoltageScalingConfig(PWR_VoltageScaling_Range1);
208   /* Wait Until the Voltage Regulator is ready */
209   while (PWR_GetFlagStatus(PWR_FLAG_VOS) != RESET) ;
210 #endif
211
212   /* configure gpios */
213
214   /* Enable GPIOs clock */      
215   RCC_AHBPeriphClockCmd(LD_GPIO_PORT_CLK, ENABLE);
216
217   /* Configure the GPIO_LED pins  LD3 & LD4*/
218   GPIO_InitStructure.GPIO_Pin = LD_GREEN_GPIO_PIN | LD_BLUE_GPIO_PIN;
219   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
220   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
221   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
222   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
223   GPIO_Init(LD_GPIO_PORT, &GPIO_InitStructure);
224   GPIO_LOW(LD_GPIO_PORT, LD_GREEN_GPIO_PIN);    
225   GPIO_LOW(LD_GPIO_PORT, LD_BLUE_GPIO_PIN);
226
227   setup_dac1();
228
229   dac_value = 0;
230
231   while (1)
232   {
233     DAC_SetChannel1Data(DAC_Align_12b_R, dac_value & 0xfff);
234     dac_value += 0x10;
235
236     if (led_state & 1) switch_leds_on();
237     else switch_leds_off();
238     led_state ^= 1;
239
240     delay();
241   }
242 }