mbed library sources. Supersedes mbed-src.
Fork of mbed-dev by
targets/hal/TARGET_Atmel/TARGET_SAM_CortexM0P/drivers/tcc/tcc.c@15:a81a8d6c1dfe, 2015-11-04 (annotated)
- 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?
User | Revision | Line number | New 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 | } |