mbed library sources

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Wed Jul 01 09:45:11 2015 +0100
Revision:
579:53297373a894
Child:
592:a274ee790e56
Synchronized with git revision d5b4d2ab9c47edb4dc5776e7177b0c2263459081

Full URL: https://github.com/mbedmicro/mbed/commit/d5b4d2ab9c47edb4dc5776e7177b0c2263459081/

Initial version of drivers for SAMR21

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 579:53297373a894 1 /**
mbed_official 579:53297373a894 2 * \file
mbed_official 579:53297373a894 3 *
mbed_official 579:53297373a894 4 * \brief SAM TC - Timer Counter Driver
mbed_official 579:53297373a894 5 *
mbed_official 579:53297373a894 6 * Copyright (C) 2013-2014 Atmel Corporation. All rights reserved.
mbed_official 579:53297373a894 7 *
mbed_official 579:53297373a894 8 * \asf_license_start
mbed_official 579:53297373a894 9 *
mbed_official 579:53297373a894 10 * \page License
mbed_official 579:53297373a894 11 *
mbed_official 579:53297373a894 12 * Redistribution and use in source and binary forms, with or without
mbed_official 579:53297373a894 13 * modification, are permitted provided that the following conditions are met:
mbed_official 579:53297373a894 14 *
mbed_official 579:53297373a894 15 * 1. Redistributions of source code must retain the above copyright notice,
mbed_official 579:53297373a894 16 * this list of conditions and the following disclaimer.
mbed_official 579:53297373a894 17 *
mbed_official 579:53297373a894 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
mbed_official 579:53297373a894 19 * this list of conditions and the following disclaimer in the documentation
mbed_official 579:53297373a894 20 * and/or other materials provided with the distribution.
mbed_official 579:53297373a894 21 *
mbed_official 579:53297373a894 22 * 3. The name of Atmel may not be used to endorse or promote products derived
mbed_official 579:53297373a894 23 * from this software without specific prior written permission.
mbed_official 579:53297373a894 24 *
mbed_official 579:53297373a894 25 * 4. This software may only be redistributed and used in connection with an
mbed_official 579:53297373a894 26 * Atmel microcontroller product.
mbed_official 579:53297373a894 27 *
mbed_official 579:53297373a894 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
mbed_official 579:53297373a894 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
mbed_official 579:53297373a894 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
mbed_official 579:53297373a894 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
mbed_official 579:53297373a894 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
mbed_official 579:53297373a894 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
mbed_official 579:53297373a894 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
mbed_official 579:53297373a894 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
mbed_official 579:53297373a894 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
mbed_official 579:53297373a894 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
mbed_official 579:53297373a894 38 * POSSIBILITY OF SUCH DAMAGE.
mbed_official 579:53297373a894 39 *
mbed_official 579:53297373a894 40 * \asf_license_stop
mbed_official 579:53297373a894 41 *
mbed_official 579:53297373a894 42 */
mbed_official 579:53297373a894 43 /**
mbed_official 579:53297373a894 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
mbed_official 579:53297373a894 45 */
mbed_official 579:53297373a894 46
mbed_official 579:53297373a894 47 #include "tc.h"
mbed_official 579:53297373a894 48
mbed_official 579:53297373a894 49 //#if TC_ASYNC == true // TEMP: Commented by V
mbed_official 579:53297373a894 50 # include "tc_interrupt.h"
mbed_official 579:53297373a894 51 # include <system_interrupt.h>
mbed_official 579:53297373a894 52
mbed_official 579:53297373a894 53 /** \internal
mbed_official 579:53297373a894 54 * Converts a given TC index to its interrupt vector index.
mbed_official 579:53297373a894 55 */
mbed_official 579:53297373a894 56 # define _TC_INTERRUPT_VECT_NUM(n, unused) \
mbed_official 579:53297373a894 57 SYSTEM_INTERRUPT_MODULE_TC##n,
mbed_official 579:53297373a894 58 //#endif
mbed_official 579:53297373a894 59
mbed_official 579:53297373a894 60 #if !defined(__DOXYGEN__)
mbed_official 579:53297373a894 61 # define _TC_GCLK_ID(n,unused) TPASTE3(TC,n,_GCLK_ID) ,
mbed_official 579:53297373a894 62 # define _TC_PM_APBCMASK(n,unused) TPASTE2(PM_APBCMASK_TC,n) ,
mbed_official 579:53297373a894 63
mbed_official 579:53297373a894 64 # define TC_INST_GCLK_ID { MRECURSION(TC_INST_NUM, _TC_GCLK_ID, TC_INST_MAX_ID) }
mbed_official 579:53297373a894 65 # define TC_INST_PM_APBCMASK { MRECURSION(TC_INST_NUM, _TC_PM_APBCMASK, TC_INST_MAX_ID) }
mbed_official 579:53297373a894 66
mbed_official 579:53297373a894 67 #endif
mbed_official 579:53297373a894 68
mbed_official 579:53297373a894 69 /**
mbed_official 579:53297373a894 70 * \internal Find the index of given TC module instance.
mbed_official 579:53297373a894 71 *
mbed_official 579:53297373a894 72 * \param[in] TC module instance pointer.
mbed_official 579:53297373a894 73 *
mbed_official 579:53297373a894 74 * \return Index of the given TC module instance.
mbed_official 579:53297373a894 75 */
mbed_official 579:53297373a894 76 uint8_t _tc_get_inst_index(
mbed_official 579:53297373a894 77 Tc *const hw)
mbed_official 579:53297373a894 78 {
mbed_official 579:53297373a894 79 /* List of available TC modules. */
mbed_official 579:53297373a894 80 Tc *const tc_modules[TC_INST_NUM] = TC_INSTS;
mbed_official 579:53297373a894 81
mbed_official 579:53297373a894 82 /* Find index for TC instance. */
mbed_official 579:53297373a894 83 for (uint32_t i = 0; i < TC_INST_NUM; i++) {
mbed_official 579:53297373a894 84 if (hw == tc_modules[i]) {
mbed_official 579:53297373a894 85 return i;
mbed_official 579:53297373a894 86 }
mbed_official 579:53297373a894 87 }
mbed_official 579:53297373a894 88
mbed_official 579:53297373a894 89 /* Invalid data given. */
mbed_official 579:53297373a894 90 Assert(false);
mbed_official 579:53297373a894 91 return 0;
mbed_official 579:53297373a894 92 }
mbed_official 579:53297373a894 93
mbed_official 579:53297373a894 94
mbed_official 579:53297373a894 95 /**
mbed_official 579:53297373a894 96 * \brief Initializes a hardware TC module instance.
mbed_official 579:53297373a894 97 *
mbed_official 579:53297373a894 98 * Enables the clock and initializes the TC module, based on the given
mbed_official 579:53297373a894 99 * configuration values.
mbed_official 579:53297373a894 100 *
mbed_official 579:53297373a894 101 * \param[in,out] module_inst Pointer to the software module instance struct
mbed_official 579:53297373a894 102 * \param[in] hw Pointer to the TC hardware module
mbed_official 579:53297373a894 103 * \param[in] config Pointer to the TC configuration options struct
mbed_official 579:53297373a894 104 *
mbed_official 579:53297373a894 105 * \return Status of the initialization procedure.
mbed_official 579:53297373a894 106 *
mbed_official 579:53297373a894 107 * \retval STATUS_OK The module was initialized successfully
mbed_official 579:53297373a894 108 * \retval STATUS_BUSY Hardware module was busy when the
mbed_official 579:53297373a894 109 * initialization procedure was attempted
mbed_official 579:53297373a894 110 * \retval STATUS_INVALID_ARG An invalid configuration option or argument
mbed_official 579:53297373a894 111 * was supplied
mbed_official 579:53297373a894 112 * \retval STATUS_ERR_DENIED Hardware module was already enabled, or the
mbed_official 579:53297373a894 113 * hardware module is configured in 32-bit
mbed_official 579:53297373a894 114 * slave mode
mbed_official 579:53297373a894 115 */
mbed_official 579:53297373a894 116 enum status_code tc_init(
mbed_official 579:53297373a894 117 struct tc_module *const module_inst,
mbed_official 579:53297373a894 118 Tc *const hw,
mbed_official 579:53297373a894 119 const struct tc_config *const config)
mbed_official 579:53297373a894 120 {
mbed_official 579:53297373a894 121 /* Sanity check arguments */
mbed_official 579:53297373a894 122 Assert(hw);
mbed_official 579:53297373a894 123 Assert(module_inst);
mbed_official 579:53297373a894 124 Assert(config);
mbed_official 579:53297373a894 125
mbed_official 579:53297373a894 126 /* Temporary variable to hold all updates to the CTRLA
mbed_official 579:53297373a894 127 * register before they are written to it */
mbed_official 579:53297373a894 128 uint16_t ctrla_tmp = 0;
mbed_official 579:53297373a894 129 /* Temporary variable to hold all updates to the CTRLBSET
mbed_official 579:53297373a894 130 * register before they are written to it */
mbed_official 579:53297373a894 131 uint8_t ctrlbset_tmp = 0;
mbed_official 579:53297373a894 132 /* Temporary variable to hold all updates to the CTRLC
mbed_official 579:53297373a894 133 * register before they are written to it */
mbed_official 579:53297373a894 134 uint8_t ctrlc_tmp = 0;
mbed_official 579:53297373a894 135 /* Temporary variable to hold TC instance number */
mbed_official 579:53297373a894 136 uint8_t instance = _tc_get_inst_index(hw);
mbed_official 579:53297373a894 137
mbed_official 579:53297373a894 138 /* Array of GLCK ID for different TC instances */
mbed_official 579:53297373a894 139 uint8_t inst_gclk_id[] = TC_INST_GCLK_ID;
mbed_official 579:53297373a894 140 /* Array of PM APBC mask bit position for different TC instances */
mbed_official 579:53297373a894 141 uint16_t inst_pm_apbmask[] = TC_INST_PM_APBCMASK;
mbed_official 579:53297373a894 142
mbed_official 579:53297373a894 143 struct system_pinmux_config pin_config;
mbed_official 579:53297373a894 144 struct system_gclk_chan_config gclk_chan_config;
mbed_official 579:53297373a894 145
mbed_official 579:53297373a894 146 //#if TC_ASYNC == true // TEMP: Commented by V
mbed_official 579:53297373a894 147 /* Initialize parameters */
mbed_official 579:53297373a894 148 for (uint8_t i = 0; i < TC_CALLBACK_N; i++) {
mbed_official 579:53297373a894 149 module_inst->callback[i] = NULL;
mbed_official 579:53297373a894 150 }
mbed_official 579:53297373a894 151 module_inst->register_callback_mask = 0x00;
mbed_official 579:53297373a894 152 module_inst->enable_callback_mask = 0x00;
mbed_official 579:53297373a894 153
mbed_official 579:53297373a894 154 /* Register this instance for callbacks*/
mbed_official 579:53297373a894 155 _tc_instances[instance] = module_inst;
mbed_official 579:53297373a894 156 //#endif
mbed_official 579:53297373a894 157
mbed_official 579:53297373a894 158 /* Associate the given device instance with the hardware module */
mbed_official 579:53297373a894 159 module_inst->hw = hw;
mbed_official 579:53297373a894 160
mbed_official 579:53297373a894 161 #if SAMD10 || SAMD11
mbed_official 579:53297373a894 162 /* Check if even numbered TC modules are being configured in 32-bit
mbed_official 579:53297373a894 163 * counter size. Only odd numbered counters are allowed to be
mbed_official 579:53297373a894 164 * configured in 32-bit counter size.
mbed_official 579:53297373a894 165 */
mbed_official 579:53297373a894 166 if ((config->counter_size == TC_COUNTER_SIZE_32BIT) &&
mbed_official 579:53297373a894 167 !((instance + TC_INSTANCE_OFFSET) & 0x01)) {
mbed_official 579:53297373a894 168 Assert(false);
mbed_official 579:53297373a894 169 return STATUS_ERR_INVALID_ARG;
mbed_official 579:53297373a894 170 }
mbed_official 579:53297373a894 171 #else
mbed_official 579:53297373a894 172 /* Check if odd numbered TC modules are being configured in 32-bit
mbed_official 579:53297373a894 173 * counter size. Only even numbered counters are allowed to be
mbed_official 579:53297373a894 174 * configured in 32-bit counter size.
mbed_official 579:53297373a894 175 */
mbed_official 579:53297373a894 176 if ((config->counter_size == TC_COUNTER_SIZE_32BIT) &&
mbed_official 579:53297373a894 177 ((instance + TC_INSTANCE_OFFSET) & 0x01)) {
mbed_official 579:53297373a894 178 Assert(false);
mbed_official 579:53297373a894 179 return STATUS_ERR_INVALID_ARG;
mbed_official 579:53297373a894 180 }
mbed_official 579:53297373a894 181 #endif
mbed_official 579:53297373a894 182
mbed_official 579:53297373a894 183 /* Make the counter size variable in the module_inst struct reflect
mbed_official 579:53297373a894 184 * the counter size in the module
mbed_official 579:53297373a894 185 */
mbed_official 579:53297373a894 186 module_inst->counter_size = config->counter_size;
mbed_official 579:53297373a894 187
mbed_official 579:53297373a894 188 if (hw->COUNT8.CTRLA.reg & TC_CTRLA_SWRST) {
mbed_official 579:53297373a894 189 /* We are in the middle of a reset. Abort. */
mbed_official 579:53297373a894 190 return STATUS_BUSY;
mbed_official 579:53297373a894 191 }
mbed_official 579:53297373a894 192
mbed_official 579:53297373a894 193 if (hw->COUNT8.STATUS.reg & TC_STATUS_SLAVE) {
mbed_official 579:53297373a894 194 /* Module is used as a slave */
mbed_official 579:53297373a894 195 return STATUS_ERR_DENIED;
mbed_official 579:53297373a894 196 }
mbed_official 579:53297373a894 197
mbed_official 579:53297373a894 198 if (hw->COUNT8.CTRLA.reg & TC_CTRLA_ENABLE) {
mbed_official 579:53297373a894 199 /* Module must be disabled before initialization. Abort. */
mbed_official 579:53297373a894 200 return STATUS_ERR_DENIED;
mbed_official 579:53297373a894 201 }
mbed_official 579:53297373a894 202
mbed_official 579:53297373a894 203 /* Set up the TC PWM out pin for channel 0 */
mbed_official 579:53297373a894 204 if (config->pwm_channel[0].enabled) {
mbed_official 579:53297373a894 205 system_pinmux_get_config_defaults(&pin_config);
mbed_official 579:53297373a894 206 pin_config.mux_position = config->pwm_channel[0].pin_mux;
mbed_official 579:53297373a894 207 pin_config.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
mbed_official 579:53297373a894 208 system_pinmux_pin_set_config(
mbed_official 579:53297373a894 209 config->pwm_channel[0].pin_out, &pin_config);
mbed_official 579:53297373a894 210 }
mbed_official 579:53297373a894 211
mbed_official 579:53297373a894 212 /* Set up the TC PWM out pin for channel 1 */
mbed_official 579:53297373a894 213 if (config->pwm_channel[1].enabled) {
mbed_official 579:53297373a894 214 system_pinmux_get_config_defaults(&pin_config);
mbed_official 579:53297373a894 215 pin_config.mux_position = config->pwm_channel[1].pin_mux;
mbed_official 579:53297373a894 216 pin_config.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
mbed_official 579:53297373a894 217 system_pinmux_pin_set_config(
mbed_official 579:53297373a894 218 config->pwm_channel[1].pin_out, &pin_config);
mbed_official 579:53297373a894 219 }
mbed_official 579:53297373a894 220
mbed_official 579:53297373a894 221 /* Enable the user interface clock in the PM */
mbed_official 579:53297373a894 222 system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC,
mbed_official 579:53297373a894 223 inst_pm_apbmask[instance]);
mbed_official 579:53297373a894 224
mbed_official 579:53297373a894 225 /* Enable the slave counter if counter_size is 32-bit */
mbed_official 579:53297373a894 226 if ((config->counter_size == TC_COUNTER_SIZE_32BIT)) {
mbed_official 579:53297373a894 227 /* Enable the user interface clock in the PM */
mbed_official 579:53297373a894 228 system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC,
mbed_official 579:53297373a894 229 inst_pm_apbmask[instance + 1]);
mbed_official 579:53297373a894 230 }
mbed_official 579:53297373a894 231
mbed_official 579:53297373a894 232 /* Setup clock for module */
mbed_official 579:53297373a894 233 system_gclk_chan_get_config_defaults(&gclk_chan_config);
mbed_official 579:53297373a894 234 gclk_chan_config.source_generator = config->clock_source;
mbed_official 579:53297373a894 235 system_gclk_chan_set_config(inst_gclk_id[instance], &gclk_chan_config);
mbed_official 579:53297373a894 236 system_gclk_chan_enable(inst_gclk_id[instance]);
mbed_official 579:53297373a894 237
mbed_official 579:53297373a894 238 /* Set ctrla register */
mbed_official 579:53297373a894 239 ctrla_tmp =
mbed_official 579:53297373a894 240 (uint32_t)config->counter_size |
mbed_official 579:53297373a894 241 (uint32_t)config->wave_generation |
mbed_official 579:53297373a894 242 (uint32_t)config->reload_action |
mbed_official 579:53297373a894 243 (uint32_t)config->clock_prescaler;
mbed_official 579:53297373a894 244
mbed_official 579:53297373a894 245 if (config->run_in_standby) {
mbed_official 579:53297373a894 246 ctrla_tmp |= TC_CTRLA_RUNSTDBY;
mbed_official 579:53297373a894 247 }
mbed_official 579:53297373a894 248
mbed_official 579:53297373a894 249 /* Write configuration to register */
mbed_official 579:53297373a894 250 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 251 /* Wait for sync */
mbed_official 579:53297373a894 252 }
mbed_official 579:53297373a894 253 hw->COUNT8.CTRLA.reg = ctrla_tmp;
mbed_official 579:53297373a894 254
mbed_official 579:53297373a894 255 /* Set ctrlb register */
mbed_official 579:53297373a894 256 if (config->oneshot) {
mbed_official 579:53297373a894 257 ctrlbset_tmp = TC_CTRLBSET_ONESHOT;
mbed_official 579:53297373a894 258 }
mbed_official 579:53297373a894 259
mbed_official 579:53297373a894 260 if (config->count_direction) {
mbed_official 579:53297373a894 261 ctrlbset_tmp |= TC_CTRLBSET_DIR;
mbed_official 579:53297373a894 262 }
mbed_official 579:53297373a894 263
mbed_official 579:53297373a894 264 /* Clear old ctrlb configuration */
mbed_official 579:53297373a894 265 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 266 /* Wait for sync */
mbed_official 579:53297373a894 267 }
mbed_official 579:53297373a894 268 hw->COUNT8.CTRLBCLR.reg = 0xFF;
mbed_official 579:53297373a894 269
mbed_official 579:53297373a894 270 /* Check if we actually need to go into a wait state. */
mbed_official 579:53297373a894 271 if (ctrlbset_tmp) {
mbed_official 579:53297373a894 272 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 273 /* Wait for sync */
mbed_official 579:53297373a894 274 }
mbed_official 579:53297373a894 275 /* Write configuration to register */
mbed_official 579:53297373a894 276 hw->COUNT8.CTRLBSET.reg = ctrlbset_tmp;
mbed_official 579:53297373a894 277 }
mbed_official 579:53297373a894 278
mbed_official 579:53297373a894 279 /* Set ctrlc register*/
mbed_official 579:53297373a894 280 ctrlc_tmp = config->waveform_invert_output;
mbed_official 579:53297373a894 281 for (uint8_t i = 0; i < NUMBER_OF_COMPARE_CAPTURE_CHANNELS; i++) {
mbed_official 579:53297373a894 282 if (config->enable_capture_on_channel[i] == true) {
mbed_official 579:53297373a894 283 ctrlc_tmp |= (TC_CTRLC_CPTEN(1) << i);
mbed_official 579:53297373a894 284 }
mbed_official 579:53297373a894 285 }
mbed_official 579:53297373a894 286
mbed_official 579:53297373a894 287 /* Write configuration to register */
mbed_official 579:53297373a894 288 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 289 /* Wait for sync */
mbed_official 579:53297373a894 290 }
mbed_official 579:53297373a894 291 hw->COUNT8.CTRLC.reg = ctrlc_tmp;
mbed_official 579:53297373a894 292
mbed_official 579:53297373a894 293 /* Write configuration to register */
mbed_official 579:53297373a894 294 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 295 /* Wait for sync */
mbed_official 579:53297373a894 296 }
mbed_official 579:53297373a894 297
mbed_official 579:53297373a894 298 /* Switch for TC counter size */
mbed_official 579:53297373a894 299 switch (module_inst->counter_size) {
mbed_official 579:53297373a894 300 case TC_COUNTER_SIZE_8BIT:
mbed_official 579:53297373a894 301 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 302 /* Wait for sync */
mbed_official 579:53297373a894 303 }
mbed_official 579:53297373a894 304
mbed_official 579:53297373a894 305 hw->COUNT8.COUNT.reg =
mbed_official 579:53297373a894 306 config->counter_8_bit.value;
mbed_official 579:53297373a894 307
mbed_official 579:53297373a894 308
mbed_official 579:53297373a894 309 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 310 /* Wait for sync */
mbed_official 579:53297373a894 311 }
mbed_official 579:53297373a894 312
mbed_official 579:53297373a894 313 hw->COUNT8.PER.reg =
mbed_official 579:53297373a894 314 config->counter_8_bit.period;
mbed_official 579:53297373a894 315
mbed_official 579:53297373a894 316 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 317 /* Wait for sync */
mbed_official 579:53297373a894 318 }
mbed_official 579:53297373a894 319
mbed_official 579:53297373a894 320 hw->COUNT8.CC[0].reg =
mbed_official 579:53297373a894 321 config->counter_8_bit.compare_capture_channel[0];
mbed_official 579:53297373a894 322
mbed_official 579:53297373a894 323 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 324 /* Wait for sync */
mbed_official 579:53297373a894 325 }
mbed_official 579:53297373a894 326
mbed_official 579:53297373a894 327 hw->COUNT8.CC[1].reg =
mbed_official 579:53297373a894 328 config->counter_8_bit.compare_capture_channel[1];
mbed_official 579:53297373a894 329
mbed_official 579:53297373a894 330 return STATUS_OK;
mbed_official 579:53297373a894 331
mbed_official 579:53297373a894 332 case TC_COUNTER_SIZE_16BIT:
mbed_official 579:53297373a894 333 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 334 /* Wait for sync */
mbed_official 579:53297373a894 335 }
mbed_official 579:53297373a894 336
mbed_official 579:53297373a894 337 hw->COUNT16.COUNT.reg
mbed_official 579:53297373a894 338 = config->counter_16_bit.value;
mbed_official 579:53297373a894 339
mbed_official 579:53297373a894 340 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 341 /* Wait for sync */
mbed_official 579:53297373a894 342 }
mbed_official 579:53297373a894 343
mbed_official 579:53297373a894 344 hw->COUNT16.CC[0].reg =
mbed_official 579:53297373a894 345 config->counter_16_bit.compare_capture_channel[0];
mbed_official 579:53297373a894 346
mbed_official 579:53297373a894 347 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 348 /* Wait for sync */
mbed_official 579:53297373a894 349 }
mbed_official 579:53297373a894 350
mbed_official 579:53297373a894 351 hw->COUNT16.CC[1].reg =
mbed_official 579:53297373a894 352 config->counter_16_bit.compare_capture_channel[1];
mbed_official 579:53297373a894 353
mbed_official 579:53297373a894 354 return STATUS_OK;
mbed_official 579:53297373a894 355
mbed_official 579:53297373a894 356 case TC_COUNTER_SIZE_32BIT:
mbed_official 579:53297373a894 357 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 358 /* Wait for sync */
mbed_official 579:53297373a894 359 }
mbed_official 579:53297373a894 360
mbed_official 579:53297373a894 361 hw->COUNT32.COUNT.reg
mbed_official 579:53297373a894 362 = config->counter_32_bit.value;
mbed_official 579:53297373a894 363
mbed_official 579:53297373a894 364 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 365 /* Wait for sync */
mbed_official 579:53297373a894 366 }
mbed_official 579:53297373a894 367
mbed_official 579:53297373a894 368 hw->COUNT32.CC[0].reg =
mbed_official 579:53297373a894 369 config->counter_32_bit.compare_capture_channel[0];
mbed_official 579:53297373a894 370
mbed_official 579:53297373a894 371 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 372 /* Wait for sync */
mbed_official 579:53297373a894 373 }
mbed_official 579:53297373a894 374
mbed_official 579:53297373a894 375 hw->COUNT32.CC[1].reg =
mbed_official 579:53297373a894 376 config->counter_32_bit.compare_capture_channel[1];
mbed_official 579:53297373a894 377
mbed_official 579:53297373a894 378 return STATUS_OK;
mbed_official 579:53297373a894 379 }
mbed_official 579:53297373a894 380
mbed_official 579:53297373a894 381 Assert(false);
mbed_official 579:53297373a894 382 return STATUS_ERR_INVALID_ARG;
mbed_official 579:53297373a894 383 }
mbed_official 579:53297373a894 384
mbed_official 579:53297373a894 385 /**
mbed_official 579:53297373a894 386 * \brief Sets TC module count value.
mbed_official 579:53297373a894 387 *
mbed_official 579:53297373a894 388 * Sets the current timer count value of a initialized TC module. The
mbed_official 579:53297373a894 389 * specified TC module may be started or stopped.
mbed_official 579:53297373a894 390 *
mbed_official 579:53297373a894 391 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 579:53297373a894 392 * \param[in] count New timer count value to set
mbed_official 579:53297373a894 393 *
mbed_official 579:53297373a894 394 * \return Status of the count update procedure.
mbed_official 579:53297373a894 395 *
mbed_official 579:53297373a894 396 * \retval STATUS_OK The timer count was updated successfully
mbed_official 579:53297373a894 397 * \retval STATUS_ERR_INVALID_ARG An invalid timer counter size was specified
mbed_official 579:53297373a894 398 */
mbed_official 579:53297373a894 399 enum status_code tc_set_count_value(
mbed_official 579:53297373a894 400 const struct tc_module *const module_inst,
mbed_official 579:53297373a894 401 const uint32_t count)
mbed_official 579:53297373a894 402 {
mbed_official 579:53297373a894 403 /* Sanity check arguments */
mbed_official 579:53297373a894 404 Assert(module_inst);
mbed_official 579:53297373a894 405 Assert(module_inst->hw);
mbed_official 579:53297373a894 406
mbed_official 579:53297373a894 407 /* Get a pointer to the module's hardware instance*/
mbed_official 579:53297373a894 408 Tc *const tc_module = module_inst->hw;
mbed_official 579:53297373a894 409
mbed_official 579:53297373a894 410 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 411 /* Wait for sync */
mbed_official 579:53297373a894 412 }
mbed_official 579:53297373a894 413
mbed_official 579:53297373a894 414 /* Write to based on the TC counter_size */
mbed_official 579:53297373a894 415 switch (module_inst->counter_size) {
mbed_official 579:53297373a894 416 case TC_COUNTER_SIZE_8BIT:
mbed_official 579:53297373a894 417 tc_module->COUNT8.COUNT.reg = (uint8_t)count;
mbed_official 579:53297373a894 418 return STATUS_OK;
mbed_official 579:53297373a894 419
mbed_official 579:53297373a894 420 case TC_COUNTER_SIZE_16BIT:
mbed_official 579:53297373a894 421 tc_module->COUNT16.COUNT.reg = (uint16_t)count;
mbed_official 579:53297373a894 422 return STATUS_OK;
mbed_official 579:53297373a894 423
mbed_official 579:53297373a894 424 case TC_COUNTER_SIZE_32BIT:
mbed_official 579:53297373a894 425 tc_module->COUNT32.COUNT.reg = (uint32_t)count;
mbed_official 579:53297373a894 426 return STATUS_OK;
mbed_official 579:53297373a894 427
mbed_official 579:53297373a894 428 default:
mbed_official 579:53297373a894 429 return STATUS_ERR_INVALID_ARG;
mbed_official 579:53297373a894 430 }
mbed_official 579:53297373a894 431 }
mbed_official 579:53297373a894 432
mbed_official 579:53297373a894 433 /**
mbed_official 579:53297373a894 434 * \brief Get TC module count value.
mbed_official 579:53297373a894 435 *
mbed_official 579:53297373a894 436 * Retrieves the current count value of a TC module. The specified TC module
mbed_official 579:53297373a894 437 * may be started or stopped.
mbed_official 579:53297373a894 438 *
mbed_official 579:53297373a894 439 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 579:53297373a894 440 *
mbed_official 579:53297373a894 441 * \return Count value of the specified TC module.
mbed_official 579:53297373a894 442 */
mbed_official 579:53297373a894 443 uint32_t tc_get_count_value(
mbed_official 579:53297373a894 444 const struct tc_module *const module_inst)
mbed_official 579:53297373a894 445 {
mbed_official 579:53297373a894 446 /* Sanity check arguments */
mbed_official 579:53297373a894 447 Assert(module_inst);
mbed_official 579:53297373a894 448 Assert(module_inst->hw);
mbed_official 579:53297373a894 449
mbed_official 579:53297373a894 450 /* Get a pointer to the module's hardware instance */
mbed_official 579:53297373a894 451 Tc *const tc_module = module_inst->hw;
mbed_official 579:53297373a894 452
mbed_official 579:53297373a894 453 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 454 /* Wait for sync */
mbed_official 579:53297373a894 455 }
mbed_official 579:53297373a894 456
mbed_official 579:53297373a894 457 /* Read from based on the TC counter size */
mbed_official 579:53297373a894 458 switch (module_inst->counter_size) {
mbed_official 579:53297373a894 459 case TC_COUNTER_SIZE_8BIT:
mbed_official 579:53297373a894 460 return (uint32_t)tc_module->COUNT8.COUNT.reg;
mbed_official 579:53297373a894 461
mbed_official 579:53297373a894 462 case TC_COUNTER_SIZE_16BIT:
mbed_official 579:53297373a894 463 return (uint32_t)tc_module->COUNT16.COUNT.reg;
mbed_official 579:53297373a894 464
mbed_official 579:53297373a894 465 case TC_COUNTER_SIZE_32BIT:
mbed_official 579:53297373a894 466 return tc_module->COUNT32.COUNT.reg;
mbed_official 579:53297373a894 467 }
mbed_official 579:53297373a894 468
mbed_official 579:53297373a894 469 Assert(false);
mbed_official 579:53297373a894 470 return 0;
mbed_official 579:53297373a894 471 }
mbed_official 579:53297373a894 472
mbed_official 579:53297373a894 473 /**
mbed_official 579:53297373a894 474 * \brief Gets the TC module capture value.
mbed_official 579:53297373a894 475 *
mbed_official 579:53297373a894 476 * Retrieves the capture value in the indicated TC module capture channel.
mbed_official 579:53297373a894 477 *
mbed_official 579:53297373a894 478 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 579:53297373a894 479 * \param[in] channel_index Index of the Compare Capture channel to read
mbed_official 579:53297373a894 480 *
mbed_official 579:53297373a894 481 * \return Capture value stored in the specified timer channel.
mbed_official 579:53297373a894 482 */
mbed_official 579:53297373a894 483 uint32_t tc_get_capture_value(
mbed_official 579:53297373a894 484 const struct tc_module *const module_inst,
mbed_official 579:53297373a894 485 const enum tc_compare_capture_channel channel_index)
mbed_official 579:53297373a894 486 {
mbed_official 579:53297373a894 487 /* Sanity check arguments */
mbed_official 579:53297373a894 488 Assert(module_inst);
mbed_official 579:53297373a894 489 Assert(module_inst->hw);
mbed_official 579:53297373a894 490
mbed_official 579:53297373a894 491 /* Get a pointer to the module's hardware instance */
mbed_official 579:53297373a894 492 Tc *const tc_module = module_inst->hw;
mbed_official 579:53297373a894 493
mbed_official 579:53297373a894 494 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 495 /* Wait for sync */
mbed_official 579:53297373a894 496 }
mbed_official 579:53297373a894 497
mbed_official 579:53297373a894 498 /* Read out based on the TC counter size */
mbed_official 579:53297373a894 499 switch (module_inst->counter_size) {
mbed_official 579:53297373a894 500 case TC_COUNTER_SIZE_8BIT:
mbed_official 579:53297373a894 501 if (channel_index <
mbed_official 579:53297373a894 502 NUMBER_OF_COMPARE_CAPTURE_CHANNELS) {
mbed_official 579:53297373a894 503 return tc_module->COUNT8.CC[channel_index].reg;
mbed_official 579:53297373a894 504 }
mbed_official 579:53297373a894 505
mbed_official 579:53297373a894 506 case TC_COUNTER_SIZE_16BIT:
mbed_official 579:53297373a894 507 if (channel_index <
mbed_official 579:53297373a894 508 NUMBER_OF_COMPARE_CAPTURE_CHANNELS) {
mbed_official 579:53297373a894 509 return tc_module->COUNT16.CC[channel_index].reg;
mbed_official 579:53297373a894 510 }
mbed_official 579:53297373a894 511
mbed_official 579:53297373a894 512 case TC_COUNTER_SIZE_32BIT:
mbed_official 579:53297373a894 513 if (channel_index <
mbed_official 579:53297373a894 514 NUMBER_OF_COMPARE_CAPTURE_CHANNELS) {
mbed_official 579:53297373a894 515 return tc_module->COUNT32.CC[channel_index].reg;
mbed_official 579:53297373a894 516 }
mbed_official 579:53297373a894 517 }
mbed_official 579:53297373a894 518
mbed_official 579:53297373a894 519 Assert(false);
mbed_official 579:53297373a894 520 return 0;
mbed_official 579:53297373a894 521 }
mbed_official 579:53297373a894 522
mbed_official 579:53297373a894 523 /**
mbed_official 579:53297373a894 524 * \brief Sets a TC module compare value.
mbed_official 579:53297373a894 525 *
mbed_official 579:53297373a894 526 * Writes a compare value to the given TC module compare/capture channel.
mbed_official 579:53297373a894 527 *
mbed_official 579:53297373a894 528 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 579:53297373a894 529 * \param[in] channel_index Index of the compare channel to write to
mbed_official 579:53297373a894 530 * \param[in] compare New compare value to set
mbed_official 579:53297373a894 531 *
mbed_official 579:53297373a894 532 * \return Status of the compare update procedure.
mbed_official 579:53297373a894 533 *
mbed_official 579:53297373a894 534 * \retval STATUS_OK The compare value was updated successfully
mbed_official 579:53297373a894 535 * \retval STATUS_ERR_INVALID_ARG An invalid channel index was supplied
mbed_official 579:53297373a894 536 */
mbed_official 579:53297373a894 537 enum status_code tc_set_compare_value(
mbed_official 579:53297373a894 538 const struct tc_module *const module_inst,
mbed_official 579:53297373a894 539 const enum tc_compare_capture_channel channel_index,
mbed_official 579:53297373a894 540 const uint32_t compare)
mbed_official 579:53297373a894 541 {
mbed_official 579:53297373a894 542 /* Sanity check arguments */
mbed_official 579:53297373a894 543 Assert(module_inst);
mbed_official 579:53297373a894 544 Assert(module_inst->hw);
mbed_official 579:53297373a894 545
mbed_official 579:53297373a894 546 /* Get a pointer to the module's hardware instance */
mbed_official 579:53297373a894 547 Tc *const tc_module = module_inst->hw;
mbed_official 579:53297373a894 548
mbed_official 579:53297373a894 549 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 550 /* Wait for sync */
mbed_official 579:53297373a894 551 }
mbed_official 579:53297373a894 552
mbed_official 579:53297373a894 553 /* Read out based on the TC counter size */
mbed_official 579:53297373a894 554 switch (module_inst->counter_size) {
mbed_official 579:53297373a894 555 case TC_COUNTER_SIZE_8BIT:
mbed_official 579:53297373a894 556 if (channel_index <
mbed_official 579:53297373a894 557 NUMBER_OF_COMPARE_CAPTURE_CHANNELS) {
mbed_official 579:53297373a894 558 tc_module->COUNT8.CC[channel_index].reg =
mbed_official 579:53297373a894 559 (uint8_t)compare;
mbed_official 579:53297373a894 560 return STATUS_OK;
mbed_official 579:53297373a894 561 }
mbed_official 579:53297373a894 562
mbed_official 579:53297373a894 563 case TC_COUNTER_SIZE_16BIT:
mbed_official 579:53297373a894 564 if (channel_index <
mbed_official 579:53297373a894 565 NUMBER_OF_COMPARE_CAPTURE_CHANNELS) {
mbed_official 579:53297373a894 566 tc_module->COUNT16.CC[channel_index].reg =
mbed_official 579:53297373a894 567 (uint16_t)compare;
mbed_official 579:53297373a894 568 return STATUS_OK;
mbed_official 579:53297373a894 569 }
mbed_official 579:53297373a894 570
mbed_official 579:53297373a894 571 case TC_COUNTER_SIZE_32BIT:
mbed_official 579:53297373a894 572 if (channel_index <
mbed_official 579:53297373a894 573 NUMBER_OF_COMPARE_CAPTURE_CHANNELS) {
mbed_official 579:53297373a894 574 tc_module->COUNT32.CC[channel_index].reg =
mbed_official 579:53297373a894 575 (uint32_t)compare;
mbed_official 579:53297373a894 576 return STATUS_OK;
mbed_official 579:53297373a894 577 }
mbed_official 579:53297373a894 578 }
mbed_official 579:53297373a894 579
mbed_official 579:53297373a894 580 return STATUS_ERR_INVALID_ARG;
mbed_official 579:53297373a894 581 }
mbed_official 579:53297373a894 582
mbed_official 579:53297373a894 583 /**
mbed_official 579:53297373a894 584 * \brief Resets the TC module.
mbed_official 579:53297373a894 585 *
mbed_official 579:53297373a894 586 * Resets the TC module, restoring all hardware module registers to their
mbed_official 579:53297373a894 587 * default values and disabling the module. The TC module will not be
mbed_official 579:53297373a894 588 * accessible while the reset is being performed.
mbed_official 579:53297373a894 589 *
mbed_official 579:53297373a894 590 * \note When resetting a 32-bit counter only the master TC module's instance
mbed_official 579:53297373a894 591 * structure should be passed to the function.
mbed_official 579:53297373a894 592 *
mbed_official 579:53297373a894 593 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 579:53297373a894 594 *
mbed_official 579:53297373a894 595 * \return Status of the procedure.
mbed_official 579:53297373a894 596 * \retval STATUS_OK The module was reset successfully
mbed_official 579:53297373a894 597 * \retval STATUS_ERR_UNSUPPORTED_DEV A 32-bit slave TC module was passed to
mbed_official 579:53297373a894 598 * the function. Only use reset on master
mbed_official 579:53297373a894 599 * TC.
mbed_official 579:53297373a894 600 */
mbed_official 579:53297373a894 601 enum status_code tc_reset(
mbed_official 579:53297373a894 602 const struct tc_module *const module_inst)
mbed_official 579:53297373a894 603 {
mbed_official 579:53297373a894 604 /* Sanity check arguments */
mbed_official 579:53297373a894 605 Assert(module_inst);
mbed_official 579:53297373a894 606 Assert(module_inst->hw);
mbed_official 579:53297373a894 607
mbed_official 579:53297373a894 608 /* Get a pointer to the module hardware instance */
mbed_official 579:53297373a894 609 TcCount8 *const tc_module = &(module_inst->hw->COUNT8);
mbed_official 579:53297373a894 610
mbed_official 579:53297373a894 611 if (tc_module->STATUS.reg & TC_STATUS_SLAVE) {
mbed_official 579:53297373a894 612 return STATUS_ERR_UNSUPPORTED_DEV;
mbed_official 579:53297373a894 613 }
mbed_official 579:53297373a894 614
mbed_official 579:53297373a894 615 /* Disable this module if it is running */
mbed_official 579:53297373a894 616 if (tc_module->CTRLA.reg & TC_CTRLA_ENABLE) {
mbed_official 579:53297373a894 617 tc_disable(module_inst);
mbed_official 579:53297373a894 618 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 619 /* wait while module is disabling */
mbed_official 579:53297373a894 620 }
mbed_official 579:53297373a894 621 }
mbed_official 579:53297373a894 622
mbed_official 579:53297373a894 623 /* Reset this TC module */
mbed_official 579:53297373a894 624 tc_module->CTRLA.reg |= TC_CTRLA_SWRST;
mbed_official 579:53297373a894 625
mbed_official 579:53297373a894 626 return STATUS_OK;
mbed_official 579:53297373a894 627 }
mbed_official 579:53297373a894 628
mbed_official 579:53297373a894 629 /**
mbed_official 579:53297373a894 630 * \brief Set the timer TOP/period value.
mbed_official 579:53297373a894 631 *
mbed_official 579:53297373a894 632 * For 8-bit counter size this function writes the top value to the period
mbed_official 579:53297373a894 633 * register.
mbed_official 579:53297373a894 634 *
mbed_official 579:53297373a894 635 * For 16- and 32-bit counter size this function writes the top value to
mbed_official 579:53297373a894 636 * Capture Compare register 0. The value in this register can not be used for
mbed_official 579:53297373a894 637 * any other purpose.
mbed_official 579:53297373a894 638 *
mbed_official 579:53297373a894 639 * \note This function is designed to be used in PWM or frequency
mbed_official 579:53297373a894 640 * match modes only. When the counter is set to 16- or 32-bit counter
mbed_official 579:53297373a894 641 * size. In 8-bit counter size it will always be possible to change the
mbed_official 579:53297373a894 642 * top value even in normal mode.
mbed_official 579:53297373a894 643 *
mbed_official 579:53297373a894 644 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 579:53297373a894 645 * \param[in] top_value New timer TOP value to set
mbed_official 579:53297373a894 646 *
mbed_official 579:53297373a894 647 * \return Status of the TOP set procedure.
mbed_official 579:53297373a894 648 *
mbed_official 579:53297373a894 649 * \retval STATUS_OK The timer TOP value was updated successfully
mbed_official 579:53297373a894 650 * \retval STATUS_ERR_INVALID_ARG The configured TC module counter size in the
mbed_official 579:53297373a894 651 * module instance is invalid.
mbed_official 579:53297373a894 652 */
mbed_official 579:53297373a894 653 enum status_code tc_set_top_value (
mbed_official 579:53297373a894 654 const struct tc_module *const module_inst,
mbed_official 579:53297373a894 655 const uint32_t top_value)
mbed_official 579:53297373a894 656 {
mbed_official 579:53297373a894 657 Assert(module_inst);
mbed_official 579:53297373a894 658 Assert(module_inst->hw);
mbed_official 579:53297373a894 659 Assert(top_value);
mbed_official 579:53297373a894 660
mbed_official 579:53297373a894 661 Tc *const tc_module = module_inst->hw;
mbed_official 579:53297373a894 662
mbed_official 579:53297373a894 663 while (tc_is_syncing(module_inst)) {
mbed_official 579:53297373a894 664 /* Wait for sync */
mbed_official 579:53297373a894 665 }
mbed_official 579:53297373a894 666
mbed_official 579:53297373a894 667 switch (module_inst->counter_size) {
mbed_official 579:53297373a894 668 case TC_COUNTER_SIZE_8BIT:
mbed_official 579:53297373a894 669 tc_module->COUNT8.PER.reg = (uint8_t)top_value;
mbed_official 579:53297373a894 670 return STATUS_OK;
mbed_official 579:53297373a894 671
mbed_official 579:53297373a894 672 case TC_COUNTER_SIZE_16BIT:
mbed_official 579:53297373a894 673 tc_module->COUNT16.CC[0].reg = (uint16_t)top_value;
mbed_official 579:53297373a894 674 return STATUS_OK;
mbed_official 579:53297373a894 675
mbed_official 579:53297373a894 676 case TC_COUNTER_SIZE_32BIT:
mbed_official 579:53297373a894 677 tc_module->COUNT32.CC[0].reg = (uint32_t)top_value;
mbed_official 579:53297373a894 678 return STATUS_OK;
mbed_official 579:53297373a894 679
mbed_official 579:53297373a894 680 default:
mbed_official 579:53297373a894 681 Assert(false);
mbed_official 579:53297373a894 682 return STATUS_ERR_INVALID_ARG;
mbed_official 579:53297373a894 683 }
mbed_official 579:53297373a894 684 }