Skip to content

Commit 7b11671

Browse files
authored
Enable CRC, FLASHIAP and CAN for STM32H5 (#471)
* enable CRC, Flash and CAN for STM32H5 * remove unneeded alignment check and comments
1 parent 8ac2744 commit 7b11671

File tree

4 files changed

+272
-6
lines changed

4 files changed

+272
-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: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
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+
23+
/**
24+
* @brief Gets the bank of a given address
25+
* @param Addr: Address of the FLASH Memory
26+
* @retval The bank of a given address
27+
*/
28+
static uint32_t GetBank(uint32_t Addr)
29+
{
30+
uint32_t bank = 0;
31+
32+
if (Addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
33+
bank = FLASH_BANK_1;
34+
} else {
35+
bank = FLASH_BANK_2;
36+
}
37+
38+
return bank;
39+
}
40+
41+
/**
42+
* @brief Gets the sector of a given address
43+
* @param Address: Flash address
44+
* @retval The sector of a given address
45+
*/
46+
static uint32_t GetSector(uint32_t Address)
47+
{
48+
uint32_t sector = 0;
49+
50+
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) {
51+
sector = (Address - FLASH_BASE) / FLASH_SECTOR_SIZE;
52+
} else {
53+
sector = (Address - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_SECTOR_SIZE;
54+
}
55+
56+
return sector;
57+
}
58+
59+
/** Initialize the flash peripheral and the flash_t object
60+
*
61+
* @param obj The flash object
62+
* @return 0 for success, -1 for error
63+
*/
64+
int32_t flash_init(flash_t *obj)
65+
{
66+
return 0;
67+
}
68+
69+
/** Uninitialize the flash peripheral and the flash_t object
70+
*
71+
* @param obj The flash object
72+
* @return 0 for success, -1 for error
73+
*/
74+
int32_t flash_free(flash_t *obj)
75+
{
76+
return 0;
77+
}
78+
79+
/** Erase one sector starting at defined address
80+
*
81+
* The address should be at sector boundary. This function does not do any check for address alignments
82+
* @param obj The flash object
83+
* @param address The sector starting address
84+
* @return 0 for success, -1 for error
85+
*/
86+
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
87+
{
88+
uint32_t PAGEError = 0;
89+
FLASH_EraseInitTypeDef EraseInitStruct;
90+
int32_t status = 0;
91+
92+
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
93+
return -1;
94+
}
95+
96+
if (HAL_FLASH_Unlock() != HAL_OK) {
97+
return -1;
98+
}
99+
100+
if (HAL_ICACHE_Disable() != HAL_OK)
101+
{
102+
return -1;
103+
}
104+
105+
core_util_critical_section_enter();
106+
107+
/* Clear error programming flags */
108+
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
109+
110+
/* MBED HAL erases 1 page / sector at a time */
111+
/* Fill EraseInit structure*/
112+
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
113+
EraseInitStruct.Banks = GetBank(address);
114+
EraseInitStruct.Sector = GetSector(address);
115+
EraseInitStruct.NbSectors = 1;
116+
117+
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
118+
status = -1;
119+
}
120+
121+
core_util_critical_section_exit();
122+
123+
if (HAL_ICACHE_Enable() != HAL_OK)
124+
{
125+
return -1;
126+
}
127+
128+
if (HAL_FLASH_Lock() != HAL_OK) {
129+
return -1;
130+
}
131+
132+
return status;
133+
}
134+
135+
/** Program one page starting at defined address
136+
*
137+
* The page should be at page boundary, should not cross multiple sectors.
138+
* This function does not do any check for address alignments or if size
139+
* is aligned to a page size.
140+
* @param obj The flash object
141+
* @param address The sector starting address
142+
* @param data The data buffer to be programmed
143+
* @param size The number of bytes to program
144+
* @return 0 for success, -1 for error
145+
*/
146+
int32_t flash_program_page(flash_t *obj, uint32_t address,
147+
const uint8_t *data, uint32_t size)
148+
{
149+
uint32_t StartAddress = 0;
150+
int32_t status = 0;
151+
152+
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
153+
return -1;
154+
}
155+
156+
if ((size % 16) != 0) {
157+
/* H5 flash devices can only be programmed 128bits/16 bytes at a time */
158+
return -1;
159+
}
160+
161+
if (HAL_FLASH_Unlock() != HAL_OK) {
162+
return -1;
163+
}
164+
165+
if (HAL_ICACHE_Disable() != HAL_OK)
166+
{
167+
return -1;
168+
}
169+
170+
/* Clear error programming flags */
171+
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
172+
173+
/* Program the user Flash area word by word */
174+
StartAddress = address;
175+
176+
while ((address < (StartAddress + size)) && (status == 0)) {
177+
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, address,
178+
(uint32_t) data)
179+
== HAL_OK) {
180+
address = address + 16;
181+
data = data + 16;
182+
} else {
183+
status = -1;
184+
}
185+
}
186+
187+
if (HAL_ICACHE_Enable() != HAL_OK)
188+
{
189+
return -1;
190+
}
191+
192+
if (HAL_FLASH_Lock() != HAL_OK) {
193+
return -1;
194+
}
195+
196+
return status;
197+
}
198+
199+
/** Get sector size
200+
*
201+
* @param obj The flash object
202+
* @param address The sector starting address
203+
* @return The size of a sector
204+
*/
205+
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
206+
{
207+
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
208+
return MBED_FLASH_INVALID_SIZE;
209+
}
210+
return (FLASH_SECTOR_SIZE);
211+
}
212+
213+
/** Get page size
214+
*
215+
* @param obj The flash object
216+
* @param address The page starting address
217+
* @return The size of a page
218+
*/
219+
uint32_t flash_get_page_size(const flash_t *obj)
220+
{
221+
/* Page size is the minimum programable size, which 16 bytes */
222+
return 16;
223+
}
224+
225+
/** Get start address for the flash region
226+
*
227+
* @param obj The flash object
228+
* @return The start address for the flash region
229+
*/
230+
uint32_t flash_get_start_address(const flash_t *obj)
231+
{
232+
return FLASH_BASE;
233+
}
234+
235+
/** Get the flash region size
236+
*
237+
* @param obj The flash object
238+
* @return The flash region size
239+
*/
240+
uint32_t flash_get_size(const flash_t *obj)
241+
{
242+
return FLASH_SIZE;
243+
}
244+
245+
uint8_t flash_get_erase_value(const flash_t *obj)
246+
{
247+
(void)obj;
248+
249+
return 0xFF;
250+
}
251+
252+
#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)