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

kostya-m

Участник
  • Постов

    207
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о kostya-m

  • Звание
    Местный
    Местный

Посетители профиля

2 118 просмотров профиля
  1. Извините, был очень занят и не увидел просьбы. Никаких терминальных или согласующих резисторов. Но стоит минимизировать расстояние от процессора до памяти
  2. Спасибо, заработало. Применил по рекомендации производственников новую китайскую RJ-45 розетку с трансформаторами. А у нее в даташите не указано где + и - (P и N) контакты. Оказалось перепутал. Сделал кабель с инверсией и заработало.
  3. Спасибо. Изучу. А приходится еще старые проекты поддерживать. А ведь до того, штук пять плат с LwIP завелись без вопросов. Упорный Н743 попался :)
  4. Прежде чем писать сюда, я много времени потратил что бы попытаться разобраться. Включая трассировку сигналов многоканальным осциллоскопом. Были и мысли, что просто не подходит фаза клока на чтении, что видно и о чем упоминается и в даташите на физику (халтурщики фазу перевернули) Потому пробовал или затянуть клок или сигналы (поведение изменяется). По сути, я считаю, что проблема не в LwIP, а в драйвере от куба. А еще точнее в том, что при генерации кода они где-то недописали какую-то настройку. Мне бы подошел какой-нибудь заведомо работающий код решения на этом проце с FrееRTOS и LwIP без остального, я бы сам проанализировал и нашел отличия. А может быть нашел ошибку в трассировке платы (что то же не исключаю). DCash я в проекте включаю только после отладки. На F745 его так и не удалось включить, найдены были ошибки его работы с SRAM.
  5. К MPU у меня претензий нет. Когда я включил код управления MPU, то LwIP начал хоть как-то ворочаться. Без MPU вообще не работало, это я писал в прошлой теме, после отладки SDRAM. Видимо не зря это требуется. Кеширование выключал, ничего не изменялось. В первых строках темы написал, что куб с FreeRTOS и LwIP. Отличие только в том, что в оригинале физика LAN8742, а у меня LAN8720. Но анализ и даташитов и кода показал, что между ними разницы нет. Т.е. все новые регистры не используются кодом. А в остальном они идентичны. Свежий куб создает несколько иной текст. Если для дескрипторов текст аналогичен, то RxBuff вообще не существует. Сделана память и создан только указатель на ее начало, но не объявлен массив. Указатель действительно смотрит на 0x30044000. А вот регион с адреса 0x30040000 вообще никак не используется. Зачем же его надо было включать в MPU, как советовали в форуме ST? Вообще, я собрал проект как его сгенерил куб и с МPU и без него и оба варианта не запустились. Что меня подивило, обычно у ST более или менее рабочий код получался. Пусть и не оптимальный. Да, компилятор у меня iar
  6. STM32H743II LwIP продолжение

    Решил выделить сюда вопрос о наладке LwIP на STM32H7x Проект сформирован в кубе с включенной FreeRTOS и LwIP. Интерфейс RMII. По рекомендации, включил MPI и добавил три страницы в исключения: void MPU_Config(void) { MPU_Region_InitTypeDef MPU_InitStruct = {0}; /* Disables the MPU */ HAL_MPU_Disable(); /** Initializes and configures the Region and the memory to be protected */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0; MPU_InitStruct.BaseAddress = 0x30000000; MPU_InitStruct.Size = MPU_REGION_SIZE_256B; MPU_InitStruct.SubRegionDisable = 0x0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /** Initializes and configures the Region and the memory to be protected */ MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.BaseAddress = 0x30044000; MPU_InitStruct.Size = MPU_REGION_SIZE_16KB; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /** Initializes and configures the Region and the memory to be protected */ MPU_InitStruct.Number = MPU_REGION_NUMBER2; MPU_InitStruct.BaseAddress = 0x30040000; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* Enables the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); } Нормально не заработало, хотя пытается. На что обратил внимание. 1. Первый регион. С ним все понятно. Он использован для дескрипторов в Ethernetif.c #pragma location=0x30000000 ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */ #pragma location=0x30000200 ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */ 2. Второй регион задекларирован в lwipopts.h "#define LWIP_RAM_HEAP_POINTER 0x30044000" и использован в mem.c ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER); Вообще, стиль этот мне очень не понравилось. Используют память по фиксированному адресу, но линкер об это не уведомлен. Оно конечно так работает, но меня несколько коробит. Потому сделал определение памяти для линкера, сделал массив, расположенный и теперь видно, что память фиксирована. 3. А вот с третьим регионом непонятно. На него нет ссылок нигде в коде проекта. Отладка показывает, что реальные приемные буфера смотрят в DTCMRAM в адреса 0х2400. Вроде как с комментариях к MAC контроллеру сказано, что на эти адреса и надо смотреть. Так зачем этот третий регион. Для контроля при старте заполнил его своими данными и при работе они не меняются, т.е. он не используется. Еще озадачило поведение ОЗУ второго и третьего регионов. После старта, на входе main из этих регионов читается белиберда. Данные становятся адекватными, например теми, что были до reset, после включения клока на TIM7, которые у меня определен как Timebase. Как связан клок системного таймера с памятью не сообразил. Пока статистика, которую я добавил в прерывание по сети, говорит о том, что иногда принимаются пакеты и один раз пакет отправляется. Что может быть еще не так?
  7. Попробовал. Да, действительно теперь не только первое прерывание проходит на прием. Но пакет обрабатывается и отправляется ответ, что регистрируется в статистике роутера. После чего от роутера посылаются очередные пакеты, а прерывание на прием больше не происходит. Хотя прерывание на отправку прошло нормально и отработалось корректно. Но дальнейшего приема нет и флаг RI в DMACSR не поднимается, хотя пакеты приходят, что видно по ногам RMII.
  8. Спасибо, попробую. Да, в примерах MPU включен и делаются соответствующие настройки. Я как бы понимал, что если нужно с MPU, то надо делать так. Указали бы сразу, что Ethernet требует обязательно MPU и вопросов бы не было. А второе, это то, что проблема не в перекачке данных, а в отсутствии прерывания по приходу пакета.
  9. Нашел опечатку. Все заработало. Появился код с работой этой SDRAM на 125 МГц. Если кому потребуется. Кварц 24 МГц static void HAL_FMC_MspInit(void){ /* USER CODE BEGIN FMC_MspInit 0 */ /* USER CODE END FMC_MspInit 0 */ GPIO_InitTypeDef GPIO_InitStruct ={0}; if (FMC_Initialized) { return; } FMC_Initialized = 1; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC; PeriphClkInitStruct.PLL2.PLL2M = 6; PeriphClkInitStruct.PLL2.PLL2N = 125; PeriphClkInitStruct.PLL2.PLL2P = 2; PeriphClkInitStruct.PLL2.PLL2Q = 2; PeriphClkInitStruct.PLL2.PLL2R = 2; PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_2; PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE; PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_PLL2; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* Peripheral clock enable */ __HAL_RCC_FMC_CLK_ENABLE(); /** FMC GPIO Configuration PF0 ------> FMC_A0 PF1 ------> FMC_A1 PF2 ------> FMC_A2 PF3 ------> FMC_A3 PF4 ------> FMC_A4 PF5 ------> FMC_A5 PC2_C ------> FMC_SDNE0 PC3_C ------> FMC_SDCKE0 PH5 ------> FMC_SDNWE PF11 ------> FMC_SDNRAS PF12 ------> FMC_A6 PF13 ------> FMC_A7 PF14 ------> FMC_A8 PF15 ------> FMC_A9 PG0 ------> FMC_A10 PG1 ------> FMC_A11 PE7 ------> FMC_D4 PE8 ------> FMC_D5 PE9 ------> FMC_D6 PE10 ------> FMC_D7 PD14 ------> FMC_D0 PD15 ------> FMC_D1 PG4 ------> FMC_BA0 PG5 ------> FMC_BA1 PG8 ------> FMC_SDCLK PD0 ------> FMC_D2 PD1 ------> FMC_D3 PG15 ------> FMC_SDNCAS */ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_11|GPIO_PIN_12 |GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; 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(GPIOF, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3; 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(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = 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(GPIOH, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5 |GPIO_PIN_8|GPIO_PIN_15; 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(GPIOG, &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.Pin = GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1; 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); /* USER CODE BEGIN FMC_MspInit 1 */ /* USER CODE END FMC_MspInit 1 */ } void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef* hsdram){ /* USER CODE BEGIN SDRAM_MspInit 0 */ /* USER CODE END SDRAM_MspInit 0 */ HAL_FMC_MspInit(); /* USER CODE BEGIN SDRAM_MspInit 1 */ /* USER CODE END SDRAM_MspInit 1 */ } static void MX_FMC_Init(void) { /* USER CODE BEGIN FMC_Init 0 */ #define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000) #define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001) #define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002) #define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0003) #define SDRAM_MODEREG_BURST_LENGTH_FULL ((uint16_t)0x0007) #define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) #define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) #define SDRAM_MODEREG_CAS_LATENCY_1 ((uint16_t)0x0010) #define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020) #define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030) #define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000) #define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) #define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) FMC_SDRAM_CommandTypeDef SdramCommand; /* USER CODE END FMC_Init 0 */ FMC_SDRAM_TimingTypeDef SdramTiming = {0}; /* USER CODE BEGIN FMC_Init 1 */ /* USER CODE END FMC_Init 1 */ /** Perform the SDRAM1 memory initialization sequence */ hsdram1.Instance = FMC_SDRAM_DEVICE; /* hsdram1.Init */ hsdram1.Init.SDBank = FMC_SDRAM_BANK1; hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9; hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12; hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_8; hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3; hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2; hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE; hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0; /* SdramTiming */ SdramTiming.LoadToActiveDelay = 4; SdramTiming.ExitSelfRefreshDelay = 1; SdramTiming.SelfRefreshTime = 6; SdramTiming.RowCycleDelay = 9; SdramTiming.WriteRecoveryTime = 3; SdramTiming.RPDelay = 3; SdramTiming.RCDDelay = 3; if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK) { Error_Handler( ); } /* USER CODE BEGIN FMC_Init 2 */ SdramCommand.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; SdramCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; SdramCommand.AutoRefreshNumber = 1; SdramCommand.ModeRegisterDefinition = 0; HAL_SDRAM_SendCommand(&hsdram1, &SdramCommand,1000); HAL_Delay( 1 ); SdramCommand.CommandMode = FMC_SDRAM_CMD_PALL; SdramCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; SdramCommand.AutoRefreshNumber = 1; SdramCommand.ModeRegisterDefinition = 0; HAL_SDRAM_SendCommand(&hsdram1, &SdramCommand,1000); SdramCommand.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; SdramCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; SdramCommand.AutoRefreshNumber = 8; SdramCommand.ModeRegisterDefinition = 0; HAL_SDRAM_SendCommand(&hsdram1, &SdramCommand,1000); HAL_Delay( 1 ); SdramCommand.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; SdramCommand.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; SdramCommand.AutoRefreshNumber = 1; SdramCommand.ModeRegisterDefinition = SDRAM_MODEREG_BURST_LENGTH_1 | SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | SDRAM_MODEREG_CAS_LATENCY_3 | SDRAM_MODEREG_OPERATING_MODE_STANDARD | SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; HAL_SDRAM_SendCommand(&hsdram1, &SdramCommand,1000); hsdram1.Instance->SDRTR |= (1933<<1); // unsigned int i=0, j; // static unsigned long t[256]; // unsigned long c = 0, q = 777; // //p = (void *)0xC0000000; // while( 1 ) { // for( i=0; i < 256; i++ ) {p[i*q] = c++; t[i] = p[i*q];} // for( i=0; i < 256; i++ ) {p[i] = c++;} //t[i & 0xff] = p[i];} // for( i=0; i < 256; i++ ) t[i] = p[i]; // for( i=0; i < 2*1024*1024; i++ ) {p[i] = c++;} //t[i & 0xff] = p[i];} // //c=(c==0xaaaaaaaa)?0x55555555:0xaaaaaaaa; // for( i=0; i < 2*1024*1024; i++ ) t[i & 0xff] = p[i]; // } /* USER CODE END FMC_Init 2 */ } В конце закомментированные тесты для проверки работы. Теперь взялся запускать эзернет с LAN8720A. В примерах идет LAN8742 , но я посмотрел что код не использует то, чем они отличаются программно. Использую FreeRTOS 10, тот что куб вложил. MPU не активирую, нужды вроде нет. Но вопрос в том, что писали про то, как правильно настроить MPU, а если я его не активирую вообще? Проблема в том, что пакеты приходят, что видно по ножкам RXD0/1 RS_DV. Но вот прерывание если и случается, то только один раз после инициализации. DMA буфера смотрят на 0x3000, как завещают на ST. Результаты инициализации проверил по регистрам, вроде все в порядке. Все остальные переменные и буфера живут в области 0х2400. Пните меня, чего проверить, что упустил. Схема соответствует NUCLEO-734VI REF_CLK идет из физики.
  10. Нашел, явно не указано, но косвенно стало понятно, что этот чип SDRAM умеет читать только пакетами (burst). Включил в настройке регистров чипа чтение всей страницы. Теперь он действительно читает много. Но вот незадача. В момент, когда происходит autorefresh, чип прекращает читать, а STMка и далее дергает CASом и думать, что ей будут давать данные, страница то не менялась.
  11. На CKE постоянно 1. На CLK клок. Сначала сделал на 100 МГц. Потом для упрощения отладки сделал 50 МГц, но с сохранением интервала ауторефреша 64 мс / 4096 Не совсем. Если DQM = 0, то в момент ауторефреш идет выброс на шине, а если =1, то шина висит постоянно. Собственно наличие выбросов в момент ауторефреша и говорит, что, в принципе, микросхема умеет работать с шиной.
  12. Только в даташите про нее нормально ничего не сказано. Сделал возможность подать и 0 и 1. Но это не изменяет ситуации.
  13. Эти емкости любимая проблема и STMок. Приходят из другой партии часовые кварцы и не стартуют, нужно менять емкости. Иногда стартуют, осциллоскопом видно, но амплитуда недостаточная, что бы сработал датчик LSE
  14. Получил из производства пару новоразработанных плат с озвученными чипами. Остальное не важно. Не могу запустить это 8-и битный SDRAM на FMC. Смотрю четырехканальным осциллоскопом, вроде все команды и временные диаграммы в порядке. Специально сделал после записи долгий цикл на чтение и заметил, что шина данных не управляется чипом. Если взять резистором и сделать подтяжку к земле или плюсу, то этот бит утягивается туда же, за исключением коротких моментов autorefresh. Я ожидаю, что шина должны управляться, когда nSC=0 nCAS=0 nRAS=1 nWE=1. Сочетание этих битиков проверено на осциллограммах, но шина не управляется чипом ОЗУ. Можно ли считать, что чип попался битый (на обоих платах) или надо бы еще что проверить? Тайминги, частоты и т.п. менял. Инициализация как положено с записью в регистры. В т.ч. собственно запись в регистр в режиме пошаговой отладки проверена на осциллограмме. Есть странная нога DQM у этого чипа, которая не имеет смысла для 8-и битного чипа и FMC под нее ничего не назначает. Пробовал ее и в 0 и 1 - не повлияло.
  15. Супер! Спасибо, все заработало
×
×
  • Создать...