STM32f107 USB VCP
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32f107 USB VCP
У тебя CDC класс. После прохождения енумерации полезные данные ходят через EP1. Принимаемые данные кладутся в прерываниях в приёмный буфер. Передаваемые Записываешь в EP1 c помощью WriteINEP и они сами уходят.
- Реклама
Re: STM32f107 USB VCP
то есть передача в комп идет по прерыванию? чет я честно говоря не понял
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32f107 USB VCP
Нет. По прерыванию приём с компа. В моём примере в этом же прерывании символ передаётся обратно чтобы эхо в терминале было. А так можешь когда хочешь передавать, только проверить что очередь отправки пуста.
Re: STM32f107 USB VCP
ну вот, видимо очередь не пустая, хотя через терминал вижу что все пришло, и второй раз не отправляет
Добавлено after 20 minutes 33 seconds:
Get_TX_Q_cnt этой функцией очередь проверять?
Добавлено after 41 minute 48 seconds:
вот такая картина
Добавлено after 20 minutes 33 seconds:
Get_TX_Q_cnt этой функцией очередь проверять?
Добавлено after 41 minute 48 seconds:
вот такая картина
- Вложения
-
- Безымянный.jpg
- (213.78 КБ) 444 скачивания
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32f107 USB VCP
Там очередь создаётся только если отправляешь данных больше 64 байт. Например, один из дескрипторов 67 байт вроде как. На коротких сообщениях очередь не задействуется.
У тебя как организован обмен? Если запрос-ответ, то не надо ничего проверять, просто пишешь в ep1 с помощью WriteINEP. У тебя так эхо в терминале работает. Без разницы один байт или много ты в ответ будешь посылать. Попробуй для начала не эхо слать, а какое-нибудь слово, типа "Привет!".
Если инициатором обмена является само устройство, то надо проверить в каком состоянии конечная точка (или FIFO не помню) перед отправкой . Это RM надо почитать. Там не сложно должно быть.
У тебя как организован обмен? Если запрос-ответ, то не надо ничего проверять, просто пишешь в ep1 с помощью WriteINEP. У тебя так эхо в терминале работает. Без разницы один байт или много ты в ответ будешь посылать. Попробуй для начала не эхо слать, а какое-нибудь слово, типа "Привет!".
Если инициатором обмена является само устройство, то надо проверить в каком состоянии конечная точка (или FIFO не помню) перед отправкой . Это RM надо почитать. Там не сложно должно быть.
- Реклама
Re: STM32f107 USB VCP
void USB_CDC::EP1_OUT_Int(void)
{
uint32_t epint = USB_OTG_OUTEP(1)->DOEPINT;
if(epint & USB_OTG_DOEPINT_XFRC)
{
WriteINEP(0x01,buffusb,7);
}
USB_OTG_OUTEP(1)->DOEPINT = epint;
USB_OTG_OUTEP(1)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
};
вот процедура, с пк я отсылаю, принимаю и отправляю в ответ "привет", затем вышел в общий цикл, жду, отправляю еще с пк, принимаю ответ, попадаю на процедуру WriteINEP, она вся проходит, но на комп ничего не прилетает
{
uint32_t epint = USB_OTG_OUTEP(1)->DOEPINT;
if(epint & USB_OTG_DOEPINT_XFRC)
{
WriteINEP(0x01,buffusb,7);
}
USB_OTG_OUTEP(1)->DOEPINT = epint;
USB_OTG_OUTEP(1)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
};
вот процедура, с пк я отсылаю, принимаю и отправляю в ответ "привет", затем вышел в общий цикл, жду, отправляю еще с пк, принимаю ответ, попадаю на процедуру WriteINEP, она вся проходит, но на комп ничего не прилетает
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32f107 USB VCP
Давай так. По приёму сообщения от компа в прерывании ставь флаг, что получил данные. А в основном цикле по наличию флага обрабатывай эти данные и отсылай ответ. Не чему там не работать. Эта же функция передаёт данные через ep0 при энумерации, а там они до 67 байт в моём примере.
Re: STM32f107 USB VCP
[uquote="VladislavS",url="/forum/viewtopic.php?p=3526455#p3526455"]Давай так. По приёму сообщения от компа в прерывании ставь флаг, что получил данные. А в основном цикле по наличию флага обрабатывай эти данные и отсылай ответ. Не чему там не работать. Эта же функция передаёт данные через ep0 при энумерации, а там они до 67 байт в моём примере.[/uquote]
https://dropmefiles.com/DXcw7
(проэкт)
все тоже самое
https://dropmefiles.com/DXcw7
(проэкт)
все тоже самое
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32f107 USB VCP
Мне сейчас не на чем посмотреть. Может вечером гляну.
Сразу на будущее. Глобальный флаг, который меняется в прерывании, определять только с volatile. Поверь, это сэкономит много времени и нервов в будущем.
Сразу на будущее. Глобальный флаг, который меняется в прерывании, определять только с volatile. Поверь, это сэкономит много времени и нервов в будущем.
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32f107 USB VCP
Dimas6262, ты одну лишнюю строчку в USB_CDC::EP1_OUT_Int() раскомментировал. В твоём проекте возиться не буду. Немного свой поправил. Добавил сохранение размера принятых данных и пример обработки принимаемых данных в основном цикле. Пройдись синхронизацией по исходникам - всё увидишь.
Работает как-то так
1. Зачем ты их так маниакально как unsigned char объявляешь? Классическая Си строка это массив char.
2. Строки, содержимое которых в процессе работы не меняется, определять как const. Они будут лежать себе мирно во flash, а не копироваться в RAM как сейчас.
3. При их объявлении и инициализации не надо указывать размер. Это лишняя работа и источник ошибок. Размер надо указывать только если ты потом будешь менять эту строку и нужно зарезервировать определённый размер для этого.
4. Для определения размера строки, которую ты определил как const char[] можно применять sizeof(). Он будет вычислен на этапе компиляции, а не так как у тебя strlen() в рантайме.
5. Не надо переопределять стандартные функции типа strlen и т.д. Во-первых, достаточно было просто сделать приведение типов, чтобы они заработали. Это в случае (char *) и (unsigned char *) совершенно бесплатно. Во-вторых, в программировании это называется велосипедостроение. Поверь, авторы стандартных библиотек написали эту функцию лучше тебя и даже без ошибок.
Давай, удачи!
Спойлер
Код: Выделить всё
const char hello[] = " Hello! ";
const char bye[] = " Good Bye! ";
int main()
{
// IsCommandReceived возвращает кол-во принятых в буфер usb_rx_buf данных
for(;;)
{
if(usb.IsCommandReceived())
{
switch(usb_rx_buf[0])
{
case 'H':
case 'h':
usb.WriteINEP(1,(uint8_t *)hello,sizeof(hello)-1);
break;
case 'G':
case 'g':
usb.WriteINEP(1,(uint8_t *)bye,sizeof(bye)-1);
break;
default:
usb.WriteINEP(1,usb_rx_buf,1);
}
usb.ClearCommandReceived();
}
};
}Спойлер
Пройдусь всё же по поводу работы со строками.1. Зачем ты их так маниакально как unsigned char объявляешь? Классическая Си строка это массив char.
2. Строки, содержимое которых в процессе работы не меняется, определять как const. Они будут лежать себе мирно во flash, а не копироваться в RAM как сейчас.
3. При их объявлении и инициализации не надо указывать размер. Это лишняя работа и источник ошибок. Размер надо указывать только если ты потом будешь менять эту строку и нужно зарезервировать определённый размер для этого.
4. Для определения размера строки, которую ты определил как const char[] можно применять sizeof(). Он будет вычислен на этапе компиляции, а не так как у тебя strlen() в рантайме.
5. Не надо переопределять стандартные функции типа strlen и т.д. Во-первых, достаточно было просто сделать приведение типов, чтобы они заработали. Это в случае (char *) и (unsigned char *) совершенно бесплатно. Во-вторых, в программировании это называется велосипедостроение. Поверь, авторы стандартных библиотек написали эту функцию лучше тебя и даже без ошибок.
- Вложения
-
- Untitled.png
- (3.86 КБ) 845 скачиваний
Re: STM32f107 USB VCP
[uquote="VladislavS",url="/forum/viewtopic.php?p=3527054#p3527054"]Dimas6262, ты одну лишнюю строчку в USB_CDC::EP1_OUT_Int() раскомментировал. В твоём проекте возиться не буду. Немного свой поправил. Добавил сохранение размера принятых данных и пример обработки принимаемых данных в основном цикле. Пройдись синхронизацией по исходникам - всё увидишь.
Работает как-то так
1. Зачем ты их так маниакально как unsigned char объявляешь? Классическая Си строка это массив char.
2. Строки, содержимое которых в процессе работы не меняется, определять как const. Они будут лежать себе мирно во flash, а не копироваться в RAM как сейчас.
3. При их объявлении и инициализации не надо указывать размер. Это лишняя работа и источник ошибок. Размер надо указывать только если ты потом будешь менять эту строку и нужно зарезервировать определённый размер для этого.
4. Для определения размера строки, которую ты определил как const char[] можно применять sizeof(). Он будет вычислен на этапе компиляции, а не так как у тебя strlen() в рантайме.
5. Не надо переопределять стандартные функции типа strlen и т.д. Во-первых, достаточно было просто сделать приведение типов, чтобы они заработали. Это в случае (char *) и (unsigned char *) совершенно бесплатно. Во-вторых, в программировании это называется велосипедостроение. Поверь, авторы стандартных библиотек написали эту функцию лучше тебя и даже без ошибок.
Давай, удачи![/uquote]
все тоже самое даже с твоим кодом
Спойлер
Код: Выделить всё
const char hello[] = " Hello! ";
const char bye[] = " Good Bye! ";
int main()
{
// IsCommandReceived возвращает кол-во принятых в буфер usb_rx_buf данных
for(;;)
{
if(usb.IsCommandReceived())
{
switch(usb_rx_buf[0])
{
case 'H':
case 'h':
usb.WriteINEP(1,(uint8_t *)hello,sizeof(hello)-1);
break;
case 'G':
case 'g':
usb.WriteINEP(1,(uint8_t *)bye,sizeof(bye)-1);
break;
default:
usb.WriteINEP(1,usb_rx_buf,1);
}
usb.ClearCommandReceived();
}
};
}Спойлер
Пройдусь всё же по поводу работы со строками.1. Зачем ты их так маниакально как unsigned char объявляешь? Классическая Си строка это массив char.
2. Строки, содержимое которых в процессе работы не меняется, определять как const. Они будут лежать себе мирно во flash, а не копироваться в RAM как сейчас.
3. При их объявлении и инициализации не надо указывать размер. Это лишняя работа и источник ошибок. Размер надо указывать только если ты потом будешь менять эту строку и нужно зарезервировать определённый размер для этого.
4. Для определения размера строки, которую ты определил как const char[] можно применять sizeof(). Он будет вычислен на этапе компиляции, а не так как у тебя strlen() в рантайме.
5. Не надо переопределять стандартные функции типа strlen и т.д. Во-первых, достаточно было просто сделать приведение типов, чтобы они заработали. Это в случае (char *) и (unsigned char *) совершенно бесплатно. Во-вторых, в программировании это называется велосипедостроение. Поверь, авторы стандартных библиотек написали эту функцию лучше тебя и даже без ошибок.
все тоже самое даже с твоим кодом
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32f107 USB VCP
Тогда не там роешь.
Re: STM32f107 USB VCP
Да бред какой то, нигде ничего не написано про такую ерунду, как он так может только один раз отправить пакет любой длины, а потом как будто в очередь становится и даже не принимает
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32f107 USB VCP
Ты ещё не разобрался? Больше недели прошло. Вот смотри, энумерация, судя по всему, у тебя проходит. Энумерация это в основном запросы-ответы: дай мне тот дискриптор, теперь этот, а теперь опять первый и так много раз. В моём примере один из дискрипторов 67 байт, насколько помню. То есть, обмен данными любого размера работает. Передача через ep0 и ep1 осуществляется одной и той же функцией. Не чему там не работать.
Может всё же в кубе натыкать?
Может всё же в кубе натыкать?
Re: STM32f107 USB VCP
а там не может быть что нибудь по схемотехнике?
Добавлено after 1 minute 20 seconds:
и после второй передачи порт занят
то есть даже принять не могу
Добавлено after 3 minutes 31 second:
каким образом можно все очереди нулить?
Добавлено after 1 minute 20 seconds:
и после второй передачи порт занят
то есть даже принять не могу
Добавлено after 3 minutes 31 second:
каким образом можно все очереди нулить?
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32f107 USB VCP
Какой порт, что значит занят, какие очереди? Давай на одном языке общаться.
Re: STM32f107 USB VCP
[uquote="VladislavS",url="/forum/viewtopic.php?p=3535156#p3535156"]Какой порт, что значит занят, какие очереди? Давай на одном языке общаться.[/uquote]
сделал передачу на ПК, прослушиваю как ком порт через Serial Monitor Port, все пришло, затем прерываю связь Serial Monitor Port, делаю 2-ю передачу, пытаюсь подключится в программе, но говорит что порт занят, но по отладчику, мы никуда не прыгаем, то есть комп думает что я ему что то передаю, а сам процессор в это время ничего не делает, не заходит в прерываиние
сделал передачу на ПК, прослушиваю как ком порт через Serial Monitor Port, все пришло, затем прерываю связь Serial Monitor Port, делаю 2-ю передачу, пытаюсь подключится в программе, но говорит что порт занят, но по отладчику, мы никуда не прыгаем, то есть комп думает что я ему что то передаю, а сам процессор в это время ничего не делает, не заходит в прерываиние
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32f107 USB VCP
Причём тут микроконтроллер, если ты с маздаиной справиться не можешь...
Re: STM32f107 USB VCP
А по подключению к stm32f107 клавиатуры нет ни каких примеров?
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: STM32f107 USB VCP
Какой клавиатуры?


