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

 
 
> 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 > »   
Start new topic
Ответов (1 - 56)
Genadi Zawidowsk...
сообщение Jul 18 2018, 14:44
Сообщение #2


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

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



Как ни странным может показаться, при передаче 8-bit
как проверкуосвобождения передатчика делю так:
Код
    while ((SPI1->SR & SPI_SR_RXP) == 0)    
    ;
    (void) * (volatile uint8_t *) & SPI1->RXDR;    /* clear SPI_SR_RXP in status register */


А вот так передача:
Код
    * (volatile uint8_t *) & (SPI1)->TXDR = v;    // prevent data packing feature

Естественно, первая передача без ожидания перед ней.

Как обычно, проект тут:
https://188.134.5.254/browser/hfreceiver/trunk/hardware.c - функция hardware_spi_master_setfreq и hardware_spi_connect

Сообщение отредактировал Genadi Zawidowski - Jul 18 2018, 14:52
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 18 2018, 15:46
Сообщение #3


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

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



Судя по осциллу SPI и его ноги ожили. Долбаный хал с его callback-ами.

Цитата(Genadi Zawidowski @ Jul 18 2018, 17:44) *
Как обычно, проект тут:
https://188.134.5.254/browser/hfreceiver/trunk/hardware.c - функция hardware_spi_master_setfreq и hardware_spi_connect


Угу, гляну, может там надо как-то ждать реального ухода байта в дисп, иначе он его не воспринимает.
Там сразу после отправки CS поднимается в 1. Если поднимется раньше реального ухода байта из всех этих очередей проца, то дисп его не воспримет ...


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


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

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



Разумеется, всегда надо (если иное не сказано). А процессор шустрый, модет и не выдать ничего. C/D тоже надо не ранее передачи перключать.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 18 2018, 16:32
Сообщение #5


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

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



С C/D и nCS всё в порядке:

CODE
void ILI9163writecommand(uint8_t c)
{
res_rs ( ); //low
res_cs ( ); //low
ili9162_sendByte ( c );
set_cs ( ); //hi
}

void ILI9163writedata(uint8_t c)
{
set_rs ( ); //hi
res_cs ( ); //low
ili9162_sendByte ( c );
set_cs ( ); //hi
}


Вопрос только в отправке байта ..


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


Участник
*

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



Если просто писать в TXDR данные пишуться в буфер, который настроить нужно (когда флаги будут выставляться и формат данных). А старт передачи так SPI1->CR1 |= SPI_CR1_CSTART; только начал тоже разбираться пока передал 4 байта, NSS красиво управляет сам с нужными задержками.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 20 2018, 14:23
Сообщение #7


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

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



Что-то я совсем запутался sad.gif
Некий прогресс есть, хоть и неполный.

1. Переписал инициализацию на регистрах:
Код
    CLEAR_BIT( SPI_PORT->CR1, SPI_CR1_SPE);            // Disable SPI
    SPI_PORT -> CR1 = SPI_CR1_SSI;        // SSI := 1
    SPI_PORT -> CR2 = 0x0;
    SPI_PORT -> CFG1 = SPI_CFG1_MBR | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0;    // MBR = 7 - clock/256; DSIZE = 0111 - 8 bit/frame
    SPI_PORT -> CFG2 = SPI_CFG2_AFCNTR | SPI_CFG2_SSM | SPI_CFG2_CPOL | SPI_CFG2_CPHA | SPI_CFG2_MASTER;

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

работает, проблем пока вроде не заметил, если так можно выразиться в свете нижеследующих пунктов....
от хала оставил только вот это
hnucleo_Spi.Instance = SPI_PORT;
hnucleo_Spi.State = HAL_SPI_STATE_READY;
потому что без него отправка байтов халовской функцией подыхает на взлёте.

Инит пинов SPI оставил пока на хале, дабы резать колбасу по кусочкам:
Код
    // SPI pins
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


2. Дисплей пока отключил, убрал в сторонку, не дорос я до него biggrin.gif . Замкнул MISO-MOSI проводком, т.е. просто эхо.
Пытаюсь передать байт:
хал:
Код
// Чтение/запись байта SPI
uint8_t ili9162_sendByte ( uint8_t data_out )
{
    uint8_t data_in;

    HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(&hnucleo_Spi, &data_out, &data_in, 1, 1000);
    return data_in;

Байт по кольцу гоняет, т.е. возвращает то, что я и отправляю. Типа нормально.

закомментариваю хал, пишу на регистрах:
Код
// Чтение/запись байта SPI
uint8_t ili9162_sendByte ( uint8_t data_out )
{
    uint8_t data_in;

    MODIFY_REG(SPI_PORT->CR2, SPI_CR2_TSIZE, 1);

    // Передача
    while ( !( SPI_PORT -> SR & SPI_SR_TXP ) );
    *((__IO uint8_t *)&SPI1->TXDR) = data_out;

    SET_BIT ( SPI_PORT->CR1, SPI_CR1_CSTART );

    // Приём
    while ((SPI1->SR & (SPI_SR_RXWNE | SPI_SR_RXPLVL)) == 0);
    data_in = *((__IO uint8_t *)&SPI_PORT->RXDR);

    return data_in;


2 байта передаёт-принимает нормально, на третьем виснет на условии приёма.
Единственное отличие здесь от хала это то, что HAL_SPI_TransmitReceive постоянно включает/выключает SPI и MODIFY_REG(SPI1->CR2, SPI_CR2_TSIZE, Size); делает при выключенном SPI.
Неужели это необходимо?
Попробовал включать-выключать SPI - стало ещё хуже - один байт передал и завис ..

3. К слову о периферийных SPI-девайсах. Тут вообще всё плачевно.
Вышеупоминавшийся дисплей вообще не инитится, пробовал подключать датчик BME280 (SPI интерфейс) - вместо ID (который равен 60h) читает одни нули, хотя на всяких там F1/F4 как положено 60h и датчик работает с песнями.
Эта хрень даже с халовской HAL_SPI_TransmitReceive, которая эхо исправно делает.

Помогите разобраться плиз. Такое чувство, что я где-то на одни и те же грабли наступаю ...
Рабочий драйвер для BME280 (SPI) могу выложить если кому интересно. По I2C я его ни разу нигде не запускал, пока не нужно.

Код уважаемого Genadi Zawidowski смотрел, но, видимо, чего-то недопонял, т.к. тоже повис на приёме байта если правильно помню sad.gif .


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


Участник
*

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



Как разберусь сам помогу) делаю для NRF24. К коду которму месяц так и не возвращался, сегодня продолжу копания.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 20 2018, 17:22
Сообщение #9


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

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



Цитата(MasterElectric @ Jul 20 2018, 19:02) *
Как разберусь сам помогу) делаю для NRF24. К коду которму месяц так и не возвращался, сегодня продолжу копания.


Угу, спасибо. Я тоже буду отписываться, если что-то новое появится.


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


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

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Пару лет назад я делал проект на похожем процессоре для Боинга. Там с SPI была проблема. Он (не помню на прием или передачу) младший бит иногда портил. В этом форуме есть моя тема про это. В конце я сделал програмный SPI. Через несколько месяцев вышла errata с описанием этой проблемы.

https://electronix.ru/forum/index.php?showtopic=135946
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 21 2018, 07:57
Сообщение #11


Участник
*

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



hd44780 Вроде бы все получилось. Особое внимание нужно уделить системе тактирования. Пока что сделал на прерываниях, нужно еще исследовать как более оптимально работать с буфером. Проверялось без железок только на анализатор.

Код
/**
  * @brief  This function handles Debug Monitor exception.
  * @param  None
  * @retval None
  */
void SPI1_IRQHandler(void)
{
uint16_t tCTSIZE = (SPI_NRF->SPI->SR >> 16);

  if(SPI_NRF->SPI->SR & SPI_SR_RXP)
  {
   while(SPI_NRF->SPI->SR & SPI_SR_RXP)
   {
    if(SPI_NRF->RxBuffPos < SPI_NRF->TransLength)
    {
     SPI_NRF->RxBuff[SPI_NRF->RxBuffPos++] = *(volatile uint8_t *) &(SPI_NRF->SPI)->RXDR;
    } else break;
   }
  }

  if(SPI_NRF->SPI->SR & SPI_SR_TXP)
  {//
   while(SPI_NRF->SPI->SR & SPI_SR_TXP)
   {
    if(SPI_NRF->TxBuffPos < SPI_NRF->TransLength)
    {
     *(volatile uint8_t *) &(SPI_NRF->SPI)->TXDR = SPI_NRF->TxBuff[SPI_NRF->TxBuffPos++];
    } else break;
   }
  }
}


настройка
Код
  RCC->D2CCIP1R = RCC_D2CCIP1R_SPI123SEL_2; // kernel clock выбираем per_ck
  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOAEN;  // разрешили тактирование GPIO на котором висит SPI
  RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;  // включаем тактирование модуля

  // конфигурируем SPI1
  SPI_NRF->SPI->CFG1 = SPI_CFG1_MBR_0 | SPI_CFG1_MBR_2 | SPI_CFG1_FTHLV_0 | SPI_CFG1_FTHLV_1 | SPI_CFG1_DSIZE_0 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_2;
  SPI_NRF->SPI->CFG2 = SPI_CFG2_SSOE | SPI_CFG2_MASTER | SPI_CFG2_AFCNTR;


void TSPI::SendBuff(uint8_t *aTxBuff, uint8_t *aRxBuff, uint16_t aCnt)
{
  RxBuffPos = 0;
  TxBuffPos = 0;
  RxBuff = aRxBuff;
  TxBuff = aTxBuff;
  TransLength = aCnt;
  SPI->CR2 = aCnt;

  SPI->CR1 |= SPI_CR1_SPE;
  SPI->CR1 |= SPI_CR1_CSTART;
  SPI->IER |= SPI_IER_RXPIE | SPI_IER_TXPIE;
}


нужно еще углубиться в настройки...
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 21 2018, 09:11
Сообщение #12


Участник
*

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



поправочка :
Код
  SPI_NRF->SPI->CFG1 = SPI_CFG1_MBR_0 | SPI_CFG1_MBR_2 | SPI_CFG1_DSIZE_0 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_2;

для работы с буфером побайтно FTHVL нужно в 0 установить
P.S. редактировать сообщения не могу.


Текущая проблема не могу передать второй и последующие пакеты. Первый нормально.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 21 2018, 09:25
Сообщение #13


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

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



Цитата(MasterElectric @ Jul 21 2018, 12:11) *
Текущая проблема не могу передать второй и последующие пакеты. Первый нормально.


У меня тож самое пока crying.gif . Первый байт проходит в песнями, потом виснет на опросе флагов SR.


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


Участник
*

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



Заработало!!! Причем особо ничего не менял. Обращение к буферу пока что побайтно. Потом поэкспериментирую при разных фреймах. Работает от HSI (64 МГц)
инициализация:
Код
  //
  RCC->D2CCIP1R = RCC_D2CCIP1R_SPI123SEL_2; // kernel clock выбираем per_ck
  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOAEN;  // разрешили тактирование GPIO на котором висит SPI
  RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;  // включаем тактирование модуля

  // конфигурируем SPI1
  SPI_NRF->SPI->CFG1 = SPI_CFG1_MBR_0 | SPI_CFG1_MBR_2 | SPI_CFG1_DSIZE_0 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_2;
  SPI_NRF->SPI->CFG2 = SPI_CFG2_SSOE | SPI_CFG2_MASTER | SPI_CFG2_AFCNTR;
  SPI_NRF->SPI->CR1 |= SPI_CR1_SPE;

  NVIC_EnableIRQ(SPI1_IRQn);


отправка пакетов в мейне
Код
  a = 19;
  SPI_NRF->SendBuff(SPI1_TxBuff, SPI1_RxBuff, a);

  while(SPI_NRF->SPI->CR1 & SPI_CR1_CSTART);
  SPI_NRF->SendBuff(SPI1_TxBuff, SPI1_RxBuff, 20);

  while(SPI_NRF->SPI->CR1 & SPI_CR1_CSTART);
  SPI_NRF->SendBuff(SPI1_TxBuff, SPI1_RxBuff, 5);

  while(SPI_NRF->SPI->CR1 & SPI_CR1_CSTART);
  SPI_NRF->SendBuff(SPI1_TxBuff, SPI1_RxBuff, 7);

  /* Infinite loop */
  while(1);


функция отправки:
Код
void TSPI::SendBuff(uint8_t *aTxBuff, uint8_t *aRxBuff, uint16_t aCnt)
{
  RxBuffPos = 0;
  TxBuffPos = 0;
  RxBuff = aRxBuff;
  TxBuff = aTxBuff;
  TransLength = aCnt;
  SPI->CR2 = aCnt;

  SPI->CR1 |= SPI_CR1_CSTART;
  SPI->IER |= SPI_IER_RXPIE | SPI_IER_TXPIE | SPI_IER_EOTIE;
}


обработчик прерывания:
Код
void SPI1_IRQHandler(void)
{
uint16_t tCTSIZE = (SPI_NRF->SPI->SR >> 16);

  if((SPI_NRF->SPI->SR & SPI_SR_RXP) && (SPI_NRF->SPI->IER & SPI_IER_RXPIE))
  {
   while(SPI_NRF->SPI->SR & SPI_SR_RXP)
   {
    if(SPI_NRF->RxBuffPos < SPI_NRF->TransLength)
    {
     SPI_NRF->RxBuff[SPI_NRF->RxBuffPos++] = *(volatile uint8_t *) &(SPI_NRF->SPI)->RXDR;
    } else break;
   }
  }

  if((SPI_NRF->SPI->SR & SPI_SR_EOT) && (SPI_NRF->SPI->IER & SPI_IER_EOTIE))
  {// закончили передавать
   SPI_NRF->SPI->IER &= ~(SPI_IER_RXPIE | SPI_IER_TXPIE);
   SPI_NRF->SPI->IFCR = SPI_IFCR_EOTC;
  }

  if((SPI_NRF->SPI->SR & SPI_SR_TXP) && (SPI_NRF->SPI->IER & SPI_IER_TXPIE))
  {//
   while(SPI_NRF->SPI->SR & SPI_SR_TXP)
   {
    if(SPI_NRF->TxBuffPos < SPI_NRF->TransLength)
    {
     *(volatile uint8_t *) &(SPI_NRF->SPI)->TXDR = SPI_NRF->TxBuff[SPI_NRF->TxBuffPos++];
    }
    else
    {// все отправили в буфер
     SPI_NRF->SPI->IER &= ~(SPI_IER_TXPIE);
     break;
    }

   }
  }
}



Сообщение отредактировал MasterElectric - Jul 21 2018, 11:00
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Jul 21 2018, 10:50
Сообщение #15


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Че-то вы тут поникли все. Надо свою поделку допаять и присоединиться к коллективным похоронам ковыряниям SPI на STM32H753 biggrin.gif



Это плата от графической части кое-какого пульта управления.
Решил под конец только для себя сделать один макет - но не на F4 уже а на F7, благо они pin-to-pin совместимы на этом корпусе rolleyes.gif
Завтра запаяю все остальное и экран поставлю, если лень не одолеет.

P.S. MasterElectric, пожалуйста, поменьше картинку сделайте...

Сообщение отредактировал Arlleex - Jul 21 2018, 10:57
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 21 2018, 12:08
Сообщение #16


Участник
*

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



В общем не получилось побороть SPI, когда количество кадров данных >1 в одном пакете. Ладно все-равно цель чтобы это все работало в связке с DMA. Буду разбираться и прикручивать теперь DMA.

Сообщение отредактировал MasterElectric - Jul 21 2018, 13:44
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 21 2018, 16:42
Сообщение #17


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

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



Я кое-как скрутил отправку одного байта ... SPI дисплей (без ноги MISO) вроде задышал.
На каких-то странных костылях...
Сейчас попробую BME280 прикрутить.. Там обмен двунаправленный.

PS. Первые впечатления - хрень полная и тихий ужас ....


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


Участник
*

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



Почему одного байта? Я пакеты нормально слал. Да не хрень, просто сложно по сравнению со старыми версиями периферии.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jul 21 2018, 17:47
Сообщение #19


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

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



Да нормально все работет... перепишите АККУРАТНО из моего проекта по смыслу обмен. И DMA и программный обмен...
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 21 2018, 17:49
Сообщение #20


Участник
*

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



О вы уже успели и ДМА изучить... это олично... намекните кде конкрентее рыть в вашем коде
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jul 21 2018, 17:58
Сообщение #21


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

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



Файл hardware.c
hardware_spi_master_initialize
hardware_spi_master_setfreq

hardware_spi_connect

hardware_spi_b8_p1, hardware_spi_b8_p2, hardware_spi_complete_b8
hardware_spi_master_send_frame
hardware_spi_master_read_frame (на H7 не тестировал)

hardware_spi_disconnect

Так же оттестирована 16-битная группа функций обмена (кроме чтения по DMA) - hardware_spi_connect_b16 и остальные.
А DMA в обе стороны с I2S и SAI оттестировано - файл hardwarecodecs.c

Подключение тактирования у источникам клока это не в этих функциях, но об этом уже тут говорили.
Код
    // RCC Domain 1 Kernel Clock Configuration Register
    // Set per_ck clock output
    RCC->D1CCIPR = (RCC->D1CCIPR & ~ (RCC_D1CCIPR_CKPERSEL)) |
        0 * RCC_D1CCIPR_CKPERSEL_0 |    // 00: hsi_ker_ck clock selected as per_ck clock (default after reset) - 64 MHz - used as PER_CK_FREQ
        0;

Код
    // RCC Domain 2 Kernel Clock Configuration Register
    RCC->D2CCIP1R = (RCC->D2CCIP1R & ~ (RCC_D2CCIP1R_SPI123SEL | RCC_D2CCIP1R_SPI45SEL)) |
        4 * RCC_D2CCIP1R_SPI123SEL_0 |        // per_ck
        3 * RCC_D2CCIP1R_SPI45SEL_0 |        // 011: hsi_ker_ck clock is selected as kernel clock
        0;

Проект делался в том числе для вот этой платы - https://electronix.ru/forum/index.php?act=a...t&id=113464.

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


Участник
*

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



Genadi Zawidowski Спасибо, буду изучать.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 22 2018, 06:11
Сообщение #23


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

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



Цитата(MasterElectric @ Jul 21 2018, 20:46) *
Почему одного байта? Я пакеты нормально слал. Да не хрень, просто сложно по сравнению со старыми версиями периферии.


Я просто постепенно делаю. Для простой инициализации дисплея и рисования точек и по одному достаточно. Попробую блоками картинки в дисплей кидать.
Ещё напоролся на какой-то странный баг: я работаю в Atollic TrueStudio, когда использовал код MasterElectric

Код
        while ( SPI_PORT->SR & SPI_SR_RXP != 0 )
        {
            if ( RxBuffPos < TransLength )
            {
                RxBuff[RxBuffPos++] = *(volatile uint8_t *) &(SPI_PORT->RXDR);
            } // if
            else
                break;
        } // while


В цикл вообще не заходило, естетвенно ничего не принимало, хотя под отладкой виден бит SR.RXP==1 и в RXDR правильное принятое значение. Соответственно всё последующее летит к такой-то матери.

Переписал так:
Код
        while ( 1 )
        {
                        uint32_t val;
            val = SPI_PORT->SR;
            val &= SPI_SR_RXP;

            if ( val != 0 )
            {
                if ( RxBuffPos < TransLength )
                {
                    r_value = RxBuff[RxBuffPos++] = *(volatile uint8_t *) &(SPI_PORT->RXDR);
                } // if
            } // if
            else
                break;

            if ( RxBuffPos == TransLength )
                break;
        } // while


Те же яйца, вид сбоку. Но работает. Никто не натыкался? Оптимизацию проверял, там None (-O0).


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


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

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



Цитата
( SPI_PORT->SR & SPI_SR_RXP != 0 )

Скобками обозначте нужную Вам последовательность операций. Вот так:
Код
((SPI_PORT->SR & SPI_SR_RXP) != 0)


Сообщение отредактировал Genadi Zawidowski - Jul 22 2018, 06:48
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 22 2018, 07:28
Сообщение #25


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

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



Genadi Zawidowski , да, чёт я тупанул, спасибо, помогло.


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


Участник
*

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



Ситуация с передачей через ДМА совсем отвратительная. Пробовал 2 варианта первый вариант: когда числом передаваймых байт управляет модуль ДМА т.е. кол-во записываеться в NDTR модуля ДМА, так и в SPI->CR2. В итоге когда число передаваемых байт больше буфера SPI (16 байт) - передает нормально первые 16 байт и все ждет чего-то при этом ДМА стрим вываливает флаг ошибки. И второй вариант когда число передаваемых байт управляет перефирийное устройство (бит PFCTRL в регистре CR ДМА стрим установлен), так передает например все 19 байт, при этом после 16 пошел мусор, и в конце вываливает ошибку передачи (FEIFx: Stream x FIFO error interrupt flag) + к этому в NDTR (0xFFFF - NDTR) переваливает за 1500. В эррате тишина по этому направлению, значит косячу я. У кого есть положительный опыт, поделитесь кодом.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jul 22 2018, 15:43
Сообщение #27


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

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



Цитата
поделитесь кодом

А чем мой не устраивает-то? SPI по DMA передает нормально...
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 22 2018, 16:24
Сообщение #28


Участник
*

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



Я смотрел Ваш код (частично взял оттуда), вроде бы все как обычно. Мой почти такой же. Если есть возможность попробуйте передать пакет > 16 байт.

Мой код:
Код
  //
  RCC->D2CCIP1R = RCC_D2CCIP1R_SPI123SEL_2; // kernel clock выбираем per_ck
  RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
  RCC->AHB2ENR |= RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN;
  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOAEN;  // разрешили тактирование GPIO на котором висит SPI
  RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;  // включаем тактирование модуля

  SPI_NRF = new TSPI();
  SPI_NRF->SPI = SPI1;

  // конфигурируем SPI1
  SPI_NRF->SPI->CFG1 = SPI_CFG1_MBR_0 | SPI_CFG1_MBR_2 | SPI_CFG1_DSIZE_0 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_2;
  SPI_NRF->SPI->CFG2 = SPI_CFG2_SSOE | SPI_CFG2_MASTER | SPI_CFG2_AFCNTR;
  SPI_NRF->SPI->CR1 |= SPI_CR1_SPE;

  // настраиваем ДМА на передачу SPI1
  DMAMUX1_Channel11->CCR = 38 * DMAMUX_CxCR_DMAREQ_ID_0;    // SPI1_TX
  DMA2_Stream3->PAR = (uint32_t)&SPI_NRF->SPI->TXDR;
  DMA2_Stream3->FCR &= ~ DMA_SxFCR_DMDIS;  // use direct mode
  DMA2_Stream3->CR = DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_PFCTRL;

  NVIC_EnableIRQ(SPI1_IRQn);

  // передаем
  a = 10;
  SPI_NRF->SendBuff_DMA(SPI1_TxBuff, SPI1_RxBuff, a);


функция передачи:
Код
void TSPI::SendBuff_DMA(uint8_t *aTxBuff, uint8_t *aRxBuff, uint16_t aCnt)
{
  DMA2_Stream3->CR &= ~(DMA_SxCR_EN);

  RxBuffPos = 0;
  TxBuffPos = 0;
  RxBuff = aRxBuff;
  TxBuff = aTxBuff;
  TransLength = aCnt;
  SPI->CR2 = aCnt;
  SPI->CFG1 |= SPI_CFG1_TXDMAEN;

  DMA2->LIFCR = DMA_LIFCR_CFEIF3 | DMA_LIFCR_CDMEIF3 | DMA_LIFCR_CTEIF3 | DMA_LIFCR_CHTIF3 | DMA_LIFCR_CTCIF3;
  DMA2_Stream3->M0AR = (uint32_t)aTxBuff;
  DMA2_Stream3->CR |= DMA_SxCR_EN;

  SPI->CR1 |= SPI_CR1_CSTART;
  SPI->IER |= SPI_IER_EOTIE | SPI_IER_RXPIE;
}


Genadi Zawidowski, с пакетом < 16 байт передает нормально, хоть у канала ДМА ошибка. Но если пакеты при работе с неким устройством меньше 16 байт, то смысла в ДМА нет вовсе. А вот если > 16 байт, как я и писал передает 16 и процесс прекращаеться, когда ДМА рулит SPI передает напимер все 19 но после 16 байта мусор, во всех случаях у ДМА ошибка.

Сообщение отредактировал MasterElectric - Jul 22 2018, 16:17
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jul 22 2018, 16:37
Сообщение #29


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

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



Цитата
Если есть возможность попробуйте передать пакет > 16 байт

Все-таки у меня передается блоками большими чем 16 байт. ПОд рукой сейчас H7 нету.
Go to the top of the page
 
+Quote Post
MasterElectric
сообщение Jul 23 2018, 07:01
Сообщение #30


Участник
*

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



Удалось побороть как всегда благодаря RM:
Код
When starting communication using DMA, to prevent DMA channel management raising
error events, these steps must be followed in order:
1. Enable DMA Rx buffer in the RXDMAEN bit in the SPI_CFG1 register, if DMA Rx is
used.
2.  Enable DMA requests for Tx and Rx in DMA registers, if the DMA is used.
3.  Enable DMA Tx buffer in the TXDMAEN bit in the SPI_CFG1 register, if DMA Tx is
used.
4.  Enable the SPI by setting the SPE bit.

Все нормально в двух режимах, когда DMA ведет SPI, и когда SPI ведет DMA, без ошибок и прочего, но... только 1 раз... второй пакет вообще не идет, совсем... нет запроса ДМА. Прием по прерыванию. Совсем не ожидал что столь незначительная разница в инициализации дала такой результат.
Go to the top of the page
 
+Quote Post
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
hd44780
сообщение Jul 26 2018, 04:28
Сообщение #46


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

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



Цитата(MasterElectric @ Jul 25 2018, 23:11) *
Да не заметил.

Я думаю под себя перепишите. Пример.

Спасибо. Попробую, отпишусь.

Цитата(MasterElectric @ Jul 25 2018, 23:11) *
P.S. Да первый модуль который я разбираю и столько граблей, то ли нужно глубже вникать, то ли сыроват еще.

Родственные сомнения..
Рано ещё этот проц в какие-то серъёзные вещи ставить имхо ... Так, чисто поизучать, поиграться.
F1/F4, помню, с полпинка заводилось всё. С SDRAM и LTDC на F439, помню, года 4 назад промучился, но во всём оказалась виновата хреновая разводка платы. Сделали другую - все мгновенно заработало как надо.
Тут на форуме даже тема моя есть про "неработающий" LTDC biggrin.gif

У меня есть свободная QSPI флэшка, думаю, следующими блоками на изучение будут QSPI и уарты rolleyes.gif
Ну и USB c сетевухой, раз уж они есть на NUCLEO. Не пропадать же добру biggrin.gif С сетью и lwIP на МК я вообще никогда не работал. Ну всякие там ESP8266 не в счёт конечно.


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


Участник
*

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



У меня план ковыряний примерно такой же, QSPI давно хотел попробовать. Доделаю ДМА и начну USART (вроде как в F7 1 в 1, так что не сложно), с ДМА пришла в голову мысль (раз уж каналы стали полностью идентичные) динамически раздавать каналы по запросу периферии, все-равно запуск от полной инициализации отличаеться не сильно по размеру, но страдаю с общими регистрами (RCC, и общие ДМА, особенно с ДМА, совсем не красиво). Пока в голову пришли одни таблицы, зависимостей не видать совсем.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 26 2018, 16:43
Сообщение #48


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

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



MasterElectric, удачи. Мои эксприменты, похоже, откладываются - см. вложение. При простом подключении всё прекрасно читает. Ошибка только после Erase.

Atollic True Studio тож ругается "flash error". Хз, чё с ней стряслось. Пытался +5в со своего БП подавать, другой программатор подключал - без разницы.
Прошивается и работает не знаю с какого раза.

2 недели всего проработала crying.gif

Если оно всё же будет работать, я тоже буду продолжать изучение всего вышесказанного.
Эскизы прикрепленных изображений
Прикрепленное изображение
 


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


Участник
*

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



Печалька, а где вы ее кстати покупали, в китае? у нас поискал еще нет в продаже. Может полетел встроенный стабилизатор (на 400 тоже не стабильно подключался поэтому сижу на HSI, но я настраивал по мануалу режим стабилизатора установил, память настроил, делители, PLL и то стремно пока что), иногда во время экспериментов неудачных, проц попав видимо в исключение не реагирует на отладчик, помогает только ресет подключить от программатора. Попробуйте загнать его в заводской бут.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 26 2018, 18:01
Сообщение #50


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

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



Цитата(MasterElectric @ Jul 26 2018, 20:35) *
Печалька, а где вы ее кстати покупали, в китае? у нас поискал еще нет в продаже. Может полетел встроенный стабилизатор (на 400 тоже не стабильно подключался поэтому сижу на HSI, но я настраивал по мануалу режим стабилизатора установил, память настроил, делители, PLL и то стремно пока что), иногда во время экспериментов неудачных, проц попав видимо в исключение не реагирует на отладчик, помогает только ресет подключить от программатора. Попробуйте загнать его в заводской бут.


Покупал не я, а знакомый. Говорил, вроде где-то в США... Кстати, мы с ним тоже подумали на хреновое питание +3.3в. Я ж подавал на неё 5 вольт, т.е. конечный 3в стабилизатор всё равно работал родной.
Стабилизатор завтра осциллом потыкаю, отпишусь.
Готовых внешних 3.3в у меня щас нету, спаять внешний стаб смогу только на выходных, т.к. у меня это хобби, в рабочее время я паять не шибко могу.

Атоллик после ругани на флэш всё-таки заходит в отладку, но ещё во время блужданий по стартовому коду попадает в DefaultHandler. Т.е. до активации PLL и HSE там дело не доходит.

Там действительно что-то странное. Добавил в ту же тестовую прошивку с SPI мигание светодиодиком, залил ST-Link utility - замигал нормально.


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


Участник
*

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



ну скорее всего ошибка в коде и он уходит в стоп режим. Я бы пока малоизучена система тактирования не разгонял бы его. Я имел в виду стабилизатор что в чипе, но раз признаки жизни подает значит живой.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Jul 27 2018, 13:33
Сообщение #52


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

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



Осциллом 3.3 платы посмотрел - чисто. Может иголки какие, хз, моим хилым UT-81B их фиг найдёшь.


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


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

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



Вот так нормально работает опросом:

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

    // старт передаем неопределенное кол-во байт
    // Disable SPI
    SPI_PORT->CR1 &= ~SPI_CR1_SPE;
    SPI_PORT->CR2 = 0;
    // Enable SPI
    SPI_PORT->CR1 |= SPI_CR1_SPE;
    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_RXP));
    data_in = *(volatile uint8_t *) &(SPI_PORT->RXDR);
    return data_in;
} // SPI_sendByte


Попробую ещё перенести это на другой SPI.


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


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

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



Датчик успешно переехал на SPI3 sm.gif .


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


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

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



Небольшой оффтоп в теме про SPI:

Покопался ещё на предмет флэша.
Пустышка вида

CODE
char sBuffer[256];

int main(void)
{
float temp = 656.89F;
int i = 78;

sprintf ( sBuffer, "%d; %.02fv", i, temp );
while ( 1 )
{
} // while
} // main


При использовании newlib standard даёт размер кода:

Код
Print size information
   text      data       bss       dec       hex   filename
  17644      1660     10772     30076      757c   STM32H7_ILI9163.elf


Ошибка записи во флэш есть.
Если эту же программу перекомпилить с newlib nano, то получаю:
Код
Print size information
   text      data       bss       dec       hex   filename
   5180       112     10720     16012      3e8c   STM32H7_ILI9163.elf


Ошибки флэша нет, всё гуд. Но в sBuffer я вижу: "78; v", т.е. видно, что sprintf не поддерживает плавающую точку, что меня лично меня категорически не устраивает.

Чтобы отсечь вопрос о "битости" некоторых участков флэша проца приведу следующий пример:
Прошивка размером

Код
Print size information
   text      data       bss       dec       hex   filename
  18480        36     10876     29392      72d0   STM32H7_ILI9163.elf



без sprintf шьётся, отлаживается и работает совершенно нормально.

Стек в обоих случаях одинаковый:

Код
/* 0x2800 == 10K */
_Min_Stack_Size = 0x2800;




Какие соображения, товарищи? И чем можно заменить sprintf? Я нашёл только это - https://github.com/torvalds/linux/blob/master/lib/vsprintf.c , но пока не пытался затащить её в проц.
Увеличение размера прошивки меня совершенно не волнует. Кто-то делал что-либо подобное?

Штуки типа itoa, ltoa я знаю, они нормально работают, но результирующие строки надо дополнительно склеивать, но самое главное, чего-то родственного для плавающей точки я не знаю.
Писать самому?

Что касается периферии - запустил UART - отправка опросом, приём прерыванием в буфер. Перешёл к USB.


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


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

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



Всё-таки это косяки в либах атоллика (я про sprintf).

Та же самая пустышка в STM32 SystemWorkbench завелась с полпинка.
Правда пришлось разобраться, как включить в нём поддержку float output в spintf. По умолчанию она отключена, %f полностью игнорится.


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


Местный
***

Группа: Участник
Сообщений: 244
Регистрация: 29-02-08
Пользователь №: 35 503



Цитата(hd44780 @ Aug 18 2018, 12:00) *
Всё-таки это косяки в либах атоллика (я про sprintf).

Та же самая пустышка в STM32 SystemWorkbench завелась с полпинка.
Правда пришлось разобраться, как включить в нём поддержку float output в spintf. По умолчанию она отключена, %f полностью игнорится.


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

Сообщение отредактировал nanorobot - Aug 18 2018, 11:04
Go to the top of the page
 
+Quote Post

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

 


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


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