55//before creating a program using ADC from older ST families, such as in this case STM32F1
66//be aware of possible hardware bugs and limitations
77//for example:
8- // temperature sensor/VREF cannot be read in interleaved mode as it requires a sample time greater than 17
9- // readings after 1ms from the previous reading may contain more noise than expected
8+ //temperature sensor/VREF cannot be read in interleaved mode as it requires a sample time greater than 17
9+ //readings after 1ms from the previous reading may contain more noise than expected
1010//Voltage glitch on ADC input 0
1111
1212const std = @import ("std" );
1313const microzig = @import ("microzig" );
14-
1514const interrupt = microzig .interrupt ;
16- const DMA = microzig .chip .peripherals .DMA1 ;
17- const DMA_t = microzig .chip .types .peripherals .bdma_v1 ;
18-
1915const stm32 = microzig .hal ;
2016const rcc = stm32 .rcc ;
21- const timer = microzig .hal .timer .GPTimer .init (.TIM2 ).into_counter_mode ();
17+ const gpio = stm32 .gpio ;
18+ const dma = stm32 .dma ;
19+ const AdvancedADC = stm32 .adc .AdvancedADC ;
2220
21+ const dma_controller = dma .DMAController .init (.DMA1 );
22+ const timer = stm32 .timer .GPTimer .init (.TIM2 ).into_counter_mode ();
2323const uart = stm32 .uart .UART .init (.USART1 );
24- const gpio = stm32 .gpio ;
24+ const adc = AdvancedADC .init (.ADC1 );
25+
2526const TX = gpio .Pin .from_port (.A , 9 );
27+ const ADC_pin1 = gpio .Pin .from_port (.A , 1 );
28+ const ADC_pin2 = gpio .Pin .from_port (.A , 2 );
29+ const ADC_pin3 = gpio .Pin .from_port (.A , 3 );
2630
2731pub const microzig_options = microzig.Options {
2832 .logFn = stm32 .uart .log ,
2933 .interrupts = .{ .ADC1_2 = .{ .c = watchdog_handler } },
3034};
3135
32- const AdvancedADC = microzig .hal .adc .AdvancedADC ;
33- const adc = AdvancedADC .init (.ADC1 );
34- const ADC_pin1 = gpio .Pin .from_port (.A , 1 );
35- const ADC_pin2 = gpio .Pin .from_port (.A , 2 );
36- const ADC_pin3 = gpio .Pin .from_port (.A , 3 );
37-
3836const v25 = 1.43 ;
3937const avg_slope = 0.0043 ; //4.3mV/°C
4038
@@ -49,28 +47,8 @@ fn adc_to_temp(val: usize) f32 {
4947 return ((v25 - temp_mv ) / avg_slope ) + 25 ; //convert to celsius
5048}
5149
52- fn DMA_init (arr_addr : u32 , adc_addr : u32 ) void {
53- const CH1 : * volatile DMA_t.CH = @ptrCast (& DMA .CH );
54- CH1 .CR .raw = 0 ; //disable channel
55- CH1 .NDTR .raw = 0 ;
56- CH1 .CR .modify (.{
57- .DIR = DMA_t .DIR .FromPeripheral ,
58- .CIRC = 1 , //disable circular mode
59- .PL = DMA_t .PL .High , //high priority
60- .MSIZE = DMA_t .SIZE .Bits16 ,
61- .PSIZE = DMA_t .SIZE .Bits16 ,
62- .MINC = 1 , //memory increment mode
63- .PINC = 0 , //peripheral not incremented
64- });
65-
66- CH1 .NDTR .modify (.{ .NDT = 4 }); //number of data to transfer, 4 samples
67- CH1 .PAR = adc_addr ; //peripheral address
68- CH1 .MAR = arr_addr ; //memory address
69- CH1 .CR .modify (.{ .EN = 1 }); //enable channel
70- }
71-
7250pub fn main () ! void {
73- try rcc .clock_init (.{ .ADCprescaler = .RCC_ADCPCLK2_DIV2 });
51+ try rcc .apply_clock (.{ .ADCprescaler = .RCC_ADCPCLK2_DIV2 });
7452
7553 rcc .enable_clock (.DMA1 );
7654 rcc .enable_clock (.TIM2 );
@@ -80,11 +58,23 @@ pub fn main() !void {
8058 rcc .enable_clock (.ADC1 );
8159
8260 const counter = timer .counter_device (rcc .get_clock (.TIM2 ));
83-
84- const adc_data_addr : u32 = @intFromPtr (& adc .regs .DR );
85- var adc_buf : [10 ]u16 = .{0 } ** 10 ;
86- const adc_buf_addr : u32 = @intFromPtr (& adc_buf );
8761 const ref_ovf_flag : * volatile bool = & ovf_flag ;
62+ var adc_buf : [10 ]u16 = .{0 } ** 10 ;
63+
64+ dma_controller .apply_channel (0 , .{
65+ .circular_mode = true ,
66+ .memory_increment = true ,
67+
68+ .direction = .FromPeripheral ,
69+ .priority = .High ,
70+ .memory_size = .Bits16 ,
71+ .peripheral_size = .Bits16 ,
72+
73+ .transfer_count = 4 ,
74+ .periph_address = @intFromPtr (& adc .regs .DR ),
75+ .mem_address = @intFromPtr (& adc_buf ),
76+ });
77+ dma_controller .start_channel (0 );
8878
8979 //configure UART log
9080
@@ -142,13 +132,10 @@ pub fn main() !void {
142132 );
143133
144134 std .log .info ("start Advanced ADC scan" , .{});
145-
146- DMA_init (adc_buf_addr , adc_data_addr );
147-
148135 while (true ) {
149136 adc .software_trigger (); //start conversion
150137 counter .sleep_ms (100 );
151- std .log .info ("\x1B [2J\x1B [H" , .{}); // Clear screen and move cursor to 1,1
138+ std .log .info ("\x1B [2J\x1B [H" , .{}); //Clear screen and move cursor to 1,1
152139 std .log .info ("CPU temp: {d:.1}C" , .{adc_to_temp (adc_buf [0 ])});
153140 std .log .info ("Vref: {d:0>4}" , .{adc_buf [1 ]});
154141 std .log .info ("CH1: {d:0>4}" , .{adc_buf [2 ]});
0 commit comments