diff --git a/examples/adc_polled/Makefile b/examples/adc_polled/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a460104b9ed98d7aa1c20904f32362c082c3f0ba --- /dev/null +++ b/examples/adc_polled/Makefile @@ -0,0 +1,41 @@ +TARGET:=adc_polled + +all : flash + +PREFIX:=riscv64-unknown-elf + +GPIO_Toggle:=EXAM/GPIO/GPIO_Toggle/User + +CH32V003FUN:=../../ch32v003fun +MINICHLINK:=../../minichlink + +CFLAGS:= \ + -g -Os -flto -ffunction-sections \ + -static-libgcc -lgcc \ + -march=rv32ec \ + -mabi=ilp32e \ + -I/usr/include/newlib \ + -I$(CH32V003FUN) \ + -nostdlib \ + -I. -DSTDOUT_UART -Wall + +LDFLAGS:=-T $(CH32V003FUN)/ch32v003fun.ld -Wl,--gc-sections + +SYSTEM_C:=$(CH32V003FUN)/ch32v003fun.c + +$(TARGET).elf : $(SYSTEM_C) $(TARGET).c + $(PREFIX)-gcc -o $@ $^ $(CFLAGS) $(LDFLAGS) + +$(TARGET).bin : $(TARGET).elf + $(PREFIX)-size $^ + $(PREFIX)-objdump -S $^ > $(TARGET).lst + $(PREFIX)-objdump -t $^ > $(TARGET).map + $(PREFIX)-objcopy -O binary $< $(TARGET).bin + $(PREFIX)-objcopy -O ihex $< $(TARGET).hex + +flash : $(TARGET).bin + $(MINICHLINK)/minichlink -w $< flash -b + +clean : + rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).lst $(TARGET).map $(TARGET).hex + diff --git a/examples/adc_polled/adc.h b/examples/adc_polled/adc.h new file mode 100644 index 0000000000000000000000000000000000000000..b9777ec29ea01c15ce6048a7fc3f9bbcbcdd750b --- /dev/null +++ b/examples/adc_polled/adc.h @@ -0,0 +1,67 @@ +/* + * Single-File-Header for using ADC with polling + * 03-27-2023 E. Brombaugh + */ + +#ifndef _ADC_H +#define _ADC_H + +#include <stdint.h> + +/* + * initialize adc for polling + */ +void adc_init( void ) +{ + // ADCCLK = 24 MHz => RCC_ADCPRE = 0: divide by 2 + RCC->CFGR0 &= ~(0x1F<<11); + + // Enable GPIOD and ADC + RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_ADC1; + + // PD4 is analog input chl 7 + GPIOD->CFGLR &= ~(0xf<<(4*4)); // CNF = 00: Analog, MODE = 00: Input + + // Reset the ADC to init all regs + RCC->APB2PRSTR |= RCC_APB2Periph_ADC1; + RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1; + + // Set up single conversion on chl 7 + ADC1->RSQR1 = 0; + ADC1->RSQR2 = 0; + ADC1->RSQR3 = 7; // 0-9 for 8 ext inputs and two internals + + // set sampling time for chl 7 + ADC1->SAMPTR2 &= ~(ADC_SMP0<<(3*7)); + ADC1->SAMPTR2 |= 7<<(3*7); // 0:7 => 3/9/15/30/43/57/73/241 cycles + + // turn on ADC and set rule group to sw trig + ADC1->CTLR2 |= ADC_ADON | ADC_EXTSEL; + + // Reset calibration + ADC1->CTLR2 |= ADC_RSTCAL; + while(ADC1->CTLR2 & ADC_RSTCAL); + + // Calibrate + ADC1->CTLR2 |= ADC_CAL; + while(ADC1->CTLR2 & ADC_CAL); + + // should be ready for SW conversion now +} + +/* + * start conversion, wait and return result + */ +uint16_t adc_get( void ) +{ + // start sw conversion (auto clears) + ADC1->CTLR2 |= ADC_SWSTART; + + // wait for conversion complete + while(!(ADC1->STATR & ADC_EOC)); + + // get result + return ADC1->RDATAR; +} + +#endif diff --git a/examples/adc_polled/adc_polled.c b/examples/adc_polled/adc_polled.c new file mode 100644 index 0000000000000000000000000000000000000000..56283d10853a3cfeba6cb98ace926d1682160901 --- /dev/null +++ b/examples/adc_polled/adc_polled.c @@ -0,0 +1,45 @@ +/* + * Example for using ADC with polling + * 03-27-2023 E. Brombaugh + */ + +// Could be defined here, or in the processor defines. +#define SYSTEM_CORE_CLOCK 48000000 +#define APB_CLOCK SYSTEM_CORE_CLOCK + +#include "ch32v003fun.h" +#include <stdio.h> +#include "adc.h" + +int main() +{ + uint32_t count = 0; + + SystemInit48HSI(); + + // start serial @ default 115200bps + SetupUART( UART_BRR ); + printf("\r\r\n\nadc_polled example\n\r"); + + // init systick @ 1ms rate + printf("initializing adc..."); + adc_init(); + printf("done.\n\r"); + + // Enable GPIOs + RCC->APB2PCENR |= RCC_APB2Periph_GPIOD; + + // GPIO D0 Push-Pull + GPIOD->CFGLR &= ~(0xf<<(4*0)); + GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0); + + printf("looping...\n\r"); + while(1) + { + GPIOD->BSHR = 1; // Turn on GPIOs + Delay_Ms( 100 ); + GPIOD->BSHR = (1<<16); // Turn off GPIODs + Delay_Ms( 100 ); + printf( "Count: %lu adc: %d\n\r", count++, adc_get() ); + } +}