Микроконтроллеры

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Микроконтроллеры » STM32 & STM8 » Периферия » USB full-speed device интерфейс в STM32F1 (L1, F3)


USB full-speed device интерфейс в STM32F1 (L1, F3)

Сообщений 91 страница 107 из 107

91

Приветствую участников форума! Вопрос у меня  про биты синхронизации.
На контроллере STM32F103VE сделал MSD. Делал все последовательно от энумерации до чтения сектора.
Не делал полностью стек как в примерах от ST а только те запросы что выдавал хост(Win7).
Про DTOG_RX DTOG_TX читал(в этой же теме) что трогать не надо они сами переключаются во время управляющих запросов.
Но вот когда дошел до SCSI команд то тоже выяснилось что все работает без принудительно переключения data0/1 при отправке
данных на стадии данных и стадии статуса. Хотя про эти команды явно указано что например команда Inquiry приходит с токеном
DATA0 а я должен ответить DATA0 при стадии Data Transport и DATA1 при стадии StatusTransport. В общем у меня работает пока только чтение
с SD карты но работает нормально. Запись думаю скоро добить и там все по аналогии.
Вопрос в том почему все отлично работает при BOT протоколе без принудительно переключения DATA0/1  при отправке данных или статуса?

92

Привет, pvo125 )
Я не разбирался со SCSI детально, может sobs что-нибудь скажет

93

Ладно с этим как нибудь потом разберусь или кто подскажет. Ведь главное работает.
Вопрос к vt ! Можешь несколькими предложениями рассказать про double buffering. В какой момент писать/ читать данные в PMA конечных точек. Чисто теоретически. Хотел впоследствии сделать а вот с теорией на английском( из RM) не очень получается понять смысл.

P.S. Очень помог твой топик на первой странице темы! Отдельное спасибо за разъяснения про  stat_tx stat_rx и операцию XOR !

94

Double buffering имеет смысл, если ты вписываешься в темп приёма-передачи данных хостом, тогда приём-передача будут непрерывными
Можешь прикинуть этот темп - 12 Мбит скорость, по 64 байта пакеты, и прикинуть сможешь ли ты в мк принимать, передавать, обрабатывать данные с таким темпом
Не все вкусняшки из RM одинаково полезны )

95

pvo125 написал(а):

Хотя про эти команды явно указано что например команда Inquiry приходит с токеном
DATA0 а я должен ответить DATA0 при стадии Data Transport и DATA1 при стадии StatusTransport.

Когда разбирался с темой этого не видел (или не обратил внимания). Я использовал эти материалы - Ссылка и Ссылка
Вот тут мои беглые разборки с SCSI Ссылка

96

Можешь прикинуть этот темп - 12 Мбит скорость, по 64 байта пакеты, и прикинуть сможешь ли ты в мк принимать, передавать, обрабатывать данные с таким темпом

Да именно для чтения с SD карты и нужен этот режим. С карты скорость чтения около 7 мегабайт с секунду(по 4 проводн. SDIO). Потому и хотел попробовать разобраться
и проверить сильно ли приблизится к теоретическому максимуму для Full Speed. Хотя думаю слабым звеном будет запись на карту. Для записи конечно не нужна двойная буферизация.

Я использовал эти материалы -...


Вот файл по командам BOT протокола. Ориентировался на него.Каждая команда расписана с каким токеном (data0/1) приходит и какой следует отправлять.
Ссылка

97

pvo125 написал(а):

хотел попробовать разобраться
и проверить сильно ли приблизится к теоретическому максимуму для Full Speed.

Перед этим неплохо было бы проверить какой практический максимум [для stm32f103] )

98

Всем привет!
Столкнулся с неприятным косяком при поднятии USB CDC. Устройство проходит энумерацию в винде, появляется устройство, ставится дефолтный драйвер, и вроде все хорошо, винда говорит что работает нормально, но когда пытаюсь подключится к COM порту через любую терминальную прогу, то она зависает на подключении, как только вытаскиваю устройство из компа прога сразу оживает.
В чем может быть косяк?
Ссылка на проект (может кто попробует или просто глянуть)
https://github.com/saewave/STM32F103-USB-CDC-CMSIS
Windows 7, терминал Termite 3.2

Отредактировано alexsam (2018-01-23 21:49:42)

99

alexsam, привет
На первый взгляд в твоём коде нет собственно самой реализации cdc [мало объявить endpoints для cdc, надо их ещё и обслуживать в соотв. со спецификацией cdc]
CDC и другие стандартные классы выходят за рамки этого топика, это чисто софтовый верхний уровень, а топик про usb и-фейс в мк
Может быть завести тут отдельный топик про cdc, может это ещё кому-то будет интересно [мне - нет, но вроде Eddy_Em интересовался]

Отредактировано vt (2018-01-24 12:07:12)

100

Ну и раз уж опять этот топик всплыл, то вот vendor specific class [bulk in1, out1, in2, out2] в стиле с++ lite

usb.cc
Код:
namespace usb {

typedef volatile struct {
    uint32_t t0a, t0c, r0a, r0c;
    uint32_t t1a, t1c, r1a, r1c;
    uint32_t t2a, t2c, r2a, r2c;
    uint32_t x[20];
    uint32_t t0b[32], r0b[32];
    uint32_t t1b[32], r1b[32];
    uint32_t t2b[32], r2b[32];
} pm_t;
pm_t *pm = (pm_t*) 0x40006000UL;

typedef const struct {volatile void *rp, *bp, *cp;} ep_t;
ep_t in1  = {&(USB->EP1R), &(pm->t1b), &(pm->t1c)};
ep_t out1 = {&(USB->EP1R), &(pm->r1b), &(pm->r1c)};
ep_t in2  = {&(USB->EP2R), &(pm->t2b), &(pm->t2c)};
ep_t out2 = {&(USB->EP2R), &(pm->r2b), &(pm->r2c)};

enum {setup, data, status} stage = setup;

uint32_t address = 0;

const struct {
    uint16_t device[9] = {
        0x112, 0x110, 0, 0x4000, 0x4444, 1, 1, 0, 0x100
    };
    uint16_t configuration[23] = {
        0x209, 46, 0x101, 0xC000, 0x900, 4, 0x400, 0xFF, 0,
        0x507, 0x281, 0x40, 0x700, 0x105, 0x4002, 0,
        0x507, 0x282, 0x40, 0x700, 0x205, 0x4002, 0
    };
} descriptor;

void init () {
    USB->CNTR = 0;
    pm->t0a =  64; pm->t0c = 0;
    pm->r0a = 128; pm->r0c = 0x8400;
    pm->t1a = 192; pm->t1c = 0;
    pm->r1a = 256; pm->r1c = 0x8400;
    pm->t2a = 320; pm->t2c = 0;
    pm->r2a = 384; pm->r2c = 0x8400;
}

void tick () {

    if (USB->ISTR_b.RESET) {
        USB->CNTR = 0;
        USB->ISTR = 0;
        USB->EP0R_b.EA = 0; USB->EP0R_b.EP_TYPE = 1;
        USB->EP1R_b.EA = 1; USB->EP1R_b.EP_TYPE = 0;
        USB->EP2R_b.EA = 2; USB->EP2R_b.EP_TYPE = 0;
        USB->EP0R ^= 0xA0A0;  // r:nak t:nak
        USB->EP1R ^= 0xB0A0;  // r:valid t:nak
        USB->EP2R ^= 0xB0A0;  // r:valid t:nak
        USB->DADDR = 0x80;
        stage = setup;

    } else if (USB->EP0R_b.CTR_RX) {
        if (USB->EP0R_b.SETUP) {
            stage = setup;
            if ((pm->r0b)[0] == 0x680) {  // get descriptor
                if ((pm->r0b)[1] == 0x100) {  // device
                    for (int i = 0; i < 9; i++) {
                        (pm->t0b)[i] = (uint32_t) (descriptor.device)[i];
                    }
                    stage = data;
                } else if ((pm->r0b)[1] == 0x200) {  // configuration
                    for (int i = 0; i < 23; i++) {
                        (pm->t0b)[i] = (uint32_t) (descriptor.configuration)[i];
                    }
                    stage = data;
                }
            } else if ((pm->r0b)[0] == 0x80) {  // get status
                (pm->t0b)[0] = 1;
                stage = data;
            } else if ((pm->r0b)[0] == 0x500) {  // set address
                address = (pm->r0b)[1];
                stage = status;
            } else if ((pm->r0b)[0] == 0x102 ||  // clear feature
                       (pm->r0b)[0] == 0x900) {  // set configuration
                stage = status;
            }
            if (stage == setup) {
                USB->EP0R ^= 0x9090;  // r:stall t:stall
            } else {
                if (stage == data) {
                    pm->t0c = ((pm->r0b)[3] > 63) ? 63 : (pm->r0b)[3];
                } else if (stage == status) {
                    pm->t0c = 0;
                }
                USB->EP0R ^= 0xE0F0;  // r:nak t:valid
            }
        } else if (stage == status) {
            stage = setup;
            USB->EP0R ^= 0xA0A0;  // r:nak t:nak
        }

    } else if (USB->EP0R_b.CTR_TX) {
        if (stage == data) {
            pm->t0c = 0;
            stage = status;
            USB->EP0R ^= 0xF0E0;  // r:valid t:nak
        } else if (stage == status) {
            USB->DADDR = 0x80 | address;
            stage = setup;
            USB->EP0R ^= 0xA0A0;  // r:nak t:nak
        }
    }
}

uint32_t rx (ep_t *ep, uint16_t *a, uint32_t n) {
    uint32_t r = *((uint32_t*) ep->rp) ^ 0x3000;
    if (r & 0xB000) {
        for (uint32_t i = 0; i < n; i++) {
            a[i] = (uint16_t) ((uint32_t*) ep->bp)[i];
        }
        *((uint32_t*) ep->rp) = (r & ~0xC070) | 0x80;
        return *((uint32_t*) ep->cp) & 0x3FF;
    } else {
        return 0;  // fail
    }
}

uint32_t tx (ep_t *ep, uint16_t *a, uint32_t n) {
    uint32_t r = *((uint32_t*) ep->rp) ^ 0x30;
    if (r & 0xB0) {
        for (uint32_t i = 0; i < n; i++) {
            ((uint32_t*) ep->bp)[i] = (uint32_t) a[i];
        }
        *((uint32_t*) ep->cp) = n*2;
        *((uint32_t*) ep->rp) = (r & ~0x70C0) | 0x8000;
        return n*2;
    } else {
        return 0;  // fail
    }
}

}

101

Ну чтоб обслуживать CDC нужно получать от хоста запросы на это самое обслуживание, а они почему-то не приходят. Структуру я обьявил, точки все в btable прописаны с адресами. Думаю что что-то с дескрипторами не то, ибо не хочет подключаться сама прога к порту чтоб что-то передать.

102

USB_DEVICE_DESC[] посмотри там версия USB 2.0 должна  быть 00  02 а у тебя 02 00. Это не значит что в этом косяк просто первое что на глаза попалось.

p.s. СDC не реализовывал но в масс сторадж у меня после SET_CONFIGURATION(  те STANDART_REQUEST) пошли CLASS_REQUEST один через EP0 а остальные специфичные для класса уже через EP1 и EP2. Не увидел у тебя реализацию для CDC класса(поправь может оно и не надо) и обработка принятия и отправка каких либо байт не через нулевую EP.

Отредактировано pvo125 (2018-01-24 18:17:52)

103

Ну что ж, поборол я CDC. Все работает, косяков вроде не замечено. Если кому нужно будет - берите :)
STM32F103-USB-CDC-CMSIS

104

alexsam, а в двух словах -в чем была проблема?

105

alexsam
Отличный эталонно минималистичный cdc получился [всего четыре (?) классово специфичных запроса]

dosikus
По ссылке на github глянь коммиты и увидишь во всех подробностях что менялось )

106

Да, проблема была в том, что провтыкал отправку ответа на установку битрейта и при подключении, когда драйвер присылал фрейм с USB_DEVICE_CDC_REQUEST_SET_LINE_CODING я ему не отправлял подтверждения. Ну и хост висел и ждал. Потом отваливался.
(нужно завязывать педалить после 2х часов ночи )) )
Сейчас в планах добавить вывод состояния подключения/отключения к COM порту приложения на хосте и, возможно стоит сделать отслеживание освобождениям буфера отправки. Но не уверен что это стоит делать в самой либе.

Отредактировано alexsam (2018-01-26 11:13:42)

107

Да я ж не для себя. Кто нибудь будет искать, а тут непонятки...
alexsam, спасибо.


Вы здесь » Микроконтроллеры » STM32 & STM8 » Периферия » USB full-speed device интерфейс в STM32F1 (L1, F3)