pokk 0 26 мая, 2019 Опубликовано 26 мая, 2019 · Жалоба Подскажите надежный вариант передачи данных по SPI. Задача такая надо сделать прием/ передачу данных с stm32f4(мастер) в stm32f0(slave). Слейв это "аналог расширителя USART", он принимает потоки данных по одним USART(2 шт) и параллельно выдает потоки данные по другим USART(2шт), вот по spi надо считать принятые данные и закинуть новые. В железе между процессорами по мимом основных выводов SPI(MISO,...) заложенные ещё 2 вывода RD RW(это походу лишнее). Так что по получению одного пакета данных slave может выдать сигнал мастеру на чтение данных, только как мастеру узнать сколько надо прочитать данных 1 пакет данных(с 1 usat 1 КБ )? Или 2 пакета(с двух usart 2кб)? Подумываю сделать регистр принятых данных в slave и после того как был выставлен лог 1 на линии RD сначала одним запросом прочитать "регистр" сколько данных надо принять, и другим запросом считать все данные. (А если данные прийдут после считывания регистра?) Теперь по поводу самого SPI как, правильнее все настроить? В прошлом проект использовал такой алгоритм. 1) Ожидаем прерывание 1->0 по CS(настраиваем SPI, так как только через reset spi очищаться буффер в stm32f0) 1.1) Включаем прерывание по CS из 0->1 (выключаем SPI) 2) Принимаем шапку через прерывания(вытаскиваем размер данных) 3) Настраиваем DMA по количеству данных 4) после завершения передачи spi и dma выключиться сам см пункт 1.1 Но как то выглядит замудренно, можно проще? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 64 26 мая, 2019 Опубликовано 26 мая, 2019 · Жалоба Что-то у вас каша какая-то. Данные передаются только в одну сторону или во все? какие USART(синхронные или асинхронные) и куда передают данные? И сколько всего USART? Если синхронные, насколько синхронно надо всё делать? И не очень понятно это потоки данных или всё-таки зависимые блоки данных? Нарисуйте укрупненную схему с потоками данных между точками входа и точками выхода в ваш блок, а потом детализируйте последовательно, расставляя точки синхронизации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 26 мая, 2019 Опубликовано 26 мая, 2019 · Жалоба 6 hours ago, pokk said: . . . (А если данные прийдут после считывания регистра?) . . . У должен быть регистр статуса и состояния FIFO слейва для каждого канала. "Новые" данные должны спокойно-независимо приходить в приемный кольцевой байтовый буфер (если он не переполнен). Данные (массив структур) в FIFO могут содержать указатели на начала пакетов во входном кольцевом буфере, длину и разные флаги (например результат проверки CRC пакета). Единственные "грабли" - переполнение входного кольцевого буфера, которое должно видется через регистр статуса и апп. прерывание в мастер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 27 мая, 2019 Опубликовано 27 мая, 2019 · Жалоба 7 hours ago, HardEgor said: Данные передаются только в одну сторону или во все? какие USART(синхронные или асинхронные) и куда передают данные? И сколько всего USART? Всего USART пока 4, данные передаются в обе стороны, это настраивает пользователь, может бы как 4 на передачу в slave так и 4 на прием из slave, так же разные комбинации (2 передача 2 прием), это все конфигурируеться в мастере. Планирую сделать по измению конфигурации отправлять блок конфигурации slave. 8 hours ago, HardEgor said: И не очень понятно это потоки данных или всё-таки зависимые блоки данных? Поток представляет собой идущие друз за другом блоки данных размером 1 кб. 7 hours ago, k155la3 said: У должен быть регистр статуса и состояния FIFO слейва для каждого канала. "Новые" данные должны спокойно-независимо приходить в приемный кольцевой байтовый буфер (если он не переполнен) Да тут планировал сделать кольцевой буфер на каждый поток и по приему блока данных увеличивать счетчик блоков в буфере. И после приема каждого блока данных запускать процедуру формирование приемного пакета, примерно с таким алгоритмом: 1) Пройтись по всем буферам и выявить которые надо передавать(счетчик блоков >0) 2) Скопировать блок данных в передающий массив SPI c пометкой с какого буфера он был извлечен 3) Посчитать размер получившегося массива занести его в регистр 4) Выставить сигнал мастеру на забор данных (сигнал по линии RD) 7 hours ago, k155la3 said: Единственные "грабли" - переполнение входного кольцевого буфера, которое должно видется через регистр статуса и апп. прерывание в мастер. Это да полезная штука благодарю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 64 27 мая, 2019 Опубликовано 27 мая, 2019 · Жалоба 44 минуты назад, pokk сказал: Всего USART пока 4, данные передаются в обе стороны, это настраивает пользователь, может бы как 4 на передачу в slave так и 4 на прием из slave, так же разные комбинации (2 передача 2 прием), это все конфигурируеться в мастере. Планирую сделать по измению конфигурации отправлять блок конфигурации slave. Поток представляет собой идущие друз за другом блоки данных размером 1 кб. master and slave - это имеются ввиду SPI? Т.е. : - каждый USART либо приемник, либо передатчик или все они могут быть приемопередатчиками? - USART могут иметь разные скорости? Макс. скорость одного USART? - максимум 4 приемника или 4 передатчика или любая комбинация, так? - при передаче через SPI к блоку 1кб надо добавлять номера USART (+1 байт) - по SPI передается пакет конфигурации Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 27 мая, 2019 Опубликовано 27 мая, 2019 (изменено) · Жалоба 1 hour ago, HardEgor said: master and slave - это имеются ввиду SPI? Да про spi 1 hour ago, HardEgor said: - каждый USART либо приемник, либо передатчик или все они могут быть приемопередатчиками? Да 1 hour ago, HardEgor said: - USART могут иметь разные скорости? Макс. скорость одного USART? Скорость у всех одинакова. Скорости SPI хватает с 3х кратным запасом что бы все принимать/передавать. 1 hour ago, HardEgor said: - максимум 4 приемника или 4 передатчика или любая комбинация, так? Все верно 1 hour ago, HardEgor said: - при передаче через SPI к блоку 1кб надо добавлять номера USART (+1 байт) Да, для того что бы по максимум нагрузить SPI и не дробить DMA на более мелкие посылки, решил объединить по максимум в одну большую посылку(все потоки, которые принялись), по этому и добавляю номер потока к данным. Изменено 27 мая, 2019 пользователем pokk Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 27 мая, 2019 Опубликовано 27 мая, 2019 · Жалоба 2 hours ago, pokk said: . . . 2) Скопировать блок данных в передающий массив SPI c пометкой с какого буфера он был извлечен Если блоки данных фиксированного (или более-менее фиксированного, например - не более 1 кБ) размера - рассмотритие возможность не копирования блоков, а "переключения" с помощью указателя. (зачем "гонять" данные внутри RAM). Если оно должно работать в реалтайм на высокой скорости - это сэкономит время. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 27 мая, 2019 Опубликовано 27 мая, 2019 · Жалоба 1 minute ago, k155la3 said: Если блоки данных фиксированного Да блоки фиксированного размера, всегда пытался так делать, и вечно получал грабли, то чего то не хватает что ещё что нибудь, в данном случае, не получиться все принятые данные с несколько потоков объединить(хотя может это и не актуально). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 27 мая, 2019 Опубликовано 27 мая, 2019 · Жалоба 1 minute ago, pokk said: Да блоки фиксированного размера, . . . в slave, при приеме блока (пакета) из канала, целостность пакета проверяется (CRC, заголовок итп) ? RAM сколько ? (под буферизацию, если 4 канала) В каждом канале - буфер на 3 пакета максимальной длины. IN_Channl1[3] IN_Channl1[0] - то что "льется" по приему из канала в данный момент IN_Channl1[1] - принято, проверено, передано мастеру на обработку. (ждет своей "участи"-приговора от мастера) IN_Channl1[2] - предыдущий принятый (и проверенный мастером) пакет, который должен быть "оттранслирован" (передается сейчас) далее на другой USART-TX. Указатель буфера USART-TX установлен на IN_Channl1[2]. Данные из IN_Channl1[2] сейчас в процессе передачи по USART-TX Channl2. (например это "транзитный" пакет, который мастеру вообще не интересен) "Передающих" буферов нет вообще, их роль выполняет приемный буфер. (если конечено, не требуется обработка или формирование с нуля ответного пакета) Это "к сведению", может Вам подойдет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 64 27 мая, 2019 Опубликовано 27 мая, 2019 · Жалоба 1 час назад, pokk сказал: Скорость у всех одинакова. Скорости SPI хватает с 3х кратным запасом что бы все принимать/передавать. Т.е. если все 4 UART работают и на прием и на передачу с трекратным запасом? Тогда всё элементарно - полная загрузка, это когда данные идут на полной скорости по всем UART, тогда: В 1кб блоках данных делаем флаг: 0-нет данных, 1...4 - данные соответств. UART Синхронно передаём данные блоками 1Кб по MOSI и MISO. slave выдает master'у индикатор READY готовности к передачи. Т.е. тупо молотим во все стороны по SPI на полной скорости. Загрузка процессора будет только на прерываниях DMA. 1. Одновременно оба процессора готовят данные, настраивают DMA c обеих сторон 2. когда master готов, он проверяет READY(флаг готовности slave) 3. Если READY встал, то master запускает передачу 4. По окончанию передачи в обеих процессорах вызываются прерывания, slave сбрасывает READY и переходим к п.1 5. проверяем флаг блока данных - если ноль, то ничего с ним не делаем. Если другое число - обрабатываем. Это будет работать в любой конфигурации UART. p.s. Мда, смотрю на QuadSPI в H7 пишу всё это.... а в F0-то обычный SPI... Но принцип не изменится - рассчитывайте алгоритм на полную загрузку SPI. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться