aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/demos/STM32/RT-STM32F303-DISCOVERY-PID/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/demos/STM32/RT-STM32F303-DISCOVERY-PID/main.c')
-rw-r--r--lib/chibios-contrib/demos/STM32/RT-STM32F303-DISCOVERY-PID/main.c170
1 files changed, 170 insertions, 0 deletions
diff --git a/lib/chibios-contrib/demos/STM32/RT-STM32F303-DISCOVERY-PID/main.c b/lib/chibios-contrib/demos/STM32/RT-STM32F303-DISCOVERY-PID/main.c
new file mode 100644
index 000000000..0061de61f
--- /dev/null
+++ b/lib/chibios-contrib/demos/STM32/RT-STM32F303-DISCOVERY-PID/main.c
@@ -0,0 +1,170 @@
1/*
2 ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17#include "ch.h"
18#include "hal.h"
19#include "pid.h"
20#include <stdlib.h>
21
22#define STM32_UUID ((uint32_t *)0x1FFFF7AC)
23#define ADC_GRP1_NUM_CHANNELS 1
24#define ADC_GRP1_BUF_DEPTH 8
25
26static pidc_t pid;
27static float input = 0, output = 0, target = 0;
28static adcsample_t samples[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH];
29
30/*
31 * ADC streaming callback.
32 */
33static void adccallback(ADCDriver *adcp) {
34
35 (void)adcp;
36 uint32_t i, tmp = 0;
37 if (adcIsBufferComplete(adcp)) {
38
39 for (i = 0; i < (adcp)->depth; i++) {
40 tmp += (adcp)->samples[i];
41 }
42 input = tmp / (adcp)->depth;
43
44 if (input <= target) {
45 palClearLine(LINE_LED7_GREEN);
46 palSetLine(LINE_LED6_GREEN);
47 }
48 else {
49 palClearLine(LINE_LED6_GREEN);
50 palSetLine(LINE_LED7_GREEN);
51 }
52 }
53}
54
55/*
56 * ADC conversion group.
57 * Mode: Linear buffer, 8 samples of 2 channels, SW triggered.
58 * Channels: IN0, IN8.
59 */
60static const ADCConversionGroup adcgrpcfg1 = {
61 TRUE,
62 ADC_GRP1_NUM_CHANNELS,
63 adccallback,
64 NULL,
65 ADC_CFGR_CONT, /* CFGR */
66 ADC_TR(0, 4095), /* TR1 */
67 { /* SMPR[2] */
68 ADC_SMPR1_SMP_AN1(ADC_SMPR_SMP_181P5),
69 0
70 },
71 { /* SQR[4] */
72 ADC_SQR1_SQ1_N(ADC_CHANNEL_IN1),
73 0,
74 0,
75 0
76 }
77};
78
79static const DACConfig dac1cfg1 = {
80 .init = 2047U,
81 .datamode = DAC_DHRM_12BIT_RIGHT,
82 .cr = 0
83};
84
85static void gptcb(GPTDriver *drv) {
86
87 (void)drv;
88 pid_compute(&pid);
89 dacPutChannelX(&DACD1, 0, (dacsample_t)output);
90}
91
92/*
93 * GPT6 configuration.
94 */
95static const GPTConfig gpt6cfg1 = {
96 .frequency = 10000U, // 10 KHz
97 .callback = gptcb,
98 .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */
99 .dier = 0U
100};
101
102
103/*
104 * Red LEDs blinker thread, times are in milliseconds.
105 */
106static THD_WORKING_AREA(waThread1, 128);
107static THD_FUNCTION(Thread1, arg) {
108
109 srand(osalOsGetSystemTimeX() + STM32_UUID[0]);
110
111 (void)arg;
112 chRegSetThreadName("blinker");
113 while (true) {
114 palToggleLine(LINE_LED10_RED);
115 chThdSleepMilliseconds(500);
116
117 target = 1000 + (rand() % 2500); // Change the PID target every 500ms.
118 }
119}
120
121/*
122 * Application entry point.
123 */
124int main(void) {
125
126 halInit();
127 chSysInit();
128
129 /*
130 * Set PA0 PA3 PA4 to Analog (ADC1_CH2, DAC1_CH1)
131 * You will have to connect these with a jumper wire
132 */
133 palSetPadMode(GPIOA, 1, PAL_MODE_INPUT_ANALOG);
134 palSetPadMode(GPIOA, 3, PAL_MODE_INPUT_ANALOG);
135
136 /*
137 * Start peripherals
138 */
139 adcStart(&ADCD1, NULL);
140 dacStart(&DACD1, &dac1cfg1);
141 gptStart(&GPTD6, &gpt6cfg1);
142
143 /*
144 * Start PID
145 */
146 pid_create(&pid, &input, &output, &target, 1.0, 1.0, 1.0, PID_ON_M, PID_DIRECT);
147 pid_setOutputLimits(&pid, 0.0, 4095.0); // Max DAC range
148 pid_setSampleTime(&pid, 10);
149 pid_setMode(&pid, PID_AUTOMATIC);
150
151 /*
152 * Starting a continuous conversion.
153 */
154 gptStartContinuous(&GPTD6, 101U); // 10000 / 101
155 adcStartConversion(&ADCD1, &adcgrpcfg1, samples, ADC_GRP1_BUF_DEPTH);
156
157 /*
158 * Creates the blinker thread.
159 */
160 chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
161
162 /*
163 * Normal main() thread activity.
164 */
165 while (true) {
166 chThdSleepMilliseconds(250);
167 palToggleLine(LINE_LED3_RED);
168 }
169 return 0;
170}