1 | #include <asf.h>
|
2 |
|
3 | /**
|
4 | * Device Revision definition
|
5 | */
|
6 | #define DEVICE_REVISION_MASK (0xFu << 8)
|
7 | #define DEVICE_REVISION_MASK_POS (8u)
|
8 | #define DEV_REV_A (0x0)
|
9 | #define DEV_REV_B (0x1)
|
10 | #define DEV_REV_C (0x2)
|
11 |
|
12 | struct rtc_module rtc_instance;
|
13 | uint32_t device_rev = 0;
|
14 |
|
15 | /*
|
16 | * switch_main_clock
|
17 | */
|
18 | void switch_main_clock(void);
|
19 |
|
20 | /*! \brief Initialize timer
|
21 | *
|
22 | */
|
23 | void timer_init( void );
|
24 |
|
25 | /*! \brief RTC timer overflow callback
|
26 | *
|
27 | */
|
28 | void rtc_overflow_callback(void);
|
29 |
|
30 | /*! \brief Configure the RTC timer callback
|
31 | *
|
32 | */
|
33 | void configure_rtc_callbacks(void);
|
34 |
|
35 | /*! \brief Configure the RTC timer count after which interrupts comes
|
36 | *
|
37 | */
|
38 | void configure_rtc_count(void);
|
39 |
|
40 | /*! \brief Set timer period.Called from Qdebug when application
|
41 | * has to change the touch time measurement
|
42 | */
|
43 | void set_timer_period(void);
|
44 |
|
45 | /*! \brief RTC timer overflow callback
|
46 | *
|
47 | */
|
48 | void rtc_overflow_callback(void)
|
49 | {
|
50 | /* Do something on RTC overflow here */
|
51 | touch_time.time_to_measure_touch = 1;
|
52 | touch_time.current_time_ms = touch_time.current_time_ms +
|
53 | touch_time.measurement_period_ms;
|
54 | }
|
55 |
|
56 | /*! \brief Configure the RTC timer callback
|
57 | *
|
58 | */
|
59 | void configure_rtc_callbacks(void)
|
60 | {
|
61 | /* register callback */
|
62 | rtc_count_register_callback(&rtc_instance,
|
63 | rtc_overflow_callback, RTC_COUNT_CALLBACK_OVERFLOW);
|
64 | /* Enable callback */
|
65 | rtc_count_enable_callback(&rtc_instance, RTC_COUNT_CALLBACK_OVERFLOW);
|
66 | }
|
67 |
|
68 | /*! \brief Configure the RTC timer count after which interrupts comes
|
69 | *
|
70 | */
|
71 | void configure_rtc_count(void)
|
72 | {
|
73 | struct rtc_count_config config_rtc_count;
|
74 | rtc_count_get_config_defaults(&config_rtc_count);
|
75 | #if ((SAMC20) || (SAMC21))
|
76 | config_rtc_count.prescaler = RTC_MODE0_CTRLA_PRESCALER_DIV32;
|
77 | #else
|
78 | config_rtc_count.prescaler = RTC_MODE0_CTRL_PRESCALER_DIV2;
|
79 | #endif
|
80 | config_rtc_count.mode = RTC_COUNT_MODE_16BIT;
|
81 | #ifdef FEATURE_RTC_CONTINUOUSLY_UPDATED
|
82 | config_rtc_count.continuously_update = true;
|
83 | #endif
|
84 | /* initialize rtc */
|
85 | rtc_count_init(&rtc_instance, RTC, &config_rtc_count);
|
86 |
|
87 | /* enable rtc */
|
88 | rtc_count_enable(&rtc_instance);
|
89 | }
|
90 |
|
91 | /*! \brief Initialize timer
|
92 | *
|
93 | */
|
94 | void timer_init(void)
|
95 | {
|
96 | /* Configure and enable RTC */
|
97 | configure_rtc_count();
|
98 |
|
99 | /* Configure and enable callback */
|
100 | configure_rtc_callbacks();
|
101 |
|
102 | /* Set Timer Period */
|
103 |
|
104 | rtc_count_set_period(&rtc_instance, DEF_TOUCH_MEASUREMENT_PERIOD_MS);
|
105 | }
|
106 |
|
107 | /*! \brief Set timer period.Called from Qdebug when application
|
108 | * has to change the touch time measurement
|
109 | */
|
110 | void set_timer_period(void )
|
111 | {
|
112 | rtc_count_set_period(&rtc_instance, touch_time.measurement_period_ms);
|
113 | }
|
114 |
|
115 | #if ((SAMC20) || (SAMC21))
|
116 | void switch_main_clock(void)
|
117 | {
|
118 | /* Update OSC48M Pre-scaler */
|
119 | struct system_clock_source_osc48m_config osc48m_config_ptr;
|
120 |
|
121 | system_clock_source_osc48m_get_config_defaults(&osc48m_config_ptr);
|
122 |
|
123 | osc48m_config_ptr.div = SYSTEM_OSC48M_DIV_1;
|
124 | osc48m_config_ptr.on_demand = false;
|
125 | osc48m_config_ptr.run_in_standby = true;
|
126 | system_clock_source_osc48m_set_config(&osc48m_config_ptr);
|
127 |
|
128 | struct system_gclk_gen_config gclk_conf;
|
129 | system_gclk_gen_get_config_defaults(&gclk_conf);
|
130 | gclk_conf.source_clock = SYSTEM_CLOCK_SOURCE_OSC48M;
|
131 | gclk_conf.division_factor = 1; //Pre-scaler
|
132 | gclk_conf.run_in_standby = false;
|
133 | gclk_conf.output_enable = false;
|
134 | system_gclk_gen_set_config(GCLK_GENERATOR_0, &gclk_conf);
|
135 | system_gclk_gen_enable(GCLK_GENERATOR_0);
|
136 |
|
137 | /* GCLK 1 - Main clock pre-scaled for PTC */
|
138 | system_gclk_gen_get_config_defaults(&gclk_conf);
|
139 | gclk_conf.source_clock = SYSTEM_CLOCK_SOURCE_OSC48M;
|
140 | gclk_conf.division_factor = 12; //Pre-scaler
|
141 | gclk_conf.run_in_standby = true;
|
142 | gclk_conf.output_enable = false;
|
143 | system_gclk_gen_set_config(GCLK_GENERATOR_1, &gclk_conf);
|
144 | system_gclk_gen_enable(GCLK_GENERATOR_1);
|
145 |
|
146 | /* Disable DPLL and corresponding GCLK */
|
147 | system_clock_source_disable(SYSTEM_CLOCK_SOURCE_DPLL);
|
148 | system_gclk_gen_disable(GCLK_GENERATOR_2);
|
149 |
|
150 | /* Set on demand bit of OSC48M to one */
|
151 | osc48m_config_ptr.on_demand = true;
|
152 | system_clock_source_osc48m_set_config(&osc48m_config_ptr);
|
153 | }
|
154 | #endif
|
155 |
|
156 | /*! \brief Main function
|
157 | *
|
158 | */
|
159 | int main(void)
|
160 | {
|
161 | /**
|
162 | * Initialize and configure system and generic clocks.
|
163 | * Use conf_clocks.h to configure system and generic clocks.
|
164 | * This example project uses Internal 8MHz oscillator.
|
165 | * The PTC module clock is provided using GCLK generator 1.
|
166 | */
|
167 | system_init();
|
168 |
|
169 | #if ((SAMC20) || (SAMC21))
|
170 | device_rev = ((DSU->DID.reg & DEVICE_REVISION_MASK) >> DEVICE_REVISION_MASK_POS);
|
171 |
|
172 | if(device_rev >= DEV_REV_C)
|
173 | {
|
174 | /* configure the cpu clock to OSC48MHz, and enable required GCLKs*/
|
175 | switch_main_clock();
|
176 | }
|
177 | #endif
|
178 | /**
|
179 | * Initialize delay service.
|
180 | */
|
181 | delay_init();
|
182 |
|
183 | //LED0
|
184 |
|
185 | struct system_pinmux_config config_pinmux;
|
186 | system_pinmux_get_config_defaults(&config_pinmux);
|
187 | config_pinmux.mux_position = SYSTEM_PINMUX_GPIO;
|
188 | config_pinmux.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
|
189 | system_pinmux_pin_set_config(PIN_PA00, &config_pinmux);
|
190 |
|
191 | // ... other pin configs ...
|
192 |
|
193 | // LED1
|
194 | system_pinmux_get_config_defaults(&config_pinmux);
|
195 | config_pinmux.mux_position = SYSTEM_PINMUX_GPIO;
|
196 | config_pinmux.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
|
197 | system_pinmux_pin_set_config(PIN_PA01, &config_pinmux);
|
198 |
|
199 | //port_pin_set_output_level(PIN_PA00, true);
|
200 |
|
201 | /**
|
202 | * Initialize timer.
|
203 | * This example projects uses RTC timer for providing timing
|
204 | * info to QTouch library.
|
205 | */
|
206 | timer_init();
|
207 |
|
208 | /**
|
209 | * Initialize QTouch library and configure touch sensors.
|
210 | */
|
211 | touch_sensors_init();
|
212 |
|
213 | /* Configure System Sleep mode to standby MODE. */
|
214 |
|
215 | system_set_sleepmode(SYSTEM_SLEEPMODE_STANDBY);
|
216 |
|
217 |
|
218 | while (1) {
|
219 | /**
|
220 | * Goto STANDBY sleep mode, unless woken by timer or PTC
|
221 | *interrupt.
|
222 | */
|
223 | system_sleep();
|
224 |
|
225 | /**
|
226 | * Start touch sensor measurement, if
|
227 | *touch_time.time_to_measure_touch flag is set by timer.
|
228 | */
|
229 | touch_sensors_measure();
|
230 | if ((p_selfcap_measure_data->measurement_done_touch == 1u)) {
|
231 | port_pin_set_output_level(PIN_PA01, true);
|
232 | uint8_t sensor_state = GET_SELFCAP_SENSOR_STATE(0);
|
233 | if(sensor_state > 0) {
|
234 | port_pin_set_output_level(PIN_PA00, true);
|
235 | }
|
236 |
|
237 | }
|
238 |
|
239 | /**
|
240 | * Update touch status once measurement complete flag is set.
|
241 | */
|
242 |
|
243 | /**
|
244 | * Self Cap method
|
245 | * if ((p_selfcap_measure_data->measurement_done_touch == 1u))
|
246 | * for self cap
|
247 | * Touch sensor ON/OFF status or rotor/slider position.
|
248 | *
|
249 | * Self Cap method
|
250 | * uint8_t sensor_state =
|
251 | * GET_SELFCAP_SENSOR_STATE(SENSOR_NUMBER);
|
252 | * uint8_t rotor_slider_position =
|
253 | * GET_SELFCAP_ROTOR_SLIDER_POSITION(SENSOR_NUMBER);
|
254 | *
|
255 | */
|
256 |
|
257 | /**
|
258 | * Mutual Cap method
|
259 | * if ((p_mutlcap_measure_data->measurement_done_touch == 1u))
|
260 | * for mutual cap
|
261 | * Touch sensor ON/OFF status or rotor/slider position.
|
262 | *
|
263 | *
|
264 | * uint8_t sensor_state =
|
265 | * GET_MUTLCAP_SENSOR_STATE(SENSOR_NUMBER);
|
266 | * uint8_t rotor_slider_position =
|
267 | * GET_MUTLCAP_ROTOR_SLIDER_POSITION(SENSOR_NUMBER);
|
268 | */
|
269 | }
|
270 | }
|