jenya7 0 21 июня, 2018 Опубликовано 21 июня, 2018 (изменено) · Жалоба я работаю с MK10FN1M0xxx12 посылаю-принимаю по СПИ uint32_t SPI_TransferByte(uint32_t spi_num, uint8_t tx_data, uint8_t *rx_data) { uint32_t timeout; uint32_t value; // Assert CS0, Use config 0 SPIx[spi_num]->PUSHR = SPI_PUSHR_CTAS(0) | SPI_PUSHR_TXDATA((uint32_t)tx_data); timeout = 0; // while transfer complete while (!(SPIx[spi_num]->SR & SPI_SR_TCF_MASK)) { timeout++; if (timeout > SPI_TIMEOUT) { // clear flag SPIx[spi_num]->SR = SPI_SR_TCF_MASK; return SPI_TIMEOUT_ERROR; } }; // clear flag SPIx[spi_num]->SR = SPI_SR_TCF_MASK; *rx_data = (uint8_t)SPIx[spi_num]->POPR; return 0; } вижу фигня какя то - раз получил байт в ответ, раз не получил. а на скопе на пине SIN все четко, байты приходят. думал-гадал - добавил задержку uint32_t SPI_TransferByte(uint32_t spi_num, uint8_t tx_data, uint8_t *rx_data) { uint32_t timeout; uint32_t value; // Assert CS0, Use config 0 SPIx[spi_num]->PUSHR = SPI_PUSHR_CTAS(0) | SPI_PUSHR_TXDATA((uint32_t)tx_data); timeout = 0; // while transfer complete while (!(SPIx[spi_num]->SR & SPI_SR_TCF_MASK)) { timeout++; if (timeout > SPI_TIMEOUT) { // clear flag SPIx[spi_num]->SR = SPI_SR_TCF_MASK; return SPI_TIMEOUT_ERROR; } }; // clear flag SPIx[spi_num]->SR = SPI_SR_TCF_MASK; for (timeout = 0; timeout < 100; timeout++); //while (!(SPIx[spi_num]->SR & SPI_SR_RFDF_MASK)) //dosen't work *rx_data = (uint8_t)SPIx[spi_num]->POPR; return 0; } и все работает как часики. фига се думаю - байт ушел но нужно ждать пока пришедший байт готов. но не задержками же. начал перебирать флаги в статусном регистре - этот вроде подходит - while (!(SPIx[spi_num]->SR & SPI_SR_RFDF_MASK)) но я не выхожу из while. Че там твориться вообще с Кинетисовским СПИ? Или я что то не так настроил? Изменено 21 июня, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 21 июня, 2018 Опубликовано 21 июня, 2018 · Жалоба Может не учитываете буферизацию SPI (регистр передачи и сдвиговый регистр), и читаете до освобождения регистра сдвига. А если таймаут - то "попадает". Смотрите бит "сдвиговый регистр свободен". С Kinetis не работал. Но это вроде-как типовая структура. (есть биты пустоты для буферного регистра и регистра сдвига.) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 37 21 июня, 2018 Опубликовано 21 июня, 2018 · Жалоба Тут, судя по ветке про таймер и по "...перебирать флаги в статусном регистре...", проблема в прочитать RefMan. Я уже почти влюбился ;) (в самом хрошем смысле этого слова) в K10. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 21 июня, 2018 Опубликовано 21 июня, 2018 · Жалоба Тут, судя по ветке про таймер и по "...перебирать флаги в статусном регистре...", проблема в прочитать RefMan. В Kinetis все операции с SPI делаю через DMA. Тогда получается надежно. А без DMA, да, есть такая проблема, как чтение раньше времени или слишком поздно. :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 22 июня, 2018 Опубликовано 22 июня, 2018 (изменено) · Жалоба В Kinetis все операции с SPI делаю через DMA. Тогда получается надежно. А без DMA, да, есть такая проблема, как чтение раньше времени или слишком поздно. :laughing: Александр, Вам как главному специалисту по Кинетису вопросы 1. почему флаг while (!(SPIx[spi_num]->SR & SPI_SR_RFDF_MASK)) не работает? 2. Можете показать пример с DMA? У меня не заработало. я вообще в шоке от Кинетивского СПИ. что это за FIFO в котором нельзя настроить глубину. где флаг дата пришла в POPR. я уже несколько дней танцы с бубнами устраиваю. пока что единственное решение которое работает for (timeout = 0; timeout < 10; timeout++); перед тем как читать из POPR. STMовский СПИ просто мерседес в сравнении с Кинетисовским. Изменено 22 июня, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 22 июня, 2018 Опубликовано 22 июня, 2018 · Жалоба Александр, Вам как главному специалисту по Кинетису вопросы 1. почему флаг while (!(SPIx[spi_num]->SR & SPI_SR_RFDF_MASK)) не работает? 2. Можете показать пример с DMA? У меня не заработало. я вообще в шоке от Кинетивского СПИ. что это за FIFO в котором нельзя настроить глубину. где флаг дата пришла в POPR. я уже несколько дней танцы с бубнами устраиваю. пока что единственное решение которое работает for (timeout = 0; timeout < 10; timeout++); перед тем как читать из POPR. STMовский СПИ просто мерседес в сравнении с Кинетисовским. Работу с SPI можно посмотреть в моем проекте - https://github.com/Indemsys/Universal3PHalf.../K66BLEZ1_SPI.c В Kinetis у разных SPI разная глубина и чаще всего она равна 1, увы. С флагом SPI_SR_RFDF_MASK у меня тоже что-то не поучалось. Уж не помню что именно. Попробуйте перед приемо-передачей очищать FIFO. void SPI_clear_FIFO(uint8_t modn) { SPI_Type *SPI = spi_mods[modn].spi; SPI->MCR |= BIT(HALT); // Остановить модуль while (SPI->SR & BIT(TXRXS)); // Ожидание пока бит 30 (TXRXS) не станет равным нулю SPI->SR = SPI->SR; SPI->MCR |= BIT(CLR_TXF) + BIT(CLR_RXF); // Установить флаги CLR_TXF и CLR_RXF для очистки обоих FIFO SPI->MCR &= ~BIT(HALT); // Запустить модуль } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 22 июня, 2018 Опубликовано 22 июня, 2018 (изменено) · Жалоба Работу с SPI можно посмотреть в моем проекте - https://github.com/Indemsys/Universal3PHalf.../K66BLEZ1_SPI.c В Kinetis у разных SPI разная глубина и чаще всего она равна 1, увы. С флагом SPI_SR_RFDF_MASK у меня тоже что-то не поучалось. Уж не помню что именно. Попробуйте перед приемо-передачей очищать FIFO. void SPI_clear_FIFO(uint8_t modn) { SPI_Type *SPI = spi_mods[modn].spi; SPI->MCR |= BIT(HALT); // Остановить модуль while (SPI->SR & BIT(TXRXS)); // Ожидание пока бит 30 (TXRXS) не станет равным нулю SPI->SR = SPI->SR; SPI->MCR |= BIT(CLR_TXF) + BIT(CLR_RXF); // Установить флаги CLR_TXF и CLR_RXF для очистки обоих FIFO SPI->MCR &= ~BIT(HALT); // Запустить модуль } а SPI_clear_FIFO перед каждым байтом или блоком данных? у меня есть посылка 4096 байт сразу. вообще я при инициализации отменяю ФИФО // Clear TX FIFO Clear RX FIFO Disable Receive FIFO Disable Transmit FIFO SPI2_MCR |= SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK | SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK; Изменено 22 июня, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 22 июня, 2018 Опубликовано 22 июня, 2018 · Жалоба вообще я при инициализации отменяю ФИФО Если отменен FIFO, то логично ожидать, что и все сигналы от него не будут работать и флаги не будут взводится. Тогда все объясняется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 22 июня, 2018 Опубликовано 22 июня, 2018 · Жалоба Если отменен FIFO, то логично ожидать, что и все сигналы от него не будут работать и флаги не будут взводится. Тогда все объясняется. хм...мне на кинетисковском форуме посоветовали отрубить ФИФО. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 24 июня, 2018 Опубликовано 24 июня, 2018 · Жалоба . . . пока что единственное решение которое работает for (timeout = 0; timeout < 10; timeout++); . . . Метод найти, где "собака порылась" не ахти, но все-же. Организуйте отладочный массив структур (или класс) для записи "среза" статусных регистров SPI. static RegsImageSPI MySPI; MySPI.SaveRegs(0); for (timeout = 0; timeout < 10; timeout++); MySPI.SaveRegs(1); --- BP --- просмотреть какой из флагов изменился Этот код добавит таймауты, надо будет скорректировать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 24 июня, 2018 Опубликовано 24 июня, 2018 · Жалоба Метод найти, где "собака порылась" не ахти, но все-же. Организуйте отладочный массив структур (или класс) для записи "среза" статусных регистров SPI. static RegsImageSPI MySPI; MySPI.SaveRegs(0); for (timeout = 0; timeout < 10; timeout++); MySPI.SaveRegs(1); --- BP --- просмотреть какой из флагов изменился Этот код добавит таймауты, надо будет скорректировать. я с дебагером вижу статусный регистр. ставлю брекпойнт и вижу что изменилось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться