Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Работа с VCP
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Jenya7
Я получаю строку с терминала
Код
int main(void)
{
  Set_System();
  Set_USBClock();
  USB_Interrupts_Config();
  USB_Init();

  while (1)
  {
    if (bDeviceState == CONFIGURED)
    {
      CDC_Receive_DATA();
      /*Check to see if we have data yet */
      if (Receive_length  != 0)
      {
        PARSER_ParseCommand((char *)Receive_Buffer);
        Receive_length = 0;
      }
    }
  }
}

Обрабатываю строку и посылаю ответ
Код
CDC_Send_DATA((uint8_t *)strbuf, strlen(strbuf));


Проблема вот в чем - если я ставлю точку останова на самой строке CDC_Send_DATA и потом Step Over - то я вижу ответ в терминале.
А если код свободно бежит - на терминал не приходит ответ. Что то с синхронизацией, не могу понять.
0men
strbuf попробуйте объявить как глобальный массив
Jenya7
Цитата(0men @ Feb 27 2018, 15:25) *
strbuf попробуйте объявить как глобальный массив

он у меня аргумент функции. генерик функция посылает или по UART или по USB.
Код
void Parser_SendInt(USART_TypeDef *USARTx, int32_t number, uint32_t cr, uint32_t out)
{
    char strbuf[10]="";
    uint32_t sign = 0;
        
    if (number<0)
    {
    number *= -1;
    sign = 1;
    }
        
    ItoA(number, strbuf);
        
    switch (out)
    {
    case 0:  //UART
            if (sign)
                USART_SendString(USARTx,"-");
                
        USART_SendString(USARTx,strbuf);
                
       if(cr)
            USART_SendString(USARTx,"\r");
    break;
                
    case 1:  //USB
            if (sign)
                CDC_Send_DATA((uint8_t *)"-", 1);
                
             CDC_Send_DATA((uint8_t *)strbuf, strlen(strbuf));
                
             if(cr)
                CDC_Send_DATA((uint8_t *)"\r", 1);
              
     break;    
    }
}
0men
char strbuf[10]="";

вот это объявите вне функции - глобально. Она останется аргументом
Jenya7
Цитата(0men @ Feb 27 2018, 16:11) *
char strbuf[10]="";

вот это объявите вне функции - глобально. Она останется аргументом

объявил. не помогло.
0men
Цитата(Jenya7 @ Feb 27 2018, 14:15) *
объявил. не помогло.


CDC_Send_DATA использует USBD_CDC_TransmitPacket? Посмотрите, что возвращают функции
Jenya7
Цитата(0men @ Feb 27 2018, 16:22) *
CDC_Send_DATA использует USBD_CDC_TransmitPacket? Посмотрите, что возвращают функции

для F103 было что то вроде этого. по человечески.
а тут крайне странная функция
Код
uint32_t CDC_Send_DATA (uint8_t *ptrBuffer, uint8_t Send_length)
{
  /*if max buffer is Not reached*/
  if(Send_length < VIRTUAL_COM_PORT_DATA_SIZE)    
  {
    /*Sent flag*/
    packet_sent = 0;
    /* send  packet to PMA*/
    UserToPMABufferCopy((unsigned char*)ptrBuffer, ENDP1_TXADDR, Send_length);
    SetEPTxCount(ENDP1, Send_length);
    SetEPTxValid(ENDP1);
  }
  else
  {
    return 0;
  }
  return 1;
}

ставлю точку останова на UserToPMABufferCopy - вижу ptrBuffer = 10 Send_length = 2 - все верно. и на терминале вижу - 10. без точки останова - на терминал не приходит ничего.
0men
Цитата(Jenya7 @ Feb 27 2018, 14:33) *
ставлю точку останова на UserToPMABufferCopy - вижу ptrBuffer = 10 Send_length = 2 - все верно. и на терминале вижу - 10. без точки останова - на терминал не приходит ничего.


Значит надо копать внутрь этих функций.
Jenya7
Цитата(0men @ Feb 27 2018, 16:55) *
Значит надо копать внутрь этих функций.

копаю. не могу докопатся.
я посмотрел в демо проекте пользуются флагом
Код
if (packet_sent == 1)
    CDC_Send_DATA((uint8_t *)Receive_Buffer, strlen((char *)Receive_Buffer));

этот флаг устанавливается в
Код
void EP1_IN_Callback (void)
{
  packet_sent = 1;
}

я вставил костыль
Код
uint32_t CDC_Send_DATA (uint8_t *ptrBuffer, uint8_t Send_length)
{
    uint32_t timeout=0;

  /*if max buffer is Not reached*/
  if(Send_length < VIRTUAL_COM_PORT_DATA_SIZE)    
  {

     //------moi kostyl---------------

     while(packet_sent == 0)
     {
         if(++timeout > 10000) break;
     }
    //---------------------------------
    
    /*Sent flag*/
    packet_sent = 0;
    /* send  packet to PMA*/
    UserToPMABufferCopy((unsigned char*)ptrBuffer, ENDP1_TXADDR, Send_length);
    SetEPTxCount(ENDP1, Send_length);
    SetEPTxValid(ENDP1);
  }
  else
  {
    return 0;
  }
  return 1;
}

так работает но мне это не нравиться. как можно разрулить это красивее?
toweroff
Тоже плевался на реализацию куба, пока отложил, есть другие задачи, но общее решение у меня нарисовалось вот какое (надо проверить) :

1. Отправка данных через функцию, в которой проверка, отправляется ли в данный момент по usb что-то или нет. Если да - добавляем в буфер, нет - вызываем CDC_Send_DATA с размером точки, остальное в буфер, ставим флаг активности.
2. В EP1_IN_Callback смотрим, есть что в буфере или нет. Есть - CDC_Send_DATA с размером точки (если данных больше), кончились данные - снимаем флаг

Jenya7
Цитата(toweroff @ Feb 28 2018, 01:01) *
Тоже плевался на реализацию куба, пока отложил, есть другие задачи, но общее решение у меня нарисовалось вот какое (надо проверить) :

1. Отправка данных через функцию, в которой проверка, отправляется ли в данный момент по usb что-то или нет. Если да - добавляем в буфер, нет - вызываем CDC_Send_DATA с размером точки, остальное в буфер, ставим флаг активности.
2. В EP1_IN_Callback смотрим, есть что в буфере или нет. Есть - CDC_Send_DATA с размером точки (если данных больше), кончились данные - снимаем флаг

ого. фига се. sm.gif. пока что уменьшил до 1000 - if(++timeout > 1000) break; - работает стабильно и слава богу. все равно это допольнительная фича для настройки параметров, типа nice-to-have, если лень UART подключать.
Jenya7
Пошел на другой комп - тоже Windows 7. Втыкаю - не распознается. Скачал с ST сайта vcp driver, установил - все равно не распознается.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.