|
| 1 | +/* |
| 2 | +Copyright (C) 2012 Albert van Dalen http://www.avdweb.nl |
| 3 | +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License |
| 4 | +as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. |
| 5 | +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty |
| 6 | +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at http://www.gnu.org/licenses . |
| 7 | +
|
| 8 | +Version 26-1-2017 |
| 9 | +
|
| 10 | +16 bit timer: max period_us = 1398080us (0.7Hz), min period_us = 1us (1MHz) |
| 11 | +
|
| 12 | +note *1 SCK, MOSI, MISO are on Arduino Zero SPI header |
| 13 | +
|
| 14 | +Timer Arduino Zero pins SAM15x15 pins |
| 15 | +SAMDtimer 0 8bit D3 D18/A4 D17 D4 d[9] d[5] d[4] d[8] timer not yet implemented |
| 16 | +SAMDtimer 0 16bit D3 D18/A4 d[9] d[5] timer not yet implemented |
| 17 | +SAMDtimer 1 8bit D0 D9 D33 D8 D1 D30 d[11] d[7] d[31] d[6] d[10] d[27] timer not yet implemented |
| 18 | +SAMDtimer 1 16bit D0 D9 D33 d[11] d[7] d[31] timer not yet implemented |
| 19 | +SAMDtimer 2 8bit D13 (D28) D22/MISO*1 D16 d[19] d[15] d[14] d[3] timer not yet implemented |
| 20 | +SAMDtimer 2 16bit D13 (D28) d[19] d[15] timer not yet implemented |
| 21 | +
|
| 22 | +SAMDtimer 3 8bit D5 D12 D2 D10 d[17] d[21] d[16] d[20] timer not yet implemented |
| 23 | +SAMDtimer 3 16bit D5 D12 d[17] d[21] |
| 24 | +SAMDtimer 4 8bit D16/A2 D21/SCL D15/A1 D20/SDA d[3] d[25] d[2] d[24] timer not yet implemented |
| 25 | +SAMDtimer 4 16bit D16/A2 D21/SCL d[3] d[25] |
| 26 | +SAMDtimer 5 8bit D24/SCK*1 D23/MOSI*1 d[13] d[12] timer not yet implemented |
| 27 | +SAMDtimer 5 16bit D24/SCK*1 d[13] |
| 28 | +*/ |
| 29 | + |
| 30 | +#include "avdweb_SAMDtimer.h" |
| 31 | + |
| 32 | +SAMDtimer::SAMDtimer(byte timerNr, tc_counter_size countersize, byte pin, unsigned period_us, int pulseWidth_us, bool timerEnable): |
| 33 | +Adafruit_ZeroTimer(timerNr), pin(pin), countersize(countersize), period_us(period_us) |
| 34 | +{ if(pulseWidth_us==-1) calc(period_us, period_us/2); |
| 35 | + else calc(period_us, pulseWidth_us); |
| 36 | + init(timerEnable); |
| 37 | +} |
| 38 | + |
| 39 | +SAMDtimer::SAMDtimer(byte timerNr, tc_callback_t _ISR, unsigned period_us, bool ISRenable): |
| 40 | +Adafruit_ZeroTimer(timerNr) |
| 41 | +{ ISR = _ISR; |
| 42 | + countersize = TC_COUNTER_SIZE_16BIT; |
| 43 | + calc(period_us, period_us/2); |
| 44 | + init(1); |
| 45 | + setCallback(ISRenable, TC_CALLBACK_CC_CHANNEL1, ISR); |
| 46 | +} |
| 47 | + |
| 48 | +void SAMDtimer::setPulseWidth(unsigned pulseWidth_us) |
| 49 | +{ calc(period_us, pulseWidth_us); |
| 50 | + setPeriodMatch(periodCounter, PWcounter, 1); |
| 51 | +} |
| 52 | + |
| 53 | +void SAMDtimer::attachInterrupt(tc_callback_t _ISR, bool interruptEnable) |
| 54 | +{ ISR = _ISR; |
| 55 | + setCallback(interruptEnable, TC_CALLBACK_CC_CHANNEL1, ISR); |
| 56 | +} |
| 57 | + |
| 58 | +void SAMDtimer::enableTimer(bool timerEnable) |
| 59 | +{ enable(timerEnable); |
| 60 | +} |
| 61 | + |
| 62 | +void SAMDtimer::enableInterrupt(bool interruptEnable) |
| 63 | +{ setCallback(interruptEnable, TC_CALLBACK_CC_CHANNEL1, ISR); |
| 64 | +} |
| 65 | + |
| 66 | +void SAMDtimer::init(bool enabled) |
| 67 | +{ configure(prescale, countersize, TC_WAVE_GENERATION_MATCH_PWM); |
| 68 | + PWMout(true, 1, pin); // must be ch1 for 16bit |
| 69 | + setPeriodMatch(periodCounter, PWcounter, 1); |
| 70 | + enable(enabled); |
| 71 | +} |
| 72 | + |
| 73 | +void SAMDtimer::calc(unsigned period_us, unsigned pulseWidth_us) |
| 74 | +{ periodCounter = (F_CPU * (signed)period_us) / 1000000; // why signed? |
| 75 | + PWcounter = (F_CPU * (signed)pulseWidth_us) / 1000000; |
| 76 | + if(periodCounter < 65536) prescale = TC_CLOCK_PRESCALER_DIV1; |
| 77 | + else if((PWcounter >>= 1, periodCounter >>= 1) < 65536) prescale = TC_CLOCK_PRESCALER_DIV2; // = 256 |
| 78 | + else if((PWcounter >>= 1, periodCounter >>= 1) < 65536) prescale = TC_CLOCK_PRESCALER_DIV4; |
| 79 | + else if((PWcounter >>= 1, periodCounter >>= 1) < 65536) prescale = TC_CLOCK_PRESCALER_DIV8; |
| 80 | + else if((PWcounter >>= 1, periodCounter >>= 1) < 65536) prescale = TC_CLOCK_PRESCALER_DIV16; |
| 81 | + else if((PWcounter >>= 2, periodCounter >>= 2) < 65536) prescale = TC_CLOCK_PRESCALER_DIV64; |
| 82 | + else if((PWcounter >>= 2, periodCounter >>= 2) < 65536) prescale = TC_CLOCK_PRESCALER_DIV256; |
| 83 | + else if((PWcounter >>= 2, periodCounter >>= 2) < 65536) prescale = TC_CLOCK_PRESCALER_DIV1024; |
| 84 | +} |
| 85 | + |
| 86 | + |
| 87 | + |
| 88 | + |
| 89 | + |
0 commit comments