Skip to content

Commit d54515f

Browse files
committed
enable CRC, Flash and CAN for STM32H5
1 parent 8ac2744 commit d54515f

File tree

4 files changed

+297
-6
lines changed

4 files changed

+297
-6
lines changed

targets/TARGET_STM/TARGET_STM32H5/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ target_sources(mbed-stm32h5
1818
spi_api.c
1919
pwmout_device.c
2020
cache.c
21+
flash_api.c
2122
)
2223

2324
target_include_directories(mbed-stm32h5
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
/* mbed Microcontroller Library
2+
* SPDX-License-Identifier: BSD-3-Clause
3+
******************************************************************************
4+
*
5+
* Copyright (c) 2015-2020 STMicroelectronics.
6+
* All rights reserved.
7+
*
8+
* This software component is licensed by ST under BSD 3-Clause license,
9+
* the "License"; You may not use this file except in compliance with the
10+
* License. You may obtain a copy of the License at:
11+
* opensource.org/licenses/BSD-3-Clause
12+
*
13+
******************************************************************************
14+
*/
15+
16+
#include "flash_api.h"
17+
#include "platform/mbed_critical.h"
18+
19+
#if DEVICE_FLASH
20+
#include "mbed_assert.h"
21+
#include "cmsis.h"
22+
#include "stdio.h"
23+
24+
/**
25+
* @brief Gets the bank of a given address
26+
* @param Addr: Address of the FLASH Memory
27+
* @retval The bank of a given address
28+
*/
29+
static uint32_t GetBank(uint32_t Addr)
30+
{
31+
uint32_t bank = 0;
32+
33+
if (Addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
34+
bank = FLASH_BANK_1;
35+
} else {
36+
bank = FLASH_BANK_2;
37+
}
38+
39+
return bank;
40+
}
41+
42+
/**
43+
* @brief Gets the sector of a given address
44+
* @param Address: Flash address
45+
* @retval The sector of a given address
46+
*/
47+
static uint32_t GetSector(uint32_t Address)
48+
{
49+
uint32_t sector = 0;
50+
51+
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) {
52+
sector = (Address - FLASH_BASE) / FLASH_SECTOR_SIZE;
53+
} else {
54+
sector = (Address - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_SECTOR_SIZE;
55+
}
56+
57+
return sector;
58+
}
59+
60+
/** Initialize the flash peripheral and the flash_t object
61+
*
62+
* @param obj The flash object
63+
* @return 0 for success, -1 for error
64+
*/
65+
int32_t flash_init(flash_t *obj)
66+
{
67+
return 0;
68+
}
69+
70+
/** Uninitialize the flash peripheral and the flash_t object
71+
*
72+
* @param obj The flash object
73+
* @return 0 for success, -1 for error
74+
*/
75+
int32_t flash_free(flash_t *obj)
76+
{
77+
return 0;
78+
}
79+
80+
/** Erase one sector starting at defined address
81+
*
82+
* The address should be at sector boundary. This function does not do any check for address alignments
83+
* @param obj The flash object
84+
* @param address The sector starting address
85+
* @return 0 for success, -1 for error
86+
*/
87+
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
88+
{
89+
uint32_t PAGEError = 0;
90+
FLASH_EraseInitTypeDef EraseInitStruct;
91+
int32_t status = 0;
92+
93+
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
94+
return -1;
95+
}
96+
97+
if (HAL_ICACHE_Disable() != HAL_OK)
98+
{
99+
return -1;
100+
}
101+
102+
if (HAL_FLASH_Unlock() != HAL_OK) {
103+
return -1;
104+
}
105+
106+
core_util_critical_section_enter();
107+
108+
/* Clear error programming flags */
109+
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
110+
111+
/* MBED HAL erases 1 page / sector at a time */
112+
/* Fill EraseInit structure*/
113+
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
114+
EraseInitStruct.Banks = GetBank(address);
115+
EraseInitStruct.Sector = GetSector(address);
116+
EraseInitStruct.NbSectors = 1;
117+
118+
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
119+
you have to make sure that these data are rewritten before they are accessed during code
120+
execution. If this cannot be done safely, it is recommended to flush the caches by setting the
121+
DCRST and ICRST bits in the FLASH_CR register. */
122+
123+
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
124+
status = -1;
125+
}
126+
127+
core_util_critical_section_exit();
128+
129+
if (HAL_FLASH_Lock() != HAL_OK) {
130+
return -1;
131+
}
132+
133+
if (HAL_ICACHE_Enable() != HAL_OK)
134+
{
135+
return -1;
136+
}
137+
138+
return status;
139+
}
140+
141+
/** Program one page starting at defined address
142+
*
143+
* The page should be at page boundary, should not cross multiple sectors.
144+
* This function does not do any check for address alignments or if size
145+
* is aligned to a page size.
146+
* @param obj The flash object
147+
* @param address The sector starting address
148+
* @param data The data buffer to be programmed
149+
* @param size The number of bytes to program
150+
* @return 0 for success, -1 for error
151+
*/
152+
int32_t flash_program_page(flash_t *obj, uint32_t address,
153+
const uint8_t *data, uint32_t size)
154+
{
155+
uint32_t StartAddress = 0;
156+
int32_t status = 0;
157+
158+
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
159+
return -1;
160+
}
161+
162+
if ((size % 16) != 0) {
163+
/* H5 flash devices can only be programmed 128bits/16 bytes at a time */
164+
return -1;
165+
}
166+
167+
if (HAL_ICACHE_Disable() != HAL_OK)
168+
{
169+
return -1;
170+
}
171+
172+
if (HAL_FLASH_Unlock() != HAL_OK) {
173+
return -1;
174+
}
175+
176+
/* Clear error programming flags */
177+
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
178+
179+
/* Program the user Flash area word by word */
180+
StartAddress = address;
181+
182+
/* HW needs an aligned address to program flash, which data
183+
* parameters doesn't ensure */
184+
if ((uint32_t) data % 16 != 0) {
185+
volatile uint64_t data128[2];
186+
while ((address < (StartAddress + size)) && (status == 0)) {
187+
for (uint8_t i = 0; i < 16; i++) {
188+
*(((uint8_t *) data128) + i) = *(data + i);
189+
}
190+
191+
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, address, (uint32_t) data128)
192+
== HAL_OK) {
193+
address = address + 16;
194+
data = data + 16;
195+
} else {
196+
status = -1;
197+
}
198+
}
199+
} else { /* case where data is aligned, so let's avoid any copy */
200+
while ((address < (StartAddress + size)) && (status == 0)) {
201+
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, address,
202+
(uint32_t) data)
203+
== HAL_OK) {
204+
address = address + 16;
205+
data = data + 16;
206+
} else {
207+
status = -1;
208+
}
209+
}
210+
}
211+
212+
if (HAL_FLASH_Lock() != HAL_OK) {
213+
return -1;
214+
}
215+
216+
if (HAL_ICACHE_Enable() != HAL_OK)
217+
{
218+
return -1;
219+
}
220+
221+
return status;
222+
}
223+
224+
/** Get sector size
225+
*
226+
* @param obj The flash object
227+
* @param address The sector starting address
228+
* @return The size of a sector
229+
*/
230+
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
231+
{
232+
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
233+
return MBED_FLASH_INVALID_SIZE;
234+
}
235+
return (FLASH_SECTOR_SIZE);
236+
}
237+
238+
/** Get page size
239+
*
240+
* @param obj The flash object
241+
* @param address The page starting address
242+
* @return The size of a page
243+
*/
244+
uint32_t flash_get_page_size(const flash_t *obj)
245+
{
246+
/* Page size is the minimum programable size, which 16 bytes */
247+
return 16;
248+
}
249+
250+
/** Get start address for the flash region
251+
*
252+
* @param obj The flash object
253+
* @return The start address for the flash region
254+
*/
255+
uint32_t flash_get_start_address(const flash_t *obj)
256+
{
257+
return FLASH_BASE;
258+
}
259+
260+
/** Get the flash region size
261+
*
262+
* @param obj The flash object
263+
* @return The flash region size
264+
*/
265+
uint32_t flash_get_size(const flash_t *obj)
266+
{
267+
return FLASH_SIZE;
268+
}
269+
270+
uint8_t flash_get_erase_value(const flash_t *obj)
271+
{
272+
(void)obj;
273+
274+
return 0xFF;
275+
}
276+
277+
#endif

targets/TARGET_STM/can_api.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,22 @@ static void _can_init_freq_direct(can_t *obj, const can_pinmap_t *pinmap, int hz
9898
return;
9999
}
100100

101+
/* Store frequency to be restored in case of reset */
102+
obj->hz = hz;
103+
101104
// Select PLL1Q as source of FDCAN clock
102105
RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
103106
#if (defined RCC_PERIPHCLK_FDCAN1)
104107
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN1;
105108
RCC_PeriphClkInit.Fdcan1ClockSelection = RCC_FDCAN1CLKSOURCE_PLL1;
106109
#else
107110
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
111+
#if (defined RCC_FDCANCLKSOURCE_PLL1Q)
112+
RCC_PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL1Q;
113+
#else
108114
RCC_PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL;
109115
#endif
116+
#endif
110117
#if defined(DUAL_CORE) && (TARGET_STM32H7)
111118
while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) {
112119
}
@@ -418,7 +425,10 @@ int can_write(can_t *obj, CAN_Message msg, int cc)
418425
}
419426

420427
TxHeader.TxFrameType = FDCAN_DATA_FRAME;
421-
TxHeader.DataLength = msg.len << 16;
428+
TxHeader.DataLength = msg.len;
429+
#if defined(TARGET_STM32L5) || defined(TARGET_STM32G0) || defined(TARGET_STM32G4)
430+
TxHeader.DataLength <<= 16;
431+
#endif
422432
TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
423433
TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
424434
TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
@@ -454,8 +464,10 @@ int can_read(can_t *obj, CAN_Message *msg, int handle)
454464
}
455465
msg->id = RxHeader.Identifier;
456466
msg->type = (RxHeader.RxFrameType == FDCAN_DATA_FRAME) ? CANData : CANRemote;
457-
msg->len = RxHeader.DataLength >> 16; // see FDCAN_data_length_code value
458-
467+
msg->len = RxHeader.DataLength;
468+
#if defined(TARGET_STM32L5) || defined(TARGET_STM32G0) || defined(TARGET_STM32G4)
469+
msg->len >>= 16;
470+
#endif
459471
return 1;
460472
}
461473

targets/targets.json5

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3105,12 +3105,13 @@ mode is recommended for target MCUs with small amounts of flash and RAM.",
31053105
"MPU",
31063106
"ANALOGOUT",
31073107
"SPI_32BIT_WORDS",
3108-
"TRNG"
3108+
"TRNG",
3109+
"FLASH",
3110+
"CAN",
3111+
"CRC"
31093112
],
31103113
"device_has_remove": [
3111-
"FLASH",
31123114
"LPTICKER",
3113-
"CAN",
31143115
"SERIAL_FC"
31153116
],
31163117
"is_mcu_family_target": true

0 commit comments

Comments
 (0)