@@ -48,34 +48,18 @@ const runtime_safety = std.debug.runtime_safety;
4848
4949const microzig = @import ("microzig" );
5050pub const gpio = @import ("STM32F303/gpio.zig" );
51+ pub const uart = @import ("STM32F303/uart.zig" );
5152
5253const SPI1 = microzig .peripherals .SPI1 ;
5354const RCC = microzig .chip .peripherals .RCC ;
54- const USART1 = microzig . chip . peripherals . USART1 ;
55+
5556const GPIOA = microzig .peripherals .GPIOA ;
5657const GPIOB = microzig .peripherals .GPIOB ;
5758const GPIOC = microzig .chip .peripherals .GPIOC ;
5859const I2C1 = microzig .peripherals .I2C1 ;
5960
6061pub const cpu = @import ("cpu" );
6162
62- pub const clock = struct {
63- pub const Domain = enum {
64- cpu ,
65- ahb ,
66- apb1 ,
67- apb2 ,
68- };
69- };
70-
71- // Default clock frequencies after reset, see top comment for calculation
72- pub const clock_frequencies = .{
73- .cpu = 8_000_000 ,
74- .ahb = 8_000_000 ,
75- .apb1 = 8_000_000 ,
76- .apb2 = 8_000_000 ,
77- };
78-
7963pub fn parse_pin (comptime spec : []const u8 ) type {
8064 const invalid_format_msg = "The given pin '" ++ spec ++ "' has an invalid format. Pins must follow the format \" P{Port}{Pin}\" scheme." ;
8165
@@ -100,142 +84,6 @@ fn set_reg_field(reg: anytype, comptime field_name: anytype, value: anytype) voi
10084 reg .write (temp );
10185}
10286
103- pub const uart = struct {
104- pub const DataBits = enum (u4 ) {
105- seven = 7 ,
106- eight = 8 ,
107- };
108-
109- /// uses the values of USART_CR2.STOP
110- pub const StopBits = enum (u2 ) {
111- one = 0b00 ,
112- half = 0b01 ,
113- two = 0b10 ,
114- one_and_half = 0b11 ,
115- };
116-
117- /// uses the values of USART_CR1.PS
118- pub const Parity = enum (u1 ) {
119- even = 0 ,
120- odd = 1 ,
121- };
122- };
123-
124- pub fn Uart () type {
125- return struct {
126- parity_read_mask : u8 ,
127-
128- const Self = @This ();
129-
130- pub fn init () ! Self {
131- // The following must all be written when the USART is disabled (UE=0).
132- if (USART1 .CR1 .read ().UE == 1 )
133- @panic ("Trying to initialize USART1 while it is already enabled" );
134- // LATER: Alternatively, set UE=0 at this point? Then wait for something?
135- // Or add a destroy() function which disables the USART?
136-
137- // enable the USART1 clock
138- RCC .APB2ENR .modify (.{ .USART1EN = 1 });
139- // enable GPIOC clock
140- RCC .AHBENR .modify (.{ .GPIOCEN = 1 });
141- // set PC4+PC5 to alternate function 7, USART1_TX + USART1_RX
142- GPIOC .MODER .modify (.{ .@"MODER[4]" = .Alternate , .@"MODER[5]" = .Alternate });
143- GPIOC .AFR [0 ].modify (.{ .@"AFR[4]" = 7 , .@"AFR[5]" = 7 });
144-
145- // clear USART1 configuration to its default
146- USART1 .CR1 .raw = 0 ;
147- USART1 .CR2 .raw = 0 ;
148- USART1 .CR3 .raw = 0 ;
149-
150- // set word length
151- // Per the reference manual, M[1:0] means
152- // - 00: 8 bits (7 data + 1 parity, or 8 data), probably the chip default
153- // - 01: 9 bits (8 data + 1 parity)
154- // - 10: 7 bits (7 data)
155- // So M1==1 means "7-bit mode" (in which
156- // "the Smartcard mode, LIN master mode and Auto baud rate [...] are not supported");
157- // and M0==1 means 'the 9th bit (not the 8th bit) is the parity bit'.
158- USART1 .CR1 .modify (.{ .M0 = .Bit8 , .M1 = .M0 });
159-
160- // set parity
161- USART1 .CR1 .modify (.{ .PCE = 0 }); // no parity, probably the chip default
162-
163- // set number of stop bits
164- USART1 .CR2 .modify (.{ .STOP = .Stop1 });
165-
166- // set the baud rate
167- // TODO: Do not use the _board_'s frequency, but the _U(S)ARTx_ frequency
168- // from the chip, which can be affected by how the board configures the chip.
169- // In our case, these are accidentally the same at chip reset,
170- // if the board doesn't configure e.g. an HSE external crystal.
171- // TODO: Do some checks to see if the baud rate is too high (or perhaps too low)
172- // TODO: Do a rounding div, instead of a truncating div?
173- const usartdiv = @as (u16 , @intCast (@divTrunc (clock_frequencies .apb2 , 115200 )));
174- USART1 .BRR .raw = usartdiv ;
175- // Above, ignore the BRR struct fields DIV_Mantissa and DIV_Fraction,
176- // those seem to be for another chipset; .svd file bug?
177- // TODO: We assume the default OVER8=0 configuration above.
178-
179- // enable USART1, and its transmitter and receiver
180- USART1 .CR1 .modify (.{ .UE = 1 });
181- USART1 .CR1 .modify (.{ .TE = 1 });
182- USART1 .CR1 .modify (.{ .RE = 1 });
183-
184- // For code simplicity, at cost of one or more register reads,
185- // we read back the actual configuration from the registers,
186- // instead of using the `config` values.
187- return read_from_registers ();
188- }
189-
190- pub fn get_or_init (config : microzig.uart.Config ) ! Self {
191- if (USART1 .CR1 .read ().UE == 1 ) {
192- // UART1 already enabled, don't reinitialize and disturb things;
193- // instead read and use the actual configuration.
194- return read_from_registers ();
195- } else return init (config );
196- }
197-
198- fn read_from_registers () Self {
199- const cr1 = USART1 .CR1 .read ();
200- // As documented in `init()`, M0==1 means 'the 9th bit (not the 8th bit) is the parity bit'.
201- // So we always mask away the 9th bit, and if parity is enabled and it is in the 8th bit,
202- // then we also mask away the 8th bit.
203- return Self { .parity_read_mask = if (cr1 .PCE == 1 and cr1 .M0 == .Bit8 ) 0x7F else 0xFF };
204- }
205-
206- pub fn can_write (self : Self ) bool {
207- _ = self ;
208- return switch (USART1 .ISR .read ().TXE ) {
209- 1 = > true ,
210- 0 = > false ,
211- };
212- }
213-
214- pub fn tx (self : Self , ch : u8 ) void {
215- while (! self .can_write ()) {} // Wait for Previous transmission
216- USART1 .TDR .modify (.{ .DR = ch });
217- }
218-
219- pub fn txflush (_ : Self ) void {
220- while (USART1 .ISR .read ().TC == 0 ) {}
221- }
222-
223- pub fn can_read (self : Self ) bool {
224- _ = self ;
225- return switch (USART1 .ISR .read ().RXNE ) {
226- 1 = > true ,
227- 0 = > false ,
228- };
229- }
230-
231- pub fn rx (self : Self ) u8 {
232- while (! self .can_read ()) {} // Wait till the data is received
233- const data_with_parity_bit : u9 = USART1 .RDR .read ().RDR ;
234- return @as (u8 , @intCast (data_with_parity_bit & self .parity_read_mask ));
235- }
236- };
237- }
238-
23987const enable_stm32f303_debug = false ;
24088
24189fn debug_print (comptime format : []const u8 , args : anytype ) void {
0 commit comments