diff --git a/ChangeLog.md b/ChangeLog.md index 96c6c9e8..819158cb 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,5 @@ # Changelog -This page documents (nearly) all bugfixes and enhancements that produce visible changes in behavior throughout the history of megaTinyCore. Note that this document is maintained by a human, who is - by nature - imperfect (this is also why there are so many bugs to fix); sometimes the changelog may not be updated at the same time as the changes go in, and occasionally a change is missed entirely in the changelog, though this is rare. Change descriptions may be incomplete or unclear; this is not meant to be an indepth reference. +This page documents (nearly) all bugfixes and enhancements that produce visible changes in behavior throughout the history of DxCore. Note that this document is maintained by a human, who is - by nature - imperfect (this is also why there are so many bugs to fix); sometimes the changelog may not be updated at the same time as the changes go in, and occasionally a change is missed entirely in the changelog, though this is rare. Change descriptions may be incomplete or unclear; this is not meant to be an indepth reference. ## Planned changes not yet implemented These items are in addition to what was listed under changes already in release. @@ -10,12 +10,13 @@ These items are in addition to what was listed under changes already in release. * Bugfix: Make serialupdi work with EA. * Enhancement: Implement sleep library * Re-add SPI attach and detach. -* Ensure libraries in sync with DxCore. +* Ensure libraries in sync with megaTinyCore. ## Planned changes implemented in github These are typically planned for release in a future version (usually the next one) as noted. * Update - was not gods of C, it was a gang of rogue peripherals. After being held captive and tortured by WEX Luther and his cronies, core developer has escaped said malicious preipherals. While held captive, my computer and equipment were sabotaged by their henchmen. Particular care in restraining WEX Luther to be taken to ensure that end users do not face such attacks. * Add support for not-yet-announced S class DA-series parts, which are identical but for having the new EB-series lockdown thingie. There are no changes needed. +* Support for the PTC peripheral on DA parts ### 1.5.11 (Emergency fix) * At some point in the recent past, I must have angered the gods of C, and suddenly millis disabled stopped working - the system would hang (actually, with in-depth investigation, it was shown to be bootlooping - before it called init(), it was calling 0x0000 (a dirty reset) instead of eliding a weakly defined function with nothing in the body except a return, or with an empty body. Why was it doing this? And why only when millis was disabled?). millis disabled is a key piece of core functionality, necessitating an urgent fix. Moving the definitions into main.cpp resolved this issue. (#485) diff --git a/megaavr/libraries/PTC/README.md b/megaavr/libraries/PTC/README.md index 060a3e96..7d065338 100644 --- a/megaavr/libraries/PTC/README.md +++ b/megaavr/libraries/PTC/README.md @@ -122,13 +122,15 @@ Different pins have a different parasitic capacitance. I suspect this is depends ### Tuning of nodes In order to ease the use of the PTC module, the ptc_add_* functions will initialize the cap_sensor_t struct with some default values, like the CC value mentioned above. That values can be easily changed and will be applied the next time a conversion of said node starts. Here is a list: -- Analog Gain. Increases the sensitivity of the electrode by adjusting a capacitor on a integrator (I think) (1x Gain) -- Digital Gain. Defines the amount of ADC Oversampling. Will not affect the count value, as it is internally right-shifted. (16x Oversampled) -- Charge Share Delay. Affects the Sample length of the ADC. (0 extra clocks) -- Prescaler. It is possible to slow down the ADC clock by adjusting the Prescaler. (Depends on CPU clock, targeted: 1MHz +/- 25%) -- Serial Resistor. Allows to change the serial resistor between the Cc and the node. Fixed at 100k for Self-Cap. Creates RC-low-pass filter. - -If a node is not sensitive enough, you can increase the Analog Gain (if it becomes too sensitive, an increase of the thresholds might be needed). However it is better to have a bigger node to begin with because the bigger the area, the higher is the capacitance delta. +- `uint8_t ptc_node_set_gain(cap_sensor_t *node, ptc_gain_t gain)`. Increases the sensitivity of the electrode by adjusting a capacitor on the integrator (I think). Valid values are: `PTC_GAIN_1, PTC_GAIN_2, PTC_GAIN_4, PTC_GAIN_8, PTC_GAIN_16, PTC_GAIN_32 (Tiny only)`. Default: 1x Gain. +- `uint8_t ptc_node_set_oversamples(cap_sensor_t *node, uint8_t ovs)`. Defines the amount of ADC Oversampling. Will not affect the count value, as it is internally right-shifted. Valid values are in the range from 0 to 6 resulting in 1x, 2x, 4x, 8x, 16x, 32x, 64x oversampling. Defaults to 16x. +- `uint8_t ptc_node_set_charge_share_delay(cap_sensor_t *node, uint8_t csd)`. Affects the Sample length of the ADC. This does pretty much the same thing as ADC.SAMPCTRL register. Valid range is from 0 to 31. Defaults to 0 extra clocks +- `uint8_t ptc_node_set_prescaler(cap_sensor_t *node, ptc_presc_t presc)`. It is possible to slow down the ADC/PTC clock by adjusting the Prescaler. The ADC/PTC Clock should be between 1 and 2 MHz. The library calculates the default based on F_CPU. +Valid values for Tiny are: `PTC_PRESC_DIV2_gc, PTC_PRESC_DIV4_gc, PTC_PRESC_DIV8_gc, PTC_PRESC_DIV16_gc, PTC_PRESC_DIV32_gc, PTC_PRESC_DIV64_gc, PTC_PRESC_DIV128_gc, PTC_PRESC_DIV256_gc` +Valid values for DA are: `PTC_PRESC_DIV2_gc, PTC_PRESC_DIV4_gc, PTC_PRESC_DIV6_gc, PTC_PRESC_DIV8_gc, PTC_PRESC_DIV10_gc, PTC_PRESC_DIV12_gc, PTC_PRESC_DIV14_gc, PTC_PRESC_DIV16_gc` +- `uint8_t ptc_node_set_resistor(cap_sensor_t *node, ptc_rsel_t res)`. Allows to change the serial resistor between the Cc and the node. Fixed at 100k for Self-Cap. Defaults to 50k for Mutual-Cap. Valid Values are: `RSEL_VAL_0, RSEL_VAL_20, RSEL_VAL_50, RSEL_VAL_70, RSEL_VAL_80 (DA only), RSEL_VAL_100, RSEL_VAL_120 (DA only), RSEL_VAL_200`. + +If a node is not sensitive enough, you can increase the Analog Gain (if it becomes too sensitive, an increase of the thresholds might be needed). However it is better to have a bigger electrode to begin with because the bigger the area, the higher is the capacitance delta. ### Global settings of the State-machine The state-machine, which changes the node's state between Calibration, touch, no touch, etc. uses some variables that are valid for all nodes, those are: diff --git a/megaavr/libraries/PTC/examples/self_and_mutual_mix/self_and_mutual_mix.ino b/megaavr/libraries/PTC/examples/self_and_mutual_mix/self_and_mutual_mix.ino index 4250c6b4..42d94a12 100644 --- a/megaavr/libraries/PTC/examples/self_and_mutual_mix/self_and_mutual_mix.ino +++ b/megaavr/libraries/PTC/examples/self_and_mutual_mix/self_and_mutual_mix.ino @@ -1,8 +1,8 @@ #include /* * This example creates four different sensing nodes. of two different types. - * PA4 and PA5 are the self-cap lines with PB0 acting as shield pin. - * PA6 and PA7 are the Y-Lines with PB1 acting as the X-line. + * PA4 and PA5 are the self-cap lines with PA0 acting as shield pin. + * PA6 and PA7 are the Y-Lines with PA1 acting as the X-line. * PTC_CB_EVENT_CONV_MUTUAL_CMPL and * PTC_CB_EVENT_CONV_SHIELD_CMPL can be used to change the type that is converted. * This will create an interlaced conversion, but it is not mandatory to do so. @@ -16,11 +16,11 @@ cap_sensor_t nodes[4]; void setup() { // put your setup code here, to run once: - ptc_add_selfcap_node(&nodes[0], PIN_TO_PTC(PIN_PB0), PIN_TO_PTC(PIN_PA4)); - ptc_add_selfcap_node(&nodes[1], PIN_TO_PTC(PIN_PB0), PIN_TO_PTC(PIN_PA5)); + ptc_add_selfcap_node(&nodes[0], PIN_TO_PTC(PIN_PA0), PIN_TO_PTC(PIN_PA4)); + ptc_add_selfcap_node(&nodes[1], PIN_TO_PTC(PIN_PA0), PIN_TO_PTC(PIN_PA5)); - ptc_add_mutualcap_node(&nodes[2], PIN_TO_PTC(PIN_PB1), PIN_TO_PTC(PIN_PA6)); - ptc_add_mutualcap_node(&nodes[3], PIN_TO_PTC(PIN_PB1), PIN_TO_PTC(PIN_PA7)); + ptc_add_mutualcap_node(&nodes[2], PIN_TO_PTC(PIN_PA1), PIN_TO_PTC(PIN_PA6)); + ptc_add_mutualcap_node(&nodes[3], PIN_TO_PTC(PIN_PA1), PIN_TO_PTC(PIN_PA7)); MySerial.begin(115200); MySerial.println("Hello World!"); diff --git a/megaavr/libraries/PTC/src/ptc.c b/megaavr/libraries/PTC/src/ptc.c index f401605d..dc3c1a29 100644 --- a/megaavr/libraries/PTC/src/ptc.c +++ b/megaavr/libraries/PTC/src/ptc.c @@ -29,10 +29,7 @@ void ptc_process_measurement(cap_sensor_t *node); // Handles (initial) calibration uint8_t ptc_process_calibrate(cap_sensor_t *node); -// Handles adjustment of the reference value when a button is not pressed -void ptc_process_adjust(); -void ptc_set_registers(cap_sensor_t *node); cap_sensor_t *firstNode = NULL; @@ -73,19 +70,11 @@ ptc_lib_sm_set_t *ptc_get_sm_settings() { #if defined (__PTC_Tiny__) #define PTC_DEFAULT_SC_CC 0x0567 #define PTC_DEFAULT_MC_CC 0x0234 - -const uint8_t ptc_a_gain_lut[] = { - 0x3F, 0x1C, 0x0B, - 0x05, 0x03, 0x01, -}; +#define PTC_GAIN_BASE 0x003F #elif defined (__PTC_DA__) #define PTC_DEFAULT_SC_CC 0x00F0 #define PTC_DEFAULT_MC_CC 0x00A0 - -const uint8_t ptc_a_gain_lut[] = { - 0x1F, 0x0F, 0x07, - 0x03, 0x01 -}; +#define PTC_GAIN_BASE 0x001F #endif @@ -113,23 +102,28 @@ uint8_t ptc_node_set_thresholds(cap_sensor_t *node, int16_t th_in, int16_t th_ou if (NULL == node) { return PTC_LIB_BAD_POINTER; } - node->touch_in_th = th_in; - node->touch_out_th = th_out; + if (th_in != 0) { + node->touch_in_th = th_in; + } + if (th_out != 0) { + node->touch_out_th = th_out; + } return PTC_LIB_SUCCESS; } // Change Resistor Setting. Note: Only has an effect on mutual sensors -uint8_t ptc_node_set_resistor(cap_sensor_t *node, uint8_t res) { +uint8_t ptc_node_set_resistor(cap_sensor_t *node, ptc_rsel_t res) { PTC_CHECK_FOR_BAD_POINTER(node); if (res > RSEL_MAX) { return PTC_LIB_BAD_ARGUMENT; } - + res &= 0x0F; + res <<= 0x04; if (node->type & NODE_MUTUAL_bm) { uint8_t presc = node->hw_rsel_presc & 0x0F; - presc |= ((res & 0x0F) << 4); + presc |= res; node->hw_rsel_presc = presc; return PTC_LIB_SUCCESS; } @@ -139,50 +133,62 @@ uint8_t ptc_node_set_resistor(cap_sensor_t *node, uint8_t res) { // Change prescaler. Recommended ADC frequency: < 1.5MHz, but max 3 factors below -uint8_t ptc_node_set_prescaler(cap_sensor_t *node, uint8_t presc) { +uint8_t ptc_node_set_prescaler(cap_sensor_t *node, ptc_presc_t presc) { PTC_CHECK_FOR_BAD_POINTER(node); if ((presc > (PTC_PRESC_DEFAULT + 2)) || (presc < PTC_PRESC_DEFAULT)) { return PTC_LIB_BAD_ARGUMENT; } - + presc &= 0x0F; uint8_t res = node->hw_rsel_presc & 0xF0; - res |= (presc & 0x0F); + res |= presc; node->hw_rsel_presc = res; return PTC_LIB_SUCCESS; } -uint8_t ptc_node_set_gain(cap_sensor_t *node, uint8_t aGain, uint8_t dGain) { +uint8_t ptc_node_set_gain(cap_sensor_t *node, ptc_gain_t gain) { PTC_CHECK_FOR_BAD_POINTER(node); - #if defined (__PTC_Tiny__) - if (aGain > 0x05) { - if (__builtin_constant_p(aGain)) { - badArg("Analog Gain too high. Max Analog Gain Value is 0x05 (equals 32x)"); + if (gain >= PTC_GAIN_MAX) { + if (__builtin_constant_p(gain)) { + badArg("Analog Gain too high. Max Analog Gain Value is 0x3F (Tiny) / 0x1F (DA)"); } return PTC_LIB_BAD_ARGUMENT; } - #elif defined (__PTC_DA__) - if (aGain > 0x04) { - if (__builtin_constant_p(aGain)) { - badArg("Analog Gain too high. Max Analog Gain Value is 0x04 (equals 16x)"); - } - return PTC_LIB_BAD_ARGUMENT; - } - #endif + gain = PTC_GAIN_MAX - gain; + gain <<= 4; + uint8_t ovs = node->hw_gain_ovs & 0x0F; + node->hw_gain_ovs = gain | ovs; + return PTC_LIB_SUCCESS; +} + +uint8_t ptc_node_set_oversamples(cap_sensor_t *node, uint8_t ovs) { + PTC_CHECK_FOR_BAD_POINTER(node); - if (dGain > 0x06) { - if (__builtin_constant_p(dGain)) { + if (ovs > 0x06) { + if (__builtin_constant_p(ovs)) { badArg("Digital Gain too high. Max Digital Gain Value is 0x06 (equals 64x)"); } return PTC_LIB_BAD_ARGUMENT; } - node->hw_a_d_gain = NODE_GAIN(aGain, dGain); + uint8_t gain = node->hw_gain_ovs & 0xF0; + node->hw_gain_ovs = gain | ovs; return PTC_LIB_SUCCESS; } +uint8_t ptc_node_set_charge_share_delay(cap_sensor_t *node, uint8_t csd) { + PTC_CHECK_FOR_BAD_POINTER(node); + if (ovs > 15) { + if (__builtin_constant_p(ovs)) { + badArg("Charge Share Delay too high, maximum value is 15"); + } + return PTC_LIB_BAD_ARGUMENT; + } + node->hw_csd = hw_csd; + return PTC_LIB_SUCCESS; +} /* * Two functions to suspend and resume of the normal PTC operation, however, @@ -291,7 +297,7 @@ uint8_t ptc_add_node(cap_sensor_t *node, uint8_t *pCh, const uint8_t type) { } #endif - node->hw_a_d_gain = NODE_GAIN(0, ADC_SAMPNUM_ACC16_gc); + node->hw_gain_ovs = NODE_GAIN(0, ADC_SAMPNUM_ACC16_gc); if (type & NODE_MUTUAL_bm) { node->touch_in_th = 10; @@ -878,7 +884,7 @@ void ptc_init_conversion(uint8_t nodeType) { if (NULL != lowPowerNode) { pPTC->INTCTRL = ADC_WCMP_bm; // Wakeup only above of window pPTC->CTRLE = ADC_WINCM_ABOVE_gc; - pPTC->WINHT = (lowPowerNode->reference + lowPowerNode->touch_in_th) << (lowPowerNode->hw_a_d_gain & 0x0F); + pPTC->WINHT = (lowPowerNode->reference + lowPowerNode->touch_in_th) << (lowPowerNode->hw_gain_ovs & 0x0F); ptc_lib_state = PTC_LIB_EVENT; ptc_start_conversion(lowPowerNode); } else { @@ -924,7 +930,7 @@ void ptc_init_conversion(uint8_t nodeType) { if (NULL != lowPowerNode) { pPTC->INTCTRL = ADC_WCMP_bm; // Wakeup only above of window pPTC->CTRLE = ADC_WINCM_ABOVE_gc; - pPTC->WINHT = (lowPowerNode->reference + lowPowerNode->touch_in_th) << (lowPowerNode->hw_a_d_gain & 0x0F); + pPTC->WINHT = (lowPowerNode->reference + lowPowerNode->touch_in_th) << (lowPowerNode->hw_gain_ovs & 0x0F); ptc_lib_state = PTC_LIB_EVENT; ptc_start_conversion(lowPowerNode); } else { @@ -951,25 +957,15 @@ void ptc_start_conversion(cap_sensor_t *node) { } currConvNode = node; - - ptc_set_registers(node); -} - -void ptc_set_registers(cap_sensor_t *node) { + PTC_t *pPTC; - _fastPtr_d(node, node); // Sometimes it takes the compiler a bit more of convincing... _fastPtr_d(pPTC, &PTC); - - if (NULL == node) { - return; + _fastPtr_d(node, node); + uint8_t analogGain = PTC_GAIN_MAX; + if (node->stateMachine != PTC_SM_NOINIT_CAL) { + analogGain = node->hw_gain_ovs / 16; // A little workaround as >> 4 is kinda broken sometimes. } - uint8_t lut_index = 0; - if ((node->state.disabled == 0) && (node->stateMachine != PTC_SM_NOINIT_CAL)) { - lut_index = node->hw_a_d_gain / 16; // A little workaround as >> 4 is kinda broken sometimes. - } - uint8_t analogGain = ptc_a_gain_lut[lut_index]; - uint8_t chargeDelay = node->hw_csd; #if defined(__PTC_Tiny__) @@ -988,10 +984,23 @@ void ptc_set_registers(cap_sensor_t *node) { pPTC->CTRLP |= 0x03; #elif defined(__PTC_DA__) - memcpy((void *)pPTC->XBM, node->hw_xCh_bm, sizeof(ptc_ch_arr_t)); - memcpy((void *)pPTC->YBM, node->hw_yCh_bm, sizeof(ptc_ch_arr_t)); + ((uint8_t*)&pPTC->XBM)[0] = node->hw_xCh_bm[0]; // avoid memcpy to reduce register pressure + ((uint8_t*)&pPTC->XBM)[1] = node->hw_xCh_bm[1]; // avoiding memcpy means we can put &PTC + ((uint8_t*)&pPTC->XBM)[2] = node->hw_xCh_bm[2]; // and node in the Z/Y-Registers and just use + ((uint8_t*)&pPTC->XBM)[3] = node->hw_xCh_bm[3]; // the fast and memory efficient std/ldd instructions + ((uint8_t*)&pPTC->XBM)[4] = node->hw_xCh_bm[4]; + + ((uint8_t*)&pPTC->YBM)[0] = node->hw_yCh_bm[0]; + ((uint8_t*)&pPTC->YBM)[1] = node->hw_yCh_bm[1]; + ((uint8_t*)&pPTC->YBM)[2] = node->hw_yCh_bm[2]; + ((uint8_t*)&pPTC->YBM)[3] = node->hw_yCh_bm[3]; + ((uint8_t*)&pPTC->YBM)[4] = node->hw_yCh_bm[4]; + #if __PTC_Pincount__ >= 40 + ((uint8_t*)&pPTC->XBM)[5] = node->hw_xCh_bm[5]; + ((uint8_t*)&pPTC->YBM)[5] = node->hw_yCh_bm[5]; + #endif - if (chargeDelay < 0x7B) { + if (chargeDelay < 0x1B) { chargeDelay += 4; } else { chargeDelay = 0x1F; @@ -1014,7 +1023,7 @@ void ptc_set_registers(cap_sensor_t *node) { pPTC->COMP = node->hw_compCaps; pPTC->AGAIN = analogGain; - pPTC->CTRLB = node->hw_a_d_gain & 0x0F; + pPTC->CTRLB = node->hw_gain_ovs & 0x0F; pPTC->RSEL = node->hw_rsel_presc / 16; pPTC->CTRLA = ADC_RUNSTBY_bm | ADC_ENABLE_bm; /* 0x81 */ @@ -1076,7 +1085,7 @@ void ptc_eoc(void) { pPTC->CTRLA = 0x00; uint8_t flags = pPTC->INTFLAGS; // save the flags before they get cleared by RES read uint16_t rawVal = pPTC->RES; // clears ISR flags - uint8_t oversampling = pCurrentNode->hw_a_d_gain & 0x0F; + uint8_t oversampling = pCurrentNode->hw_gain_ovs & 0x0F; pCurrentNode->sensorData = rawVal >> oversampling; //currConvNode->sensorData = pPTC->RES_TRUE; diff --git a/megaavr/libraries/PTC/src/ptc.h b/megaavr/libraries/PTC/src/ptc.h index ff789012..3854be43 100644 --- a/megaavr/libraries/PTC/src/ptc.h +++ b/megaavr/libraries/PTC/src/ptc.h @@ -97,17 +97,25 @@ void ptc_set_next_conversion_type(ptc_node_type_t type); void ptc_process(uint16_t currTime); -// Set the threshold for touch detection and away from touch for a node +// Set the threshold for touch detection and away from touch for a node. +// a "0" will be interpreted as don't change uint8_t ptc_node_set_thresholds(cap_sensor_t *node, int16_t th_in, int16_t th_out); // Change Resistor Setting. Note: Only has an effect on mutual sensors -uint8_t ptc_node_set_resistor(cap_sensor_t *node, uint8_t res); +uint8_t ptc_node_set_resistor(cap_sensor_t *node, ptc_rsel_t res); // Change prescaler. -uint8_t ptc_node_set_prescaler(cap_sensor_t *node, uint8_t presc); +uint8_t ptc_node_set_prescaler(cap_sensor_t *node, ptc_presc_t presc); -uint8_t ptc_node_set_gain(cap_sensor_t *node, uint8_t aGain, uint8_t dGain); +// Sets the gain through adjusting the charge integrator (increases the sensitivity (and noise)) +uint8_t ptc_node_set_gain(cap_sensor_t *node, ptc_gain_t gain); + +// Sets the number of oversamples. (the value is right-shifted automatically (reduces noise)) +uint8_t ptc_node_set_oversamples(cap_sensor_t *node, uint8_t ovs); + +// Sets the number of additional PTC Clocks for sampling a node. See also: ADC.SAMPCTRL +uint8_t ptc_node_set_charge_share_delay(cap_sensor_t *node, uint8_t csd); // this is an internal function, there is no sense in calling it directly uint8_t ptc_add_node(cap_sensor_t *node, uint8_t *pCh, const uint8_t type); diff --git a/megaavr/libraries/PTC/src/ptc_io.h b/megaavr/libraries/PTC/src/ptc_io.h index 981c1e1b..854a7f5d 100644 --- a/megaavr/libraries/PTC/src/ptc_io.h +++ b/megaavr/libraries/PTC/src/ptc_io.h @@ -56,13 +56,13 @@ typedef struct PTC_struct { #define PRSC_MAX ADC_PRESC_DIV256_gc #if F_CPU >= 12000000 // 16 MHz / 16 = 1.0 MHz, 20 MHz / 16 = 1.25 MHz -#define PTC_PRESC_DEFAULT ADC_PRESC_DIV16_gc +#define PTC_PRESC_DEFAULT PTC_PRESC_DIV16_gc #elif F_CPU >= 6000000 // 8 MHz / 8 = 1.0 MHz, 10 MHz / 8 = 1.25 MHz -#define PTC_PRESC_DEFAULT ADC_PRESC_DIV8_gc +#define PTC_PRESC_DEFAULT PTC_PRESC_DIV8_gc #elif F_CPU >= 3000000 // 4 MHz / 4 = 1.0 MHz, 5 MHz / 4 = 1.25 MHz -#define PTC_PRESC_DEFAULT ADC_PRESC_DIV4_gc +#define PTC_PRESC_DEFAULT PTC_PRESC_DIV4_gc #else // 1 MHz / 2 = 500 kHz - the lowest setting -#define PTC_PRESC_DEFAULT ADC_PRESC_DIV2_gc +#define PTC_PRESC_DEFAULT PTC_PRESC_DIV2_gc #endif #elif defined (__PTC_DA__) diff --git a/megaavr/libraries/PTC/src/ptc_types.h b/megaavr/libraries/PTC/src/ptc_types.h index 2d6369aa..b5832ab3 100644 --- a/megaavr/libraries/PTC/src/ptc_types.h +++ b/megaavr/libraries/PTC/src/ptc_types.h @@ -90,8 +90,8 @@ typedef enum PTC_PRESC_enum { PTC_PRESC_DIV32_gc = (0x04 << 0), /* CLK_PER divided by 32 */ PTC_PRESC_DIV64_gc = (0x05 << 0), /* CLK_PER divided by 64 */ PTC_PRESC_DIV128_gc = (0x06 << 0), /* CLK_PER divided by 128 */ - PTC_PRESC_DIV256_gc = (0x07 << 0) /* CLK_PER divided by 256 */ -} PTC_PRESC_t; + PTC_PRESC_DIV256_gc = (0x07 << 0), /* CLK_PER divided by 256 */ +} ptc_presc_t; typedef enum PTC_RSEL_enum { RSEL_VAL_0, @@ -100,7 +100,18 @@ typedef enum PTC_RSEL_enum { RSEL_VAL_70, RSEL_VAL_100, RSEL_VAL_200 -} PTC_RSEL_t; +} ptc_rsel_t; + +typedef enum ptc_gain_enum { + PTC_GAIN_1 = 0x00, + PTC_GAIN_2 = 0x23, + PTC_GAIN_4 = 0x34, + PTC_GAIN_8 = 0x3A, + PTC_GAIN_16 = 0x3C, + PTC_GAIN_32 = 0x3E, + PTC_GAIN_MAX = 0x3F, +} ptc_gain_t; + #elif defined (__PTC_DA__) typedef enum PTC_PRESC_enum { PTC_PRESC_DIV2_gc = (0x00 << 0), /* CLK_PER divided by 2 */ @@ -111,7 +122,7 @@ typedef enum PTC_PRESC_enum { PTC_PRESC_DIV12_gc = (0x05 << 0), /* CLK_PER divided by 8 */ PTC_PRESC_DIV14_gc = (0x06 << 0), /* CLK_PER divided by 8 */ PTC_PRESC_DIV16_gc = (0x07 << 0), /* CLK_PER divided by 16 */ -} PTC_PRESC_t; +} ptc_presc_t; typedef enum tag_rsel_val_t { RSEL_VAL_0, @@ -122,7 +133,16 @@ typedef enum tag_rsel_val_t { RSEL_VAL_100, RSEL_VAL_120, RSEL_VAL_200 -} PTC_RSEL_t; +} ptc_rsel_t; + +typedef enum ptc_gain_enum { + PTC_GAIN_1 = 0x00, + PTC_GAIN_2 = 0x10, + PTC_GAIN_4 = 0x18, + PTC_GAIN_8 = 0x1C, + PTC_GAIN_16 = 0x1E, + PTC_GAIN_MAX = 0x1F, +} ptc_gain_t; #endif typedef struct ptc_node_state_type { @@ -220,7 +240,7 @@ typedef struct cap_sensor_type { ptc_ch_arr_t hw_yCh_bm; // do not separate them or change order. uint16_t hw_compCaps; // [13:12] rough; [11:8] course; [7:4] fine; [3:0] accurate (on Tinies only) uint8_t hw_rsel_presc; // [7:4] RSEL, [3:0] PRESC - uint8_t hw_a_d_gain; // [7:4] Analog Gain, [3:0] Digital Gain /* PTC_AGAIN / CTRLB.SAMPNUM */ + uint8_t hw_gain_ovs; // [7:4] Analog Gain, [3:0] Oversampling /* PTC_AGAIN / CTRLB.SAMPNUM */ uint8_t hw_csd; // [4:0] Charge Share Delay /* SAMPLEN in SAMPCTRL */ ptc_node_state_t state;