реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Проблема с SPI.
Jenya7
сообщение Jun 21 2018, 13:17
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



я работаю с 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. Че там твориться вообще с Кинетисовским СПИ? Или я что то не так настроил?


Сообщение отредактировал Jenya7 - Jun 21 2018, 15:01
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jun 21 2018, 15:20
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Может не учитываете буферизацию SPI (регистр передачи и сдвиговый регистр), и читаете до освобождения регистра сдвига.
А если таймаут - то "попадает". Смотрите бит "сдвиговый регистр свободен".
С Kinetis не работал. Но это вроде-как типовая структура. (есть биты пустоты для буферного регистра и регистра сдвига.)
Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 21 2018, 16:17
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Тут, судя по ветке про таймер и по "...перебирать флаги в статусном регистре...", проблема в прочитать RefMan.

Я уже почти влюбился wink.gif (в самом хрошем смысле этого слова) в K10.


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jun 21 2018, 20:38
Сообщение #4


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(Obam @ Jun 21 2018, 19:17) *
Тут, судя по ветке про таймер и по "...перебирать флаги в статусном регистре...", проблема в прочитать RefMan.

В Kinetis все операции с SPI делаю через DMA. Тогда получается надежно.
А без DMA, да, есть такая проблема, как чтение раньше времени или слишком поздно. laughing.gif
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 22 2018, 10:43
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(AlexandrY @ Jun 22 2018, 01:38) *
В Kinetis все операции с SPI делаю через DMA. Тогда получается надежно.
А без DMA, да, есть такая проблема, как чтение раньше времени или слишком поздно. laughing.gif


Александр, Вам как главному специалисту по Кинетису вопросы
1. почему флаг while (!(SPIx[spi_num]->SR & SPI_SR_RFDF_MASK)) не работает?
2. Можете показать пример с DMA? У меня не заработало.

я вообще в шоке от Кинетивского СПИ. что это за FIFO в котором нельзя настроить глубину. где флаг дата пришла в POPR. я уже несколько дней танцы с бубнами устраиваю.
пока что единственное решение которое работает for (timeout = 0; timeout < 10; timeout++); перед тем как читать из POPR.
STMовский СПИ просто мерседес в сравнении с Кинетисовским.

Сообщение отредактировал Jenya7 - Jun 22 2018, 11:09
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jun 22 2018, 11:28
Сообщение #6


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(Jenya7 @ Jun 22 2018, 13:43) *
Александр, Вам как главному специалисту по Кинетису вопросы
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); // Запустить модуль
}


Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 22 2018, 11:42
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(AlexandrY @ Jun 22 2018, 16:28) *
Работу с 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;


Сообщение отредактировал Jenya7 - Jun 22 2018, 12:19
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jun 22 2018, 14:17
Сообщение #8


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(Jenya7 @ Jun 22 2018, 14:42) *
вообще я при инициализации отменяю ФИФО

Если отменен FIFO, то логично ожидать, что и все сигналы от него не будут работать и флаги не будут взводится.
Тогда все объясняется.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 22 2018, 18:47
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(AlexandrY @ Jun 22 2018, 19:17) *
Если отменен FIFO, то логично ожидать, что и все сигналы от него не будут работать и флаги не будут взводится.
Тогда все объясняется.

хм...мне на кинетисковском форуме посоветовали отрубить ФИФО.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jun 24 2018, 08:49
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(Jenya7 @ Jun 22 2018, 13:43) *
. . . пока что единственное решение которое работает for (timeout = 0; timeout < 10; timeout++); . . .

Метод найти, где "собака порылась" не ахти, но все-же.
Организуйте отладочный массив структур (или класс) для записи "среза" статусных регистров SPI.
Код
static RegsImageSPI MySPI;
MySPI.SaveRegs(0);
for (timeout = 0; timeout < 10; timeout++);
MySPI.SaveRegs(1);
--- BP --- просмотреть какой из флагов изменился

Этот код добавит таймауты, надо будет скорректировать.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 24 2018, 09:18
Сообщение #11


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(k155la3 @ Jun 24 2018, 14:49) *
Метод найти, где "собака порылась" не ахти, но все-же.
Организуйте отладочный массив структур (или класс) для записи "среза" статусных регистров SPI.
Код
static RegsImageSPI MySPI;
MySPI.SaveRegs(0);
for (timeout = 0; timeout < 10; timeout++);
MySPI.SaveRegs(1);
--- BP --- просмотреть какой из флагов изменился

Этот код добавит таймауты, надо будет скорректировать.

я с дебагером вижу статусный регистр. ставлю брекпойнт и вижу что изменилось.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 16th April 2024 - 23:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01465 секунд с 7
ELECTRONIX ©2004-2016