Oleg_IT 0 Posted November 23, 2015 · Report post STM32F417. Есть два дивайса, датчик температуры и управляемый резистор, из первого нужно только читать данные, во второй только писать, выводы MOSI, MISO развожу по соответствующим девайсам, CS понятно разные. SPI2 назначать как Full-Duplex Master? Quote Ответить с цитированием Share this post Link to post Share on other sites
arhiv6 0 Posted November 23, 2015 · Report post Да, это будет случай Full-Duplex Master. Quote Ответить с цитированием Share this post Link to post Share on other sites
Oleg_IT 0 Posted November 23, 2015 · Report post Спасибо. Quote Ответить с цитированием Share this post Link to post Share on other sites
Oleg_IT 0 Posted December 11, 2015 · Report post Так не получается. Проект генерю из STM32CubeMx. Пока работаю только с датчиком температуры, подключены SO, SCK и CS. Если конфигурить SPI как Full-Duplex Master то программа виснет на чтении данных, если как Receive Only Msster то данные идут, но не полностью. SPI сконфигурю с DMA, когда наступает момент чтения температуры вызываю функции uint16_t Temp; // Значение измеренной температуры ………………………………………………… HAL_GPIO_WritePin(GPIOA,CS_Termo_Pin,GPIO_PIN_RESET); HAL_SPI_Receive_DMA(&hspi1,(uint8_t*)&Temp,2); По окончанию работы DMA вызывается прерывание со статусом HAL_DMA_STATE_READY_MEM0, поднимаю пин CS HAL_GPIO_WritePin(GPIOA,CS_Termo_Pin,GPIO_PIN_SET); Но по осциллографу вижу, что CS отключает датчик температуры ровно посередине второго байта. Соответственно первый байт приходит, видно он меняется, второго байта нет. Почему так может быть? В какой момент отключать CS? Как правильно работать с несколькими девайсами ни одном SPI? Нужно и одно чтение и одна запись и Full-Duplex Master для третьего девайса. Quote Ответить с цитированием Share this post Link to post Share on other sites
Obam 0 Posted December 11, 2015 · Report post "…Как правильно работать с несколькими девайсами ни одном SPI?…" Каждому ведомому свой отдельный CS. MOSI, MISO общие для всех ведомых. В каждый конкретный момент времени общение идёт с одним конкретным ведомым (активен только один CS). Quote Ответить с цитированием Share this post Link to post Share on other sites
Oleg_IT 0 Posted December 11, 2015 · Report post Каждому ведомому свой отдельный CS. MOSI, MISO общие для всех ведомых. В каждый конкретный момент времени общение идёт с одним конкретным ведомым (активен только один CS). Я так и делаю, у меня пока один девайс с одной линией SO и с Full-Duplex Master не работает. Наверное придётся переключать Full-Duplex Master <-> Receive Only Msster <-> Transmit Only Msster Quote Ответить с цитированием Share this post Link to post Share on other sites
Obam 0 Posted December 11, 2015 · Report post SPI сконфигурю с DMA, когда наступает момент чтения температуры вызываю функции uint16_t Temp; // Значение измеренной температуры ………………………………………………… HAL_GPIO_WritePin(GPIOA,CS_Termo_Pin,GPIO_PIN_RESET); HAL_SPI_Receive_DMA(&hspi1,(uint8_t*)&Temp,2); По окончанию работы DMA вызывается прерывание со статусом HAL_DMA_STATE_READY_MEM0, поднимаю пин CS HAL_GPIO_WritePin(GPIOA,CS_Termo_Pin,GPIO_PIN_SET); Но по осциллографу вижу, что CS отключает датчик температуры ровно посередине второго байта. Соответственно первый байт приходит, видно он меняется, второго байта нет. Почему так может быть? В какой момент отключать CS? Как правильно работать с несколькими девайсами ни одном SPI? Нужно и одно чтение и одна запись и Full-Duplex Master для третьего девайса. CS снимается, когда DMA записал последний байт в DR, а должен сниматься когда вычитан последний байт из DR. Вообще странно: цикл SPI это одновременное запись-чтение и надёжным признаком является заполнение DR принятым. Может есть другой более подходящий статус HAL_DMA_STATE_**** Quote Ответить с цитированием Share this post Link to post Share on other sites
scifi 0 Posted December 11, 2015 · Report post Так не получается. Проект генерю из STM32CubeMx. По-моему, вывод очевиден. Куб - в топку. Накодить всё самостоятельно, как принято у настоящих мущщин :laughing: Quote Ответить с цитированием Share this post Link to post Share on other sites
Oleg_IT 0 Posted December 11, 2015 · Report post По-моему, вывод очевиден. Куб - в топку. А что таково в нём плохого? Открытый код делает, что не нравится можно менять, дорабатывать, знать бы что, где. Quote Ответить с цитированием Share this post Link to post Share on other sites
Obam 0 Posted December 11, 2015 · Report post Вот тут-то и парадокс: когда знаешь что и где "кубы" без надобности. Так почему DMA, не приняв последний байт, отваливался? Quote Ответить с цитированием Share this post Link to post Share on other sites
Oleg_IT 0 Posted December 11, 2015 · Report post Вот тут-то и парадокс: когда знаешь что и где "кубы" без надобности. Так почему DMA, не приняв последний байт, отваливался? Да ни какого парадокса, просто экономия времени и можно посмотреть как люди программы пишут, если опыта мало. А с DMA пока не пойму. в прерывания он входит только с HAL_DMA_STATE_READY_MEM0, сконфигурил я его так. Я вот думаю, может в SPI флаг окончания приёма контролировать, в основном цикле и когда прерывание от DMA пришло. Кривовато это как-то. Quote Ответить с цитированием Share this post Link to post Share on other sites
Tarbal 0 Posted December 12, 2015 · Report post Да ни какого парадокса, просто экономия времени и можно посмотреть как люди программы пишут, если опыта мало. А с DMA пока не пойму. в прерывания он входит только с HAL_DMA_STATE_READY_MEM0, сконфигурил я его так. Я вот думаю, может в SPI флаг окончания приёма контролировать, в основном цикле и когда прерывание от DMA пришло. Кривовато это как-то. Контролировать в цикле неправильно. Во первых есть аппаратный CS, который праввильно поведет себя. Если совсем нет выбора, а надо подключить несколько SPI устройств, то можно включить их последовательно. Поищите по ключевым словам daisy chain. SPI устройство это регистр сдвига, который защелкивает информацию по положительному фронту CS. Для записи в устройство в конце цепочки вам придется формировать посылку из нескольких слов, чтобы нужное дошло. Ну вот например так как здесь описано: https://en.wikipedia.org/wiki/Serial_Periph...l_Interface_Bus Есть и другие способы, но это уже если устройство их поддерживает. А куб мне пока нравится. Quote Ответить с цитированием Share this post Link to post Share on other sites
Oleg_IT 0 Posted December 13, 2015 · Report post Заметил особенность, при увеличении BaudRatePrescaler общее время приёма растёт быстрее чем время нахождения CS в открытом состоянии, т.е. при BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2(4, 8, 16) приём укладывается в CS == 0, а когда BaudRatePrescaler больше, приём обрезается. Похоже DMA живёт отдельно от SPI. CS аппаратный не подходит, для каждого девайса у меня он свой. Теорию SPI я знаю, но сейчас не в ней проблема. Quote Ответить с цитированием Share this post Link to post Share on other sites
Oleg_IT 0 Posted December 14, 2015 · Report post Контролировать в цикле неправильно. Не правильно, но работает. Почему прерывание раньше происходит так и не понял, может так задумано. Quote Ответить с цитированием Share this post Link to post Share on other sites
Tarbal 0 Posted December 14, 2015 · Report post Не правильно, но работает. Почему прерывание раньше происходит так и не понял, может так задумано. Пренебрежение опытом -- источник "необъяснимых" чудес в поведении разрабатываемого устройства. Бывает, что несколько событий могут вызвать прерывание по одному и тому же вектору. Если это так, то прочитайте в прерывании флаги и определите то ли прерывание произошло, которого вы ожидали. Если не то, то покинте (если вам его не надо обрабатывать) обработчик. Quote Ответить с цитированием Share this post Link to post Share on other sites