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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> STM32F4Discovery SPI, сигнал CS, что-то пошло не так
ilkz
сообщение Sep 9 2015, 10:49
Сообщение #1


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

Группа: Участник
Сообщений: 135
Регистрация: 9-09-11
Пользователь №: 67 084



Друзья, не могу понять в чем дело.
Завожу SPI в режиме мастера, сигналом CS управляю как отдельным пином.
Ожидаю поведения, когда он (CS) нулем подчеркивает все данные, но он почему-то этого не делает (см картинку).
Самое интересное, что если в начало тела while(1) дописать что-то типа printf("spi send %X\n", 0xC1);, то CS начинает формироваться правильно.

Код привожу ниже.

CODE
void spi2_init(void){
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2); // sck
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2); // mosi
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2); // miso

GPIO.GPIO_Mode = GPIO_Mode_AF;
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO.GPIO_OType = GPIO_OType_PP;
GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOB, &GPIO);

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI2, &SPI_InitStructure);
//SPI_I2S_ITConfig(SPI2,SPI_I2S_IT_RXNE,ENABLE);
SPI_Cmd(SPI2, ENABLE);
SPI_NSSInternalSoftwareConfig(SPI2, SPI_NSSInternalSoft_Set);

GPIO.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
GPIO.GPIO_Mode = GPIO_Mode_OUT;
GPIO.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init (GPIOB, &GPIO);
}

void spi2_send(uint8_t value) {
SPI_I2S_SendData(SPI2, value);
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
}

void ad_send(uint8_t value) {
GPIO_ResetBits(GPIOB, GPIO_Pin_12);
spi2_send(value);
GPIO_SetBits(GPIOB, GPIO_Pin_12);
}

int main(void) {
SystemInit();
TM_DELAY_Init();
TM_DISCO_LedInit();
spi2_init();
while (1) {
//printf("spi send %X\n", 0xC1);
ad_send(0xC1);
Delayms(1);
}
}


Прикрепленное изображение





UPD:
Опытным путем выяснилось, что если вставить задержку между SPI_I2S_SendData() и ожиданием флага SPI_I2S_FLAG_BSY, то все начинает работать:

Код
void spi2_send(uint8_t value) {
    int i;
    SPI_I2S_SendData(SPI2, value);
    for(i=0; i<63; i++);
    while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
}


Получается что нельзя проверяь флаг SPI_I2S_FLAG_BSY сразу после отправки? Он что, не успевает встать?

Сообщение отредактировал IgorKossak - Sep 9 2015, 19:36
Причина редактирования: [codeebox] для длинного кода, [code] - для короткого!
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Sep 9 2015, 11:23
Сообщение #2


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

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Какой-то странный флаг у ST-шников получился, да.

Они это и сами признают:
Цитата(Reference manual)
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


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
ilkz
сообщение Sep 9 2015, 11:28
Сообщение #3


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

Группа: Участник
Сообщений: 135
Регистрация: 9-09-11
Пользователь №: 67 084



Цитата(esaulenka @ Sep 9 2015, 14:23) *
Какой-то странный флаг у ST-шников получился, да.

Они это и сами признают:


Ок, допустим. Но рекомендуемый ими флаг TXE имеет не совсем то поведение что нужно: он единичится, когда данные попадают в сдвиговый регистр, а не когда они из него улетели на улицу. Т.е. для управления собственным сигналом CS испоьзование флага TXE не подходит.

Как вы выходите из положения?
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Sep 9 2015, 11:37
Сообщение #4


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

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Вопрос крайне интересен :-)
Мне всегда был нужен двунаправленный SPI, в этом случае отлично работает метод "положили в DR, подождали RXNE, считали DR".


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
ilkz
сообщение Sep 9 2015, 11:43
Сообщение #5


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

Группа: Участник
Сообщений: 135
Регистрация: 9-09-11
Пользователь №: 67 084



:-)
С приемом да - все понятно.
Вопрос с только передачей.
Переадресую его к аудитории: как вы управляете сигналом CS, если SPI работает только на отправку?
Go to the top of the page
 
+Quote Post
Obam
сообщение Sep 9 2015, 11:53
Сообщение #6


Знающий
****

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



"…как вы управляете сигналом CS, если SPI работает только на отправку?…"

Вот именно так и управляем sm.gif
RXNE==1 равнозначен полностью завершённой транзакции.


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Sep 9 2015, 11:57
Сообщение #7


Гуру
******

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



Можно поилить TXE и BSY, или действительно что проще по RXNE,
Go to the top of the page
 
+Quote Post
ilkz
сообщение Sep 9 2015, 12:06
Сообщение #8


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

Группа: Участник
Сообщений: 135
Регистрация: 9-09-11
Пользователь №: 67 084



Ну ок, логика вида:

Код
void spi2_send(uint8_t value) {
    SPI_I2S_SendData(SPI2, value);
    while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
}


не работает - все равно нужна задержка между send() и while().
Go to the top of the page
 
+Quote Post
Obam
сообщение Sep 9 2015, 12:24
Сообщение #9


Знающий
****

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



Удалено. Согласен с rudy_b

Сообщение отредактировал Obam - Sep 9 2015, 12:32


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
rudy_b
сообщение Sep 9 2015, 12:25
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 888
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458



Это стандартная проблема для всей криворукой периферии Stm32, особенно раздражает в RTC. Хардовый автомат тактируется не клоками проца, а деленными клоками периферии. Соответственно, busy устанавливается с задержкой по клоку периферии. А догадаться асинхронно установить busy по загрузке данных DR сразу у них ума не хватило.

Рекомендованные действия:
1. Wait until TXE=1
2. Then wait until BSY=0

Вероятно можно использовать и RXNE, но не проверял его работу при настройке только на передачу.
Go to the top of the page
 
+Quote Post
ilkz
сообщение Sep 9 2015, 12:53
Сообщение #11


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

Группа: Участник
Сообщений: 135
Регистрация: 9-09-11
Пользователь №: 67 084



rudy_b, проверяем:

Код
void spi2_send(uint8_t value) {
    SPI_I2S_SendData(SPI2, value);
    while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == 1);
    while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == 0);
}


Прикрепленное изображение


Как видим, сдвинулось на 1 клок laughing.gif
Go to the top of the page
 
+Quote Post
rudy_b
сообщение Sep 9 2015, 13:05
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 888
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458



Рекомендация - из их даташита (stm32F207).

Ну, какой-то прогресс есть. Можно попробовать еще (до анализа busy) подождать RXNE.

P.S. А можно попробовать сначала дождаться busy=1, а, потом, busy=0. Но аккуратно, это чревато осложнениями при наличии прерываний.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Sep 9 2015, 13:08
Сообщение #13


Гуру
******

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



Ну может тогда еще проще
Код
void spi2_send(uint8_t value) {
    SPI_I2S_SendData(SPI2, value);
    while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == 1);
    while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == 0);
}
Go to the top of the page
 
+Quote Post
Obam
сообщение Sep 9 2015, 13:37
Сообщение #14


Знающий
****

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



SPI в 8 раз медленней ядра (пост #1); на какой частоте ядро "молотит" что флаги не успевают (с т.з. ядра) высталяться\сниматься?

Сообщение отредактировал Obam - Sep 9 2015, 13:40


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
ilkz
сообщение Sep 9 2015, 13:47
Сообщение #15


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

Группа: Участник
Сообщений: 135
Регистрация: 9-09-11
Пользователь №: 67 084



Вроде как 168МГц.
Go to the top of the page
 
+Quote Post
Obam
сообщение Sep 9 2015, 13:56
Сообщение #16


Знающий
****

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



Запустите ядро ядро мегагерцах на 30-ти. Что будет?


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
rudy_b
сообщение Sep 9 2015, 13:58
Сообщение #17


Знающий
****

Группа: Свой
Сообщений: 888
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458



Делитель (1/8) работает с клоками APB1. А есть еще делитель самих клоков APB1 относительно клоков проца (APB1_Prescaler), его тоже нужно знать.

А макисмальная частота APB1 - 30 Мгц, т.е. делитель - не менее 1/8. В результате общее деление, скорее всего, равно 1/64. Но это данные для Stm32F207, для F4 частота APB1 может и отличаться.
Go to the top of the page
 
+Quote Post
Obam
сообщение Sep 9 2015, 14:09
Сообщение #18


Знающий
****

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



Если уж исследовать, то не грех подтянуть частоту SPI к частоте ядра. Положим, ядро "затормозим", APB1_Prescaler=1 и fPCLK=4; вход\выход из подпрограмм занимает (нормально занимает) что-то, вот и будет видно как флаги в SPI успевают\не успевают к опросу. Надеюсь TS под JTAGом отлаживается?

Сообщение отредактировал Obam - Sep 9 2015, 14:11


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 10 2015, 02:56
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ilkz @ Sep 9 2015, 17:28) *
Как вы выходите из положения?

Мы в такое положение не попадаем, так как всегда работаем с SPI через DMA или хотя-бы посредством прерываний. wink.gif
Чего и Вам советуем.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 10 2015, 04:43
Сообщение #20


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(ilkz @ Sep 9 2015, 15:49) *
Друзья, не могу понять в чем дело.

На эту тему уже было большое обсуждение.
Вкратце вывод таков: надо ждать RXNE, и потом ещё несколько тактов, в зависимости от скорости и режима SPI.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ilkz
сообщение Sep 10 2015, 07:58
Сообщение #21


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

Группа: Участник
Сообщений: 135
Регистрация: 9-09-11
Пользователь №: 67 084



Ладно, с этм разберусь когда железяку запущу хоть как-то. Идея в целом понятна. По результатам дам знать. Спасибо за разжевывание )))

Пока что возник следующий проблем:
Что-то записываю в слейв, потом пытаюсь прочитать и... не вижу клока для чтения.
Код
void mcp_read(uint8_t addr) {
    GPIO_ResetBits(GPIOB, GPIO_Pin_11);
    spi2_send(0x41);
    spi2_send(addr);
    SPI_I2S_ReceiveData(SPI2);
    GPIO_SetBits(GPIOB, GPIO_Pin_11);
}

...

mcp_write(0x05, 0x20); // IOCON
mcp_write(0x00, 0x00); // IODIR
mcp_write(0x01, 0xA5); // IPOL
mcp_read(0x01); // IPOL


Я вижу что слейв что-то пытается выдать на свой SDO, но т.к. нет клока, то слейв обламывается и мой мастер ничего не принимает... Что за очередной бред? (Мы щас пока не трогаем всякие прерывания и прочие DMA).
Соответственно, никакие прерывания не дергаются.

Сообщение отредактировал ilkz - Sep 10 2015, 08:03
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Sep 10 2015, 08:57
Сообщение #22


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

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Потому что StdLib - ад и ужас.

Клок на шине выставляет мастер. Чтобы он это сделал, ему надо сказать "передавай". Этот StdLib так не делает, хотя, если судить только по названиям функций, должен.
Т.е. берём и делаем ОДНУ функцию
Код
    uint8_t Rw(uint8_t out = 0xFF)
    {
        SPIx->DR = out;
        while (!(SPIx->SR & SPI_SR_RXNE));
        return SPIx->DR;
    }

(украдено из Stm32tpl авторства AHTOXA)
и вызываем (сиплюсплюс):

Код
mcp.Active ();
mcp.Rw (0x41);
mcp.Rw (addr);
uint8_t res = mcp.Rw ();
mcp.Deactive ();
return res;


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
ilkz
сообщение Sep 11 2015, 06:30
Сообщение #23


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

Группа: Участник
Сообщений: 135
Регистрация: 9-09-11
Пользователь №: 67 084



Цитата(esaulenka @ Sep 10 2015, 11:57) *
Потому что StdLib - ад и ужас.

Клок на шине выставляет мастер. Чтобы он это сделал, ему надо сказать "передавай". Этот StdLib так не делает, хотя, если судить только по названиям функций, должен.
Т.е. берём и делаем ОДНУ функцию


Т.е., чтобы что-то прочитать - надо что-то записать. Люююто. А как быть, если нужно прочитать много байт, а слейв не допускает dummy-записей? Ну, то есть, во время записи dummy-слов слейв может на них как-то отреагировать, т.к. для него это будут команды какие-нибудь.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Sep 11 2015, 06:40
Сообщение #24


Гуру
******

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



Ну тут надо немного подумать.
Как слейв узнает пишите вы или нетsm.gif? Клоки то чтобы данные забрать все равно идутsm.gif)))) Это же не РС232 где есть факт начала записи. Смотрите описание, там написано в каком состоянии нога должна быть
в 1 шлите FF, в 0 шлите 00, скорее всего там будет в состоянии пофиг....
Go to the top of the page
 
+Quote Post
Obam
сообщение Sep 11 2015, 07:04
Сообщение #25


Знающий
****

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



"А как быть, если нужно прочитать много байт, а слейв не допускает dummy-записей?"

Тогда это не SPI: SCK тактируют одновременно и MOSI и MISO.


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
ilkz
сообщение Sep 11 2015, 07:41
Сообщение #26


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

Группа: Участник
Сообщений: 135
Регистрация: 9-09-11
Пользователь №: 67 084



Ну в принципе да, в командах всегда есть флаг R/W.
Go to the top of the page
 
+Quote Post
Obam
сообщение Sep 11 2015, 08:10
Сообщение #27


Знающий
****

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



ilkz, попробуете замедлить ядро чтобы SPI успевал обновлять флаги к опросу?

Сообщение отредактировал Obam - Sep 11 2015, 08:12


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 11 2015, 08:30
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(AHTOXA @ Sep 10 2015, 10:43) *
Вкратце вывод таков: надо ждать RXNE, и потом ещё несколько тактов, в зависимости от скорости и режима SPI.

Жесть какая.... wacko.gif
Вот ответ на вопрос, почему я в своих проектах стараюсь не использовать STM32....
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Sep 11 2015, 09:02
Сообщение #29


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

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



Напоминаю, что дождавшись RXNE надо обязательно прочитать DR, нужен он Вам или нет... И дуло исчезнет... И жести не будет.

Сообщение отредактировал Genadi Zawidowski - Sep 11 2015, 09:20
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 11 2015, 09:25
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Genadi Zawidowski @ Sep 11 2015, 15:02) *
Напоминаю, что дождавшись RXNE надо обязательно прочитать DR, нужен он Вам или нет... И дуло исчезнет... И жести не будет.

Думаете всё-таки рискнуть и применить в следующей (как раз намечающейся) разработке STM32? rolleyes.gif
Go to the top of the page
 
+Quote Post
ilkz
сообщение Sep 11 2015, 10:06
Сообщение #31


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

Группа: Участник
Сообщений: 135
Регистрация: 9-09-11
Пользователь №: 67 084



Цитата(Obam @ Sep 11 2015, 11:10) *
ilkz, попробуете замедлить ядро чтобы SPI успевал обновлять флаги к опросу?

Да, только позже. Я напишу.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Sep 11 2015, 10:11
Сообщение #32


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

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



Сейчас применяются STM32F4 и STM32F7 уже... В намечающихся, если не хватит производительности, будет RENESAS RZ1AL (напримкр http://www.eltech.spb.ru/item/r7s721020vcfpaa0).
С SPI проблем нет (если читать документацию на чип полнтсьью, а не по диагонали, как я иногда это делал)...

Сообщение отредактировал Genadi Zawidowski - Sep 11 2015, 19:31
Go to the top of the page
 
+Quote Post
ilkz
сообщение Sep 11 2015, 11:58
Сообщение #33


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

Группа: Участник
Сообщений: 135
Регистрация: 9-09-11
Пользователь №: 67 084



Цитата(Genadi Zawidowski @ Sep 11 2015, 13:11) *
Сейчас применяются STM32F4 и STM32F7 уже...


Так я про STM32F4 и вел речь.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Sep 11 2015, 19:32
Сообщение #34


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

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



Цитата
Думаете всё-таки рискнуть и применить в следующей

Вы спросили про будущие проекты на STM32F4 - у меня текущие, на которые требуется/хватает ресурсов этого семейства процессоров, уже делаются на них.

Сообщение отредактировал Genadi Zawidowski - Sep 11 2015, 19:33
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 28th June 2025 - 19:54
Рейтинг@Mail.ru


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