Миландр

Ключевым подразделением нашей компании
является Центр Проектирования интегральных микросхем
Текущее время: 2019-окт-18 18:05

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 14 ] 
Автор Сообщение
 Заголовок сообщения: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 08:59 
Не в сети

Зарегистрирован: 2013-сен-26 08:21
Сообщения: 4
Добрый день! Возникла проблема с записью данных в EEPROM.
Написан кусок программы (с использованием SPL) для записи данных в eeprom.
Открыть main.c
Код:
#include "MDR1986VE1T.h"
#include "MDR32F9Qx_eeprom.h"
#include "main.h"
#define EEPROM_PAGE_SIZE             (4*1024)
#define MAIN_EEPAGE                  29
int8_t data = 0;
int main()
{   
           EEPROM_config();
           Address = 0x00000000 + MAIN_EEPAGE * EEPROM_PAGE_SIZE;
   BankSelector = EEPROM_Main_Bank_Select;
   
   data = EEPROM_ReadByte(Address, BankSelector);
           while(1);

}

void EEPROM_config(){
   RST_CLK_PCLKcmd(RST_CLK_PCLK_EEPROM, ENABLE);
}
Закрыть

Открыть system_MDR1986VE1T.c
Код:
void SystemCoreClockUpdate (void)
{
MDR_RST_CLK->PER_CLOCK |= (1<<4);            // RST_CLK clock enable
MDR_RST_CLK->HS_CONTROL = 0x00000005;             // HSE On, HSE2 on, Oscillator mode;
while((MDR_RST_CLK->CLOCK_STATUS&0x0c)!=0x0c);               // Wait until HSE not ready
MDR_RST_CLK->CPU_CLOCK = 0x00000002;          // CPU_C1 = HSE (8MHz)
MDR_RST_CLK->PLL_CONTROL=(1<<2)|(11<<8);                  // CPU PLL On, PLL_MULL =11    
while((MDR_RST_CLK->CLOCK_STATUS&0x02)!=0x02);               // Wait until PLL not ready
MDR_RST_CLK->PER_CLOCK |= (1<<3);             // EEPROM_CTRL clock enable
MDR_EEPROM->CMD |= (3<<3);
MDR_RST_CLK->PER_CLOCK&=(~0x08);             // EEPROM_CTRL clock disable
MDR_RST_CLK->CPU_CLOCK = 0x00000106;          // HCLK = PLL clock (96MHz)
}
void SystemInit (void)
{
  /* Reset all clock but RST_CLK & BKP_CLC bits */
  MDR_RST_CLK->PER_CLOCK   = (uint32_t)0x8000010;
  /* Reset CPU_CLOCK bits */
  MDR_RST_CLK->CPU_CLOCK   &= (uint32_t)0x00000000;
  /* Reset PLL_CONTROL bits */
  MDR_RST_CLK->PLL_CONTROL &= (uint32_t)0x00000000;
  /* Reset HSEON and HSEBYP bits */
  MDR_RST_CLK->HS_CONTROL  &= (uint32_t)0x00000000;
  /* Reset USB_CLOCK bits */
  MDR_RST_CLK->USB_CLOCK   &= (uint32_t)0x00000000;
  /* Reset ADC_MCO_CLOCK bits */
  MDR_RST_CLK->ADC_MCO_CLOCK   &= (uint32_t)0x00000000;
  SystemCoreClockUpdate();
}
Закрыть

Проблема заключается в следующем: когда программа начинает выполнять функцию «EEPROM_ReadByte» она сразу же перескакивает на выполнения прерывания «HardFault_Handler» и все зависает.
Кроме EEPROM все остальное не инициализируется, прерывания не включаются.
Функции из «MDR32F9Qx_eeprom.h» размешены и выполняются из ОЗУ микроконтроллера.
Прошу помочь решить данную проблему.
Спасибо за внимание!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 10:52 
Не в сети

Зарегистрирован: 2010-июл-08 08:50
Сообщения: 734
Откуда: АО "ПКК Миландр"
AlexChas писал(а):
Функции из «MDR32F9Qx_eeprom.h» размешены и выполняются из ОЗУ микроконтроллера.

Куда конкретно размещаются функции?
Код, исполняемый из ОЗУ, можно размещать, начиная с адреса 0x2010_0000 до 0x2010_3FFF.
На время работы с Flash-памятью, как с периферийным блоком, необходимо запрещать прерывания, так как вектора обработчиков прерываний находятся во Flash и их нельзя перемещать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 11:16 
Не в сети
Аватара пользователя

Зарегистрирован: 2012-авг-07 09:58
Сообщения: 132
AlexChas писал(а):
Добрый день! Возникла проблема с записью данных в EEPROM.
Написан кусок программы (с использованием SPL) для записи данных в eeprom.

Для правильного размещения функций в памяти МК необходимо использовать нужный файл линкера (keil: MDR1986VE1T.sct; IAR: MDR1986VE1T.icf).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 11:32 
Не в сети

Зарегистрирован: 2013-сен-26 08:21
Сообщения: 4
Цитата:
Куда конкретно размещаются функции?

Ниже скрин из Keil
Цитата:
Код, исполняемый из ОЗУ, можно размещать, начиная с адреса 0x2010_0000 до 0x2010_3FFF.

Интересно, этого я не знал. Из скрина ниже видно, что этот адреса начинаются с 0х2000_0000. Напрашивается вопрос, как задать правильный адрес? Попробую предположить что можно изменить адреса в 2 местах. Первое это скатер файл, что, по-моему, трогать не нужно. Второе это в настройках проекта вкладка target окно Read_write memory areas изменить адрес на выше сказанный.
Цитата:

На время работы с Flash-памятью, как с периферийным блоком, необходимо запрещать прерывания, так как вектора обработчиков прерываний находятся во Flash и их нельзя перемещать.

Это мне известно, и я специально написал программу без включения прерываний
Спасибо!


Вложения:
Комментарий к файлу: Скрин
Безымянный.JPG
Безымянный.JPG [ 87.67 КБ | Просмотров: 9153 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 11:49 
Не в сети

Зарегистрирован: 2013-сен-26 08:21
Сообщения: 4
Перечитал спецификацию, увидел интересную таблицу: 0х20000000-0х200FFFFF Область памяти шины DTCM для данных. Доступ за инструкцией в эту область приводит к ошибке. 0x20100000-0x3FFFFFFF Область памяти внешней системной шины для кода программы и данных. Моя ошибка, не дочитал.
Как я понимаю скатер файл генерируется исходя из настроек проекта. Я прав или нет?
Спасибо!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 12:16 
Не в сети

Зарегистрирован: 2013-сен-26 08:21
Сообщения: 4
Разобрался. Переписал Scatter файл. Заработало. Буду тестировать дальше.
Код:
LR_IROM1 0x00000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00007FFF  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x20100000 0x00003FFF  {
    MDR32F9Qx_eeprom.o (+RO)
   .ANY (+RW +ZI)
  }
}

Спасибо за внимания.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 12:28 
Не в сети
Аватара пользователя

Зарегистрирован: 2012-авг-07 09:58
Сообщения: 132
AlexChas писал(а):
Разобрался. Переписал Scatter файл. Заработало. Буду тестировать дальше.

Зачем его переписывать?
MDR1986VE1T.sct уже написан и прилагается к библиотеке.
Код:
LR_IROM1 0x00000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00008000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x20100000 0x00004000  {
   *.o (EXECUTABLE_MEMORY_SECTION)
   .ANY (+RW +ZI)
  }
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2015-июл-27 10:55 
Не в сети

Зарегистрирован: 2015-апр-10 22:42
Сообщения: 18
Добрый день форумчане.
У меня функция
Код:
EEPROM_ReadWord()
вычитывает нули,
а функция
Код:
EEPROM_ProgramWord()
ничего не меняет.
Повторное вычитывание после записи снова возвращает нули.
Вот код:
Код:
int main(void)
{
   UART_Init();

      RST_CLK_PCLKcmd(RST_CLK_PCLK_EEPROM, ENABLE);
     uint32_t data = EEPROM_ReadWord(0x00000000, EEPROM_Main_Bank_Select);
     printf("before: %x ", data);
     EEPROM_ProgramWord(0x00000000, EEPROM_Main_Bank_Select, 0x55);
     data = EEPROM_ReadWord(0x00000000, EEPROM_Main_Bank_Select);
     printf("after: %x ", data);

   while(1);
  return 0;
}

Программа крутится в пространстве начиная с адреса 0x2010_0000 - и MAP-файл и пошаговое выполнение программы утилитой
Код:
JLink.exe
это подтверждают. USART шлет данные как нужно. Но флеш не перезаписывается и даже не вычитывается. Проверил код используемых функций чтения и записи во флеш - они соответсвуют требуемой последовательности работы с EEPROM в спецификации на камень. В чем может быть проблема?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2015-июл-31 11:48 
Не в сети

Зарегистрирован: 2010-июл-08 08:50
Сообщения: 734
Откуда: АО "ПКК Миландр"
посмотрите пример отсюда


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2016-авг-02 18:28 
Не в сети

Зарегистрирован: 2015-авг-26 16:21
Сообщения: 10
Откуда: г. Москва, "Экспериментальная лаборатория Наукасофт"
Здравствуйте.
Не хочу создавать новую тему по тому же самому вопросу, поэтому пишу сюда.
Использую МК 1986ВЕ92 + отладочную плату, среду Keil 5. На Кейл поставил SPL + SP и радостно все это полгода использую. Но появилась необходимость работать с EEPROM.
Для начала воспользовался готовым примером, из тех, что шли в комплекте с библиотеками (обозначен как "code in RAM"). Указал, чтобы MDR32F9Qx_eeprom.c запускался из RAM (скрин прилагаю), откомпилировал, запустил... и все.
Стал выполнять программу построчно, увидел, что все стопорится на строке
Код:
MDR_EEPROM->ADR = Address + Offset;
(строка 230 в MDR32F9Qx_eeprom.c, функция EEPROM_ErasePage).
Далее отбросил готовые библиотеки и начал писать свое. Подробно, построчно, выполняя действия, указанные на страницах 44-47 описания моего МК.
Написал main.c, лежащий в основной памяти, добавил eeprom.c, указав, что его код должен запускаться из RAM, в него положил функцию для очистки одной страницы информационной памяти.
Выяснил, что после перевода памяти в режим программирования, когда устанавливается бит CON регистра MDR_EEPROM->CMD, микроконтроллер перестает реагировать.
Получается, что программа не выполняется из RAM? Или я не отключил прерывания (я использовал __disable_irq() )?
Буду благодарен любым комментариям.

П.С. Искал примеры, пробовал примеры с этого форума, но запустить не смог.
П.П.С. На скрине кейловская настройка запуска из RAMа. Ниже мой код, который слизан с описания МК и, опять же, виснет при установке CON.
Открыть
Код:
        MDR_EEPROM->KEY = 0x8AAA5551; //вводим ключ на старт   
   MDR_EEPROM->CMD = MDR_EEPROM->CMD | (1 << 9); //работу с информационной памятью IFREN = 1
   MDR_EEPROM->CMD = MDR_EEPROM->CMD | (1 << 0); //переводим в режим программирования CON = 1
   MDR_EEPROM->ADR = 0x08000000;   //выставляем адрес страницы (ВОТ ТУТ УЖЕ ВИСИТ)
   //биты EEPROM_ADR оставляем 00, соответствует работе с сектором A
   MDR_EEPROM->CMD = MDR_EEPROM->CMD | (1 << 6); //XE в единицу
   MDR_EEPROM->CMD = MDR_EEPROM->CMD | (1 << 10); //ERASE в единицу
  ProgramDelay(40);   //ждем 5мкс
   MDR_EEPROM->CMD = MDR_EEPROM->CMD | (1 << 13); //ставим NVSTR в единицу - команда на стирание
  ProgramDelay(320); //ждем 40мкс
   MDR_EEPROM->CMD = MDR_EEPROM->CMD & (~(1 << 10));   //очищаем ERASE
  ProgramDelay(40);   //ждем 5мкс
   MDR_EEPROM->CMD = MDR_EEPROM->CMD & (~(1 << 6)); //XE в нуль
   MDR_EEPROM->CMD = MDR_EEPROM->CMD & (~(1 << 13)); //NVSTR в нуль
  ProgramDelay(8); //ждем 1мкс
Закрыть


Вложения:
1.jpg
1.jpg [ 29.02 КБ | Просмотров: 6924 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2016-авг-03 08:55 
Не в сети

Зарегистрирован: 2009-сен-21 12:39
Сообщения: 508
Вот это, часом, не забыли?
MDR_RST_CLK->PER_CLOCK |= (1 << 3); // вкл. тактирование EEPROM


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2016-авг-03 09:12 
Не в сети

Зарегистрирован: 2015-авг-26 16:21
Сообщения: 10
Откуда: г. Москва, "Экспериментальная лаборатория Наукасофт"
Нет, тактирование включил. Вот код:
Код:
RST_CLK_DeInit();
  RST_CLK_HSEconfig(RST_CLK_HSE_ON);
   RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTF, ENABLE);
   RST_CLK_PCLKcmd(RST_CLK_PCLK_EEPROM, ENABLE);
   RST_CLK_CPUclkSelection(RST_CLK_CPUclkCPU_C3);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2016-авг-03 12:49 
Не в сети

Зарегистрирован: 2009-сен-21 12:39
Сообщения: 508
Ну тогда методом сравнения. На форуме есть рабочие примеры работы с flash/eeprom, да и функции из SPL по виду :) похожи на рабочие.
Например, здесь http://forum.milandr.ru/viewtopic.php?p=893#p893
Ниже "наш" код, но для info-flash
Код:
//================================================================================
// API чтения/записи/стирания банков информационной страницы FLASH-памяти
// В странице четыре банка с начальными адресами FLASH_START, FLASH_START+4,
//  FLASH_START+8, FLASH_START+12, т.е. между соседними словами одного банка
// разница в 16 байт (или 4 слова)
// Каждый из банков содержит 256 слов по 32 бита
// Внимание!
//    Все функции должны запускаться из ОЗУ, для ВЕ1,3 в области IRAM2
//  Функция настройки DWT таймера DelayConfig() должна быть вызвана из preinit()
//  Для корректного отсчёта задержек задать параметр SYSCLK равный частоте ядра
//================================================================================
#if defined(USE_MDR1986VE9x) || defined(USE_MDR1986VE94)
   //-------------------------------------------------------------------------------
   // Задержка полингом по DWT таймеру, вх. параметр в микросекундах
   //-------------------------------------------------------------------------------
   #pragma inline
void Sleep(u32 cnt)
   {    
   DWT->CYCCNT = 0;
   while (DWT->CYCCNT < (cnt * SYSCLK_MHZ));
   }

   //-------------------------------------------------------------------------------
   //-------------------------------------------------------------------------------
void DelayConfig()
   {
   CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;   // включение модуля DWT
   DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
   DWT->CYCCNT = 0;
   }
   
#elif defined(USE_MDR1986VE1T) || defined(USE_MDR1986VE3)
   //------------------------------------------------------------------------------------------------
   // Задержка полингом по SysTick таймеру, вх. параметр в микросекундах
   // SysTick в ВЕ1 все равно глючный при работе из Flash (см. errata), для других целей не подходит
   //------------------------------------------------------------------------------------------------
#define SYS_TICK_MAX   (u32)0x00FFFFFF   // не более ~130 мс при SYSCLK_MHZ = 128
void Sleep(u32 cnt)
   {
   cnt *= SYSCLK_MHZ;
   if( cnt > SYS_TICK_MAX )
      cnt = SYS_TICK_MAX;
   SysTick->LOAD = cnt;
   SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
   while( (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0 );
   }
   
#endif

#if defined(USE_MDR1986VE9x) || defined(USE_MDR1986VE94)
   #include "flash.h"
#elif defined(USE_MDR1986VE1T) || defined(USE_MDR1986VE3)
   #include "flash_BE1.h"
#endif

#define   EEPROM_KEY   (uint32_t)0x8AAA5551

//-------------------------------------------------------------------------------
// Очистка одного банка Flash
//-------------------------------------------------------------------------------
void ErasePage(u32 Addr)
{
MDR_EEPROM->ADR = Addr;
MDR_EEPROM->CMD |= EEPROM_CMD_XE;
MDR_EEPROM->CMD |= EEPROM_CMD_ERASE;
Sleep(6);// 5.5us
MDR_EEPROM->CMD |= EEPROM_CMD_NVSTR;
Sleep(46000);// 46ms
MDR_EEPROM->CMD &= ~EEPROM_CMD_ERASE;
Sleep(6);// 5.5us
MDR_EEPROM->CMD &= ~EEPROM_CMD_XE;
MDR_EEPROM->CMD &= ~EEPROM_CMD_NVSTR;
Sleep(2); // 1.8us
}

//-------------------------------------------------------------------------------
// Установка сигналов программирования flash
//-------------------------------------------------------------------------------
void ProgramSignalsOn(void)
{
MDR_EEPROM->CMD |= EEPROM_CMD_XE;
MDR_EEPROM->CMD |= EEPROM_CMD_PROG;
Sleep(6);   // 5.5us
MDR_EEPROM->CMD |= EEPROM_CMD_NVSTR;
Sleep(11);   // 10.6us
}

//-------------------------------------------------------------------------------
// Сброс сигналов программирования flash
//-------------------------------------------------------------------------------
void ProgramSignalsOff(void)
{
MDR_EEPROM->CMD &= ~EEPROM_CMD_PROG;
Sleep(6);   // 5.5us
MDR_EEPROM->CMD &= ~EEPROM_CMD_XE;
MDR_EEPROM->CMD &= ~EEPROM_CMD_NVSTR;
Sleep(2); // 1.8us
}

//-------------------------------------------------------------------------------
// Запись 32 бит слова по адресу
//-------------------------------------------------------------------------------
void WriteFlash(u32 Addr, u32 Data)
{
MDR_EEPROM->ADR = Addr;
MDR_EEPROM->DI = Data;

Sleep(1);   // 0.3us
MDR_EEPROM->CMD |= EEPROM_CMD_YE;   // YE=1
Sleep(46);   // 46us
MDR_EEPROM->CMD &= ~EEPROM_CMD_YE;   // YE=0
Sleep(1);   // 0.3us
}

//-------------------------------------------------------------------------------
// Чтение из ОДНОГО БАНКА информационной страницы Flash
// Входные параметры:
// - указатель на буфер-приёмник
// - смещение первого считываемого слова от начала информационной страницы
// - число 32-бит слов, которые нужно считать
// Возвращаемое значение : нет
//-------------------------------------------------------------------------------
void InfPageRead(u32 *buff, int offs, int len)
{
int i;

int irq_was_masked = __disable_irq();

MDR_EEPROM->KEY = EEPROM_KEY;
MDR_EEPROM->CMD |= EEPROM_CMD_CON;   // перевод в режим программирования

MDR_EEPROM->CMD |= (1 << EEPROM_CMD_IFREN_Pos); // установка режима информационной памяти

MDR_EEPROM->CMD |= ((1 << EEPROM_CMD_XE_Pos) | (1 << EEPROM_CMD_YE_Pos) | (1 << EEPROM_CMD_SE_Pos));

for (i=0; i < len; i++)
   {
   MDR_EEPROM->ADR = (u32)FLASH_START + offs*4 + i*16;
   Sleep(2);
   buff[i] = MDR_EEPROM->DO;
   }

MDR_EEPROM->CMD &= ~((1 << EEPROM_CMD_XE_Pos) | (1 << EEPROM_CMD_YE_Pos) | (1 << EEPROM_CMD_SE_Pos));
MDR_EEPROM->CMD &= ~EEPROM_CMD_CON;   // выход из режима программирования
MDR_EEPROM->KEY = 0;

if(!irq_was_masked)
   __enable_irq();
}

//-------------------------------------------------------------------------------
// Стирание информационной страницы Flash (все 4 банка), требуется 225 мс
//-------------------------------------------------------------------------------
void InfPageErase()
{
int irq_was_masked = __disable_irq();

MDR_EEPROM->KEY = EEPROM_KEY;
MDR_EEPROM->CMD |= EEPROM_CMD_CON;
MDR_EEPROM->CMD |= (1 << EEPROM_CMD_IFREN_Pos);

// Чтобы очистить страницу целиком, надо очистить все четыре банка
ErasePage(FLASH_START + 0x00);
ErasePage(FLASH_START + 0x04);
ErasePage(FLASH_START + 0x08);
ErasePage(FLASH_START + 0x0C);

MDR_EEPROM->CMD &= ~EEPROM_CMD_CON;// CON=0
MDR_EEPROM->KEY = 0;

if(!irq_was_masked)
   __enable_irq();
}

//-------------------------------------------------------------------------------
// Стирание одного банка Flash
//-------------------------------------------------------------------------------
void InfBankErase(u8 bank)
{
int irq_was_masked = __disable_irq();

MDR_EEPROM->KEY = EEPROM_KEY;
MDR_EEPROM->CMD |= EEPROM_CMD_CON;   // CON=1
MDR_EEPROM->CMD |= (1 << EEPROM_CMD_IFREN_Pos);

ErasePage(FLASH_START + bank * 4);

MDR_EEPROM->CMD &= ~EEPROM_CMD_CON;   // CON=0
MDR_EEPROM->KEY = 0;

if(!irq_was_masked)
   __enable_irq();
}

//-------------------------------------------------------------------------------
// Запись массива 32 бит слов в ОДИН БАНК информационной страницы Flash
// Входные параметры:
// - указатель на источник данных
// - смещение от начала страницы
// - число 32 бит слов, которые нужно записать
// Возвращаемое значение : нет
// Внимание, писать можно только по чистым ячейкам
//-------------------------------------------------------------------------------
void InfPageWrite(u32 *buff, int beg, int len)
{
int j;

int irq_was_masked = __disable_irq();

MDR_EEPROM->KEY = EEPROM_KEY;
MDR_EEPROM->CMD |= EEPROM_CMD_CON;
MDR_EEPROM->CMD |= (1 << EEPROM_CMD_IFREN_Pos);

ProgramSignalsOn();

for(j = 0; j < len; j++)
   WriteFlash((u32)FLASH_START + j * 16 + beg * 4, buff[j]);

ProgramSignalsOff();

MDR_EEPROM->CMD &= ~EEPROM_CMD_CON;
MDR_EEPROM->KEY = 0;

if(!irq_was_masked)
   __enable_irq();
}    

//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
/*
void MainPageWrite(u32 Addr, u32 Data)
{
int irq_was_masked = __disable_irq();

MDR_EEPROM->KEY = EEPROM_KEY;
MDR_EEPROM->CMD |= EEPROM_CMD_CON;
MDR_EEPROM->CMD &= ~(1 << EEPROM_CMD_IFREN_Pos);

ProgramSignalsOn();
WriteFlash(Addr, Data);
ProgramSignalsOff(); 

MDR_EEPROM->CMD &= ~EEPROM_CMD_CON;
MDR_EEPROM->KEY = 0;

if(!irq_was_masked)
   __enable_irq();
}
*/



Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2016-авг-03 19:29 
Не в сети

Зарегистрирован: 2015-авг-26 16:21
Сообщения: 10
Откуда: г. Москва, "Экспериментальная лаборатория Наукасофт"
Проблему решил.
Проблема оказалась в том, что код выполнялся не из ОЗУ. Причины:
1). Keil в Evaluation версии не дает выполнять код из ОЗУ, при этом не выводится никаких предупреждений. Смена на MDK-ARM Professional исправила причину.
2). __RAMFUNC в Keil не работает. Пришлось городить конструкцию вида __attribute__((section("EXECUTABLE_MEMORY_SECTION"))); после объявления функции и добавлять Scatter-файл. Код Scatter'а прилагаю, вдруг кому понадобится.
Код:
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00008000  {  ; RW data
  *.o (EXECUTABLE_MEMORY_SECTION)
   .ANY (+RW +ZI)
  }
}

Спасибо за помощь!


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB