Analog Comparatos AC Atmel Sam D21 - Bare Code - Page 1
Forum section: electronics / general

author: Franc
author_rank: Regular Contributor
timestamp: October 15, 2016, 12:01:07 am
content: Hi All!!As I did not found any topic AC in Atmel SAM devices, I decided to open this topic.I started to configure my Driver for AC of Atmel Sam D21 in Bare Code.I think important to set the Hysteresis for cut any noise.In page 907 of DS, topic 34.6.7 I found the register HYSTEN to set the Hysteresis and the HYST to configure the Hysteresis level as below:''Hysteresis is enabled for each comparator individually by the Hysteresis Enable bit in the Comparator xControl register (COMPCTRLx.HYSTEN). Furthermore, when enabled, the level of hysteresis isprogrammable through the Hysteresis Level bits also in the Comparator x Control register(COMPCTRLx.HYST). Hysteresis is available only in continuous mode (COMPCTRLx.SINGLE=0).''When I checked the register in AS7 and DS page 911, I did not find any register called HYSTEN and the unique option is set the Hysteresis by HYST bit.Anybody used the AC of Sam D21 before? How I can configure the Hysteresis level?I am in doubt for this case.Best Regards!

author: ataradov
author_rank: Super Contributor
timestamp: October 15, 2016, 12:52:37 am
content: There is COMPCTRLn.HYST that enables and disables hysteresis. I don't think there is a way to actually configure it. If I'm not mistaken, actual hysteresis is about 50-70 mV.

author: ataradov
author_rank: Super Contributor
timestamp: October 15, 2016, 12:55:52 am
content: Also, most recent version of the DS has this text:QuoteAnd nothing about the level.And the DS from 2014 did not have any of this at all

author: Franc
author_rank: Regular Contributor
timestamp: October 15, 2016, 01:10:08 pm
content: Thanks Alex. I am using the REV 02/2014 but I did download some weeks ago through google.. I will search any other recent version.Now I found the info and the Hystereris is typically 50mV in fast mode.Regards!

author: Franc
author_rank: Regular Contributor
timestamp: October 15, 2016, 04:45:59 pm
content: The topic 34.6.14 in 909 page also is wrong, the RUNSTDBY is in CTRLA register (latest DS).Again, I am suffering with I/O ports.When I debugging my AC Drive I am getting this error belowCode:C:\Users\Paulo\Desktop\Controle de Carga\Source\board_defs.h(64,24): error: 'A' undeclared (first use in this function)#define COM_0_OUT A, 18 // EXT2-pin16 SERCOM1-PAD2 SPI MOSI^C:\Program Files\Atmel\Studio\7.0\Packs\atmel\SAMD21_DFP\1.0.231\samd21a\include\component\ac.h(496,62): info: in definition of macro 'AC_COMPCTRL_OUT'#define AC_COMPCTRL_OUT(value) (AC_COMPCTRL_OUT_Msk & ((value) << AC_COMPCTRL_OUT_Pos))^C:\Users\Paulo\Desktop\Controle de Carga\Source\AC_Deteccao\AC_Deteccao.c(41,42): info: in expansion of macro 'COM_0_OUT'| AC_COMPCTRL_OUT(COM_0_OUT);^C:\Users\Paulo\Desktop\Controle de Carga\Source\board_defs.h(64,24): info: each undeclared identifier is reported only once for each function it appears in#define COM_0_OUT A, 18 // EXT2-pin16 SERCOM1-PAD2 SPI MOSI^C:\Program Files\Atmel\Studio\7.0\Packs\atmel\SAMD21_DFP\1.0.231\samd21a\include\component\ac.h(496,62): info: in definition of macro 'AC_COMPCTRL_OUT'#define AC_COMPCTRL_OUT(value) (AC_COMPCTRL_OUT_Msk & ((value) << AC_COMPCTRL_OUT_Pos))^C:\Users\Paulo\Desktop\Controle de Carga\Source\AC_Deteccao\AC_Deteccao.c(41,42): info: in expansion of macro 'COM_0_OUT'| AC_COMPCTRL_OUT(COM_0_OUT);^C:\Users\Paulo\Desktop\Controle de Carga\Source\board_defs.h(64,25): warning: left-hand operand of comma expression has no effect [-Wunused-value]#define COM_0_OUT A, 18 // EXT2-pin16 SERCOM1-PAD2 SPI MOSI^C:\Program Files\Atmel\Studio\7.0\Packs\atmel\SAMD21_DFP\1.0.231\samd21a\include\component\ac.h(496,62): info: in definition of macro 'AC_COMPCTRL_OUT'#define AC_COMPCTRL_OUT(value) (AC_COMPCTRL_OUT_Msk & ((value) << AC_COMPCTRL_OUT_Pos))^C:\Users\Paulo\Desktop\Controle de Carga\Source\AC_Deteccao\AC_Deteccao.c(41,42): info: in expansion of macro 'COM_0_OUT'| AC_COMPCTRL_OUT(COM_0_OUT);^C:\Users\Paulo\Desktop\Controle de Carga\Source\board_defs.h(66,25): warning: left-hand operand of comma expression has no effect [-Wunused-value]#define COM_1_OUT A, 19 // EXT2-pin18 SERCOM1-PAD3 SPI SCK^C:\Program Files\Atmel\Studio\7.0\Packs\atmel\SAMD21_DFP\1.0.231\samd21a\include\component\ac.h(496,62): info: in definition of macro 'AC_COMPCTRL_OUT'#define AC_COMPCTRL_OUT(value) (AC_COMPCTRL_OUT_Msk & ((value) << AC_COMPCTRL_OUT_Pos))^C:\Users\Paulo\Desktop\Controle de Carga\Source\AC_Deteccao\AC_Deteccao.c(43,42): info: in expansion of macro 'COM_1_OUT'| AC_COMPCTRL_OUT(COM_1_OUT);^make: *** [Source/AC_Deteccao/AC_Deteccao.o] Error 1make: *** Waiting for unfinished jobs....In the 'AC_COMPCTRL_OUT(COM_1_OUT)' what is the correct sintax to declare?ThisCOM_1_OUTI did declare as '#define COM_1_OUT A, 18'Also myac_init()starts as below:Code:GPIO_dirOut(COM_0_OUT);GPIO_pmuxen(COM_0_OUT, AC_COM0_PMUX);GPIO_dirOut(COM_1_OUT);GPIO_pmuxen(COM_1_OUT, AC_COM1_PMUX);Best Regards!

author: ataradov
author_rank: Super Contributor
timestamp: October 15, 2016, 04:53:58 pm
content: The datasheet clearly says that AC_COMPCTRL_OUT can be one of: OFF, ASYNC, SYNC. If you look in the header file, then you will find definitions like AC_COMPCTRL_OUT_OFF, AC_COMPCTRL_OUT_ASYNC and AC_COMPCTRL_OUT_SYNC.This is not a declaration of the actual output. This is declaration of how AC component connected to the PORT component.Then in the port component you need to configure PMUX setting to further let this signal out of the device.

author: Franc
author_rank: Regular Contributor
timestamp: October 15, 2016, 07:03:33 pm
content: yes Alex, I was looking only the AC.h of AS7 'AC_COMPCTRL_OUT(value)'My Driver is not working, I think my error is in I/O ports. I think my OUTPUTs are okay but my INPUTS are wrong.The PMUX I am using is the 'H', but I do not understand how to habilit my PB00 and PB01 to ACs positive inputs.Code:#include "samd21.h"#include "board_defs.h"void ac_init(void){GPIO_dirOut(COM_0_OUT);GPIO_pmuxen(COM_0_OUT, AC_COM0_PMUX);GPIO_dirOut(COM_1_OUT);GPIO_pmuxen(COM_1_OUT, AC_COM1_PMUX);GPIO_dirIn(COM_0_IN);GPIO_set(COM_0_IN);GPIO_dirIn(COM_1_IN);GPIO_set(COM_1_IN);PM->APBCMASK.reg |= PM_APBCMASK_AC;GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID (AC_GCLK_ID_DIG) |// AC share same GCLK 48MhzGCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN (AC_GCLK_SOURCE);while (0==(GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN));AC->CTRLA.reg = AC_CTRLA_SWRST; //Reset AC registerAC->CTRLA.reg = AC_CTRLA_RUNSTDBY(1); // AC remain active in Sleep mode.// COMPx - Positive Pin, and Negative VDDscale source, Hysteresys Control, High SpeedAC->COMPCTRL.reg = AC_COMPCTRL_MUXPOS_PIN0 | AC_COMPCTRL_MUXNEG_VSCALE | AC_COMPCTRL_HYST | AC_COMPCTRL_SPEED_HIGH| AC_COMPCTRL_OUT_SYNC;AC->COMPCTRL.reg = AC_COMPCTRL_MUXPOS_PIN2 | AC_COMPCTRL_MUXNEG_VSCALE | AC_COMPCTRL_HYST | AC_COMPCTRL_SPEED_HIGH| AC_COMPCTRL_OUT_SYNC;AC->SCALER.reg = AC_SCALER_VALUE(49); //Negative reference in 2.5V for 3.2VanaAC->SCALER.reg = AC_SCALER_VALUE(49);AC->CTRLA.reg = AC_CTRLA_ENABLE;}Thanks again!

author: ataradov
author_rank: Super Contributor
timestamp: October 15, 2016, 07:10:16 pm
content: Can you describe what you are trying to do? Take what pins and compare them to what?Comparator works with analog inputs, so you need to configure corresponding PMUXes for the inputs.None (almost) of the internal peripherals connect directly to the pins. If you are using a pin for anything other than GPIO, you always need to expect to set a PMUX to instruct PORT component to pass the signal along.

author: Franc
author_rank: Regular Contributor
timestamp: October 15, 2016, 07:28:23 pm
content: Alex, I will supply a sinusoidal signal of 6Vpp to PB00 and PB01 (just an experience). PB00 is the Positive input for COMP0 and PB01 is the Positive to COMP1 . Both analog pins.The negative input for both comparators will be the Vscaler with 2.5V (49) .The output for COMP0 will be PA18 and for COMP1 PA19. Both mentioned as CMPx in DS with Mux H.In DS, I have few explanations to do the bridge to Positive COMP. I found the 'AC_COMPCTRL_MUXPOS_PIN2' but superficial.Regards!!

author: ataradov
author_rank: Super Contributor
timestamp: October 15, 2016, 07:32:35 pm
content: Quote from: Franc on October 15, 2016, 07:28:23 pmBut there are no AC inputs on those pins. AC can take external inputs only from PA04, PA05, PA06 and PA07 (Table 7-1. PORT Function Multiplexing).

author: Franc
author_rank: Regular Contributor
timestamp: October 15, 2016, 07:46:17 pm
content: I will try....I checked only the page 23, there are PB00 and PB01 as analog pins.Now I understand. AIN[] of ADCs are used to COMP also. Atmel mixed the COMPs with GCLK in the 7.1 table and I saw only the Outputs in H mux.

author: ataradov
author_rank: Super Contributor
timestamp: October 15, 2016, 07:52:23 pm
content: Quote from: Franc on October 15, 2016, 07:46:17 pmThey are analog in a sense that they are powered from analog power domain, because they are connected to ADC.Quote from: Franc on October 15, 2016, 07:46:17 pmComparator outputs and GCLK outputs are on the same MUX setting, there is no other way to show that.There is a separate column for MUX B with analog inputs.In general, you should start from I/O description of the peripheral. In case of AC, they are listed in the section 34.4 "Signal Description". The table clearly lists that peripheral takes inputs AIN[3..0] and outputs are CMP[1..0]. After that you go to the Table 7-1 and check on what pins those things are available (can be MUXed).

author: Franc
author_rank: Regular Contributor
timestamp: October 15, 2016, 09:24:21 pm
content: Now, I changed the I/O direct in register as below but no success.. (no HALGPIO)My Input is PA04 for positive COMP0 and PA18 as CMP0Code:void ac_init(void){PORT->Group.PINCFG.reg = 1;PORT->Group.PMUX.bit.PMUXE = AC_COM0_PMUX_IN; //Mux B for input, PA04 as AINPORT->Group.DIRSET.reg=18;PORT->Group.PINCFG.reg = 1;PORT->Group.PMUX.bit.PMUXE = AC_COM0_PMUX_OUT;//mux H for output, PA18 as CMPPM->APBCMASK.reg |= PM_APBCMASK_AC;GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID (AC_GCLK_ID_DIG) |// AC share same GCLK 48MhzGCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN (AC_GCLK_SOURCE);while (0==(GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN));AC->CTRLA.reg = AC_CTRLA_SWRST; //Reset AC registerAC->CTRLA.reg = AC_CTRLA_RUNSTDBY(1); // AC remain active in Sleep mode.// COMPx - Positive Pin, and Negative VDDscale source, Hysteresys Control, High SpeedAC->COMPCTRL.reg = AC_COMPCTRL_MUXPOS_PIN0 | AC_COMPCTRL_MUXNEG_VSCALE | AC_COMPCTRL_HYST | AC_COMPCTRL_SPEED_HIGH| AC_COMPCTRL_OUT_SYNC;AC->COMPCTRL.reg = AC_COMPCTRL_MUXPOS_PIN2 | AC_COMPCTRL_MUXNEG_VSCALE | AC_COMPCTRL_HYST | AC_COMPCTRL_SPEED_HIGH| AC_COMPCTRL_OUT_SYNC;AC->SCALER.reg = AC_SCALER_VALUE(49); //Negative reference in 2.5V for 3.2VanaAC->SCALER.reg = AC_SCALER_VALUE(49);AC->CTRLA.reg = AC_CTRLA_ENABLE;}

author: ataradov
author_rank: Super Contributor
timestamp: October 15, 2016, 09:28:44 pm
content: Quote from: Franc on October 15, 2016, 09:24:21 pmI'm not going to read code full of magic numbers. I don't know what bit 1 in PINCFG means, and I'm not even going to look it up. Rewrite the code so it is actually readable and then you may even find your problem yourself.

author: ataradov
author_rank: Super Contributor
timestamp: October 15, 2016, 09:30:27 pm
content: Also, you did not enable clock to the analog part of the AC.Here is the code from a working project:Code:HAL_GPIO_PIN(AC1, A, 5);{HAL_GPIO_AC1_in();HAL_GPIO_AC1_pmuxen(PORT_PMUX_PMUXE_B_Val);PM->APBCMASK.reg |= PM_APBCMASK_AC;GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(AC_GCLK_ID_ANA) |GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(AC_GCLK_ID_DIG) |GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);AC->COMPCTRL.reg = AC_COMPCTRL_ENABLE |AC_COMPCTRL_SPEED(AC_COMPCTRL_SPEED_HIGH_Val) |AC_COMPCTRL_INTSEL(AC_COMPCTRL_INTSEL_RISING_Val) |AC_COMPCTRL_HYST |AC_COMPCTRL_MUXNEG(AC_COMPCTRL_MUXNEG_VSCALE_Val) |AC_COMPCTRL_MUXPOS(AC_COMPCTRL_MUXPOS_PIN1_Val) |AC_COMPCTRL_OUT(AC_COMPCTRL_OUT_ASYNC_Val);while (AC->STATUSB.bit.SYNCBUSY);HAL_GPIO_CMP0_out();HAL_GPIO_CMP0_pmuxen(PORT_PMUX_PMUXE_H_Val);AC->SCALER.reg = 4;while (AC->STATUSB.bit.SYNCBUSY);AC->CTRLA.reg |= AC_CTRLA_ENABLE;while (AC->STATUSB.bit.SYNCBUSY);}

author: Franc
author_rank: Regular Contributor
timestamp: October 17, 2016, 09:45:34 pm
content: Dear Alex, how are you. My code below worked perfect. My outputs are PA12 and PA13 .THanks!!I want to start with interrupts but I have doubts. Once I have two ACs, I found only one NVIC_EnableIRQ(AC_IRQn) in samd21j18a.h.Also in DS I found in page 48 a descryption about NVIC but superficial.How I can call a interrupt from AC0 and other for AC1? For example, I want to increase a variable in an external function for AC0 and decrease a variable in another function with AC1.**obs. This is the first time I am using NVIC. If you has any web link to learn about them, I will be greaful.Best Regards!Code:void ac_init(void){GPIO_dirIn(COM_0_IN);GPIO_pmuxen(COM_0_IN, PF_MUX_B);GPIO_dirIn(COM_1_IN);GPIO_pmuxen(COM_1_IN, PF_MUX_B);PM->APBCMASK.reg |= PM_APBCMASK_AC;GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID (AC_GCLK_ID_DIG) |// AC share same GCLK 48MhzGCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN (AC_GCLK_SOURCE);while (0==(GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN));GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(AC_GCLK_ID_ANA) | // Habilita o clock analogico para os AC.GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(AC_GCLK_SOURCE);AC->CTRLA.reg = AC_CTRLA_SWRST; //Reset AC registerAC->CTRLA.reg = AC_CTRLA_RUNSTDBY(1); // AC remain active in Sleep mode.// COMPx - Positive Pin, and Negative VDDscale source, Hysteresys Control, High Speed, Interruption RisingAC->COMPCTRL.reg = AC_COMPCTRL_ENABLE | AC_COMPCTRL_MUXPOS_PIN0 | AC_COMPCTRL_MUXNEG_VSCALE| AC_COMPCTRL_HYST | AC_COMPCTRL_INTSEL_RISING | AC_COMPCTRL_SPEED_HIGH | AC_COMPCTRL_OUT_SYNC | AC_COMPCTRL_FLEN_MAJ3;while (AC->STATUSB.bit.SYNCBUSY);AC->COMPCTRL.reg = AC_COMPCTRL_ENABLE | AC_COMPCTRL_MUXPOS_PIN2 | AC_COMPCTRL_MUXNEG_VSCALE| AC_COMPCTRL_HYST | AC_COMPCTRL_INTSEL_RISING | AC_COMPCTRL_SPEED_HIGH | AC_COMPCTRL_OUT_SYNC | AC_COMPCTRL_FLEN_MAJ3;while (AC->STATUSB.bit.SYNCBUSY);GPIO_dirOut(COM_0_OUT);GPIO_pmuxen(COM_0_OUT, PF_MUX_H); //mux H for output, PA12 as CMPGPIO_dirOut(COM_1_OUT);GPIO_pmuxen(COM_1_OUT, PF_MUX_H); //mux H for output, PA13 as CMPAC->SCALER.reg = AC_SCALER_VALUE(49); //Negative reference in 2.5V for 3.2Vanawhile (AC->STATUSB.bit.SYNCBUSY); //Aguarda sincronizaçãoAC->SCALER.reg = AC_SCALER_VALUE(49);while (AC->STATUSB.bit.SYNCBUSY);AC->CTRLA.reg = AC_CTRLA_ENABLE; //Habilita os comparadoreswhile (AC->STATUSB.bit.SYNCBUSY);}

author: ataradov
author_rank: Super Contributor
timestamp: October 17, 2016, 09:51:11 pm
content: Quote from: Franc on October 17, 2016, 09:45:34 pmYou can only have one handler. In that handler you can look up what flag has triggered this interrupt and act accordingly.This is the same as for any other peripheral. All interrupt source are combined into a single interrupt request and a single interrupt handler is called.Quote from: Franc on October 17, 2016, 09:45:34 pmWell, there is plenty of documentation, depending on what level of detail you are looking for.If you are just starting, then you can just use my sample code, it has example of using NVIC for timers. It basically boils down to enabling proper interrupt sources in the peripheral, and calling NVIC_EnableIRQ().

author: Franc
author_rank: Regular Contributor
timestamp: October 18, 2016, 10:49:27 pm
content: Hi Alex, my code below worked perfectly as you said. I increase and decrease a variable in my OLED display injecting a sinusoidal signal of 2Hz..In this moment I cannot test it in High frequency but do you think possible I run NVIC for 64Khz? In the past, I tried to toggle a LED using the NVIC from TC and did not work for 64Khz. (obs. I was using ASF)Best Regards!Code:void AC_Handler(void){if (AC->INTFLAG.reg & AC_INTFLAG_COMP0){spi_potenciometro_write(pot_count--);AC->INTFLAG.reg = AC_INTFLAG_COMP0;}if (AC->INTFLAG.reg & AC_INTFLAG_COMP1){spi_potenciometro_write(pot_count++);AC->INTFLAG.reg = AC_INTFLAG_COMP1;}}

author: ataradov
author_rank: Super Contributor
timestamp: October 18, 2016, 10:58:07 pm
content: Quote from: Franc on October 18, 2016, 10:49:27 pmDo you mean is it possible to have interrupts at 64 kHz rate?If so, then it is a very bad idea. Lets do some math. Assume that we are running at 48 MHz, and we are running from SRAM (not flash), so we have 0 wait states, and further assume that each instruction takes only 1 cycle to execute. All of those assumptions are very optimistic, as you can see.Now you will have 48000000 / 64000 = 750 clock cycles between the interrupts. It takes 15 clock cycles to enter and leave the interrupt routine, so you have 720 clock cycles for both ISR code and the main code. And those are very ideal cycles. In real life, be happy if you get half of that.So it is possible, but you really-really need to know what you are doing, and probably code in assembly at this point.

author: Franc
author_rank: Regular Contributor
timestamp: October 18, 2016, 11:24:57 pm
content: What a pity :/ ...there is no other way to read the CMPx state in my code for HF? I don't know Assembly language.I tested the CMPx direct to I/O ports PA12 and PA13 in 64Khz and worked, but I know the NVIC unstable.I would like to read 8 signals in 64Khz, stop 125microSeconds....read 8 signals 64khz and stop 125micSeconds...and so on.regards!

author: ataradov
author_rank: Super Contributor
timestamp: October 18, 2016, 11:30:50 pm
content: Quote from: Franc on October 18, 2016, 11:24:57 pmI don't really understand what exactly you want to achieve. You need to provide more details.Quote from: Franc on October 18, 2016, 11:24:57 pmDo you mean you have MUXed comparator outputs directly to pins? In that case, I'm pretty sure they will for up to a few MHz, it is just a hardware comparator, no software is involved here.Quote from: Franc on October 18, 2016, 11:24:57 pmNVIC is perfectly stable.Quote from: Franc on October 18, 2016, 11:24:57 pmAgain, I'm not following. What 8 signals?You can probably just run that code in your main while (1) loop, you will save some cycles entering and exiting the interrupt.Also, what do you want to do with those "signals"?

author: Franc
author_rank: Regular Contributor
timestamp: October 19, 2016, 12:03:24 am
content: QuoteThere is another way to read the Comparatos outs in my firmware? Is the NVIC the unique way?QuoteYes, I just muxed them.QuoteI will read a inductive sensor. This inductive sensor sends 8 cycles at 64Khz and stop 125microS. This routine is made continuously.Just the signals returned above of 2.5V (from sensor) will be acceptable. My code will need count how many signals were read per routine of 8 cycles.Once I got the result, I can act accordialy.

author: ataradov
author_rank: Super Contributor
timestamp: October 19, 2016, 12:17:06 am
content: Quote from: Franc on October 19, 2016, 12:03:24 amJust disable the interrupt and do exactly the same thing in the main application.Quote from: Franc on October 19, 2016, 12:03:24 amDo you have some documentation for this sensor?I don't really see the problem with handling something like this using interrupts. You will obviously have to be very careful with your coding to meet timing demands. Like all that spi_potenciometro_write() will obviously have to go away.

author: Franc
author_rank: Regular Contributor
timestamp: October 19, 2016, 09:08:45 pm
content: Hi Alex...The act of my software will be true, if the sensor returned 4+ readings above 2.5V per routine of 8 cycles, that is, each routine will be valid only if I have 4+ readings.So, I think possible treat it in my AC Driver and only return the NVIC in this condition. What do you think? Could I use a conditional 'if' to treat how many ACouts the INTFlag is returning by routine, then return NVIC if the conditional is okay.Regards!Code:Do you have some documentation for this sensor?Sorry, I don't have because I produced it. It is very simple and I can send a picture to you.

author: ataradov
author_rank: Super Contributor
timestamp: October 19, 2016, 09:13:21 pm
content: Quote from: Franc on October 19, 2016, 09:08:45 pmI don'y understand this explanation. There obviously needs to be some timer involved here as well to know when to start counting.Quote from: Franc on October 19, 2016, 09:08:45 pmCan you at least explain what is the significance of 2.5 V? Is it actually an analog signal or digital?

author: zat
author_rank: Newbie
timestamp: January 12, 2018, 03:43:52 am
content: Can anyone give a minimum working project for AC settings bare metal (Atmel Studio 7)?Tried a lot of options, nothing works. There may be a problem in initializing system timers,I can not figure it out .. As soon as the signal is supplied to the comparator,everything hangs. Clock speed 48 MHzPlease help.

author: ataradov
author_rank: Super Contributor
timestamp: January 12, 2018, 03:49:11 am
content: Quote from: zat on January 12, 2018, 03:43:52 amHangs how exactly?My best guess is you had enabled interrupts, but have not actually declared an interrupt handler.I can provide an example, but only tomorrow.But the cod from my earlier post is 100% working.

author: zat
author_rank: Newbie
timestamp: January 12, 2018, 05:08:33 am
content: Thanks,ataradov.3 days I try to start the comparator and it does not work.The interrogation mode is continuous, I try to apply a voltage of 3.3 V to pin PA04(for the test).In interrupting (by raising), I increase the counter by 1,and in the main cycle I light the LED for 200 ms.Does not work.

author: ataradov
author_rank: Super Contributor
timestamp: January 12, 2018, 05:11:35 am
content: Can you post your code you have so far?

author: zat
author_rank: Newbie
timestamp: January 12, 2018, 05:30:38 am
content: Code://----------------------------------------void AC_Init(void) {PORT->Group.PMUX[4/2].reg |= PORT_PMUX_PMUXE_B ;PORT->Group.PINCFG.reg |= PORT_PINCFG_PMUXEN | PORT_PINCFG_INEN ;/*Only for test */PORT->Group.PMUX[12/2].reg |= PORT_PMUX_PMUXE_H ;PORT->Group.PINCFG.reg |= PORT_PINCFG_PMUXEN ;REG_AC_CTRLA = AC_CTRLA_SWRST ;while( REG_AC_STATUSA & AC_CTRLA_SWRST) ;REG_PM_APBCMASK |= PM_APBCMASK_AC ;REG_GCLK_CLKCTRL = (GCLK_CLKCTRL_ID_AC_DIG |GCLK_CLKCTRL_GEN_GCLK0 |//48 MHzGCLK_CLKCTRL_CLKEN);while( REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY) ;REG_GCLK_CLKCTRL = (GCLK_CLKCTRL_ID_AC_ANA |GCLK_CLKCTRL_GEN_GCLK0 | //48 MGz or need max 64 kHz ?GCLK_CLKCTRL_CLKEN);while( REG_GCLK_STATUS & GCLK_STATUS_SYNCBUSY) ;REG_AC_CTRLA = (AC_CTRLA_RUNSTDBY(1));REG_AC_COMPCTRL0 |= ((0 << AC_COMPCTRL_SINGLE_Pos) |AC_COMPCTRL_HYST |AC_COMPCTRL_SPEED_HIGH |AC_COMPCTRL_INTSEL_RISING |AC_COMPCTRL_MUXNEG_VSCALE |AC_COMPCTRL_MUXPOS_PIN0 |//AC_COMPCTRL_OUT_SYNC |AC_COMPCTRL_OUT_OFF |AC_COMPCTRL_FLEN(AC_COMPCTRL_FLEN_OFF_Val) |AC_COMPCTRL_ENABLE);while( REG_AC_STATUSB & AC_STATUSB_SYNCBUSY) ;REG_AC_SCALER0 = AC_SCALER_VALUE(32); //~1,6 Vwhile( REG_AC_STATUSB & AC_STATUSB_SYNCBUSY) ;REG_AC_INTENSET = AC_INTENSET_COMP0 ;NVIC_EnableIRQ(AC_IRQn);REG_AC_CTRLA |= AC_CTRLA_ENABLE;while (REG_AC_STATUSB & AC_STATUSB_SYNCBUSY);}//------------------------------------------------------void AC_Handler (void){ac_pulse_count +=1 ;}//---------------------------------------------------int main(void){__disable_irq();SetupMainClock_48M();AC_Init();__enable_irq();while (1){if (ac_pulse_count != 0) {REG_PORT_OUTCLR1 = LED0 ; //on_delay_ms(200);REG_PORT_OUTSET1 = LED0 ; //offac_pulse_count = 0;}} // end while} // end main

author: ataradov
author_rank: Super Contributor
timestamp: January 12, 2018, 05:41:46 am
content: You don't loop in the main(), what do you expect to happen?EDIT: Well, now you do.

author: ataradov
author_rank: Super Contributor
timestamp: January 12, 2018, 05:53:15 am
content: I don't see anything obviously wrong with the code. I'll make a complete demo project tomorrow.

author: ataradov
author_rank: Super Contributor
timestamp: January 12, 2018, 09:20:09 pm
content: Here is a complete project.Your original code does not clear the interrupt flag, so it is constantly called. There may be something else wrong as well, I have not checked.Also make sure to declare ac_pulse_count volatile.

author: zat
author_rank: Newbie
timestamp: January 13, 2018, 01:30:22 am
content: Quote from: ataradov on January 12, 2018, 09:20:09 pmThanks again, Alex.Thanks to the provided project, I was able to find the problem.Indeed, it's all about resetting the interrupt flag.But why is it necessary for the comparator to do this?I have SPI and UART, and there are no such problems.They also use the interrupt, but it is not necessary to reset the flag.Code:void AC_Handler (void){REG_AC_INTFLAG = AC_INTFLAG_COMP0;ac_pulse_count +=1 ;}QuoteYes, it's present.Code:/* AC */uint16_t volatile ac_pulse_count = 0 ;

author: ataradov
author_rank: Super Contributor
timestamp: January 13, 2018, 01:40:08 am
content: Quote from: zat on January 13, 2018, 01:30:22 amIt is necessary for all peripherals to know when you have actually handled the interrupt.Quote from: zat on January 13, 2018, 01:30:22 amIt is necessary, but there flags are reset by reading the data from the DATA register. If you exit from UART RX interrupt without reading the DATA register, you will get exact same result.The exact way flags are cleared depends on the peripheral and described in the datasheet.Also, a bit of debugging helps with finding bugs like this. Debuggers are extremely cheap nowadays.

author: zat
author_rank: Newbie
timestamp: January 13, 2018, 02:45:39 am
content: I checked with debugger , I saw that the interrupt was working. But for 3 days of comparing different results, I probably just did not pay attention. Most likely this has already affected from fatigue.Sometimes need to rest