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

stm32f407 SPI обнаружил косяк

по картинке

Думаю, что врёт картинка. Потому что в тексте не так. (И из опыта - тоже не так.)

BSY сделан для управления чипселектом, а чипселект надо держать до конца байта, а не до гипотетического момента, когда нам думается, что ведомое устройство уже приняло байт.

У нас есть команды проверки флага, перехода, если установился, подготовки байта (CS) для засылки в порт, засылки в порт. Даже на 168 MHz тактовой это займет не один десяток ns. Пара nop, что вы добавляете, составит ~1/4 от всего количества команд.

Да ради бога, если вам нравится делать устройства, работа которых зависит от погоды на Марсе - делайте, как вам угодно. Только потом не удивляйтесь, если ваш девайс перестанет работать с новой партией микросхем. Вам два человека хором говорят, что RXNE и BSY - это не одно и то же, и что они ходили по этим граблям. Но выбор, конечно, за вами.

 

Именно на STM32F207. НА STM32F103 разрешал отдельной командой. Иначе - никак.

У меня на 10x тоже одной командой:

    RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
    SPIx->I2SCFGR &= ~SPI_I2SCFGR_I2SMOD;
    SPIx->CR2 = 0;
    SPIx->CR1 = SPI_CR1_MSTR | divisor | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE | phase | cpol;

И работает. ЧЯДНТ?

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


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

... а чипселект надо держать до конца байта, а не до гипотетического момента...

Не надо

И работает. ЧЯДНТ?

Что нам скажет товарищ HHIMERA?

 

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

  SPI1->CR1 = SPI_CR1_SSI | SPI_CR1_BR_0 | SPI_CR1_MSTR;        // Fpclk/4
  SPI1->CR2 = SPI_CR2_SSOE;
...
  SPI_Cmd(SPI1, ENABLE);        // разрешить SPI1

 

два человека хором говорят, что RXNE и BSY - это не одно и то же, и что они ходили по этим граблям

И я прошелся когда-то давным-давно, и ничего не заметил:

inline uint8_t SFMByte_send(uint8_t data) {
  while (!(SPI1->SR & SPI_SR_TXE));    // ждать освобождения
  SPI1->DR = data;            // послать данные
  while (!(SPI1->SR & SPI_SR_RXNE));    // ждать байта в приемнике (конца передачи)
//  while (SPI1->SR & SPI_SR_BSY);    // другой способ дождаться конца передачи
  return SPI1->DR;

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


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

Что вы референс не читали...

RXNE говорит только о том, что можно/нельзя забирать данные из приёмного буфера, но это, увы, не признак окончания передачи... вернее, не всегда является признаком...

По поводу SPI_CR1_SSM и SPI_CR1_SSI... всегда их устанавливал... во всей линейке STM32...

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


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

Что вы референс не читали...

RXNE говорит только о том, что можно/нельзя забирать данные из приёмного буфера, но это, увы, не признак окончания передачи... вернее, не всегда является признаком...

Да ну? А вы в курсе, что прием и передача происходят синхронно? Один битик выдвинули, один задвинули.

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


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

И я прошелся когда-то давным-давно, и ничего не заметил:

inline uint8_t SFMByte_send(uint8_t data) {
  while (!(SPI1->SR & SPI_SR_TXE));    // ждать освобождения
  SPI1->DR = data;            // послать данные
  while (!(SPI1->SR & SPI_SR_RXNE));    // ждать байта в приемнике (конца передачи)
//  while (SPI1->SR & SPI_SR_BSY);    // другой способ дождаться конца передачи
  return SPI1->DR;

Конечно не заметили...

while (!(SPI1->SR & SPI_SR_TXE)); здесь и даром не нужна... смело можно выкинуть...

И вполне логично, если возвращать return SPI1->DR, то и проверять нужно while (!(SPI1->SR & SPI_SR_RXNE)); ...

О дёргании CS тут не слова... увы...

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


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

О дёргании CS тут не слова... увы...

inline uint32_t SFMID_read(void)
{
  SFMSel_low();
  volatile uint32_t ID = 0;
  SFMByte_send(SFM_RDID);            // Send "RDID " instruction
  ID = SFMByte_send(SFM_DUMMY);            // Read a byte from the SFM
  ID = (ID<<8) | (SFMByte_send(SFM_DUMMY));    // Read a byte from the SFM
  ID = (ID<<8) | (SFMByte_send(SFM_DUMMY));    // Read a byte from the SFM
  SFMSel_high();
  return ID;
}

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


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

Да ну? А вы в курсе, что прием и передача происходят синхронно? Один битик выдвинули, один задвинули.

И о чем нам это говорит? (с)

 

Какая еще такая "синхронная" связь, между "выдвижением битиков" и выставлением флагов, которые еще через стопицот разных шин, с не пойми какими частотами, доставляются до ядра? В каком порядке эти флаги выставляются, какие там буферизации/задержки, не видя исходного Verilog/VHDL ( на чем там был пИсан этот SPI модуль ), можно только гадать. Или просто воспользоваться описанием в документации.

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


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

Да ну? А вы в курсе, что прием и передача происходят синхронно? Один битик выдвинули, один задвинули.

Неужели???

Вы так и собираетесь мучаться со SPI STM32 на уровне АВР??? )))

Да дочитайте уже референс до конца... спокойно и без нервов... включите воображение...

В частности... для чего существует TXE... и что такое непрерывный режим передачи...

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


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

Не надо

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

Вообще, у вас очень странная позиция. Если вы утверждаете, что нет разницы между RXNE и BSY, то почему вы упёрлись в использование RXNE? Чисто чтоб поспорить?

Короче, утомили вы меня, не стану больше вас отговаривать от глупых поступков. Да и вообще зря я это начал, сразу было понятно, что бесперспективняк.

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


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

while (!(SPI1->SR & SPI_SR_TXE)); здесь и даром не нужна... смело можно выкинуть...

это верно

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


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

Я лично сталкивался с устройствами, которые отбрасывали посылку, если чипселект не удерживать до окончания клоков

Скажу больше, я даже сталкивался с камнем, который защелкивал CS фронтом последнего клока. :) Хотя, формально, это не был SPI, просто serial interface.

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


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

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

Взгляните на картинку еще раз. Среза при передаче последнего бита b7 нет. Ждать нечего.

Вообще, у вас очень странная позиция. Если вы утверждаете, что нет разницы между RXNE и BSY, то почему вы упёрлись в использование RXNE? Чисто чтоб поспорить?

А вы?

 

Вы так и собираетесь мучаться со SPI STM32 на уровне АВР??? )))

Да дочитайте уже референс до конца... спокойно и без нервов... включите воображение...

В частности... для чего существует TXE... и что такое непрерывный режим передачи...

Фантазии отбрасываем. Обсуждаем технические вопросы. Оценки личностных качеств оставляем при себе.

 

Меня больше интересуют биты SSM и SSI.

 

Скажу больше, я даже сталкивался с камнем, который защелкивал CS фронтом последнего клока. :) Хотя, формально, это не был SPI, просто serial interface.

О сдвиговых регистрах я упоминал выше.

 

И о чем нам это говорит? (с)

 

Какая еще такая "синхронная" связь, между "выдвижением битиков" и выставлением флагов, которые еще через стопицот разных шин, с не пойми какими частотами, доставляются до ядра?

О том, что если флаги дошли до ядра, то битики уже выдвинуты и задвинуты. :)

А пока от ядра дойдет до порта, пройдет ох... ох, сколько наносекунд! Так что ведомое устройство уже получит своё.

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


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

Фантазии отбрасываем. Обсуждаем технические вопросы.

А я технически и обсудил...

Приведённые вами примеры - "лишь бы работало"...

В них возможности SPI STM32 не раскрыты даже частично... но я не настаиваю...

Меня больше интересуют биты SSM и SSI.

Всё сначала... Что с ними не так???

 

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


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

О том, что если флаги дошли до ядра, то битики уже выдвинуты и задвинуты. :)

Не надо приписывать флагу то, в чем он "не копенгаген". Битики может и задвинуты, но откуда RXNE знать, что SPI трансфер завершен?

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


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

Подправил код для чтения идентификатора SPI Flash Memory, что показывал выше. Такты выдаются непрерывным потоком, сигнал SS стал короче в 1.5 раза.

uint32_t SFMID_read(void) {
 SMSS_ON();
 uint32_t id = 0;
 SPI1->DR = SFM_RDID;			// послать команду "RDID"
 while (!(SPI1->SR & SPI_SR_TXE));	// ждать освобождение передатчика
 SPI1->DR = SFM_DUMMY;			// послать пустой байт 
 while (!(SPI1->SR & SPI_SR_RXNE));	// ждать байт в приемнике
 id = SPI1->DR;				// High Impedance
 while (!(SPI1->SR & SPI_SR_TXE));	// ждать освобождение передатчика
 SPI1->DR = SFM_DUMMY;			// послать пустой байт
 while (!(SPI1->SR & SPI_SR_RXNE));	// ждать байт в приемнике
 id = SPI1->DR << 16;				// Manufacturer
 while (!(SPI1->SR & SPI_SR_TXE));	// ждать освобождение передатчика
 SPI1->DR = SFM_DUMMY;			// послать пустой байт
 while (!(SPI1->SR & SPI_SR_RXNE));	// ждать байт в приемнике  
 id |= SPI1->DR << 8;				// Memory type
 // while (!(SPI1->SR & SPI_SR_TXE));	// ждать освобождение передатчика  
 while (!(SPI1->SR & SPI_SR_RXNE));	// ждать байт в приемнике
 id |= SPI1->DR;				// Memory capacity
 // while (SPI1->SR & SPI_SR_BSY);	// ждать, если SPI занят
 SMSS_OFF();
 // Test = id;
 return id;
}

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


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

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

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

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

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

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

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

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

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

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