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

    

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

При инициализации с делителем на 64 (с другими не проверял). SPI3 (с другими не проверял). stm407 на 168МГц (с другими не проверял).

После записи в регистр DR необходимо выждать задержку до проверки флага BSY в регистре SR. Иначе байт может потерятся (затерется следующим).

То есть флаг занятости выскакивает с задержкой. Причём задержка приличная, успеваю выйти и войти в процедуру.

После установки задержки всё устаканилось.

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


Ссылка на сообщение
Поделиться на другие сайты
После записи в регистр DR необходимо выждать задержку до проверки флага BSY в регистре SR.

Имхо, не BSY нужно проверять, а TXE. А SPI на STM32 кажется и правда слегка шизанутый, обмен стартует с задержкой после записи в DR если в текущий момент еще ничего не передавалось. Есть у меня подозрение что это схема аппаратного руления CS не до конца отключена и паузы вставляет.

 

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


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

Попробуйте проверять TXE, а не BSY. BSY это наверно когда непосредственно обмен начался.

post-19443-1353064062_thumb.jpg

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


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

Я конечно понимаю, но

Bit 7 BSY: Busy flag

0: SPI (or I2S)not busy

1: SPI (or I2S)is busy in communication or Tx buffer is not empty

This flag is set and cleared by hardware.

И по моему у них в stdlib именно BSY используется ...

 

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


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

наверное не просто так в RM написано

Note: Do not use the BSY flag to handle each data transmission or reception. It is better to use the

TXE and RXNE flags instead.

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


Ссылка на сообщение
Поделиться на другие сайты
При инициализации с делителем на 64 (с другими не проверял). SPI3 (с другими не проверял). stm407 на 168МГц (с другими не проверял).

Это есть во всех STM32... и ни какой это не косяк...

"Читать даташит до, а не после!"(С)

Note: 1 During discontinuous communications, there is a 2 APB clock period delay between the

write operation to SPI_DR and the BSY bit setting.

После записи в регистр DR необходимо выждать задержку до проверки флага BSY в регистре SR. Иначе байт может потерятся (затерется следующим).

То есть флаг занятости выскакивает с задержкой. Причём задержка приличная, успеваю выйти и войти в процедуру.

После установки задержки всё устаканилось.

Если STM32F4 сидит на 168MHz, a APB SPI3 42MHz... сам и посчитай...

Всё правильно... никаких косяков и нет...

 

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

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


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

C учётом последствий - это просто косяк описанный в даташите.

Там, кстати 2 APB. APB1 (SPI3) и APB2. APB1 по-моему у меня /2.

===

Спорить не буду - сложно посчитать будет. Да и не это главное... Написал, чтобы народ обратил внимание. Я не исключаю, что в другой периферии не может оказаться аналогичных проблем. Думаю из-за значительной скорости процессора.

Я не спорю, это можно описать как "особенности работы с узлами МК" ...

Так, у меня уже проявились "особенности" при работе с I2C и SPI. Так это только начало. Этот SPI работает с АЦП, а SPI1 будет с датафлэшем работать... Если там ещё особенности вылезут - опишу ... ))

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


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

Поддерживаю. Для полнодуплексного (даже если только передача нужна) SPI завершение передачи нужно проверять по... RXNE (и забыть о TXE или BSY, т.к. STM32F не поддерживает аппаратное формирование SS в режиме мастера!). Тогда будет абсолютная уверенность, что байт ушел, а следующий его не затрет по пути: ведь пока байт выдвигается по MOSI, входящий байт вдвигается по MISO тем же тактовым сигналом. Это означает, что флаг RXNE все равно возникнет, пусть позже TXE, зато наверняка после последнего такта. Нужно помнить чистить RXNE путем чтения DR перед записью туда:

 

1. Прочесть DR.

2. Записать в DR байт для передачи.

3. Ждать RXNE (будь-то тупо или путем реакции на прерывание).

4. Перейти к п.1., если еще есть данные для передачи.

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

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


Ссылка на сообщение
Поделиться на другие сайты
Поддерживаю. Для полнодуплексного (даже если только передача нужна) SPI завершение передачи нужно проверять по... RXNE (и забыть о TXE или BSY, т.к. STM32F не поддерживает аппаратное формирование SS в режиме мастера!). Тогда будет абсолютная уверенность, что байт ушел, а следующий его не затрет по пути: ведь пока байт выдвигается по MOSI, входящий байт вдвигается по MISO тем же тактовым сигналом. Это означает, что флаг RXNE все равно возникнет, пусть позже TXE, зато наверняка после последнего такта. Нужно помнить чистить RXNE путем чтения DR перед записью туда:

Делал я так. Побочный эффект - обмен не непрерывный, между байтами пропуски получаются. При тактовой 15МГц, еле на 1МБайт/сек выходило. Пришлось сделать такой вариант:

IO_CALL_TYPE
DWORD
IO_CALL_OPTION
io_at45_read(void)
{
PSTM_SPI pspi = _AT_SPI_;
//
// В целях сохранения быстродействия не	производим проверку
// синхроресурса в функциях	самого нижнего уровня
//
//	IO_ASSERT( at45_mutex.holder ==	tn_curr_run_task, "AT45 synch failure");
//
for(;;)
{
	DWORD stat;
	//
	// Значительно более быстрый вариант - ждать TXE и немедленно
	// запускать новый цикл на SPI если буфер передатчика готов
	// Иначе контроллер делает паузы между символами. Чтобы не
	// потерять принимаемый символ при вытеснении потока, запуск
	// осуществляем при запрещенных прерываниях
	//
	stat = pspi->sSPI_SR;
	if (stat & bSPI_TXE)
	{
		DWORD lock, ret;

		lock = hal_lock_interrupt();
		pspi->sSPI_DR = 0xFF;

		for(;;)
		{
			//
			// Ждем завершения предыдущего цикла
			// и забираем принятые данные по готовности
			//
			if (stat & bSPI_RXNE) 
			{
				ret = pspi->sSPI_DR;
				break;
			}
			stat = pspi->sSPI_SR;
		}
		hal_unlock_interrupt(lock);
		return ret & 0xFF;			
	}
}
}

Скорость выросла раза в 1.5, DMA не пробовал - не очень подходт для задачи.

 

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


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

Да всё там просто...

Всё скрупулёзно и последовательно расписано в даташите...

Нужно просто воспринять TXE, RXNE и BSY так, как их задумал производитель... и обратить их во благо своё...

Вся эта чехарда с флагами, ИМХО, мнимая и надуманная...

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

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


Ссылка на сообщение
Поделиться на другие сайты
Да всё там просто...

Ok. Не поленюсь и в понедельник проверю. Есть осциллограф - он чётко покажет. Какие вопросы.

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


Ссылка на сообщение
Поделиться на другие сайты
Это означает, что флаг RXNE все равно возникнет, пусть позже TXE, зато наверняка после последнего такта.

Кстати, не факт, что после. В зависимости от режима SPI, RXNE может возникать на середине последнего такта (если данные на приёме защёлкиваются по переднему фронту). Вот тут-то наверное и может пригодиться BSY. (Хотя я лично просто делаю несколько nop-ов перед отпусканием CS)

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


Ссылка на сообщение
Поделиться на другие сайты
Вот тут-то наверное и может пригодиться BSY.

Подтверждаю. CS по BSY работает корректно. И вообще. Минимальная библиотека получается. Единственное, что требуется задержка перед проверкой флага. Я на этом остановился. Меня это устраивает полностью. Правда пока я работаю с достаточно медленным АЦП. AD7192. Чуть позже, и по другому SPI буду работать с AT45DB... Пока не решил для себя как. Наверное, сначала, чтобы полностью проверить функционал прибора запущу его тем же драйвером. Потом, уже буду думать. Может ПДП буду испоьзовать и CRC аппаратный ... не знаю.

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


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

2. Записать в DR байт для передачи.

3. Ждать RXNE (будь-то тупо или путем реакции на прерывание).

4. Перейти к п.1., если еще есть данные для передачи.

Не получается: 1. Прочесть DR - после этого флаг RXNE не устанавливается (У меня разрешены прерывания по RXNE). Если сперва что-то записать в DR, то тогда RXNE устанавливается и происходит прерывание.

 

Еще вопрос как я понимаю при работе с SPI необходимо Мастером всегда толкать данные? Например data-flash at45db имеет команду для чтения manufacture id и device id длиной 1 байт=0x9FH, а ответ 6 байт, т.е. после подачи первого байта я должен еще подать 5 фиктивных байт?

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

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


Ссылка на сообщение
Поделиться на другие сайты
Не получается: 1. Прочесть DR - после этого флаг RXNE не устанавливается (У меня разрешены прерывания по RXNE). Если сперва что-то записать в DR, то тогда RXNE устанавливается и происходит прерывание.

 

Еще вопрос как я понимаю при работе с SPI необходимо Мастером всегда толкать данные? Например data-flash at45db имеет команду для чтения manufacture id и device id длиной 1 байт=0x9FH, а ответ 6 байт, т.е. после подачи первого байта я должен еще подать 5 фиктивных байт?

 

В любом случае микросхема SPI памяти не будет выталкивать из себя данные сама, для чтения нужно слать что-нибудь мастером, какие либо незначащие байты.

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


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

Для публикации сообщений создайте учётную запись или авторизуйтесь

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

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация