diff --git a/examples/adc_fixed_fs/Makefile b/examples/adc_fixed_fs/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..83283cb7139f36dedbc3d60fc58dec21aa068731
--- /dev/null
+++ b/examples/adc_fixed_fs/Makefile
@@ -0,0 +1,10 @@
+all : flash
+
+TARGET:=adc_fixed_fs
+
+include ../../ch32v003fun/ch32v003fun.mk
+
+flash : cv_flash
+clean : cv_clean
+
+
diff --git a/examples/adc_fixed_fs/adc_fixed_fs.c b/examples/adc_fixed_fs/adc_fixed_fs.c
new file mode 100644
index 0000000000000000000000000000000000000000..283e5550ea29f53992f7dbb943f89bcd6c5bf0ce
--- /dev/null
+++ b/examples/adc_fixed_fs/adc_fixed_fs.c
@@ -0,0 +1,146 @@
+/*
+ * Example for using ADC with DMA and timer for fixed sampling rate
+ * by eeucalyptus
+ */
+
+#include "ch32v003fun.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#define BUFFER_LENGTH 128
+volatile uint16_t buffer[2][BUFFER_LENGTH] = {0};
+volatile uint32_t current_write_buffer = 0;
+#define current_read_buffer (1-current_write_buffer)
+
+void init_dma()
+{
+	// Start DMA clock
+	RCC->AHBPCENR |= RCC_AHBPeriph_DMA1;
+
+	// Setup DMA Channel 1 (adc triggered) as reading, 16-bit, linear buffer
+	DMA1_Channel1->CFGR = DMA_DIR_PeripheralSRC |
+												DMA_MemoryInc_Enable |
+												DMA_PeripheralDataSize_HalfWord |
+												DMA_MemoryDataSize_HalfWord;
+	// No of samples to get before irq
+	DMA1_Channel1->CNTR = BUFFER_LENGTH;
+	// Source
+	DMA1_Channel1->PADDR = (uint32_t)&ADC1->RDATAR;
+	// Destination
+	DMA1_Channel1->MADDR = (uint32_t)buffer[current_write_buffer];
+
+	// Enable IRQ and DMA channel
+	NVIC_EnableIRQ(DMA1_Channel1_IRQn);
+	DMA1_Channel1->CFGR |= DMA_IT_TC | DMA_CFGR1_EN;
+}
+
+void init_timer() {
+  // TIMER
+  printf("Initializing timer...\r\n");
+  RCC->APB2PCENR |= RCC_APB2Periph_TIM1;
+  TIM1->CTLR1 |= TIM_CounterMode_Up | TIM_CKD_DIV1;
+	TIM1->CTLR2 = TIM_MMS_1;
+  TIM1->ATRLR = 1000;
+  TIM1->PSC = 10-1;
+  TIM1->RPTCR = 0;
+  TIM1->SWEVGR = TIM_PSCReloadMode_Immediate;
+
+  NVIC_EnableIRQ(TIM1_UP_IRQn);
+  TIM1->INTFR = ~TIM_FLAG_Update;
+  TIM1->DMAINTENR |= TIM_IT_Update;
+  TIM1->CTLR1 |= TIM_CEN;
+}
+
+void init_adc() {
+  printf("Initializing ADC...\r\n");
+
+  RCC->APB2PCENR |= RCC_APB2Periph_GPIOC;
+	GPIOC->CFGLR &= ~(0xf<<(4*4));	// CNF = 00: Analog, MODE = 00: Input
+
+	RCC->APB2PCENR |= RCC_APB2Periph_ADC1;
+
+	// Reset the ADC to init all regs
+	RCC->APB2PRSTR |= RCC_APB2Periph_ADC1;
+	RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1;
+
+	// ADCCLK = 24 MHz => RCC_ADCPRE divide by 2
+	RCC->CFGR0 &= ~RCC_ADCPRE;  // Clear out the bis in case they were set
+	RCC->CFGR0 |= RCC_ADCPRE_DIV2;	// set it to 010xx for /2.
+
+	// Keep CALVOL register with initial value
+	ADC1->CTLR1 |= ADC_ExternalTrigConv_T1_TRGO;
+	ADC1->CTLR2 = ADC_ADON | ADC_DMA | ADC_EXTTRIG;
+
+	// Possible times: 0->3,1->9,2->15,3->30,4->43,5->57,6->73,7->241 cycles
+	ADC1->SAMPTR2 = 0/*3 cycles*/ << (3/*offset per channel*/ * 2/*channel*/);
+
+	// Set sequencer to channel 2 only
+	ADC1->RSQR3 = 2;
+
+	// Calibrate
+	printf("Calibrating ADC...\r\n");
+	ADC1->CTLR2 |= ADC_RSTCAL;
+	while(ADC1->CTLR2 & ADC_RSTCAL);
+	ADC1->CTLR2 |= ADC_CAL;
+	while(ADC1->CTLR2 & ADC_CAL);
+
+  // Interrupt will no work as long as DMA is on. why? does DMA clear the flag so fast?
+//  ADC1->STATR = ~ADC_FLAG_EOC;
+//	ADC1->CTLR1 |= ADC_IT_EOC;
+//  NVIC_EnableIRQ(ADC_IRQn);
+
+}
+
+void TIM1_UP_IRQHandler(void) __attribute__((interrupt));
+void TIM1_UP_IRQHandler() {
+  if(TIM1->INTFR & TIM_FLAG_Update) {
+    TIM1->INTFR = ~TIM_FLAG_Update;
+    //printf("TIMER ISR!...\r\n");
+  }
+}
+
+void ADC1_IRQHandler(void) __attribute__((interrupt));
+void ADC1_IRQHandler() {
+  if(ADC1->STATR & ADC_FLAG_EOC) {
+    ADC1->STATR = ~ADC_FLAG_EOC;
+    int adcraw = ADC1->RDATAR;
+    //printf("ADC ISR! in=%d\r\n", adcraw);
+  }
+}
+
+void DMA1_Channel1_IRQHandler(void) __attribute__((interrupt));
+void DMA1_Channel1_IRQHandler()
+{
+  if(DMA1->INTFR & DMA1_FLAG_TC1)
+  {
+      DMA1->INTFCR = DMA_CTCIF1;
+//        printf("DMA ISR!\r\n");
+      current_write_buffer = current_read_buffer;
+      init_dma();
+  }
+}
+
+volatile int test = 0;
+
+int main() {
+  SystemInit();
+
+  init_dma();
+  init_adc();
+  init_timer();
+
+  test = atoi("123");
+
+  int last_handled_buffer = current_read_buffer;
+  while(1) {
+  		if(last_handled_buffer != current_read_buffer) {
+  				last_handled_buffer = current_read_buffer;
+  				for(int i = 0; i < BUFFER_LENGTH; i++) {
+  						while( !(USART1->STATR & USART_FLAG_TC));
+  						USART1->DATAR = (const char)((buffer[current_read_buffer][i])&0xff);
+  						while( !(USART1->STATR & USART_FLAG_TC));
+							USART1->DATAR = (const char)((buffer[current_read_buffer][i])>>8);
+  				}
+  		}
+  }
+}
diff --git a/examples/adc_fixed_fs/funconfig.h b/examples/adc_fixed_fs/funconfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..2cd0523c8bb8cc23021c2079b0954116f3e38ebc
--- /dev/null
+++ b/examples/adc_fixed_fs/funconfig.h
@@ -0,0 +1,11 @@
+#ifndef _FUNCONFIG_H
+#define _FUNCONFIG_H
+
+#define CH32V003           1
+#define FUNCONF_USE_HSE 1
+#define FUNCONF_USE_PLL 1               // Do not use built-in 2x PLL 
+#define FUNCONF_USE_UARTPRINTF 1
+#define FUNCONF_UART_PRINTF_BAUD 115200
+
+#endif
+