|  |  | @ -6,9 +6,11 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <stddef.h> |  |  |  | #include <stddef.h> | 
			
		
	
		
		
			
				
					
					|  |  |  | #include "yaMBSiavr.h" |  |  |  | #include "yaMBSiavr.h" | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #define AVRG 1024 |  |  |  | #define AVRG 512 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | volatile uint16_t adc_buffer[AVRG]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | volatile float ch_values[9]; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | uint16_t adc_values[AVRG]; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void init_clk(void) |  |  |  | void init_clk(void) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
	
		
		
			
				
					|  |  | @ -37,7 +39,7 @@ void init_clk(void) | 
			
		
	
		
		
			
				
					
					|  |  |  | void init_timer_100us(){ |  |  |  | void init_timer_100us(){ | 
			
		
	
		
		
			
				
					
					|  |  |  |     TCC0.CTRLA |= TC_CLKSEL_DIV256_gc; |  |  |  |     TCC0.CTRLA |= TC_CLKSEL_DIV256_gc; | 
			
		
	
		
		
			
				
					
					|  |  |  |     TCC0.PER = 13; // ==> 9615Hz
 |  |  |  |     TCC0.PER = 13; // ==> 9615Hz
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     TCC0.INTCTRLA |= TC_OVFINTLVL_MED_gc; |  |  |  |     TCC0.INTCTRLA |= TC_OVFINTLVL_HI_gc; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void adc_init(void){ |  |  |  | void adc_init(void){ | 
			
		
	
	
		
		
			
				
					|  |  | @ -69,16 +71,17 @@ uint16_t adc_read(void){ | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | float avrg(uint16_t * values, uint16_t length){ |  |  |  | float avrg(uint16_t * values, uint16_t length){ | 
			
		
	
		
		
			
				
					
					|  |  |  |     uint64_t res = 0; |  |  |  |     uint64_t res = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |     for(uint16_t i=0; i < length; i++){ |  |  |  |     //ommit first and last sample
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     for(uint16_t i=1; i < length-1; i++){ | 
			
		
	
		
		
			
				
					
					|  |  |  |         res += values[i]; |  |  |  |         res += values[i]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     return (float)(res)/length; |  |  |  |     return (float)(res)/(length-2); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void dma_init(void){ |  |  |  | void dma_init(void){ | 
			
		
	
		
		
			
				
					
					|  |  |  |     DMA.CTRL = DMA_ENABLE_bm; |  |  |  |     DMA.CTRL = DMA_ENABLE_bm; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     //DMA.CH0.CTRLB = DMA_CH_TRNINTLVL_LO_gc;
 |  |  |  |     DMA.CH0.CTRLB = DMA_CH_TRNINTLVL_LO_gc; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     DMA.CH0.TRFCNT = AVRG * 2; |  |  |  |     DMA.CH0.TRFCNT = AVRG * 2; | 
			
		
	
		
		
			
				
					
					|  |  |  |     DMA.CH0.CTRLA = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_SINGLE_bm; |  |  |  |     DMA.CH0.CTRLA = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_SINGLE_bm; | 
			
		
	
	
		
		
			
				
					|  |  | @ -92,9 +95,9 @@ void dma_init(void){ | 
			
		
	
		
		
			
				
					
					|  |  |  |     DMA.CH0.SRCADDR1 = (((uintptr_t)&ADCA.CH0.RES) >> 0x08) & 0xFF; |  |  |  |     DMA.CH0.SRCADDR1 = (((uintptr_t)&ADCA.CH0.RES) >> 0x08) & 0xFF; | 
			
		
	
		
		
			
				
					
					|  |  |  |     DMA.CH0.SRCADDR2 = (((uintptr_t)&ADCA.CH0.RES) >> 0x0F) & 0xFF; |  |  |  |     DMA.CH0.SRCADDR2 = (((uintptr_t)&ADCA.CH0.RES) >> 0x0F) & 0xFF; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     DMA.CH0.DESTADDR0 = ((uintptr_t)adc_values) & 0xFF; |  |  |  |     DMA.CH0.DESTADDR0 = ((uintptr_t)adc_buffer) & 0xFF; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     DMA.CH0.DESTADDR1 = ((uintptr_t)adc_values >> 0x08) & 0xFF; |  |  |  |     DMA.CH0.DESTADDR1 = ((uintptr_t)adc_buffer >> 0x08) & 0xFF; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     DMA.CH0.DESTADDR2 = ((uintptr_t)adc_values >> 0x0F) & 0xFF; |  |  |  |     DMA.CH0.DESTADDR2 = ((uintptr_t)adc_buffer >> 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.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_DESTRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -106,12 +109,7 @@ void modbusGet(void) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         switch(rxbuffer[1]) { |  |  |  |         switch(rxbuffer[1]) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             case fcReadHoldingRegisters: ; |  |  |  |             case fcReadHoldingRegisters: ; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 float tmp[4]; |  |  |  |                 modbusExchangeRegisters(ch_values, 0, 18); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 tmp[0] = avrg(adc_values, AVRG) - 170; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 tmp[1] = (tmp[0])/ 3926 * 1.95; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 tmp[2] = (tmp[1]*980)/(3.3-tmp[1]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 tmp[3] = (tmp[2]-100)/0.3927; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 modbusExchangeRegisters(tmp, 0, 8); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 break; |  |  |  |                 break; | 
			
		
	
		
		
			
				
					
					|  |  |  |             default: |  |  |  |             default: | 
			
		
	
		
		
			
				
					
					|  |  |  |                 modbusSendException(ecIllegalFunction); |  |  |  |                 modbusSendException(ecIllegalFunction); | 
			
		
	
	
		
		
			
				
					|  |  | @ -149,3 +147,25 @@ int main(void){ | 
			
		
	
		
		
			
				
					
					|  |  |  | ISR(TCC0_OVF_vect){ |  |  |  | ISR(TCC0_OVF_vect){ | 
			
		
	
		
		
			
				
					
					|  |  |  |     modbusTickTimer(); |  |  |  |     modbusTickTimer(); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ISR(DMA_CH0_vect){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     static uint8_t pin = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     DMA.INTFLAGS |= DMA_CH0TRNIF_bm; // clear flag
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_OFF_gc; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ADCA.CTRLB = 0; // stop ADC
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     uint8_t old_pin = pin; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     pin=(pin+1)%1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ADCA.CH0.MUXCTRL = pin << ADC_CH_MUXPOS_gp; // give MUX time to switch during averaging
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     float temp = avrg(adc_buffer, AVRG); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     temp = temp - 170; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     temp = (temp)/ 3926 * 1.95; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     temp = (temp*993.5)/(3.3-temp); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     temp = (temp-100)/0.3927; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ch_values[old_pin] = temp; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH0_gc; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ADCA.CTRLB = ADC_FREERUN_bm; // start ADC again
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |