aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/testhal/KINETIS/FRDM-KL26Z/PWM/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/testhal/KINETIS/FRDM-KL26Z/PWM/main.c')
-rw-r--r--lib/chibios-contrib/testhal/KINETIS/FRDM-KL26Z/PWM/main.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/lib/chibios-contrib/testhal/KINETIS/FRDM-KL26Z/PWM/main.c b/lib/chibios-contrib/testhal/KINETIS/FRDM-KL26Z/PWM/main.c
new file mode 100644
index 000000000..740471a54
--- /dev/null
+++ b/lib/chibios-contrib/testhal/KINETIS/FRDM-KL26Z/PWM/main.c
@@ -0,0 +1,172 @@
1/*
2 * (c) 2015 flabbergast <[email protected]>
3 * Based on ChibiOS 3.0.1 demo code, license below.
4 * Licensed under the Apache License, Version 2.0.
5 */
6
7/*
8 * ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23#include "ch.h"
24#include "hal.h"
25
26/*
27 * on FRDM-KL26Z:
28 * red LED on PTE29/TPM0_CH2 (AF3)
29 * green LED on PTE31/TPM0_CH4 (AF3)
30 * blue LED on PTD5/TPM0_CH5 (AF4)
31 */
32
33#define PWM_DRIVER PWMD1
34
35/* PWM config structure */
36/* Note: the PWM clock frequency must be so that
37 * SYSCLK / FREQ is a power of 2 between 1 and 128.
38 */
39static const PWMConfig pwmcfg = {
40 750000, /* 750kHz PWM clock frequency. */
41 1000, /* PWM period is 1000 cycles. */
42 /* meaning PWM resolution is 750 */
43 NULL, /* no callback */
44 {
45 {PWM_OUTPUT_DISABLED, NULL}, /* ch0: mode, no callback */
46 {PWM_OUTPUT_DISABLED, NULL}, /* ch1: mode, no callback */
47 {PWM_OUTPUT_ACTIVE_LOW, NULL}, /* ch2: mode, no callback */
48 {PWM_OUTPUT_DISABLED, NULL}, /* ch3: mode, no callback */
49 {PWM_OUTPUT_ACTIVE_LOW, NULL}, /* ch4: mode, no callback */
50 {PWM_OUTPUT_ACTIVE_LOW, NULL} /* ch5: mode, no callback */
51 },
52};
53
54#define BREATHE_STEP 16 /* ms; = 4000ms/TABLE_SIZE */
55
56/* Breathing Sleep LED brighness(PWM On period) table
57 *
58 * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
59 * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
60 */
61/* ruby -e "a = ((0..255).map{|x| Math.exp(Math.cos(Math::PI+(2*x*(Math::PI)/255)))-Math.exp(-1) }); m = a.max; a.map\!{|x| (10000*x/m).to_i}; p a" */
62#define TABLE_SIZE 256
63static const uint16_t breathing_table[TABLE_SIZE] = {
64 0, 0, 1, 4, 7, 11, 17, 23, 30, 38, 47, 58, 69, 81, 94, 109, 124, 141, 159, 177, 197, 218, 241, 264, 289, 315, 343, 372, 402, 433, 466, 501, 537, 574, 613, 654, 696, 741, 786, 834, 883, 935, 988, 1043, 1100, 1159, 1220, 1283, 1349, 1416, 1486, 1558, 1632, 1709, 1788, 1870, 1954, 2040, 2129, 2220, 2314, 2411, 2510, 2611, 2715, 2822, 2932, 3044, 3158, 3275, 3395, 3517, 3641, 3768, 3897, 4028, 4162, 4298, 4436, 4576, 4717, 4861, 5006, 5152, 5300, 5449, 5600, 5751, 5903, 6055, 6208, 6361, 6513, 6666, 6818, 6970, 7120, 7269, 7417, 7563, 7708, 7850, 7990, 8127, 8261, 8391, 8519, 8643, 8762, 8878, 8989, 9095, 9196, 9293, 9383, 9469, 9548, 9622, 9689, 9750, 9805, 9853, 9895, 9930, 9957, 9978, 9992, 9999, 10000, 9992, 9978, 9957, 9930, 9895, 9853, 9805, 9750, 9689, 9622, 9548, 9469, 9383, 9293, 9196, 9095, 8989, 8878, 8762, 8643, 8519, 8391, 8261, 8127, 7990, 7850, 7708, 7563, 7417, 7269, 7120, 6970, 6818, 6666, 6513, 6361, 6208, 6055, 5903, 5751, 5600, 5449, 5300, 5152, 5006, 4861, 4717, 4576, 4436, 4298, 4162, 4028, 3897, 3768, 3641, 3517, 3395, 3275, 3158, 3044, 2932, 2822, 2715, 2611, 2510, 2411, 2314, 2220, 2129, 2040, 1954, 1870, 1788, 1709, 1632, 1558, 1486, 1416, 1349, 1283, 1220, 1159, 1100, 1043, 988, 935, 883, 834, 786, 741, 696, 654, 613, 574, 537, 501, 466, 433, 402, 372, 343, 315, 289, 264, 241, 218, 197, 177, 159, 141, 124, 109, 94, 81, 69, 58, 47, 38, 30, 23, 17, 11, 7, 4, 1, 0, 0
65};
66
67uint16_t table_pos = 0;
68uint8_t active_led = 0;
69
70static THD_WORKING_AREA(waBreatheThread, 128);
71static THD_FUNCTION(BreatheThread, arg) {
72 (void)arg;
73 chRegSetThreadName("breatheThread");
74
75 while(true) {
76 switch(active_led) {
77 case 0: /* red LED */
78 pwmEnableChannel(&PWM_DRIVER, 2, PWM_PERCENTAGE_TO_WIDTH(&PWM_DRIVER,breathing_table[table_pos]));
79 break;
80 case 1: /* green LED */
81 pwmEnableChannel(&PWM_DRIVER, 4, PWM_PERCENTAGE_TO_WIDTH(&PWM_DRIVER,breathing_table[table_pos]));
82 break;
83 case 2: /* blue LED */
84 pwmEnableChannel(&PWM_DRIVER, 5, PWM_PERCENTAGE_TO_WIDTH(&PWM_DRIVER,breathing_table[table_pos]));
85 break;
86 }
87 table_pos++;
88 if(table_pos == TABLE_SIZE) {
89 table_pos = 0;
90 active_led = (active_led+1) % 3;
91 }
92 chThdSleepMilliseconds(BREATHE_STEP);
93 }
94}
95
96/*
97 * Check button thread
98 */
99static THD_WORKING_AREA(waButtonThread, 128);
100static THD_FUNCTION(ButtonThread, arg) {
101 (void)arg;
102 chRegSetThreadName("buttonThread");
103
104 uint8_t newstate, state = PAL_HIGH;
105
106 while(true) {
107 if(palReadLine(LINE_BUTTON) != state) {
108 chThdSleepMilliseconds(20); /* debounce */
109 newstate = palReadLine(LINE_BUTTON);
110 if(newstate != state) {
111 state = newstate;
112 if(newstate == PAL_LOW) {
113 table_pos = (table_pos + 120)%TABLE_SIZE;
114 }
115 }
116 }
117 chThdSleepMilliseconds(20);
118 }
119}
120
121/*
122 * Application entry point.
123 */
124int main(void) {
125 /*
126 * System initializations.
127 * - HAL initialization, this also initializes the configured device drivers
128 * and performs the board-specific initializations.
129 * - Kernel initialization, the main() function becomes a thread and the
130 * RTOS is active.
131 */
132 halInit();
133 chSysInit();
134
135 /*
136 * Turn off the RGB LED.
137 */
138 palSetLine(LINE_LED_RED); /* red */
139 palSetLine(LINE_LED_GREEN); /* green */
140 palSetLine(LINE_LED_BLUE); /* blue */
141
142 /*
143 * Create the button check thread.
144 */
145 chThdCreateStatic(waButtonThread, sizeof(waButtonThread), NORMALPRIO, ButtonThread, NULL);
146
147 /*
148 * Start the PWM driver, route TPM0 output to PTE29, PTE31, PTD5.
149 * Enable channels now to avoid a blink later.
150 */
151 pwmStart(&PWM_DRIVER, &pwmcfg);
152 palSetLineMode(LINE_LED_RED, PAL_MODE_ALTERNATIVE_3);
153 palSetLineMode(LINE_LED_GREEN, PAL_MODE_ALTERNATIVE_3);
154 palSetLineMode(LINE_LED_BLUE, PAL_MODE_ALTERNATIVE_4);
155 pwmEnableChannel(&PWM_DRIVER, 2, 0);
156 pwmEnableChannel(&PWM_DRIVER, 4, 0);
157 pwmEnableChannel(&PWM_DRIVER, 5, 0);
158
159 /*
160 * Create the breathe thread.
161 */
162 chThdCreateStatic(waBreatheThread, sizeof(waBreatheThread), NORMALPRIO, BreatheThread, NULL);
163
164 /*
165 * Normal main() thread activity, in this demo it does nothing except
166 * sleeping in a loop and check the button state, when the button is
167 * pressed ... nothing happens.
168 */
169 while(true) {
170 chThdSleepMilliseconds(500);
171 }
172}