Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SPI1 в STM32F429 считывает 0 в младший бит
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
Tarbal
Если не давать сброс на периферийное устройство (slave), подключенное к SPI, то у него на выходе MISO стоит твердая единица. Однако если считывать в процессор, то вместо 0xFF читается 0xFE.

Происходит ошибочное чтение нестабильно. Иногда читается правильно. Однако если к выходу SPI CLK присоединить щуп осциллографа, то правильного чтения больше не происходит. Стабильно читается 0xFE.

Я нашел в форуме ST, что такое происходит если читать данные не дожидаясь установки RXNE в единицу. Однако в моем коде я жду установки RXNE в единицу.
RadiatoR
Попробуйте прочитать по флагу BSY. Вообще есть ли у вас возможность посмотреть оба канала - MISO относительно клока?
SasaVitebsk
А какая настройка?
ViKo
Смотря, каким фронтом записываете и читаете. Надо внимательно изучить все варианты.
scifi
Цитата(RadiatoR @ Jun 16 2016, 08:11) *
Попробуйте прочитать по флагу BSY.

+1.
В своё время отлаживал SPI, приходилось плясать вокруг разных битов статуса. До конца не стал вникать, как оно по феншую должно быть. Получил вариант, который работает, и оставил его:
Код
SPI1_DR = 0x05;
while ((SPI1_SR & (1 << 1)) == 0) { /* wait for TXE */ }
while ((SPI1_SR & (1 << 0)) == 0) { /* wait for RXNE */ }
while ((SPI1_SR & (1 << 7)) != 0) { /* wait for !BUSY */ }
CS_DEASSERT();
return SPI1_DR;
RadiatoR
Вообще сам флаг BSY для приема использовать не правильно. Для этого и нужен RXNE. Я отлаживая SPI на LIS3DS6 при вылавливании косяков тоже его использовал, думая что он сейчас все решит. Проблема оказалась в другом.
Цитата(ЯadiatoR @ May 28 2016, 11:44) *
После записи в регистре DR оставалось 2 байта. и при следующем чтении CS устанавливался и сразу сбрасывался

И считывалось хрен знает что. Может тут тоже CS ножка на этот бит улетает и MISO в HiZ попадает? Отсюда и периодические срабатывания...
Tarbal
Цитата(RadiatoR @ Jun 16 2016, 09:11) *
Попробуйте прочитать по флагу BSY. Вообще есть ли у вас возможность посмотреть оба канала - MISO относительно клока?


Оба канала в смысле MOSI MISO? Нет как раз спалил логический анализатор. Только двухлучевой осциллограф.

Но у меня на MISO жестко стоит единица -- нет надобности. Должен всефда читать 0xFF.

Цитата(ViKo @ Jun 16 2016, 10:06) *
Смотря, каким фронтом записываете и читаете. Надо внимательно изучить все варианты.


Там всего четыре варианта. Я выбрал то, что надо периферийному устройству:
инвертированный CLK и по читать фронту. Но в моем тесте нет вариантов получить сдвиг или гонки на меняющемся в момент выборки входе даже если неправильная фаза выборки -- у меня всегда единица на входе.
RadiatoR
Цитата(Tarbal @ Jun 16 2016, 15:37) *
Оба канала в смысле MOSI MISO? Нет как раз спалил логический анализатор. Только двухлучевой осциллограф.

Я когда боролся с акселерометром нашел проблему просмотрев одновременно сигналы CS, MISO, CLK.
Если есть возможность посмотрите их. У меня тоже читалось одно, а на ноге была единица - как я понял она подтягивалась осциллографом, я это по ссылке выше описывал.
adnega
Цитата(Tarbal @ Jun 16 2016, 15:37) *
Но у меня на MISO жестко стоит единица -- нет надобности. Должен всефда читать 0xFF.

Видел такое, вроде, на SPI4 на PE2-PE6.
Tarbal
Цитата(adnega @ Jun 16 2016, 23:38) *
Видел такое, вроде, на SPI4 на PE2-PE6.


На форуме поддержки мне написали, что известная проблема, но ST не шевелится:

This is a recurrent problem, with around a dozen threads on this forum, which was never completely investigated down to the root - but I am afraid it can't be without active involvement of ST.

It might be related to the sequencing of the very first SCK clock after enabling the peripheral, i.e. whether the SCK line was in active or inactive state from the point of view of CPOL just before enabling the peripheral or so. I've seen issues of a similar nature although not quite the same, when changing CPOL/CPHA on-the-go without stopping/restarting the peripheral (it's lots of fun to find out what's going on, I can recommend it as a weekend project ;-) ). Also, one friend of mine discovered, that the SPI receiver is driven from the pin directly rather than from an internal signal (i.e. when no pin was not set as SPI-SCK AF, the receiver did not work at all).

I can't quite explain how could it be more specific to SPI1 - either through different parasitics, or different source clock (different APB)?

https://my.st.com/public/STe2ecommunities/m...urrentviews=260
adnega
Цитата(Tarbal @ Jun 17 2016, 14:59) *
На форуме поддержки мне написали, что известная проблема, но ST не шевелится:

Хоть бы в эррате упомянули.
ViKo
Что-то мне подсказывает, что если прочитать руководство, то окажется, что-нибудь из примечаний пользователи не выполняют.
У меня в STM32F207 переключаются режимы работы, так сначала запрещаю, изменяю, потом разрешаю. И все работает. Не думаю, что в STM32F429 сделали неработающий SPI. Не верю!
На упомянутом выше форуме поддержки сидят Кубодрочеры, похоже.

Код
void AnaDAC_send(uint16_t data)
{
  ANAS->CR1 &= ~SPI_CR1_SPE;        // запретить SPI
  ANAS->CR1 |= SPI_CR1_CPOL;        // данные стабильные на срезе \_
  ANAS->CR1 |= SPI_CR1_SPE;            // разрешить SPI

  ANSYN_ON();                        // \__
  ANAS->DR = (uint8_t)(data >> 8);    // послать биты 15 - 8
  while (!(ANAS->SR & SPI_SR_TXE));    // ждать освобождение буфера
  ANAS->DR = (uint8_t)(data);        // послать биты 7 - 0
  while (!(ANAS->SR & SPI_SR_TXE));    // ждать освобождение буфера
  // while (!(ANAS->SR & SPI_SR_RXNE)); // ждать конец передачи - нельзя!
  while (ANAS->SR & SPI_SR_BSY);    // ждать освобождение приемопередатчика
  ANSYN_OFF();                        //            __/

  ANAS->CR1 &= ~SPI_CR1_SPE;        // запретить SPI
  ANAS->CR1 &= ~SPI_CR1_CPOL;        // данные стабильные на фронте _/
  ANAS->CR1 |= SPI_CR1_SPE;            // разрешить SPI
}
Tarbal
Цитата(ViKo @ Jun 17 2016, 17:16) *
Не думаю, что в STM32F429 сделали неработающий SPI. Не верю!


Да я тоже не верю, но уж упростил задачу до минимума. Инициализирую SPI, удерживаю периферию в сбросе (что значит на вход MISO подаю единицу).
Читаю инигда 0xFE иногда 0xFF. Подключаю осциллограф к клоку и всегда читаю 0xFE.
Каким таким чудесным образом клок влияет на достоверность чтения? В форуме объяснили этот эффект тем, что клок с ножки используется для работы приемника SPI.

Но попробую добавить while (ANAS->SR & SPI_SR_BSY);

Вы привели код для передачи. У меня с этим проблем нет. Вот прием читает нестабильно.
Alex11
А у Вас что, на клоке вход и нет ни сигнала ни подтяжки? Почему подключение осциллографа влияет хоть на что-то?
Tarbal
Цитата(Alex11 @ Jun 17 2016, 20:02) *
А у Вас что, на клоке вход и нет ни сигнала ни подтяжки? Почему подключение осциллографа влияет хоть на что-то?


На клоке есть сигнал клок. Представьте мастер SPI у которого MISO жестко к единице подключен. Это мой тест. Если читаем, то только 0хFF, но никак не 0xFE.
ViKo
Цитата(Tarbal @ Jun 16 2016, 15:37) *
у меня всегда единица на входе.

Повесьте резистор вместо вашего устройства. Вряд ли будет читаться 0xFE.
adnega
Цитата(ViKo @ Jun 17 2016, 21:52) *
Повесьте резистор вместо вашего устройства. Вряд ли будет читаться 0xFE.

Дык, вам же говорят, что висит резистор. Ноль ом.
ViKo
Цитата(adnega @ Jun 17 2016, 21:56) *
Дык, вам же говорят, что висит резистор. Ноль ом.

И де вы такое прочитали? rolleyes.gif
На ноль омов резисторов не бывает. laughing.gif
adnega
Цитата(ViKo @ Jun 17 2016, 23:12) *
И де вы такое прочитали? rolleyes.gif
На ноль омов резисторов не бывает. laughing.gif

На выводе MISO лог 1, которая получается подключением к шине 3.3В.
В регистре данных SPI принимаем 0xFE, т.е. младший бит равен нулю. Откуда?
ViKo
Цитата(adnega @ Jun 18 2016, 01:46) *
На выводе MISO лог 1, которая получается подключением к шине 3.3В.

"Подключением" чего? Резистора 0 Ом? Где... вы такое прочитали?
adnega
Цитата(ViKo @ Jun 18 2016, 09:32) *
"Подключением" чего? Резистора 0 Ом? Где... вы такое прочитали?

На пине микроконтроллера с AF SPI_MISO логическая единица, а приемник стабильно принимает байт с нулем в младшем разряде.
Чего еще не понятно? Нигде этого не читал, сам с этим столкнулся и долго бодался. Было на каком-то SPI, на каком-то пине,
(подробностей не помню, т.к. 2 года прошло) перешел на другие пины и другой номер SPI - чудеса пропали.
ViKo
Цитата(adnega @ Jun 18 2016, 11:40) *
На пине микроконтроллера с AF SPI_MISO логическая единица, а приемник стабильно принимает байт с нулем в младшем разряде.
Чего еще не понятно? Нигде этого не читал, сам с этим столкнулся и долго бодался. Было на каком-то SPI, на каком-то пине,
(подробностей не помню, т.к. 2 года прошло) перешел на другие пины и другой номер SPI - чудеса пропали.

Непонятно того, что из-за неправильного использования SPI (предполагаю, связано с периферийными тактами микроконтроллера), вы вдруг решили мне высказать несказанное, что на этом входе висит резистор. "Где имение, а где вода?" С железным подвешенным резистором можно быстрее докопаться до сути проблемы, чем с неким устройством, висящим в сбросе (может, и не выдающем единицу, а находящимся в высокоимпедансном состоянии).
Желаете дальше дискутировать насчет резистора 0 ом?

Цитата
Prior to changing the CPOL/CPHA bits the SPI must be disabled by resetting the SPE bit.

Цитата
It is recommended to enable the SPI slave before the master sends the clock. If not,
undesired data transmission might occur. The data register of the slave needs to be ready
before the first edge of the communication clock or before the end of the ongoing
communication. It is mandatory to have the polarity of the communication clock set to the
steady state value before the slave and the master are enabled.

Цитата
During discontinuous communications, there is a 2 APB clock period delay between the
write operation to SPI_DR and the BSY bit setting. As a consequence, in transmit-only
mode, it is mandatory to wait first until TXE is set and then until BSY is cleared after writing
the last data.
adnega
Цитата(ViKo @ Jun 18 2016, 13:45) *
С железным подвешенным резистором можно быстрее докопаться до сути проблемы, чем с неким устройством, висящим в сбросе (может, и не выдающем единицу, а находящимся в высокоимпедансном состоянии).

С чего вы вообще взяли некое устройство? В #7 и #15 сообщениях сказано "на MISO жестко стоит единица".
ViKo
Цитата(adnega @ Jun 18 2016, 14:24) *
С чего вы вообще взяли некое устройство? В #7 и #15 сообщениях сказано "на MISO жестко стоит единица".

С первого же сообщения (slave устройство...) и до последнего от топикстартера.
Поскольку есть устройство, то гарантии, что оно выдает мощную единицу всегда - нет. Топикстартер мог даже и не разглядеть кратковременного провала в цепи, в зависимости от качества осциллографа и квалификации "наблюдателя".
adnega
Цитата(ViKo @ Jun 18 2016, 16:01) *
С первого же сообщения...

Дык, это была всего-лишь иллюстрация странного поведения. Затем русским-по-белому говорилось о жесткой единице.
Подтверждаю, что сам сталкивался на stm32f429i-disco с аналогичной ситуацией.
Сначала получал от слейва левый "нолик", затем довел ситуацию до предела - подключил MISO к 3.3В, а считывалось 0xFE.
Перешел на другой порт и другие пины - и слейв прекрасно заработал. В эррате не нашел сей глюк, для себя отметил, может,
экземпляр МК с дефектом. Похоже, что нет.
ViKo
То, что читалось 0xFE, связано с работой не по мануалу. Чтобы убедиться, я и предложил повесить резистор. Во всяком случае, подключенный "щуп" осциллографа уж точно не должен был влиять на разное чтение, если там висит единица всегда.

Цитата(adnega @ Jun 18 2016, 16:24) *
Перешел на другой порт и другие пины - и слейв прекрасно заработал. В эррате не нашел сей глюк, для себя отметил, может,
экземпляр МК с дефектом. Похоже, что нет.

Вы просто не докопались до сути проблемы, вот на что это похоже.
adnega
Цитата(ViKo @ Jun 18 2016, 17:07) *
Вы просто не докопались до сути проблемы, вот на что это похоже.

Я особо и не копал. Посмотрел эррату, Интернет - все тихо. Значит проблема у меня.
Решил ее по-другому - без копания и костылей. Сейчас оказывается, что не только у меня.
Посмотрим на решение. Была бы у вас stm32f429i-disco, могли бы сами проверить и предложить решение.
Genadi Zawidowski
Код отсылки/приёма байта по SPI в студию...
adnega
Цитата(Genadi Zawidowski @ Jun 18 2016, 23:04) *
Код отсылки/приёма байта по SPI в студию...

Давно то было. Допускаю, что примерно так было
CODE
//---------------------------------------------------------------------------
// LED & BUTTON
//---------------------------------------------------------------------------
SPI_NSS_bit = 1;
for(i = 0; i < 3; i++) __NOP();
SPI_OE_bit = 0;
SPI_NSS_bit = 0;

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

DMA1_Stream4->CR =
(0 << DMA_SCR_PL)
| (0 << DMA_SCR_CHSEL)
| (1 << DMA_SCR_MINC)
| (1 << DMA_SCR_DIR)
| (0 << DMA_SCR_EN);

DMA1_Stream3->CR =
(0 << DMA_SCR_PL)
| (0 << DMA_SCR_CHSEL)
| (1 << DMA_SCR_MINC)
| (0 << DMA_SCR_DIR)
| (0 << DMA_SCR_EN);

DMA1->LIFCR = (0x3D << 22);
DMA1->HIFCR = (0x3D << 0);

for(i = 0; i < 10; i++) __NOP();

DMA1_Stream3->PAR = (DWORD)&SPI2->DR;
DMA1_Stream3->M0AR = (DWORD)spi_rx;
DMA1_Stream3->NDTR = SPI_SIZE;
DMA1_Stream3->CR =
(0 << DMA_SCR_PL)
| (0 << DMA_SCR_CHSEL)
| (1 << DMA_SCR_MINC)
| (0 << DMA_SCR_DIR)
| (1 << DMA_SCR_EN);

DMA1_Stream4->PAR = (DWORD)&SPI2->DR;
DMA1_Stream4->M0AR = (DWORD)spi_tx;
DMA1_Stream4->NDTR = SPI_SIZE;
DMA1_Stream4->CR =
(0 << DMA_SCR_PL)
| (0 << DMA_SCR_CHSEL)
| (1 << DMA_SCR_MINC)
| (1 << DMA_SCR_DIR)
| (1 << DMA_SCR_EN);

for(i = 0; i < 10; i++) __NOP();

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

Это рабочий код, т.к. использует SPI2 и DMA1.
Нерабочий был, вроде, на SPI4 и DMA2.
Отправка работала корректно, а прием 2 байт давал нулевой младший бит (вроде только в первом принимаемом байте, а не в каждом).
ViKo
Цитата(adnega @ Jun 18 2016, 22:25) *
Посмотрим на решение. Была бы у вас stm32f429i-disco, могли бы сами проверить и предложить решение.

У меня есть STM32F429I-Disco. Если выложите код, похожий на нерабочий, могу посмотреть. Но с нуля писать лень. Вдруг не не заработает. rolleyes.gif
Tarbal
Вроде нашел в чем дело.
Я поначалу не знал, что хардвер чип селект не доделан и его нужно только вручную ставить. Ну и выбрал хардвер, где-то нашел, что для его снятия надо вызывать DISABLE_SPI(). Вроде обмен происходит, а поскольку проблема не возникла сразу, а SPI это мизерная часть моего проекта, то я не стал вникать в детали тогда.

Что происходит. При каждой транзакции разрешается интерфейс и одновременно сигнал клока идет в единицу (клок инвертирован), чип селект в ноль. Если на клоке есть емкость, то он немного запаздывает и видимо воспринимается как первый фронт клока.

Будет время переделаю на софтвер чипселект и расскажу.

Цитата(ViKo @ Jun 18 2016, 00:12) *
И де вы такое прочитали? rolleyes.gif
На ноль омов резисторов не бывает. laughing.gif


Бывают.

Цитата(ViKo @ Jun 18 2016, 17:01) *
С первого же сообщения (slave устройство...) и до последнего от топикстартера.
Поскольку есть устройство, то гарантии, что оно выдает мощную единицу всегда - нет. Топикстартер мог даже и не разглядеть кратковременного провала в цепи, в зависимости от качества осциллографа и квалификации "наблюдателя".


Ну осциллографом я пользоваться умею и никакого другого значения кроме единицы там не видел.
ViKo
Цитата(Tarbal @ Jun 19 2016, 19:42) *
Бывают.

Пе-ре-мыч-ки.
Цитата
Ну осциллографом я пользоваться умею и никакого другого значения кроме единицы там не видел.

Назовите модель осциллографа, полосу частот, частоту дискретизации.
adnega
Цитата(ViKo @ Jun 19 2016, 18:28) *
У меня есть STM32F429I-Disco. Если выложите код, похожий на нерабочий, могу посмотреть. Но с нуля писать лень. Вдруг не не заработает. rolleyes.gif

Короче, пытаюсь воспроизвести ошибку - не получается.
Перепробовал SPI1, SPI4, SPI5.
Точные номер SPI и номера пинов не помню.
Хотел же тогда на электроникс запостить, но поленился описывать глюк.
Итого: ошибку воспроизвести не могу; если кто сообщит номер SPI и номера пинов (и каналов DMA опционально), то могу попробовать на макете.
Tarbal
Цитата(ViKo @ Jun 19 2016, 22:13) *
Пе-ре-мыч-ки.

Назовите модель осциллографа, полосу частот, частоту дискретизации.


Я умею найти проблемы и в железе и в софте. Не будем меня экзаменовать на этот предмет.
adnega
Цитата(adnega @ Jun 19 2016, 21:21) *
ошибку воспроизвести не могу

Короче, проверил все с SPI1 по SPI5. Ошибка, увы, не воспроизводится.

Читаю-пишу так
Код
BYTE spi_send_byte(const BYTE data)
{
    BYTE spib;
    while((SPI3->SR & (1 << SPI_SR_TXE)) == 0);
    SPI3->DR = data;
    while((SPI3->SR & (1 << SPI_SR_RXNE)) == 0);
    spib = SPI3->DR;
    return spib;
}


Цитата(ViKo @ Jun 19 2016, 21:13) *
Пе-ре-мыч-ки.

Вопрос определений. Под "резистором 0 Ом" можно понимать: перемычку, резистор, кусок провода, печатную дорожку и т.п.
Я покупаю такие; в счете написано "резисторы".
ViKo
Цитата(adnega @ Jun 19 2016, 22:16) *
Вопрос определений. Под "резистором 0 Ом" можно понимать: перемычку, резистор, кусок провода, печатную дорожку и т.п.
Я покупаю такие; в счете написано "резисторы".

Да, вопрос терминологии. Grammar nazi... Нажмите для просмотра прикрепленного файла

Пролистал каталог Yageo (верхний из списка http://www.yageo.com/NewPortal/_en/download/download-3.jsp)
http://www.yageo.com/exep/pages/download/l..._2016_Final.pdf, и не нашел 0Ω. Где?
Tarbal
Цитата(ViKo @ Jun 19 2016, 22:13) *
Пе-ре-мыч-ки.


Вы можете называть как вам угодно, но их принято называть резисторами.
https://www.tu-eshop.com/index.php?route=in...s&news_id=8

http://www.hkresistors.com/-products-zero-ohm-resistor.html
ViKo
Ага, нашел, jumper. Он еще и точность имеет, и мощность рассеивания. biggrin.gif

Цитата(Tarbal @ Jun 19 2016, 23:58) *
Вы можете называть как вам угодно, но их принято называть резисторами.

Я буду называть перемычками, как принято.
Tarbal
Цитата(ViKo @ Jun 20 2016, 01:14) *
Ага, нашел, jumper. Он еще и точность имеет, и мощность рассеивания. biggrin.gif


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


sm.gif


Цитата(ViKo @ Jun 19 2016, 19:28) *
У меня есть STM32F429I-Disco. Если выложите код, похожий на нерабочий, могу посмотреть. Но с нуля писать лень. Вдруг не не заработает. rolleyes.gif


Вот такой код. Только теперь вместо нуля всегда читает единицу и только в первом интерфейсе.

CODE

HAL_StatusTypeDef SPI_WaitOnFlagTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
{
uint32_t start = jiffies;
while(__HAL_SPI_GET_FLAG(hspi, Flag) == Status){
if(jiffies - start >= Timeout){
return -HAL_TIMEOUT;
}
}
return HAL_OK;
}
#if 0
/* This funtion is used to transmit and receive data
* with SPI1
* data --> data to be transmitted
* returns received value
*/
uint8_t SPI1_send(uint8_t data){

SPI1->DR = data; // write data to be transmitted to the SPI data register
while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete
while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete
while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore
return SPI1->DR; // return received data from SPI data register
}
#endif

int SPI_Transmit1(SPI_HandleTypeDef *hspi, uint8_t* val, uint32_t timeout)
{
FlagStatus Status;
__HAL_SPI_ENABLE(hspi);
hspi->Instance->DR = *val;
Status = SPI_WaitOnFlagTimeout(hspi, SPI_FLAG_TXE, RESET, timeout);
if(HAL_OK != Status){
return Status;
}
Status = SPI_WaitOnFlagTimeout(hspi, SPI_FLAG_RXNE, RESET, timeout);
if(HAL_OK != Status){
return Status;
}
Status = SPI_WaitOnFlagTimeout(hspi, SPI_FLAG_BSY, SET, timeout);
*val = hspi->Instance->DR;
return Status;
}

int write_spi_reg(uint8_t chip_id, uint8_t reg_addr, uint8_t val)
{
SPI_HandleTypeDef* hspi;
uint8_t buf[SPI_WRITE_LEN];
uint8_t i;
uint8_t id;
GPIO_TypeDef* port;
uint16_t pin;

HAL_StatusTypeDef ret;


if(CHIPS_AMOUNT <= chip_id){
return -WRONG_PARAMETER;
}

hspi = hspi1;
id = 0
port = GPIOA;
pin = GPIO_PIN_4;


buf[0] = WR_SPI_CMD(id);
buf[1] = reg_addr;
buf[2] = val;

for(i = 0; i < SPI_WRITE_LEN; i++){
HAL_GPIO_WritePin(port, pin, 0);
short_delay(7);
ret = SPI_Transmit1(hspi, &buf[i], SPI_TIMEOUT);
HAL_GPIO_WritePin(port, pin, 1);
short_delay(7);

if(HAL_OK != ret){
responce_handle(ret);
return -ret;
}
}
return NO_ERROR;
}

int read_spi_reg(uint8_t chip_id, uint8_t reg_addr)
{
SPI_HandleTypeDef* hspi;
uint8_t buf[2];
uint8_t id;
HAL_StatusTypeDef ret;
GPIO_TypeDef* port;
uint16_t pin;
chip_interface_t* chip_if;



if(CHIPS_AMOUNT <= chip_id){
return;
}
hspi = hspi1;
id = 0
port = GPIOA;
pin = GPIO_PIN_4;

buf[0] = RD_SPI_CMD(id);
buf[1] = reg_addr;

HAL_GPIO_WritePin(port, pin, 0);
short_delay(7);
ret = SPI_Transmit1(hspi, &buf[0], SPI_TIMEOUT);

HAL_GPIO_WritePin(port, pin, 1);
short_delay(7);

HAL_GPIO_WritePin(port, pin, 0);
short_delay(7);
ret = SPI_Transmit1(hspi, &buf[1], SPI_TIMEOUT);
HAL_GPIO_WritePin(port, pin, 1);
short_delay(7);

if(HAL_OK != ret){
responce_handle(ret);
return (uint16_t) -1;
}

HAL_GPIO_WritePin(port, pin, 0);
short_delay(7);
ret = SPI_Transmit1(hspi, &buf[0], SPI_TIMEOUT);
HAL_GPIO_WritePin(port, pin, 1);
short_delay(7);

if(HAL_OK != ret){
responce_handle(ret);
}

return (uint32_t)buf[0];
}


Конфигурация:
Registers
SPI_CR1 = 0x0000015F
SPI_CR2 = 0x00000004
Tarbal
А замена на такую функцию (без аппаратной поддержки SPI) прекрасно работает.

CODE

#define PIN(PORT, PIN) GPIO##PORT, GPIO_PIN_##PIN

#define SPI1_CLK_PIN PIN(B, 3)
#define SPI1_MOSI_PIN PIN(A,7)
#define SPI1_MISO_PIN PIN(A, 6)
#define SPI1_SS_PIN PIN(A, 4)

#define SET_CLK1() HAL_GPIO_WritePin(SPI1_CLK_PIN, 1)
#define CLR_CLK1() HAL_GPIO_WritePin(SPI1_CLK_PIN, 0)

#define SET_MOSI1() HAL_GPIO_WritePin(SPI1_MOSI_PIN, 1)
#define CLR_MOSI1() HAL_GPIO_WritePin(SPI1_MOSI_PIN, 0)

#define GET_MISO1() HAL_GPIO_ReadPin(SPI1_MISO_PIN)

int SPI_Transmit1(SPI_HandleTypeDef *hspi, uint8_t* val, uint32_t timeout)
{
int i;
uint8_t res= 0, tmp = *val;
if(&hspi1 == hspi){
for(i = 0; i < 8; i++){
res <<= 1;
CLR_CLK1();
if(tmp & 0x80){
SET_MOSI1();
} else {
CLR_MOSI1();
}
res |= GET_MISO1();
SET_CLK1();
tmp <<= 1;
}
} else {
return SPI_Transmit1_hw(hspi, val, timeout);
}
*val = res;
return 0;
}


В принципе если ожидать в цикле флагов, аппаратное исполнение не дает выигрыша, ну разве только на выскоких частотах обмена. Программное исполнение дает клок 1 мегагерц, что довольно сносно.
ViKo
С HAL мучайтесь сами, мне это не интересно. У меня свой HAL.
Tarbal
Цитата(ViKo @ Jun 20 2016, 08:52) *
С HAL мучайтесь сами, мне это не интересно. У меня свой HAL.


Да вроде ключевые моменты не на HAL. Разве только ножкой подрыгать не переписал. Да и не надо проверять. Я уже все исследовал сам.
ViKo
Цитата(Tarbal @ Jun 20 2016, 15:20) *
Я уже все исследовал сам.

И какие же выводы от исследований? "Кто был охотник, кто добыча?" SPI-то работает или где? В первом интерфейсе читает единицу, а в других что? А должен что читать? rolleyes.gif Какие-то невнятные сообщения.
Tarbal
Цитата(ViKo @ Jun 20 2016, 16:52) *
И какие же выводы от исследований? "Кто был охотник, кто добыча?" SPI-то работает или где? В первом интерфейсе читает единицу, а в других что? А должен что читать? rolleyes.gif Какие-то невнятные сообщения.


Программная имплементация SPI работает без проблем, что подтверждает, что во внешних цепях SPI все правильно. На форуме ST проблема младшего бита именно в SPI1 возникала много раз.
ViKo
Еще бы и программный ногодрыг не работал... rolleyes.gif Четыре провода проложены, как положено. Это хорошо. Но мало.
Заметьте, у adnega все каналы SPI работают! А вы ссылаетесь на форум каких-то... неучей...
adnega
Цитата(ViKo @ Jun 21 2016, 17:28) *
Заметьте, у adnega все каналы SPI работают!

Сейчас не получается воссоздать ошибку. Раньше точно помню, что замыкал MISO на 3.3В и получал 0xFE.
Допускаю:
1. тогда я где-то нокосячил;
2. сейчас использую простой проект (LTDC, SDRAM, SPIx), а тогда - куча SPI (кнопки и светодиоды на сдвиговых регистрах, цифровой микрофон, I2S-кодек),
таймеры (DS18B20, импульсы тестирования усилителей), UART (GSM, console), SDIO (uSD-карта), I2C (радио RDA5807). Все это густо разбавлено DMA.
Tarbal
Цитата(ViKo @ Jun 21 2016, 18:28) *
Еще бы и программный ногодрыг не работал... rolleyes.gif Четыре провода проложены, как положено. Это хорошо. Но мало.
Заметьте, у adnega все каналы SPI работают! А вы ссылаетесь на форум каких-то... неучей...

Не будьте так высокомерны. Это форум поддержки ST.
ViKo
Цитата(Tarbal @ Jun 22 2016, 02:31) *
Не будьте так высокомерны. Это форум поддержки ST.

И что с того? "Специалист" любого уровня может задать там тупейший вопрос. Как и здесь. Если не путаю, там был участник Cliv(не вспомню точный ник), вот он и утирал сопли направо и налево. Задайте и вы там вопрос. Гуглопереводчик-то доступен.
P.S. Нашел. clive1 он обзывается. Его ответам доверяю.
Tarbal
Цитата(ViKo @ Jun 22 2016, 09:04) *
И что с того? "Специалист" любого уровня может задать там тупейший вопрос. Как и здесь. Если не путаю, там был участник Cliv(не вспомню точный ник), вот он и утирал сопли направо и налево. Задайте и вы там вопрос. Гуглопереводчик-то доступен.
P.S. Нашел. clive1 он обзывается. Его ответам доверяю.


clive1 про чип селект что-то сказал, но когда я вывалил побольше информации, то он слинял. Он не сопли утирает, а работает в поддержке и отвечает на вопросы.
Мне гуглопереводчик не нужен. Я на аглицкой мове немного могу говорить sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.