Jump to content

    

V_M_Luck

Участник
  • Content Count

    55
  • Joined

  • Last visited

Posts posted by V_M_Luck


  1. Добрый день уважаемый V_M_Luck. Работаю с той же физикой KSZ8041.

    Вопрос следующий: как вы изменили файл stm32_eth.h, а конкретно мне интересно

    та часть кода где указывается адрес PHY_SR, регистра который у каждой физики разный

    Извините, что сразу не ответил. Если еще актуально...

    Все адреса регистров и биты описаны в даташите на KSZ8041.

    Фактически, если работаете с библиотеками STM, вам нужно оперделить адреса регистров и биты и слегка подправить ETH_Init в файле stm32fxxx_eth.c.

    У меня в этой функции от настройки физики оставлено только это:

      /*-------------------- PHY initialization and configuration ----------------*/
      /* Put the PHY in reset mode */
      if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_Reset)))
      {
        /* Return ERROR in case of write timeout */
        return ETH_ERROR;
      }
      
      while(ETH_ReadPHYRegister(PHYAddress, PHY_BCR) & PHY_Reset);
    
      /* Enable Auto-Negotiation */
      if(!(ETH_WritePHYRegister(PHYAddress, PHY_ANAR, PHY_ANAR_100BTX_FD | PHY_ANAR_100BTX_HD | PHY_ANAR_10BT_FD | PHY_ANAR_10BT_HD | PHY_ANAR_SELECT)))
      {
        /* Return ERROR in case of write timeout */
        return ETH_ERROR;
      }
      /* Start Auto-Negotiation */
      if(!(ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_AutoNegotiation | PHY_Restart_AutoNegotiation)))
      {
        /* Return ERROR in case of write timeout */
        return ETH_ERROR;
      }

    И, далее, в какой-нибудь низкоуровневой задаче (или просто в main) проверять состояние подключения (идею и куски кода позаимствовал у кого-то на форуме - большое ему спасибо):

      if (ETH_ReadPHYRegister(PHY_ADDRESS, PHY_BSR) & PHY_Linked_Status)
      {
        //Соединение установлено
        switch(prev_link_state)
        {
        case 0:
          RegValue = ETH_ReadPHYRegister(PHY_ADDRESS, PHY_CNTR2) & PHY_CNTR2_OP_MODE;
          
          switch(RegValue)
          {
          case PHY_CNTR2_OP_MODE_10HD:  // 10 BASE T Half-duplex
            prev_link_state=1;
            RegValue = PHY_HALFDUPLEX_10M;
            ETH_WritePHYRegister(PHY_ADDRESS, PHY_BCR, RegValue);
            RegValue = ETH->MACCR;
            RegValue &= ~(ETH_MACCR_FES | ETH_MACCR_DM);
            ETH->MACCR = RegValue;
            break;
          case PHY_CNTR2_OP_MODE_100HD:  // 100 BASE TX Half-duplex
            prev_link_state=1;
            RegValue = PHY_HALFDUPLEX_100M;
            ETH_WritePHYRegister(PHY_ADDRESS, PHY_BCR, RegValue);
            RegValue = ETH->MACCR;
            RegValue &= ~(ETH_MACCR_FES | ETH_MACCR_DM);
            RegValue |= ETH_MACCR_FES;
            ETH->MACCR = RegValue;
            break;
          case PHY_CNTR2_OP_MODE_10FD: // 10 BASE T Full-duplex
            prev_link_state=2;
            RegValue = PHY_FULLDUPLEX_10M;
            ETH_WritePHYRegister(PHY_ADDRESS, PHY_BCR, RegValue);
            RegValue = ETH->MACCR;
            RegValue &= ~(ETH_MACCR_FES | ETH_MACCR_DM);
            RegValue |= ETH_MACCR_DM;
            ETH->MACCR = RegValue;
            break;
          case PHY_CNTR2_OP_MODE_100FD: // 100 BASE TX Full-duplex
            prev_link_state=2;
            RegValue = PHY_FULLDUPLEX_100M;
            ETH_WritePHYRegister(PHY_ADDRESS, PHY_BCR, RegValue);
            RegValue = ETH->MACCR;
            RegValue |= (ETH_MACCR_FES | ETH_MACCR_DM);
            ETH->MACCR = RegValue;
            break;
          default:
            break;
          }
        case 1:
          
          break;
        }
      }
      else
      {
        //Нет соединения
        if (prev_link_state) 
        {
          //Соединение было потеряно
          prev_link_state=0;
          // Enable and start Auto-Negotiation
          ETH_WritePHYRegister(PHY_ADDRESS, PHY_BCR, PHY_AutoNegotiation | PHY_Restart_AutoNegotiation);
        }
      }

  2. Причем тут флуд? На ваш вопрос конкретный ответ.

    >Повторяю, проблема в том, как снять Read protect, write protect и после этого продолжить процедуру обновления.

    таким образом никак. Переписывайте загрузчик, устраняйте ошибки.

    Понятно. Спасибо.

    Все-таки я уточню. Возможно меня не так поняли. Снимать read protect мне не нужно. Просто без снятия этого бита нельзя снять защиту от записи двух первых страниц - а там и расположен мой загрузчик. Получается, что обновить загрузчик на уже прошитых устройствах можно только при помощи jtag...

  3. Уважаемые!

    Я не понимаю ваших ответов. У меня вполне конкретный вопрос, никаких "снятий" прошивок мне не нужно. При проектировании загрузчика в нашем устройстве были допущены неточности. Загрузчик нужно обновить. Если все так просто, поясните как. Если ничего конкретного по теме нет - не флудите.

  4. Ну так создайте приложение, в составе которого будет образ нового загрузчика, после запуска снимите защиту и перепрошейте новый загрузчик.

    Проблема не в алгоритме обновления загрузчика. Это все и ежу понятно.

    Повторяю, проблема в том, как снять Read protect, write protect и после этого продолжить процедуру обновления.

  5. Камень STM32F103RCT6.

    Есть проект с загрузчиком. Загрузчик располагается по младшим адресам FLASH (16 первых страниц). На старте загрузчик проверяет и в случае необходимости выставляет ReadProtect bit в FLASH_OBR.

    Возникла необходимость перезашить загрузчик. Оказалось, что при выставлении ReadProtect bit первые две страницы автоматически становятся write-protected. Что бы снять защиту от записи, необходимо запуститься из ОЗУ, снять ReadProtect, полностью сотрется весь FLASH, перезапуститься. Запуск контроллера произойдет опять из FLASH, а там прошивки уже нет никакой. Дергать ножками BOOT нет возможности.

    Возможно как-то можно обойтись без перезапуска всего? Или как-то еще можно разрулить эту проблему?

  6. Попробуйте запустить сервер на не блокирующих сокетах..

    Для UDP вродебы нет смысла, там нет установления соединений, ожидания подтверждений и т.п. Да и пакеты я шлю небольшие. От компа 160 байт, в обратную сторону - 60 байт.

    Так если используете плагин AVIX-RT для RTOS, то в окошке Tasks можно посмотреть Event Object. Если задача заблокирована то в Event Object отображается адресс обьекта (очередь/мьютекс) котораый заблокировал задачу.

    Я и смотрю. Состояние задачи READY! Ничего не блокирует. А шедулер на эту задачу не переключает.

     

    Вот что еще накопал.

    Во время сбоя стал бряком в vTaskSwitchContext( ). Вижу, что в pxReadyTasksLists на списке уровня приоритета 6 (задача ethernetif_input) задача есть. А в переменной uxTopReadyPriority то 0, то 1. Т.е. шедулер так и не узнал о существовании готовой высокоприоритетной задачи. Или что-то ему помешало переключиться на эту задачу при ее размещении в очереди готовых. Если руками здесь подправить uxTopReadyPriority на 6, все начинает крутиться дальше, правда до следующего сбоя.

    Справедливости ради, необходимо отметить, что иногда, гораздо реже, чем возникновение проблемы, описанной в топике, я сваливаюсь в HardFault. Видимо разваливается стек. Что из этих проблем первично - не совсем понятно, но проблема с зависанием задачи возникает чаще, пока разбираюсь с ней.

  7. Продолжаю разбираться с FreeRTOS+LwIP. Камень STM32F207, физика KSZ8041.

    Делаю простой UDP сервер, netconn, на основе примера ST.

     

    Симптом следующий.

    Посылаю с ПК запросы, устройство отвечает. Примерно через полчаса такой работы ответы приходить перестают. Просмотр состояния задач, очередей показал, что задача ethernetif_input висит в состоянии READY, но sheduler ее не запускает. Cемафор s_xSemaphore заполняется полностью. При этом другие задачи с меньшим приоритетом (мигание лампочки) выполняться продолжают.

     

    Прочитал топик, внес изменения в ethernetif.c, это ни к чему не привело.

    static void ethernet_watchdog(void) {
       /* When Rx Buffer unavailable flag is set: clear it and resume reception */
       if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)  
       {
           /* Clear RBUS ETHERNET DMA flag */
           ETH->DMASR = ETH_DMASR_RBUS;   
    
           /* Resume DMA reception. The register doesn't care what you write to it. */
           ETH->DMARPDR = 0;
       }
    }
    
    unsigned int thread_cnt = 0;
    void ethernetif_input( void * pvParameters )
    {
     struct pbuf *p;
    
     for( ;; )
     {
       if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE)
       {
         while ((p = low_level_input( s_pxNetIf )) != 0) 
    //      p = low_level_input( s_pxNetIf );
         {
           thread_cnt++;
           if (p != 0) {
               if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf))
               {
                 pbuf_free(p);
                 p=NULL;
               }
           }
         }
       }
       ethernet_watchdog();
     }
    }

     

    Настройки FreeRTOS:

    #define configUSE_PREEMPTION		1
    #define configUSE_IDLE_HOOK	        0
    #define configUSE_TICK_HOOK	        0
    #define configCPU_CLOCK_HZ              ( ( unsigned long ) 120000000 )	
    #define configTICK_RATE_HZ	        ( ( portTickType ) 1000 )
    #define configMAX_PRIORITIES		( ( unsigned portBASE_TYPE ) 7 )
    #define configMINIMAL_STACK_SIZE	( ( unsigned short ) 128 )
    #define configTOTAL_HEAP_SIZE		( ( size_t ) ( 15 * 1024 ) )
    #define configMAX_TASK_NAME_LEN		( 16 )
    #define configUSE_TRACE_FACILITY	0
    #define configUSE_16_BIT_TICKS		0
    #define configIDLE_SHOULD_YIELD		1
    #define configUSE_MUTEXES               1
    #define configUSE_COUNTING_SEMAPHORES   1
    #define configUSE_MALLOC_FAILED_HOOK    0
    
    //For queue trace
    #define configQUEUE_REGISTRY_SIZE       5
    
    #define configCHECK_FOR_STACK_OVERFLOW  0
    
    /* Co-routine definitions. */
    #define configUSE_CO_ROUTINES 		0
    #define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
    
    /* Set the following definitions to 1 to include the API function, or zero
    to exclude the API function. */
    
    #define INCLUDE_vTaskPrioritySet		0
    #define INCLUDE_uxTaskPriorityGet		0
    #define INCLUDE_vTaskDelete			0
    #define INCLUDE_vTaskCleanUpResources	        0
    #define INCLUDE_vTaskSuspend			0
    #define INCLUDE_vTaskDelayUntil			0
    #define INCLUDE_vTaskDelay		        1
    
    /* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
    (lowest) to 0 (1?) (highest). */
    #define configKERNEL_INTERRUPT_PRIORITY         255
    #define configMAX_SYSCALL_INTERRUPT_PRIORITY 	191 /* equivalent to 0xb0, or priority 11. */
    
    
    /* This is the value being used as per the ST library which permits 16
    priority values, 0 to 15.  This must correspond to the
    configKERNEL_INTERRUPT_PRIORITY setting.  Here 15 corresponds to the lowest
    NVIC value of 255. */
    #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY	15

     

    Настройки LwIP:

    #define SYS_LIGHTWEIGHT_PROT    1
    
    #define ETHARP_TRUST_IP_MAC     0
    #define IP_REASSEMBLY           0
    #define IP_FRAG                 0
    #define ARP_QUEUEING            0
    
    #define LWIP_TCPIP_CORE_LOCKING 0
    
    #define NO_SYS                  0
    
    #define MEM_ALIGNMENT           4
    
    #define MEM_SIZE                (20*1024)
    
    #define MEMP_NUM_PBUF           200
    #define MEMP_NUM_UDP_PCB        6
    #define MEMP_NUM_TCP_PCB        10
    #define MEMP_NUM_TCP_PCB_LISTEN 5
    #define MEMP_NUM_TCP_SEG        20
    #define MEMP_NUM_SYS_TIMEOUT    10
    
    #define PBUF_POOL_SIZE          20
    
    #define PBUF_POOL_BUFSIZE       500
    
    #define LWIP_TCP                0
    #define TCP_TTL                 255
    
    #define LWIP_ICMP                       1
    
    #define LWIP_DHCP               0
    
    #define LWIP_UDP                1
    #define UDP_TTL                 255
    
    /* ---------- Statistics options ---------- */
    #define LWIP_STATS 1
    #define ETHARP_STATS 1
    #define UDP_STATS 1
    #define LWIP_PROVIDE_ERRNO 1
    #define MEM_STATS 1
    
    
    #define CHECKSUM_BY_HARDWARE 
    
    #define LWIP_NETCONN                    1
    
    #define LWIP_SOCKET                     0
    
    #define LWIP_DEBUG                      0
    
    #define TCPIP_THREAD_STACKSIZE          1000
    #define TCPIP_MBOX_SIZE                 50
    #define DEFAULT_UDP_RECVMBOX_SIZE       2
    #define DEFAULT_TCP_RECVMBOX_SIZE       20
    #define DEFAULT_ACCEPTMBOX_SIZE         20
    #define DEFAULT_THREAD_STACKSIZE        500
    #define TCPIP_THREAD_PRIO               (configMAX_PRIORITIES - 2)
    

     

     

     

  8. Возможно. Но если я вижу активность на TXEN, значит из MAC все уходит. Получается, что на физике запрещена трансляция броадкастов? Такое может быть?

    Физика KSZ8041TL.

  9. Да вроде не известно о таком, выложите дамп этого запроса, глянем, но вряд ли там чего-то криминальное. А broadcast' ы в принципе от вашей железки улетают?

    Смотрел сразу после копирования в область DMA

    Первым формируется вот это запрос:

     

    FFFFFFFFFFFF - Destination MAC

    30EC0068ADE1 - Мой MAC

    0806 - ARP

    0001 - HTYPE Ethernet

    0800 - PTYPE IPv4

    06 - HLEN

    04 - PLEN

    0001 - Operation

    30EC0068ADE1 - SHA

    C0A8000A- SPA (192.168.0.10)

    000000000000 - THA

    C0A8000A - TPA (192.168.0.10) ????

     

    Почему-то SPA и TPA одинаковы. Я так думаю - проверка на конфликт адресов в подсети.

    Далее идут запросы, в которых TPA = C0A8000B (192.168.0.11). Это как-раз адрес узла, на который идет отправка.

     

    По поводу broadcast - вот он, единственный. И не уходит. Может где чего в MAC разрешить надо? Но что-то не нашел.

     

    А я так понимаю железка к компьютеру с Wireshrk'ом напрямую подключена? А если повторить попытку послать пакет, получается или нужен обязательно пакет от кого-то?

    Извиняюсь, упустил пост.

    Железка подключена напрямую. Повтор попыток отправки ничего не дает. Вот если с ПК придет ARP запрос, то с моего устройства уходит правильный ответ, MAC адрес ПК прописывается в ARP таблице и дальше все работает.

  10. У меня ножки на 50МГц настроены. Так интересно, что отправка работает стабильно. Всего, кроме ARP запросов. Может есть какой косяк в lwip в самой структуре ARP запроса?

  11. К сожалению с STM32f2xx не знаком - боюсь увести в неверном направлении.

    Насколько я понимаю у Вас не передается самый первый пакет?

    В некоторых случаях проще повторить попытку передачи. Например, в uIP зачем-то посылается два пакета в сеть вместо одного.

    Если есть осциллограф, то можно посмотреть ногу ETH_TXEN на наличие импульса отправки "неприходящего" пакета.

    Спасибо, завтра гляну.

  12. Erratу для STM32 по поводу Ethernet-MAC читали? Ваш случай?

    Уточните, пожалуйста, что вы имеете ввиду? Erratу посмотрел, но там вроде ограничения по CRC при использовании IPv6. Store and Forward использую, MCO не использую. Вроде бы все.

  13. Совершенно верно. Запрос не виден. Причем обратный запрос от компа и ответ на него замечательно видны и обрабатываются на ура. В принципе мне это не сильно мешает. Планируется устройство UDP сервер. Просто непонятный камушек не хочется оставлять.

  14. Начинаю разбираться с Ethernet. Контроллер STM32F207. Иду по обычному пути - пример от ST LwIP+FREERTOS. Сделал простенькую задачу, в которой отправляю пакеты по UDP. В принципе работает.

    НО. Если просто запустить проект, никаких пакетов на стороне PC не наблюдается (Wireshark). Вот если как-нибудь дернуть мой девайс со стороны компа (например ECHO запросить) - сразу все оживает. Поразбиравшись обнаружил, что при старте не заполняется ARP таблица. При чем ARP запрос формируется. Я проследил до low_level_output. Там все нормально. Смотрел счетчик ушедших паетов ETH_MMCTGFCR в EMAC - все соответствует количеству ARP запросов. Но Wireshark молчит.

    Как-то так.

    Может кто сталкивался - подскажите куда смотреть.

  15. В исходном виду у вас прерывание вообще не происходит до полного окончания DMA трансфера. Вы измеряете интервал между импульсами на PB6, а не разность фаз, естественно результат неверен.

     

    Человек именно и измеряет разность фаз. И как по вашему прерывание от внешней линии зависит от DMA capture?

     

  16. Поэтому, имхо, грамотный подход - это использовать представленные специально для этого средства и не заморачиваться на порядок выполнения выражений.

    А как грамотно в данном случае использовать DSB?

     

    Например, в случае с таймером:

    void TIM4_IRQHandler(void)
    {    
        if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
        {
           ...
            TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
            __DSB();
            ...
        }
    
    }

     

    Так верно?

  17. Уважаемый brag.

    Либы не юзаю, тк у меня ось своя и оно не совместимо, да и не люблю я эти либы, то,что там прописано,вернее то,что тебе нужно из того что там прописано :) прописывается за день-два.

    В доке все почти хорошо описано, если прочитать ее несколько раз )

     

    пс. в инете примеров для OTG_FS stm32f1xx не нашел )

     

    вот мой кодик. код местами блокирует систему - в прерывании есть циклические ожидания, писалось чтобы освоить otg_fs в stm32f1, но и применяю уже. на какое время блокирует не проверял, но пока устраивает.

    Я так-же делаю otg без фреймворка. У меня так удачно прочитать доки что-то не получилось.

    Я задал свой вопрос http://electronix.ru/forum/index.php?showtopic=92328. Но потом нашел это обсуждение и решил обратиться к вам в этой ветке.

    Ваш пример внимательно изучил. Не вижу принципиальной разницы со своим кодом. Тем не менее у меня не работает. Проблема - получаю запрос дескриптора устройства, отправляю этот дескриптор - и все. ни ответа ни привета.

    Мой кодик. usb_otg.txt Это очень черновой вариант.

    Посмотрите пожалуйста, ткните носом, что не так.

  18. Вновь поднимаю тему.

    Пример-то заработал. Но тянуть к себе в проект дикий фреймворк из-за одного эндпоинта для HID совсем не хочется. Стал разбираться в регистрах по даташиту и примеру.

    Инициализацию вроде-бы сделал. Получаю USBRST, ENUMDNE, потом получаю запрос GET_DEVICE_DESCRIPTOR.

    И тут-то все начинается. Настраиваю DIEPTSIZ0, DIEPCTL0 .

    Помещаю в фифо данные.

    Получаю прерывание на IN endpoint XFRCM. Вроде все ОК. Но HOST этого дескриптора не видит. В результате, вместо SET_ADDRESS опять получаю GET_DEVICE_DESCRIPTOR и все по кругу. Так раз 5 и HOST прекращает енумерацию.

     

    Уже два дня голову ломаю. Может кто-нибудь сталкивался? Подскажите, в какую сторону посмотреть.

  19. Разбираюсь с USB FS OTG на STM32F107. Есть плата с STM32F107 и USB. Мне нужен только device. Что то самостоятельно по даташиту не очень получилось. Попытался запустить пример HID от ST из STM32_USB-FS-Device_Lib_V3.3.0. Не работает. Попадает пару раз в прерывание по RESET, потом в ENUMDN и все. Больше никакой активности.

    Смотрел USB TRACE - host даже не пытается запрашивать дескрипторы.

    Вопрос - у кого-нибудь этот пример заработал?

     

    Извините. Нашел у себя косяк - пример заработал.