mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Wed Nov 04 16:30:11 2015 +0000
Revision:
15:a81a8d6c1dfe
Synchronized with git revision 46af745ef4405614c3fa49abbd9a706a362ea514

Full URL: https://github.com/mbedmicro/mbed/commit/46af745ef4405614c3fa49abbd9a706a362ea514/

Renamed TARGET_SAM_CortexM0+ to TARGET_SAM_CortexM0P for compatiblity with online compiler

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 15:a81a8d6c1dfe 1 /**
mbed_official 15:a81a8d6c1dfe 2 * \file
mbed_official 15:a81a8d6c1dfe 3 *
mbed_official 15:a81a8d6c1dfe 4 * \brief SAM TCC - Timer Counter for Control Applications Driver
mbed_official 15:a81a8d6c1dfe 5 *
mbed_official 15:a81a8d6c1dfe 6 * Copyright (C) 2013-2015 Atmel Corporation. All rights reserved.
mbed_official 15:a81a8d6c1dfe 7 *
mbed_official 15:a81a8d6c1dfe 8 * \asf_license_start
mbed_official 15:a81a8d6c1dfe 9 *
mbed_official 15:a81a8d6c1dfe 10 * \page License
mbed_official 15:a81a8d6c1dfe 11 *
mbed_official 15:a81a8d6c1dfe 12 * Redistribution and use in source and binary forms, with or without
mbed_official 15:a81a8d6c1dfe 13 * modification, are permitted provided that the following conditions are met:
mbed_official 15:a81a8d6c1dfe 14 *
mbed_official 15:a81a8d6c1dfe 15 * 1. Redistributions of source code must retain the above copyright notice,
mbed_official 15:a81a8d6c1dfe 16 * this list of conditions and the following disclaimer.
mbed_official 15:a81a8d6c1dfe 17 *
mbed_official 15:a81a8d6c1dfe 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
mbed_official 15:a81a8d6c1dfe 19 * this list of conditions and the following disclaimer in the documentation
mbed_official 15:a81a8d6c1dfe 20 * and/or other materials provided with the distribution.
mbed_official 15:a81a8d6c1dfe 21 *
mbed_official 15:a81a8d6c1dfe 22 * 3. The name of Atmel may not be used to endorse or promote products derived
mbed_official 15:a81a8d6c1dfe 23 * from this software without specific prior written permission.
mbed_official 15:a81a8d6c1dfe 24 *
mbed_official 15:a81a8d6c1dfe 25 * 4. This software may only be redistributed and used in connection with an
mbed_official 15:a81a8d6c1dfe 26 * Atmel microcontroller product.
mbed_official 15:a81a8d6c1dfe 27 *
mbed_official 15:a81a8d6c1dfe 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
mbed_official 15:a81a8d6c1dfe 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
mbed_official 15:a81a8d6c1dfe 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
mbed_official 15:a81a8d6c1dfe 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
mbed_official 15:a81a8d6c1dfe 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
mbed_official 15:a81a8d6c1dfe 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
mbed_official 15:a81a8d6c1dfe 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
mbed_official 15:a81a8d6c1dfe 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
mbed_official 15:a81a8d6c1dfe 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
mbed_official 15:a81a8d6c1dfe 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
mbed_official 15:a81a8d6c1dfe 38 * POSSIBILITY OF SUCH DAMAGE.
mbed_official 15:a81a8d6c1dfe 39 *
mbed_official 15:a81a8d6c1dfe 40 * \asf_license_stop
mbed_official 15:a81a8d6c1dfe 41 *
mbed_official 15:a81a8d6c1dfe 42 */
mbed_official 15:a81a8d6c1dfe 43 /*
mbed_official 15:a81a8d6c1dfe 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
mbed_official 15:a81a8d6c1dfe 45 */
mbed_official 15:a81a8d6c1dfe 46
mbed_official 15:a81a8d6c1dfe 47 #include "tcc.h"
mbed_official 15:a81a8d6c1dfe 48
mbed_official 15:a81a8d6c1dfe 49 #if TCC_ASYNC == true
mbed_official 15:a81a8d6c1dfe 50 # include "tcc_callback.h"
mbed_official 15:a81a8d6c1dfe 51 # include <system_interrupt.h>
mbed_official 15:a81a8d6c1dfe 52
mbed_official 15:a81a8d6c1dfe 53 /** \internal
mbed_official 15:a81a8d6c1dfe 54 * Converts a given TCC index to its interrupt vector index.
mbed_official 15:a81a8d6c1dfe 55 */
mbed_official 15:a81a8d6c1dfe 56 # define _TCC_INTERRUPT_VECT_NUM(n, unused) \
mbed_official 15:a81a8d6c1dfe 57 SYSTEM_INTERRUPT_MODULE_TCC##n,
mbed_official 15:a81a8d6c1dfe 58 #endif
mbed_official 15:a81a8d6c1dfe 59
mbed_official 15:a81a8d6c1dfe 60 #define _SIZE_MAX(size) ((size==32u) ? 0xFFFFFFFF : ( \
mbed_official 15:a81a8d6c1dfe 61 (1u << size) - 1))
mbed_official 15:a81a8d6c1dfe 62
mbed_official 15:a81a8d6c1dfe 63 #define _SIZE_MAX_WITH_DITHER 0x03FFFFFF
mbed_official 15:a81a8d6c1dfe 64
mbed_official 15:a81a8d6c1dfe 65 /* Extension support mapping bits */
mbed_official 15:a81a8d6c1dfe 66 #define _TCC_DITHERING_B 16u
mbed_official 15:a81a8d6c1dfe 67 #define _TCC_PG_B 8u
mbed_official 15:a81a8d6c1dfe 68 #define _TCC_SWAP_B 4u
mbed_official 15:a81a8d6c1dfe 69 #define _TCC_DTI_B 2u
mbed_official 15:a81a8d6c1dfe 70 #define _TCC_OTMX_B 1u
mbed_official 15:a81a8d6c1dfe 71
mbed_official 15:a81a8d6c1dfe 72 #if !defined(__DOXYGEN__)
mbed_official 15:a81a8d6c1dfe 73
mbed_official 15:a81a8d6c1dfe 74 # define _TCC_GCLK_ID(n,unused) TPASTE3(TCC,n,_GCLK_ID),
mbed_official 15:a81a8d6c1dfe 75 # if (SAML21) || (SAMC20) || (SAMC21)
mbed_official 15:a81a8d6c1dfe 76 # define _TCC_APBCMASK(n,unused) TPASTE2(MCLK_APBCMASK_TCC,n),
mbed_official 15:a81a8d6c1dfe 77 # else
mbed_official 15:a81a8d6c1dfe 78 # define _TCC_APBCMASK(n,unused) TPASTE2(PM_APBCMASK_TCC,n),
mbed_official 15:a81a8d6c1dfe 79 # endif
mbed_official 15:a81a8d6c1dfe 80
mbed_official 15:a81a8d6c1dfe 81 # define _TCC_SIZE(n,unused) TPASTE3(TCC,n,_SIZE),
mbed_official 15:a81a8d6c1dfe 82 # define _TCC_MAX(n,unused) _SIZE_MAX(TPASTE3(TCC,n,_SIZE)),
mbed_official 15:a81a8d6c1dfe 83 # define _TCC_EXT(n,unused) TPASTE3(TCC,n,_EXT),
mbed_official 15:a81a8d6c1dfe 84 # define _TCC_CC_NUM(n,unused) min(TPASTE3(TCC,n,_CC_NUM),TCC_NUM_CHANNELS),
mbed_official 15:a81a8d6c1dfe 85 # define _TCC_OW_NUM(n,unused) min(TPASTE3(TCC,n,_OW_NUM),TCC_NUM_WAVE_OUTPUTS),
mbed_official 15:a81a8d6c1dfe 86
mbed_official 15:a81a8d6c1dfe 87 # define TCC_GCLK_IDS { MREPEAT(TCC_INST_NUM, _TCC_GCLK_ID, 0) }
mbed_official 15:a81a8d6c1dfe 88 # define TCC_APBCMASKS { MREPEAT(TCC_INST_NUM, _TCC_APBCMASK, 0) }
mbed_official 15:a81a8d6c1dfe 89
mbed_official 15:a81a8d6c1dfe 90 # define TCC_SIZES { MREPEAT(TCC_INST_NUM, _TCC_SIZE, 0) }
mbed_official 15:a81a8d6c1dfe 91 # define TCC_MAXS { MREPEAT(TCC_INST_NUM, _TCC_MAX, 0) }
mbed_official 15:a81a8d6c1dfe 92 # define TCC_EXTS { MREPEAT(TCC_INST_NUM, _TCC_EXT, 0) }
mbed_official 15:a81a8d6c1dfe 93 # define TCC_CC_NUMS { MREPEAT(TCC_INST_NUM, _TCC_CC_NUM, 0) }
mbed_official 15:a81a8d6c1dfe 94 # define TCC_OW_NUMS { MREPEAT(TCC_INST_NUM, _TCC_OW_NUM, 0) }
mbed_official 15:a81a8d6c1dfe 95
mbed_official 15:a81a8d6c1dfe 96 #endif
mbed_official 15:a81a8d6c1dfe 97
mbed_official 15:a81a8d6c1dfe 98 /* List of available TCC modules. */
mbed_official 15:a81a8d6c1dfe 99 const Tcc *const tcc_modules[TCC_INST_NUM] = TCC_INSTS;
mbed_official 15:a81a8d6c1dfe 100
mbed_official 15:a81a8d6c1dfe 101 /* List of TCC GCLK IDs */
mbed_official 15:a81a8d6c1dfe 102 const uint8_t _tcc_gclk_ids[TCC_INST_NUM] = TCC_GCLK_IDS;
mbed_official 15:a81a8d6c1dfe 103
mbed_official 15:a81a8d6c1dfe 104 /* List of TCC APBC Masks */
mbed_official 15:a81a8d6c1dfe 105 const uint32_t _tcc_apbcmasks[TCC_INST_NUM] = TCC_APBCMASKS;
mbed_official 15:a81a8d6c1dfe 106
mbed_official 15:a81a8d6c1dfe 107 /* List of extension support of TCC modules. */
mbed_official 15:a81a8d6c1dfe 108 const uint8_t _tcc_exts[TCC_INST_NUM] = TCC_EXTS;
mbed_official 15:a81a8d6c1dfe 109
mbed_official 15:a81a8d6c1dfe 110 /* List of sizes support of TCC modules. */
mbed_official 15:a81a8d6c1dfe 111 const uint8_t _tcc_sizes[TCC_INST_NUM] = TCC_SIZES;
mbed_official 15:a81a8d6c1dfe 112
mbed_official 15:a81a8d6c1dfe 113 /* List of maximumvalues supported of TCC modules. */
mbed_official 15:a81a8d6c1dfe 114 const uint32_t _tcc_maxs[TCC_INST_NUM] = TCC_MAXS;
mbed_official 15:a81a8d6c1dfe 115
mbed_official 15:a81a8d6c1dfe 116 /* List of available channel number of TCC modules. */
mbed_official 15:a81a8d6c1dfe 117 const uint8_t _tcc_cc_nums[TCC_INST_NUM] = TCC_CC_NUMS;
mbed_official 15:a81a8d6c1dfe 118
mbed_official 15:a81a8d6c1dfe 119 /* List of available output number of TCC modules. */
mbed_official 15:a81a8d6c1dfe 120 const uint8_t _tcc_ow_nums[TCC_INST_NUM] = TCC_OW_NUMS;
mbed_official 15:a81a8d6c1dfe 121
mbed_official 15:a81a8d6c1dfe 122 /**
mbed_official 15:a81a8d6c1dfe 123 * \internal Find the index of the given TCC module instance.
mbed_official 15:a81a8d6c1dfe 124 *
mbed_official 15:a81a8d6c1dfe 125 * \param[in] The TCC module instance pointer
mbed_official 15:a81a8d6c1dfe 126 *
mbed_official 15:a81a8d6c1dfe 127 * \return Index of the given TCC module instance.
mbed_official 15:a81a8d6c1dfe 128 */
mbed_official 15:a81a8d6c1dfe 129 uint8_t _tcc_get_inst_index(
mbed_official 15:a81a8d6c1dfe 130 Tcc *const hw)
mbed_official 15:a81a8d6c1dfe 131 {
mbed_official 15:a81a8d6c1dfe 132 /* Find index for TCC instance. */
mbed_official 15:a81a8d6c1dfe 133 for (uint32_t i = 0; i < TCC_INST_NUM; i++) {
mbed_official 15:a81a8d6c1dfe 134 if (hw == tcc_modules[i]) {
mbed_official 15:a81a8d6c1dfe 135 return i;
mbed_official 15:a81a8d6c1dfe 136 }
mbed_official 15:a81a8d6c1dfe 137 }
mbed_official 15:a81a8d6c1dfe 138
mbed_official 15:a81a8d6c1dfe 139 /* Invalid data given. */
mbed_official 15:a81a8d6c1dfe 140 Assert(false);
mbed_official 15:a81a8d6c1dfe 141 return 0;
mbed_official 15:a81a8d6c1dfe 142 }
mbed_official 15:a81a8d6c1dfe 143
mbed_official 15:a81a8d6c1dfe 144 /**
mbed_official 15:a81a8d6c1dfe 145 * \brief Initializes config with predefined default values.
mbed_official 15:a81a8d6c1dfe 146 *
mbed_official 15:a81a8d6c1dfe 147 * This function will initialize a given TCC configuration structure to
mbed_official 15:a81a8d6c1dfe 148 * a set of known default values. This function should be called on
mbed_official 15:a81a8d6c1dfe 149 * any new instance of the configuration structures before being
mbed_official 15:a81a8d6c1dfe 150 * modified by the user application.
mbed_official 15:a81a8d6c1dfe 151 *
mbed_official 15:a81a8d6c1dfe 152 * The default configuration is as follows:
mbed_official 15:a81a8d6c1dfe 153 * \li Don't run in standby
mbed_official 15:a81a8d6c1dfe 154 * \li When setting top,compare or pattern by API, do double buffering write
mbed_official 15:a81a8d6c1dfe 155 * \li The base timer/counter configurations:
mbed_official 15:a81a8d6c1dfe 156 * - GCLK generator 0 clock source
mbed_official 15:a81a8d6c1dfe 157 * - No prescaler
mbed_official 15:a81a8d6c1dfe 158 * - GCLK reload action
mbed_official 15:a81a8d6c1dfe 159 * - Count upward
mbed_official 15:a81a8d6c1dfe 160 * - Don't perform one-shot operations
mbed_official 15:a81a8d6c1dfe 161 * - Counter starts on 0
mbed_official 15:a81a8d6c1dfe 162 * - Period/top value set to maximum
mbed_official 15:a81a8d6c1dfe 163 * \li The match/capture configurations:
mbed_official 15:a81a8d6c1dfe 164 * - All Capture compare channel value set to 0
mbed_official 15:a81a8d6c1dfe 165 * - No capture enabled (all channels use compare function)
mbed_official 15:a81a8d6c1dfe 166 * - Normal frequency wave generation
mbed_official 15:a81a8d6c1dfe 167 * - Waveform generation polarity set to 0
mbed_official 15:a81a8d6c1dfe 168 * - Don't perform ramp on waveform
mbed_official 15:a81a8d6c1dfe 169 * \li The waveform extension configurations:
mbed_official 15:a81a8d6c1dfe 170 * - No recoverable fault is enabled, fault actions are disabled, filter
mbed_official 15:a81a8d6c1dfe 171 * is set to 0
mbed_official 15:a81a8d6c1dfe 172 * - No non-recoverable fault state output is enabled and filter is 0
mbed_official 15:a81a8d6c1dfe 173 * - No inversion of waveform output
mbed_official 15:a81a8d6c1dfe 174 * \li No channel output enabled
mbed_official 15:a81a8d6c1dfe 175 * \li No PWM pin output enabled
mbed_official 15:a81a8d6c1dfe 176 * \li Pin and MUX configuration not set
mbed_official 15:a81a8d6c1dfe 177 *
mbed_official 15:a81a8d6c1dfe 178 * \param[out] config Pointer to a TCC module configuration structure to set
mbed_official 15:a81a8d6c1dfe 179 * \param[in] hw Pointer to the TCC hardware module
mbed_official 15:a81a8d6c1dfe 180 *
mbed_official 15:a81a8d6c1dfe 181 */
mbed_official 15:a81a8d6c1dfe 182 void tcc_get_config_defaults(
mbed_official 15:a81a8d6c1dfe 183 struct tcc_config *const config,
mbed_official 15:a81a8d6c1dfe 184 Tcc *const hw)
mbed_official 15:a81a8d6c1dfe 185 {
mbed_official 15:a81a8d6c1dfe 186 /* TCC instance index */
mbed_official 15:a81a8d6c1dfe 187 uint8_t module_index = _tcc_get_inst_index(hw);
mbed_official 15:a81a8d6c1dfe 188
mbed_official 15:a81a8d6c1dfe 189 /* Base counter defaults */
mbed_official 15:a81a8d6c1dfe 190 config->counter.count = 0;
mbed_official 15:a81a8d6c1dfe 191
mbed_official 15:a81a8d6c1dfe 192 config->counter.period = _tcc_maxs[module_index];
mbed_official 15:a81a8d6c1dfe 193
mbed_official 15:a81a8d6c1dfe 194 config->counter.clock_source = GCLK_GENERATOR_0;
mbed_official 15:a81a8d6c1dfe 195 config->counter.clock_prescaler = TCC_CLOCK_PRESCALER_DIV1;
mbed_official 15:a81a8d6c1dfe 196 config->counter.reload_action = TCC_RELOAD_ACTION_GCLK;
mbed_official 15:a81a8d6c1dfe 197
mbed_official 15:a81a8d6c1dfe 198 config->counter.direction = TCC_COUNT_DIRECTION_UP;
mbed_official 15:a81a8d6c1dfe 199 config->counter.oneshot = false;
mbed_official 15:a81a8d6c1dfe 200
mbed_official 15:a81a8d6c1dfe 201 /* Match/Capture defaults */
mbed_official 15:a81a8d6c1dfe 202 # define _TCC_CHANNEL_MATCH_VALUE_INIT(n, value) \
mbed_official 15:a81a8d6c1dfe 203 config->compare.match[n] = value;
mbed_official 15:a81a8d6c1dfe 204 MREPEAT(TCC_NUM_CHANNELS,
mbed_official 15:a81a8d6c1dfe 205 _TCC_CHANNEL_MATCH_VALUE_INIT, 0)
mbed_official 15:a81a8d6c1dfe 206 # undef _TCC_CHANNEL_MATCH_VALUE_INIT
mbed_official 15:a81a8d6c1dfe 207
mbed_official 15:a81a8d6c1dfe 208 /* Wave polarity defaults */
mbed_official 15:a81a8d6c1dfe 209 # define _TCC_CHANNEL_WAVE_POLARITY_INIT(n, value) \
mbed_official 15:a81a8d6c1dfe 210 config->compare.wave_polarity[n] = value;
mbed_official 15:a81a8d6c1dfe 211 MREPEAT(TCC_NUM_CHANNELS,
mbed_official 15:a81a8d6c1dfe 212 _TCC_CHANNEL_WAVE_POLARITY_INIT, TCC_WAVE_POLARITY_0)
mbed_official 15:a81a8d6c1dfe 213 # undef _TCC_CHANNEL_WAVE_POLARITY_INIT
mbed_official 15:a81a8d6c1dfe 214
mbed_official 15:a81a8d6c1dfe 215 config->compare.wave_generation = TCC_WAVE_GENERATION_NORMAL_FREQ;
mbed_official 15:a81a8d6c1dfe 216 config->compare.wave_ramp = TCC_RAMP_RAMP1;
mbed_official 15:a81a8d6c1dfe 217
mbed_official 15:a81a8d6c1dfe 218 # define _TCC_CHANNEL_FUNCTION_INIT(n, value) \
mbed_official 15:a81a8d6c1dfe 219 config->compare.channel_function[n] = value;
mbed_official 15:a81a8d6c1dfe 220 MREPEAT(TCC_NUM_CHANNELS,
mbed_official 15:a81a8d6c1dfe 221 _TCC_CHANNEL_FUNCTION_INIT, TCC_CHANNEL_FUNCTION_COMPARE)
mbed_official 15:a81a8d6c1dfe 222 # undef _TCC_CHANNEL_FUNCTION_INIT
mbed_official 15:a81a8d6c1dfe 223
mbed_official 15:a81a8d6c1dfe 224 /* Recoverable fault defaults */
mbed_official 15:a81a8d6c1dfe 225 # define _TCC_FAULT_FUNCTION_INIT(n, dummy) \
mbed_official 15:a81a8d6c1dfe 226 config->wave_ext.recoverable_fault[n].filter_value = 0; \
mbed_official 15:a81a8d6c1dfe 227 config->wave_ext.recoverable_fault[n].blanking_cycles = 0; \
mbed_official 15:a81a8d6c1dfe 228 config->wave_ext.recoverable_fault[n].restart = false; \
mbed_official 15:a81a8d6c1dfe 229 config->wave_ext.recoverable_fault[n].keep = false; \
mbed_official 15:a81a8d6c1dfe 230 config->wave_ext.recoverable_fault[n].qualification = false; \
mbed_official 15:a81a8d6c1dfe 231 config->wave_ext.recoverable_fault[n].source = TCC_FAULT_SOURCE_DISABLE; \
mbed_official 15:a81a8d6c1dfe 232 config->wave_ext.recoverable_fault[n].blanking = TCC_FAULT_BLANKING_DISABLE; \
mbed_official 15:a81a8d6c1dfe 233 config->wave_ext.recoverable_fault[n].halt_action = TCC_FAULT_HALT_ACTION_DISABLE; \
mbed_official 15:a81a8d6c1dfe 234 config->wave_ext.recoverable_fault[n].capture_action = TCC_FAULT_CAPTURE_DISABLE; \
mbed_official 15:a81a8d6c1dfe 235 config->wave_ext.recoverable_fault[n].capture_channel = TCC_FAULT_CAPTURE_CHANNEL_0;
mbed_official 15:a81a8d6c1dfe 236 MREPEAT(TCC_NUM_FAULTS, _TCC_FAULT_FUNCTION_INIT, 0)
mbed_official 15:a81a8d6c1dfe 237 # undef _TCC_FAULT_FUNCTION_INIT
mbed_official 15:a81a8d6c1dfe 238
mbed_official 15:a81a8d6c1dfe 239 /* Non-recoverable fault defaults */
mbed_official 15:a81a8d6c1dfe 240 # define _TCC_NRF_FUNCTION_INIT(n, dummy) \
mbed_official 15:a81a8d6c1dfe 241 config->wave_ext.non_recoverable_fault[n].filter_value = 0; \
mbed_official 15:a81a8d6c1dfe 242 config->wave_ext.non_recoverable_fault[n].output = TCC_FAULT_STATE_OUTPUT_OFF;
mbed_official 15:a81a8d6c1dfe 243 MREPEAT(TCC_NUM_WAVE_OUTPUTS, _TCC_NRF_FUNCTION_INIT, 0)
mbed_official 15:a81a8d6c1dfe 244 # undef _TCC_NRF_FUNCTION_INIT
mbed_official 15:a81a8d6c1dfe 245
mbed_official 15:a81a8d6c1dfe 246 /* Output inversion defaults */
mbed_official 15:a81a8d6c1dfe 247 # define _TCC_OUT_INVERT_INIT(n, value) \
mbed_official 15:a81a8d6c1dfe 248 config->wave_ext.invert[n] = value;
mbed_official 15:a81a8d6c1dfe 249 MREPEAT(TCC_NUM_WAVE_OUTPUTS, _TCC_OUT_INVERT_INIT, false)
mbed_official 15:a81a8d6c1dfe 250 # undef _TCC_OUT_INVERT_INIT
mbed_official 15:a81a8d6c1dfe 251
mbed_official 15:a81a8d6c1dfe 252 # define _TCC_CHANNEL_OUT_PIN_INIT(n, dummy) \
mbed_official 15:a81a8d6c1dfe 253 config->pins.enable_wave_out_pin[n] = false;\
mbed_official 15:a81a8d6c1dfe 254 config->pins.wave_out_pin[TCC_WAVE_OUTPUT_##n] = 0; \
mbed_official 15:a81a8d6c1dfe 255 config->pins.wave_out_pin_mux[TCC_WAVE_OUTPUT_##n] = 0;
mbed_official 15:a81a8d6c1dfe 256 MREPEAT(TCC_NUM_WAVE_OUTPUTS, _TCC_CHANNEL_OUT_PIN_INIT, 0)
mbed_official 15:a81a8d6c1dfe 257 # undef _TCC_CHANNEL_OUT_PIN_INIT
mbed_official 15:a81a8d6c1dfe 258
mbed_official 15:a81a8d6c1dfe 259 config->double_buffering_enabled = true;
mbed_official 15:a81a8d6c1dfe 260 config->run_in_standby = false;
mbed_official 15:a81a8d6c1dfe 261 }
mbed_official 15:a81a8d6c1dfe 262
mbed_official 15:a81a8d6c1dfe 263
mbed_official 15:a81a8d6c1dfe 264 /**
mbed_official 15:a81a8d6c1dfe 265 * \brief Build CTRLA register value from configuration.
mbed_official 15:a81a8d6c1dfe 266 *
mbed_official 15:a81a8d6c1dfe 267 * \param[in] module_index The software module instance index
mbed_official 15:a81a8d6c1dfe 268 * \param[in] config Pointer to the TCC configuration options struct
mbed_official 15:a81a8d6c1dfe 269 * \param[out] value_buffer Pointer to the buffer to fill with built value
mbed_official 15:a81a8d6c1dfe 270 *
mbed_official 15:a81a8d6c1dfe 271 * \return Configuration validation status.
mbed_official 15:a81a8d6c1dfe 272 *
mbed_official 15:a81a8d6c1dfe 273 * \retval STATUS_OK Configuration values are good and register
mbed_official 15:a81a8d6c1dfe 274 * value built and save to buffer
mbed_official 15:a81a8d6c1dfe 275 * \retval STATUS_ERR_INVALID_ARG Invalid parameter found:
mbed_official 15:a81a8d6c1dfe 276 * assigned dither mode is invalid for module;
mbed_official 15:a81a8d6c1dfe 277 * used capture channel is invalid for module
mbed_official 15:a81a8d6c1dfe 278 */
mbed_official 15:a81a8d6c1dfe 279 static inline enum status_code _tcc_build_ctrla(
mbed_official 15:a81a8d6c1dfe 280 const uint8_t module_index,
mbed_official 15:a81a8d6c1dfe 281 const struct tcc_config *const config,
mbed_official 15:a81a8d6c1dfe 282 uint32_t *value_buffer)
mbed_official 15:a81a8d6c1dfe 283 {
mbed_official 15:a81a8d6c1dfe 284 uint32_t ctrla = 0;
mbed_official 15:a81a8d6c1dfe 285
mbed_official 15:a81a8d6c1dfe 286 int i;
mbed_official 15:a81a8d6c1dfe 287 for (i = 0; i < TCC_NUM_CHANNELS; i ++) {
mbed_official 15:a81a8d6c1dfe 288 if (config->capture.channel_function[i] ==
mbed_official 15:a81a8d6c1dfe 289 TCC_CHANNEL_FUNCTION_CAPTURE) {
mbed_official 15:a81a8d6c1dfe 290
mbed_official 15:a81a8d6c1dfe 291 if (i > _tcc_cc_nums[module_index]) {
mbed_official 15:a81a8d6c1dfe 292 /* Channel not supported */
mbed_official 15:a81a8d6c1dfe 293 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 294 }
mbed_official 15:a81a8d6c1dfe 295 ctrla |= (TCC_CTRLA_CPTEN0 << i);
mbed_official 15:a81a8d6c1dfe 296 }
mbed_official 15:a81a8d6c1dfe 297 }
mbed_official 15:a81a8d6c1dfe 298
mbed_official 15:a81a8d6c1dfe 299 if (config->run_in_standby) {
mbed_official 15:a81a8d6c1dfe 300 ctrla |= TCC_CTRLA_RUNSTDBY;
mbed_official 15:a81a8d6c1dfe 301 }
mbed_official 15:a81a8d6c1dfe 302 ctrla |= config->counter.reload_action << TCC_CTRLA_PRESCSYNC_Pos;
mbed_official 15:a81a8d6c1dfe 303 ctrla |= config->counter.clock_prescaler << TCC_CTRLA_PRESCALER_Pos;
mbed_official 15:a81a8d6c1dfe 304
mbed_official 15:a81a8d6c1dfe 305 *value_buffer = ctrla;
mbed_official 15:a81a8d6c1dfe 306 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 307 }
mbed_official 15:a81a8d6c1dfe 308
mbed_official 15:a81a8d6c1dfe 309 /**
mbed_official 15:a81a8d6c1dfe 310 * \brief Build CTRLB register value from configuration.
mbed_official 15:a81a8d6c1dfe 311 *
mbed_official 15:a81a8d6c1dfe 312 * \param[in] module_index The software module instance index
mbed_official 15:a81a8d6c1dfe 313 * \param[in] config Pointer to the TCC configuration options struct
mbed_official 15:a81a8d6c1dfe 314 * \param[out] value_buffer Pointer to the buffer to fill with built value
mbed_official 15:a81a8d6c1dfe 315 */
mbed_official 15:a81a8d6c1dfe 316 static inline void _tcc_build_ctrlb(
mbed_official 15:a81a8d6c1dfe 317 const uint8_t module_index,
mbed_official 15:a81a8d6c1dfe 318 const struct tcc_config *const config,
mbed_official 15:a81a8d6c1dfe 319 uint8_t *value_buffer)
mbed_official 15:a81a8d6c1dfe 320 {
mbed_official 15:a81a8d6c1dfe 321 uint8_t ctrlb = 0;
mbed_official 15:a81a8d6c1dfe 322
mbed_official 15:a81a8d6c1dfe 323 if (config->counter.oneshot) {
mbed_official 15:a81a8d6c1dfe 324 ctrlb |= TCC_CTRLBSET_ONESHOT;
mbed_official 15:a81a8d6c1dfe 325 }
mbed_official 15:a81a8d6c1dfe 326 if (config->counter.direction == TCC_COUNT_DIRECTION_DOWN) {
mbed_official 15:a81a8d6c1dfe 327 ctrlb |= TCC_CTRLBSET_DIR;
mbed_official 15:a81a8d6c1dfe 328 }
mbed_official 15:a81a8d6c1dfe 329
mbed_official 15:a81a8d6c1dfe 330 *value_buffer = ctrlb;
mbed_official 15:a81a8d6c1dfe 331 }
mbed_official 15:a81a8d6c1dfe 332
mbed_official 15:a81a8d6c1dfe 333 /**
mbed_official 15:a81a8d6c1dfe 334 * \brief Build FAULTs register values from configuration.
mbed_official 15:a81a8d6c1dfe 335 *
mbed_official 15:a81a8d6c1dfe 336 * \param[in] module_index The software module instance index
mbed_official 15:a81a8d6c1dfe 337 * \param[in] config Pointer to the TCC configuration options struct
mbed_official 15:a81a8d6c1dfe 338 * \param[out] value_buffer Pointer to the buffer to fill with built values
mbed_official 15:a81a8d6c1dfe 339 *
mbed_official 15:a81a8d6c1dfe 340 * \retval STATUS_OK Configuration values are good and register
mbed_official 15:a81a8d6c1dfe 341 * value built and save to buffer
mbed_official 15:a81a8d6c1dfe 342 * \retval STATUS_ERR_INVALID_ARG Invalid parameter found: assigned fault
mbed_official 15:a81a8d6c1dfe 343 * capture channel is invalid; assigned filter
mbed_official 15:a81a8d6c1dfe 344 * value is invalid
mbed_official 15:a81a8d6c1dfe 345 */
mbed_official 15:a81a8d6c1dfe 346 static inline enum status_code _tcc_build_faults(
mbed_official 15:a81a8d6c1dfe 347 const uint8_t module_index,
mbed_official 15:a81a8d6c1dfe 348 const struct tcc_config *const config,
mbed_official 15:a81a8d6c1dfe 349 uint32_t *value_buffer)
mbed_official 15:a81a8d6c1dfe 350 {
mbed_official 15:a81a8d6c1dfe 351 struct tcc_recoverable_fault_config *cfg;
mbed_official 15:a81a8d6c1dfe 352 uint8_t cc_num = _tcc_cc_nums[module_index];
mbed_official 15:a81a8d6c1dfe 353 uint32_t fault;
mbed_official 15:a81a8d6c1dfe 354 int i;
mbed_official 15:a81a8d6c1dfe 355 for (i = 0; i < TCC_NUM_FAULTS; i ++) {
mbed_official 15:a81a8d6c1dfe 356 cfg = (struct tcc_recoverable_fault_config *)
mbed_official 15:a81a8d6c1dfe 357 &config->wave_ext.recoverable_fault[i];
mbed_official 15:a81a8d6c1dfe 358 if (cfg->capture_channel >= cc_num) {
mbed_official 15:a81a8d6c1dfe 359 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 360 }
mbed_official 15:a81a8d6c1dfe 361 if (cfg->filter_value > 0xF) {
mbed_official 15:a81a8d6c1dfe 362 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 363 }
mbed_official 15:a81a8d6c1dfe 364 fault = TCC_FCTRLA_FILTERVAL(cfg->filter_value)
mbed_official 15:a81a8d6c1dfe 365 | TCC_FCTRLA_BLANKVAL(cfg->blanking_cycles)
mbed_official 15:a81a8d6c1dfe 366 | (cfg->restart ? TCC_FCTRLA_RESTART : 0)
mbed_official 15:a81a8d6c1dfe 367 | (cfg->keep ? TCC_FCTRLA_KEEP : 0)
mbed_official 15:a81a8d6c1dfe 368 | (cfg->qualification ? TCC_FCTRLA_QUAL : 0)
mbed_official 15:a81a8d6c1dfe 369 | TCC_FCTRLA_SRC(cfg->source)
mbed_official 15:a81a8d6c1dfe 370 | TCC_FCTRLA_BLANK(cfg->blanking)
mbed_official 15:a81a8d6c1dfe 371 | TCC_FCTRLA_HALT(cfg->halt_action)
mbed_official 15:a81a8d6c1dfe 372 | TCC_FCTRLA_CAPTURE(cfg->capture_action)
mbed_official 15:a81a8d6c1dfe 373 | TCC_FCTRLA_CHSEL(cfg->capture_channel);
mbed_official 15:a81a8d6c1dfe 374 value_buffer[i] = fault;
mbed_official 15:a81a8d6c1dfe 375 }
mbed_official 15:a81a8d6c1dfe 376 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 377 }
mbed_official 15:a81a8d6c1dfe 378
mbed_official 15:a81a8d6c1dfe 379 /**
mbed_official 15:a81a8d6c1dfe 380 * \brief Build DRVCTRL register values from configuration.
mbed_official 15:a81a8d6c1dfe 381 *
mbed_official 15:a81a8d6c1dfe 382 * \param[in] module_index The software module instance index
mbed_official 15:a81a8d6c1dfe 383 * \param[in] config Pointer to the TCC configuration options struct
mbed_official 15:a81a8d6c1dfe 384 * \param[out] value_buffer Pointer to the buffer to fill with built value
mbed_official 15:a81a8d6c1dfe 385 *
mbed_official 15:a81a8d6c1dfe 386 * \retval STATUS_OK Configuration values are good and register
mbed_official 15:a81a8d6c1dfe 387 * value built and save to buffer
mbed_official 15:a81a8d6c1dfe 388 * \retval STATUS_ERR_INVALID_ARG Invalid parameter found: assigned output line
mbed_official 15:a81a8d6c1dfe 389 * is invalid; filter value is invalid
mbed_official 15:a81a8d6c1dfe 390 */
mbed_official 15:a81a8d6c1dfe 391 static inline enum status_code _tcc_build_drvctrl(
mbed_official 15:a81a8d6c1dfe 392 const uint8_t module_index,
mbed_official 15:a81a8d6c1dfe 393 const struct tcc_config *const config,
mbed_official 15:a81a8d6c1dfe 394 uint32_t *value_buffer)
mbed_official 15:a81a8d6c1dfe 395 {
mbed_official 15:a81a8d6c1dfe 396 uint32_t i;
mbed_official 15:a81a8d6c1dfe 397 uint8_t ow_num = _tcc_ow_nums[module_index];
mbed_official 15:a81a8d6c1dfe 398 uint32_t drvctrl;
mbed_official 15:a81a8d6c1dfe 399
mbed_official 15:a81a8d6c1dfe 400 drvctrl = 0;
mbed_official 15:a81a8d6c1dfe 401
mbed_official 15:a81a8d6c1dfe 402 for (i = 0; i < TCC_NUM_WAVE_OUTPUTS; i ++) {
mbed_official 15:a81a8d6c1dfe 403 if (config->wave_ext.invert[i]) {
mbed_official 15:a81a8d6c1dfe 404 if (i >= ow_num) {
mbed_official 15:a81a8d6c1dfe 405 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 406 }
mbed_official 15:a81a8d6c1dfe 407 drvctrl |= (TCC_DRVCTRL_INVEN0 << i);
mbed_official 15:a81a8d6c1dfe 408 }
mbed_official 15:a81a8d6c1dfe 409 if (config->wave_ext.non_recoverable_fault[i].output !=
mbed_official 15:a81a8d6c1dfe 410 TCC_FAULT_STATE_OUTPUT_OFF) {
mbed_official 15:a81a8d6c1dfe 411 if (i >= ow_num) {
mbed_official 15:a81a8d6c1dfe 412 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 413 }
mbed_official 15:a81a8d6c1dfe 414 if (config->wave_ext.non_recoverable_fault[i].output ==
mbed_official 15:a81a8d6c1dfe 415 TCC_FAULT_STATE_OUTPUT_1) {
mbed_official 15:a81a8d6c1dfe 416 drvctrl |= (TCC_DRVCTRL_NRE0 | TCC_DRVCTRL_NRV0) << i;
mbed_official 15:a81a8d6c1dfe 417 } else {
mbed_official 15:a81a8d6c1dfe 418 drvctrl |= (TCC_DRVCTRL_NRE0) << i;
mbed_official 15:a81a8d6c1dfe 419 }
mbed_official 15:a81a8d6c1dfe 420 }
mbed_official 15:a81a8d6c1dfe 421 }
mbed_official 15:a81a8d6c1dfe 422 *value_buffer = drvctrl;
mbed_official 15:a81a8d6c1dfe 423 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 424 }
mbed_official 15:a81a8d6c1dfe 425
mbed_official 15:a81a8d6c1dfe 426 /**
mbed_official 15:a81a8d6c1dfe 427 * \brief Build WAVE & WAVEB register values from configuration.
mbed_official 15:a81a8d6c1dfe 428 *
mbed_official 15:a81a8d6c1dfe 429 * \param[in] module_index The software module instance index
mbed_official 15:a81a8d6c1dfe 430 * \param[in] config Pointer to the TCC configuration options struct
mbed_official 15:a81a8d6c1dfe 431 * \param[out] value_buffer Pointer to the buffer to fill with built value
mbed_official 15:a81a8d6c1dfe 432 *
mbed_official 15:a81a8d6c1dfe 433 * \retval STATUS_OK Configuration values are good and register
mbed_official 15:a81a8d6c1dfe 434 * value built and save to buffer
mbed_official 15:a81a8d6c1dfe 435 * \retval STATUS_ERR_INVALID_ARG Invalid parameter found: assigned output line
mbed_official 15:a81a8d6c1dfe 436 * is invalid; circular and double buffering
mbed_official 15:a81a8d6c1dfe 437 * conflict; assigned function not supported by
mbed_official 15:a81a8d6c1dfe 438 * module
mbed_official 15:a81a8d6c1dfe 439 */
mbed_official 15:a81a8d6c1dfe 440 static inline enum status_code _tcc_build_waves(
mbed_official 15:a81a8d6c1dfe 441 const uint8_t module_index,
mbed_official 15:a81a8d6c1dfe 442 const struct tcc_config *const config,
mbed_official 15:a81a8d6c1dfe 443 uint32_t *value_buffer)
mbed_official 15:a81a8d6c1dfe 444 {
mbed_official 15:a81a8d6c1dfe 445 int n;
mbed_official 15:a81a8d6c1dfe 446
mbed_official 15:a81a8d6c1dfe 447 uint8_t cc_num = _tcc_cc_nums[module_index];
mbed_official 15:a81a8d6c1dfe 448 struct tcc_match_wave_config const *wav_cfg = &config->compare;
mbed_official 15:a81a8d6c1dfe 449
mbed_official 15:a81a8d6c1dfe 450 uint32_t wave;
mbed_official 15:a81a8d6c1dfe 451
mbed_official 15:a81a8d6c1dfe 452 wave = TCC_WAVE_RAMP(wav_cfg->wave_ramp) |
mbed_official 15:a81a8d6c1dfe 453 TCC_WAVE_WAVEGEN(wav_cfg->wave_generation);
mbed_official 15:a81a8d6c1dfe 454
mbed_official 15:a81a8d6c1dfe 455 for (n = 0; n < TCC_NUM_CHANNELS; n++) {
mbed_official 15:a81a8d6c1dfe 456 if (wav_cfg->wave_polarity[n]) {
mbed_official 15:a81a8d6c1dfe 457 if (n >= cc_num) {
mbed_official 15:a81a8d6c1dfe 458 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 459 }
mbed_official 15:a81a8d6c1dfe 460 wave |= (TCC_WAVE_POL0 << n);
mbed_official 15:a81a8d6c1dfe 461 }
mbed_official 15:a81a8d6c1dfe 462 }
mbed_official 15:a81a8d6c1dfe 463
mbed_official 15:a81a8d6c1dfe 464 value_buffer[0] = wave;
mbed_official 15:a81a8d6c1dfe 465
mbed_official 15:a81a8d6c1dfe 466 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 467 }
mbed_official 15:a81a8d6c1dfe 468
mbed_official 15:a81a8d6c1dfe 469 /**
mbed_official 15:a81a8d6c1dfe 470 * \brief Initializes a hardware TCC module instance.
mbed_official 15:a81a8d6c1dfe 471 *
mbed_official 15:a81a8d6c1dfe 472 * Enables the clock and initializes the given TCC module, based on the given
mbed_official 15:a81a8d6c1dfe 473 * configuration values.
mbed_official 15:a81a8d6c1dfe 474 *
mbed_official 15:a81a8d6c1dfe 475 * \param[in,out] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 476 * \param[in] hw Pointer to the TCC hardware module
mbed_official 15:a81a8d6c1dfe 477 * \param[in] config Pointer to the TCC configuration options struct
mbed_official 15:a81a8d6c1dfe 478 *
mbed_official 15:a81a8d6c1dfe 479 * \return Status of the initialization procedure.
mbed_official 15:a81a8d6c1dfe 480 *
mbed_official 15:a81a8d6c1dfe 481 * \retval STATUS_OK The module was initialized successfully
mbed_official 15:a81a8d6c1dfe 482 * \retval STATUS_BUSY Hardware module was busy when the
mbed_official 15:a81a8d6c1dfe 483 * initialization procedure was attempted
mbed_official 15:a81a8d6c1dfe 484 * \retval STATUS_INVALID_ARG An invalid configuration option or argument
mbed_official 15:a81a8d6c1dfe 485 * was supplied
mbed_official 15:a81a8d6c1dfe 486 * \retval STATUS_ERR_DENIED Hardware module was already enabled
mbed_official 15:a81a8d6c1dfe 487 */
mbed_official 15:a81a8d6c1dfe 488 enum status_code tcc_init(
mbed_official 15:a81a8d6c1dfe 489 struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 490 Tcc *const hw,
mbed_official 15:a81a8d6c1dfe 491 const struct tcc_config *const config)
mbed_official 15:a81a8d6c1dfe 492 {
mbed_official 15:a81a8d6c1dfe 493 int i;
mbed_official 15:a81a8d6c1dfe 494
mbed_official 15:a81a8d6c1dfe 495 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 496 Assert(hw);
mbed_official 15:a81a8d6c1dfe 497 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 498 Assert(config);
mbed_official 15:a81a8d6c1dfe 499
mbed_official 15:a81a8d6c1dfe 500 /* TCC instance index */
mbed_official 15:a81a8d6c1dfe 501 uint8_t module_index = _tcc_get_inst_index(hw);
mbed_official 15:a81a8d6c1dfe 502
mbed_official 15:a81a8d6c1dfe 503 /* Enable the user interface clock for TCC */
mbed_official 15:a81a8d6c1dfe 504 system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC,
mbed_official 15:a81a8d6c1dfe 505 _tcc_apbcmasks[module_index]);
mbed_official 15:a81a8d6c1dfe 506
mbed_official 15:a81a8d6c1dfe 507 /* Check if it's enabled. */
mbed_official 15:a81a8d6c1dfe 508 if (hw->CTRLA.reg & TCC_CTRLA_ENABLE) {
mbed_official 15:a81a8d6c1dfe 509 return STATUS_ERR_DENIED;
mbed_official 15:a81a8d6c1dfe 510 }
mbed_official 15:a81a8d6c1dfe 511 /* Check if it's resetting */
mbed_official 15:a81a8d6c1dfe 512 if (hw->CTRLA.reg & TCC_CTRLA_SWRST) {
mbed_official 15:a81a8d6c1dfe 513 return STATUS_ERR_DENIED;
mbed_official 15:a81a8d6c1dfe 514 }
mbed_official 15:a81a8d6c1dfe 515
mbed_official 15:a81a8d6c1dfe 516 enum status_code status;
mbed_official 15:a81a8d6c1dfe 517
mbed_official 15:a81a8d6c1dfe 518 /* Check COUNT, PER, CCx */
mbed_official 15:a81a8d6c1dfe 519 uint32_t count_max = _tcc_maxs[module_index];
mbed_official 15:a81a8d6c1dfe 520
mbed_official 15:a81a8d6c1dfe 521 /* Check all counter values */
mbed_official 15:a81a8d6c1dfe 522 if ((config->counter.count > count_max)
mbed_official 15:a81a8d6c1dfe 523 || (config->counter.period > count_max)
mbed_official 15:a81a8d6c1dfe 524 ) {
mbed_official 15:a81a8d6c1dfe 525 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 526 }
mbed_official 15:a81a8d6c1dfe 527
mbed_official 15:a81a8d6c1dfe 528 /* Check all channel values */
mbed_official 15:a81a8d6c1dfe 529 for (i = 0; i < TCC_NUM_CHANNELS; i ++) {
mbed_official 15:a81a8d6c1dfe 530 if ((config->compare.match[i] > count_max)
mbed_official 15:a81a8d6c1dfe 531 ) {
mbed_official 15:a81a8d6c1dfe 532 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 533 }
mbed_official 15:a81a8d6c1dfe 534 }
mbed_official 15:a81a8d6c1dfe 535
mbed_official 15:a81a8d6c1dfe 536 /* Check all outputs */
mbed_official 15:a81a8d6c1dfe 537 for (i = 0; i < TCC_NUM_WAVE_OUTPUTS; i ++) {
mbed_official 15:a81a8d6c1dfe 538 if (!config->pins.enable_wave_out_pin[i]) {
mbed_official 15:a81a8d6c1dfe 539 continue;
mbed_official 15:a81a8d6c1dfe 540 }
mbed_official 15:a81a8d6c1dfe 541 /* Output line is not supported */
mbed_official 15:a81a8d6c1dfe 542 if (i >= _tcc_ow_nums[module_index]) {
mbed_official 15:a81a8d6c1dfe 543 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 544 }
mbed_official 15:a81a8d6c1dfe 545 }
mbed_official 15:a81a8d6c1dfe 546
mbed_official 15:a81a8d6c1dfe 547 /* CTRLA settings */
mbed_official 15:a81a8d6c1dfe 548 uint32_t ctrla = 0;
mbed_official 15:a81a8d6c1dfe 549 status = _tcc_build_ctrla(module_index, config, &ctrla);
mbed_official 15:a81a8d6c1dfe 550 if (STATUS_OK != status) {
mbed_official 15:a81a8d6c1dfe 551 return status;
mbed_official 15:a81a8d6c1dfe 552 }
mbed_official 15:a81a8d6c1dfe 553
mbed_official 15:a81a8d6c1dfe 554 /* CTRLB settings */
mbed_official 15:a81a8d6c1dfe 555 uint8_t ctrlb;
mbed_official 15:a81a8d6c1dfe 556 _tcc_build_ctrlb(module_index, config, &ctrlb);
mbed_official 15:a81a8d6c1dfe 557
mbed_official 15:a81a8d6c1dfe 558 /* FAULTs settings */
mbed_official 15:a81a8d6c1dfe 559 uint32_t faults[TCC_NUM_FAULTS];
mbed_official 15:a81a8d6c1dfe 560
mbed_official 15:a81a8d6c1dfe 561 status = _tcc_build_faults(module_index, config, faults);
mbed_official 15:a81a8d6c1dfe 562 if (STATUS_OK != status) {
mbed_official 15:a81a8d6c1dfe 563 return status;
mbed_official 15:a81a8d6c1dfe 564 }
mbed_official 15:a81a8d6c1dfe 565
mbed_official 15:a81a8d6c1dfe 566 /* DRVCTRL */
mbed_official 15:a81a8d6c1dfe 567 uint32_t drvctrl = 0;
mbed_official 15:a81a8d6c1dfe 568
mbed_official 15:a81a8d6c1dfe 569 status = _tcc_build_drvctrl(module_index, config, &drvctrl);
mbed_official 15:a81a8d6c1dfe 570 if (STATUS_OK != status) {
mbed_official 15:a81a8d6c1dfe 571 return status;
mbed_official 15:a81a8d6c1dfe 572 }
mbed_official 15:a81a8d6c1dfe 573
mbed_official 15:a81a8d6c1dfe 574 /* WAVE */
mbed_official 15:a81a8d6c1dfe 575 uint32_t waves[1];
mbed_official 15:a81a8d6c1dfe 576
mbed_official 15:a81a8d6c1dfe 577 status = _tcc_build_waves(module_index, config, waves);
mbed_official 15:a81a8d6c1dfe 578 if (STATUS_OK != status) {
mbed_official 15:a81a8d6c1dfe 579 return status;
mbed_official 15:a81a8d6c1dfe 580 }
mbed_official 15:a81a8d6c1dfe 581
mbed_official 15:a81a8d6c1dfe 582 /* Initialize module */
mbed_official 15:a81a8d6c1dfe 583 #if TCC_ASYNC
mbed_official 15:a81a8d6c1dfe 584 /* Initialize parameters */
mbed_official 15:a81a8d6c1dfe 585 for (i = 0; i < TCC_CALLBACK_N; i ++) {
mbed_official 15:a81a8d6c1dfe 586 module_inst->callback[i] = NULL;
mbed_official 15:a81a8d6c1dfe 587 }
mbed_official 15:a81a8d6c1dfe 588 module_inst->register_callback_mask = 0;
mbed_official 15:a81a8d6c1dfe 589 module_inst->enable_callback_mask = 0;
mbed_official 15:a81a8d6c1dfe 590 _tcc_instances[module_index] = module_inst;
mbed_official 15:a81a8d6c1dfe 591 #endif
mbed_official 15:a81a8d6c1dfe 592
mbed_official 15:a81a8d6c1dfe 593 module_inst->hw = hw;
mbed_official 15:a81a8d6c1dfe 594
mbed_official 15:a81a8d6c1dfe 595 module_inst->double_buffering_enabled = config->double_buffering_enabled;
mbed_official 15:a81a8d6c1dfe 596
mbed_official 15:a81a8d6c1dfe 597 /* Setup clock for module */
mbed_official 15:a81a8d6c1dfe 598 struct system_gclk_chan_config gclk_chan_config;
mbed_official 15:a81a8d6c1dfe 599 system_gclk_chan_get_config_defaults(&gclk_chan_config);
mbed_official 15:a81a8d6c1dfe 600 gclk_chan_config.source_generator = config->counter.clock_source;
mbed_official 15:a81a8d6c1dfe 601 system_gclk_chan_set_config(_tcc_gclk_ids[module_index], &gclk_chan_config);
mbed_official 15:a81a8d6c1dfe 602 system_gclk_chan_enable(_tcc_gclk_ids[module_index]);
mbed_official 15:a81a8d6c1dfe 603
mbed_official 15:a81a8d6c1dfe 604 /* Initialize pins */
mbed_official 15:a81a8d6c1dfe 605 struct system_pinmux_config pin_config;
mbed_official 15:a81a8d6c1dfe 606 for (i = 0; i < _tcc_ow_nums[module_index]; i ++) {
mbed_official 15:a81a8d6c1dfe 607 if (!config->pins.enable_wave_out_pin[i]) {
mbed_official 15:a81a8d6c1dfe 608 continue;
mbed_official 15:a81a8d6c1dfe 609 }
mbed_official 15:a81a8d6c1dfe 610
mbed_official 15:a81a8d6c1dfe 611 system_pinmux_get_config_defaults(&pin_config);
mbed_official 15:a81a8d6c1dfe 612 pin_config.mux_position = config->pins.wave_out_pin_mux[i];
mbed_official 15:a81a8d6c1dfe 613 pin_config.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
mbed_official 15:a81a8d6c1dfe 614 system_pinmux_pin_set_config(
mbed_official 15:a81a8d6c1dfe 615 config->pins.wave_out_pin[i], &pin_config);
mbed_official 15:a81a8d6c1dfe 616 }
mbed_official 15:a81a8d6c1dfe 617
mbed_official 15:a81a8d6c1dfe 618 /* Write to registers */
mbed_official 15:a81a8d6c1dfe 619
mbed_official 15:a81a8d6c1dfe 620 hw->CTRLA.reg = ctrla;
mbed_official 15:a81a8d6c1dfe 621 while (hw->SYNCBUSY.reg & TCC_SYNCBUSY_CTRLB) {
mbed_official 15:a81a8d6c1dfe 622 /* Wait for sync */
mbed_official 15:a81a8d6c1dfe 623 }
mbed_official 15:a81a8d6c1dfe 624
mbed_official 15:a81a8d6c1dfe 625 hw->CTRLBCLR.reg = 0xFF;
mbed_official 15:a81a8d6c1dfe 626 while (hw->SYNCBUSY.reg & TCC_SYNCBUSY_CTRLB) {
mbed_official 15:a81a8d6c1dfe 627 /* Wait for sync */
mbed_official 15:a81a8d6c1dfe 628 }
mbed_official 15:a81a8d6c1dfe 629 hw->CTRLBSET.reg = ctrlb;
mbed_official 15:a81a8d6c1dfe 630
mbed_official 15:a81a8d6c1dfe 631 hw->FCTRLA.reg = faults[0];
mbed_official 15:a81a8d6c1dfe 632 hw->FCTRLB.reg = faults[1];
mbed_official 15:a81a8d6c1dfe 633
mbed_official 15:a81a8d6c1dfe 634 hw->DRVCTRL.reg = drvctrl;
mbed_official 15:a81a8d6c1dfe 635
mbed_official 15:a81a8d6c1dfe 636 #if (!SAML21) && (!SAMC20) && (!SAMC21)
mbed_official 15:a81a8d6c1dfe 637 while (hw->SYNCBUSY.reg & (TCC_SYNCBUSY_WAVE | TCC_SYNCBUSY_WAVEB)) {
mbed_official 15:a81a8d6c1dfe 638 /* Wait for sync */
mbed_official 15:a81a8d6c1dfe 639 }
mbed_official 15:a81a8d6c1dfe 640 #endif
mbed_official 15:a81a8d6c1dfe 641 hw->WAVE.reg = waves[0];
mbed_official 15:a81a8d6c1dfe 642
mbed_official 15:a81a8d6c1dfe 643 while (hw->SYNCBUSY.reg & TCC_SYNCBUSY_COUNT) {
mbed_official 15:a81a8d6c1dfe 644 /* Wait for sync */
mbed_official 15:a81a8d6c1dfe 645 }
mbed_official 15:a81a8d6c1dfe 646 hw->COUNT.reg = config->counter.count;
mbed_official 15:a81a8d6c1dfe 647
mbed_official 15:a81a8d6c1dfe 648 #if (!SAML21) && (!SAMC20) && (!SAMC21)
mbed_official 15:a81a8d6c1dfe 649 while (hw->SYNCBUSY.reg & (TCC_SYNCBUSY_PER | TCC_SYNCBUSY_PERB)) {
mbed_official 15:a81a8d6c1dfe 650 /* Wait for sync */
mbed_official 15:a81a8d6c1dfe 651 }
mbed_official 15:a81a8d6c1dfe 652 #endif
mbed_official 15:a81a8d6c1dfe 653 hw->PER.reg = (config->counter.period);
mbed_official 15:a81a8d6c1dfe 654
mbed_official 15:a81a8d6c1dfe 655 for (i = 0; i < _tcc_cc_nums[module_index]; i ++) {
mbed_official 15:a81a8d6c1dfe 656 #if (!SAML21) && (!SAMC20) && (!SAMC21)
mbed_official 15:a81a8d6c1dfe 657 while (hw->SYNCBUSY.reg & (
mbed_official 15:a81a8d6c1dfe 658 (TCC_SYNCBUSY_CC0 | TCC_SYNCBUSY_CCB0) << i)) {
mbed_official 15:a81a8d6c1dfe 659 /* Wait for sync */
mbed_official 15:a81a8d6c1dfe 660 }
mbed_official 15:a81a8d6c1dfe 661 #endif
mbed_official 15:a81a8d6c1dfe 662 hw->CC[i].reg = (config->compare.match[i]);
mbed_official 15:a81a8d6c1dfe 663 }
mbed_official 15:a81a8d6c1dfe 664
mbed_official 15:a81a8d6c1dfe 665 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 666 }
mbed_official 15:a81a8d6c1dfe 667
mbed_official 15:a81a8d6c1dfe 668
mbed_official 15:a81a8d6c1dfe 669 /**
mbed_official 15:a81a8d6c1dfe 670 * \brief Enables the TCC module event input or output.
mbed_official 15:a81a8d6c1dfe 671 *
mbed_official 15:a81a8d6c1dfe 672 * Enables one or more input or output events to or from the TCC module.
mbed_official 15:a81a8d6c1dfe 673 * See \ref tcc_events for a list of events this module supports.
mbed_official 15:a81a8d6c1dfe 674 *
mbed_official 15:a81a8d6c1dfe 675 * \note Events cannot be altered while the module is enabled.
mbed_official 15:a81a8d6c1dfe 676 *
mbed_official 15:a81a8d6c1dfe 677 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 678 * \param[in] events Struct containing flags of events to enable or
mbed_official 15:a81a8d6c1dfe 679 * configure
mbed_official 15:a81a8d6c1dfe 680 *
mbed_official 15:a81a8d6c1dfe 681 * \return Status of the events setup procedure.
mbed_official 15:a81a8d6c1dfe 682 *
mbed_official 15:a81a8d6c1dfe 683 * \retval STATUS_OK The module was initialized successfully
mbed_official 15:a81a8d6c1dfe 684 * \retval STATUS_INVALID_ARG An invalid configuration option or argument
mbed_official 15:a81a8d6c1dfe 685 * was supplied
mbed_official 15:a81a8d6c1dfe 686 */
mbed_official 15:a81a8d6c1dfe 687 enum status_code tcc_enable_events(
mbed_official 15:a81a8d6c1dfe 688 struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 689 struct tcc_events *const events)
mbed_official 15:a81a8d6c1dfe 690 {
mbed_official 15:a81a8d6c1dfe 691 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 692 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 693 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 694 Assert(events);
mbed_official 15:a81a8d6c1dfe 695
mbed_official 15:a81a8d6c1dfe 696 Tcc *const tcc_module = module_inst->hw;
mbed_official 15:a81a8d6c1dfe 697
mbed_official 15:a81a8d6c1dfe 698 /* Check if it's enabled or resetting. */
mbed_official 15:a81a8d6c1dfe 699 if (tcc_module->CTRLA.reg & (TCC_CTRLA_ENABLE | TCC_CTRLA_SWRST)) {
mbed_official 15:a81a8d6c1dfe 700 return STATUS_ERR_DENIED;
mbed_official 15:a81a8d6c1dfe 701 }
mbed_official 15:a81a8d6c1dfe 702
mbed_official 15:a81a8d6c1dfe 703 uint32_t evctrl = tcc_module->EVCTRL.reg;
mbed_official 15:a81a8d6c1dfe 704
mbed_official 15:a81a8d6c1dfe 705 /* Setup event output action */
mbed_official 15:a81a8d6c1dfe 706 if (events->output_config.modify_generation_selection) {
mbed_official 15:a81a8d6c1dfe 707 evctrl &= ~ TCC_EVCTRL_CNTSEL_Msk;
mbed_official 15:a81a8d6c1dfe 708 switch(events->output_config.generation_selection) {
mbed_official 15:a81a8d6c1dfe 709 case TCC_EVENT_GENERATION_SELECTION_START:
mbed_official 15:a81a8d6c1dfe 710 evctrl |= TCC_EVCTRL_CNTSEL_START;
mbed_official 15:a81a8d6c1dfe 711 break;
mbed_official 15:a81a8d6c1dfe 712 case TCC_EVENT_GENERATION_SELECTION_END:
mbed_official 15:a81a8d6c1dfe 713 evctrl |= TCC_EVCTRL_CNTSEL_END;
mbed_official 15:a81a8d6c1dfe 714 break;
mbed_official 15:a81a8d6c1dfe 715 case TCC_EVENT_GENERATION_SELECTION_BETWEEN:
mbed_official 15:a81a8d6c1dfe 716 evctrl |= TCC_EVCTRL_CNTSEL_BETWEEN;
mbed_official 15:a81a8d6c1dfe 717 break;
mbed_official 15:a81a8d6c1dfe 718 case TCC_EVENT_GENERATION_SELECTION_BOUNDARY:
mbed_official 15:a81a8d6c1dfe 719 evctrl |= TCC_EVCTRL_CNTSEL_BOUNDARY;
mbed_official 15:a81a8d6c1dfe 720 break;
mbed_official 15:a81a8d6c1dfe 721 default:
mbed_official 15:a81a8d6c1dfe 722 Assert(false);
mbed_official 15:a81a8d6c1dfe 723 /* Wrong configuration */
mbed_official 15:a81a8d6c1dfe 724 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 725 }
mbed_official 15:a81a8d6c1dfe 726 }
mbed_official 15:a81a8d6c1dfe 727 /* Setup input event0 */
mbed_official 15:a81a8d6c1dfe 728 if (events->on_input_event_perform_action[0]) {
mbed_official 15:a81a8d6c1dfe 729 evctrl |= TCC_EVCTRL_TCEI0;
mbed_official 15:a81a8d6c1dfe 730 }
mbed_official 15:a81a8d6c1dfe 731 if (events->input_config[0].invert) {
mbed_official 15:a81a8d6c1dfe 732 evctrl |= TCC_EVCTRL_TCINV0;
mbed_official 15:a81a8d6c1dfe 733 }
mbed_official 15:a81a8d6c1dfe 734 if (events->input_config[0].modify_action) {
mbed_official 15:a81a8d6c1dfe 735 evctrl &= ~ TCC_EVCTRL_EVACT0_Msk;
mbed_official 15:a81a8d6c1dfe 736 switch(events->input_config[0].action) {
mbed_official 15:a81a8d6c1dfe 737 case TCC_EVENT0_ACTION_OFF:
mbed_official 15:a81a8d6c1dfe 738 evctrl |= TCC_EVCTRL_EVACT0_OFF;
mbed_official 15:a81a8d6c1dfe 739 break;
mbed_official 15:a81a8d6c1dfe 740 case TCC_EVENT0_ACTION_RETRIGGER:
mbed_official 15:a81a8d6c1dfe 741 evctrl |= TCC_EVCTRL_EVACT0_RETRIGGER;
mbed_official 15:a81a8d6c1dfe 742 break;
mbed_official 15:a81a8d6c1dfe 743 case TCC_EVENT0_ACTION_COUNT_EVENT:
mbed_official 15:a81a8d6c1dfe 744 evctrl |= TCC_EVCTRL_EVACT0_COUNTEV;
mbed_official 15:a81a8d6c1dfe 745 break;
mbed_official 15:a81a8d6c1dfe 746 case TCC_EVENT0_ACTION_START:
mbed_official 15:a81a8d6c1dfe 747 evctrl |= TCC_EVCTRL_EVACT0_START;
mbed_official 15:a81a8d6c1dfe 748 break;
mbed_official 15:a81a8d6c1dfe 749 case TCC_EVENT0_ACTION_INCREMENT:
mbed_official 15:a81a8d6c1dfe 750 evctrl |= TCC_EVCTRL_EVACT0_INC;
mbed_official 15:a81a8d6c1dfe 751 break;
mbed_official 15:a81a8d6c1dfe 752 case TCC_EVENT0_ACTION_COUNT_DURING_ACTIVE:
mbed_official 15:a81a8d6c1dfe 753 evctrl |= TCC_EVCTRL_EVACT0_COUNT;
mbed_official 15:a81a8d6c1dfe 754 break;
mbed_official 15:a81a8d6c1dfe 755 case TCC_EVENT0_ACTION_NON_RECOVERABLE_FAULT:
mbed_official 15:a81a8d6c1dfe 756 evctrl |= TCC_EVCTRL_EVACT0_FAULT;
mbed_official 15:a81a8d6c1dfe 757 break;
mbed_official 15:a81a8d6c1dfe 758 default:
mbed_official 15:a81a8d6c1dfe 759 Assert(false);
mbed_official 15:a81a8d6c1dfe 760 /* Wrong configuration */
mbed_official 15:a81a8d6c1dfe 761 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 762 }
mbed_official 15:a81a8d6c1dfe 763 }
mbed_official 15:a81a8d6c1dfe 764 /* Setup input event1 */
mbed_official 15:a81a8d6c1dfe 765 if (events->on_input_event_perform_action[1]) {
mbed_official 15:a81a8d6c1dfe 766 evctrl |= TCC_EVCTRL_TCEI1;
mbed_official 15:a81a8d6c1dfe 767 }
mbed_official 15:a81a8d6c1dfe 768 if (events->input_config[1].invert) {
mbed_official 15:a81a8d6c1dfe 769 evctrl |= TCC_EVCTRL_TCINV1;
mbed_official 15:a81a8d6c1dfe 770 }
mbed_official 15:a81a8d6c1dfe 771 if (events->input_config[1].modify_action) {
mbed_official 15:a81a8d6c1dfe 772 evctrl &= ~ TCC_EVCTRL_EVACT1_Msk;
mbed_official 15:a81a8d6c1dfe 773 switch(events->input_config[1].action) {
mbed_official 15:a81a8d6c1dfe 774 case TCC_EVENT1_ACTION_OFF:
mbed_official 15:a81a8d6c1dfe 775 evctrl |= TCC_EVCTRL_EVACT1_OFF;
mbed_official 15:a81a8d6c1dfe 776 break;
mbed_official 15:a81a8d6c1dfe 777 case TCC_EVENT1_ACTION_RETRIGGER:
mbed_official 15:a81a8d6c1dfe 778 evctrl |= TCC_EVCTRL_EVACT1_RETRIGGER;
mbed_official 15:a81a8d6c1dfe 779 break;
mbed_official 15:a81a8d6c1dfe 780 case TCC_EVENT1_ACTION_DIR_CONTROL:
mbed_official 15:a81a8d6c1dfe 781 evctrl |= TCC_EVCTRL_EVACT1_DIR;
mbed_official 15:a81a8d6c1dfe 782 break;
mbed_official 15:a81a8d6c1dfe 783 case TCC_EVENT1_ACTION_STOP:
mbed_official 15:a81a8d6c1dfe 784 evctrl |= TCC_EVCTRL_EVACT1_STOP;
mbed_official 15:a81a8d6c1dfe 785 break;
mbed_official 15:a81a8d6c1dfe 786 case TCC_EVENT1_ACTION_DECREMENT:
mbed_official 15:a81a8d6c1dfe 787 evctrl |= TCC_EVCTRL_EVACT1_DEC;
mbed_official 15:a81a8d6c1dfe 788 break;
mbed_official 15:a81a8d6c1dfe 789 case TCC_EVENT1_ACTION_PERIOD_PULSE_WIDTH_CAPTURE:
mbed_official 15:a81a8d6c1dfe 790 evctrl |= TCC_EVCTRL_EVACT1_PPW |
mbed_official 15:a81a8d6c1dfe 791 TCC_EVCTRL_MCEI0 | TCC_EVCTRL_MCEI1;
mbed_official 15:a81a8d6c1dfe 792 break;
mbed_official 15:a81a8d6c1dfe 793 case TCC_EVENT1_ACTION_PULSE_WIDTH_PERIOD_CAPTURE:
mbed_official 15:a81a8d6c1dfe 794 evctrl |= TCC_EVCTRL_EVACT1_PWP |
mbed_official 15:a81a8d6c1dfe 795 TCC_EVCTRL_MCEI0 | TCC_EVCTRL_MCEI1;
mbed_official 15:a81a8d6c1dfe 796 break;
mbed_official 15:a81a8d6c1dfe 797 case TCC_EVENT1_ACTION_NON_RECOVERABLE_FAULT:
mbed_official 15:a81a8d6c1dfe 798 evctrl |= TCC_EVCTRL_EVACT1_FAULT;
mbed_official 15:a81a8d6c1dfe 799 break;
mbed_official 15:a81a8d6c1dfe 800 default:
mbed_official 15:a81a8d6c1dfe 801 Assert(false);
mbed_official 15:a81a8d6c1dfe 802 /* Wrong configuration */
mbed_official 15:a81a8d6c1dfe 803 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 804 }
mbed_official 15:a81a8d6c1dfe 805 }
mbed_official 15:a81a8d6c1dfe 806 uint32_t ch;
mbed_official 15:a81a8d6c1dfe 807 for(ch = 0; ch < TCC_NUM_CHANNELS; ch ++) {
mbed_official 15:a81a8d6c1dfe 808 if (events->generate_event_on_channel[ch]) {
mbed_official 15:a81a8d6c1dfe 809 evctrl |= (TCC_EVCTRL_MCEO(1) << ch);
mbed_official 15:a81a8d6c1dfe 810 }
mbed_official 15:a81a8d6c1dfe 811 if (events->on_event_perform_channel_action[ch]) {
mbed_official 15:a81a8d6c1dfe 812 evctrl |= (TCC_EVCTRL_MCEI(1) << ch);
mbed_official 15:a81a8d6c1dfe 813 }
mbed_official 15:a81a8d6c1dfe 814 }
mbed_official 15:a81a8d6c1dfe 815 if (events->generate_event_on_counter_overflow) {
mbed_official 15:a81a8d6c1dfe 816 evctrl |= TCC_EVCTRL_OVFEO;
mbed_official 15:a81a8d6c1dfe 817 }
mbed_official 15:a81a8d6c1dfe 818 if (events->generate_event_on_counter_retrigger) {
mbed_official 15:a81a8d6c1dfe 819 evctrl |= TCC_EVCTRL_TRGEO;
mbed_official 15:a81a8d6c1dfe 820 }
mbed_official 15:a81a8d6c1dfe 821 if (events->generate_event_on_counter_event) {
mbed_official 15:a81a8d6c1dfe 822 evctrl |= TCC_EVCTRL_CNTEO;
mbed_official 15:a81a8d6c1dfe 823 }
mbed_official 15:a81a8d6c1dfe 824
mbed_official 15:a81a8d6c1dfe 825 tcc_module->EVCTRL.reg = evctrl;
mbed_official 15:a81a8d6c1dfe 826
mbed_official 15:a81a8d6c1dfe 827 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 828 }
mbed_official 15:a81a8d6c1dfe 829
mbed_official 15:a81a8d6c1dfe 830 /**
mbed_official 15:a81a8d6c1dfe 831 * \brief Disables the event input or output of a TCC instance.
mbed_official 15:a81a8d6c1dfe 832 *
mbed_official 15:a81a8d6c1dfe 833 * Disables one or more input or output events for the given TCC module.
mbed_official 15:a81a8d6c1dfe 834 * See \ref tcc_events for a list of events this module supports.
mbed_official 15:a81a8d6c1dfe 835 *
mbed_official 15:a81a8d6c1dfe 836 * \note Events cannot be altered while the module is enabled.
mbed_official 15:a81a8d6c1dfe 837 *
mbed_official 15:a81a8d6c1dfe 838 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 839 * \param[in] events Struct containing flags of events to disable
mbed_official 15:a81a8d6c1dfe 840 */
mbed_official 15:a81a8d6c1dfe 841 void tcc_disable_events(
mbed_official 15:a81a8d6c1dfe 842 struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 843 struct tcc_events *const events)
mbed_official 15:a81a8d6c1dfe 844 {
mbed_official 15:a81a8d6c1dfe 845 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 846 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 847 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 848 Assert(events);
mbed_official 15:a81a8d6c1dfe 849
mbed_official 15:a81a8d6c1dfe 850 Tcc *const tcc_module = module_inst->hw;
mbed_official 15:a81a8d6c1dfe 851
mbed_official 15:a81a8d6c1dfe 852 /* Check if it's enabled or resetting. */
mbed_official 15:a81a8d6c1dfe 853 if (tcc_module->CTRLA.reg & (TCC_CTRLA_ENABLE | TCC_CTRLA_SWRST)) {
mbed_official 15:a81a8d6c1dfe 854 return;
mbed_official 15:a81a8d6c1dfe 855 }
mbed_official 15:a81a8d6c1dfe 856
mbed_official 15:a81a8d6c1dfe 857
mbed_official 15:a81a8d6c1dfe 858 uint32_t evctrl = 0;
mbed_official 15:a81a8d6c1dfe 859 uint32_t ch;
mbed_official 15:a81a8d6c1dfe 860 for(ch = 0; ch < TCC_NUM_CHANNELS; ch ++) {
mbed_official 15:a81a8d6c1dfe 861 if (events->generate_event_on_channel[ch]) {
mbed_official 15:a81a8d6c1dfe 862 evctrl |= (TCC_EVCTRL_MCEO(1) << ch);
mbed_official 15:a81a8d6c1dfe 863 }
mbed_official 15:a81a8d6c1dfe 864 if (events->on_event_perform_channel_action[ch]) {
mbed_official 15:a81a8d6c1dfe 865 evctrl |= (TCC_EVCTRL_MCEI(1) << ch);
mbed_official 15:a81a8d6c1dfe 866 }
mbed_official 15:a81a8d6c1dfe 867 }
mbed_official 15:a81a8d6c1dfe 868 if (events->generate_event_on_counter_overflow) {
mbed_official 15:a81a8d6c1dfe 869 evctrl |= TCC_EVCTRL_OVFEO;
mbed_official 15:a81a8d6c1dfe 870 }
mbed_official 15:a81a8d6c1dfe 871 if (events->generate_event_on_counter_retrigger) {
mbed_official 15:a81a8d6c1dfe 872 evctrl |= TCC_EVCTRL_TRGEO;
mbed_official 15:a81a8d6c1dfe 873 }
mbed_official 15:a81a8d6c1dfe 874 if (events->generate_event_on_counter_event) {
mbed_official 15:a81a8d6c1dfe 875 evctrl |= TCC_EVCTRL_CNTEO;
mbed_official 15:a81a8d6c1dfe 876 }
mbed_official 15:a81a8d6c1dfe 877 if (events->on_input_event_perform_action[0]) {
mbed_official 15:a81a8d6c1dfe 878 evctrl |= TCC_EVCTRL_TCEI0;
mbed_official 15:a81a8d6c1dfe 879 }
mbed_official 15:a81a8d6c1dfe 880 if (events->on_input_event_perform_action[1]) {
mbed_official 15:a81a8d6c1dfe 881 evctrl |= TCC_EVCTRL_TCEI1;
mbed_official 15:a81a8d6c1dfe 882 }
mbed_official 15:a81a8d6c1dfe 883 if (events->input_config[0].invert) {
mbed_official 15:a81a8d6c1dfe 884 evctrl |= TCC_EVCTRL_TCINV0;
mbed_official 15:a81a8d6c1dfe 885 }
mbed_official 15:a81a8d6c1dfe 886 if (events->input_config[1].invert) {
mbed_official 15:a81a8d6c1dfe 887 evctrl |= TCC_EVCTRL_TCINV1;
mbed_official 15:a81a8d6c1dfe 888 }
mbed_official 15:a81a8d6c1dfe 889
mbed_official 15:a81a8d6c1dfe 890 tcc_module->EVCTRL.reg &= ~evctrl;
mbed_official 15:a81a8d6c1dfe 891 }
mbed_official 15:a81a8d6c1dfe 892
mbed_official 15:a81a8d6c1dfe 893
mbed_official 15:a81a8d6c1dfe 894
mbed_official 15:a81a8d6c1dfe 895 /**
mbed_official 15:a81a8d6c1dfe 896 * \brief Sets count value for the given TCC module.
mbed_official 15:a81a8d6c1dfe 897 *
mbed_official 15:a81a8d6c1dfe 898 * Sets the timer count value of an initialized TCC module. The
mbed_official 15:a81a8d6c1dfe 899 * specified TCC module can remain running or stopped.
mbed_official 15:a81a8d6c1dfe 900 *
mbed_official 15:a81a8d6c1dfe 901 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 902 * \param[in] count New timer count value to set
mbed_official 15:a81a8d6c1dfe 903 *
mbed_official 15:a81a8d6c1dfe 904 * \return Status which indicates whether the new value is set.
mbed_official 15:a81a8d6c1dfe 905 *
mbed_official 15:a81a8d6c1dfe 906 * \retval STATUS_OK The timer count was updated successfully
mbed_official 15:a81a8d6c1dfe 907 * \retval STATUS_ERR_INVALID_ARG An invalid timer counter size was specified
mbed_official 15:a81a8d6c1dfe 908 */
mbed_official 15:a81a8d6c1dfe 909 enum status_code tcc_set_count_value(
mbed_official 15:a81a8d6c1dfe 910 const struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 911 const uint32_t count)
mbed_official 15:a81a8d6c1dfe 912 {
mbed_official 15:a81a8d6c1dfe 913 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 914 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 915 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 916
mbed_official 15:a81a8d6c1dfe 917 /* Get a pointer to the module's hardware instance*/
mbed_official 15:a81a8d6c1dfe 918 Tcc *const tcc_module = module_inst->hw;
mbed_official 15:a81a8d6c1dfe 919 /* Get a index of the module */
mbed_official 15:a81a8d6c1dfe 920 uint8_t module_index = _tcc_get_inst_index(tcc_module);
mbed_official 15:a81a8d6c1dfe 921
mbed_official 15:a81a8d6c1dfe 922 uint32_t max_count = _tcc_maxs[module_index];
mbed_official 15:a81a8d6c1dfe 923
mbed_official 15:a81a8d6c1dfe 924 if (count > max_count) {
mbed_official 15:a81a8d6c1dfe 925 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 926 }
mbed_official 15:a81a8d6c1dfe 927
mbed_official 15:a81a8d6c1dfe 928 while (tcc_module->SYNCBUSY.bit.COUNT) {
mbed_official 15:a81a8d6c1dfe 929 /* Wait for sync */
mbed_official 15:a81a8d6c1dfe 930 }
mbed_official 15:a81a8d6c1dfe 931
mbed_official 15:a81a8d6c1dfe 932 /* Write to based on the TCC dithering */
mbed_official 15:a81a8d6c1dfe 933 tcc_module->COUNT.reg = (count);
mbed_official 15:a81a8d6c1dfe 934
mbed_official 15:a81a8d6c1dfe 935 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 936 }
mbed_official 15:a81a8d6c1dfe 937
mbed_official 15:a81a8d6c1dfe 938 /**
mbed_official 15:a81a8d6c1dfe 939 * \brief Get count value of the given TCC module.
mbed_official 15:a81a8d6c1dfe 940 *
mbed_official 15:a81a8d6c1dfe 941 * Retrieves the current count value of a TCC module. The specified TCC module
mbed_official 15:a81a8d6c1dfe 942 * can remain running or stopped.
mbed_official 15:a81a8d6c1dfe 943 *
mbed_official 15:a81a8d6c1dfe 944 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 945 *
mbed_official 15:a81a8d6c1dfe 946 * \return Count value of the specified TCC module.
mbed_official 15:a81a8d6c1dfe 947 */
mbed_official 15:a81a8d6c1dfe 948 uint32_t tcc_get_count_value(
mbed_official 15:a81a8d6c1dfe 949 const struct tcc_module *const module_inst)
mbed_official 15:a81a8d6c1dfe 950 {
mbed_official 15:a81a8d6c1dfe 951 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 952 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 953 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 954
mbed_official 15:a81a8d6c1dfe 955 /* Get a pointer to the module's hardware instance*/
mbed_official 15:a81a8d6c1dfe 956 Tcc *const tcc_module = module_inst->hw;
mbed_official 15:a81a8d6c1dfe 957 uint32_t last_cmd;
mbed_official 15:a81a8d6c1dfe 958
mbed_official 15:a81a8d6c1dfe 959 /* Wait last command done */
mbed_official 15:a81a8d6c1dfe 960 do {
mbed_official 15:a81a8d6c1dfe 961 while (tcc_module->SYNCBUSY.bit.CTRLB) {
mbed_official 15:a81a8d6c1dfe 962 /* Wait for sync */
mbed_official 15:a81a8d6c1dfe 963 }
mbed_official 15:a81a8d6c1dfe 964 last_cmd = tcc_module->CTRLBSET.reg & TCC_CTRLBSET_CMD_Msk;
mbed_official 15:a81a8d6c1dfe 965 if (TCC_CTRLBSET_CMD_NONE == last_cmd) {
mbed_official 15:a81a8d6c1dfe 966 /* Issue read command and break */
mbed_official 15:a81a8d6c1dfe 967 tcc_module->CTRLBSET.bit.CMD = TCC_CTRLBSET_CMD_READSYNC_Val;
mbed_official 15:a81a8d6c1dfe 968 break;
mbed_official 15:a81a8d6c1dfe 969 } else if (TCC_CTRLBSET_CMD_READSYNC == last_cmd) {
mbed_official 15:a81a8d6c1dfe 970 /* Command have been issued */
mbed_official 15:a81a8d6c1dfe 971 break;
mbed_official 15:a81a8d6c1dfe 972 }
mbed_official 15:a81a8d6c1dfe 973 } while (1);
mbed_official 15:a81a8d6c1dfe 974
mbed_official 15:a81a8d6c1dfe 975 while (tcc_module->SYNCBUSY.bit.COUNT) {
mbed_official 15:a81a8d6c1dfe 976 /* Wait for sync */
mbed_official 15:a81a8d6c1dfe 977 }
mbed_official 15:a81a8d6c1dfe 978 return (tcc_module->COUNT.reg);
mbed_official 15:a81a8d6c1dfe 979 }
mbed_official 15:a81a8d6c1dfe 980
mbed_official 15:a81a8d6c1dfe 981
mbed_official 15:a81a8d6c1dfe 982
mbed_official 15:a81a8d6c1dfe 983 /**
mbed_official 15:a81a8d6c1dfe 984 * \brief Gets the TCC module capture value.
mbed_official 15:a81a8d6c1dfe 985 *
mbed_official 15:a81a8d6c1dfe 986 * Retrieves the capture value in the indicated TCC module capture channel.
mbed_official 15:a81a8d6c1dfe 987 *
mbed_official 15:a81a8d6c1dfe 988 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 989 * \param[in] channel_index Index of the Compare Capture channel to read
mbed_official 15:a81a8d6c1dfe 990 *
mbed_official 15:a81a8d6c1dfe 991 * \return Capture value stored in the specified timer channel.
mbed_official 15:a81a8d6c1dfe 992 */
mbed_official 15:a81a8d6c1dfe 993 uint32_t tcc_get_capture_value(
mbed_official 15:a81a8d6c1dfe 994 const struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 995 const enum tcc_match_capture_channel channel_index)
mbed_official 15:a81a8d6c1dfe 996 {
mbed_official 15:a81a8d6c1dfe 997 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 998 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 999 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 1000
mbed_official 15:a81a8d6c1dfe 1001 Assert(channel_index < _tcc_cc_nums[_tcc_get_inst_index(module_inst->hw)]);
mbed_official 15:a81a8d6c1dfe 1002
mbed_official 15:a81a8d6c1dfe 1003 /* Get a pointer to the module's hardware instance */
mbed_official 15:a81a8d6c1dfe 1004 Tcc *const tcc_module = module_inst->hw;
mbed_official 15:a81a8d6c1dfe 1005
mbed_official 15:a81a8d6c1dfe 1006 while(tcc_module->SYNCBUSY.reg & (TCC_SYNCBUSY_CC0 << channel_index)) {
mbed_official 15:a81a8d6c1dfe 1007 /* Sync wait */
mbed_official 15:a81a8d6c1dfe 1008 }
mbed_official 15:a81a8d6c1dfe 1009
mbed_official 15:a81a8d6c1dfe 1010 return tcc_module->CC[channel_index].reg;
mbed_official 15:a81a8d6c1dfe 1011 }
mbed_official 15:a81a8d6c1dfe 1012
mbed_official 15:a81a8d6c1dfe 1013 /**
mbed_official 15:a81a8d6c1dfe 1014 * \internal
mbed_official 15:a81a8d6c1dfe 1015 * \brief Sets a TCC module compare value/buffer.
mbed_official 15:a81a8d6c1dfe 1016 *
mbed_official 15:a81a8d6c1dfe 1017 * Writes a compare value to the given TCC module compare/capture channel or
mbed_official 15:a81a8d6c1dfe 1018 * buffer one.
mbed_official 15:a81a8d6c1dfe 1019 *
mbed_official 15:a81a8d6c1dfe 1020 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 1021 * \param[in] channel_index Index of the compare channel to write to
mbed_official 15:a81a8d6c1dfe 1022 * \param[in] compare New compare value/buffer value to set
mbed_official 15:a81a8d6c1dfe 1023 * \param[in] double_buffering_enabled Set to \c true to write to CCBx
mbed_official 15:a81a8d6c1dfe 1024 *
mbed_official 15:a81a8d6c1dfe 1025 * \return Status of the compare update procedure.
mbed_official 15:a81a8d6c1dfe 1026 *
mbed_official 15:a81a8d6c1dfe 1027 * \retval STATUS_OK The compare value was updated successfully
mbed_official 15:a81a8d6c1dfe 1028 * \retval STATUS_ERR_INVALID_ARG An invalid channel index was supplied or
mbed_official 15:a81a8d6c1dfe 1029 * compare value exceed resolution
mbed_official 15:a81a8d6c1dfe 1030 */
mbed_official 15:a81a8d6c1dfe 1031 static enum status_code _tcc_set_compare_value(
mbed_official 15:a81a8d6c1dfe 1032 const struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 1033 const enum tcc_match_capture_channel channel_index,
mbed_official 15:a81a8d6c1dfe 1034 const uint32_t compare,
mbed_official 15:a81a8d6c1dfe 1035 const bool double_buffering_enabled)
mbed_official 15:a81a8d6c1dfe 1036 {
mbed_official 15:a81a8d6c1dfe 1037 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 1038 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 1039 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 1040
mbed_official 15:a81a8d6c1dfe 1041 /* Get a pointer to the module's hardware instance */
mbed_official 15:a81a8d6c1dfe 1042 Tcc *const tcc_module = module_inst->hw;
mbed_official 15:a81a8d6c1dfe 1043 /* Get a index of the module */
mbed_official 15:a81a8d6c1dfe 1044 uint8_t module_index = _tcc_get_inst_index(tcc_module);
mbed_official 15:a81a8d6c1dfe 1045
mbed_official 15:a81a8d6c1dfe 1046 /* Check index */
mbed_official 15:a81a8d6c1dfe 1047 if (channel_index >= _tcc_cc_nums[module_index]) {
mbed_official 15:a81a8d6c1dfe 1048 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 1049 }
mbed_official 15:a81a8d6c1dfe 1050
mbed_official 15:a81a8d6c1dfe 1051 uint32_t max_count = _tcc_maxs[module_index];
mbed_official 15:a81a8d6c1dfe 1052
mbed_official 15:a81a8d6c1dfe 1053 /* Check compare value */
mbed_official 15:a81a8d6c1dfe 1054 if (compare > max_count) {
mbed_official 15:a81a8d6c1dfe 1055 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 1056 }
mbed_official 15:a81a8d6c1dfe 1057
mbed_official 15:a81a8d6c1dfe 1058 if (double_buffering_enabled) {
mbed_official 15:a81a8d6c1dfe 1059 #if (SAML21) || (SAMC20) || (SAMC21)
mbed_official 15:a81a8d6c1dfe 1060 tcc_module->CCBUF[channel_index].reg = compare;
mbed_official 15:a81a8d6c1dfe 1061 #else
mbed_official 15:a81a8d6c1dfe 1062 while(tcc_module->SYNCBUSY.reg &
mbed_official 15:a81a8d6c1dfe 1063 (TCC_SYNCBUSY_CCB0 << channel_index)) {
mbed_official 15:a81a8d6c1dfe 1064 /* Sync wait */
mbed_official 15:a81a8d6c1dfe 1065 }
mbed_official 15:a81a8d6c1dfe 1066 tcc_module->CCB[channel_index].reg = compare;
mbed_official 15:a81a8d6c1dfe 1067 #endif
mbed_official 15:a81a8d6c1dfe 1068 } else {
mbed_official 15:a81a8d6c1dfe 1069 while(tcc_module->SYNCBUSY.reg & (TCC_SYNCBUSY_CC0 << channel_index)) {
mbed_official 15:a81a8d6c1dfe 1070 /* Sync wait */
mbed_official 15:a81a8d6c1dfe 1071 }
mbed_official 15:a81a8d6c1dfe 1072 tcc_module->CC[channel_index].reg = compare;
mbed_official 15:a81a8d6c1dfe 1073 }
mbed_official 15:a81a8d6c1dfe 1074 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 1075 }
mbed_official 15:a81a8d6c1dfe 1076
mbed_official 15:a81a8d6c1dfe 1077
mbed_official 15:a81a8d6c1dfe 1078 /**
mbed_official 15:a81a8d6c1dfe 1079 * \brief Sets a TCC module compare value.
mbed_official 15:a81a8d6c1dfe 1080 *
mbed_official 15:a81a8d6c1dfe 1081 * Writes a compare value to the given TCC module compare/capture channel.
mbed_official 15:a81a8d6c1dfe 1082 *
mbed_official 15:a81a8d6c1dfe 1083 * If double buffering is enabled it always write to the buffer
mbed_official 15:a81a8d6c1dfe 1084 * register. The value will then be updated immediately by calling
mbed_official 15:a81a8d6c1dfe 1085 * \ref tcc_force_double_buffer_update(), or be updated when the lock update bit
mbed_official 15:a81a8d6c1dfe 1086 * is cleared and the UPDATE condition happen.
mbed_official 15:a81a8d6c1dfe 1087 *
mbed_official 15:a81a8d6c1dfe 1088 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 1089 * \param[in] channel_index Index of the compare channel to write to
mbed_official 15:a81a8d6c1dfe 1090 * \param[in] compare New compare value to set
mbed_official 15:a81a8d6c1dfe 1091 *
mbed_official 15:a81a8d6c1dfe 1092 * \return Status of the compare update procedure.
mbed_official 15:a81a8d6c1dfe 1093 *
mbed_official 15:a81a8d6c1dfe 1094 * \retval STATUS_OK The compare value was updated successfully
mbed_official 15:a81a8d6c1dfe 1095 * \retval STATUS_ERR_INVALID_ARG An invalid channel index was supplied or
mbed_official 15:a81a8d6c1dfe 1096 * compare value exceed resolution
mbed_official 15:a81a8d6c1dfe 1097 */
mbed_official 15:a81a8d6c1dfe 1098 enum status_code tcc_set_compare_value(
mbed_official 15:a81a8d6c1dfe 1099 const struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 1100 const enum tcc_match_capture_channel channel_index,
mbed_official 15:a81a8d6c1dfe 1101 const uint32_t compare)
mbed_official 15:a81a8d6c1dfe 1102 {
mbed_official 15:a81a8d6c1dfe 1103 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 1104 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 1105
mbed_official 15:a81a8d6c1dfe 1106 return _tcc_set_compare_value(module_inst, channel_index, compare,
mbed_official 15:a81a8d6c1dfe 1107 module_inst->double_buffering_enabled);
mbed_official 15:a81a8d6c1dfe 1108 }
mbed_official 15:a81a8d6c1dfe 1109
mbed_official 15:a81a8d6c1dfe 1110 /**
mbed_official 15:a81a8d6c1dfe 1111 * \brief Sets a TCC module compare value and buffer value.
mbed_official 15:a81a8d6c1dfe 1112 *
mbed_official 15:a81a8d6c1dfe 1113 * Writes compare value and buffer to the given TCC module compare/capture
mbed_official 15:a81a8d6c1dfe 1114 * channel. Usually as preparation for double buffer or circulared double buffer
mbed_official 15:a81a8d6c1dfe 1115 * (circular buffer).
mbed_official 15:a81a8d6c1dfe 1116 *
mbed_official 15:a81a8d6c1dfe 1117 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 1118 * \param[in] channel_index Index of the compare channel to write to
mbed_official 15:a81a8d6c1dfe 1119 * \param[in] compare New compare value to set
mbed_official 15:a81a8d6c1dfe 1120 * \param[in] compare_buffer New compare buffer value to set
mbed_official 15:a81a8d6c1dfe 1121 *
mbed_official 15:a81a8d6c1dfe 1122 * \return Status of the compare update procedure.
mbed_official 15:a81a8d6c1dfe 1123 *
mbed_official 15:a81a8d6c1dfe 1124 * \retval STATUS_OK The compare value was updated successfully
mbed_official 15:a81a8d6c1dfe 1125 * \retval STATUS_ERR_INVALID_ARG An invalid channel index was supplied or
mbed_official 15:a81a8d6c1dfe 1126 * compare value exceed resolution
mbed_official 15:a81a8d6c1dfe 1127 */
mbed_official 15:a81a8d6c1dfe 1128 enum status_code tcc_set_double_buffer_compare_values(
mbed_official 15:a81a8d6c1dfe 1129 struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 1130 const enum tcc_match_capture_channel channel_index,
mbed_official 15:a81a8d6c1dfe 1131 const uint32_t compare, const uint32_t compare_buffer)
mbed_official 15:a81a8d6c1dfe 1132 {
mbed_official 15:a81a8d6c1dfe 1133 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 1134 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 1135
mbed_official 15:a81a8d6c1dfe 1136 enum status_code status;
mbed_official 15:a81a8d6c1dfe 1137 status = _tcc_set_compare_value(module_inst, channel_index, compare, false);
mbed_official 15:a81a8d6c1dfe 1138 if (status != STATUS_OK) {
mbed_official 15:a81a8d6c1dfe 1139 return status;
mbed_official 15:a81a8d6c1dfe 1140 }
mbed_official 15:a81a8d6c1dfe 1141 return _tcc_set_compare_value(module_inst, channel_index, compare_buffer,
mbed_official 15:a81a8d6c1dfe 1142 true);
mbed_official 15:a81a8d6c1dfe 1143 }
mbed_official 15:a81a8d6c1dfe 1144
mbed_official 15:a81a8d6c1dfe 1145
mbed_official 15:a81a8d6c1dfe 1146 /**
mbed_official 15:a81a8d6c1dfe 1147 * \internal
mbed_official 15:a81a8d6c1dfe 1148 * \brief Set the timer TOP/PERIOD buffer/value.
mbed_official 15:a81a8d6c1dfe 1149 *
mbed_official 15:a81a8d6c1dfe 1150 * This function writes the given value to the PER/PERB register.
mbed_official 15:a81a8d6c1dfe 1151 *
mbed_official 15:a81a8d6c1dfe 1152 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 1153 * \param[in] top_value New value to be loaded into the PER/PERB register
mbed_official 15:a81a8d6c1dfe 1154 * \param[in] double_buffering_enabled Set to \c true to write to PERB
mbed_official 15:a81a8d6c1dfe 1155 *
mbed_official 15:a81a8d6c1dfe 1156 * \return Status of the TOP set procedure.
mbed_official 15:a81a8d6c1dfe 1157 *
mbed_official 15:a81a8d6c1dfe 1158 * \retval STATUS_OK The timer TOP value was updated successfully
mbed_official 15:a81a8d6c1dfe 1159 * \retval STATUS_ERR_INVALID_ARG An invalid channel index was supplied or
mbed_official 15:a81a8d6c1dfe 1160 * top/period value exceed resolution
mbed_official 15:a81a8d6c1dfe 1161 */
mbed_official 15:a81a8d6c1dfe 1162 static enum status_code _tcc_set_top_value(
mbed_official 15:a81a8d6c1dfe 1163 const struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 1164 const uint32_t top_value,
mbed_official 15:a81a8d6c1dfe 1165 const bool double_buffering_enabled)
mbed_official 15:a81a8d6c1dfe 1166 {
mbed_official 15:a81a8d6c1dfe 1167 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 1168 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 1169 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 1170
mbed_official 15:a81a8d6c1dfe 1171 /* Get a pointer to the module's hardware instance */
mbed_official 15:a81a8d6c1dfe 1172 Tcc *const tcc_module = module_inst->hw;
mbed_official 15:a81a8d6c1dfe 1173 /* Get a index of the module */
mbed_official 15:a81a8d6c1dfe 1174 uint8_t module_index = _tcc_get_inst_index(tcc_module);
mbed_official 15:a81a8d6c1dfe 1175
mbed_official 15:a81a8d6c1dfe 1176 uint32_t max_count = _tcc_maxs[module_index];
mbed_official 15:a81a8d6c1dfe 1177
mbed_official 15:a81a8d6c1dfe 1178 /* Check compare value */
mbed_official 15:a81a8d6c1dfe 1179 if (top_value > max_count) {
mbed_official 15:a81a8d6c1dfe 1180 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 1181 }
mbed_official 15:a81a8d6c1dfe 1182
mbed_official 15:a81a8d6c1dfe 1183 if (double_buffering_enabled) {
mbed_official 15:a81a8d6c1dfe 1184 #if (SAML21) || (SAMC20) || (SAMC21)
mbed_official 15:a81a8d6c1dfe 1185 tcc_module->PERBUF.reg = top_value;
mbed_official 15:a81a8d6c1dfe 1186 #else
mbed_official 15:a81a8d6c1dfe 1187 while(tcc_module->SYNCBUSY.reg & TCC_SYNCBUSY_PERB) {
mbed_official 15:a81a8d6c1dfe 1188 /* Sync wait */
mbed_official 15:a81a8d6c1dfe 1189 }
mbed_official 15:a81a8d6c1dfe 1190 tcc_module->PERB.reg = top_value;
mbed_official 15:a81a8d6c1dfe 1191 #endif
mbed_official 15:a81a8d6c1dfe 1192 } else {
mbed_official 15:a81a8d6c1dfe 1193 while(tcc_module->SYNCBUSY.reg & TCC_SYNCBUSY_PER) {
mbed_official 15:a81a8d6c1dfe 1194 /* Sync wait */
mbed_official 15:a81a8d6c1dfe 1195 }
mbed_official 15:a81a8d6c1dfe 1196 tcc_module->PER.reg = top_value;
mbed_official 15:a81a8d6c1dfe 1197 }
mbed_official 15:a81a8d6c1dfe 1198 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 1199 }
mbed_official 15:a81a8d6c1dfe 1200
mbed_official 15:a81a8d6c1dfe 1201
mbed_official 15:a81a8d6c1dfe 1202 /**
mbed_official 15:a81a8d6c1dfe 1203 * \brief Set the timer TOP/PERIOD value.
mbed_official 15:a81a8d6c1dfe 1204 *
mbed_official 15:a81a8d6c1dfe 1205 * This function writes the given value to the PER/PERB register.
mbed_official 15:a81a8d6c1dfe 1206 *
mbed_official 15:a81a8d6c1dfe 1207 * If double buffering is enabled it always write to the buffer
mbed_official 15:a81a8d6c1dfe 1208 * register (PERB). The value will then be updated immediately by calling
mbed_official 15:a81a8d6c1dfe 1209 * \ref tcc_force_double_buffer_update(), or be updated when the lock update bit
mbed_official 15:a81a8d6c1dfe 1210 * is cleared and the UPDATE condition happen.
mbed_official 15:a81a8d6c1dfe 1211 *
mbed_official 15:a81a8d6c1dfe 1212 * When using MFRQ, the top value is defined by the CC0 register value and the
mbed_official 15:a81a8d6c1dfe 1213 * PER value is ignored, so
mbed_official 15:a81a8d6c1dfe 1214 * \ref tcc_set_compare_value (module,channel_0,value) must be used instead of
mbed_official 15:a81a8d6c1dfe 1215 * this function to change the actual top value in that case.
mbed_official 15:a81a8d6c1dfe 1216 * For all other waveforms operation the top value is defined by PER register
mbed_official 15:a81a8d6c1dfe 1217 * value.
mbed_official 15:a81a8d6c1dfe 1218 *
mbed_official 15:a81a8d6c1dfe 1219 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 1220 * \param[in] top_value New value to be loaded into the PER/PERB register
mbed_official 15:a81a8d6c1dfe 1221 *
mbed_official 15:a81a8d6c1dfe 1222 * \return Status of the TOP set procedure.
mbed_official 15:a81a8d6c1dfe 1223 *
mbed_official 15:a81a8d6c1dfe 1224 * \retval STATUS_OK The timer TOP value was updated successfully
mbed_official 15:a81a8d6c1dfe 1225 * \retval STATUS_ERR_INVALID_ARG An invalid channel index was supplied or
mbed_official 15:a81a8d6c1dfe 1226 * top/period value exceed resolution
mbed_official 15:a81a8d6c1dfe 1227 */
mbed_official 15:a81a8d6c1dfe 1228 enum status_code tcc_set_top_value(
mbed_official 15:a81a8d6c1dfe 1229 const struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 1230 const uint32_t top_value)
mbed_official 15:a81a8d6c1dfe 1231 {
mbed_official 15:a81a8d6c1dfe 1232 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 1233 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 1234
mbed_official 15:a81a8d6c1dfe 1235 return _tcc_set_top_value(module_inst, top_value,
mbed_official 15:a81a8d6c1dfe 1236 module_inst->double_buffering_enabled);
mbed_official 15:a81a8d6c1dfe 1237 }
mbed_official 15:a81a8d6c1dfe 1238
mbed_official 15:a81a8d6c1dfe 1239 /**
mbed_official 15:a81a8d6c1dfe 1240 * \brief Set the timer TOP/PERIOD value and buffer value.
mbed_official 15:a81a8d6c1dfe 1241 *
mbed_official 15:a81a8d6c1dfe 1242 * This function writes the given value to the PER and PERB register. Usually as
mbed_official 15:a81a8d6c1dfe 1243 * preparation for double buffer or circulared double buffer (circular buffer).
mbed_official 15:a81a8d6c1dfe 1244 *
mbed_official 15:a81a8d6c1dfe 1245 * When using MFRQ, the top values are defined by the CC0 and CCB0, the PER and
mbed_official 15:a81a8d6c1dfe 1246 * PERB values are ignored, so
mbed_official 15:a81a8d6c1dfe 1247 * \ref tcc_set_double_buffer_compare_values (module,channel_0,value,buffer) must
mbed_official 15:a81a8d6c1dfe 1248 * be used instead of this function to change the actual top values in that
mbed_official 15:a81a8d6c1dfe 1249 * case. For all other waveforms operation the top values are defined by PER and
mbed_official 15:a81a8d6c1dfe 1250 * PERB registers values.
mbed_official 15:a81a8d6c1dfe 1251 *
mbed_official 15:a81a8d6c1dfe 1252 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 1253 * \param[in] top_value New value to be loaded into the PER register
mbed_official 15:a81a8d6c1dfe 1254 * \param[in] top_buffer_value New value to be loaded into the PERB register
mbed_official 15:a81a8d6c1dfe 1255 *
mbed_official 15:a81a8d6c1dfe 1256 * \return Status of the TOP set procedure.
mbed_official 15:a81a8d6c1dfe 1257 *
mbed_official 15:a81a8d6c1dfe 1258 * \retval STATUS_OK The timer TOP value was updated successfully
mbed_official 15:a81a8d6c1dfe 1259 * \retval STATUS_ERR_INVALID_ARG An invalid channel index was supplied or
mbed_official 15:a81a8d6c1dfe 1260 * top/period value exceed resolution
mbed_official 15:a81a8d6c1dfe 1261 */
mbed_official 15:a81a8d6c1dfe 1262 enum status_code tcc_set_double_buffer_top_values(
mbed_official 15:a81a8d6c1dfe 1263 const struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 1264 const uint32_t top_value, const uint32_t top_buffer_value)
mbed_official 15:a81a8d6c1dfe 1265 {
mbed_official 15:a81a8d6c1dfe 1266 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 1267 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 1268
mbed_official 15:a81a8d6c1dfe 1269 enum status_code status;
mbed_official 15:a81a8d6c1dfe 1270 status = _tcc_set_top_value(module_inst, top_value, false);
mbed_official 15:a81a8d6c1dfe 1271 if (status != STATUS_OK) {
mbed_official 15:a81a8d6c1dfe 1272 return status;
mbed_official 15:a81a8d6c1dfe 1273 }
mbed_official 15:a81a8d6c1dfe 1274 return _tcc_set_top_value(module_inst, top_buffer_value, true);
mbed_official 15:a81a8d6c1dfe 1275 }
mbed_official 15:a81a8d6c1dfe 1276
mbed_official 15:a81a8d6c1dfe 1277
mbed_official 15:a81a8d6c1dfe 1278 /**
mbed_official 15:a81a8d6c1dfe 1279 * \brief Sets the TCC module waveform output pattern.
mbed_official 15:a81a8d6c1dfe 1280 *
mbed_official 15:a81a8d6c1dfe 1281 * Force waveform output line to generate specific pattern (0, 1, or as is).
mbed_official 15:a81a8d6c1dfe 1282 *
mbed_official 15:a81a8d6c1dfe 1283 * If double buffering is enabled it always write to the buffer
mbed_official 15:a81a8d6c1dfe 1284 * register. The value will then be updated immediately by calling
mbed_official 15:a81a8d6c1dfe 1285 * \ref tcc_force_double_buffer_update(), or be updated when the lock update bit
mbed_official 15:a81a8d6c1dfe 1286 * is cleared and the UPDATE condition happen.
mbed_official 15:a81a8d6c1dfe 1287 *
mbed_official 15:a81a8d6c1dfe 1288 * \param[in] module_inst Pointer to the software module instance struct
mbed_official 15:a81a8d6c1dfe 1289 * \param[in] line_index Output line index
mbed_official 15:a81a8d6c1dfe 1290 * \param[in] pattern Output pattern to use (\ref tcc_output_pattern)
mbed_official 15:a81a8d6c1dfe 1291 *
mbed_official 15:a81a8d6c1dfe 1292 * \return Status of the pattern set procedure.
mbed_official 15:a81a8d6c1dfe 1293 *
mbed_official 15:a81a8d6c1dfe 1294 * \retval STATUS_OK The PATT register is updated successfully
mbed_official 15:a81a8d6c1dfe 1295 * \retval STATUS_ERR_INVALID_ARG An invalid line index was supplied
mbed_official 15:a81a8d6c1dfe 1296 */
mbed_official 15:a81a8d6c1dfe 1297 enum status_code tcc_set_pattern(
mbed_official 15:a81a8d6c1dfe 1298 const struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 1299 const uint32_t line_index,
mbed_official 15:a81a8d6c1dfe 1300 const enum tcc_output_pattern pattern)
mbed_official 15:a81a8d6c1dfe 1301 {
mbed_official 15:a81a8d6c1dfe 1302 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 1303 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 1304 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 1305
mbed_official 15:a81a8d6c1dfe 1306 /* Get a pointer to the module's hardware instance */
mbed_official 15:a81a8d6c1dfe 1307 Tcc *const tcc_module = module_inst->hw;
mbed_official 15:a81a8d6c1dfe 1308 /* Get a index of the module */
mbed_official 15:a81a8d6c1dfe 1309 uint8_t module_index = _tcc_get_inst_index(tcc_module);
mbed_official 15:a81a8d6c1dfe 1310 /* Get number of output lines */
mbed_official 15:a81a8d6c1dfe 1311 uint8_t ow_num = _tcc_ow_nums[module_index];
mbed_official 15:a81a8d6c1dfe 1312
mbed_official 15:a81a8d6c1dfe 1313 /* Check if line number is OK */
mbed_official 15:a81a8d6c1dfe 1314 if (line_index >= ow_num) {
mbed_official 15:a81a8d6c1dfe 1315 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 1316 }
mbed_official 15:a81a8d6c1dfe 1317
mbed_official 15:a81a8d6c1dfe 1318 uint32_t patt_value;
mbed_official 15:a81a8d6c1dfe 1319
mbed_official 15:a81a8d6c1dfe 1320 while(tcc_module->SYNCBUSY.reg & TCC_SYNCBUSY_PATT) {
mbed_official 15:a81a8d6c1dfe 1321 /* Sync wait */
mbed_official 15:a81a8d6c1dfe 1322 }
mbed_official 15:a81a8d6c1dfe 1323 patt_value = tcc_module->PATT.reg;
mbed_official 15:a81a8d6c1dfe 1324 if (TCC_OUTPUT_PATTERN_DISABLE == pattern) {
mbed_official 15:a81a8d6c1dfe 1325 patt_value &= ~(TCC_PATT_PGE0 << line_index);
mbed_official 15:a81a8d6c1dfe 1326 } else if (TCC_OUTPUT_PATTERN_0 == pattern) {
mbed_official 15:a81a8d6c1dfe 1327 patt_value &= ~(TCC_PATT_PGV0 << line_index);
mbed_official 15:a81a8d6c1dfe 1328 patt_value |= (TCC_PATT_PGE0 << line_index);
mbed_official 15:a81a8d6c1dfe 1329 } else {
mbed_official 15:a81a8d6c1dfe 1330 patt_value |= ((TCC_PATT_PGE0 | TCC_PATT_PGV0) << line_index);
mbed_official 15:a81a8d6c1dfe 1331 }
mbed_official 15:a81a8d6c1dfe 1332
mbed_official 15:a81a8d6c1dfe 1333 if (module_inst->double_buffering_enabled) {
mbed_official 15:a81a8d6c1dfe 1334 #if (SAML21) || (SAMC20) || (SAMC21)
mbed_official 15:a81a8d6c1dfe 1335 tcc_module->PATTBUF.reg = patt_value;
mbed_official 15:a81a8d6c1dfe 1336 #else
mbed_official 15:a81a8d6c1dfe 1337 while(tcc_module->SYNCBUSY.reg & TCC_SYNCBUSY_PATTB) {
mbed_official 15:a81a8d6c1dfe 1338 /* Sync wait */
mbed_official 15:a81a8d6c1dfe 1339 }
mbed_official 15:a81a8d6c1dfe 1340 tcc_module->PATTB.reg = patt_value;
mbed_official 15:a81a8d6c1dfe 1341 #endif
mbed_official 15:a81a8d6c1dfe 1342 } else {
mbed_official 15:a81a8d6c1dfe 1343 tcc_module->PATT.reg = patt_value;
mbed_official 15:a81a8d6c1dfe 1344 }
mbed_official 15:a81a8d6c1dfe 1345 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 1346 }
mbed_official 15:a81a8d6c1dfe 1347
mbed_official 15:a81a8d6c1dfe 1348 /**
mbed_official 15:a81a8d6c1dfe 1349 * \brief Retrieves the current module status.
mbed_official 15:a81a8d6c1dfe 1350 *
mbed_official 15:a81a8d6c1dfe 1351 * Retrieves the status of the module, giving overall state information.
mbed_official 15:a81a8d6c1dfe 1352 *
mbed_official 15:a81a8d6c1dfe 1353 * \param[in] module_inst Pointer to the TCC software instance struct
mbed_official 15:a81a8d6c1dfe 1354 *
mbed_official 15:a81a8d6c1dfe 1355 * \return Bitmask of \c TCC_STATUS_* flags.
mbed_official 15:a81a8d6c1dfe 1356 *
mbed_official 15:a81a8d6c1dfe 1357 * \retval TCC_STATUS_CHANNEL_MATCH_CAPTURE(n) Channel n match/capture has occured
mbed_official 15:a81a8d6c1dfe 1358 * \retval TCC_STATUS_CHANNEL_OUTPUT(n) Channel n match/capture output state
mbed_official 15:a81a8d6c1dfe 1359 * \retval TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(x) Non-recoverable fault x has occured
mbed_official 15:a81a8d6c1dfe 1360 * \retval TCC_STATUS_RECOVERABLE_FAULT_OCCUR(n) Recoverable fault n has occured
mbed_official 15:a81a8d6c1dfe 1361 * \retval TCC_STATUS_NON_RECOVERABLE_FAULT_PRESENT(x) Non-recoverable fault x input present
mbed_official 15:a81a8d6c1dfe 1362 * \retval TCC_STATUS_RECOVERABLE_FAULT_PRESENT(n) Recoverable fault n input present
mbed_official 15:a81a8d6c1dfe 1363 * \retval TCC_STATUS_SYNC_READY None of register is syncing
mbed_official 15:a81a8d6c1dfe 1364 * \retval TCC_STATUS_CAPTURE_OVERFLOW Timer capture data has overflowed
mbed_official 15:a81a8d6c1dfe 1365 * \retval TCC_STATUS_COUNTER_EVENT Timer counter event has occurred
mbed_official 15:a81a8d6c1dfe 1366 * \retval TCC_STATUS_COUNT_OVERFLOW Timer count value has overflowed
mbed_official 15:a81a8d6c1dfe 1367 * \retval TCC_STATUS_COUNTER_RETRIGGERED Timer counter has been retriggered
mbed_official 15:a81a8d6c1dfe 1368 * \retval TCC_STATUS_STOP Timer counter has been stopped
mbed_official 15:a81a8d6c1dfe 1369 * \retval TCC_STATUS_RAMP_CYCLE_INDEX Wave ramp index for cycle
mbed_official 15:a81a8d6c1dfe 1370 */
mbed_official 15:a81a8d6c1dfe 1371 uint32_t tcc_get_status(
mbed_official 15:a81a8d6c1dfe 1372 struct tcc_module *const module_inst)
mbed_official 15:a81a8d6c1dfe 1373 {
mbed_official 15:a81a8d6c1dfe 1374 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 1375 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 1376 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 1377
mbed_official 15:a81a8d6c1dfe 1378 uint32_t int_flags = module_inst->hw->INTFLAG.reg;
mbed_official 15:a81a8d6c1dfe 1379 uint32_t status_flags = module_inst->hw->STATUS.reg;
mbed_official 15:a81a8d6c1dfe 1380 uint32_t status = 0;
mbed_official 15:a81a8d6c1dfe 1381 int i;
mbed_official 15:a81a8d6c1dfe 1382
mbed_official 15:a81a8d6c1dfe 1383 /* SYNC */
mbed_official 15:a81a8d6c1dfe 1384 if (module_inst->hw->SYNCBUSY.reg == 0) {
mbed_official 15:a81a8d6c1dfe 1385 status |= TCC_STATUS_SYNC_READY;
mbed_official 15:a81a8d6c1dfe 1386 }
mbed_official 15:a81a8d6c1dfe 1387
mbed_official 15:a81a8d6c1dfe 1388 /* Channels */
mbed_official 15:a81a8d6c1dfe 1389 for (i = 0; i < TCC_NUM_CHANNELS; i++) {
mbed_official 15:a81a8d6c1dfe 1390 if (int_flags & TCC_INTFLAG_MC(i)) {
mbed_official 15:a81a8d6c1dfe 1391 status |= TCC_STATUS_CHANNEL_MATCH_CAPTURE(i);
mbed_official 15:a81a8d6c1dfe 1392 }
mbed_official 15:a81a8d6c1dfe 1393 if (status_flags & TCC_STATUS_CMP(i)) {
mbed_official 15:a81a8d6c1dfe 1394 status |= TCC_STATUS_CHANNEL_OUTPUT(i);
mbed_official 15:a81a8d6c1dfe 1395 }
mbed_official 15:a81a8d6c1dfe 1396 }
mbed_official 15:a81a8d6c1dfe 1397 /* Non-recoverable fault state */
mbed_official 15:a81a8d6c1dfe 1398 if ((int_flags & TCC_INTFLAG_FAULT1) ||
mbed_official 15:a81a8d6c1dfe 1399 (status_flags & TCC_STATUS_FAULT1)) {
mbed_official 15:a81a8d6c1dfe 1400 status |= TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(1);
mbed_official 15:a81a8d6c1dfe 1401 }
mbed_official 15:a81a8d6c1dfe 1402 if ((int_flags & TCC_INTFLAG_FAULT0) ||
mbed_official 15:a81a8d6c1dfe 1403 (status_flags & TCC_STATUS_FAULT0)) {
mbed_official 15:a81a8d6c1dfe 1404 status |= TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(0);
mbed_official 15:a81a8d6c1dfe 1405 }
mbed_official 15:a81a8d6c1dfe 1406 /* Non-recoverable fault inputs */
mbed_official 15:a81a8d6c1dfe 1407 if (status_flags & TCC_STATUS_FAULT0IN) {
mbed_official 15:a81a8d6c1dfe 1408 status |= TCC_STATUS_NON_RECOVERABLE_FAULT_PRESENT(0);
mbed_official 15:a81a8d6c1dfe 1409 }
mbed_official 15:a81a8d6c1dfe 1410 if (status_flags & TCC_STATUS_FAULT1IN) {
mbed_official 15:a81a8d6c1dfe 1411 status |= TCC_STATUS_NON_RECOVERABLE_FAULT_PRESENT(1);
mbed_official 15:a81a8d6c1dfe 1412 }
mbed_official 15:a81a8d6c1dfe 1413 /* Recoverable fault state */
mbed_official 15:a81a8d6c1dfe 1414 if ((int_flags & TCC_INTFLAG_FAULTB) ||
mbed_official 15:a81a8d6c1dfe 1415 (status_flags & TCC_STATUS_FAULTB)) {
mbed_official 15:a81a8d6c1dfe 1416 status |= TCC_STATUS_RECOVERABLE_FAULT_OCCUR(1);
mbed_official 15:a81a8d6c1dfe 1417 }
mbed_official 15:a81a8d6c1dfe 1418 if ((int_flags & TCC_INTFLAG_FAULTA) ||
mbed_official 15:a81a8d6c1dfe 1419 (status_flags & TCC_STATUS_FAULTA)) {
mbed_official 15:a81a8d6c1dfe 1420 status |= TCC_STATUS_RECOVERABLE_FAULT_OCCUR(0);
mbed_official 15:a81a8d6c1dfe 1421 }
mbed_official 15:a81a8d6c1dfe 1422 /* Recoverable fault inputs */
mbed_official 15:a81a8d6c1dfe 1423 if (status_flags & TCC_STATUS_FAULTAIN) {
mbed_official 15:a81a8d6c1dfe 1424 status |= TCC_STATUS_RECOVERABLE_FAULT_PRESENT(0);
mbed_official 15:a81a8d6c1dfe 1425 }
mbed_official 15:a81a8d6c1dfe 1426 if (status_flags & TCC_STATUS_FAULTBIN) {
mbed_official 15:a81a8d6c1dfe 1427 status |= TCC_STATUS_RECOVERABLE_FAULT_PRESENT(1);
mbed_official 15:a81a8d6c1dfe 1428 }
mbed_official 15:a81a8d6c1dfe 1429
mbed_official 15:a81a8d6c1dfe 1430 /* Check for TCC capture overflow */
mbed_official 15:a81a8d6c1dfe 1431 if (int_flags & TCC_INTFLAG_ERR) {
mbed_official 15:a81a8d6c1dfe 1432 status |= TCC_STATUS_CAPTURE_OVERFLOW;
mbed_official 15:a81a8d6c1dfe 1433 }
mbed_official 15:a81a8d6c1dfe 1434 /* Check for TCC count counter */
mbed_official 15:a81a8d6c1dfe 1435 if (int_flags & TCC_INTFLAG_CNT) {
mbed_official 15:a81a8d6c1dfe 1436 status |= TCC_STATUS_COUNTER_EVENT;
mbed_official 15:a81a8d6c1dfe 1437 }
mbed_official 15:a81a8d6c1dfe 1438 /* Check for TCC count retrigger */
mbed_official 15:a81a8d6c1dfe 1439 if (int_flags & TCC_INTFLAG_TRG) {
mbed_official 15:a81a8d6c1dfe 1440 status |= TCC_STATUS_COUNTER_RETRIGGERED;
mbed_official 15:a81a8d6c1dfe 1441 }
mbed_official 15:a81a8d6c1dfe 1442 /* Check for TCC count overflow */
mbed_official 15:a81a8d6c1dfe 1443 if (int_flags & TCC_INTFLAG_OVF) {
mbed_official 15:a81a8d6c1dfe 1444 status |= TCC_STATUS_COUNT_OVERFLOW;
mbed_official 15:a81a8d6c1dfe 1445 }
mbed_official 15:a81a8d6c1dfe 1446 /* Check for TCC count stop */
mbed_official 15:a81a8d6c1dfe 1447 if (status_flags & TCC_STATUS_STOP) {
mbed_official 15:a81a8d6c1dfe 1448 status |= TCC_STATUS_STOPPED;
mbed_official 15:a81a8d6c1dfe 1449 }
mbed_official 15:a81a8d6c1dfe 1450 return status;
mbed_official 15:a81a8d6c1dfe 1451 }
mbed_official 15:a81a8d6c1dfe 1452
mbed_official 15:a81a8d6c1dfe 1453 /**
mbed_official 15:a81a8d6c1dfe 1454 * \brief Clears a module status flag.
mbed_official 15:a81a8d6c1dfe 1455 *
mbed_official 15:a81a8d6c1dfe 1456 * Clears the given status flag of the module.
mbed_official 15:a81a8d6c1dfe 1457 *
mbed_official 15:a81a8d6c1dfe 1458 * \param[in] module_inst Pointer to the TCC software instance struct
mbed_official 15:a81a8d6c1dfe 1459 * \param[in] status_flags Bitmask of \c TCC_STATUS_* flags to clear
mbed_official 15:a81a8d6c1dfe 1460 */
mbed_official 15:a81a8d6c1dfe 1461 void tcc_clear_status(
mbed_official 15:a81a8d6c1dfe 1462 struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 1463 const uint32_t status_flags)
mbed_official 15:a81a8d6c1dfe 1464 {
mbed_official 15:a81a8d6c1dfe 1465 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 1466 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 1467 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 1468
mbed_official 15:a81a8d6c1dfe 1469 uint32_t int_clr = 0;
mbed_official 15:a81a8d6c1dfe 1470 uint32_t status_clr = 0;
mbed_official 15:a81a8d6c1dfe 1471 int i;
mbed_official 15:a81a8d6c1dfe 1472
mbed_official 15:a81a8d6c1dfe 1473 /* Channels */
mbed_official 15:a81a8d6c1dfe 1474 for (i = 0; i < TCC_NUM_CHANNELS; i++) {
mbed_official 15:a81a8d6c1dfe 1475 if (status_flags & TCC_STATUS_CHANNEL_MATCH_CAPTURE(i)) {
mbed_official 15:a81a8d6c1dfe 1476 int_clr |= TCC_INTFLAG_MC(i);
mbed_official 15:a81a8d6c1dfe 1477 }
mbed_official 15:a81a8d6c1dfe 1478 }
mbed_official 15:a81a8d6c1dfe 1479 /* Faults */
mbed_official 15:a81a8d6c1dfe 1480 if (status_flags & TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(1)) {
mbed_official 15:a81a8d6c1dfe 1481 int_clr |= TCC_INTFLAG_FAULT1;
mbed_official 15:a81a8d6c1dfe 1482 status_clr |= TCC_STATUS_FAULT1;
mbed_official 15:a81a8d6c1dfe 1483 }
mbed_official 15:a81a8d6c1dfe 1484 if (status_flags & TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(0)) {
mbed_official 15:a81a8d6c1dfe 1485 int_clr |= TCC_INTFLAG_FAULT0;
mbed_official 15:a81a8d6c1dfe 1486 status_clr |= TCC_STATUS_FAULT0;
mbed_official 15:a81a8d6c1dfe 1487 }
mbed_official 15:a81a8d6c1dfe 1488 if (status_flags & TCC_STATUS_RECOVERABLE_FAULT_OCCUR(1)) {
mbed_official 15:a81a8d6c1dfe 1489 int_clr |= TCC_INTFLAG_FAULTB;
mbed_official 15:a81a8d6c1dfe 1490 status_clr |= TCC_STATUS_FAULTB;
mbed_official 15:a81a8d6c1dfe 1491 }
mbed_official 15:a81a8d6c1dfe 1492 if (status_flags & TCC_STATUS_RECOVERABLE_FAULT_OCCUR(0)) {
mbed_official 15:a81a8d6c1dfe 1493 int_clr |= TCC_INTFLAG_FAULTA;
mbed_official 15:a81a8d6c1dfe 1494 status_clr |= TCC_STATUS_FAULTA;
mbed_official 15:a81a8d6c1dfe 1495 }
mbed_official 15:a81a8d6c1dfe 1496 /* Check for TCC capture overflow */
mbed_official 15:a81a8d6c1dfe 1497 if (status_flags & TCC_STATUS_CAPTURE_OVERFLOW) {
mbed_official 15:a81a8d6c1dfe 1498 int_clr |= TCC_INTFLAG_ERR;
mbed_official 15:a81a8d6c1dfe 1499 }
mbed_official 15:a81a8d6c1dfe 1500 /* Check for TCC count counter */
mbed_official 15:a81a8d6c1dfe 1501 if (status_flags & TCC_STATUS_COUNTER_EVENT) {
mbed_official 15:a81a8d6c1dfe 1502 int_clr |= TCC_INTFLAG_CNT;
mbed_official 15:a81a8d6c1dfe 1503 }
mbed_official 15:a81a8d6c1dfe 1504 /* Check for TCC count retrigger */
mbed_official 15:a81a8d6c1dfe 1505 if (status_flags & TCC_STATUS_COUNTER_RETRIGGERED) {
mbed_official 15:a81a8d6c1dfe 1506 int_clr = TCC_INTFLAG_TRG;
mbed_official 15:a81a8d6c1dfe 1507 }
mbed_official 15:a81a8d6c1dfe 1508 /* Check for TCC count overflow */
mbed_official 15:a81a8d6c1dfe 1509 if (status_flags & TCC_STATUS_COUNT_OVERFLOW) {
mbed_official 15:a81a8d6c1dfe 1510 int_clr |= TCC_INTFLAG_OVF;
mbed_official 15:a81a8d6c1dfe 1511 }
mbed_official 15:a81a8d6c1dfe 1512 /* Clear status flag */
mbed_official 15:a81a8d6c1dfe 1513 module_inst->hw->STATUS.reg = status_clr;
mbed_official 15:a81a8d6c1dfe 1514 /* Clear interrupt flag */
mbed_official 15:a81a8d6c1dfe 1515 module_inst->hw->INTFLAG.reg = int_clr;
mbed_official 15:a81a8d6c1dfe 1516 }
mbed_official 15:a81a8d6c1dfe 1517
mbed_official 15:a81a8d6c1dfe 1518 /**
mbed_official 15:a81a8d6c1dfe 1519 * \brief Enable circular option for double buffered compare values.
mbed_official 15:a81a8d6c1dfe 1520 *
mbed_official 15:a81a8d6c1dfe 1521 * Enable circular option for the double buffered channel compare values.
mbed_official 15:a81a8d6c1dfe 1522 * On each UPDATE condition, the contents of CCBx and CCx are switched, meaning
mbed_official 15:a81a8d6c1dfe 1523 * that the contents of CCBx are transferred to CCx and the contents of CCx are
mbed_official 15:a81a8d6c1dfe 1524 * transferred to CCBx.
mbed_official 15:a81a8d6c1dfe 1525 *
mbed_official 15:a81a8d6c1dfe 1526 * \param[in] module_inst Pointer to the TCC software instance struct
mbed_official 15:a81a8d6c1dfe 1527 * \param[in] channel_index Index of the compare channel to set up to
mbed_official 15:a81a8d6c1dfe 1528 *
mbed_official 15:a81a8d6c1dfe 1529 * \retval STATUS_OK The module was initialized successfully
mbed_official 15:a81a8d6c1dfe 1530 * \retval STATUS_INVALID_ARG An invalid channel index is supplied
mbed_official 15:a81a8d6c1dfe 1531 */
mbed_official 15:a81a8d6c1dfe 1532 enum status_code tcc_enable_circular_buffer_compare(
mbed_official 15:a81a8d6c1dfe 1533 struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 1534 enum tcc_match_capture_channel channel_index)
mbed_official 15:a81a8d6c1dfe 1535 {
mbed_official 15:a81a8d6c1dfe 1536 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 1537 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 1538 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 1539
mbed_official 15:a81a8d6c1dfe 1540 /* Get a pointer to the module's hardware instance */
mbed_official 15:a81a8d6c1dfe 1541 Tcc *const tcc_module = module_inst->hw;
mbed_official 15:a81a8d6c1dfe 1542 /* Get a index of the module */
mbed_official 15:a81a8d6c1dfe 1543 uint8_t module_index = _tcc_get_inst_index(tcc_module);
mbed_official 15:a81a8d6c1dfe 1544
mbed_official 15:a81a8d6c1dfe 1545 /* Check index */
mbed_official 15:a81a8d6c1dfe 1546 if (channel_index > 3) {
mbed_official 15:a81a8d6c1dfe 1547 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 1548 }
mbed_official 15:a81a8d6c1dfe 1549 if (channel_index >= _tcc_cc_nums[module_index]) {
mbed_official 15:a81a8d6c1dfe 1550 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 1551 }
mbed_official 15:a81a8d6c1dfe 1552
mbed_official 15:a81a8d6c1dfe 1553 tcc_module->WAVE.reg |= (TCC_WAVE_CICCEN0 << channel_index);
mbed_official 15:a81a8d6c1dfe 1554
mbed_official 15:a81a8d6c1dfe 1555 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 1556 }
mbed_official 15:a81a8d6c1dfe 1557
mbed_official 15:a81a8d6c1dfe 1558 /**
mbed_official 15:a81a8d6c1dfe 1559 * \brief Disable circular option for double buffered compare values.
mbed_official 15:a81a8d6c1dfe 1560 *
mbed_official 15:a81a8d6c1dfe 1561 * Stop circularing the double buffered compare values.
mbed_official 15:a81a8d6c1dfe 1562 *
mbed_official 15:a81a8d6c1dfe 1563 * \param[in] module_inst Pointer to the TCC software instance struct
mbed_official 15:a81a8d6c1dfe 1564 * \param[in] channel_index Index of the compare channel to set up to
mbed_official 15:a81a8d6c1dfe 1565 *
mbed_official 15:a81a8d6c1dfe 1566 * \retval STATUS_OK The module was initialized successfully
mbed_official 15:a81a8d6c1dfe 1567 * \retval STATUS_INVALID_ARG An invalid channel index is supplied
mbed_official 15:a81a8d6c1dfe 1568 */
mbed_official 15:a81a8d6c1dfe 1569 enum status_code tcc_disable_circular_buffer_compare(
mbed_official 15:a81a8d6c1dfe 1570 struct tcc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 1571 enum tcc_match_capture_channel channel_index)
mbed_official 15:a81a8d6c1dfe 1572 {
mbed_official 15:a81a8d6c1dfe 1573 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 1574 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 1575 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 1576
mbed_official 15:a81a8d6c1dfe 1577 /* Get a pointer to the module's hardware instance */
mbed_official 15:a81a8d6c1dfe 1578 Tcc *const tcc_module = module_inst->hw;
mbed_official 15:a81a8d6c1dfe 1579 /* Get a index of the module */
mbed_official 15:a81a8d6c1dfe 1580 uint8_t module_index = _tcc_get_inst_index(tcc_module);
mbed_official 15:a81a8d6c1dfe 1581
mbed_official 15:a81a8d6c1dfe 1582 /* Check index */
mbed_official 15:a81a8d6c1dfe 1583 if (channel_index > 3) {
mbed_official 15:a81a8d6c1dfe 1584 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 1585 }
mbed_official 15:a81a8d6c1dfe 1586 if (channel_index >= _tcc_cc_nums[module_index]) {
mbed_official 15:a81a8d6c1dfe 1587 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 1588 }
mbed_official 15:a81a8d6c1dfe 1589
mbed_official 15:a81a8d6c1dfe 1590 tcc_module->WAVE.reg &= ~(TCC_WAVE_CICCEN0 << channel_index);
mbed_official 15:a81a8d6c1dfe 1591
mbed_official 15:a81a8d6c1dfe 1592 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 1593 }