Skip to content

Commit a409db9

Browse files
Start CNC controller on the STM32F4-DISCO
1 parent 5746b9d commit a409db9

9 files changed

+501
-1
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
*.o
33
*.exe
44
*.cgpr
5-
5+
*#
6+
*.db
7+
*-loc.xml
68
# Ada Library Information
79
*.ali

gcode/src/gcode-planner.adb

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
with Bounded_Buffers_Blocking_Consumer;
22
with Bounded_Buffers_Blocking_Producer;
3+
with Ada.Real_Time; use Ada.Real_Time;
34
with System;
45

56
package body Gcode.Planner is
@@ -180,6 +181,7 @@ package body Gcode.Planner is
180181
Seg_Time : Float_Value;
181182
pragma Unreferenced (Seg_Time);
182183
begin
184+
delay until Time_Last;
183185
loop
184186

185187
-- Blocking call
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Ignore everything in this directory
2+
*
3+
# Except this file
4+
!.gitignore

stm32f4-disco_controller/src/coms.adb

+301
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
with Ada.Unchecked_Conversion;
2+
with STM32; use STM32;
3+
with STM32_SVD;
4+
5+
package body Coms is
6+
7+
use type STM32_SVD.UInt9;
8+
9+
type DMA_Data is array (Integer range <>) of Interfaces.Unsigned_8;
10+
11+
-------------------------------
12+
-- Initialize_GPIO_Port_Pins --
13+
-------------------------------
14+
15+
procedure Initialize_GPIO_Port_Pins is
16+
Configuration : GPIO_Port_Configuration;
17+
begin
18+
Enable_Clock (IO_Port);
19+
20+
Configuration.Mode := Mode_AF;
21+
Configuration.Speed := Speed_50MHz;
22+
Configuration.Output_Type := Push_Pull;
23+
Configuration.Resistors := Pull_Up;
24+
25+
Configure_IO
26+
(Port => IO_Port,
27+
Pins => Rx_Pin & Tx_Pin,
28+
Config => Configuration);
29+
30+
Configure_Alternate_Function
31+
(Port => IO_Port,
32+
Pins => Rx_Pin & Tx_Pin,
33+
AF => Transceiver_AF);
34+
end Initialize_GPIO_Port_Pins;
35+
36+
----------------------
37+
-- Initialize_USART --
38+
----------------------
39+
40+
procedure Initialize_USART is
41+
begin
42+
Enable_Clock (Transceiver);
43+
44+
Enable (Transceiver);
45+
46+
Set_Baud_Rate (Transceiver, 115_200);
47+
Set_Mode (Transceiver, Tx_Rx_Mode);
48+
Set_Stop_Bits (Transceiver, Stopbits_1);
49+
Set_Word_Length (Transceiver, Word_Length_8);
50+
Set_Parity (Transceiver, No_Parity);
51+
Set_Flow_Control (Transceiver, No_Flow_Control);
52+
end Initialize_USART;
53+
54+
--------------------
55+
-- Initialize_DMA --
56+
--------------------
57+
58+
procedure Initialize_DMA is
59+
Configuration : DMA_Stream_Configuration;
60+
begin
61+
Enable_Clock (Controller);
62+
63+
Configuration.Channel := Tx_Channel;
64+
Configuration.Direction := Memory_To_Peripheral;
65+
Configuration.Increment_Peripheral_Address := False;
66+
Configuration.Increment_Memory_Address := True;
67+
Configuration.Peripheral_Data_Format := Bytes;
68+
Configuration.Memory_Data_Format := Bytes;
69+
Configuration.Operation_Mode := Normal_Mode;
70+
Configuration.Priority := Priority_Very_High;
71+
Configuration.FIFO_Enabled := True;
72+
Configuration.FIFO_Threshold := FIFO_Threshold_Full_Configuration;
73+
Configuration.Memory_Burst_Size := Memory_Burst_Inc4;
74+
Configuration.Peripheral_Burst_Size := Peripheral_Burst_Inc4;
75+
76+
Configure (Controller, Tx_Stream, Configuration);
77+
-- note the controller is disabled by the call to Configure
78+
end Initialize_DMA;
79+
80+
---------------
81+
-- Initalize --
82+
---------------
83+
84+
procedure Initalize is
85+
begin
86+
Initialize_GPIO_Port_Pins;
87+
Initialize_USART;
88+
Initialize_DMA;
89+
Enable (Transceiver);
90+
Enable_Interrupts (Transceiver, Source => Received_Data_Not_Empty);
91+
end Initalize;
92+
93+
----------------------------
94+
-- UART_Get_Data_Blocking --
95+
----------------------------
96+
97+
procedure UART_Get_Data_Blocking (C : out Character) is
98+
function Data_To_Character is new Ada.Unchecked_Conversion
99+
(Interfaces.Unsigned_8, Character);
100+
Rx_Byte : Interfaces.Unsigned_8;
101+
begin
102+
Rx_IRQ_Handler.Await_Byte_Reception (Rx_Byte);
103+
C := Data_To_Character (Rx_Byte);
104+
end UART_Get_Data_Blocking;
105+
106+
---------------------------------
107+
-- UART_Send_DMA_Data_Blocking --
108+
---------------------------------
109+
110+
procedure UART_Send_DMA_Data_Blocking
111+
(Data : String)
112+
is
113+
function Character_To_Data is new Ada.Unchecked_Conversion
114+
(Character, Interfaces.Unsigned_8);
115+
Source_Block : DMA_Data (Data'Range);
116+
begin
117+
for Index in Source_Block'Range loop
118+
Source_Block (Index) := Character_To_Data (Data (Index));
119+
end loop;
120+
121+
Start_Transfer_with_Interrupts
122+
(Controller,
123+
Tx_Stream,
124+
Source => Source_Block'Address,
125+
Destination => Data_Register_Address (Transceiver),
126+
Data_Count => Half_Word (Source_Block'Length));
127+
-- also enables the stream
128+
129+
Enable_DMA_Transmit_Requests (Transceiver);
130+
131+
Tx_IRQ_Handler.Await_Transfer_Complete;
132+
end UART_Send_DMA_Data_Blocking;
133+
-------------------------------
134+
-- Finalize_DMA_Transmission --
135+
-------------------------------
136+
137+
procedure Finalize_DMA_Transmission (Transceiver : in out USART) is
138+
-- see static void USART_DMATransmitCplt
139+
begin
140+
loop
141+
exit when Status (Transceiver, Transmission_Complete_Indicated);
142+
end loop;
143+
Clear_Status (Transceiver, Transmission_Complete_Indicated);
144+
Disable_DMA_Transmit_Requests (Transceiver);
145+
end Finalize_DMA_Transmission;
146+
147+
--------------------
148+
-- Tx_IRQ_Handler --
149+
--------------------
150+
151+
protected body Tx_IRQ_Handler is
152+
153+
-----------------------------
154+
-- Await_Transfer_Complete --
155+
-----------------------------
156+
157+
entry Await_Transfer_Complete when Transfer_Complete is
158+
begin
159+
Event_Occurred := False;
160+
Transfer_Complete := False;
161+
end Await_Transfer_Complete;
162+
163+
-----------------
164+
-- IRQ_Handler --
165+
-----------------
166+
167+
procedure IRQ_Handler is
168+
begin
169+
-- Transfer Error Interrupt management
170+
if Status (Controller, Tx_Stream, Transfer_Error_Indicated) then
171+
if Interrupt_Enabled
172+
(Controller, Tx_Stream, Transfer_Error_Interrupt)
173+
then
174+
Disable_Interrupt
175+
(Controller, Tx_Stream, Transfer_Error_Interrupt);
176+
Clear_Status (Controller, Tx_Stream, Transfer_Error_Indicated);
177+
Event_Kind := Transfer_Error_Interrupt;
178+
Event_Occurred := True;
179+
return;
180+
end if;
181+
end if;
182+
183+
-- FIFO Error Interrupt management.
184+
if Status (Controller, Tx_Stream, FIFO_Error_Indicated) then
185+
if Interrupt_Enabled
186+
(Controller, Tx_Stream, FIFO_Error_Interrupt)
187+
then
188+
Disable_Interrupt (Controller, Tx_Stream, FIFO_Error_Interrupt);
189+
Clear_Status (Controller, Tx_Stream, FIFO_Error_Indicated);
190+
Event_Kind := FIFO_Error_Interrupt;
191+
Event_Occurred := True;
192+
return;
193+
end if;
194+
end if;
195+
196+
-- Direct Mode Error Interrupt management
197+
if Status (Controller, Tx_Stream, Direct_Mode_Error_Indicated) then
198+
if Interrupt_Enabled
199+
(Controller, Tx_Stream, Direct_Mode_Error_Interrupt)
200+
then
201+
Disable_Interrupt
202+
(Controller, Tx_Stream, Direct_Mode_Error_Interrupt);
203+
Clear_Status
204+
(Controller, Tx_Stream, Direct_Mode_Error_Indicated);
205+
Event_Kind := Direct_Mode_Error_Interrupt;
206+
Event_Occurred := True;
207+
return;
208+
end if;
209+
end if;
210+
211+
-- Half Transfer Complete Interrupt management
212+
if Status
213+
(Controller, Tx_Stream, Half_Transfer_Complete_Indicated)
214+
then
215+
if Interrupt_Enabled
216+
(Controller, Tx_Stream, Half_Transfer_Complete_Interrupt)
217+
then
218+
if Double_Buffered (Controller, Tx_Stream) then
219+
Clear_Status
220+
(Controller, Tx_Stream, Half_Transfer_Complete_Indicated);
221+
else -- not double buffered
222+
if not Circular_Mode (Controller, Tx_Stream) then
223+
Disable_Interrupt
224+
(Controller,
225+
Tx_Stream,
226+
Half_Transfer_Complete_Interrupt);
227+
end if;
228+
Clear_Status
229+
(Controller, Tx_Stream, Half_Transfer_Complete_Indicated);
230+
end if;
231+
Event_Kind := Half_Transfer_Complete_Interrupt;
232+
Event_Occurred := True;
233+
end if;
234+
end if;
235+
236+
-- Transfer Complete Interrupt management
237+
if Status (Controller, Tx_Stream, Transfer_Complete_Indicated) then
238+
if Interrupt_Enabled
239+
(Controller, Tx_Stream, Transfer_Complete_Interrupt)
240+
then
241+
if Double_Buffered
242+
(Controller, Tx_Stream)
243+
then
244+
Clear_Status
245+
(Controller, Tx_Stream, Transfer_Complete_Indicated);
246+
-- TODO: handle the difference between M0 and M1 callbacks
247+
else
248+
if not Circular_Mode (Controller, Tx_Stream) then
249+
Disable_Interrupt
250+
(Controller, Tx_Stream, Transfer_Complete_Interrupt);
251+
end if;
252+
Clear_Status
253+
(Controller, Tx_Stream, Transfer_Complete_Indicated);
254+
end if;
255+
Finalize_DMA_Transmission (Transceiver);
256+
Event_Kind := Transfer_Complete_Interrupt;
257+
Event_Occurred := True;
258+
Transfer_Complete := True;
259+
end if;
260+
end if;
261+
end IRQ_Handler;
262+
263+
end Tx_IRQ_Handler;
264+
--------------------
265+
-- Rx_IRQ_Handler --
266+
--------------------
267+
268+
protected body Rx_IRQ_Handler is
269+
270+
--------------------------
271+
-- Await_Byte_Reception --
272+
--------------------------
273+
274+
entry Await_Byte_Reception (Rx_Byte : out Interfaces.Unsigned_8)
275+
when Byte_Avalaible is
276+
begin
277+
-- Dequeue (Rx_Queue, Rx_Byte);
278+
-- Byte_Avalaible := not Is_Empty (Rx_Queue);
279+
Rx_Byte := Data;
280+
Byte_Avalaible := False;
281+
end Await_Byte_Reception;
282+
283+
-----------------
284+
-- IRQ_Handler --
285+
-----------------
286+
287+
procedure IRQ_Handler is
288+
Received_Byte : Interfaces.Unsigned_8;
289+
begin
290+
if Status (Transceiver, Read_Data_Register_Not_Empty) then
291+
Received_Byte :=
292+
Interfaces.Unsigned_8 (Current_Input (Transceiver) and 16#FF#);
293+
Clear_Status (Transceiver, Read_Data_Register_Not_Empty);
294+
-- Enqueue (Rx_Queue, Received_Byte);
295+
Data := Received_Byte;
296+
Byte_Avalaible := True;
297+
end if;
298+
end IRQ_Handler;
299+
300+
end Rx_IRQ_Handler;
301+
end Coms;

stm32f4-disco_controller/src/coms.ads

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
with STM32.Device; use STM32.Device;
2+
with STM32.GPIO; use STM32.GPIO;
3+
with STM32.USARTs; use STM32.USARTs;
4+
with STM32.Timers; use STM32.Timers;
5+
with STM32.DMA; use STM32.DMA;
6+
with Ada.Interrupts;
7+
with Ada.Interrupts.Names; use Ada.Interrupts.Names;
8+
with Interfaces;
9+
10+
package Coms is
11+
procedure Initalize;
12+
procedure UART_Send_DMA_Data_Blocking (Data : String);
13+
procedure UART_Get_Data_Blocking (C : out Character);
14+
private
15+
IO_Port : GPIO_Port renames GPIO_A;
16+
17+
Transceiver : USART renames USART_2;
18+
19+
Transceiver_AF : constant GPIO_Alternate_Function := GPIO_AF_USART2;
20+
21+
TX_Pin : constant GPIO_Pin := Pin_2;
22+
RX_Pin : constant GPIO_Pin := Pin_3;
23+
24+
Controller : STM32.Device.DMA_Controller renames STM32.Device.DMA_1;
25+
26+
Tx_Channel : constant DMA_Channel_Selector := Channel_4;
27+
28+
Tx_Stream : constant DMA_Stream_Selector := Stream_6;
29+
30+
DMA_Tx_IRQ : constant Ada.Interrupts.Interrupt_Id := DMA1_Stream6_Interrupt;
31+
-- must match that of the selected controller and stream number!!!!
32+
33+
-- DMA Interrupt Handler for transmission.
34+
protected Tx_IRQ_Handler is
35+
pragma Interrupt_Priority;
36+
37+
entry Await_Transfer_Complete;
38+
39+
private
40+
41+
Event_Occurred : Boolean := False;
42+
Transfer_Complete : Boolean := False;
43+
Event_Kind : DMA_Interrupt;
44+
45+
procedure IRQ_Handler;
46+
pragma Attach_Handler (IRQ_Handler, DMA_Tx_IRQ);
47+
end Tx_IRQ_Handler;
48+
49+
-- Interrupt Handler for reception (DMA not used here).
50+
protected Rx_IRQ_Handler is
51+
pragma Interrupt_Priority;
52+
53+
entry Await_Byte_Reception (Rx_Byte : out Interfaces.Unsigned_8);
54+
55+
private
56+
57+
Byte_Avalaible : Boolean := False;
58+
Data : Interfaces.Unsigned_8;
59+
-- Rx_Queue : T_Queue (UART_RX_QUEUE_SIZE);
60+
61+
procedure IRQ_Handler;
62+
pragma Attach_Handler (IRQ_Handler, USART2_Interrupt);
63+
end Rx_IRQ_Handler;
64+
end Coms;

0 commit comments

Comments
 (0)