1 | // includes
|
2 | #include <stddef.h>
|
3 | #include <stdlib.h>
|
4 | #include "stm32l1xx.h"
|
5 | #include "halfSinus.h"
|
6 |
|
7 | // defines
|
8 | #define VREF 2920 // VREF+ (mV), nearly VDD
|
9 |
|
10 | // variables
|
11 | volatile uint16_t amplitude;
|
12 |
|
13 | // function prototypes
|
14 | void DAC_Voltage(uint8_t channel, uint16_t mV);
|
15 | uint16_t ADC_Voltage(uint8_t channel);
|
16 | void InitPeriph();
|
17 | void Delay(uint32_t c) {
|
18 | while(c--);
|
19 | }
|
20 |
|
21 | // main program
|
22 | int main() {
|
23 |
|
24 | SystemInit();
|
25 |
|
26 | //PWR_VoltageScalingConfig(PWR_VoltageScaling_Range1); // selects best performance; also set in SystemInit()
|
27 |
|
28 | // we can't use HSE because no quarz soldered in place
|
29 | /*RCC_HSEConfig(RCC_HSE_ON);
|
30 | while(!RCC_GetFlagStatus(RCC_FLAG_HSERDY));
|
31 | RCC_PLLConfig(RCC_PLLSource_HSE, RCC_PLLMul_12, RCC_PLLDiv_3);
|
32 | RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
|
33 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL);*/
|
34 |
|
35 | // use HSI instead
|
36 | RCC_HSICmd(ENABLE);
|
37 | while(!RCC_GetFlagStatus(RCC_FLAG_HSIRDY));
|
38 | // HSI can't be used as source for PLL for some reason
|
39 | RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
|
40 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_HSI);
|
41 |
|
42 | RCC_ClocksTypeDef clock;
|
43 | RCC_GetClocksFreq(&clock); // get current clockspeed -> 16MHz it says
|
44 |
|
45 | InitPeriph();
|
46 |
|
47 | amplitude = 2000;
|
48 |
|
49 | while(1) {
|
50 | // just play around with ADC: light up green LED when swiping on touchpad
|
51 | if (ADC_Voltage(14) > 1100) {
|
52 | GPIO_WriteBit(GPIOB, GPIO_Pin_7, Bit_SET);
|
53 | } else {
|
54 | GPIO_WriteBit(GPIOB, GPIO_Pin_7, Bit_RESET);
|
55 | }
|
56 | Delay(1000);
|
57 | DAC_Voltage(2, ADC_Voltage(2)); // digitalize input voltage and output on other pin, useful for calibrating VREF
|
58 | GPIO_ToggleBits(GPIOB, GPIO_Pin_6);
|
59 | }
|
60 | }
|
61 |
|
62 | // timer interrupt handler
|
63 | void TIM4_IRQHandler() {
|
64 | static uint8_t i = 0;
|
65 |
|
66 | if (TIM_GetITStatus(TIM4, TIM_IT_Update)) { // period overflow
|
67 | // clear interrupt trigger
|
68 | TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
|
69 |
|
70 | TIM3->CCR3 = halfSin[i]*511/4095;
|
71 | //TIM9->CCR1 = halfSin[i]*511/4095;
|
72 | DAC_SetChannel1Data(DAC_Align_12b_R, halfSin[i]*amplitude/VREF);
|
73 | if ((i+=2) >= 99) i = 0;
|
74 | }
|
75 | }
|
76 |
|
77 |
|
78 | // functions
|
79 | void DAC_Voltage(uint8_t channel, uint16_t mV) {
|
80 | if (channel == 1) DAC_SetChannel1Data(DAC_Align_12b_R, mV*4059/VREF);
|
81 | if (channel == 2) DAC_SetChannel2Data(DAC_Align_12b_R, mV*4059/VREF);
|
82 | }
|
83 |
|
84 | uint16_t ADC_Voltage(uint8_t channel) {
|
85 | ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_4Cycles);
|
86 | ADC_SoftwareStartConv(ADC1);
|
87 | while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
|
88 | return ADC_GetConversionValue(ADC1)*VREF/4059;
|
89 | }
|
90 |
|
91 | void InitPeriph() {
|
92 | // turn on clock for LEDs
|
93 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
|
94 | // initialize LEDs on board
|
95 | GPIO_InitTypeDef gpioInitStruct;
|
96 | gpioInitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6; // green led: PB7 , blue led: PB6
|
97 | gpioInitStruct.GPIO_Mode = GPIO_Mode_OUT;
|
98 | gpioInitStruct.GPIO_OType = GPIO_OType_PP;
|
99 | gpioInitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
100 | gpioInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
|
101 | GPIO_Init(GPIOB, &gpioInitStruct);
|
102 |
|
103 | // turn on clock for DAC
|
104 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
|
105 | // initialize DAC
|
106 | DAC_InitTypeDef dacInitStruct;
|
107 | dacInitStruct.DAC_Trigger = DAC_Trigger_None;
|
108 | dacInitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
|
109 | dacInitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None;
|
110 | // initialize both DAC channels with structure settings above
|
111 | DAC_Init(DAC_Channel_1, &dacInitStruct);
|
112 | DAC_Init(DAC_Channel_2, &dacInitStruct);
|
113 | // enable both DAC channels
|
114 | DAC_Cmd(DAC_Channel_1, ENABLE);
|
115 | DAC_Cmd(DAC_Channel_2, ENABLE);
|
116 |
|
117 | // turn on clock for ADC1
|
118 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
|
119 | /* turn on highspeed internal clock
|
120 | RCC_HSICmd(ENABLE);
|
121 | while(!RCC_GetFlagStatus(RCC_FLAG_HSIRDY)); // wait until done
|
122 | // initialize common (ADC analog clock prescaler) - wtf is this?
|
123 | ADC_CommonInitTypeDef adcCommonInitStruct;
|
124 | adcCommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div1;
|
125 | ADC_CommonInit(&adcCommonInitStruct);*/
|
126 | // initialize ADC
|
127 | ADC_InitTypeDef adcInitStruct;
|
128 | adcInitStruct.ADC_ScanConvMode = DISABLE;
|
129 | adcInitStruct.ADC_ContinuousConvMode = DISABLE;
|
130 | adcInitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;
|
131 | adcInitStruct.ADC_DataAlign = ADC_DataAlign_Right;
|
132 | adcInitStruct.ADC_NbrOfConversion = 1;
|
133 | ADC_Init(ADC1, &adcInitStruct);
|
134 | // enable ADC1
|
135 | ADC_Cmd(ADC1, ENABLE);
|
136 | while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS));
|
137 |
|
138 | // turn on clock for timer4
|
139 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
|
140 | // initialize timer
|
141 | TIM_TimeBaseInitTypeDef timInitStruct;
|
142 | timInitStruct.TIM_Prescaler = 1;
|
143 | timInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
|
144 | timInitStruct.TIM_Period = 200;
|
145 | timInitStruct.TIM_ClockDivision = 0;
|
146 | TIM_TimeBaseInit(TIM4, &timInitStruct);
|
147 | // initialize interrupts
|
148 | NVIC_InitTypeDef intInitStruct;
|
149 | intInitStruct.NVIC_IRQChannel = TIM4_IRQn;
|
150 | intInitStruct.NVIC_IRQChannelCmd = ENABLE;
|
151 | intInitStruct.NVIC_IRQChannelPreemptionPriority = 0x0F;
|
152 | intInitStruct.NVIC_IRQChannelSubPriority = 0x0F;
|
153 | NVIC_Init(&intInitStruct);
|
154 | // enable timer interrupt
|
155 | TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
|
156 | TIM_Cmd(TIM4, ENABLE);
|
157 |
|
158 | // turn on clock for timer3
|
159 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
|
160 | // initialize timer
|
161 | timInitStruct.TIM_Prescaler = 1;
|
162 | timInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
|
163 | timInitStruct.TIM_Period = 511;
|
164 | timInitStruct.TIM_ClockDivision = 0;
|
165 | TIM_TimeBaseInit(TIM3, &timInitStruct);
|
166 | // initialize pwm
|
167 | TIM_OCInitTypeDef ocInitStruct;
|
168 | ocInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
|
169 | ocInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
|
170 | ocInitStruct.TIM_OutputState = TIM_OutputState_Enable;
|
171 | ocInitStruct.TIM_Pulse = 0;
|
172 | TIM_OC3Init(TIM3, &ocInitStruct);
|
173 | TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
|
174 | TIM_Cmd(TIM3, ENABLE);
|
175 | // configure pwm pin
|
176 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
|
177 | gpioInitStruct.GPIO_Pin = GPIO_Pin_8;
|
178 | gpioInitStruct.GPIO_Mode = GPIO_Mode_AF;
|
179 | gpioInitStruct.GPIO_OType = GPIO_OType_PP;
|
180 | gpioInitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
181 | gpioInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
|
182 | GPIO_Init(GPIOC, &gpioInitStruct);
|
183 | GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_TIM3);
|
184 |
|
185 | /* turn on clock for timer9
|
186 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);
|
187 | // initialize timer
|
188 | timInitStruct.TIM_Prescaler = 1;
|
189 | timInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
|
190 | timInitStruct.TIM_Period = 511;
|
191 | timInitStruct.TIM_ClockDivision = 0;
|
192 | TIM_TimeBaseInit(TIM9, &timInitStruct);
|
193 | // initialize pwm
|
194 | TIM_OCInitTypeDef ocInitStruct;
|
195 | ocInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
|
196 | ocInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
|
197 | ocInitStruct.TIM_OutputState = TIM_OutputState_Enable;
|
198 | ocInitStruct.TIM_Pulse = 0;
|
199 | TIM_OC1Init(TIM9, &ocInitStruct);
|
200 | TIM_OC1PreloadConfig(TIM9, TIM_OCPreload_Enable);
|
201 | TIM_Cmd(TIM9, ENABLE);
|
202 | // configure pwm pin
|
203 | RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
|
204 | gpioInitStruct.GPIO_Pin = GPIO_Pin_13;
|
205 | gpioInitStruct.GPIO_Mode = GPIO_Mode_AF;
|
206 | gpioInitStruct.GPIO_OType = GPIO_OType_PP;
|
207 | gpioInitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
208 | gpioInitStruct.GPIO_Speed = GPIO_Speed_40MHz;
|
209 | GPIO_Init(GPIOB, &gpioInitStruct);
|
210 | GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_TIM9);*/
|
211 | }
|