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

STM32H743 (NUCLEO-144) и FMC

Пытаюсь завести контроллер внешней шины(FMC) на отладочной плате Nucleo-144 STM32H743.

 

Прицепил SRAM на 32 кБ, адресные биты посадил на GND, кроме самого младшего A0, который заведён на A16 микроконтроллера.

 

Делаю такой нехитрый тест:

int main(void)
{
//  SCB_EnableICache();
//  SCB_EnableDCache();

 HAL_Init();
 SystemClock_Config();
 MX_GPIO_Init();
 MX_FMC_Init();

// __disable_irq();

#define STATUS_REG		(*(volatile unsigned char*) 0x60000000)
#define DATA_REG		(*(volatile unsigned char*) 0x60010000)

u8 test1,test2,i=0;

while(1)
{
 test1=i*i;

 test2=(i+25)*(i+25);

 i++;

 STATUS_REG=test1;
 DATA_REG=test2;

 if((STATUS_REG!=test1)||(DATA_REG!=test2))
 {
  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET);
  while(1);
 }
 else
 {
  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14);
  delay_ms(1);
 }
}

}

 

Если данные в двух ячейках не совпадают, то светодиод должен потухнуть и в вечный цикл. Если тест ОК, то светодиод быстро мерцает.

 

Так вот, при полностью исключенной SRAM тест успешен!

 

Верны ли вообще адреса для FMC : ?

(*(volatile unsigned char*) 0x60000000 и (*(volatile unsigned char*) 0x60010000 ? Складывается впечатление, что там другая периферия.

 

 

На всякий случай код инита GPIO и FMC (сгенерирован кубом и подправлен):

/* FMC initialization function */
void MX_FMC_Init(void)
{
 FMC_NORSRAM_TimingTypeDef Timing;

 /** Perform the SRAM1 memory initialization sequence
 */
 hsram1.Instance = FMC_NORSRAM_DEVICE;
 hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
 /* hsram1.Init */
 hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
 hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
 hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
 hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8;
 hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
 hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
 hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
 hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
 hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
 hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
 hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
 hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
 hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
 hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
 hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
 /* Timing */
 Timing.AddressSetupTime = 0; //15;
 Timing.AddressHoldTime = 0; //15;
 Timing.DataSetupTime = 6; //255;
 Timing.BusTurnAroundDuration = 0; //15;
 Timing.CLKDivision = 0; //16;
 Timing.DataLatency = 0; //17;
 Timing.AccessMode = FMC_ACCESS_MODE_A;
 /* ExtTiming */

 if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
 {
_Error_Handler(__FILE__, __LINE__);
 }

}

static uint32_t FMC_Initialized = 0;

static void HAL_FMC_MspInit(void){
 /* USER CODE BEGIN FMC_MspInit 0 */

 /* USER CODE END FMC_MspInit 0 */
 GPIO_InitTypeDef GPIO_InitStruct;
 if (FMC_Initialized) {
return;
 }
 FMC_Initialized = 1;
 /* Peripheral clock enable */
 __HAL_RCC_FMC_CLK_ENABLE();

 /** FMC GPIO Configuration  
 PE7   ------> FMC_D4
 PE8   ------> FMC_D5
 PE9   ------> FMC_D6
 PE10   ------> FMC_D7
 PD11   ------> FMC_A16
 PD14   ------> FMC_D0
 PD15   ------> FMC_D1
 PC7   ------> FMC_NE1
 PD0   ------> FMC_D2
 PD1   ------> FMC_D3
 PD4   ------> FMC_NOE
 PD5   ------> FMC_NWE
 */
 /* GPIO_InitStruct */
 GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF12_FMC;

 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

 /* GPIO_InitStruct */
 GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0 
					  |GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF12_FMC;

 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

 /* GPIO_InitStruct */
 GPIO_InitStruct.Pin = GPIO_PIN_7;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF9_FMC;

 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

 /* USER CODE BEGIN FMC_MspInit 1 */

 /* USER CODE END FMC_MspInit 1 */
}

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

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


Ссылка на сообщение
Поделиться на другие сайты
#define STATUS_REG (*(volatile unsigned char*) 0x60000000)

#define DATA_REG (*(volatile unsigned char*) 0x60010000)

 

u8 test1,test2,i=0;

 

Отладчиком смотрели значения test1 и test2? Может оптимзатор посчитал их вычисление излишним и они всегда равны 0? На всякий случай объявить их как volatile?

Вообще тема меня живо интересует, только платы пока нет... Опыт работы с FMC/FSMC более младших СТМ имею и всегда было непросто получить результат. Жду H743, попробую живьем..

Настроить UART и каждый шаг сопровождать отладочным выводом. Кроме того отладочный вывод внесет задержку между записью-чтением и исключит возможный (это чисто моя паранойя)

эффект сохранения выведенных значений на емкостях выводов ;)

 

Заранее согласен, что озвученные предположения не слишком обоснованны - насчет оптимизатора и volatile, но уж больно поведение чудесатое - даже при остсутствии RAM тест проходит...

Изменено пользователем nanorobot

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


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

Эта же программа на STM32F4Discovery (stm32f407) даёт провал теста, если памяти на шине нет.

 

так уж и быть: заволатайлил переменные i,test1, test2. Ничего не изменилось на H743.

 

Попробовал сделать задержку 1 мс и тест стал валиться, что верно, когда SRAM не подключена к FMC.

Зато когда подключена, то ни одна из времянок не дала положительного исхода теста - чтение из SRAM происходит некорректно.

 

Я уже начинаю побаиваться: камень свежий вдруг там с FMC напороли глюков? Ну не работает он вообще - с 70-нс SRAM типа UT62256CPC-70LL чтение неверно.

 

Ещё глянул HAL, там зачем-то объявлены функции чтения-записи из внешней памяти. Зачем? Это также глупо, как и писать функцию чтения-записи массива.

 

Главное GPIO работают, прерывание таймера и задержки работают, с FMC не хочет(точнее, не происходит корректное чтение). Сигналы на всех линиях присутствуют (проверял тестером, делая вечный цикл чтения или записи по определенному адресу, взводя по одному биту в данных: 0x01 , 0x02, 4,8,16,32,.. 128)

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


Ссылка на сообщение
Поделиться на другие сайты
Проблема (возможно и её решение) здесь: https://community.st.com/thread/49249-stm32...spurious-writes

 

Какое то очень простое решение.. Попробуйте - отпишитесь. Оч. интересно. Мне плата подойдет не ранее чем через три недели, да и возможно проблема будет не моя, LCD планирую подключать по RGB.

Изменено пользователем nanorobot

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


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

Отремапил банки, как там было написано. Заработало!!! :yeah:

 

Теперь уровень логической "1" на линиях данных D0..D7 около 3V, что верно. Подсоединил SRAM на 32 кБ (старшие адреса посадил на GND, младший A0 => на A16 контроллера) , прогнал тест - всё успешно.

 

Причём, если во время работы хотя бы 1 бит отсоединить, то тест проваливается, что логично.

Времянки подобрал самые быстрые, при чтении времянка чуть длинее, что логично. Если сделать ещё короче, что ниже, то тест проваливается (что тоже логично).

 

Так что проблема с FMC решена. Но STM подосрала конкретно ))) 2 дня убил. :smile3009:

 

Тестилка SRAM 32 kB UT62256CPC-70LL:

#include <stdlib.h>

#define LCD_COM8 (*(volatile unsigned char*) 0xC0000000)
#define LCD_DAT8 (*(volatile unsigned char*) 0xC0010000)

volatile unsigned char t1,t2;

int main(void)
{
HAL_Init();
SystemClock_Config();

MX_GPIO_Init();
MX_FMC_Init();

HAL_SetFMCMemorySwappingConfig(FMC_SWAPBMAP_SDRAM_SRAM); //=======================> ЭТО ВАЖНО !!!

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET);

while(1)
{
 t1=rand();
 t2=rand();

 LCD_COM8=t1;
 LCD_DAT8=t2;

 if((LCD_COM8!=t1)||(LCD_DAT8!=t2))
 {
  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET);
  while(1);
 }

}

}

 

Настройки времянок (частота FMC и CPU 168 МГц !):

  /* READ */
  Timing.AddressSetupTime     =0; //0.. 15
  Timing.AddressHoldTime      =1; //1.. 15
  Timing.DataSetupTime        =5; //1..255
  Timing.BusTurnAroundDuration=0; //0.. 15
  Timing.CLKDivision          =2; //2.. 16
  Timing.DataLatency          =2; //2.. 17
  Timing.AccessMode           =FMC_ACCESS_MODE_D;

  /* WRITE */
  ExtTiming.AddressSetupTime     =0; //0.. 15
  ExtTiming.AddressHoldTime      =1; //1.. 15
  ExtTiming.DataSetupTime        =3; //1..255
  ExtTiming.BusTurnAroundDuration=0; //0.. 15
  ExtTiming.CLKDivision          =2; //2.. 16
  ExtTiming.DataLatency          =2; //2.. 17
  ExtTiming.AccessMode           =FMC_ACCESS_MODE_D;

  HAL_SRAM_Init(&hsram1, &Timing, &ExtTiming);

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

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


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

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация