Skip to content

Commit 5f2ed1b

Browse files
authored
Merge pull request #41 from maxiwoj/tm/stm32f4-tune-operations
Tm/stm32f4 tune operations this closes #37
2 parents 67035d5 + 736a637 commit 5f2ed1b

File tree

4 files changed

+117
-8
lines changed

4 files changed

+117
-8
lines changed

Inc/cortexm/stm32/stm32f4.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define STM32F4_FLASH_CR_PG (1 << 0)
1414
#define STM32F4_FLASH_CR_SER (1 << 1)
1515
#define STM32F4_FLASH_CR_MER (1 << 2)
16+
#define STM32F4_FLASH_CR_SNB_SHIFT (3)
1617
#define STM32F4_FLASH_CR_PSIZE8 (0 << 8)
1718
#define STM32F4_FLASH_CR_PSIZE16 (1 << 8)
1819
#define STM32F4_FLASH_CR_PSIZE32 (2 << 8)

Inc/jtag/jtag_low_level.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
#include "stm32f4xx_it.h"
55

6-
#define TCKWAIT 10
6+
// if TCKWAIT == 0 than alternate method of delay is used.
7+
// if TCKWAIT > 0 than it represent half of TCK cycle in micro seconds
8+
#define TCKWAIT 0
79
#define SIZEOF_IN_BITS(x) (sizeof(x) * 8)
810

911
// maximum size of transfer in jtag_tdin function

Src/cortexm/stm32/stm32f4.c

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ static int stm32f4_erase_all_flash(STM32F4_PRIV_t *priv, int *progress, int prog
6161
int time = 0;
6262
int progress_step = progress_end/10;
6363

64-
printf("Erase Flash\n");
6564
/* Flash mass erase start instruction */
6665
priv->cortex->ops->write_word(priv->cortex->priv, STM32F4_FLASH_CR, STM32F4_FLASH_CR_MER);
6766
priv->cortex->ops->write_word(priv->cortex->priv, STM32F4_FLASH_CR, STM32F4_FLASH_CR_STRT | STM32F4_FLASH_CR_MER | STM32F4_FLASH_CR_EOPIE);
@@ -73,7 +72,7 @@ static int stm32f4_erase_all_flash(STM32F4_PRIV_t *priv, int *progress, int prog
7372
printf("Error while waiting for erase end\n");
7473
return STM32F4_ERASE_NEVER_END;
7574
}
76-
osDelay(1);
75+
osDelay(10);
7776
time++;
7877
// after each 100 loops add one to progress, we asume that whole erase will take 1000 loops
7978
if(time > 100) {
@@ -98,6 +97,84 @@ static int stm32f4_erase_all_flash(STM32F4_PRIV_t *priv, int *progress, int prog
9897
return 0;
9998
}
10099

100+
// This function return how many sectors is needed in bank 1 of flash
101+
// to save len bytes. If len is bigger then 7 sectors, return bigger number than number of sectors
102+
static uint8_t stm32f4_sectors_in_bank1(int len)
103+
{
104+
uint8_t sector = 0;
105+
while(len > 0) {
106+
/*
107+
* Secotr sizes from:
108+
* RM0090 -- STM32F4xx reference manual, chapter 3.3
109+
*/
110+
switch (sector) {
111+
case 0:
112+
case 1:
113+
case 2:
114+
case 3:
115+
len -= 0x4000;
116+
break;
117+
case 4:
118+
len -= 0x10000;
119+
break;
120+
case 5:
121+
case 6:
122+
case 7:
123+
len -= 0x20000;
124+
break;
125+
case 8:
126+
return 255;
127+
}
128+
sector++;
129+
}
130+
return sector;
131+
}
132+
133+
static int stm32f4_erase_flash(STM32F4_PRIV_t *priv, int len, int *progress, int progress_end)
134+
{
135+
uint16_t sr;
136+
uint32_t cr;
137+
uint8_t last_sector_to_flash = stm32f4_sectors_in_bank1(len);
138+
int progress_step = (progress_end + 31)/32;
139+
140+
printf("Erase Flash\n");
141+
// TODO: For simplicity only when writing less than 512KB optimal sector erase
142+
// algorithm is used. First 7 sectors are the same size which is independent
143+
// of single and dual bank mode and size of flash memory.
144+
if(last_sector_to_flash > 7) {
145+
return stm32f4_erase_all_flash(priv, progress, progress_end);
146+
}
147+
148+
for(uint8_t sector = 0; sector <= last_sector_to_flash; sector++) {
149+
cr = STM32F4_FLASH_CR_EOPIE | STM32F4_FLASH_CR_ERRIE | STM32F4_FLASH_CR_SER;
150+
cr |= sector << STM32F4_FLASH_CR_SNB_SHIFT;
151+
/* Flash page erase instruction */
152+
priv->cortex->ops->write_word(priv->cortex->priv, STM32F4_FLASH_CR, cr);
153+
/* write address to FMA */
154+
priv->cortex->ops->write_word(priv->cortex->priv, STM32F4_FLASH_CR, cr | STM32F4_FLASH_CR_STRT);
155+
/* Read FLASH_SR to poll for BSY bit */
156+
while(priv->cortex->ops->read_word(priv->cortex->priv, STM32F4_FLASH_SR) & STM32F4_FLASH_SR_BSY) {
157+
if(priv->cortex->ops->check_error(priv->cortex->priv)) {
158+
// TODO: handle error
159+
printf("Error while waiting for erase end\n");
160+
return STM32F4_ERASE_NEVER_END;
161+
}
162+
}
163+
*progress += progress_step;
164+
printf("Flash progress %d\n", *progress);
165+
}
166+
167+
/* Check for error */
168+
sr = priv->cortex->ops->read_word(priv->cortex->priv, STM32F4_FLASH_SR);
169+
if ((sr & STM32F4_SR_ERROR_MASK) || !(sr & STM32F4_SR_EOP)) {
170+
// TODO: handle error
171+
printf("Error after erase 0x%x\n", sr);
172+
return sr | STM32F4_ERASE_ERROR_BIT;
173+
}
174+
175+
return 0;
176+
}
177+
101178
static int stm32f4_flash_write(STM32F4_PRIV_t *priv, uint32_t dest, const uint32_t *src, int len)
102179
{
103180
uint32_t start_of_ram = 0x20000000;
@@ -144,22 +221,25 @@ static int stm32f4_program(void *priv_void, FIL *file, int *progress)
144221
uint32_t *data = pvPortMalloc(STM32F4_SIZE_OF_ONE_WRITE/sizeof(uint32_t));
145222
STM32F4_PRIV_t *priv = priv_void;
146223
uint16_t result;
224+
uint32_t file_len = f_size(file);
147225

148226
// these variables are only needed to show progress
149-
int number_of_writes = (f_size(file) + STM32F4_SIZE_OF_ONE_WRITE - 1)/STM32F4_SIZE_OF_ONE_WRITE + STM32F4_ERASE_TIME_IN_WRITES;
150-
float progress_as_float = 100 * STM32F4_ERASE_TIME_IN_WRITES/number_of_writes;
151-
float progress_on_one_write = 100.0/number_of_writes;
227+
int number_of_writes = (file_len + STM32F4_SIZE_OF_ONE_WRITE - 1)/STM32F4_SIZE_OF_ONE_WRITE;
228+
float progress_as_float = 100 * STM32F4_ERASE_TIME_IN_WRITES/(number_of_writes + STM32F4_ERASE_TIME_IN_WRITES);
229+
float progress_on_one_write;
152230

153231
printf("Start flashing STM32F4x\n");
154232

155233
priv->cortex->ops->halt_request(priv->cortex->priv);
156234
stm32f4_flash_unlock(priv);
157-
result = stm32f4_erase_all_flash(priv, progress, progress_as_float);
235+
result = stm32f4_erase_flash(priv, file_len, progress, progress_as_float);
158236
if(result) {
159237
vPortFree(data);
160238
return result;
161239
}
162240

241+
progress_as_float = *progress;
242+
progress_on_one_write = (100 - *progress)/number_of_writes;
163243

164244
do {
165245
f_read(file, data, STM32F4_SIZE_OF_ONE_WRITE, &br);

Src/jtag/jtag_low_level.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
#include "jtag/jtag_low_level.h"
66

77
uint32_t getUs(void) {
8-
uint32_t usTicks = HAL_RCC_GetSysClockFreq() / 1000000;
8+
static uint32_t usTicks = 0;
9+
if (usTicks == 0) {
10+
usTicks = HAL_RCC_GetSysClockFreq() / 1000000;
11+
}
912
register uint32_t ms, cycle_cnt;
1013
do {
1114
ms = HAL_GetTick();
@@ -23,15 +26,38 @@ void delayUs(uint16_t micros)
2326
}
2427
}
2528

29+
#if TCKWAIT == 0
30+
// current implementation of JTAG low level routines allow us to get ~1MHz if there
31+
// is no additional delay.
32+
static inline void short_delay(){
33+
asm("nop");
34+
asm("nop");
35+
asm("nop");
36+
asm("nop");
37+
asm("nop");
38+
asm("nop");
39+
asm("nop");
40+
asm("nop");
41+
}
42+
#endif
43+
2644
void jtag_tclk_up()
2745
{
46+
#if TCKWAIT == 0
47+
short_delay();
48+
#else
2849
delayUs(TCKWAIT);
50+
#endif
2951
HAL_GPIO_WritePin(JTAG_TCLK_GPIO_Port, JTAG_TCLK_Pin, GPIO_PIN_SET);
3052
}
3153

3254
void jtag_tclk_down()
3355
{
56+
#if TCKWAIT == 0
57+
short_delay();
58+
#else
3459
delayUs(TCKWAIT);
60+
#endif
3561
HAL_GPIO_WritePin(JTAG_TCLK_GPIO_Port, JTAG_TCLK_Pin, GPIO_PIN_RESET);
3662
}
3763

0 commit comments

Comments
 (0)