|
STM32L151 FLASH_ACR_LATENCY FLASH_ACR_ACC64, Как правильно работать с этими битами |
|
|
|
Oct 3 2013, 06:54
|

Гуру
     
Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702

|
Переключаю напряжение питание ядра и тактовую частоту ~5раз в секунду. Это вместе со входом в спящие режимы позволяет экономить питание. Но в самом экономичном сочетании частот и напряжений, которое согласно документации допустимо, процесор виснет раз в сутки. В связи с этим вопрос, правильно ли я понимаю то что изложено в PM0062 FLASH and EEPROM Programming на с 50. Понимаю написанное там так : 1)Биты ACC64 и LATENCY нужно ставить и снимать одновременно, другие вариации бессмысленны. Причём ставить сначала ACC64 следующей командой LATENCY а снимать сначала LATENCY а следующей командой ACC64. 2)При снятых ACC64 и LATENCY допустимы только некоторые сочетания напряжение частота , те которые в верхней строчке таблицы. А при поставленных ACC64 и LATENCY все сочетания которые и в верхней строчке и в нижней. По этой причине биты ставятся перед увеличением частоты. А после уменьшения снимаются по желанию, для экономии потребления. Будь это не так, было бы противоречие : биты выставлены, а частота ещё не увеличена, стало быть процессор какое-то время находится в недопустимом режиме.
Эскизы прикрепленных изображений
--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
|
|
|
|
|
Oct 3 2013, 11:02
|
Знающий
   
Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840

|
Цитата(MiklPolikov @ Oct 3 2013, 10:54)  В связи с этим вопрос, правильно ли я понимаю то что изложено в PM0062 FLASH and EEPROM Programming на с 50. Понимаю написанное там так : 1)Биты ACC64 и LATENCY нужно ставить и снимать одновременно, другие вариации бессмысленны. Причём ставить сначала ACC64 следующей командой LATENCY а снимать сначала LATENCY а следующей командой ACC64. 2)При снятых ACC64 и LATENCY допустимы только некоторые сочетания напряжение частота , те которые в верхней строчке таблицы. А при поставленных ACC64 и LATENCY все сочетания которые и в верхней строчке и в нижней. По этой причине биты ставятся перед увеличением частоты. А после уменьшения снимаются по желанию, для экономии потребления. Будь это не так, было бы противоречие : биты выставлены, а частота ещё не увеличена, стало быть процессор какое-то время находится в недопустимом режиме. На самом деле это сделано (ACC64 & LATENCY) для возможности Prefetch. Смотрите таблицу 5 с возможными конфигурациями ACC64, LATENCY, Prefetch. Цитата Prefetch is useful when the Flash memory cannot be accessed for a CPU cycle. In this case, the number of wait states (LATENCY) must be correctly programmed in the Flash access control register (FLASH_ACR) according to the frequency of the CPU clock (HCLK) and the supply voltage of the device.
|
|
|
|
|
Oct 3 2013, 11:24
|

Местный
  
Группа: Свой
Сообщений: 206
Регистрация: 14-06-06
Из: Могилев
Пользователь №: 18 059

|
Цитата(MiklPolikov @ Oct 3 2013, 09:54)  Будь это не так, было бы противоречие : биты выставлены, а частота ещё не увеличена, стало быть процессор какое-то время находится в недопустимом режиме. Думаю это не важно, главное в этот момент не обращаться к флеш (у меня вешалось когда оперировал константами). Хотя, всегда лучше соблюсти рекомендации производителя.
|
|
|
|
|
Oct 3 2013, 12:06
|
Знающий
   
Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840

|
Цитата(ViKo @ Oct 3 2013, 15:24)  Перед повышением частоты я сначала устанавливал бы LATENCY, а потом ACC64. Производитель же четко это оговорил Цитата ST strongly recommends to use the following software sequences to tune the number of wait states needed to access the Flash memory with the CPU frequency.
Increasing the CPU frequency (in the same voltage range). ● Program the 64-bit access by setting the ACC64 bit in FLASH_ACR ● Check that 64-bit access is taken into account by reading FLASH_ACR ● Program 1 WS to the LATENCY bit in FLASH_ACR ● Check that the new number of WS is taken into account by reading FLASH_ACR ● Modify the CPU clock source by writing to the SW bits in the RCC_CFGR register ● If needed, modify the CPU clock prescaler by writing to the HPRE bits in RCC_CFGR ● Check that the new CPU clock source or/and the new CPU clock prescaler value is/are taken into account by reading the clock source status (SWS bits) or/and the AHB prescaler value (HPRE bits), respectively, in the RCC_CFGR register
Decreasing the CPU frequency (in the same voltage range). ● Modify the CPU clock source by writing to the SW bits in the RCC_CFGR register ● If needed, modify the CPU clock prescaler by writing to the HPRE bits in RCC_CFGR ● Check that the new CPU clock source or/and the new CPU clock prescaler value is/are taken into account by reading the clock source status (SWS bits) or/and the AHB prescaler value (HPRE bits), respectively, in the RCC_CFGR register ● Program the new number of WS to the LATENCY bit in FLASH_ACR ● Check that the new number of WS is taken into account by reading FLASH_ACR ● Program the 32-bit access by clearing ACC64 in FLASH_ACR ● Check that 32-bit access is taken into account by reading FLASH_ACR
|
|
|
|
|
Oct 3 2013, 13:23
|

Гуру
     
Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702

|
Цитата(ViKo @ Oct 3 2013, 16:16)  Да, оговорил. Ну, значит, так надо и делать. Я спрашиваю о другом. То что при переходе на более высокую частоту ACC64 и LATECY установить надо это понятно. А при возврате обратно на низкую, нужно снять или это по желанию ? Размышления в п 2) первого сообщения.
--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
|
|
|
|
|
Oct 3 2013, 13:42
|
Знающий
   
Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840

|
Цитата(MiklPolikov @ Oct 3 2013, 17:23)  А при возврате обратно на низкую, нужно снять или это по желанию ? Размышления в п 2) первого сообщения. Опять же я указывал таблицу 5. Цитата 32-bit access reduces the consumption, so it is used when the CPU frequency is low. In this case, the number of wait states must be 0 Т.е. если Вы хотите уменьшить энергопотребление переходом в 32-битный режим снимая ACC64, то и LATENCY и PRFTEN должны быть сброшены. Посмотрите внимательнее таблицу 5, там это четко оговорено.
|
|
|
|
|
Oct 8 2013, 03:07
|

Гуру
     
Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702

|
Проблема в том, что процессор висит если я переключаюсь (несколько раз в секунду) между SYSTEM_CLOCK_HSI_VOLTAGE_RANGE_2; SYSTEM_CLOCK_MSI_VOLTAGE_RANGE_3; Зависает каждые 10ч работы, чёткой привязки ко времени нет. Если я переключаюсь между SYSTEM_CLOCK_HSI_VOLTAGE_RANGE_1; SYSTEM_CLOCK_MSI_VOLTAGE_RANGE_1; то всё хорошо. При этом если я запускаю в бесконечном цикле while(1) { SYSTEM_CLOCK_HSI_VOLTAGE_RANGE_2; SYSTEM_CLOCK_MSI_VOLTAGE_RANGE_3; } То процессор не зависает. Коды макросов приведены ниже. Вопрос : на первый взгляд код правильный ? Причина зависания глубже чем то что я просто что-то не понял из документации ? CODE #define VOLTAGE_RANGE_1 {\ while(PWR->CSR & PWR_CSR_VOSF){}\ PWR->CR &=~ PWR_CR_VOS_1;\ PWR->CR |= PWR_CR_VOS_0;\ while(PWR->CSR & PWR_CSR_VOSF){}}
#define VOLTAGE_RANGE_2 {\ while(PWR->CSR & PWR_CSR_VOSF){}\ PWR->CR &=~ PWR_CR_VOS_0;\ PWR->CR |= PWR_CR_VOS_1;\ while(PWR->CSR & PWR_CSR_VOSF){}}
#define VOLTAGE_RANGE_3 {\ while(PWR->CSR & PWR_CSR_VOSF){}\ PWR->CR |= PWR_CR_VOS_0;\ PWR->CR |= PWR_CR_VOS_1;\ while(PWR->CSR & PWR_CSR_VOSF){}}
#define SYSTEM_CLOCK_HSI_VOLTAGE_RANGE_1 {\ VOLTAGE_RANGE_1;\ RCC->CFGR &=~(RCC_CFGR_SW_0 | RCC_CFGR_SW_1);\ RCC->CFGR |=RCC_CFGR_SW_0;\ FLASH->ACR &=~FLASH_ACR_LATENCY;\ FLASH->ACR &=~FLASH_ACR_ACC64;}
#define SYSTEM_CLOCK_HSI_VOLTAGE_RANGE_2 {\ VOLTAGE_RANGE_2;\ FLASH->ACR |=FLASH_ACR_ACC64;\ FLASH->ACR |=FLASH_ACR_LATENCY;\ RCC->CFGR &=~(RCC_CFGR_SW_0 | RCC_CFGR_SW_1);\ RCC->CFGR |=RCC_CFGR_SW_0;}
#define SYSTEM_CLOCK_MSI_VOLTAGE_RANGE_1 {\ RCC->CFGR &=~(RCC_CFGR_SW_0 | RCC_CFGR_SW_1);\ FLASH->ACR &=~FLASH_ACR_LATENCY;\ FLASH->ACR &=~FLASH_ACR_ACC64;\ VOLTAGE_RANGE_1;}
#define SYSTEM_CLOCK_MSI_VOLTAGE_RANGE_2 {\ RCC->CFGR &=~(RCC_CFGR_SW_0 | RCC_CFGR_SW_1);\ FLASH->ACR &=~FLASH_ACR_LATENCY;\ FLASH->ACR &=~FLASH_ACR_ACC64;\ VOLTAGE_RANGE_2;}
#define SYSTEM_CLOCK_MSI_VOLTAGE_RANGE_3 {\ FLASH->ACR |=FLASH_ACR_ACC64;\ FLASH->ACR |=FLASH_ACR_LATENCY;\ RCC->CFGR &=~(RCC_CFGR_SW_0 | RCC_CFGR_SW_1);\ VOLTAGE_RANGE_3;}
Сообщение отредактировал IgorKossak - Oct 8 2013, 18:14
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
|
|
|
|
|
Oct 8 2013, 05:19
|

Гуру
     
Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702

|
Цитата(сарматъ @ Oct 8 2013, 09:08)  а вы локализовали место и причину зависания? Нет. Я сейчас задаю приземлённый вопрос : последовательность, в которой я переключаю частоты, напряжения и биты ACC64 и LATENCY правильная ? С учётом того что программа из каждого макроса может уйти в прерывание? Разумеется, в прерывании не будет другого макроса переключающего частоту.
--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|