Skip to content

Commit 86d8e3f

Browse files
committed
Add CRC unit for STM32F7x MCUs
1 parent 68b8aa9 commit 86d8e3f

File tree

9 files changed

+568
-4
lines changed

9 files changed

+568
-4
lines changed

arch/ARM/STM32/devices/stm32f7x/stm32-device.adb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
------------------------------------------------------------------------------
22
-- --
3-
-- Copyright (C) 2015-2016, AdaCore --
3+
-- Copyright (C) 2015-2026, AdaCore --
44
-- --
55
-- Redistribution and use in source and binary forms, with or without --
66
-- modification, are permitted provided that the following conditions are --
@@ -1089,4 +1089,14 @@ package body STM32.Device is
10891089
RCC_Periph.AHB1RSTR.ETHMACRST := False;
10901090
end Reset_Eth;
10911091

1092+
------------------
1093+
-- Enable_Clock --
1094+
------------------
1095+
1096+
procedure Enable_Clock (This : in out CRC_32) is
1097+
pragma Unreferenced (This);
1098+
begin
1099+
RCC_Periph.AHB1ENR.CRCEN := True;
1100+
end Enable_Clock;
1101+
10921102
end STM32.Device;

arch/ARM/STM32/devices/stm32f7x/stm32-device.ads

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
------------------------------------------------------------------------------
22
-- --
3-
-- Copyright (C) 2015-2018, AdaCore --
3+
-- Copyright (C) 2015-2026, AdaCore --
44
-- --
55
-- Redistribution and use in source and binary forms, with or without --
66
-- modification, are permitted provided that the following conditions are --
@@ -39,8 +39,8 @@
3939
-- COPYRIGHT(c) 2014 STMicroelectronics --
4040
------------------------------------------------------------------------------
4141

42-
-- This file provides declarations for devices on the STM32F42xxx MCUs
43-
-- manufactured by ST Microelectronics. For example, an STM32F429.
42+
-- This file provides declarations for devices on the STM32F7x MCUs
43+
-- manufactured by ST Microelectronics. For example, an STM32F746.
4444

4545
private with ADL_Config;
4646

@@ -60,6 +60,7 @@ with STM32.SPI.DMA; use STM32.SPI.DMA;
6060
with STM32.I2S; use STM32.I2S;
6161
with STM32.Timers; use STM32.Timers;
6262
with STM32.RTC; use STM32.RTC;
63+
with STM32.CRC; use STM32.CRC;
6364

6465
package STM32.Device is
6566
pragma Elaborate_Body;
@@ -542,6 +543,14 @@ package STM32.Device is
542543
procedure Reset (This : in out SAI_Port);
543544
function Get_Input_Clock (Periph : SAI_Port) return UInt32;
544545

546+
---------
547+
-- CRC --
548+
---------
549+
550+
CRC_Unit : CRC_32 with Volatile, Address => STM32_SVD.CRC_Base, Import;
551+
552+
procedure Enable_Clock (This : in out CRC_32);
553+
545554
-----------
546555
-- SDMMC --
547556
-----------
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The CRC unit on the F7 devices (and others) has the additional ability
2+
to define the initial value and the polynomial value, but the same core
3+
capabilities of the F4 are present.
4+
5+
TODO: enhance these source files to add the extra functionality of the F7x
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
------------------------------------------------------------------------------
2+
-- --
3+
-- Copyright (C) 2017, AdaCore --
4+
-- --
5+
-- Redistribution and use in source and binary forms, with or without --
6+
-- modification, are permitted provided that the following conditions are --
7+
-- met: --
8+
-- 1. Redistributions of source code must retain the above copyright --
9+
-- notice, this list of conditions and the following disclaimer. --
10+
-- 2. Redistributions in binary form must reproduce the above copyright --
11+
-- notice, this list of conditions and the following disclaimer in --
12+
-- the documentation and/or other materials provided with the --
13+
-- distribution. --
14+
-- 3. Neither the name of the copyright holder nor the names of its --
15+
-- contributors may be used to endorse or promote products derived --
16+
-- from this software without specific prior written permission. --
17+
-- --
18+
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --
19+
-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --
20+
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR --
21+
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT --
22+
-- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, --
23+
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT --
24+
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, --
25+
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY --
26+
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
27+
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE --
28+
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --
29+
-- --
30+
------------------------------------------------------------------------------
31+
32+
with STM32.Device; use STM32.Device;
33+
34+
package body STM32.CRC.DMA is
35+
36+
procedure Configure_DMA
37+
(Controller : access DMA_Controller;
38+
Stream : DMA_Stream_Selector;
39+
Data_Width : DMA_Data_Transfer_Widths);
40+
-- Configures the DMA controller and stream for transfering memory blocks,
41+
-- of the width specified, to the CRC processor.
42+
43+
---------------------------
44+
-- Transfer_Input_To_CRC --
45+
---------------------------
46+
47+
procedure Transfer_Input_To_CRC
48+
(This : in out CRC_32;
49+
Controller : access DMA_Controller;
50+
Stream : DMA_Stream_Selector;
51+
Input_Address : System.Address;
52+
Input_Length : UInt16;
53+
Data_Width : DMA_Data_Transfer_Widths)
54+
is
55+
begin
56+
Configure_DMA (Controller, Stream, Data_Width);
57+
-- We configure the unit each time to ensure the data width is right.
58+
59+
Clear_All_Status (Controller.all, Stream);
60+
-- Ensure previous calls or other use hasn't set any status flags.
61+
62+
Start_Transfer_with_Interrupts
63+
(Controller.all,
64+
Stream,
65+
Source => Input_Address,
66+
Destination => This.DR'Address,
67+
Data_Count => Input_Length,
68+
Enabled_Interrupts => (Transfer_Complete_Interrupt => True,
69+
others => False));
70+
end Transfer_Input_To_CRC;
71+
72+
----------------
73+
-- Update_CRC --
74+
----------------
75+
76+
procedure Update_CRC
77+
(This : in out CRC_32;
78+
Controller : access DMA_Controller;
79+
Stream : DMA_Stream_Selector;
80+
Input : Block_32) is
81+
begin
82+
Transfer_Input_To_CRC
83+
(This,
84+
Controller,
85+
Stream,
86+
Input'Address,
87+
Input'Length,
88+
Data_Width => Words);
89+
end Update_CRC;
90+
91+
----------------
92+
-- Update_CRC --
93+
----------------
94+
95+
procedure Update_CRC
96+
(This : in out CRC_32;
97+
Controller : access DMA_Controller;
98+
Stream : DMA_Stream_Selector;
99+
Input : Block_16) is
100+
begin
101+
Transfer_Input_To_CRC
102+
(This,
103+
Controller,
104+
Stream,
105+
Input'Address,
106+
Input'Length,
107+
Data_Width => HalfWords);
108+
end Update_CRC;
109+
110+
----------------
111+
-- Update_CRC --
112+
----------------
113+
114+
procedure Update_CRC
115+
(This : in out CRC_32;
116+
Controller : access DMA_Controller;
117+
Stream : DMA_Stream_Selector;
118+
Input : Block_8) is
119+
begin
120+
Transfer_Input_To_CRC
121+
(This,
122+
Controller,
123+
Stream,
124+
Input'Address,
125+
Input'Length,
126+
Data_Width => Bytes);
127+
end Update_CRC;
128+
129+
-------------------
130+
-- Configure_DMA --
131+
-------------------
132+
133+
procedure Configure_DMA
134+
(Controller : access DMA_Controller;
135+
Stream : DMA_Stream_Selector;
136+
Data_Width : DMA_Data_Transfer_Widths)
137+
is
138+
Config : DMA_Stream_Configuration;
139+
begin
140+
-- See app note AN4187 Table 3 for this configuration (other than the
141+
-- channel number). It works, although it looks counterintuitive.
142+
143+
Config.Channel := Channel_0; -- arbitrary
144+
Config.Direction := Memory_To_Memory;
145+
Config.Memory_Data_Format := Data_Width;
146+
Config.Peripheral_Data_Format := Words;
147+
Config.Increment_Peripheral_Address := True;
148+
Config.Increment_Memory_Address := False;
149+
Config.Operation_Mode := Normal_Mode;
150+
Config.Priority := Priority_Very_High;
151+
Config.FIFO_Enabled := False;
152+
Config.Memory_Burst_Size := Memory_Burst_Single;
153+
Config.Peripheral_Burst_Size := Peripheral_Burst_Single;
154+
155+
Configure (Controller.all, Stream, Config);
156+
end Configure_DMA;
157+
158+
end STM32.CRC.DMA;
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
------------------------------------------------------------------------------
2+
-- --
3+
-- Copyright (C) 2017, AdaCore --
4+
-- --
5+
-- Redistribution and use in source and binary forms, with or without --
6+
-- modification, are permitted provided that the following conditions are --
7+
-- met: --
8+
-- 1. Redistributions of source code must retain the above copyright --
9+
-- notice, this list of conditions and the following disclaimer. --
10+
-- 2. Redistributions in binary form must reproduce the above copyright --
11+
-- notice, this list of conditions and the following disclaimer in --
12+
-- the documentation and/or other materials provided with the --
13+
-- distribution. --
14+
-- 3. Neither the name of the copyright holder nor the names of its --
15+
-- contributors may be used to endorse or promote products derived --
16+
-- from this software without specific prior written permission. --
17+
-- --
18+
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --
19+
-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --
20+
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR --
21+
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT --
22+
-- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, --
23+
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT --
24+
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, --
25+
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY --
26+
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
27+
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE --
28+
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --
29+
-- --
30+
------------------------------------------------------------------------------
31+
32+
-- A driver for the Cyclic Redundancy Check CRC-32 calculation processor,
33+
-- using DMA to transfer the data to the CRC unit (instead of the CPU).
34+
35+
-- Note this API is for the STM32 F4x family. Other STM MCUs have additional
36+
-- CRC capabilities.
37+
38+
-- See also app note AN4187 "Using CRC through DMA"
39+
40+
-- Example usage, assuming prior clock enabling for the CRC unit:
41+
42+
-- Checksum_DMA : UInt32 := 0;
43+
--
44+
-- Data : constant Block_32 := ( .... );
45+
--
46+
-- ...
47+
--
48+
-- Enable_Clock (Controller);
49+
--
50+
-- Reset (Controller);
51+
--
52+
-- Reset_Calculator (CRC_Unit); -- if need be
53+
--
54+
-- Update_CRC (CRC_Unit, Controller'Access, Stream, Input => Data);
55+
--
56+
-- DMA_IRQ_Handler.Await_Event (Next_DMA_Interrupt);
57+
--
58+
-- if Next_DMA_Interrupt /= Transfer_Complete_Interrupt then
59+
-- Panic;
60+
-- end if;
61+
--
62+
-- Checksum_DMA := Value (CRC_Unit);
63+
64+
with STM32.DMA; use STM32.DMA;
65+
with System;
66+
67+
package STM32.CRC.DMA is
68+
pragma Elaborate_Body;
69+
70+
-- These routines use the specified controller and stream to transfer
71+
-- all of the Input data components to This CRC unit, updating the
72+
-- CRC value accordingly. At the end of the transfer the DMA interrupt
73+
-- Transfer_Complete_Interrupt is triggered. Clients are expected to have
74+
-- an application-defined handler for that interrupt, in order to await
75+
-- completion of the transfer.
76+
77+
-- These routines can be called multiple times, back-to-back, presumably
78+
-- with different input blocks, in order to update the value of the
79+
-- calculated CRC checksum within the CRC processor. Each call will
80+
-- result in a Transfer_Complete_Interrupt event.
81+
82+
-- Note that you can use a slice if the entire block is not intended for
83+
-- transfer, but beware alignment boundaries to prevent copying of the
84+
-- actual parameter into a temporary.
85+
86+
procedure Update_CRC
87+
(This : in out CRC_32;
88+
Controller : access DMA_Controller;
89+
Stream : DMA_Stream_Selector;
90+
Input : Block_32);
91+
-- Update the calculated CRC value based on all of the 32-bit components
92+
-- of Input. Triggers the Transfer_Complete_Interrupt on completion.
93+
94+
procedure Update_CRC
95+
(This : in out CRC_32;
96+
Controller : access DMA_Controller;
97+
Stream : DMA_Stream_Selector;
98+
Input : Block_16);
99+
-- Update the calculated CRC value based on all of the 16-bit components
100+
-- of Input. Triggers the Transfer_Complete_Interrupt on completion.
101+
102+
procedure Update_CRC
103+
(This : in out CRC_32;
104+
Controller : access DMA_Controller;
105+
Stream : DMA_Stream_Selector;
106+
Input : Block_8);
107+
-- Update the calculated CRC value based on all of the 8-bit components
108+
-- of Input. Triggers the Transfer_Complete_Interrupt on completion.
109+
110+
private
111+
112+
procedure Transfer_Input_To_CRC
113+
(This : in out CRC_32;
114+
Controller : access DMA_Controller;
115+
Stream : DMA_Stream_Selector;
116+
Input_Address : System.Address;
117+
Input_Length : UInt16;
118+
Data_Width : DMA_Data_Transfer_Widths);
119+
-- Configures the DMA controller and stream for transfering memory blocks,
120+
-- of the width specified by Data_Width, to This CRC processor. Then uses
121+
-- the controller and stream to transfer the data starting at Input_Address
122+
-- to This CRC unit, updating the CRC value accordingly. The number of
123+
-- Input memory items (of Data_Width size) to be transferred is specified
124+
-- by Input_Length. At the end of the transfer the DMA interrupt
125+
-- Transfer_Complete_Interrupt is triggered.
126+
127+
end STM32.CRC.DMA;

0 commit comments

Comments
 (0)