Ako na I2C-DMA v stm32duino?
Moderátor: Moderátori
- lucky62
- Zaslúžilý člen
- Príspevky: 1151
- Dátum registrácie: 14 Feb 2012, 20:16
- Bydlisko: Liptovský Mikuláš, SK
Ako na I2C-DMA v stm32duino?
Ahojte,
neriešil niekto použitie DMA v stm32duino?
Snažím sa nájsť k tomu nejaké info, ale ujo googel nič moc nenašiel.
Potrebujem prenášať cyklicky cca 1K dát z bluepill (STM32F103) do externého DAC cez I2C.
Softvérový prenos je pomalý a pri použití knižnice Wire CPU vždy čaká na dokončenie prenosu, takže nerobí nič iné. DMA by bolo fajn, ale neviem ako na to...
neriešil niekto použitie DMA v stm32duino?
Snažím sa nájsť k tomu nejaké info, ale ujo googel nič moc nenašiel.
Potrebujem prenášať cyklicky cca 1K dát z bluepill (STM32F103) do externého DAC cez I2C.
Softvérový prenos je pomalý a pri použití knižnice Wire CPU vždy čaká na dokončenie prenosu, takže nerobí nič iné. DMA by bolo fajn, ale neviem ako na to...
0
- jirka.jirka.
- 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?
DMA tutoriál:http://www.pd-nb.cz/clanky/stm32_dma/stm32_dma.html
Tady máš DMA a UART. http://www.pd-nb.cz/clanky/stm32_usart1 ... sart1.html
U I2C to bude velmi obdobné jako u toho uartu.
Tady máš DMA a UART. http://www.pd-nb.cz/clanky/stm32_usart1 ... sart1.html
U I2C to bude velmi obdobné jako u toho uartu.
0
- lucky62
- Zaslúžilý člen
- Príspevky: 1151
- Dátum registrácie: 14 Feb 2012, 20:16
- Bydlisko: Liptovský Mikuláš, SK
- lucky62
- 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?
Tak začínam s implementáciou - na začiatok sa snažím nastaviť hodiny. V STM32Cube som si naklikal, ako by som si to predstavoval.
Len netuším, čo znamená parameter LL_UTILS_HSEBYPASS_ON...
A takto som to nahodil do kódu:Kód: Vybrať všetko
void setupClock(void) {
// 72MHz from 8MHz HSE
LL_UTILS_PLLInitTypeDef pll;
pll.Prediv = LL_RCC_PREDIV_DIV_1; // 8MHz / 1 = 4MHz
pll.PLLMul = LL_RCC_PLL_MUL_9; // 8MHz * 9 = 72MHz
LL_UTILS_ClkInitTypeDef clk;
clk.AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
clk.APB1CLKDivider = LL_RCC_APB1_DIV_2;
clk.APB2CLKDivider = LL_RCC_APB2_DIV_1;
// configure clock
LL_PLL_ConfigSystemClock_HSE(8000000,LL_UTILS_HSEBYPASS_ON,&pll,&clk);
SystemCoreClockUpdate();
}
0
Re: Ako na I2C-DMA v stm32duino?
Tady je popis hodin včetně HSE Bypass
http://www.elektromys.eu/clanky/stm_clock1/clanek.html
http://www.elektromys.eu/clanky/stm_clock1/clanek.html
0
- lucky62
- 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?
Tam som našiel len toto:
V prípade externého zdroja hodín (nie kryštál) je potrebný len jeden pin - ten druhý sa môže použiť na iné účely...
A teda:
LL_UTILS_HSEBYPASS_ON - na výstupnom pine je signál hodín
LL_UTILS_HSEBYPASS_OFF - výstupný pin nie je zdrojom hodín použitý
Je to tak správne?
EDIT: tak som zle čítal, je to naopak:
LL_UTILS_HSEBYPASS_ON - výstupný pin nie je zdrojom hodín použitý (je v stave vysokej impedancie = hi-Z podľa Reference Manual).
LL_UTILS_HSEBYPASS_OFF - na výstupnom pine OSC_OUT je signál hodín - spätná väzba pre kryštál
Tak uvažujem, že v prípade kryštálu sú potrebné dva piny - vstup aj výstup (pre spätnú väzbu).Druhý parametr vybírá zda používáte externí krystal nebo externí clock (LL_UTILS_HSEBYPASS_ON)
V prípade externého zdroja hodín (nie kryštál) je potrebný len jeden pin - ten druhý sa môže použiť na iné účely...
A teda:
LL_UTILS_HSEBYPASS_ON - na výstupnom pine je signál hodín
LL_UTILS_HSEBYPASS_OFF - výstupný pin nie je zdrojom hodín použitý
Je to tak správne?
EDIT: tak som zle čítal, je to naopak:
LL_UTILS_HSEBYPASS_ON - výstupný pin nie je zdrojom hodín použitý (je v stave vysokej impedancie = hi-Z podľa Reference Manual).
LL_UTILS_HSEBYPASS_OFF - na výstupnom pine OSC_OUT je signál hodín - spätná väzba pre kryštál
0
Naposledy upravil/-a lucky62 v 16 Mar 2020, 11:06, upravené celkom 1 krát.
-
- Ultimate člen
- Príspevky: 2573
- Dátum registrácie: 20 Júl 2010, 00:00
- Bydlisko: okolie KE
- Vek: 27
Re: Ako na I2C-DMA v stm32duino?
Tesne vedľa. HSEON zapína zdroj externých hodín(interné hodiny sú HSI). HSEON a ~HSEBYP je kryštálový oscilátor. HSEON a HSEBYP je externý zdroj hodín bez použitia interného oscilátora.
Ešte pre istotu, najprv je nutné nastaviť HSEBYP a až tak zapínať HSEON. Určite neodporúčam z OSC_OUT odoberať hodiny pre iné zariadenia. Stačí osciloskopická sonda a vysadí oscilátor. Na tieto účely je Master Clock Output.
Ešte pre istotu, najprv je nutné nastaviť HSEBYP a až tak zapínať HSEON. Určite neodporúčam z OSC_OUT odoberať hodiny pre iné zariadenia. Stačí osciloskopická sonda a vysadí oscilátor. Na tieto účely je Master Clock Output.
0
- lucky62
- 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?
Áno, už som to naštudoval...
Takže pre BluePill dosku musím dať HSE Bypass OFF.
Takže pre BluePill dosku musím dať HSE Bypass OFF.
0
- lucky62
- 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?
Narazil som na malý problém.
Chcel som zistiť predpokladané frekvencie - ako je uvedené na web stránke:
Chcel som zistiť predpokladané frekvencie - ako je uvedené na web stránke:
ale program sa neskompiluje z dôvodu chyby:// spočítej a uož frekvence SYSCLK,AHB a APB do struktury "clocks"
LL_RCC_ClocksTypeDef clocks;
LL_RCC_GetSystemClocksFreq(&clocks);
Deklarácia tohoto typu je v stm32f1xx_ll_rcc.h (mám ho v #include):error: 'LL_RCC_ClocksTypeDef' was not declared in this scope
119 | LL_RCC_ClocksTypeDef clocks;
| ^~~~~~~~~~~~~~~~~~~~
ale je zatienená podmienkou:typedef struct
{
uint32_t SYSCLK_Frequency; /*!< SYSCLK clock frequency */
uint32_t HCLK_Frequency; /*!< HCLK clock frequency */
uint32_t PCLK1_Frequency; /*!< PCLK1 clock frequency */
uint32_t PCLK2_Frequency; /*!< PCLK2 clock frequency */
} LL_RCC_ClocksTypeDef;
Skúsil som toto definovať na začiatku môjho programu - potom kompilácia zbehne ok ale zhavaruje linker:#if defined(USE_FULL_LL_DRIVER)
Vie niekto, kde je chyba?..undefined reference to `LL_RCC_GetSystemClocksFreq'
0
- jirka.jirka.
- 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?
Co používáš za IDE? Vidím v názvu duino... Nemáš náhodou takové ti arduino IDE?
Dál, máš v makefile vyřešené závislosti? Tzn. neutekl ti nějaký c soubor? Popř. jestli používáš HAL, tak to přepiš do HALu. Ukaž nám projekt.
Takto je to jak věštit z
Dál, máš v makefile vyřešené závislosti? Tzn. neutekl ti nějaký c soubor? Popř. jestli používáš HAL, tak to přepiš do HALu. Ukaž nám projekt.
Takto je to jak věštit z
0
- lucky62
- 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?
Áno, mám nainštalované STM32 Core v Arduino IDE.
prefixy LL_ naznačujú, že ide o Low-Level API.
Tu je celý program - je to zatiaľ len kostra pre ten DMA I2C prenos:
všetko funguje, až na tie dva príkazy LL_RCC... Tam kompilátor vyhodí chybu.
Inšpiráciu čerpám z web stránok, na ktoré si mi dal odkaz (a tiež z ST dokumentov).This porting is based on STM32Cube MCU Packages including:
- The HAL hardware abstraction layer, enabling portability between different STM32 devices via standardized API calls
The Low-Layer (LL) APIs, a light-weight, optimized, expert oriented set of APIs designed for both performance and runtime efficiency
CMSIS device defintion for STM32
CMSIS: Cortex Microcontroller Software Interface Standard (CMSIS) is a vendor-independent hardware abstraction layer for the Cortex®-M processor series and defines generic tool interfaces. It has been packaged as a module for Arduino IDE: https://github.com/stm32duino/ArduinoModule-CMSIS
GNU Arm Embedded Toolchain: Arm Embedded GCC compiler, libraries and other GNU tools necessary for bare-metal software development on devices based on the Arm Cortex-M. Packages are provided thanks The xPack GNU Arm Embedded GCC: https://github.com/xpack-dev-tools/arm- ... -gcc-xpack
prefixy LL_ naznačujú, že ide o Low-Level API.
Tu je celý program - je to zatiaľ len kostra pre ten DMA I2C prenos:
Kód: Vybrať všetko
#include "stm32f1xx.h"
#include "stm32f1xx_ll_bus.h"
#include "stm32f1xx_ll_gpio.h"
#include "stm32f1xx_ll_utils.h"
#include "stm32f1xx_ll_rcc.h"
#include "stm32f1xx_ll_system.h"
void setupClock(void) {
// 72MHz from 8MHz HSE
LL_UTILS_PLLInitTypeDef pll;
pll.Prediv = LL_RCC_PREDIV_DIV_1; // 8MHz / 1 = 8MHz
pll.PLLMul = LL_RCC_PLL_MUL_9; // 8MHz * 9 = 72MHz
LL_UTILS_ClkInitTypeDef clk;
clk.AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
clk.APB1CLKDivider = LL_RCC_APB1_DIV_2;
clk.APB2CLKDivider = LL_RCC_APB2_DIV_1;
// configure clock
LL_PLL_ConfigSystemClock_HSE(8000000,LL_UTILS_HSEBYPASS_OFF,&pll,&clk);
SystemCoreClockUpdate();
Serial.print("SystemCoreClock: ");
Serial.println(SystemCoreClock);
}
void setupDMA(void) {}
void setupI2C(void) {}
void setup() {
Serial.begin(115200);
setupClock();
// spočítej a uož frekvence SYSCLK,AHB a APB do struktury "clocks"
LL_RCC_ClocksTypeDef clocks;
LL_RCC_GetSystemClocksFreq(&clocks);
setupI2C();
setupDMA();
}
void loop() {
Serial.print(".");
delay( 1000 );
}
0
- jirka.jirka.
- 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?
Jo tak jak skloubit knihovny arduina a stm-ka nevím. V tom IDE pracovat neumím. Jestli nebude snazší integrovat do třeba do eclipse....
Nebo zkusit nástroj přímo od STMka, ale s tím taktéž neumím. Já pracuji v eclipse s čistými knihovnami od STM32. Všechno ostatní si píši sám. Možná bych se mohl dokopat k tomu, udělat tutoriál sem na stránky, jak na projekt řízený makefilem a čistým kódem bez duina. Ale nevím kam dřív skočit (práce, přítelkyně, koníčky, ...)
https://www.st.com/en/development-tools ... beide.html
Nebo zkusit nástroj přímo od STMka, ale s tím taktéž neumím. Já pracuji v eclipse s čistými knihovnami od STM32. Všechno ostatní si píši sám. Možná bych se mohl dokopat k tomu, udělat tutoriál sem na stránky, jak na projekt řízený makefilem a čistým kódem bez duina. Ale nevím kam dřív skočit (práce, přítelkyně, koníčky, ...)
https://www.st.com/en/development-tools ... beide.html
0
Re: Ako na I2C-DMA v stm32duino?
Taky ti poradím, vyber si jedno prostředí, a v tom se snaž dělat. Tahle míchanina Arduino - STM, v tom se asi nikdo nevyzná.
A dnes, kdy je k dispozici zdarma kompletní IDE (viz Jirka), tak si ho stáhni a vyzkoušej, a odpadne ti spousta problémů. V cubeMX naklikáš co potřebuješ, a můžeš začít blikat Ledkou (nebo DMA I2C). To je hodně podobné Adruino stylu.
Pokud se budeš chtít ponořit hloubš (LL API), tak ti v tom nic nebrání, to je v tom IDE obsaženo komplet taky.
LL API je už vlastně na úrovni registrů.
A dnes, kdy je k dispozici zdarma kompletní IDE (viz Jirka), tak si ho stáhni a vyzkoušej, a odpadne ti spousta problémů. V cubeMX naklikáš co potřebuješ, a můžeš začít blikat Ledkou (nebo DMA I2C). To je hodně podobné Adruino stylu.
Pokud se budeš chtít ponořit hloubš (LL API), tak ti v tom nic nebrání, to je v tom IDE obsaženo komplet taky.
LL API je už vlastně na úrovni registrů.
0
- lucky62
- 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?
No ja osobne nemám rád Eclipse a aj to STM32CubeIDE je "založené" na Eclipse.
Mám nainštalované Arduino a kompilujem v ňom programy pre viacero platforiem, takže mi to vyhovuje.
Ale už sa odkláňame od riešenia problému... Nechcel by som riešiť filozofické otázky.
Tento môj problém bude zrejme niekde v konfigurácii, ale s STM32 len začínam, tak ešte neviem, kde sa čo nastavuje...
Idem pátrať, čo znamená ten konfiguračný parameter USE_FULL_LL_DRIVER.
Mám nainštalované Arduino a kompilujem v ňom programy pre viacero platforiem, takže mi to vyhovuje.
Ale už sa odkláňame od riešenia problému... Nechcel by som riešiť filozofické otázky.
Tento môj problém bude zrejme niekde v konfigurácii, ale s STM32 len začínam, tak ešte neviem, kde sa čo nastavuje...
Idem pátrať, čo znamená ten konfiguračný parameter USE_FULL_LL_DRIVER.
0
Re: Ako na I2C-DMA v stm32duino?
OK, piš v čem ti to vyhovuje. Stáhni si dokument UM1850 od ST, a hned zjistíš, k čemu ten přepínač je str.42 .
The definition of these LL initialization functions and associated resources (structure, literals and prototypes) is
conditioned by a compilation switch: USE_FULL_LL_DRIVER. To use these functions, this switch must be added
in the toolchain compiler preprocessor or to any generic header file which is processed before the LL drivers.
atd....
viz třeba tady:
http://www.elektromys.eu/clanky/stm_uvod/clanek.html
Pro konfiguraci periferií slouží přehledné struktury, které před-plníme čitelnými parametry a zavoláním příslušné funkce se toto nastavení aplikuje.Aby jste tyto struktury mohli používat, musíte si v překladači mezi definované symboly zařadit "USE_FULL_LL_DRIVER".
The definition of these LL initialization functions and associated resources (structure, literals and prototypes) is
conditioned by a compilation switch: USE_FULL_LL_DRIVER. To use these functions, this switch must be added
in the toolchain compiler preprocessor or to any generic header file which is processed before the LL drivers.
atd....
viz třeba tady:
http://www.elektromys.eu/clanky/stm_uvod/clanek.html
Pro konfiguraci periferií slouží přehledné struktury, které před-plníme čitelnými parametry a zavoláním příslušné funkce se toto nastavení aplikuje.Aby jste tyto struktury mohli používat, musíte si v překladači mezi definované symboly zařadit "USE_FULL_LL_DRIVER".
0
- lucky62
- 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?
vďaka, už som to našiel tiež, práve som to dočítal.
Takže je úplne v poriadku, keď ten parameter dám na začiatok môjho programu.
Problém je, že už som to skúsil (to som napísal vyššie), ale potom zhavaruje linker. Takže idem pátrať, prečo...
Takže je úplne v poriadku, keď ten parameter dám na začiatok môjho programu.
Problém je, že už som to skúsil (to som napísal vyššie), ale potom zhavaruje linker. Takže idem pátrať, prečo...
0
- jirka.jirka.
- 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?
A nebude tím, že jsi ten příkaz USE_FULL_LL_DRIVER dal na blbé místo???
Viz dotaz v gůglu: Výsledky
Pak jsem použil nějaký odkaz na první stránce google, což je zde tento:
https://stm32duinoforum.com/forum/viewt ... _4420.html
Kde je konkrétně napsáno:
Viz dotaz v gůglu: Výsledky
Pak jsem použil nějaký odkaz na první stránce google, což je zde tento:
https://stm32duinoforum.com/forum/viewt ... _4420.html
Kde je konkrétně napsáno:
Thank! Indeed the file "build_opt.h" in the sketch directory with a string "-DUSE_FULL_LL_DRIVER" completely solved the problem.
0
- lucky62
- Zaslúžilý člen
- Príspevky: 1151
- Dátum registrácie: 14 Feb 2012, 20:16
- Bydlisko: Liptovský Mikuláš, SK
- jirka.jirka.
- 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?
Tak hlavně že se povedlo.
Pak dej vědět, jestli jede i to DMA pro I2C. Časem bych to možná taky zkusil naroubovat.
Pak dej vědět, jestli jede i to DMA pro I2C. Časem bych to možná taky zkusil naroubovat.
0
- lucky62
- 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?
Tak som sa trochu zasekol...
Môj program by mal opakovane posielať dáta z bufferu do DA prevodníka cez I2C/DMA a tým generovať ľubovolný periodický signál - podľa toho, čo sa uloží du bufferu. Program som nejako poskladal podľa viacerých zdrojov - problém je, že ten I2C prenos nefunguje.
Pretože DMA je zložitejšie, tak som to najprv chcel rozbehať v polling režime, ale nefunguje mi ani ten.
Vysielanie (v master režime) skončí chybou HAL_I2C_ERROR_AF, čo znamená že slave nepotvrdil prijatie adresy.
Pátral som po príčine na internete - zdá sa, že je to dosť častá chyba a spôsobiť ju môže všeličo...
Tu je nejaký zaujímavý pokec, ale priznám sa, že som nepochopil, v čom bol problém...
Hardvérovú chybu som vylúčil, lebo program s použitím Arduino-like knižnice Wire prenos funguje.
Takže sa jedná o nejakú konfiguračnú chybu, ale neviem prísť na to akú. Privítam akúkoľvek radu...
Prikladám program - nie je dlhý - očesal som ho na minimum:
Môj program by mal opakovane posielať dáta z bufferu do DA prevodníka cez I2C/DMA a tým generovať ľubovolný periodický signál - podľa toho, čo sa uloží du bufferu. Program som nejako poskladal podľa viacerých zdrojov - problém je, že ten I2C prenos nefunguje.
Pretože DMA je zložitejšie, tak som to najprv chcel rozbehať v polling režime, ale nefunguje mi ani ten.
Vysielanie (v master režime) skončí chybou HAL_I2C_ERROR_AF, čo znamená že slave nepotvrdil prijatie adresy.
Pátral som po príčine na internete - zdá sa, že je to dosť častá chyba a spôsobiť ju môže všeličo...
Tu je nejaký zaujímavý pokec, ale priznám sa, že som nepochopil, v čom bol problém...
Hardvérovú chybu som vylúčil, lebo program s použitím Arduino-like knižnice Wire prenos funguje.
Takže sa jedná o nejakú konfiguračnú chybu, ale neviem prísť na to akú. Privítam akúkoľvek radu...
Prikladám program - nie je dlhý - očesal som ho na minimum:
Kód: Vybrať všetko
/*
* NOTES:
* I2C1_SCL - pin PB6
* I2C1_SDA - pin PB7
*/
#include "stm32f1xx_hal_gpio.h"
#include "stm32f1xx_hal_rcc.h"
#include "stm32f1xx_hal_dma.h"
#include "stm32f1xx_hal_i2c.h"
#define I2C_CLOCK 100000 // 100000, 400000, 1000000, 3400000
#define I2C_DAC_ADDR 0x27 // I2C DAC address
#define BUF_SIZE 8 // Number of wave samples
#define MAX_AMP 255 // wave Amplitude - depends on DAC resloution
uint8_t wave8[BUF_SIZE];
// naplní buffer hodnotami pre DAC
void genWave( uint8_t amp ) {
if ( amp > MAX_AMP ) amp = MAX_AMP;
for( uint16_t i=0; i<BUF_SIZE; i++ ) {
// square wave generation
if ( i<BUF_SIZE/2 ) {
wave8[i] = 0x00;
} else {
wave8[i] = amp;
}
}
}
void setupGPIO(void) {
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
/**I2C1 Pins - PB6, PB7 */
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* LED Pin - PC13 */
HAL_GPIO_WritePin( GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init( GPIOC, &GPIO_InitStruct );
digitalWrite( LED_BUILTIN, 1 ); // LED OFF
Serial.println("GPIO initialized.");
}
I2C_HandleTypeDef I2C_Handle;
void setupI2C(void) {
I2C_Handle.Instance = I2C1;
I2C_Handle.Init.ClockSpeed = I2C_CLOCK;
I2C_Handle.Init.DutyCycle = I2C_DUTYCYCLE_2;
I2C_Handle.Init.OwnAddress1 = 0;
I2C_Handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2C_Handle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
I2C_Handle.Init.OwnAddress2 = 0;
I2C_Handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
I2C_Handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
// HAL_I2C_DeInit( &I2C_Handle );
__HAL_RCC_I2C1_CLK_ENABLE();
__HAL_RCC_I2C1_FORCE_RESET();
__HAL_RCC_I2C1_RELEASE_RESET();
if ( HAL_I2C_Init( &I2C_Handle ) != HAL_OK ) {
Serial.println("I2C Init Error!");
Serial.print("Reset is required!");
while(1){};
} else {
Serial.println("I2C initialized.");
}
}
void printI2CError( uint32_t err ) {
Serial.print("I2C Trasnfer ERROR!!! - ");
switch ( err ) {
case HAL_I2C_ERROR_NONE: Serial.println( "HAL_I2C_ERROR_NONE" ); break;
case HAL_I2C_ERROR_BERR: Serial.println( "HAL_I2C_ERROR_BERR" ); break;
case HAL_I2C_ERROR_ARLO: Serial.println( "HAL_I2C_ERROR_ARLO" ); break;
case HAL_I2C_ERROR_AF: Serial.println( "HAL_I2C_ERROR_AF" ); break;
case HAL_I2C_ERROR_OVR: Serial.println( "HAL_I2C_ERROR_OVR" ); break;
case HAL_I2C_ERROR_DMA: Serial.println( "HAL_I2C_ERROR_DMA" ); break;
case HAL_I2C_ERROR_TIMEOUT: Serial.println( "HAL_I2C_ERROR_TIMEOUT" ); break;
case HAL_I2C_ERROR_SIZE: Serial.println( "HAL_I2C_ERROR_SIZE" ); break;
case HAL_I2C_ERROR_DMA_PARAM: Serial.println( "HAL_I2C_ERROR_DMA_PARAM" ); break;
// case HAL_I2C_ERROR_INVALID_CALLBACK: Serial.println( "HAL_I2C_ERROR_INVALID_CALLBACK" ); break;
}
// stop okrem chyby Acknowledge Failure
if ( err == HAL_I2C_ERROR_AF ) {
delay( 5000 );
} else {
Serial.print("Reset is required!!!");
while(1){}; //endless loop
}
}
// inicializácia
void setup() {
Serial.begin(115200);
delay( 2000 );
genWave( MAX_AMP ); // prepare waveform in buffer
HAL_Init();
setupGPIO(); // prepare used GPIO pins
setupI2C(); // prepare I2C - sending data to DAC
}
// hlavná slučka
void loop() {
if ( HAL_I2C_IsDeviceReady( &I2C_Handle, (uint16_t)I2C_DAC_ADDR, 5, 1000 ) ) {
if ( HAL_I2C_Master_Transmit( &I2C_Handle, (uint16_t)I2C_DAC_ADDR, (uint8_t*)wave8, BUF_SIZE, 10000000 ) != HAL_OK ) {
printI2CError( HAL_I2C_GetError( &I2C_Handle ) );
} else {
digitalWrite( LED_BUILTIN, !digitalRead( LED_BUILTIN ) ); // toggle LED
}
} else {
Serial.println("I2C Not Ready !!!");
}
}
0
-
- Podobné témy
- Odpovedí
- Zobrazení
- Posledný príspevok
-
- 17 Odpovedí
- 2414 Zobrazení
-
Posledný príspevok od používateľa Sani1
-
- 17 Odpovedí
- 2370 Zobrazení
-
Posledný príspevok od používateľa kapor
-
- 13 Odpovedí
- 2045 Zobrazení
-
Posledný príspevok od používateľa hal_sk
-
- 0 Odpovedí
- 1338 Zobrazení
-
Posledný príspevok od používateľa lato
-
- 1 Odpovedí
- 535 Zobrazení
-
Posledný príspevok od používateľa mr.dred