diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..f0e2614 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,46 @@ +Thank you for opening an issue on an Adafruit Arduino library repository. To +improve the speed of resolution please review the following guidelines and +common troubleshooting steps below before creating the issue: + +- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use + the forums at http://forums.adafruit.com to ask questions and troubleshoot why + something isn't working as expected. In many cases the problem is a common issue + that you will more quickly receive help from the forum community. GitHub issues + are meant for known defects in the code. If you don't know if there is a defect + in the code then start with troubleshooting on the forum first. + +- **If following a tutorial or guide be sure you didn't miss a step.** Carefully + check all of the steps and commands to run have been followed. Consult the + forum if you're unsure or have questions about steps in a guide/tutorial. + +- **For Arduino projects check these very common issues to ensure they don't apply**: + + - For uploading sketches or communicating with the board make sure you're using + a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes + very hard to tell the difference between a data and charge cable! Try using the + cable with other devices or swapping to another cable to confirm it is not + the problem. + + - **Be sure you are supplying adequate power to the board.** Check the specs of + your board and plug in an external power supply. In many cases just + plugging a board into your computer is not enough to power it and other + peripherals. + + - **Double check all soldering joints and connections.** Flakey connections + cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. + + - **Ensure you are using an official Arduino or Adafruit board.** We can't + guarantee a clone board will have the same functionality and work as expected + with this code and don't support them. + +If you're sure this issue is a defect in the code and checked the steps above +please fill in the following fields to provide enough troubleshooting information. +You may delete the guideline and text above to just leave the following details: + +- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** + +- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO + VERSION HERE** + +- List the steps to reproduce the problem below (if possible attach a sketch or + copy the sketch code in too): **LIST REPRO STEPS BELOW** diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..7b641eb --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,26 @@ +Thank you for creating a pull request to contribute to Adafruit's GitHub code! +Before you open the request please review the following guidelines and tips to +help it be more easily integrated: + +- **Describe the scope of your change--i.e. what the change does and what parts + of the code were modified.** This will help us understand any risks of integrating + the code. + +- **Describe any known limitations with your change.** For example if the change + doesn't apply to a supported platform of the library please mention it. + +- **Please run any tests or examples that can exercise your modified code.** We + strive to not break users of the code and running tests/examples helps with this + process. + +Thank you again for contributing! We will try to test and integrate the change +as soon as we can, but be aware we have many GitHub repositories to manage and +can't immediately respond to every request. There is no need to bump or check in +on a pull request (it will clutter the discussion of the request). + +Also don't be worried if the request is closed or not integrated--sometimes the +priorities of Adafruit's GitHub code (education, ease of use) might not match the +priorities of the pull request. Don't fret, the open source community thrives on +forks and GitHub makes it easy to keep your changes in a forked repo. + +After reviewing the guidelines above you can delete this text from the pull request. diff --git a/.github/workflows/githubci.yml b/.github/workflows/githubci.yml new file mode 100644 index 0000000..f726b44 --- /dev/null +++ b/.github/workflows/githubci.yml @@ -0,0 +1,26 @@ +name: Arduino Library CI + +on: [pull_request, push, repository_dispatch] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/setup-python@v1 + with: + python-version: '3.x' + - uses: actions/checkout@v2 + - uses: actions/checkout@v2 + with: + repository: adafruit/ci-arduino + path: ci + + - name: pre-install + run: bash ci/actions_install.sh + + - name: test platforms + run: python3 ci/build_platform.py zero + + - name: clang + run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . diff --git a/Adafruit_FreeTouch.cpp b/Adafruit_FreeTouch.cpp index 4624b7e..72dc31a 100644 --- a/Adafruit_FreeTouch.cpp +++ b/Adafruit_FreeTouch.cpp @@ -27,110 +27,119 @@ #include "adafruit_ptc.h" -Adafruit_FreeTouch::Adafruit_FreeTouch(int p, oversample_t f, series_resistor_t r, freq_mode_t fh) { - adafruit_ptc_get_config_default(&config); - pin = p; - uint8_t port_offset = 0; - if (g_APinDescription[pin].ulPort == PORTB) { - port_offset += 32; - } - config.pin = port_offset + g_APinDescription[pin].ulPin; - config.yline = getYLine(); // determine the Y0-15 # - config.oversample = f; - config.seriesres = r; - config.freqhop = fh; +Adafruit_FreeTouch::Adafruit_FreeTouch(int p, oversample_t f, + series_resistor_t r, freq_mode_t fh) { + adafruit_ptc_get_config_default(&config); + pin = p; + uint8_t port_offset = 0; + if (g_APinDescription[pin].ulPort == PORTB) { + port_offset += 32; + } + config.pin = port_offset + g_APinDescription[pin].ulPin; + config.yline = getYLine(); // determine the Y0-15 # + config.oversample = f; + config.seriesres = r; + config.freqhop = fh; } bool Adafruit_FreeTouch::begin(void) { - if (config.yline == -1) { // not all pins have Y line - return false; - } + if (config.yline == -1) { // not all pins have Y line + return false; + } - /* Setup and enable generic clock source for PTC module. - struct system_gclk_chan_config gclk_chan_conf; - system_gclk_chan_get_config_defaults(&gclk_chan_conf); - */ - - uint8_t channel = PTC_GCLK_ID; - uint8_t source_generator = 3; - - // original line: system_gclk_chan_set_config(PTC_GCLK_ID, &gclk_chan_conf); - uint32_t new_clkctrl_config = (channel << GCLK_CLKCTRL_ID_Pos); // from gclk.c - - // original line: gclk_chan_conf.source_generator = GCLK_GENERATOR_1; - /* Select the desired generic clock generator */ - new_clkctrl_config |= source_generator << GCLK_CLKCTRL_GEN_Pos; // from gclk.c - - /* Disable generic clock channel */ - // original line: system_gclk_chan_disable(channel); - noInterrupts(); - - /* Select the requested generator channel */ - *((uint8_t*)&GCLK->CLKCTRL.reg) = channel; - - /* Sanity check WRTLOCK */ - //Assert(!GCLK->CLKCTRL.bit.WRTLOCK); - - /* Switch to known-working source so that the channel can be disabled */ - uint32_t prev_gen_id = GCLK->CLKCTRL.bit.GEN; - GCLK->CLKCTRL.bit.GEN = 0; - - /* Disable the generic clock */ - GCLK->CLKCTRL.reg &= ~GCLK_CLKCTRL_CLKEN; - while (GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN) { - /* Wait for clock to become disabled */ - } - - /* Restore previous configured clock generator */ - GCLK->CLKCTRL.bit.GEN = prev_gen_id; - - //system_interrupt_leave_critical_section(); - interrupts(); - - /* Write the new configuration */ - GCLK->CLKCTRL.reg = new_clkctrl_config; - - // original line: system_gclk_chan_enable(PTC_GCLK_ID); - *((uint8_t*)&GCLK->CLKCTRL.reg) = channel; - GCLK->CLKCTRL.reg |= GCLK_CLKCTRL_CLKEN; /* Enable the generic clock */ - - - // original line: system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_PTC); - PM->APBCMASK.reg |= PM_APBCMASK_PTC; - - adafruit_ptc_init(PTC, &config); - - return true; + /* Setup and enable generic clock source for PTC module. + struct system_gclk_chan_config gclk_chan_conf; + system_gclk_chan_get_config_defaults(&gclk_chan_conf); + */ + + uint8_t channel = PTC_GCLK_ID; + uint8_t source_generator = 3; + + // original line: system_gclk_chan_set_config(PTC_GCLK_ID, &gclk_chan_conf); + uint32_t new_clkctrl_config = (channel << GCLK_CLKCTRL_ID_Pos); // from gclk.c + + // original line: gclk_chan_conf.source_generator = GCLK_GENERATOR_1; + /* Select the desired generic clock generator */ + new_clkctrl_config |= source_generator << GCLK_CLKCTRL_GEN_Pos; // from gclk.c + + /* Disable generic clock channel */ + // original line: system_gclk_chan_disable(channel); + noInterrupts(); + + /* Select the requested generator channel */ + *((uint8_t *)&GCLK->CLKCTRL.reg) = channel; + + /* Sanity check WRTLOCK */ + // Assert(!GCLK->CLKCTRL.bit.WRTLOCK); + + /* Switch to known-working source so that the channel can be disabled */ + uint32_t prev_gen_id = GCLK->CLKCTRL.bit.GEN; + GCLK->CLKCTRL.bit.GEN = 0; + + /* Disable the generic clock */ + GCLK->CLKCTRL.reg &= ~GCLK_CLKCTRL_CLKEN; + while (GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN) { + /* Wait for clock to become disabled */ + } + + /* Restore previous configured clock generator */ + GCLK->CLKCTRL.bit.GEN = prev_gen_id; + + // system_interrupt_leave_critical_section(); + interrupts(); + + /* Write the new configuration */ + GCLK->CLKCTRL.reg = new_clkctrl_config; + + // original line: system_gclk_chan_enable(PTC_GCLK_ID); + *((uint8_t *)&GCLK->CLKCTRL.reg) = channel; + GCLK->CLKCTRL.reg |= GCLK_CLKCTRL_CLKEN; /* Enable the generic clock */ + + // original line: system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, + // PM_APBCMASK_PTC); + PM->APBCMASK.reg |= PM_APBCMASK_PTC; + + adafruit_ptc_init(PTC, &config); + + return true; } uint16_t Adafruit_FreeTouch::measure(void) { uint16_t m; m = measureRaw(); - if (m == -1) return -1; + if (m == -1) + return -1; // normalize the signal switch (config.oversample) { - case OVERSAMPLE_1: return m; - case OVERSAMPLE_2: return m/2; - case OVERSAMPLE_4: return m/4; - case OVERSAMPLE_8: return m/8; - case OVERSAMPLE_16: return m/16; - case OVERSAMPLE_32: return m/32; - case OVERSAMPLE_64: return m/64; + case OVERSAMPLE_1: + return m; + case OVERSAMPLE_2: + return m / 2; + case OVERSAMPLE_4: + return m / 4; + case OVERSAMPLE_8: + return m / 8; + case OVERSAMPLE_16: + return m / 16; + case OVERSAMPLE_32: + return m / 32; + case OVERSAMPLE_64: + return m / 64; } return -1; // shouldn't reach here but fail if we do! } uint16_t Adafruit_FreeTouch::measureRaw(void) { - adafruit_ptc_start_conversion(PTC, &config); + adafruit_ptc_start_conversion(PTC, &config); - while (!adafruit_ptc_is_conversion_finished(PTC)) { - yield(); - } + while (!adafruit_ptc_is_conversion_finished(PTC)) { + yield(); + } - return adafruit_ptc_get_conversion_result(PTC); + return adafruit_ptc_get_conversion_result(PTC); } /*********************************** low level config **/ @@ -153,24 +162,22 @@ int Adafruit_FreeTouch::getYLine(void) { } void Adafruit_FreeTouch::setCompCap(uint16_t cc) { - config.compcap = cc & 0x3FFF; + config.compcap = cc & 0x3FFF; } -void Adafruit_FreeTouch::setIntCap(uint8_t ic) { - config.intcap = ic & 0x3F; -} +void Adafruit_FreeTouch::setIntCap(uint8_t ic) { config.intcap = ic & 0x3F; } void Adafruit_FreeTouch::setOversampling(oversample_t lvl) { - config.oversample = lvl; // back it up for later + config.oversample = lvl; // back it up for later } void Adafruit_FreeTouch::setSeriesResistor(series_resistor_t res) { - config.seriesres = res; + config.seriesres = res; } void Adafruit_FreeTouch::setFreqHopping(freq_mode_t fh, freq_hop_t hs) { - config.freqhop = fh; - config.hops = hs; + config.freqhop = fh; + config.hops = hs; } /**************************** DEBUGGING ASSIST *************************/ @@ -179,102 +186,216 @@ void Adafruit_FreeTouch::snapshotRegsAndPrint(uint32_t base, uint8_t numregs) { uint8_t datas[255]; digitalWrite(LED_BUILTIN, HIGH); - for (uint8_t i=0; i #include "adafruit_ptc.h" +#include class Adafruit_FreeTouch { - public: - Adafruit_FreeTouch(int p = 0, oversample_t f = OVERSAMPLE_4, series_resistor_t r = RESISTOR_0, freq_mode_t fh = FREQ_MODE_NONE); +public: + Adafruit_FreeTouch(int p = 0, oversample_t f = OVERSAMPLE_4, + series_resistor_t r = RESISTOR_0, + freq_mode_t fh = FREQ_MODE_NONE); bool begin(void); uint16_t measure(void); uint16_t measureRaw(void); - private: +private: void ptcInitSettings(void); void ptcConfigIOpin(void); uint16_t startPtcAcquire(void); - int getYLine(void); + int getYLine(void); void selectYLine(void); void setOversampling(oversample_t lvl); void setSeriesResistor(series_resistor_t res); @@ -29,9 +31,9 @@ class Adafruit_FreeTouch { void printHex(uint8_t h, boolean newline); void printPTCregs(uint32_t base, uint8_t *regs, uint8_t num); - private: - int pin; // arduino pin # - struct adafruit_ptc_config config; +private: + int pin; // arduino pin # + struct adafruit_ptc_config config; }; #endif diff --git a/README.md b/README.md index 3b179a4..e7cdf82 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# Adafruit_FreeTouch +# Adafruit_FreeTouch [![Build Status](https://github.com/adafruit/Adafruit_FreeTouch/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_FreeTouch/actions) + A QTouch-compatible library diff --git a/adafruit_ptc.c b/adafruit_ptc.c index 5312fb7..6bd0d8f 100644 --- a/adafruit_ptc.c +++ b/adafruit_ptc.c @@ -25,140 +25,140 @@ #include "adafruit_ptc.h" -static void sync_config(Ptc const* module_inst) { - while (module_inst->CTRLB.bit.SYNCFLAG); +static void sync_config(Ptc const *module_inst) { + while (module_inst->CTRLB.bit.SYNCFLAG) + ; } void adafruit_ptc_get_config_default(struct adafruit_ptc_config *config) { - config->pin = 0xff; - config->yline = -1; - config->oversample = OVERSAMPLE_4; - config->seriesres = RESISTOR_0; - config->freqhop = FREQ_MODE_NONE; - config->compcap = 0x2000; - config->intcap = 0x3F; + config->pin = 0xff; + config->yline = -1; + config->oversample = OVERSAMPLE_4; + config->seriesres = RESISTOR_0; + config->freqhop = FREQ_MODE_NONE; + config->compcap = 0x2000; + config->intcap = 0x3F; } -void adafruit_ptc_init(Ptc* module_inst, struct adafruit_ptc_config const* config) { - // Configure the pin. - PortGroup* group = &PORT->Group[config->pin / 32]; - uint8_t pin = config->pin % 32; - uint32_t pin_mask = (1UL << pin); - uint32_t wr_pin_mask; - uint32_t half_word_select; - if (pin > 15) { - wr_pin_mask = pin_mask >> 16; - half_word_select = PORT_WRCONFIG_HWSEL; - } else { - wr_pin_mask = pin_mask & 0xffff; - half_word_select = 0; - } - // Atomically change the pin config and the pin mux. - group->WRCONFIG.reg = wr_pin_mask | - PORT_WRCONFIG_WRPINCFG | - PORT_WRCONFIG_WRPMUX | - PORT_WRCONFIG_PMUXEN | - PORT_WRCONFIG_PMUX(1) | - half_word_select; - // Make sure output is off. - group->DIRCLR.reg = pin_mask; - - sync_config(module_inst); - module_inst->CTRLA.bit.ENABLE = 0; - sync_config(module_inst); - - module_inst->UNK4C04.reg &= 0xF7; //MEMORY[0x42004C04] &= 0xF7u; - module_inst->UNK4C04.reg &= 0xFB; //MEMORY[0x42004C04] &= 0xFBu; - module_inst->UNK4C04.reg &= 0xFC; //MEMORY[0x42004C04] &= 0xFCu; - sync_config(module_inst); - module_inst->FREQCTRL.reg &= 0x9F; //MEMORY[0x42004C0C] &= 0x9Fu; - sync_config(module_inst); - module_inst->FREQCTRL.reg &= 0xEF; //MEMORY[0x42004C0C] &= 0xEFu; - sync_config(module_inst); - module_inst->FREQCTRL.bit.SAMPLEDELAY = 0; //MEMORY[0x42004C0C] &= 0xF0u; - module_inst->CTRLC.bit.INIT = 1; //MEMORY[0x42004C05] |= 1u; - module_inst->CTRLA.bit.RUNINSTANDBY = 1; //MEMORY[0x42004C00] |= 4u; - sync_config(module_inst); - module_inst->INTDISABLE.bit.WCO = 1; - sync_config(module_inst); - module_inst->INTDISABLE.bit.EOC = 1; - sync_config(module_inst); - - // enable the sensor, only done once per line - if (config->yline < 8) { - sync_config(module_inst); - module_inst->YENABLEL.reg |= 1 << config->yline; - sync_config(module_inst); - } else if (config->yline < 16) { - module_inst->YENABLEH.reg |= 1 << (config->yline - 8); - } - - sync_config(module_inst); - module_inst->CTRLA.bit.ENABLE = 1; - sync_config(module_inst); +void adafruit_ptc_init(Ptc *module_inst, + struct adafruit_ptc_config const *config) { + // Configure the pin. + PortGroup *group = &PORT->Group[config->pin / 32]; + uint8_t pin = config->pin % 32; + uint32_t pin_mask = (1UL << pin); + uint32_t wr_pin_mask; + uint32_t half_word_select; + if (pin > 15) { + wr_pin_mask = pin_mask >> 16; + half_word_select = PORT_WRCONFIG_HWSEL; + } else { + wr_pin_mask = pin_mask & 0xffff; + half_word_select = 0; + } + // Atomically change the pin config and the pin mux. + group->WRCONFIG.reg = wr_pin_mask | PORT_WRCONFIG_WRPINCFG | + PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_PMUXEN | + PORT_WRCONFIG_PMUX(1) | half_word_select; + // Make sure output is off. + group->DIRCLR.reg = pin_mask; + + sync_config(module_inst); + module_inst->CTRLA.bit.ENABLE = 0; + sync_config(module_inst); + + module_inst->UNK4C04.reg &= 0xF7; // MEMORY[0x42004C04] &= 0xF7u; + module_inst->UNK4C04.reg &= 0xFB; // MEMORY[0x42004C04] &= 0xFBu; + module_inst->UNK4C04.reg &= 0xFC; // MEMORY[0x42004C04] &= 0xFCu; + sync_config(module_inst); + module_inst->FREQCTRL.reg &= 0x9F; // MEMORY[0x42004C0C] &= 0x9Fu; + sync_config(module_inst); + module_inst->FREQCTRL.reg &= 0xEF; // MEMORY[0x42004C0C] &= 0xEFu; + sync_config(module_inst); + module_inst->FREQCTRL.bit.SAMPLEDELAY = 0; // MEMORY[0x42004C0C] &= 0xF0u; + module_inst->CTRLC.bit.INIT = 1; // MEMORY[0x42004C05] |= 1u; + module_inst->CTRLA.bit.RUNINSTANDBY = 1; // MEMORY[0x42004C00] |= 4u; + sync_config(module_inst); + module_inst->INTDISABLE.bit.WCO = 1; + sync_config(module_inst); + module_inst->INTDISABLE.bit.EOC = 1; + sync_config(module_inst); + + // enable the sensor, only done once per line + if (config->yline < 8) { + sync_config(module_inst); + module_inst->YENABLEL.reg |= 1 << config->yline; + sync_config(module_inst); + } else if (config->yline < 16) { + module_inst->YENABLEH.reg |= 1 << (config->yline - 8); + } + + sync_config(module_inst); + module_inst->CTRLA.bit.ENABLE = 1; + sync_config(module_inst); } -void adafruit_ptc_start_conversion(Ptc* module_inst, struct adafruit_ptc_config const* config) { - module_inst->CTRLA.bit.RUNINSTANDBY = 1; - sync_config(module_inst); - module_inst->CTRLA.bit.ENABLE = 1; - sync_config(module_inst); - module_inst->INTDISABLE.bit.WCO = 1; - sync_config(module_inst); - module_inst->INTFLAGS.bit.WCO = 1; - sync_config(module_inst); - module_inst->INTFLAGS.bit.EOC = 1; - sync_config(module_inst); - - // set up pin! - sync_config(module_inst); - if (config->yline < 8) { - module_inst->YSELECTL.reg = 1 << config->yline; - } else { - module_inst->YSELECTL.reg = 0; - } - - if (config->yline > 7) { - module_inst->YSELECTH.reg = 1 << (config->yline - 8); - } else { - module_inst->YSELECTH.reg = 0; - } - - sync_config(module_inst); - // set up sense resistor - module_inst->SERRES.bit.RESISTOR = config->seriesres; - sync_config(module_inst); - // set up prescalar - module_inst->CONVCTRL.bit.ADCACCUM = config->oversample; - sync_config(module_inst); - // set up freq hopping - if (config->freqhop == FREQ_MODE_NONE) { - module_inst->FREQCTRL.bit.FREQSPREADEN = 0; - module_inst->FREQCTRL.bit.SAMPLEDELAY = 0; - } else { - module_inst->FREQCTRL.bit.FREQSPREADEN = 1; - module_inst->FREQCTRL.bit.SAMPLEDELAY = config->hops; - } - // set up compensation cap + int (?) cap - sync_config(module_inst); - module_inst->COMPCAPL.bit.VALUE = config->compcap & 0xFF; - module_inst->COMPCAPH.bit.VALUE = (config->compcap>>8) & 0x3F; - sync_config(module_inst); - module_inst->INTCAP.bit.VALUE = config->intcap & 0x3F; - sync_config(module_inst); - - module_inst->BURSTMODE.reg = 0xA4; - sync_config(module_inst); - - module_inst->CONVCTRL.bit.CONVERT = 1; - sync_config(module_inst); +void adafruit_ptc_start_conversion(Ptc *module_inst, + struct adafruit_ptc_config const *config) { + module_inst->CTRLA.bit.RUNINSTANDBY = 1; + sync_config(module_inst); + module_inst->CTRLA.bit.ENABLE = 1; + sync_config(module_inst); + module_inst->INTDISABLE.bit.WCO = 1; + sync_config(module_inst); + module_inst->INTFLAGS.bit.WCO = 1; + sync_config(module_inst); + module_inst->INTFLAGS.bit.EOC = 1; + sync_config(module_inst); + + // set up pin! + sync_config(module_inst); + if (config->yline < 8) { + module_inst->YSELECTL.reg = 1 << config->yline; + } else { + module_inst->YSELECTL.reg = 0; + } + + if (config->yline > 7) { + module_inst->YSELECTH.reg = 1 << (config->yline - 8); + } else { + module_inst->YSELECTH.reg = 0; + } + + sync_config(module_inst); + // set up sense resistor + module_inst->SERRES.bit.RESISTOR = config->seriesres; + sync_config(module_inst); + // set up prescalar + module_inst->CONVCTRL.bit.ADCACCUM = config->oversample; + sync_config(module_inst); + // set up freq hopping + if (config->freqhop == FREQ_MODE_NONE) { + module_inst->FREQCTRL.bit.FREQSPREADEN = 0; + module_inst->FREQCTRL.bit.SAMPLEDELAY = 0; + } else { + module_inst->FREQCTRL.bit.FREQSPREADEN = 1; + module_inst->FREQCTRL.bit.SAMPLEDELAY = config->hops; + } + // set up compensation cap + int (?) cap + sync_config(module_inst); + module_inst->COMPCAPL.bit.VALUE = config->compcap & 0xFF; + module_inst->COMPCAPH.bit.VALUE = (config->compcap >> 8) & 0x3F; + sync_config(module_inst); + module_inst->INTCAP.bit.VALUE = config->intcap & 0x3F; + sync_config(module_inst); + + module_inst->BURSTMODE.reg = 0xA4; + sync_config(module_inst); + + module_inst->CONVCTRL.bit.CONVERT = 1; + sync_config(module_inst); } -bool adafruit_ptc_is_conversion_finished(Ptc* module_inst) { - return module_inst->CONVCTRL.bit.CONVERT == 0; +bool adafruit_ptc_is_conversion_finished(Ptc *module_inst) { + return module_inst->CONVCTRL.bit.CONVERT == 0; } -uint16_t adafruit_ptc_get_conversion_result(Ptc* module_inst) { - sync_config(module_inst); - return module_inst->RESULT.reg; +uint16_t adafruit_ptc_get_conversion_result(Ptc *module_inst) { + sync_config(module_inst); + return module_inst->RESULT.reg; } diff --git a/adafruit_ptc.h b/adafruit_ptc.h index 1dcefca..6338df2 100644 --- a/adafruit_ptc.h +++ b/adafruit_ptc.h @@ -38,73 +38,71 @@ extern "C" { /* Touch library oversampling (filter) setting */ typedef enum tag_oversample_level_t { - OVERSAMPLE_1, - OVERSAMPLE_2, - OVERSAMPLE_4, - OVERSAMPLE_8, - OVERSAMPLE_16, - OVERSAMPLE_32, - OVERSAMPLE_64 -} -oversample_t; + OVERSAMPLE_1, + OVERSAMPLE_2, + OVERSAMPLE_4, + OVERSAMPLE_8, + OVERSAMPLE_16, + OVERSAMPLE_32, + OVERSAMPLE_64 +} oversample_t; /* Touch library series resistor setting */ typedef enum tag_series_resistor_t { - RESISTOR_0, - RESISTOR_20K, - RESISTOR_50K, - RESISTOR_100K, -} -series_resistor_t; + RESISTOR_0, + RESISTOR_20K, + RESISTOR_50K, + RESISTOR_100K, +} series_resistor_t; typedef enum tag_freq_mode_t { - FREQ_MODE_NONE, - FREQ_MODE_HOP, - FREQ_MODE_SPREAD, - FREQ_MODE_SPREAD_MEDIAN -} -freq_mode_t; + FREQ_MODE_NONE, + FREQ_MODE_HOP, + FREQ_MODE_SPREAD, + FREQ_MODE_SPREAD_MEDIAN +} freq_mode_t; typedef enum tag_freq_hop_t { - FREQ_HOP_1, - FREQ_HOP_2, - FREQ_HOP_3, - FREQ_HOP_4, - FREQ_HOP_5, - FREQ_HOP_6, - FREQ_HOP_7, - FREQ_HOP_8, - FREQ_HOP_9, - FREQ_HOP_10, - FREQ_HOP_11, - FREQ_HOP_12, - FREQ_HOP_13, - FREQ_HOP_14, - FREQ_HOP_15, - FREQ_HOP_16 -} -freq_hop_t; + FREQ_HOP_1, + FREQ_HOP_2, + FREQ_HOP_3, + FREQ_HOP_4, + FREQ_HOP_5, + FREQ_HOP_6, + FREQ_HOP_7, + FREQ_HOP_8, + FREQ_HOP_9, + FREQ_HOP_10, + FREQ_HOP_11, + FREQ_HOP_12, + FREQ_HOP_13, + FREQ_HOP_14, + FREQ_HOP_15, + FREQ_HOP_16 +} freq_hop_t; struct adafruit_ptc_config { - uint8_t pin; // ASF pin # - int8_t yline; // the Y select line (see datasheet) - oversample_t oversample; - series_resistor_t seriesres; - freq_mode_t freqhop; - freq_hop_t hops; - uint16_t compcap; - uint8_t intcap; + uint8_t pin; // ASF pin # + int8_t yline; // the Y select line (see datasheet) + oversample_t oversample; + series_resistor_t seriesres; + freq_mode_t freqhop; + freq_hop_t hops; + uint16_t compcap; + uint8_t intcap; }; void adafruit_ptc_get_config_default(struct adafruit_ptc_config *config); -void adafruit_ptc_init(Ptc* module_inst, struct adafruit_ptc_config const* config); -void adafruit_ptc_start_conversion(Ptc* module_inst, struct adafruit_ptc_config const* config); +void adafruit_ptc_init(Ptc *module_inst, + struct adafruit_ptc_config const *config); +void adafruit_ptc_start_conversion(Ptc *module_inst, + struct adafruit_ptc_config const *config); -bool adafruit_ptc_is_conversion_finished(Ptc* module_inst); -uint16_t adafruit_ptc_get_conversion_result(Ptc* module_inst); +bool adafruit_ptc_is_conversion_finished(Ptc *module_inst); +uint16_t adafruit_ptc_get_conversion_result(Ptc *module_inst); #ifdef __cplusplus } #endif -#endif // ADAFRUIT_FREETOUCH_ADAFRUIT_PTC_H +#endif // ADAFRUIT_FREETOUCH_ADAFRUIT_PTC_H diff --git a/library.properties b/library.properties index 7fe0b85..6f9ad53 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit FreeTouch Library -version=1.0.2 +version=1.1.0 author=Adafruit maintainer=Adafruit sentence=Arduino library for QTouch on samd21 microcontroller diff --git a/samd21_ptc_component.h b/samd21_ptc_component.h index eb7707f..672c191 100644 --- a/samd21_ptc_component.h +++ b/samd21_ptc_component.h @@ -31,17 +31,16 @@ #include "sam.h" /*************** CTRL A register ***************/ -#define PTC_REG_CTRLA 0x42004C00 -#define PTC_BIT_ENABLE 0x02 -#define PTC_BIT_RUNINSTBY 0x04 - +#define PTC_REG_CTRLA 0x42004C00 +#define PTC_BIT_ENABLE 0x02 +#define PTC_BIT_RUNINSTBY 0x04 typedef union { struct { - uint8_t SWRESET:1; - uint8_t ENABLE:1; - uint8_t RUNINSTANDBY:1; - uint8_t __pad0__:5; + uint8_t SWRESET : 1; + uint8_t ENABLE : 1; + uint8_t RUNINSTANDBY : 1; + uint8_t __pad0__ : 5; } bit; uint8_t reg; } PTC_REG_CTRLA_Type; @@ -53,8 +52,8 @@ typedef union { typedef union { struct { - uint8_t __pad0__:7; - uint8_t SYNCFLAG:1; + uint8_t __pad0__ : 7; + uint8_t SYNCFLAG : 1; } bit; uint8_t reg; } PTC_REG_CTRLB_Type; @@ -67,7 +66,6 @@ typedef union { uint8_t reg; } PTC_REG_UNK4C04_Type; - /*************** CTRL C register ***************/ #define PTC_REG_CTRLC 0x42004C05 @@ -75,43 +73,39 @@ typedef union { typedef union { struct { - uint8_t INIT:1; - uint8_t __pad0__:7; + uint8_t INIT : 1; + uint8_t __pad0__ : 7; } bit; uint8_t reg; } PTC_REG_CTRLC_Type; - - /*************** INT registers ***************/ typedef union { struct { - uint8_t EOC:1; - uint8_t WCO:1; - uint8_t __pad0__:6; + uint8_t EOC : 1; + uint8_t WCO : 1; + uint8_t __pad0__ : 6; } bit; uint8_t reg; } PTC_REG_INT_Type; - #define PTC_REG_INTDISABLE 0x42004C08 #define PTC_REG_INTENABLE 0x42004C09 -#define PTC_BIT_EOCINTEN 0x01 -#define PTC_BIT_WCOINTEN 0x02 +#define PTC_BIT_EOCINTEN 0x01 +#define PTC_BIT_WCOINTEN 0x02 #define PTC_REG_INTFLAGS 0x42004C0A #define PTC_BIT_EOCINTFLAG 0x01 #define PTC_BIT_WCOINTFLAG 0x02 - /*************** FREQ CTRL reg ***************/ typedef union { struct { - uint8_t SAMPLEDELAY:4; - uint8_t FREQSPREADEN:1; - uint8_t __pad0__:3; + uint8_t SAMPLEDELAY : 4; + uint8_t FREQSPREADEN : 1; + uint8_t __pad0__ : 3; } bit; uint8_t reg; } PTC_REG_FREQCTRL_Type; @@ -124,48 +118,46 @@ typedef union { typedef union { struct { - uint8_t ADCACCUM:3; - uint8_t __pad0__:4; - uint8_t CONVERT:1; + uint8_t ADCACCUM : 3; + uint8_t __pad0__ : 4; + uint8_t CONVERT : 1; } bit; uint8_t reg; -} __attribute__ ((packed)) PTC_REG_CONVCTRL_Type; - +} __attribute__((packed)) PTC_REG_CONVCTRL_Type; #define PTC_REG_CONVCTRL 0x42004C0D #define PTC_BIT_CONVSTARTED 0x80 #define PTC_REG_ADCACC_MASK 0x07 - /*************** Y SELECT L+H reg ***************/ typedef union { struct { - uint8_t Y0:1; - uint8_t Y1:1; - uint8_t Y2:1; - uint8_t Y3:1; - uint8_t Y4:1; - uint8_t Y5:1; - uint8_t Y6:1; - uint8_t Y7:1; + uint8_t Y0 : 1; + uint8_t Y1 : 1; + uint8_t Y2 : 1; + uint8_t Y3 : 1; + uint8_t Y4 : 1; + uint8_t Y5 : 1; + uint8_t Y6 : 1; + uint8_t Y7 : 1; } bit; uint8_t reg; -} __attribute__ ((packed)) PTC_REG_YSELECTL_Type; +} __attribute__((packed)) PTC_REG_YSELECTL_Type; typedef union { struct { - uint8_t Y8:1; - uint8_t Y9:1; - uint8_t Y10:1; - uint8_t Y11:1; - uint8_t Y12:1; - uint8_t Y13:1; - uint8_t Y14:1; - uint8_t Y15:1; + uint8_t Y8 : 1; + uint8_t Y9 : 1; + uint8_t Y10 : 1; + uint8_t Y11 : 1; + uint8_t Y12 : 1; + uint8_t Y13 : 1; + uint8_t Y14 : 1; + uint8_t Y15 : 1; } bit; uint8_t reg; -} __attribute__ ((packed)) PTC_REG_YSELECTH_Type; +} __attribute__((packed)) PTC_REG_YSELECTH_Type; #define PTC_REG_YSELECT_L 0x42004C10 #define PTC_REG_YSELECT_H 0x42004C11 @@ -173,37 +165,35 @@ typedef union { #define PTC_REG_YENABLE_L 0x42004C14 #define PTC_REG_YENABLE_H 0x42004C15 - /*************** X SELECT L+H reg ***************/ typedef union { struct { - uint8_t X0:1; - uint8_t X1:1; - uint8_t X2:1; - uint8_t X3:1; - uint8_t X4:1; - uint8_t X5:1; - uint8_t X6:1; - uint8_t X7:1; + uint8_t X0 : 1; + uint8_t X1 : 1; + uint8_t X2 : 1; + uint8_t X3 : 1; + uint8_t X4 : 1; + uint8_t X5 : 1; + uint8_t X6 : 1; + uint8_t X7 : 1; } bit; uint8_t reg; -} __attribute__ ((packed)) PTC_REG_XSELECTL_Type; +} __attribute__((packed)) PTC_REG_XSELECTL_Type; typedef union { struct { - uint8_t X8:1; - uint8_t X9:1; - uint8_t X10:1; - uint8_t X11:1; - uint8_t X12:1; - uint8_t X13:1; - uint8_t X14:1; - uint8_t X15:1; + uint8_t X8 : 1; + uint8_t X9 : 1; + uint8_t X10 : 1; + uint8_t X11 : 1; + uint8_t X12 : 1; + uint8_t X13 : 1; + uint8_t X14 : 1; + uint8_t X15 : 1; } bit; uint8_t reg; -} __attribute__ ((packed)) PTC_REG_XSELECTH_Type; - +} __attribute__((packed)) PTC_REG_XSELECTH_Type; #define PTC_REG_XSELECT_L 0x42004C12 #define PTC_REG_XSELECT_H 0x42004C13 @@ -215,56 +205,55 @@ typedef union { typedef union { struct { - uint8_t VALUE:8; + uint8_t VALUE : 8; } bit; uint8_t reg; -} __attribute__ ((packed)) PTC_REG_COMPCAPL_Type; +} __attribute__((packed)) PTC_REG_COMPCAPL_Type; typedef union { struct { - uint8_t VALUE:6; - uint8_t __pad0__:2; + uint8_t VALUE : 6; + uint8_t __pad0__ : 2; } bit; uint8_t reg; -} __attribute__ ((packed)) PTC_REG_COMPCAPH_Type; +} __attribute__((packed)) PTC_REG_COMPCAPH_Type; -#define PTC_REG_COMPCAPL 0x42004C18 -#define PTC_REG_COMPCAPH 0x42004C19 +#define PTC_REG_COMPCAPL 0x42004C18 +#define PTC_REG_COMPCAPH 0x42004C19 /*************** Int Cap reg ***************/ typedef union { struct { - uint8_t VALUE:6; - uint8_t __pad0__:2; + uint8_t VALUE : 6; + uint8_t __pad0__ : 2; } bit; uint8_t reg; -} __attribute__ ((packed)) PTC_REG_INTCAP_Type; - +} __attribute__((packed)) PTC_REG_INTCAP_Type; -#define PTC_REG_INTCAP 0x42004C1A +#define PTC_REG_INTCAP 0x42004C1A /*************** Series resistor reg ***************/ typedef union { struct { - uint8_t RESISTOR:2; - uint8_t __pad0__:6; + uint8_t RESISTOR : 2; + uint8_t __pad0__ : 6; } bit; uint8_t reg; -} __attribute__ ((packed)) PTC_REG_SERRES_Type; +} __attribute__((packed)) PTC_REG_SERRES_Type; -#define PTC_REG_SERIESRES 0x42004C1B +#define PTC_REG_SERIESRES 0x42004C1B /*************** conversion result reg ***************/ typedef union { struct { - uint8_t LOWBYTE; - uint8_t HIGHBYTE; + uint8_t LOWBYTE; + uint8_t HIGHBYTE; } byte; uint16_t reg; -} __attribute__ ((packed)) PTC_REG_CONVRESULT_Type; +} __attribute__((packed)) PTC_REG_CONVRESULT_Type; #define PTC_REG_CONVRESULT_L 0x42004C1C #define PTC_REG_CONVRESULT_H 0x42004C1D @@ -273,26 +262,25 @@ typedef union { typedef union { struct { - uint8_t __pad0__:2; - uint8_t CTSLOWPOWER:1; - uint8_t __pad1__:1; - uint8_t BURSTMODE:4; + uint8_t __pad0__ : 2; + uint8_t CTSLOWPOWER : 1; + uint8_t __pad1__ : 1; + uint8_t BURSTMODE : 4; } bit; uint8_t reg; -} __attribute__ ((packed)) PTC_REG_BURSTMODE_Type; - +} __attribute__((packed)) PTC_REG_BURSTMODE_Type; -#define PTC_REG_BURSTMODE 0x42004C20 -#define PTC_REG_BURSTMODE_MASK 0xF0 -#define PTC_BIT_CTSLOWPOWER 0x04 +#define PTC_REG_BURSTMODE 0x42004C20 +#define PTC_REG_BURSTMODE_MASK 0xF0 +#define PTC_BIT_CTSLOWPOWER 0x04 /*************** etc unused reg ***************/ -#define PTC_REG_XYENABLE 0x42004C16 -#define PTC_BIT_XYENABLE 0x02 +#define PTC_REG_XYENABLE 0x42004C16 +#define PTC_BIT_XYENABLE 0x02 -#define PTC_REG_WCO_MODE 0x42004C21 -#define PTC_REG_WCO_MODE_MASK 0x07 +#define PTC_REG_WCO_MODE 0x42004C21 +#define PTC_REG_WCO_MODE_MASK 0x07 #define PTC_SET_WCO_THRESHHOLD_A_L 0x42004C24 #define PTC_SET_WCO_THRESHHOLD_A_H 0x42004C25 @@ -300,51 +288,51 @@ typedef union { #define PTC_SET_WCO_THRESHHOLD_B_H 0x42004C27 typedef struct { - __IO PTC_REG_CTRLA_Type CTRLA; // 0x42004C00 - __IO PTC_REG_CTRLB_Type CTRLB; // 0x42004C01 - uint8_t __pad4c02__; // 0x42004C02 unknown - uint8_t __pad4c03__; // 0x42004C03 unknown - __IO PTC_REG_UNK4C04_Type UNK4C04; // 0x42004C04 unknown - __IO PTC_REG_CTRLC_Type CTRLC; // 0x42004C05 - uint8_t __pad4c06__; // 0x42004C06 unknown - uint8_t __pad4c07__; // 0x42004C07 unknown - __IO PTC_REG_INT_Type INTDISABLE; // 0x42004C08 - __IO PTC_REG_INT_Type INTENABLE; // 0x42004C09 - __IO PTC_REG_INT_Type INTFLAGS; // 0x42004C0A - uint8_t __pad4c0b__; // 0x42004C0B unknown - __IO PTC_REG_FREQCTRL_Type FREQCTRL; //0x42004C0C - __IO PTC_REG_CONVCTRL_Type CONVCTRL; // 0x42004C0D - uint8_t __pad4c0e__; // 0x42004C0E unknown - uint8_t __pad4c0f__; // 0x42004C0F unknown - __IO PTC_REG_YSELECTL_Type YSELECTL; // 0x42004C10 - __IO PTC_REG_YSELECTL_Type YSELECTH; // 0x42004C11 - __IO PTC_REG_XSELECTL_Type XSELECTL; // 0x42004C12 - __IO PTC_REG_XSELECTL_Type XSELECTH; // 0x42004C13 - __IO PTC_REG_YSELECTL_Type YENABLEL; // 0x42004C14 - __IO PTC_REG_YSELECTL_Type YENABLEH; // 0x42004C15 - __IO PTC_REG_XSELECTL_Type XENABLEL; // 0x42004C16 - __IO PTC_REG_XSELECTL_Type XENABLEH; // 0x42004C17 - - __IO PTC_REG_COMPCAPL_Type COMPCAPL; // 0x42004C18 - __IO PTC_REG_COMPCAPH_Type COMPCAPH; // 0x42004C19 - __IO PTC_REG_INTCAP_Type INTCAP; // 0x42004C1A - __IO PTC_REG_SERRES_Type SERRES; // 0x42004C1B - - __IO PTC_REG_CONVRESULT_Type RESULT; // 0x42004C1C + 0x42004C1D - uint8_t __pad4c1e__; // 0x42004C1E unknown - uint8_t __pad4c1f__; // 0x42004C1F unknown + __IO PTC_REG_CTRLA_Type CTRLA; // 0x42004C00 + __IO PTC_REG_CTRLB_Type CTRLB; // 0x42004C01 + uint8_t __pad4c02__; // 0x42004C02 unknown + uint8_t __pad4c03__; // 0x42004C03 unknown + __IO PTC_REG_UNK4C04_Type UNK4C04; // 0x42004C04 unknown + __IO PTC_REG_CTRLC_Type CTRLC; // 0x42004C05 + uint8_t __pad4c06__; // 0x42004C06 unknown + uint8_t __pad4c07__; // 0x42004C07 unknown + __IO PTC_REG_INT_Type INTDISABLE; // 0x42004C08 + __IO PTC_REG_INT_Type INTENABLE; // 0x42004C09 + __IO PTC_REG_INT_Type INTFLAGS; // 0x42004C0A + uint8_t __pad4c0b__; // 0x42004C0B unknown + __IO PTC_REG_FREQCTRL_Type FREQCTRL; // 0x42004C0C + __IO PTC_REG_CONVCTRL_Type CONVCTRL; // 0x42004C0D + uint8_t __pad4c0e__; // 0x42004C0E unknown + uint8_t __pad4c0f__; // 0x42004C0F unknown + __IO PTC_REG_YSELECTL_Type YSELECTL; // 0x42004C10 + __IO PTC_REG_YSELECTL_Type YSELECTH; // 0x42004C11 + __IO PTC_REG_XSELECTL_Type XSELECTL; // 0x42004C12 + __IO PTC_REG_XSELECTL_Type XSELECTH; // 0x42004C13 + __IO PTC_REG_YSELECTL_Type YENABLEL; // 0x42004C14 + __IO PTC_REG_YSELECTL_Type YENABLEH; // 0x42004C15 + __IO PTC_REG_XSELECTL_Type XENABLEL; // 0x42004C16 + __IO PTC_REG_XSELECTL_Type XENABLEH; // 0x42004C17 + + __IO PTC_REG_COMPCAPL_Type COMPCAPL; // 0x42004C18 + __IO PTC_REG_COMPCAPH_Type COMPCAPH; // 0x42004C19 + __IO PTC_REG_INTCAP_Type INTCAP; // 0x42004C1A + __IO PTC_REG_SERRES_Type SERRES; // 0x42004C1B + + __IO PTC_REG_CONVRESULT_Type RESULT; // 0x42004C1C + 0x42004C1D + uint8_t __pad4c1e__; // 0x42004C1E unknown + uint8_t __pad4c1f__; // 0x42004C1F unknown __IO PTC_REG_BURSTMODE_Type BURSTMODE; // 0x42004C20 } Ptc; #ifndef PTC -#define PTC (( Ptc *)0x42004C00U) +#define PTC ((Ptc *)0x42004C00U) #endif #define PTC_REG_INTDISABLE 0x42004C08 #define PTC_REG_INTENABLE 0x42004C09 -#define PTC_BIT_EOCINTEN 0x01 -#define PTC_BIT_WCOINTEN 0x02 +#define PTC_BIT_EOCINTEN 0x01 +#define PTC_BIT_WCOINTEN 0x02 #define PTC_REG_INTFLAGS 0x42004C0A -#endif // ADAFRUIT_FREETOUCH_PTC_COMPONENT_H +#endif // ADAFRUIT_FREETOUCH_PTC_COMPONENT_H