Перейти к содержанию
    

Проблема с SPI.

я работаю с 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может не учитываете буферизацию SPI (регистр передачи и сдвиговый регистр), и читаете до освобождения регистра сдвига.

А если таймаут - то "попадает". Смотрите бит "сдвиговый регистр свободен".

С Kinetis не работал. Но это вроде-как типовая структура. (есть биты пустоты для буферного регистра и регистра сдвига.)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

В Kinetis все операции с SPI делаю через DMA. Тогда получается надежно.

А без DMA, да, есть такая проблема, как чтение раньше времени или слишком поздно. :laughing:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 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овский СПИ просто мерседес в сравнении с Кинетисовским.

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Александр, Вам как главному специалисту по Кинетису вопросы

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); // Запустить модуль
}

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Работу с 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вообще я при инициализации отменяю ФИФО

Если отменен FIFO, то логично ожидать, что и все сигналы от него не будут работать и флаги не будут взводится.

Тогда все объясняется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если отменен FIFO, то логично ожидать, что и все сигналы от него не будут работать и флаги не будут взводится.

Тогда все объясняется.

хм...мне на кинетисковском форуме посоветовали отрубить ФИФО.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

. . . пока что единственное решение которое работает for (timeout = 0; timeout < 10; timeout++); . . .

Метод найти, где "собака порылась" не ахти, но все-же.

Организуйте отладочный массив структур (или класс) для записи "среза" статусных регистров SPI.

static RegsImageSPI MySPI;
MySPI.SaveRegs(0); 
for (timeout = 0; timeout < 10; timeout++); 
MySPI.SaveRegs(1); 
--- BP --- просмотреть какой из флагов изменился

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Метод найти, где "собака порылась" не ахти, но все-же.

Организуйте отладочный массив структур (или класс) для записи "среза" статусных регистров SPI.

static RegsImageSPI MySPI;
MySPI.SaveRegs(0); 
for (timeout = 0; timeout < 10; timeout++); 
MySPI.SaveRegs(1); 
--- BP --- просмотреть какой из флагов изменился

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

я с дебагером вижу статусный регистр. ставлю брекпойнт и вижу что изменилось.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...