Ako na I2C-DMA v stm32duino?

Sekcia určená pre Arduino nadšencov

Moderátor: Moderátori

Používateľov profilový obrázok
lucky62
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1151
Dátum registrácie: 14 Feb 2012, 20:16
Bydlisko: Liptovský Mikuláš, SK

Re: Ako na I2C-DMA v stm32duino?

Príspevok od používateľa lucky62 » 20 Mar 2020, 12:57

Tak som sa dostal ďalej.. polling režim funguje...

Z nepochopiteľných dôvodov je nutné vo funkcii HAL_I2C_Master_Transmit I2C adresu posunúť o jeden bit doľava...

A teda sa musí zavolať s tým shiftom (<<1) takto:

Kód: Vybrať všetko

HAL_I2C_Master_Transmit( &I2C_Handle, (uint16_t)I2C_DAC_ADDR<<1, (uint8_t*)wave8, BUF_SIZE, (uint32_t)1000 )
0
....môj bazar....

...Nikdy sa nehádaj s blbcom...

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1538
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Re: Ako na I2C-DMA v stm32duino?

Príspevok od používateľa jirka.jirka. » 20 Mar 2020, 16:06

Ten posun je jasný.
https://i2c.info/i2c-bus-specification

Ten osmý bit určuje read or write. :thumbup:

Obrázok
0

Používateľov profilový obrázok
lucky62
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1151
Dátum registrácie: 14 Feb 2012, 20:16
Bydlisko: Liptovský Mikuláš, SK

Re: Ako na I2C-DMA v stm32duino?

Príspevok od používateľa lucky62 » 20 Mar 2020, 17:09

Toto je jasné.

Nepochopiteľné je, prečo sa s tým musí zapodievať programátor a neurobí to tá "vysokoúrovňová" funkcia sama.
Veď predsa HAL bolo urobené na to, aby sa programátor nezapodieval detailami o registroch.
Naviac je celé HAL veľmi biedne zdokumentované.
0
....môj bazar....

...Nikdy sa nehádaj s blbcom...

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1538
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Re: Ako na I2C-DMA v stm32duino?

Príspevok od používateľa jirka.jirka. » 20 Mar 2020, 17:31

Nepochopiteľné je, prečo sa s tým musí zapodievať programátor a neurobí to tá "vysokoúrovňová" funkcia sama.
Veď predsa HAL bolo urobené na to, aby sa programátor nezapodieval detailami o registroch.
Naviac je celé HAL veľmi biedne zdokumentované.
To je pouze úhel pohledu. Kdyby se všechno dělalo vysokoúrovňově, co by programátoři dělali? :D Ale ne vážně, to že to má posunout programátor má své výhody. Nemusí přepočítávát adresu. ;) Ale opět, pokud ti HAL nevyhovuje, udělej si vlastní funkce a naprogramuj to čistě za pomocí registrů. Je to sice opruz, ale budeš přesně vědět co to dělá. A dokumentace HAL. No nezbývá, než se podívat do té funkce a do datasheetu a podívat se, co ta funkce dělá.
Stejně je v tom HAL akorát zabalené plnění registrů. :thumbup:
0

Používateľov profilový obrázok
lucky62
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1151
Dátum registrácie: 14 Feb 2012, 20:16
Bydlisko: Liptovský Mikuláš, SK

Re: Ako na I2C-DMA v stm32duino?

Príspevok od používateľa lucky62 » 21 Mar 2020, 11:05

To DMA je neskutočný zápas...

Po spustení prenosu sa I2C aj DMA dostane do stavu BUSY, ale nič sa neodosiela.

Pátral som po internete a všade píšu, že je potrebné nakonfigurovať aj prerušenia (NVIC).
príklady:
https://community.st.com/s/question/0D5 ... keeps-busy
https://community.st.com/s/question/0D5 ... ma-is-busy
https://community.st.com/s/question/0D5 ... n-busy-bug

Avšak Reference Manual tvrdí:
13.1 DMA introduction
Direct memory access (DMA) is used in order to provide high-speed data transfer between
peripherals and memory as well as memory to memory. Data can be quickly moved by DMA
without any CPU actions
. This keeps CPU resources free for other operations.
V tom treťom linku chlap modifikoval UART knižnicu, aby to chodilo...

Skutočne to bez prerušení nejde?...
0
....môj bazar....

...Nikdy sa nehádaj s blbcom...

Používateľov profilový obrázok
lucky62
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1151
Dátum registrácie: 14 Feb 2012, 20:16
Bydlisko: Liptovský Mikuláš, SK

Re: Ako na I2C-DMA v stm32duino?

Príspevok od používateľa lucky62 » 22 Mar 2020, 22:39

Odpovedám si sám... NEJDE!
V tom HAL to proste bez množstva callback funkcií a IRQ rutín nejde...

Toto je výňatok z funkcie HAL_I2C_Master_Transmit_DMA - minimum sú štyri podporné funkcie:

Kód: Vybrať všetko

      /* Set the I2C DMA transfer complete callback */
      hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt;

      /* Set the DMA error callback */
      hi2c->hdmatx->XferErrorCallback = I2C_DMAError;

      /* Set the unused DMA callbacks to NULL */
      hi2c->hdmatx->XferHalfCpltCallback = NULL;
      hi2c->hdmatx->XferAbortCallback = NULL;

      /* Enable the DMA channel */
      dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize);

      if (dmaxferstatus == HAL_OK)
      {
        /* Enable Acknowledge */
        SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);

        /* Generate Start */
        SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);

        /* Process Unlocked */
        __HAL_UNLOCK(hi2c);

        /* Note : The I2C interrupts must be enabled after unlocking current process
        to avoid the risk of I2C interrupt handle execution before current
        process unlock */

        /* Enable EVT and ERR interrupt */
        __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);

        /* Enable DMA Request */
        SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
      }
0
....môj bazar....

...Nikdy sa nehádaj s blbcom...

Používateľov profilový obrázok
lucky62
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1151
Dátum registrácie: 14 Feb 2012, 20:16
Bydlisko: Liptovský Mikuláš, SK

Re: Ako na I2C-DMA v stm32duino?

Príspevok od používateľa lucky62 » 24 Mar 2020, 07:03

Tak som to rozbehal ručne.

po inicializácii I2C a DMA sa prenos zaháji takto:

Kód: Vybrať všetko

  SET_BIT( I2C1->CR1, I2C_CR1_START );    // generate START condition by setting START bit

  uint64_t time = 0xFFFFFFFF;
  while ( READ_BIT( I2C1->SR1, I2C_SR1_SB ) == 0 ) {   // wait for SB
    time--;
    if ( time == 0 ) {
      Serial.println("SB timeout.");
      return;
    }
  };
  Serial.println("SB detected.");

  WRITE_REG( I2C1->DR, I2C_DAC_ADDR2 );   // write the SHIFTED slave address to DR

  while ( READ_BIT( I2C1->SR1, I2C_SR1_ADDR ) == 0 ) {   // wait for ADDR flag
    time--;
    if ( time == 0 ) {
      Serial.println("ADDR timeout.");
      return;
    }
  };
  Serial.println("ADDR detected.");

  SET_BIT( I2C1->CR2, I2C_CR2_DMAEN );   // enable DMA requests

  READ_REG( I2C1->SR1 );   // Read registers SR1 and SR2
  READ_REG( I2C1->SR2 );   // this will start the DMA tranfer by generating DMA request (setting TxE flag)
Ďalej už to beží samo - DMA je v režime CIRCULAR, posiela buffer dokola.
Samozrejme treba z času na čas skontrolovať stav a ošetriť prípadné chybové stavy.
0
....môj bazar....

...Nikdy sa nehádaj s blbcom...

Napísať odpoveď
  • Podobné témy
    Odpovedí
    Zobrazení
    Posledný príspevok