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

 
 
> STM32H743 SPI, Не работает
hd44780
сообщение Jul 18 2018, 13:34
Сообщение #1


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

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Привет всем.
Попал тут в руки проц STM32H743 в виде платы NUCLEO-H743I.

Разобрался, как запустить его на все 400 МГц, Systick завёл, светодиодиками помигал - все это заработало. Частоту систика проверил осциллом.
Перешёл к SPI (маленький дисплейчик ILI9163). Сам дисп рабочий, работал на Ф103. Драйвер диспа собственно оттуда же.
Драйвер разделён на 2 части - низкоуровневая (работа с SPI и ногами) и т.н. высокоуровневая (пуляние в дисп команд, отрисовка точек, знакогенератор и пр).
Соответственно в адаптации нуждается только низкоуровневая часть, т.к. высокоуровневая напрямую в ноги и SPI не лезет.
С ногами nCS, nRESET и пр. ногодрыгом я управился, они работают нормально, а с SPI затык - синхра идёт исправно, а из ноги MOSI упорно прёт ноль. Нога MISO в данном случае не нужна вообще, т.к. у дисплея её нет.

Пишу на помеси из регистров и кубового хала. М.б. это и нехорошо, но с ходу писать на регистрах на проце, которого раньше в глаза не видел как-то нехорошо.

Инит пинов:

CODE
// Configure PA5 - SPI1 SCK
GPIO_InitStruct.Pin = GPIO_PIN_5; // SCK
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
// GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/*
// Configure PA7 - SPI1 MOSI
// Configure PB5 - SPI1 MOSI
// Configure PD7 - SPI1 MOSI
GPIO_InitStruct.Pin = GPIO_PIN_7; // MOSI
// GPIO_InitStruct.Pin = GPIO_PIN_5; // MOSI
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
// GPIO_InitStruct.Pull = GPIO_PULLUP;
// GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
// HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
*/
// PA7 - SPI1 MOSI
// MODER - AF = 10
GPIOA->MODER |= GPIO_MODER_MODER5_1; // 10
// TYPER - PP = 0 - Push-pull
GPIOA->OTYPER |= GPIO_OTYPER_IDR_7; // 0
// SPEEDR - OSPEEDRy = 11
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR7; // 11
// PUPD_R = 10 - Pull-down
GPIOA->PUPDR |= GPIO_PUPDR_PUPDR7_1; // 10


Нога PA5 (SCK) работает как угодно - хоть халом её инитить, хоть чем. PA7 (MOSI) - не работает никак. Инитил по-разному.

Инит SPI (в основном хал):
CODE
/*** Configure the SPI peripheral ***/
SPI_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI123;
SPI_PeriphClkInit.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
HAL_RCCEx_PeriphCLKConfig(&SPI_PeriphClkInit);

/* Enable SPI clock */
// __HAL_RCC_SPI1_CLK_ENABLE();
// SET_BIT (RCC->APB2ENR, RCC_APB2ENR_SPI1EN);
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;

// SPI Config
hnucleo_Spi.Instance = SPI_PORT;
// hnucleo_Spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hnucleo_Spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
hnucleo_Spi.Init.Direction = SPI_DIRECTION_2LINES;
// hnucleo_Spi.Init.Direction = SPI_DIRECTION_2LINES_TXONLY;
hnucleo_Spi.Init.CLKPhase = SPI_PHASE_2EDGE;
hnucleo_Spi.Init.CLKPolarity = SPI_POLARITY_HIGH;
hnucleo_Spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hnucleo_Spi.Init.CRCPolynomial = 7;
hnucleo_Spi.Init.DataSize = SPI_DATASIZE_8BIT;
hnucleo_Spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
hnucleo_Spi.Init.NSS = SPI_NSS_SOFT;
hnucleo_Spi.Init.TIMode = SPI_TIMODE_DISABLE;
hnucleo_Spi.Init.Mode = SPI_MODE_MASTER;
hnucleo_Spi.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; /* Recommended setting to avoid glitches */

hnucleo_Spi.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
hnucleo_Spi.Init.CRCLength = SPI_CRC_LENGTH_8BIT;
hnucleo_Spi.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hnucleo_Spi.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hnucleo_Spi.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
hnucleo_Spi.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
hnucleo_Spi.Init.MasterSSIdleness = 0x00000000;
hnucleo_Spi.Init.MasterInterDataIdleness = 0x00000000;
hnucleo_Spi.Init.MasterReceiverAutoSusp = 0x00000000;

HAL_SPI_Init(&hnucleo_Spi);

// Enable SPI peripheral
SET_BIT( SPI_PORT->CR1 , SPI_CR1_SPE);

SPI_PORT === SPI1.

Отправка байта в SPI1 (хал):
CODE
// Чтение/запись байта SPI
void ili9162_sendByte ( uint8_t data )
{
/*
// Длина передаваемых байт - 1
MODIFY_REG (SPI1->CR2, SPI_CR2_TSIZE, 1);
// Старт передачи
SET_BIT(SPI1->CR1, SPI_CR1_CSTART);

while ( !( SPI1 -> SR & SPI_SR_TXP ) );
SPI1 ->TXDR = data;

// Ждать завершения передачи
// while ( ! ( SPI1 -> SR & SPI_SR_TXC ) );
*/
uint8_t data_in;
HAL_StatusTypeDef status = HAL_OK;
status = HAL_SPI_TransmitReceive(&hnucleo_Spi, &data_in, &data, 1, 1000);
} // SPI_sendByte


Моя поделка на регистрах не пашет вообще, я пока бросил, оставил хал.
Проверяю всё это вызовом в вечном цикле ili9162_sendByte ( 0xAA );

В чём может быть дело? Если надо, выложу весь проект на 9 атоллике.

Спасибо.


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
4 страниц V  < 1 2 3 4 >  
Start new topic
Ответов (30 - 44)
Genadi Zawidowsk...
сообщение Jul 23 2018, 07:13
Сообщение #31


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

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



Снять SPE бит в конце пробовали?

Сообщение отредактировал Genadi Zawidowski - Jul 23 2018, 07:18
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 23 2018, 07:28
Сообщение #32


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 19-07-18
Пользователь №: 106 151



Да, в обработчике прерывания EOT, отключаю.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jul 23 2018, 07:38
Сообщение #33


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

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



Тогда не знаю...
В моем варианте connect/send_frame/disconnect много раз повторяются... есть устройство работающее. У Вас нормальный процессор, не ES32Hxxx ?
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 23 2018, 08:06
Сообщение #34


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 19-07-18
Пользователь №: 106 151



Да вроде нормальный.
https://drive.google.com/open?id=1Jibo-gxol...5AZZYmEYEfauK-Q

Пытаюсь выполнить рекомендованную последовательность:
Код
To close communication it is mandatory to follow these steps in order:
1. Disable DMA request for Tx and Rx in the DMA registers, if the DMA issued.
2.  Disable the SPI by following the SPI disable procedure.
3.  Disable DMA Tx and Rx buffers by clearing the TXDMAEN and RXDMAEN bits in the
SPI_CFG1 register, if DMA Tx and/or DMA Rx are used.


Не совсем понятен первый пункт, ДМА стрим я отключаю, но как отключить запросы ДМА по Tx в регистрах ДМА я не понял.
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 23 2018, 11:19
Сообщение #35


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 19-07-18
Пользователь №: 106 151



После отключения SPI (SPE), в регистре статуса появляеться черти что, мол данные не все ушли, RxFIFO не пуст. Я плюнул играться и после передачи пакета просто сбрасываю модуль, кстати в эррате есть подобная фигня на счет ДМА, но немного не такая. Теперь работает нормально. Благо инициализация SPI 2 регистра записать. С другой стороны не так уж и печально задача заняла ресурс попользовала и отключила.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 23 2018, 11:56
Сообщение #36


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

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



MasterElectric , у Вас приём через прерывание нормально работает?

У меня странно как-то - эхо (через проводок MOSI - MISO) нормально идёт, а пытаюсь работать с датчиком BME280 - он на команды не реагирует, читаются одни нули.
Дисплей (вообще без ноги MISO) тож нормально работает.

Дисп отключил, датчик к тем же ногам подключен.


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 23 2018, 18:15
Сообщение #37


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 19-07-18
Пользователь №: 106 151



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

Сообщение отредактировал MasterElectric - Jul 23 2018, 18:34
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 24 2018, 05:11
Сообщение #38


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

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Цитата(MasterElectric @ Jul 23 2018, 21:15) *
может полярность или фаза не так настроена. пока просто пробую на анализатор нужно еще rx пдп попробовать.не работала с упакованными данными, особо не печалит


Лог анализатора у меня нету, только осцилл. Смотрел я им ногу MISO датчика - там действительно тишина.
Полярность и фаза у дисплея и у датчика идентичные. Вот мои настройки SPI дисплея и датчика с F103 проца, где всё работает:

Дисплей:
Код
    SPI_Cmd ( SPI1, DISABLE );
    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_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
//    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init ( SPI1, &SPI_InitStructure );

    SPI_Cmd ( SPI1, ENABLE );
    SPI_CalculateCRC ( SPI1, DISABLE );


Датчик:
Код
    SPI_Cmd ( SPI2, DISABLE );
    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_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
//    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init ( SPI2, &SPI_InitStructure );

    SPI_Cmd ( SPI2, ENABLE );
    SPI_CalculateCRC ( SPI1, DISABLE );


как видно, они идентичные. Попробую ещё настройки пинов сопоставить. У H7 порты, похоже, такие же как и у F4. Этот датчик у меня и на F439 успешно работает, есть с чем сравнивать.


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 24 2018, 16:40
Сообщение #39


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

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Датчик заработал, всё гуд. Осталось его только на другой SPI перенести. DMA не делал, пока не нужно, тем более, что ещё надо с UART, таймерами и пр. разобраться.
Что касается SPI, остался один простой вопрос - как отправить-принять байт SPI простым опросом? Т.е. то что на F1/F4 делается буквально 4-мя строками кода:

Код
// Чтение/запись байта SPI
uint8_t bme280_sendbyte ( uint8_t data )
{
    uint8_t _rxbyte;

    while ( !( SPI2 -> SR & SPI_SR_TXE ) );
    SPI2 -> DR = data;

    while ( !( SPI2 -> SR & SPI_SR_RXNE ) );
    _rxbyte = SPI2 -> DR;

    return _rxbyte;
} // SPI_sendbyte


Здесь же, если написать
Код
// Чтение/запись байта SPI
uint8_t spi1_sendByte ( uint8_t data_out )
{
    uint8_t data_in = 0;

    // Disable SPI
       SET_BIT( SPI_PORT->CR1, SPI_CR1_SPE);
       MODIFY_REG(SPI_PORT->CR2, SPI_CR2_TSIZE, 1);
    // Enable SPI
    SET_BIT( SPI_PORT->CR1, SPI_CR1_SPE);

    SPI_PORT->CR2 = 1;        // Передать 1 байт

    // Start transfer
    SPI_PORT->CR1 |= SPI_CR1_CSTART;

    while ( !( SPI_PORT -> SR & SPI_SR_TXP ) );
    *((__IO uint8_t *)&SPI_PORT->TXDR) = data_out;

    // Ждать завершения передачи
//    while ( !(SPI_PORT->SR & SPI_SR_EOT) );

    // Ждать завершения приёма
    while ( !( SPI_PORT -> SR & SPI_SR_RXP ) );
    data_in = *((__IO uint8_t *)&SPI_PORT->RXDR);

    return data_in;
} // SPI_sendByte


Оно тупо виснет на первом цикле ожидания единицы в SPI_SR_TXP sad.gif До всего остального просто не доходит.
Как это сделать правильно? Повторяю - без прерываний.

С прерываниями всё хорошо sm.gif .


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 24 2018, 17:51
Сообщение #40


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 19-07-18
Пользователь №: 106 151



тут наверное ошибочка
Код
    // Disable SPI
       SET_BIT( SPI_PORT->CR1, SPI_CR1_SPE);


ну по логике так же как и на прерываниях только постоянным опросом флагов, скорее всего прийдеться опрашивать несколько флагов в вечном цикле, выход из вечного цикла после EOT.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jul 24 2018, 21:33
Сообщение #41


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

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



Цитата
Оно тупо виснет на первом цикле ожидания единицы в SPI_SR_TXP

У меня первая выдача данных для передачи идет без проверки (функции с окончанием имени на _p1) - потом перед остальными ожидаем. И конес отидельно (complete) - после чего можно переключать C/D или снимать CS.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 25 2018, 07:08
Сообщение #42


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

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Да, со SPE опечатка вышла при вставке кода в форум. Сорри ...
Вот полный текст:

Код
// Чтение/запись байта SPI
uint8_t spi1_sendByte ( uint8_t data_out )
{
    uint8_t data_in = 0;

    // Disable SPI
    CLEAR_BIT( SPI_PORT->CR1, SPI_CR1_SPE);
    MODIFY_REG(SPI_PORT->CR2, SPI_CR2_TSIZE, 1);
    // Enable SPI
    SET_BIT( SPI_PORT->CR1, SPI_CR1_SPE);

    SPI_PORT->CR2 = 1;        // Передать 1 байт
    // Start transfer
    SPI_PORT->CR1 |= SPI_CR1_CSTART;

    while ( !( SPI_PORT -> SR & SPI_SR_TXP ) );
    *((__IO uint8_t *)&SPI_PORT->TXDR) = data_out;

    // Ждать завершения передачи
//    while ( !(SPI_PORT->SR & SPI_SR_EOT) );

    // Ждать завершения приёма
    while ( !( SPI_PORT -> SR & SPI_SR_RXP ) );
    data_in = *((__IO uint8_t *)&SPI_PORT->RXDR);

    return data_in;
} // SPI_sendByte


На TXP ни разу не висит, теперь виснет на EOT (если его раскомментарить), либо (если прикрыть EOT) на следующем за ним RXP.

Genadi Zawidowski, да, я помню, вы выше писали об этом, но на TXP у меня вобщем-то никогда не висло, а когда и висло, то по факту это оказывалось следствием моих же ошибок/экспериментов.
Поэтому пока я проверяю всегда этот флаг.


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 25 2018, 14:33
Сообщение #43


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 19-07-18
Пользователь №: 106 151



Вы же не указываете кол-во передаваемых байт?
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 25 2018, 16:26
Сообщение #44


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

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Цитата(MasterElectric @ Jul 25 2018, 17:33) *
Вы же не указываете кол-во передаваемых байт?


Задал вроде:

SPI_PORT->CR2 = 1; // Передать 1 байт

После Enable SPI.


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 25 2018, 20:11
Сообщение #45


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 19-07-18
Пользователь №: 106 151



Да не заметил.

Я думаю под себя перепишите. Пример.
Код
  NRF24_SPI->Connect();
  NRF24_SPI->SendByte(0x55);
  NRF24_SPI->SendByte(0xaa);
  NRF24_SPI->Disconnect();


функции библиотеки:
Код
void TSPI::Connect(void)
{
  // конфигурируем SPI1
  this->SPI->CFG1 = SPI_CFG1_MBR_0 | SPI_CFG1_MBR_2 | SPI_CFG1_DSIZE_0 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_2;
  this->SPI->CFG2 = SPI_CFG2_SSOE | SPI_CFG2_MASTER | SPI_CFG2_AFCNTR;
  // старт передаем неопределенное кол-во байт
  this->SPI->CR2 = 0;
  this->SPI->CR1 |= SPI_CR1_SPE;
  this->SPI->CR1 |= SPI_CR1_CSTART;
}

void TSPI::Disconnect(void)
{
  this->SPI->CR1 |= SPI_CR1_CSUSP;
  this->SPI->CR1 &= ~SPI_CR1_SPE;
  // еще можно сбросить сам модуль
  // ...
}

uint8_t TSPI::SendByte(uint8_t data_out)
{
uint8_t data_in = 0;

  while (!(this->SPI->SR & SPI_SR_TXP));
  *((__IO uint8_t *)&this->SPI->TXDR) = data_out;

  // Ждать завершения приёма
  while(!(this->SPI->SR & SPI_SR_RXP));
  data_in = *(volatile uint8_t *) &(this->SPI)->RXDR;

  return data_in;
}


P.S. Да первый модуль который я разбираю и столько граблей, то ли нужно глубже вникать, то ли сыроват еще.
Go to the top of the page
 
+Quote Post

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

 


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


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