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

 
 
> STM32F407 Проблемы с SPI, Не отсылается байт сразу после проверки бита ТХЕ в регистре SR
BlackOps
сообщение Apr 21 2013, 05:50
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Вот код:

Код
    while ( ( (SPI2 -> SR) & 0x2 ) == RESET)
    {
     //wait until TXE bit is 1
    }
    SPI2 -> DR = d0;



когда этот код исполняется на чипе, или в дебаггере без брейкпоинтов то на осциллографе я только вижу SCK поднятый а MOSI на нуле.
Но когда я исполняю этот код по очереди линию за линией в дебаггере, или же ставлю брейк поинт в дебаггере между циклом while и строчкой с записью в DR, а затем достигнув брейкпоинта опятй продолжаю исполнять код, то на осциллографе вижу переключение SCK и отсылку битов d0.

в чем может быть проблема?

Мне например кажется что SPI2 -> DR = d0; который сразу следует после цикла не дает возможности SPI контроллеру быстро среагировать и послать бит, а исполняя код строка за строкой все работает.

но ведь с другой стороны, я же циклом проверяю бит ТХЕ!? и если я вышел с цикла то буфер свободен и должен бит нормально отослатся?
(я пробовал тоже самое циклом проверять и бит BSY, тоже самое)

есть идеи?


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
6 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 76)
ViKo
сообщение Apr 21 2013, 06:30
Сообщение #2


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Вы только посылаете, ничего не читаете?
Покажите, что у вас до и после делается.
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 06:46
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



после - бесконечный цикл.
до - ничего касательно этого SPI порта.

да, я просто отсылаю один байт. ничего не принимаю.

простой тест, отсылаю, а на выходе ножки цепляю на осциллограф посмотреть.


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 21 2013, 08:02
Сообщение #4


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



На тактовые частоты посмотрите, все ли такие, как задумано.
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 08:30
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



вот настройка SPI
Код
//=============================================================================
// SPI2 Related configuration
//=============================================================================
// enable SPI2 clock
((RCC_TypeDef *) (RCC_BASE))->APB1ENR |= RCC_APB1ENR_SPI2EN;


// configure SPI2
((SPI_TypeDef *) (SPI2_BASE)) -> CR1 |= (SPI_CR1_SPE | SPI_CR1_CPOL |
SPI_CR1_CPHA | SPI_CR1_MSTR |
SPI_CR1_BR_1 | SPI_CR1_SSM | SPI_CR1_SSI);


фпцлк=42MHz, BR=010, когда на осциллографе (в случае если между циклом проверки ТХЕ и записью в регистр DR стоит брейкпоинт) виден SCK , его период примерно 5 MHz.

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

я даже пробовал считывать в переменные содержимое регистра SRи CR1сразу после выхода из цикла проверки на бит ТХЕ. результат:
CR1=б1101010111
(SSM=1,SSI=1,SPE=1,BR=010,MSTR=1,CPOL=1,CPHA=1)
SR=0х2 (т.е. только ТХЕ=1)

а после этого идет запись в DR.
все же вроде правильно!

в чем может быть причина?


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 21 2013, 08:39
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(BlackOps @ Apr 21 2013, 12:30) *
в чем может быть причина?

Может, в настройках оптимизации. Попробуйте отключить оптимизацию.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 21 2013, 08:41
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



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

может вы не тот флажок смотрите, проверяете что освободился не передающий (сдвиговый) регистр, а проверяет что приемный свободен (в смысле тот в которые кладут данные, которые потом передаются в сдвиговый?)
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 08:43
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Цитата(Golikov A. @ Apr 21 2013, 13:41) *
идея такая
данные в регистр
включили передатчик (данные из приемного регистра передаются в сдвиговый)
подождали когда освободиться передающий регистр.

может вы не тот флажок смотрите, проверяете что освободился не передающий (сдвиговый) регистр, а проверяет что приемный свободен (в смысле тот в которые кладут данные, которые потом передаются в сдвиговый?)

Вы кажется первый мой пост совсем пропустили.
вот же код:
Код
    while ( ( (SPI2 -> SR) & 0x2 ) == RESET)
    {
     //wait until TXE bit is 1
    }
    SPI2 -> DR = d0;


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


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 21 2013, 12:54
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ну у меня нет даташита на все стм я не могу проверить реистры биты и названияsad.gif...

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

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

БЛИН!!!

while ( ( (SPI2 -> SR) & 0x2 ) == RESET) - ждете пока бит равен нулю
в коментах пишите //wait until TXE bit is 1, правильно я понимаю что ждать пока 1?

ну и как началась отправка вы сразу вылетаете из цикла, и заменяете отправляемый байт 0

SPI2 -> DR = d0;

готов спорить что написав
SPI2 -> DR = 0xAA; - увидите на выходе AA
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 17:20
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Да нет же!
Все правильно сдесь!

while ( ( (SPI2 -> SR) & 0x2 ) == RESET)

* Если ТХЕ = 0, то (SPI2 -> SR) & 0x2 ) = 0, и 0 = RESET, цикл продолжает исполнятся
* Если ТХЕ = 1, то (SPI2 -> SR) & 0x2 ) = 1, и 0 != RESET, и мы вылетаем из цыкла!

Таким образом я и жду пока бит ТХЕ = 1.


Проблема значит в чем то другом?


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 21 2013, 17:37
Сообщение #11


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



А что за константа RESET?

Вот мой вариант (медленный, вообще-то при выдаче группы бацт готовность проверяю только перед очередным байтом и отдельно - в конце блока для снятия CS):
Код
/* передача байта/слова, возврат считанного */
uint_fast16_t hardware_spi_word(
    uint_fast16_t v        /* значение байта для передачи */
    )
{
    (void) SPI1->DR;    /* clear SPI_SR_RXNE in status register */
    SPI1->DR = (v & SPI_DR_DR);

    // дождаться, пока последний байт выйдет из передатчика
    while ((SPI1->SR & SPI_SR_TXE) == 0)
    ;
    while(!(SPI1->SR & SPI_SR_RXNE))    /* Receive buffer Not Empty */
    ;

    return (SPI1->DR & SPI_DR_DR);
    
}


Обратите вниманире на первое чтние DR.
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 17:45
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



вот моя константа как объявлена: typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;

а зачем делать вот это: SPI1->DR & SPI_DR_DR ?


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 21 2013, 17:59
Сообщение #13


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Цитата
а зачем делать вот это: SPI1->DR & SPI_DR_DR ?

Забейте на это. Необходимости в этом нет. Наследство от AT91SAM7S.
У Вас заработало?

Сообщение отредактировал Genadi Zawidowski - Apr 21 2013, 18:00
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 18:04
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



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


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 21 2013, 18:11
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ну остается только последнее SPI2 или SPI1
точно через 2 посылаете? может пишите в 1 а статуса ждете от 2, а он всегда пустой?
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 18:21
Сообщение #16


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Да, как яуже говорил, если например ставлю брейк межу циклом и между отправкой, то все работает (если SPI2 были бы сконфигурированы не верне, не работало бы вообще!)

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

а прогоняя весь код не работает! причем проблема именно в этих двух линиях! но какая именно понять не могу?

еще вот какой вариант работает:

никаких циклов, ничего, ставлю только это: SPI2->DR = d0;
НО! перед этой строкоы ставлю брейк!

в дебаггере исполняю, доходит до брейка, и на осциллографе вижу как преже поднятй SCK и нулевой MOSI! Но потом, нажимаю кнопку Run опять, и уже исполняыется вышеописанная команда!И вот вижу свой байт на осциллографе и переключение SCK!

А вот если без брейка... т.е. сразу запустить всю прогу! то только вижу приподнятй SCK и нулевой MOSI!


Это на какие либо мысли толкает? что это может быть?


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 21 2013, 18:31
Сообщение #17


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Покажите код, который получился после того, как Вы применили мой образец. Тот код, который сейчас не работает.
Как Вы понимаете, я из рабочего проекта прислал кусок, в котором проблемы из-за двойной буферизации в STM32 решены.
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 18:41
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



вот по вашему образцу код мой:

Код
(void) SPI2->DR;    /* clear SPI_SR_RXNE in status register */
// breakpoint here!
SPI2->DR = (d0 & SPI_DR_DR);

while ((SPI2->SR & SPI_SR_TXE) == 0)
;


Видите коммент где про breakpoint сказано?так вот если ставлю туда брейкпоинт, дохожу до него и опять стартую то работает! если без брейк поинта, то не работает когда исполняется все сразу!

не могу понать почему?


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 21 2013, 18:50
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



у меня глупый вопрос, а скорости SPI хватает? вы частоту не превысили максимально допустимую?

все выглядит каким то чудом.
а вот так если сделать

int dummy = SPI2->DR;
SPI2->DR = 0xAA;
while(1);

что будет?
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 21 2013, 18:58
Сообщение #20


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Подсократили, однако...
Функцию выдачи байта на SPI целиком можно привести?
И как работает без дебаггера? МОжет, где-то статусы изменяются из-за чтения регистра данных дебаггером?
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 19:05
Сообщение #21


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



естесственно хватает, вот что вижу на осциллографе когда работает:
[DELETED]

а вот когда не работает:
[DELETED]


чтото пост большой какойто стал :Р

без дебаггера тоже не работает! т.е. если на чип заливаю, и включаю, то не работает!

Никакой функции нету! исполняю прямо кодом для простоты!

вот один из кодов привожу еще раз, где в комменте указано если там стоит брейк то работает, если нет брейка то не работает.
Код
(void) SPI2->DR;    /* clear SPI_SR_RXNE in status register */
// breakpoint here!
SPI2->DR = (d0 & SPI_DR_DR);

while ((SPI2->SR & SPI_SR_TXE) == 0)
;


да! я знаю! проблема сократилась! но дело в том что непонятно в чем сейчас дело... все просто...убираю брейк не работает если прогорняыется код сразу! ставлю брейк вижу сначала изображение №2 в посте, потом вновь запускаю как только достиг брейка, и вижу изображение №1 (т.е. рабочее)

а если нет брейка, т.е. сразу прогоняыется весь код, то тока изображение №2!

Сообщение отредактировал IgorKossak - Apr 22 2013, 08:01
Причина редактирования: изображения следует прикреплять к сообщению, а не вставлять


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 21 2013, 19:12
Сообщение #22


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Так... 1) А что с выходом чипселекта? Сказать что есть и не подкдючаться к нему:
const uint_fast32_t cr1bits = SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SPE | baudrate;
const uint_fast32_t cr1bits16w = cr1bits | SPI_CR1_DFF;



0) У STM32F1xxx есть errata:
// Silicon errata:
// 2.6.7 I2C1 with SPI1 remapped and used in master mode
// Workaround:
// When using SPI1 remapped, the I2C1 clock must be disabled.


ВЫ не дожидаетесь пока байт передастся (когда примется обратно!). Зачем сократили мой код? Там же это было!
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 19:14
Сообщение #23


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Цитата(Golikov A. @ Apr 21 2013, 22:50) *
все выглядит каким то чудом.
а вот так если сделать

int dummy = SPI2->DR;
SPI2->DR = 0xAA;
while(1);

что будет?


ничего не будет, тоже не работает!
а вот если ставлю брейк на линии int dummy = SPI2->DR; исполняю код, дохожу до брейка, затем опять исполняют, то работает! не могу понять в чем дело!


Цитата(Genadi Zawidowski @ Apr 21 2013, 23:12) *
Так... 1) А что с выходом чипселекта? Сказать что есть и не подкдючаться к нему:
const uint_fast32_t cr1bits = SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SPE | baudrate;
const uint_fast32_t cr1bits16w = cr1bits | SPI_CR1_DFF;



0) У STM32F1xxx есть errata:
// Silicon errata:
// 2.6.7 I2C1 with SPI1 remapped and used in master mode
// Workaround:
// When using SPI1 remapped, the I2C1 clock must be disabled.


ВЫ не дожидаетесь пока байт передастся (когда примется обратно!). Зачем сократили мой код? Там же это было!


да но ведь я же использую SPI2 а не SPI1!


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 21 2013, 19:15
Сообщение #24


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Раз с глухим while не работает, точно с аппаратным выходом NSS Вам надо разбираться.
Цитату их errata я привёл как пример странных взаимосвязей и как намёк на что смотреть. Правда, при этом не работает совсем. Смотрите на NSS.

Сообщение отредактировал Genadi Zawidowski - Apr 21 2013, 19:17
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 21 2013, 19:20
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Не ну тоды магия.

А во придумал!!! А если так?

while ( (SPI2->SR & SPI_SR_TXE) ==0 );
int dummy = SPI2->DR;
SPI2->DR = 0xAA;
while(1);


и как проверить что прием окончен?

Может у вас вызов идет во время приема потому ничего и не работает? А когда перед записью регистра есть брек поинт, проц успевает что-то принять или передать...
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 19:31
Сообщение #26


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



попробовал добавление SPI_CR1_DFF, тоже самое, не работает если прогонять код сразу.
NSS я не использую! И не используя его но исполняя код по строчкам все работает!

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

Ведь ллогически, если сам интерфейс работае в дебаггере когда исполняется по строчкам.. почему он не должен работать когда разом исполняется весь код! вот в чем дело я не думаю чтоэто какое то отношение имеет к NSS.

Просто я не могу понять что еще тут может быть?

Цитата(Golikov A. @ Apr 21 2013, 23:20) *
Не ну тоды магия.

А во придумал!!! А если так?

while ( (SPI2->SR & SPI_SR_TXE) ==0 );
int dummy = SPI2->DR;
SPI2->DR = 0xAA;
while(1);


и как проверить что прием окончен?

Может у вас вызов идет во время приема потому ничего и не работает? А когда перед записью регистра есть брек поинт, проц успевает что-то принять или передать...


нет. и так не работает!

И нет у меня никакого приема! все просто в тех строчках которые я привел! просто использую пины SCK и MOSI и подключаю их к осциллографу! никакого приема или ччего то еще!


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 21 2013, 19:41
Сообщение #27


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



DFF вообще не нужно (этио 16 бит слова).
Вам надо разобраться с SPI_CR1_SSM в Вашей программе.
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 19:53
Сообщение #28


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Ну а что там разбиратся?
у меня и SSM=1 и SSI = 1

Когда SSM=1 то програмное управление слейвом включено.
в таком случае значение бита SSI передается на ногу NSS, и то что на ноге NSS извне игнорируется!
Цитата
Bit 8SSI:Internal slave select
This bit has an effect only when the SSM bit isset. The value of this bit is forced onto the
NSS pin and the IO value of the NSS pin is ignored.

иными словами этим битом можно ногой NSS управлять.

в моемслучае это вообще не принципиально... т.е. с этим я разобрался и это думаю к данной проблеме не имеет отношения.
Ил я не прав в чем то?


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 21 2013, 19:59
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а проц то вообще запускается? без дебагера? Может не стартует?

ну я бы вот что сделал:
я бы статусные регистры выкидывал бы на порт UART если есть.
До
SPI2->DR = Data;
и после, во время while

может чего то оптимизируется?

Если нет порта UART то можно на порт GPIO какой то выводить и осциллографом смотреть...

но считывать состояние регистра постоянно, и определиться где хоть виснет в рабочем режиме...
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 20:41
Сообщение #30


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



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

вот как я считываю сейчас регистры: SR,CR1,CR2 кодом своим:

Код
while ( (SPI2->SR & SPI_SR_TXE) ==0 );
sr_t = SPI2->SR;
cr1_t = SPI2->CR1;
cr2_t = SPI2->CR2;
// breakpoint here!
SPI2->DR = 0xAA;



и вот что вижу в дебаггере, все вроде нормально
CR1=б1101010111
(SSM=1,SSI=1,SPE=1,BR=010,MSTR=1,CPOL=1,CPHA=1)
SR=0х2 (т.е. только ТХЕ=1)
CR2=0

сделал так как Вы предлагли через USART тоже. вот код:

Код
while ( (SPI2->SR & SPI_SR_TXE) ==0 )
    {
    while(!(USART3->SR & USART_SR_TXE)); // check if TXE bit is set
    USART3->DR = (uint8_t)( (SPI2->SR)>>8 ); // sending a byte
    while(!(USART3->SR & USART_SR_TC)); // check if TC bit is set

    while(!(USART3->SR & USART_SR_TXE)); // check if TXE bit is set
    USART3->DR = (uint8_t)( SPI2->SR); // sending a byte
    while(!(USART3->SR & USART_SR_TC)); // check if TC bit is set
    }


while(!(USART3->SR & USART_SR_TXE)); // check if TXE bit is set
USART3->DR = (uint8_t)( (SPI2->SR)>>8 ); // sending a byte
while(!(USART3->SR & USART_SR_TC)); // check if TC bit is set

while(!(USART3->SR & USART_SR_TXE)); // check if TXE bit is set
USART3->DR = (uint8_t)( SPI2->SR); // sending a byte
while(!(USART3->SR & USART_SR_TC)); // check if TC bit is set

SPI2->DR = d0;


в USART увидел только два полученных байта: 00 02

что говорит о том что, то что внутри while цикла не выполнилось, т.к. ТХЕбыл уже равен 1 (т.е. буфер отправки данных изначально ыл свободен)

А затем я получилдва байта 00 02, перед SPI2->DR = d0; как Вы и предлагали
изначение 02 говорит что ТХЕ по пренему равен 1, т.е. буфер свободен.

но не работает это! на осцилографе вижу подтянутый ввех SCK и нулевой MOSI

есть какие идеи?


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 21 2013, 21:04
Сообщение #31


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



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


а если в том месте где вы ставите брекпоинт поставить for(volatile int i=0;i<32000;i++) __NOP();
ну вообщем любую тупую задержку, да на побольше, чтобы секунда прям вышла... несколько раз цикл воткните... хотя отправки по уарту уже сделали эту задержку...

А воткните циклы выдачи на уарт значения SR после строчки
SPI2->DR = Data; ну так для полноты картины...


думаю что уже все проверили, может чип какой то подгоревший? Фиг же его знает, если бы SPI так странно не работал это бы все заметили...

Есть у меня последняя идея.

Может там какая просадка или помеха по питанию при попытке отправки по SPI, которая реально вешает проц... Циклы выдачи после DR=d0; Должны помочь понять. Если вы ставите брек поинт или медленно идете тока хватает, а если программа быстро летит, что-то проседает и кирдык?


Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 21:10
Сообщение #32


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



ладно, мне кажется я частичто решил проблему.
Сейчас работаю БЕЗ дебаггера, компилирую заливаю на чип включаю плату (хотя в дебаггере поведение такоеже)

вот фрагмент кода №1, как уже знаете просто цикл проверки и отправка байта.
Код
while ( (SPI2->SR & SPI_SR_TXE) ==0 )
    {

    }

SPI2->DR = d0;



А вот фрагмент кода №2
Код
for(;;)
{

if ((USART3->SR & USART_SR_RXNE))
    if (USART3->DR == 0x01)
        break;
}


Этот код просто бесконечный цикл, пока с USART3 не будет получена команда 01, как только эта команда получена цикл прерывается, и исполнение программы переходит к фрагменту кода №1

Так вот, компилю, заливаю на флеш.
Затем включаю плату, естесственно ничег не происходит т.к. цикл фрагмента кода №2 работает, затем подаю команду 01 с USART3 и немедленно вижу свой байт на осциллографе!


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

Выходит проблема была в том что когда я подаю питание на плату (и на чип естесственно) то толи порт вывода толи SPI2 периферия еще не успела войти в рабочий режим необходимый для отправки данных?
Или чтото вроде того?
Что думаете?


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 21 2013, 21:15
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



думаю стоит ли у вас микросхема рессета проца?

а в целом там же куча всяких клоков должно запуститься, настроиться всякие ПЛЛ, от них должны появиться клоки периферии и прочее, были ли сделаны все эти процедуры стабилизации клока и прочее?
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 21 2013, 21:37
Сообщение #34


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



да было иначе периферия не работала бы вообще.

Вот еще один интересный тест сделал(как вы говорили проверил также статус после записи), вот код (в этот раз убрал бесконечный цикл в начале):

Код
while ( (SPI2->SR & SPI_SR_TXE) ==0 )
    {
    while(!(USART3->SR & USART_SR_TXE)); // check if TXE bit is set
    USART3->DR = (uint8_t)( (SPI2->SR)>>8 ); // sending a byte
    while(!(USART3->SR & USART_SR_TC)); // check if TC bit is set

    while(!(USART3->SR & USART_SR_TXE)); // check if TXE bit is set
    USART3->DR = (uint8_t)( SPI2->SR); // sending a byte
    while(!(USART3->SR & USART_SR_TC)); // check if TC bit is set
    }


while(!(USART3->SR & USART_SR_TXE)); // check if TXE bit is set
USART3->DR = (uint8_t)( (SPI2->SR)>>8 ); // sending a byte
while(!(USART3->SR & USART_SR_TC)); // check if TC bit is set

while(!(USART3->SR & USART_SR_TXE)); // check if TXE bit is set
USART3->DR = (uint8_t)( SPI2->SR); // sending a byte
while(!(USART3->SR & USART_SR_TC)); // check if TC bit is set

SPI2->DR = d0;

while(!(USART3->SR & USART_SR_TXE)); // check if TXE bit is set
USART3->DR = (uint8_t)( (SPI2->SR)>>8 ); // sending a byte
while(!(USART3->SR & USART_SR_TC)); // check if TC bit is set

while(!(USART3->SR & USART_SR_TXE)); // check if TXE bit is set
USART3->DR = (uint8_t)( SPI2->SR); // sending a byte
while(!(USART3->SR & USART_SR_TC)); // check if TC bit is set



И вот некоторые наблюдения:

1) Когда я скомпилировал и зашил контроллер, то я не только не увиден на осциллографе свой байт, но я еще и не увидел байты полученные от USART3!! Интерестно нет?

2) Затем перед кодом который показан выше я добавляю фрагмент кода №2из моего предыдущего поста(непрерывный цикл с ожиданием команды от USART3), комилю, заливаю, включаю..естесственно ничего пока не происходит т.к. нет команды от USART3 на прерывание цикла, подаю команду на прерывание цикла, И вижу свой отправленныйбайт на осциллографе!
А также вижу уже 4 полученных байта, и вот они:
00 02 до посылки
00 03 после посылки!

Как видите интерестно то что после посылки не только TXE=1 но и RXNE=1 что говорит о том что приемник полный.. (хотя странно ничего я не принимаю..)


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

Если есть какие то еще идеи интерестно было бы узнать



Цитата(Golikov A. @ Apr 22 2013, 02:15) *
думаю стоит ли у вас микросхема рессета проца?


стоит просто ресет кнопка на плате, сбрасывание не помогало ничем


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 22 2013, 03:29
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



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

Такова суть СПИ, как включили клок генератор, так байт не только отправиться но и примется...

Кстати вот интересный момент, а где вы включаете клок генератор? Он в STM автоматом что ли включается по записи байта в DR?

Думаю что после загрузки первое что надо делать это настроить клоки, дождаться везде выставленных флагов, что все клоковые линии работают как надо, а уж потом инициализировать и включат периферию... Но в целом крайне странное поведение, что после старта и передачи управления в main процессор полурабочий. Там же должен быть еще файл стартапа....
Go to the top of the page
 
+Quote Post
HHIMERA
сообщение Apr 22 2013, 03:48
Сообщение #36


Местный
***

Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126



Цитата(BlackOps @ Apr 22 2013, 00:37) *
Интерестно нет?

Ничего интересного... подобная тема уже была...
SPI работает так, как заявлено в даташите... остальное всё от недопонимания...
Цитата
Если есть какие то еще идеи интерестно было бы узнать

Читать даташит до просветления... в части тактирования ядра, тактирования SPI и работы самого SPI...
Исходите из того, что транзакция начинается не сразу после загрузки DR... следовательно... и изменение TXE происходит не сразу...

Сообщение отредактировал HHIMERA - Apr 22 2013, 03:49
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 22 2013, 04:05
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



я вот поглядел даташит(как и реф мануал) и не увидел там упоминания о том что SPI может вообще не запуститься... А тем более упоминания о паузе перед посылкой которая влияет на его работоспособность. Также не нашел никаких битиков говорящих о неработоспособности или о том что еще не вышло время подготовки SPI.

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

Так что если вы знаете что именно надо глядеть, подскажите, всем нам будет интересно. А если пишите из соображений что SPI простая штука, то увы...
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 22 2013, 04:26
Сообщение #38


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Цитата(Golikov A. @ Apr 22 2013, 08:29) *
Кстати вот интересный момент, а где вы включаете клок генератор? Он в STM автоматом что ли включается по записи байта в DR?

Его я включаю перед тем как начать работать с СПИ. Вот так:
Код
//=============================================================================
// SPI2 Related configuration
//=============================================================================
// enable SPI2 clock
((RCC_TypeDef *) (RCC_BASE))->APB1ENR |= RCC_APB1ENR_SPI2EN;


// configure SPI2
((SPI_TypeDef *) (SPI2_BASE)) -> CR1 |= (SPI_CR1_SPE | SPI_CR1_CPOL |
SPI_CR1_CPHA | SPI_CR1_MSTR |
SPI_CR1_BR_1 | SPI_CR1_SSM | SPI_CR1_SSI);


Цитата(Golikov A. @ Apr 22 2013, 08:05) *
А тем более упоминания о паузе перед посылкой которая влияет на его работоспособность. Также не нашел никаких битиков говорящих о неработоспособности или о том что еще не вышло время подготовки SPI.


тоже самое делал и я после тех двух описанных мною тестов в посте №34 и №32.

Согласен, Пустые умные посты типа "все происходит от недопонимания" никому не интерестны, если кто понял и знает в чем именно проблема и желает поделится, буду рад посмотреть, если нет то и постить не стоит.





Цитата(HHIMERA @ Apr 22 2013, 07:48) *
транзакция начинается не сразу после загрузки DR... следовательно... и изменение TXE происходит не сразу...

а это не важно, т.к. я отправляю первый байт, и ТХЕ уже заведомо имеет значение 1.
Об этом я тоже писал, Вы видимо не прочли ветку и поспешили дать банальный совет.



--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 22 2013, 04:39
Сообщение #39


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



HHIMERA выразился не точно. TXE выставляется сразу после загрузки данных в регистр. Пересылка (сдвиг) наружу начинается позже, через 2 такта шины. Тогда же устанавливается флаг BSY.
Кстати, за эти два такта периферийной шины процессор успевает наделать много чего.
BlackOps, поставьте задержку вместо точки останова.
Go to the top of the page
 
+Quote Post
HHIMERA
сообщение Apr 22 2013, 07:07
Сообщение #40


Местный
***

Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126



Цитата(Golikov A. @ Apr 22 2013, 07:05) *
то увы...

Как прочитали - так и работает... увы...

Цитата(BlackOps @ Apr 22 2013, 07:26) *
Вы видимо не прочли ветку и поспешили дать банальный совет.

Угу...
Ещё раз... разногласия/разночтения по SPI присутствуют только в F0 и F3...
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 22 2013, 08:05
Сообщение #41


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата(HHIMERA @ Apr 22 2013, 11:07) *
Как прочитали - так и работает... увы...
Угу...
Ещё раз... разногласия/разночтения по SPI присутствуют только в F0 и F3...


вы написали уже 2 сообщения, но так и не дали ответа. Меня СПИ в этом проце не интересует я другим занимаюсь, потому не копал. Наблюдаю действия человека который с ним мучается, противоречий не вижу, потому заинтригован.

Если же у вас есть что по сути посвятите нас темных... [DELETED]

Сообщение отредактировал IgorKossak - Apr 22 2013, 11:16
Go to the top of the page
 
+Quote Post
HHIMERA
сообщение Apr 22 2013, 09:49
Сообщение #42


Местный
***

Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126



[DELETED]

Сообщение отредактировал IgorKossak - Apr 22 2013, 11:18
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 22 2013, 10:39
Сообщение #43


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(BlackOps @ Apr 22 2013, 08:26) *
Его я включаю перед тем как начать работать с СПИ. Вот так:
Код
//=============================================================================
// SPI2 Related configuration
//=============================================================================
// enable SPI2 clock
((RCC_TypeDef *) (RCC_BASE))->APB1ENR |= RCC_APB1ENR_SPI2EN;


// configure SPI2
((SPI_TypeDef *) (SPI2_BASE)) -> CR1 |= (SPI_CR1_SPE | SPI_CR1_CPOL |
SPI_CR1_CPHA | SPI_CR1_MSTR |
SPI_CR1_BR_1 | SPI_CR1_SSM | SPI_CR1_SSI);

Где-то есть упоминание (для F4), что между установкой битика включения тактирования блока и работы с блоком должно пройти какое-то время. У меня так FSMC не заработал)
Попробую найти это в доках...

UPD: STM32F405/407xx and STM32F415/417xx device limitations
2.1.12 Delay after an RCC peripheral clock enabling
Description
A delay between an RCC peripheral clock enable and the effective peripheral enabling
should be taken into account in order to manage the peripheral read/write to registers.
This delay depends on the peripheral’s mapping:
● If the peripheral is mapped on AHB: the delay should be equal to 2 AHB cycles.
● If the peripheral is mapped on APB: the delay should be equal to 1 + (AHB/APB
prescaler) cycles.
Workarounds
1. Use the DSB instruction to stall the Cortex-M CPU pipeline until the instruction is
completed.
2. Insert ”n” NOPs between the RCC enable bit write and the peripheral register writes
(n = 2 for AHB peripherals, n = 1 + AHB/APB prescaler in case of APB peripherals).
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 22 2013, 10:48
Сообщение #44


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Наконец-то увидел инициализацию.
Зачем SSI и SSM одновременно ставить? В моём (работающем) варианте только SSM стоит (на что я и обращал внимание).
А как следствие - отказ SPI работать, когда кто-то другой держит сигнал SS.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 22 2013, 11:01
Сообщение #45


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



[DELETED]
Цитата(Genadi Zawidowski @ Apr 22 2013, 14:48) *
Наконец-то увидел инициализацию.
Зачем SSI и SSM одновременно ставить? В моём (работающем) варианте только SSM стоит (на что я и обращал внимание).
А как следствие - отказ SPI работать, когда кто-то другой держит сигнал SS.


ну да, наверное правильнее было сразу попросить и инициализацию...

Сообщение отредактировал IgorKossak - Apr 22 2013, 11:17
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 22 2013, 11:06
Сообщение #46


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



У меня хорошо работает такая инициализация:
CODE
void __inline init_SPI2(void)
{
SPI2->CR1 =
(0 << SPI_CR1_SPE)
| (0 << SPI_CR1_DFF)
| (1 << SPI_CR1_SSM)
| (1 << SPI_CR1_SSI)
| (1 << SPI_CR1_MSTR)
| (0 << SPI_CR1_BR);

SPI2->CR2 =
(0 << SPI_CR2_RXNEIE)
| (0 << SPI_CR2_TXDMAEN)
| (1 << SPI_CR2_SSOE);

SPI2->CR1 =
(1 << SPI_CR1_SPE)
| (0 << SPI_CR1_DFF)
| (1 << SPI_CR1_SSM)
| (1 << SPI_CR1_SSI)
| (1 << SPI_CR1_MSTR)
| (0 << SPI_CR1_BR);
}


И такая отправка/прием
Код
BYTE sd_send_byte(const BYTE data)
{
    BYTE spib;
    while((SPI2->SR & (1 << SPI_SR_TXE)) == 0);
    SPI2->DR = data;
    while((SPI2->SR & (1 << SPI_SR_RXNE)) == 0);
    spib = SPI2->DR;
    return spib;
}


Правда, битики я объявляю номером, а не маской...

Сообщение отредактировал IgorKossak - Apr 22 2013, 11:18
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 22 2013, 12:28
Сообщение #47


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Я свои SPI в STM32F207 инициализировал так. Тактирование, естественно, задавал раньше, вместе с остальными устройствами. И больше не трогал.
CODE

/* SPI1 -- связь с SFM M25PE40
8-bit, MSB first, SPEn, Fpclk2 / 4 (15 MHz), Master, CPOL=0, CPHA=0 */
SPI1->CR1 =
SPI_CR1_CPHA * 0 | // Clock Phase
SPI_CR1_CPOL * 0 | // Clock Polarity
SPI_CR1_MSTR * 1 | // Master Selection
SPI_CR1_BR_0 * 1 | // Baud Rate Control - fpclk2 / 4 = 15 MHz
SPI_CR1_BR_1 * 0 | //
SPI_CR1_BR_2 * 0 | //
SPI_CR1_SPE * 1 | // SPI Enable
SPI_CR1_LSBFIRST * 0 | // Frame Format
SPI_CR1_SSI * 1 | // Internal slave select
SPI_CR1_SSM * 1 | // Software slave management
SPI_CR1_RXONLY * 0 | // Receive only
SPI_CR1_DFF * 0 | // Data Frame Format
SPI_CR1_CRCNEXT * 0 | // Transmit CRC next
SPI_CR1_CRCEN * 0 | // Hardware CRC calculation enable
SPI_CR1_BIDIOE * 0 | // Output enable in bidirectional mode
SPI_CR1_BIDIMODE * 0; // Bidirectional data mode enable
SPI1->CR2 =
SPI_CR2_RXDMAEN * 0 | // Rx Buffer DMA Enable
SPI_CR2_TXDMAEN * 0 | // Tx Buffer DMA Enable
SPI_CR2_SSOE * 0 | // SS Output Enable
SPI_CR2_FRF * 0 | // Protocol format - 0: SPI Motorola mode, 1: SPI TI mode
SPI_CR2_ERRIE * 0 | // Error Interrupt Enable
SPI_CR2_RXNEIE * 0 | // RX buffer Not Empty Interrupt Enable
SPI_CR2_TXEIE * 0; // Tx buffer Empty Interrupt Enable
// SPI1->CR1 |= SPI_CR1_MSTR | SPI_CR1_SPE; // Разрешить, Мастер

/* SPI2 -- конфигурирование EP3C5
CONF_N (NSS) переключается программно */
SPI2->CR1 =
SPI_CR1_CPHA * 0 | // Clock Phase
SPI_CR1_CPOL * 0 | // Clock Polarity
SPI_CR1_MSTR * 1 | // Master Selection
SPI_CR1_BR_0 * 0 | // Baud Rate Control - fpclk1 / 2 = 15 MHz
SPI_CR1_BR_1 * 0 | //
SPI_CR1_BR_2 * 0 | //
SPI_CR1_SPE * 1 | // SPI Enable (раньше включалось позже!)
SPI_CR1_LSBFIRST * 1 | // Frame Format
SPI_CR1_SSI * 1 | // Internal slave select (раньше задавалось!)
SPI_CR1_SSM * 1 | // Software slave management
SPI_CR1_RXONLY * 0 | // Receive only
SPI_CR1_DFF * 0 | // Data Frame Format - 8 bit
SPI_CR1_CRCNEXT * 0 | // Transmit CRC next
SPI_CR1_CRCEN * 0 | // Hardware CRC calculation enable
SPI_CR1_BIDIOE * 0 | // Output enable in bidirectional mode
SPI_CR1_BIDIMODE * 0; // Bidirectional data mode enable
SPI2->CR2 =
SPI_CR2_RXDMAEN * 0 | // Rx Buffer DMA Enable
SPI_CR2_TXDMAEN * 0 | // Tx Buffer DMA Enable
SPI_CR2_SSOE * 0 | // SS Output Enable (все равно используется GPIO?)
SPI_CR2_FRF * 0 | // Protocol format - 0: SPI Motorola mode, 1: SPI TI mode
SPI_CR2_ERRIE * 0 | // Error Interrupt Enable
SPI_CR2_RXNEIE * 0 | // RX buffer Not Empty Interrupt Enable
SPI_CR2_TXEIE * 0; // Tx buffer Empty Interrupt Enable
// SPI2->CR1 |= SPI_CR1_SPE;

/* SPI3 -- регистр управления аналоговыми узлами
8-bit, MSB first, SPEn, Fpclk1 / 2 (15MHz), Master, CPOL=0, CPHA=0
74HC595 SCK - Pos, AD5314 SCK - Neg (изменить CPOL) */
SPI3->CR1 =
SPI_CR1_CPHA * 0 | // Clock Phase
SPI_CR1_CPOL * 0 | // Clock Polarity HC595
SPI_CR1_MSTR * 1 | // Master Selection
SPI_CR1_BR_0 * 0 | // Baud Rate Control - fpclk1 / 2 = 15 MHz
SPI_CR1_BR_1 * 0 | //
SPI_CR1_BR_2 * 0 | //
SPI_CR1_SPE * 1 | // SPI Enable
SPI_CR1_LSBFIRST * 0 | // Frame Format
SPI_CR1_SSI * 1 | // Internal slave select
SPI_CR1_SSM * 1 | // Software slave management
SPI_CR1_RXONLY * 0 | // Receive only
SPI_CR1_DFF * 0 | // Data Frame Format (8 bit)
SPI_CR1_CRCNEXT * 0 | // Transmit CRC next
SPI_CR1_CRCEN * 0 | // Hardware CRC calculation enable
SPI_CR1_BIDIOE * 0 | // Output enable in bidirectional mode
SPI_CR1_BIDIMODE * 0; // Bidirectional data mode enable
SPI3->CR2 =
SPI_CR2_RXDMAEN * 0 | // Rx Buffer DMA Enable
SPI_CR2_TXDMAEN * 0 | // Tx Buffer DMA Enable
SPI_CR2_SSOE * 0 | // SS Output Enable
SPI_CR2_FRF * 0 | // Protocol format - 0: SPI Motorola mode, 1: SPI TI mode
SPI_CR2_ERRIE * 0 | // Error Interrupt Enable
SPI_CR2_RXNEIE * 0 | // RX buffer Not Empty Interrupt Enable
SPI_CR2_TXEIE * 0; // Tx buffer Empty Interrupt Enable
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 22 2013, 15:56
Сообщение #48


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата(Genadi Zawidowski @ Apr 22 2013, 14:48) *
Наконец-то увидел инициализацию.
Зачем SSI и SSM одновременно ставить? В моём (работающем) варианте только SSM стоит (на что я и обращал внимание).
А как следствие - отказ SPI работать, когда кто-то другой держит сигнал SS.

нашел вот тут такое руководство http://chipspace.ru/stm32-spi/

в нем утверждается что если поставить SSM, чтобы устройство было мастером необходимо поставить и SSI, это будет двигать уровень NSS, тоже говорит и реф мануал...


Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 22 2013, 16:18
Сообщение #49


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Цитата
в нем утверждается что если поставить SSM, чтобы устройство было мастером необходимо поставить и SSI, это будет двигать уровень NSS, тоже говорит и реф мануал...

В комментах к руководству есть подтверждения проблем. Кроме всего прочего, в статье указывается о диагностике, с которой SPI MASTER переходит в режим SLAVE из-за проблем с NSS. Нашему коллеге с проблемами в SPI может помочь.

Сообщение отредактировал Genadi Zawidowski - Apr 22 2013, 19:52
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 22 2013, 16:28
Сообщение #50


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



не понятно почему пауза перед записью в регистр помогала решить проблему... может все таки что-то схемное...
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 22 2013, 21:04
Сообщение #51


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Цитата(Golikov A. @ Apr 22 2013, 19:56) *
в нем утверждается что если поставить SSM, чтобы устройство было мастером необходимо поставить и SSI, это будет двигать уровень NSS, тоже говорит и реф мануал...

так это и я говорил вот в этом посте, ссылаясь на даташит:
http://electronix.ru/forum/index.php?showt...t&p=1156434



Цитата(Golikov A. @ Apr 22 2013, 20:28) *
не понятно почему пауза перед записью в регистр помогала решить проблему... может все таки что-то схемное...

да нет там ничего сложного в схеме, цепляю выводи к осциллографу и все.
А плата стандартная дискавери.


Golikov A.
за линк спасибо, пройдусь по нему тоже.

Genadi Zawidowski: использование только SSM без SSI проблему тоже не решало.


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 23 2013, 04:11
Сообщение #52


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Я так и не увидел ответа, что SPI не работал из-за того, что тактовая частота на модуль SPI подавалась непосредственно перед его использованием.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 23 2013, 04:26
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата(ViKo @ Apr 23 2013, 08:11) *
Я так и не увидел ответа, что SPI не работал из-за того, что тактовая частота на модуль SPI подавалась непосредственно перед его использованием.


потому что это не так.

перед отправкой байта пробовали втыкать посылку по уарт явно больше 2 тактов шины
после отправки ставили while(1) на случай если бит TXE ставиться с задержкой.
пробовали ждать ТХЕ до отправки он в 1 и ситуация таже.

нужна достаточно долгая пауза перед стартом, непонятно почему. Я ставлю на то что либо какие то клоки стабилизируются (не понятно почему тогда УАРТ работает), или что-то заряжается... вообщем ситуация странная о чем мы все и говорим...



Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 23 2013, 06:16
Сообщение #54


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Если вход NSS перед началом передачи где-то около "0", то и не передаст. Если успел зарядиться - то прокатывает. Я "ставлю" на это.
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 23 2013, 07:41
Сообщение #55


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Цитата(Golikov A. @ Apr 23 2013, 08:26) *
нужна достаточно долгая пауза перед стартом, непонятно почему. Я ставлю на то что либо какие то клоки стабилизируются (не понятно почему тогда УАРТ работает),

в этом посте:
http://electronix.ru/forum/index.php?showt...t&p=1156458

я как раз таки хотел сказать в пункте 1), что отправка байта с УАРТ тоже не сработала! пришлось поставить непрерывный цикл, и ждать команды от того же уарта (приема от него байта команды) который прерывает цикл, а дальше код исполняет ту процедуру с отправкой байта в СПИ.


Цитата(Genadi Zawidowski @ Apr 23 2013, 10:16) *
Если вход NSS перед началом передачи где-то около "0", то и не передаст. Если успел зарядиться - то прокатывает. Я "ставлю" на это.

Я не думаю что это так, потомучто я сделал такой тест:

Подключил к осциллографу не только SCK/MOSI, но еще и NSS. И включил передачю байта разумеется в режиме в котором у меня работает нормально, т.е. байт я вижу на осциллографе.. а вот НСС всегда нулевой! Даже не дернулся во время передачи! (хотя байт сам передался как надо я ето вижу на дисплее осциллографа)
хотя это странно у меня же и SSM и SSI поставлены как 1...




--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 23 2013, 08:49
Сообщение #56


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Нет желания подтянуть к "1" вывод NSS? ИЛи поиграться отключением его от вывода процессора?
Go to the top of the page
 
+Quote Post
HHIMERA
сообщение Apr 23 2013, 09:37
Сообщение #57


Местный
***

Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126



Детский сад... гадание пальцем на манной каше... biggrin.gif
Да не так это всё делается... по хорошему...
Выкладывается проект со всеми настройками, по самому минимуму и без всяких излишеств... типа УАРТ и прочей хрени... когда ещё глюк "имеет место быть"...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 23 2013, 09:41
Сообщение #58


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(HHIMERA @ Apr 23 2013, 12:37) *
Выкладывается проект со всеми настройками, по самому минимуму и без всяких излишеств...

+1.
Имею Дискавери F4, Кейл. Могу проверить. И осциллограф - Agilent. sm.gif
Go to the top of the page
 
+Quote Post
Tolyaha
сообщение Apr 23 2013, 10:11
Сообщение #59


Частый гость
**

Группа: Свой
Сообщений: 116
Регистрация: 2-03-07
Из: Украина
Пользователь №: 25 826



Цитата(ViKo @ Apr 23 2013, 12:41) *
Имею Дискавери F4, Кейл. Могу проверить. И осциллограф - Agilent. sm.gif

Вобщем, щас загрузил кусочек ТС к себе на плату (скопировал и вставил с первого поста) с STM405, все работает
Не выложена инициализация портов.
Так что, гдето в другом месте лажа.
Прошу прощения не первый, а с настройкой SPI
Go to the top of the page
 
+Quote Post
HHIMERA
сообщение Apr 23 2013, 11:01
Сообщение #60


Местный
***

Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126



Цитата(Tolyaha @ Apr 23 2013, 13:11) *
Не выложена инициализация портов.

Ага... и в итоге окажется, что ноги настроены open-drain и Low Speed... laughing.gif
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 23 2013, 11:14
Сообщение #61


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Цитата
Детский сад... гадание пальцем на манной каше...

А что ещё делать с неполной информацией?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 23 2013, 16:21
Сообщение #62


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



написать что типа в мануале все верно, а все дураки...

кстати про ноги хорошая идея, они настроены на правильную частоту работы то?
НСС - сам не должен прыгать , в режиме когда SSM в 1, SSI им управляет, вы задаете значение SSI, а NSS реагирует, вроде как...
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 23 2013, 19:46
Сообщение #63


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Короче,чтобы начать плностью с нуля, пошел взял новую плату Дискавери, девственную, вскрыл упаковку подключил только ноги PB13,PB14 к осциллографу.

Переписал новый проект, выкинул все, оставил только SPI2 работающий на:
PB12 - NSS
PB13 - SCK
PB14 - MISO (не использую в тесте)
PB15 - MOSI

Проект прикреплен к сообщению.

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

Значит в старом проекте проблема усугублялась тем чтоподключены и другие устройства к порту были (PWM - просто вывод напины,I2C1 - подключены 2 сенсора)
Я не думаю хотя что в старой плате дискавери был дефект, т.к. тогда не рабтало бы вообще. Сорее всего проблемабыла с включением нескольких периферий на одном порту сразу, другого ничего не может быть.


Вот что я отработал в новом проекте:

1) SSM=0,SSI=0
Включил, естессвтенно не сработало

2) SSM=0,SSI=0, Подтянул 1 к выводу NSS (PB12) как посоветовали.
Сработало, сразу после включения вижу байт на осциллографе

3) SSM=1,SSI=1, ничего не подтянуто к NSS
Сработало тоже, сразу после включения вижу байт на осциллографе


Прикрепленный проект содержит конфигурацию №3


Теперь у меня вопрос по конфигурации №3: Почему после и во время того как я увидел свой байт на осциллографе NSS (PB12) ни разу не поднялся на уровень "1"?
Ведь у меня же стоит SSM=1,SSI=1... Почему NSS не равен "1" на ножке PB12?
Проверяю тестером и осциллографом, он всегда 0
Пробовал включать SSOE в регистре СR2 всеравно пин NSS всегда 0





Да, я вижу вы говорили про настройки ног, вот как настроены они был для порта B в старом проекте:
(К данному прикрепленному тестовому проекту отношения не имеет!!, NSS и MISO были закомментированы позже)

CODE
//=============================================================================
// GPIOB configuration
//=============================================================================

// enable GPIOB clock
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;

// Alternate Function
GPIOB->MODER = 0; // clear moder register
GPIOB->MODER |=
(
//GPIO_MODER_MODER12_1 | // Alternate Function, SPI2 NSS
GPIO_MODER_MODER13_1 | // Alternate Function, SPI2 SCK
//GPIO_MODER_MODER14_1 | // Alternate Function, SPI2 MISO
GPIO_MODER_MODER15_1 | // Alternate Function, SPI2 MOSI

GPIO_MODER_MODER9_1 | // Alternate Function, I2C1, SDA
GPIO_MODER_MODER8_1 | // Alternate Function, I2C1, SCL

GPIO_MODER_MODER4_1 | // AF, PWM_OUT1, TIM3_CH1
GPIO_MODER_MODER5_1 | // AF, PWM_OUT2, TIM3_CH2
GPIO_MODER_MODER0_1 | // AF, PWM_OUT3, TIM3_CH3
GPIO_MODER_MODER1_1 | // AF, PWM_OUT4, TIM3_CH4
GPIO_MODER_MODER6_1 | // AF, PWM_IN5, TIM4_CH1
GPIO_MODER_MODER7_1 // AF, PWM_IN6, TIM4_CH2
);

// Output type
GPIOB->OTYPER = 0; // clear otype register
GPIOB->OTYPER |= // push-pull if 0
(
GPIO_OTYPER_OT_8 | // Open-Drain, I2C1, SCL
GPIO_OTYPER_OT_9 // OPen-Drain, I2C1, SDA
);

// Speed type
GPIOB->OSPEEDR = 0; // clear ospeedr register
GPIOB->OSPEEDR |=
(
//GPIO_OSPEEDER_OSPEEDR12_1 | // SPI2 NSS 50MH
GPIO_OSPEEDER_OSPEEDR13_1 | // SPI2 SCK, 50MHz
//GPIO_OSPEEDER_OSPEEDR14_1 | // SPI2 MISO 50MH
GPIO_OSPEEDER_OSPEEDR15_1 | // SPI2 MOSI 50MH

GPIO_OSPEEDER_OSPEEDR4_1 | // PWM_OUT1, TIM3_CH1, 50MHz
GPIO_OSPEEDER_OSPEEDR5_1 | // PWM_OUT2, TIM3_CH2, 50MHz
GPIO_OSPEEDER_OSPEEDR0_1 | // PWM_OUT3, TIM3_CH3, 50MHz
GPIO_OSPEEDER_OSPEEDR1_1 | // PWM_OUT4, TIM3_CH4, 50MHz
GPIO_OSPEEDER_OSPEEDR6_1 | // PWM_IN5, TIM4_CH1, 50MHz
GPIO_OSPEEDER_OSPEEDR7_1 // PWM_IN6, TIM4_CH2, 50MHz
);

// Push/Pull
GPIOB->PUPDR = 0; // clear pupdr register
GPIOB->PUPDR |=
(
GPIO_PUPDR_PUPDR8_0 | // Pull-Up, I2C1, SCL
GPIO_PUPDR_PUPDR9_0 | // Pull-Up, I2C1, SDA
GPIO_PUPDR_PUPDR4_0 | // Pull-Up, PWM_OUT1, TIM3_CH1
GPIO_PUPDR_PUPDR5_0 | // Pull-Up, PWM_OUT2, TIM3_CH2
GPIO_PUPDR_PUPDR0_0 | // Pull-Up, PWM_OUT3, TIM3_CH3
GPIO_PUPDR_PUPDR1_0 | // Pull-Up, PWM_OUT4, TIM3_CH4
GPIO_PUPDR_PUPDR6_0 | // Pull-Up, PWM_IN5, TIM4_CH1
GPIO_PUPDR_PUPDR7_0 // Pull-Up, PWM_IN6, TIM4_CH2
);


// Alternate Function pins
GPIOB->AFR[1] = 0; // clear AFR_H register
GPIOB->AFR[1] |=
(
(4 << ((8 - 8) << 2)) | // I2C1 SCL, AF4
(4 << ((9 - 8) << 2)) | // I2C1 SDA, AF4

//(5 << ((12 - 8) << 2)) | // SPI2 NSS, AF5
(5 << ((13 - 8) << 2)) | // SPI2 SCK, AF5
//(5 << ((14 - 8) << 2)) | // SPI2 MISO, AF5
(5 << ((15 - 8) << 2)) // SPI2 MOSI, AF5

);

GPIOB->AFR[0] = 0; // clear AFR_L register
GPIOB->AFR[0] |=
(
(2 << ((4 - 0) << 2)) | // PWM_OUT1, TIM3_CH1, AF2
(2 << ((5 - 0) << 2)) | // PWM_OUT2, TIM3_CH2, AF2
(2 << ((0 - 0) << 2)) | // PWM_OUT3, TIM3_CH3, AF2
(2 << ((1 - 0) << 2)) | // PWM_OUT4, TIM3_CH4, AF2
(2 << ((6 - 0) << 2)) | // TIM4_CH1, AF2
(2 << ((7 - 0) << 2)) // TIM4_CH2, AF2
);

Прикрепленные файлы
Прикрепленный файл  test3_with_spi2_working.zip ( 3.62 мегабайт ) Кол-во скачиваний: 10
 


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 24 2013, 03:41
Сообщение #64


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а где варианта
SSM =1, SSI = 0?

вроде как инструкция об этом говорит. SSM = 1, SSI - задает состояние NSS, или нет?

еще вот такая приписка

Когда NSS разрешено работать в качестве выхода (SSM = 0, SSOE = 1), эта конфигурация используется только в режиме Master. Когда ведущее устройство начинает соединение, NSS переводится в состояние низкого уровня, и поддерживается в этом состоянии до момента деактивации модуля SPI.


и остается теперь потихоньку добавлять периферию прошлого проекта и смотреть какой модуль убъет СПИsm.gif
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 24 2013, 04:13
Сообщение #65


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Цитата(Golikov A. @ Apr 24 2013, 08:41) *
Когда NSS разрешено работать в качестве выхода (SSM = 0, SSOE = 1), эта конфигурация используется только в режиме Master. Когда ведущее устройство начинает соединение, NSS переводится в состояние низкого уровня, и поддерживается в этом состоянии до момента деактивации модуля SPI.

Попробовал этот вариант тоже. Тогда байт не передается, мне нужно вручную проводом подтянуть NSS к "1" чтобы заработало (ну и тогда естесственно NSS никогда на ноль естесственно не подтягивается стоит как 1 всегда, даже когда выключаю модуль)


Цитата(Golikov A. @ Apr 24 2013, 08:41) *
а где варианта
SSM =1, SSI = 0?

Тогда вообще не работает.

Простенькй проект прикрепил (работающий: SSM=1,SSI=1,SSOE=0) если хотите можете проверить.


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 24 2013, 04:37
Сообщение #66


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(BlackOps @ Apr 24 2013, 08:13) *
Простенькй проект прикрепил (работающий: SSM=1,SSI=1,SSOE=0) если хотите можете проверить.

А зачем SSOE=0?
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 24 2013, 04:51
Сообщение #67


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



затем что с ним не работает как надо!
SSM = 0, SSOE = 1
"Попробовал этот вариант тоже. Тогда байт не передается, мне нужно вручную проводом подтянуть NSS к "1" чтобы заработало (ну и тогда естесственно NSS никогда на ноль естесственно не подтягивается стоит как 1 всегда, даже когда выключаю модуль)"


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 24 2013, 04:54
Сообщение #68


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(BlackOps @ Apr 24 2013, 08:51) *
затем что с ним не работает как надо!

А вариант: SSM=1, SSI=1, SSOE=1, NSS управляется через GPIO чем-то не устраивает?
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 24 2013, 05:05
Сообщение #69


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Я не пойму немного, разве целью установки SSOE=1 не является автоматическое управление пином NSS?
т.е.сделать так, чтобы этот пин сам подтягивался на 0 во время транзакции и возвращался на 1 когда транзакция закончена?
как можно достичь такoго поведения?


И еще, вы говорите SSOE=1 и управляй пином NSS через GPIO.. но ведь пин PB12 (NSS) настроен как Alternate Function... ?


(тестовыйпроект выложен в этом посте если что: http://electronix.ru/forum/index.php?showt...&p=1157091)


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 24 2013, 05:51
Сообщение #70


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



SSM=1, SSI = 0 - тут пин NSS в 1 вроде должен быть, передавать нельзя до момента SSI = 1, который как раз пин NSS переведет в 0. Я вроде так понял мануал...
Go to the top of the page
 
+Quote Post
adnega
сообщение Apr 24 2013, 06:22
Сообщение #71


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(BlackOps @ Apr 24 2013, 09:05) *
И еще, вы говорите SSOE=1 и управляй пином NSS через GPIO.. но ведь пин PB12 (NSS) настроен как Alternate Function... ?

Никто не мешает изменить его на OUT_PP.
Вообще разные бывают случаи и управлять NSS "автоматом" можно только в простейших из них.
Например, при инициализации SD карт по SPI вначале нужно передать 0xFF 74 раза при NSS=1.
Go to the top of the page
 
+Quote Post
BlackOps
сообщение Apr 24 2013, 07:45
Сообщение #72


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Цитата(adnega @ Apr 24 2013, 11:22) *
Никто не мешает изменить его на OUT_PP.
Вообще разные бывают случаи и управлять NSS "автоматом" можно только в простейших из них.
Например, при инициализации SD карт по SPI вначале нужно передать 0xFF 74 раза при NSS=1.


Ну вобщем сейчас я поменял NSS на General Purpose Pin, и захотел чтобы этот пин был 0 во время транзакции и 1 когда нет транзакции.
решил установить его в начале 1, затем перед транзакцией на 0, потом проверить биты TXE и BSY а затем опять выставить в 1.

Проблема была в том, что TXE и BSY видимо выставляются почти сразу после того как сдвиговый регистр загружен, и если после этого выставлять пин на 1 то получается слишком рано, чуть ли не у начала реальной транзакции ( а не в конце).

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

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

для справки, мне надо чтобы этот SS (NSS) пин вел себя как сигнал LE вот на этой диаграмме:
http://i.imgur.com/EV9flrf.jpg

вот еще такое решение, проверка RXNE, чтение DR затем проверка BSY, затем уже поднять вручную пин на 1

CODE
GPIOB->ODR |= GPIO_ODR_ODR_12;

//////////////// SPI2 Communication Routine ///////////////////////////////////
while ( ( (SPI2 -> SR) & SPI_SR_TXE ) == RESET)
{
// wait until TXE bit is 1
}
GPIOB->ODR &= !GPIO_ODR_ODR_12;

SPI2 -> DR = d0;


while ( //( ( (SPI2 -> SR) & SPI_SR_TXE ) == RESET) &&
(( (SPI2 -> SR) & SPI_SR_RXNE ) == RESET) )
{

}

dd = SPI2->DR;


while ( //( ( (SPI2 -> SR) & SPI_SR_TXE ) == RESET) &&
(( (SPI2 -> SR) & SPI_SR_BSY ) == SET) )
{

}


GPIOB->ODR |= GPIO_ODR_ODR_12;


так более красиво как то (не нужно циклы вставлять..)

Сообщение отредактировал IgorKossak - Apr 24 2013, 08:44
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 24 2013, 07:51
Сообщение #73


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



http://electronix.ru/forum/index.php?showt...t&p=1127634
Go to the top of the page
 
+Quote Post
HHIMERA
сообщение Apr 24 2013, 11:44
Сообщение #74


Местный
***

Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126



Всё это, конечно... очень интересно... rolleyes.gif
"А был ли мальчик?"(С)
А глюк то... где??? Неужто самоликвидировался???
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 24 2013, 12:00
Сообщение #75


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Цитата
поетому поставил небольшой цикл for, чтобы отрегулировать задержку

Смотрим мой кусочек кода и копируем оттуда ожидание ПРИЁМА - после этого точно байт/слово передался. с задержками это опять магия потребуется.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 24 2013, 13:52
Сообщение #76


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата(HHIMERA @ Apr 24 2013, 15:44) *
Всё это, конечно... очень интересно... rolleyes.gif
"А был ли мальчик?"(С)
А глюк то... где??? Неужто самоликвидировался???


если коротко ТС взял другую плату дискавери, и залил туда проект с одним лишь СПИ, без прочей периферии, и глюк пропал.

Предложение по одному добавлять остальную периферию и найти какой модуль рушит СПИ одобрения не встретило. Потому до конца не ясно что же является причиной плата или остальная периферия.
Go to the top of the page
 
+Quote Post
BlackOps
сообщение May 2 2013, 03:51
Сообщение #77


Знающий
****

Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121



Пишу с опозданием надобыло кое какие проекты сдавать и платы делать.

Во первых я не заявлял что нашел глюк, тема четко говорит "проблемы с СПИ", а проблемы могут быть по разым причинам, в том числе и по причине моей ошибки.

Сделал вот что:

1) После того как убедился что на новой голой плате проект СПИ заработал, я переписал старый проект по новому, и прогнал его тоже на новой плате - Заработало.

2) Старую платуполностью отсоеденил от всего что было соеденено, прогнал тот же епределанный проект - Заработало.

3) Начал присоеденять по очереди остальную перферию - Заработало с присоединенной всей периферией (Uart,PWM,I2C)

4) После того как СПИ проект с подсоединенной но не активизированной программно периферией заработал, я ее начал по очереди активизировать, в итоге проект был доведен до "оригиального" состояния, и тоже заработал

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


Единственное что я заметил в результате всего этого это задержка SCK на примерно 1500нс когда все нижеприведенные функции не заккоментированны.
Когда закомментированны две последние функции включения i2c и usart3 то задержка подтянутого SCK не более 400нс
Когда закомментирован только usart3 то задержка SCk перед его переключением и посылкой байта 900нс
Когда все нижеприведенные функции включены (не закомментированны) то задержка SCK перед его переключением и посылкой байта 1500нс

При этом: Если включить всеэти функции (не комментировать их) и включить цикл задержки длинной после включения платы, а потом подать через тот же Usart3 команду на посылку байта по SPI, то байт отсылается сразу и SCK не задерживается (сразу начинает пиерелючатся)

Вот моя последовательность включения программно периферии:
Код
config_gpio_all(); // configure all GPIOs
config_pwm_io(); // configure Input and Output PWM channels
config_spi_all(); // config all peripherals using SPI
config_i2c_all(); // config all peripherals using I2C
config_usart3(); // configure USART3


А вот код каждой функции:
CODE

uint32_t config_gpio_all(void)
{

//=============================================================================
// GPIOB configuration
//=============================================================================

// enable GPIOB clock
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;

// Alternate Function
GPIOB->MODER = 0; // clear moder register
GPIOB->MODER |=
(
GPIO_MODER_MODER12_1 | // Alternate Function, SPI2 NSS
GPIO_MODER_MODER13_1 | // Alternate Function, SPI2 SCK
GPIO_MODER_MODER14_1 | // Alternate Function, SPI2 MISO
GPIO_MODER_MODER15_1 | // Alternate Function, SPI2 MOSI

GPIO_MODER_MODER9_1 | // Alternate Function, I2C1, SDA
GPIO_MODER_MODER8_1 | // Alternate Function, I2C1, SCL

GPIO_MODER_MODER4_1 | // AF, PWM_OUT1, TIM3_CH1
GPIO_MODER_MODER5_1 | // AF, PWM_OUT2, TIM3_CH2
GPIO_MODER_MODER0_1 | // AF, PWM_OUT3, TIM3_CH3
GPIO_MODER_MODER1_1 | // AF, PWM_OUT4, TIM3_CH4
GPIO_MODER_MODER6_1 | // AF, PWM_IN5, TIM4_CH1
GPIO_MODER_MODER7_1 // AF, PWM_IN6, TIM4_CH2
);

// Output type
GPIOB->OTYPER = 0; // clear otype register
GPIOB->OTYPER |= // push-pull if 0
(
GPIO_OTYPER_OT_8 | // Open-Drain, I2C1, SCL
GPIO_OTYPER_OT_9 // OPen-Drain, I2C1, SDA
);

// Speed type
GPIOB->OSPEEDR = 0; // clear ospeedr register
GPIOB->OSPEEDR |=
(
GPIO_OSPEEDER_OSPEEDR12_1 | // SPI2 NSS 50MH
GPIO_OSPEEDER_OSPEEDR13_1 | // SPI2 SCK, 50MHz
GPIO_OSPEEDER_OSPEEDR14_1 | // SPI2 MISO 50MH
GPIO_OSPEEDER_OSPEEDR15_1 | // SPI2 MOSI 50MH

GPIO_OSPEEDER_OSPEEDR4_1 | // PWM_OUT1, TIM3_CH1, 50MHz
GPIO_OSPEEDER_OSPEEDR5_1 | // PWM_OUT2, TIM3_CH2, 50MHz
GPIO_OSPEEDER_OSPEEDR0_1 | // PWM_OUT3, TIM3_CH3, 50MHz
GPIO_OSPEEDER_OSPEEDR1_1 | // PWM_OUT4, TIM3_CH4, 50MHz
GPIO_OSPEEDER_OSPEEDR6_1 | // PWM_IN5, TIM4_CH1, 50MHz
GPIO_OSPEEDER_OSPEEDR7_1 // PWM_IN6, TIM4_CH2, 50MHz
);

// Push/Pull
GPIOB->PUPDR = 0; // clear pupdr register
GPIOB->PUPDR |=
(
GPIO_PUPDR_PUPDR8_0 | // Pull-Up, I2C1, SCL
GPIO_PUPDR_PUPDR9_0 | // Pull-Up, I2C1, SDA
GPIO_PUPDR_PUPDR4_0 | // Pull-Up, PWM_OUT1, TIM3_CH1
GPIO_PUPDR_PUPDR5_0 | // Pull-Up, PWM_OUT2, TIM3_CH2
GPIO_PUPDR_PUPDR0_0 | // Pull-Up, PWM_OUT3, TIM3_CH3
GPIO_PUPDR_PUPDR1_0 | // Pull-Up, PWM_OUT4, TIM3_CH4
GPIO_PUPDR_PUPDR6_0 | // Pull-Up, PWM_IN5, TIM4_CH1
GPIO_PUPDR_PUPDR7_0 // Pull-Up, PWM_IN6, TIM4_CH2
);


// Alternate Function pins
GPIOB->AFR[1] = 0; // clear AFR_H register
GPIOB->AFR[1] |=
(
(4 << ((8 - 8) << 2)) | // I2C1 SCL, AF4
(4 << ((9 - 8) << 2)) | // I2C1 SDA, AF4

(5 << ((12 - 8) << 2)) | // SPI2 NSS, AF5
(5 << ((13 - 8) << 2)) | // SPI2 SCK, AF5
(5 << ((14 - 8) << 2)) | // SPI2 MISO, AF5
(5 << ((15 - 8) << 2)) // SPI2 MOSI, AF5

);

GPIOB->AFR[0] = 0; // clear AFR_L register
GPIOB->AFR[0] |=
(
(2 << ((4 - 0) << 2)) | // PWM_OUT1, TIM3_CH1, AF2
(2 << ((5 - 0) << 2)) | // PWM_OUT2, TIM3_CH2, AF2
(2 << ((0 - 0) << 2)) | // PWM_OUT3, TIM3_CH3, AF2
(2 << ((1 - 0) << 2)) | // PWM_OUT4, TIM3_CH4, AF2
(2 << ((6 - 0) << 2)) | // TIM4_CH1, AF2
(2 << ((7 - 0) << 2)) // TIM4_CH2, AF2
);







//=============================================================================
// GPIOD configuration
//=============================================================================
// enable GPIOD clock
((RCC_TypeDef *)(RCC_BASE))->AHB1ENR |= RCC_AHB1ENR_GPIODEN;


// Alternate Function
((GPIO_TypeDef *)(GPIOD_BASE))->MODER |=
(GPIO_MODER_MODER9_1 | // Alternate Function, USART3_RX
GPIO_MODER_MODER8_1 ); // Alternate Function, USART3_TX

// Output type
((GPIO_TypeDef *)(GPIOD_BASE))->OTYPER |= 0;// push-pull if 0
//(GPIO_OTYPER_OT_8 | // Open-Drain, I2C1, SCL
//GPIO_OTYPER_OT_9); // OPen-Drain, I2C1, SDA



// Speed type
((GPIO_TypeDef *)(GPIOD))->OSPEEDR |=
(GPIO_OSPEEDER_OSPEEDR8_1 | // USART3 TX 50 MHz
GPIO_OSPEEDER_OSPEEDR9_1); // USART3 RX 50 MHz


// Push/Pull for USART3
((GPIO_TypeDef *)(GPIOD_BASE))->PUPDR |=
(
GPIO_PUPDR_PUPDR8_0 | // Pull-Up, USART3 TX
GPIO_PUPDR_PUPDR9_0 // Pull-Up, USART3 RX
);


((GPIO_TypeDef *)(GPIOD_BASE))->AFR[1] |= (
(7 << ((8 - 8) << 2)) | // USART3 TX, AF7
(7 << ((9 - 8) << 2)) ); // USART3 RX, AF7







return 0;
}


CODE

uint32_t config_pwm_io(void)
{
//=============================================================================
// set up PWM Output on TIM3 channels
//=============================================================================

// enable TIM3 clock
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;


// set the prescaler for 2MHz clock count
// fpclk = 42MHz, TIM3_clk = 2*fpclk = 84MHz
// CK_CNT = TIM3_clk / (PSC + 1)
// PSC = TIM3_clk / CK_CNT - 1
TIM3->PSC = 41; // 84MHz/2MHz - 1 = 41

// set the Auto Reload Register
// Needed period = (1/CK_CNT) * ARR
TIM3->ARR = 30000; // PWM_period = 15ms / (1/2MHz)

// clear CR2
TIM3->CR2 = 0;


TIM3->CCR1 = 3000; // 10% duty cycle, for CH1
TIM3->CCR2 = 3000; // 10% duty cycle, for CH2
TIM3->CCR3 = 3000; // 10% duty cycle, for CH3
TIM3->CCR4 = 3000; // 10% duty cycle, for CH4

// set output compare mode 1.
TIM3->CCMR1 |=
TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | // CH1
TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1; // CH2

TIM3->CCMR2 |=
TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | // CH3
TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1; // CH4


// enable Output compare
TIM3->CCER |= TIM_CCER_CC1E; //CH1
TIM3->CCER |= TIM_CCER_CC2E; //CH2
TIM3->CCER |= TIM_CCER_CC3E; //CH3
TIM3->CCER |= TIM_CCER_CC4E; //CH4

// enable TIM3
TIM3->CR1 |= TIM_CR1_CEN;


return 0;
}


CODE

uint32_t config_spi_all(void)
{

//=============================================================================
// SPI1 Related configuration
//=============================================================================
// enable SPI2 clock
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;


// configure SPI2
SPI2 -> CR1 |= (SPI_CR1_SPE | SPI_CR1_CPOL |
SPI_CR1_CPHA | SPI_CR1_MSTR |
SPI_CR1_BR_1 | SPI_CR1_SSM | SPI_CR1_SSI);


//SPI2->CR2 |= (SPI_CR2_SSOE);



return 0;
}



CODE

uint32_t config_i2c_all(void)
{

//=============================================================================
// I2C1 Related configuration
//=============================================================================
// enable I2C1 clock
((RCC_TypeDef *) (RCC_BASE))->APB1ENR |= RCC_APB1ENR_I2C1EN;





// 1) configure I2C_CR2
I2C1 -> CR2 |= (I2C_CR2_FREQ_5 | I2C_CR2_FREQ_3 |
I2C_CR2_FREQ_1); // APB1 clock is 42MHz

// 2) Configure Clock Control Register, I2C_CCR
// For 100KHz, APB1clk=42MHz, T_high = T_low = (1/42MHz)*210 = 5us
// For Fast mode, T_high = 9*(1/42MHz)*CCR = 0.8us,
// T_low = 16*(1/42MHz)*CCR = 1.5us,
// CCR = 4, F/S = 1, DUTY = 1, I2C_CCR = 0xc004
I2C1 -> CCR = 0xc004; // 0xd2, d210 for 100KHz,

// 3) Configure I2C_TRISE, Rise Time register
I2C1 -> TRISE = 0x2b; // 0x2b, d42 (42 + 1)

// 4) enable I2C1 peripheral
I2C1 -> CR1 |= (I2C_CR1_PE);


return 0;
}




CODE

uint32_t config_usart3(void)
{

//=============================================================================
// USART3 Related configuration
//=============================================================================
// enable I2C1 clock
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;


// 1) Setting UE, amd M bits
USART3-> CR1 |= 0x2000; // UE = 1

// 2) Programming number of stop bits if needed


// 3) Enable DMA if needed


// 4) set the Baud Rate
// BAUD = fck / ( 8 * (2 - OVER8) * USARTDIV )
// fck = 42MHz,
// OVER8 = 0
// Choose BAUD = 115200
// then: USARTDIV = fck / ( 8 * (2 -OVER8) * BAUD = 22.75
// BRR = (22 << 4) | ( 0.75 * 16) = 364,
// or: BRR = fck / BAUD = 42MHz / 115200 = 364
USART3->BRR = 364;


// enable transmitter
USART3->CR1 |= USART_CR1_TE;

// enable receiver
USART3->CR1 |= USART_CR1_RE;

return 0;
}



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


p.s. задача поднятия пина SS после передачи байта тоже решена программным путем. Никакие эксперименты с битами SSOE SSI SSM ни следование мануалу не привело к тому чтобыstm32 сам поднимал пин SS вверх после успешной отправки байта. (как я уже написал...после отправки читаю прием а потом уже BSY и вручную поднимаю его сам)
(почти тоже самое что в теме приведенной Viko)

а так вобщем работает все.


--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 18:01
Рейтинг@Mail.ru


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