2 * Copyright © 2022 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 #define BEEP_SCALE (AO_SYSCLK / 750000)
27 struct samd21_tcc *tcc = AO_BEEP_TCC;
29 tcc->per = (beep * BEEP_SCALE);
30 tcc->ctrla = (1 << SAMD21_TCC_CTRLA_ENABLE);
32 tcc->ctrla = (0 << SAMD21_TCC_CTRLA_ENABLE);
37 ao_beep_for(uint8_t beep, AO_TICK_TYPE ticks)
45 ao_tcc_init(struct samd21_tcc *tcc, uint32_t apbcmask)
47 samd21_pm.apbcmask |= apbcmask;
49 /* Reset the device */
50 tcc->ctrla = (1 << SAMD21_TCC_CTRLA_SWRST);
52 while ((tcc->ctrla & (1 << SAMD21_TCC_CTRLA_SWRST)) != 0 ||
53 (tcc->syncbusy & (1 << SAMD21_TCC_SYNCBUSY_SWRST)) != 0)
56 tcc->per = 94 * BEEP_SCALE;
58 tcc->wave = ((SAMD21_TCC_WAVE_WAVEGEN_NFRQ << SAMD21_TCC_WAVE_WAVEGEN) |
59 (0 << SAMD21_TCC_WAVE_RAMP) |
60 (0 << SAMD21_TCC_WAVE_CIPEREN) |
61 (0 << SAMD21_TCC_WAVE_CCCEN(0)) |
62 (0 << SAMD21_TCC_WAVE_CCCEN(1)) |
63 (0 << SAMD21_TCC_WAVE_CCCEN(2)) |
64 (0 << SAMD21_TCC_WAVE_CCCEN(3)) |
65 (0 << SAMD21_TCC_WAVE_POL(0)) |
66 (0 << SAMD21_TCC_WAVE_POL(1)) |
67 (0 << SAMD21_TCC_WAVE_POL(1)) |
68 (0 << SAMD21_TCC_WAVE_POL(3)) |
69 (0 << SAMD21_TCC_WAVE_SWAP(0)) |
70 (0 << SAMD21_TCC_WAVE_SWAP(1)) |
71 (0 << SAMD21_TCC_WAVE_SWAP(1)) |
72 (0 << SAMD21_TCC_WAVE_SWAP(3)));
74 tcc->dbgctrl = (1 << SAMD21_TCC_DBGCTRL_DBGRUN);
80 struct samd21_port *port = AO_BEEP_PORT;
81 uint8_t pin = AO_BEEP_PIN;
82 struct samd21_tcc *tcc = AO_BEEP_TCC;
83 uint32_t apbc_mask = 1UL << AO_BEEP_TCC_APBC_MASK;
85 if (tcc == &samd21_tcc0 || tcc == &samd21_tcc1) {
86 samd21_gclk_clkctrl(0, SAMD21_GCLK_CLKCTRL_ID_TCC0_TCC1);
88 samd21_gclk_clkctrl(0, SAMD21_GCLK_CLKCTRL_ID_TCC2_TC3);
91 ao_tcc_init(tcc, apbc_mask);
93 ao_enable_output(port, pin, 0);
95 samd21_port_pmux_set(port, pin, AO_BEEP_FUNC);