#include #include #include #include #include #include #include "yaMBSiavr.h" #define AVRG 1024 uint16_t adc_values[AVRG]; void init_clk(void) { // ========= System Clock configuration ========= // Set to external 16Mhz crystal, using the PLL at *2 // set it to be a 12-16Mhz crystal with a slow start-up time. OSC.XOSCCTRL = OSC_FRQRANGE_2TO9_gc | OSC_XOSCSEL_XTAL_16KCLK_gc ; OSC.CTRL |= OSC_XOSCEN_bm ; // enable it while( (OSC.STATUS & OSC_XOSCRDY_bm) == 0 ){} // wait until it's stable // The external crystal is now running and stable. // (Note that it's not yet selected as the clock source) // Now configure the PLL to be eXternal oscillator * 2 OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | 2; // now enable the PLL... OSC.CTRL |= OSC_PLLEN_bm ; // enable the PLL... while( (OSC.STATUS & OSC_PLLRDY_bm) == 0 ){} // wait until it's stable // And now, *finally*, we can switch from the internal 2Mhz clock to the PLL CCP = CCP_IOREG_gc; // protected write follows CLK.CTRL = CLK_SCLKSEL_PLL_gc; // The System clock is now PLL (16Mhz * 2) // ============================================== } void init_timer_100us(){ TCC0.CTRLA |= TC_CLKSEL_DIV256_gc; TCC0.PER = 13; // ==> 9615Hz TCC0.INTCTRLA |= TC_OVFINTLVL_MED_gc; } void adc_init(void){ ADCA.CTRLB = ADC_FREERUN_bm; ADCA.REFCTRL = ADC_REFSEL_VCC_gc; ADCA.PRESCALER = ADC_PRESCALER_DIV512_gc; uint8_t CalibrationByteL; uint8_t CalibrationByteH; NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc; CalibrationByteL = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0)); CalibrationByteH = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1)); NVM_CMD = NVM_CMD_NO_OPERATION_gc; ADCA.CALL = CalibrationByteL; ADCA.CALH = CalibrationByteH; ADCA.CTRLA = ADC_ENABLE_bm; ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc; } uint16_t adc_read(void){ ADCA.CH0.CTRL |= ADC_CH_START_bm; while(!(ADCA.CH0.INTFLAGS & ADC_CH_CHIF_bm)); ADCA.CH0.INTFLAGS = ADC_CH_CHIF_bm; return ADCA.CH0.RES; } float avrg(uint16_t * values, uint16_t length){ uint64_t res = 0; for(uint16_t i=0; i < length; i++){ res += values[i]; } return (float)(res)/length; } void dma_init(void){ DMA.CTRL = DMA_ENABLE_bm; //DMA.CH0.CTRLB = DMA_CH_TRNINTLVL_LO_gc; DMA.CH0.TRFCNT = AVRG * 2; DMA.CH0.CTRLA = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_SINGLE_bm; DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH0_gc; //repeat endless DMA.CH0.CTRLA |= DMA_CH_REPEAT_bm; DMA.CH0.REPCNT = 0; DMA.CH0.SRCADDR0 = ((uintptr_t)&ADCA.CH0.RES) & 0xFF; DMA.CH0.SRCADDR1 = (((uintptr_t)&ADCA.CH0.RES) >> 0x08) & 0xFF; DMA.CH0.SRCADDR2 = (((uintptr_t)&ADCA.CH0.RES) >> 0x0F) & 0xFF; DMA.CH0.DESTADDR0 = ((uintptr_t)adc_values) & 0xFF; DMA.CH0.DESTADDR1 = ((uintptr_t)adc_values >> 0x08) & 0xFF; DMA.CH0.DESTADDR2 = ((uintptr_t)adc_values >> 0x0F) & 0xFF; DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_DESTRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc; DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; } void modbusGet(void) { if (modbusGetBusState() & (1<