Перейти к содержанию
    

STM32 – вопросы – проблемы - решения.

Из errat-ы про flash

"Read the BSY bit at least one cycle after setting the STRT bit."

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это из ераты для 101 семейства?

У меня stm32f103cb.

Но тем не менее попробовал поставить несколько nop() после установки START бита - не дало никакого эффекта.

Спасибо за идею почитать ерату!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это ерата на 101C/D/E и 103C/D/E ревижн Z, старая правда - 2009 год.

Посмотрел свою функцию стирания - почти тоже самое, только включение режима стирания делается так

FLASH->CR |= CR_PER_Set;

соответственно, после опускания бита Busy стоит

FLASH->CR &= ~CR_PER_Set;

 

Помню похожие грабли, но вроде бы они решились втыканием нопов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот работающие куски. По крайней мере я несколько раз всё стёр, и зашил и считал тестовые данные:)

template<typename props>
void stm32_flash_t<props>::wait()
{
while (FLASH->SR & FLASH_SR_BSY) ;
}

template<typename props>
void stm32_flash_t<props>::delay()
{
for (volatile int i = 0; i < 0xFF; i++) ;
}

template<typename props>
bool stm32_flash_t<props>::wait(uint32_t timeout)
{
while (FLASH->SR & FLASH_SR_BSY)
{
	if (!--timeout)
		return false;
	delay();
}
return true;
}

template<typename props>
bool stm32_flash_t<props>::write_halfword(uint32_t addr, uint32_t data)
{
TCritSect cs;
volatile uint16_t* addr_16 = reinterpret_cast<volatile uint16_t*>(addr);

uint32_t cr = FLASH->CR;
FLASH->CR = FLASH_CR_PG;
wait();
addr_16[0] = data;
wait();
FLASH->CR = cr & ~FLASH_CR_PG;
return (*(uint16_t*)addr == data);
}

template<typename props>
bool stm32_flash_t<props>::write(uint32_t addr, void* buf, uint32_t count)
{
uint8_t* src = static_cast<uint8_t*>(buf);
uint32_t end = addr + count;

while (addr < end)
{
	uint32_t w = 0xFFFFFFFF;
	if ((uint32_t)addr & 1)	// odd flash address - step back
		--addr;
	else
		w = 0xFFFFFF00 | (*src++);
	if (addr < end)
		w = (w & 0xFFFF00FF) | (*src++ << 8);

	if (!write_halfword(addr, w))
		return false;
	addr += 2;
}
return true;
}

template<typename props>
bool stm32_flash_t<props>::erase_page(uint32_t addr)
{
TCritSect cs;
wait();
FLASH->CR |= FLASH_CR_PER;
FLASH->AR = addr;
FLASH->CR |= FLASH_CR_STRT;
return wait(PAGE_ERASE_TIMEOUT);
}

template<typename props>
bool stm32_flash_t<props>::mass_erase()
{
TCritSect cs;
wait();
FLASH->CR |= FLASH_CR_MER;
FLASH->CR |= FLASH_CR_STRT;
return wait(MASS_ERASE_TIMEOUT);
}

 

Что касается тактирования - я ничего специально не включал и не отключал, работал от HSE. (Инициализацию можно посмотреть вот здесь)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что касается тактирования - я ничего специально не включал и не отключал, работал от HSE.

 

Не помню точно в какой ветке, но я где-то на форуме читал обсуждения, якобы STM32 можно просто «убить» при едино разовом не корректном обращении с flash, камень потом перестает программироваться, читаться и т.п. В чем там прикол? Или просто слухи?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я тоже это читал. К сожалению, точные причины/алгоритм "убиения" там не были описаны, так что пока считаю на уровне слухов.

Кстати, в примере от ST (AN2557 - "in-application programming using the USART") тактирование также производится от HSE.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

УРААА!!!! Заработала хреновина!

Я слопушил - адрес страницы для стирания это адрес её первого байта а не порядковый номер страницы как я подумал.

Получалось что моя программа сама себя затирала. Вот такой вот заскок мозга случился.

Всем большущее спасибо за участие! :cheers:

 

Извлёк урок: Чтобы такого геморроя с отладкой не было нужно сразу ставить защиту от стирания на область прошивки и быть внимательнее.

Вот выстраданное:

int flash_page_erase(uint32_t page_address) // page_address not page_number
{
    static const uint32_t FPEC_KEY1 = 0x45670123;
    static const uint32_t FPEC_KEY2 = 0xCDEF89AB;

    int res;

    ENTER_CRITICAL_SECTION();
    {
        FPEC->KEYR = FPEC_KEY1;     // Authorize the FPEC Access 
        FPEC->KEYR = FPEC_KEY2;

        while (FPEC->SR & FPEC_SR_BSY) {;}

        FPEC->SR = FPEC_SR_EOP | FPEC_SR_WRPRTERR | FPEC_SR_PGERR; // clr bits by writing 1
        FPEC->CR = FPEC_CR_PER;                // page erase operation w/o fpec interrupts
        FPEC->AR = page_address;               // page address
        FPEC->CR = FPEC_CR_STRT | FPEC_CR_PER; // start operation    
        FPEC->SR;                               // according to errata: must be dummy cycle before polling BSY after START operation

        while (FPEC->SR & FPEC_SR_BSY) {;}

        res = ((FPEC->SR & FPEC_SR_EOP)  != 0);// EOP is asserted at the end of each successful program or erase operation

        FPEC->CR = FPEC_CR_LOCK;  // Set the Lock Bit to lock the FPEC and the FCR
    }
    LEAVE_CRITICAL_SECTION();

    return (res); 
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В каком порядке ST нумерует ревизии чипов?

У меня stm32f217 rev Z, а в доках фигурирует только Y, кто из них новее?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я тоже это читал. К сожалению, точные причины/алгоритм "убиения" там не были описаны, так что пока считаю на уровне слухов.

Кстати, в примере от ST (AN2557 - "in-application programming using the USART") тактирование также производится от HSE.

 

 

Поработал с Flash, вроде бы все нормально и адекватно. Смотрел примеры из периферийной библиотеки, официальный Programming manual и код пользователя AHTOXA. Кстати в Programming manual клик все таки оговаривается о HSI на стр.10:

”For write and erase operations on the Flash memory (write/erase), the internal RC oscillator (HSI) must be ON.”

Но я просто тактировал от HSE, и все нормально было, надобы разобраться что за там прикол. Скорее «убиени проца» у людей происходило из за многократного стирания/записи flash в цикле, просто выработали ресурс поди.

 

             ...........................................
    ENTER_CRITICAL_SECTION();
             ...........................................
    LEAVE_CRITICAL_SECTION();
}

 

Что там определено, можете привести эти функции?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что там определено, можете привести эти функции?
Пожалуйста.

#ifndef _ATOMIC_H_
#define _ATOMIC_H_

#ifdef __cplusplus
  extern "C" {
#endif

//=============================================================================
static __asm __inline uint32_t get_interrupt_state(void)
{
    mrs r0, primask
    bx lr
}

//=============================================================================
static __asm __inline void set_interrupt_state(uint32_t status)
{
    msr primask, r0
    bx lr
}

#define ENTER_CRITICAL_SECTION()  do {uint32_t sreg_temp = get_interrupt_state(); __disable_irq()
#define LEAVE_CRITICAL_SECTION()  set_interrupt_state(sreg_temp);} while (0)

#ifdef __cplusplus
  }
#endif

#endif

 

Кстати в Programming manual клик все таки оговаривается о HSI на стр.10
Да я об этом писал несколькими постами ранее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не помню точно в какой ветке, но я где-то на форуме читал обсуждения, якобы STM32 можно просто «убить» при едино разовом не корректном обращении с flash, камень потом перестает программироваться, читаться и т.п. В чем там прикол? Или просто слухи?

 

Сделал собственный бутлоадер. При простой записи ничего с флешью не происходит, при оладке кода некоректности было много, но все решалось

простой перепрошивкой в отладчике.

 

Когда начал прорабатывать варианты зашиты кода, вот тут впервые немного поволновался.

После установки битов зашиты записи отладчик контроллер не увидел, думал все приплыли надо перепаивть.

Но потом SEGGER J-Flash ARM меня спас, закладка Target->Unsecure chip.

 

Так что не получилось пока убить флеш.

 

Пытался использовать USER option byte, но крайне неудобно сделано, особенно если использовать совместно с write protect и закрытым загрузчиком.

Думаю пока хватит одной защиты от чтения.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Заинтересовал вопрос прошивки stm32f217 через USB, там вроде как в нем есть встроенный загрузчик DFU

но что-то ни в одном документе "USB DFU protocol used in the STM32™ bootloader" и "STM32™ microcontroller system memory boot mode" и на сайте стм не нашел ничего про прошивающий софт?! Есть ли для DFU что-то типа Flash_Loader_Demonstrator_v2.2.0_Setup ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

Спасибо большое, ща тоже нашел её в Design support у 103 их

Но что-то странно к 217 стмцы не выкладывают, а в файле что идет в архиве написано что тока недавно появилась поодержка Connectivity Line, хотя они вроде как древние

кто-нить испытывал прогу на F2 ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...