Fórum témák

» Több friss téma
Fórum » ARM - Miértek hogyanok
 
Témaindító: gtk, idő: Jún 26, 2007
Lapozás: OK   106 / 106
(#) csabeszq válasza csatti2 hozzászólására (») Pé, 18:37 /
 
Kihagynám: egyrészt nem ad rendes tápot (sem 3.3V, sem 5V, másrészt meg 15 euro. Ennyiért már zenéljen is).

Lehet, hogy a Black Magic Probe-bal felülvágom a firmware-t, megnézem hogyan megy.

A SWIM-et (PB11) elvileg UART RX-ként is lehet használni. Kis módosítással lehet, hogy menne.
Bár annyira nem érdekel a dolog.

Lehet, hogy egyszerűbb valódi USB-n átküldeni az adatokat.
(#) csatti2 válasza csabeszq hozzászólására (») Pé, 18:40 /
 
Ez egy J-Link. Speciel sokkal gyorsabb mint az ST-Link. Dolgozz majd kicsit a nagyobb uC-kel, ahol már sokkal nagyobb a program, ég és föld a kettő.
(#) icserny válasza cimopata hozzászólására (») Pé, 19:28 /
 
"Nem tudom végül mi oldotta meg de letöröltem újratettem állítgattam össze vissza végül valahogy újból elkezdett működni."

Egész napi szerencsétlenkedés után úgy néz ki, hogy egy

  1. ST-LINK_CLI.exe -c -ID=0 SWD UR


parancs kiadása után (kiadáskor a Reset gombot nyomva kell tartani, majd elengedni) egy darabig újra használható lesz az ST-link és az ST-Link Utility.

A BAITE gyártmányú klónnal sajnos tényleg nem sikerült az SWO kimenetet fogadni (bár homályos emlékeim szerint pont emiatt vettem meg ezt a kütyüt, mert a JTAG opció aligha izgatott, SDW programozóm pedig már volt kettő is).

Sajnos, már nem emlékszem rá, hogy tavasszal milyen eszközökkel és pontosan hogyan (kínai J-link klón? Blue pill + ST-Link firmware? ST-Link klón?) sikerült az SWO kimenetet használni. Itt írtam róla.

Közben rájöttem, hogy Itt írta csabeszq kolléga, hogy a "Best Quality ST-Link" rendelkezik SWO bemenettel, ezen felbuzdulva rendeltem én is egyet. De a fenti kísérletben még azt nyilván nem használhattam.
A hozzászólás módosítva: Pé, 19:28
(#) csabeszq hozzászólása Pé, 22:13 /
 
A legegyszerűbb megoldás SWO-ra a "Best Quality ST-Link" átalakítása. A kínaiak félig voltak trehányok, mert a JTDO/SWO pineket nem kötötték össze, viszont a PA10-re csináltak jól forrasztható tappancsot.

Nem csináltam mást, mint egy zsugorcsőbe belepakoltam egy 220 ohmos ellenállást és összekötöttem a PA10-et a JTDO-val lásd fotókat.

Innentől simán ment az SWO nekem Keil alatt.
(#) csabeszq válasza vargham hozzászólására (») Szo, 19:46 /
 
Idézet:
„Nem valószínű. Ráadásul nem sokban különbözik az eredetitől. Akár te magad is készíthetsz. Legegyszerűbben egy bluepill, két ellenállás, két led, plusz a firmware.”


Blue pillre sikerült esetleg V2.1-es firmware-t raknod? Abban már van VCP (virtuális comm port), magyarul ha magam készítenék stlink-et, akkor az UART RX/TX fantasztikus lenne. Tök jó az SWO, de az UART azért mégiscsak jobb. Megérni saját programozót csinálni UART-tal.

Ha van esetleg tört 2.1-es firmware-ed, amit fel lehetne pakolni, az jó lenne.

Ami probléma, hogy 128k-s chip kellene neki. Az meg is van, csak 64k-s nak hazudja magát.

A V2-es bootloadert simán felraktam a blue pillre, sőt frissíti is magát, de a 2.1 nekem nem nagyon indul el.
(#) vargham válasza csabeszq hozzászólására (») Szo, 20:02 /
 
Idézet:
„de a 2.1 nekem nem nagyon indul el”

A V2-1-re gondolsz? Honnan sikerült letöltened?
Feltöltötted, és nem működik?
(#) csabeszq válasza vargham hozzászólására (») Szo, 20:12 /
 
Itt vannak a bootloader-ek:

https://github.com/Krakenw/Stlink-Bootloaders

Csak a bootloader-t felrakod (v2 unprotected), értelemszerűen a panel nem fog csinálni semmi.
Viszont firmware update-nél a blue pill-t elfogadja. Magyarul felrakom a bootloader-t, firmware update és a legfrissebb V2-es firmware felmegy.

Ezután minthogy az unprotected bootloadert raktad fel, ki is olvashatod a memória tartalmát.
Az unprotected változat az option bitekben a firmware tiltást NOP-okkal helyettesíti.

Csináltam egyébként hex fájlt is a firmware-ből, hogy egy lépésben lehessen telepíteni, szórakozás nélkül.
(#) csabeszq válasza csabeszq hozzászólására (») Vas, 0:15 /
 
Csatoltam egy ST-Link V2/1-es hex fájlt blue pillre.
Nem tudom, hogy jól működik-e, 3 eszköz jelenik meg miután bedugom:
- az ST-LINK programozó
- a modem (soros port)
- és egy NUCLEO nevű meghajtó (mass storage device)

Majd letesztelem, látszólag elindul, nem játszottam vele sokat.
A firmware update biztosan nem fog vele menni, mert 64k-s chipre hivatalosan nem lehet 128k-t felpaszírozni. A kód viszont nagyobb 64k-nál, túlírjuk a chipet.

Részletek:
- letöltöttem a bootloader-t
- a bootloadert megfoltoztam, hogy 128k-s a chip mérete, ne olvassa ki 0x1FFFF7E0 címről
- letöltöttem a legfrissebb st-link utility-t, van egy AllPlatform része, java-ban írva
- Az STLinkUpgrade.jar egy zip fájl, tartalmazza a firmware-eket, az f2_4.bin a firmware neve
- az st-decrypt program segítségével dekódoltam a firmware-t (feltörtem)
- a firmware akkor érvényes, ha az utolsó 4 byte a 0x0801FFFC címen 0xD3 0x27 0x00 0xA5
írtam egy szkriptet, ami
- törli a chipet
- 0x08000000 címtől kiírja a megfoltozott bootloadert
- 0x08004000 címtől feltölti a feltört firmware-t
- 0x0801FFFC-n meg beállítja az utolsó 4 byte-ot érvényesnek

Ezután a kód elindul, hogy működik-e, még kérdéses. Mindenesetre jó szórakozás volt egy kicsit warezolni.
(#) csabeszq hozzászólása Vas, 21:23 / 1
 
A fentebb csatolt firmware-t sikerült végigtesztelni.
- ment a feltöltés, lekérés
- ment a debug
- szépen RESET-elt, jól adta az NRST-t
- jól ment az SWO
- ment az USART RX/TX
- szépen kapcsolgatta a LED-eket
- ment a drag & drop feltöltés a csatolt meghajtón keresztül

Az ST-LINK V2/1 firmware érdekessége, hogy nincs benne SWIMM (STM8) támogatás, a Nucleo panel része. Nagyon frankó, hogy van benne kétirányú USART átalakító is, emellett ha egy .bin kiterjesztésű bináris fájlt dobok a meghajtóba, akkor feltölti azt. Úgy megy, hogy mondjuk a progim.bin-t felmásolom, bár hex fájlokra nálam nem ment.

A JTAG-et nem próbáltam ki, az USB reenumerationt sem. Lehet, hogy valamikor érdemes lesz egy próba panelt legyártani, ami az ST-LINK V2/1-es kivezetéseket tartalmazza blue pill-en.

Egy próbát szerintem mindenkinél megér, mert nem a tipikus ST-LINK-es cucc.
Kapcsolási rajz itt.
A hozzászólás módosítva: Vas, 21:24
(#) benjami válasza csabeszq hozzászólására (») Vas, 23:24 /
 
És olyan hekkelt st-link firmware-röl nem tudsz amivel fel lehet programozni a magát 64kB-osnak valló, de valójában 128kB-os f103C8T6-t teljes memóriaterületét?
(#) csabeszq válasza benjami hozzászólására (») Hé, 8:26 /
 
Én linuxot használok, ott az st-flash-től az openocd-n keresztül minden szét van peccselve.

Windows alatt megnyitottam az ST-Link Utility-t:
- File -> Open file... -> 128k-s hex fájl neve
- Target -> Program & Verify -> Start

Akadékoskodás nélkül fölment a cucc. Kiírta, hogy a chip 64k, viszont tovább már nem érdekli. Az ST-Link Utility simán írja olvassa a 128k-t.
(#) benjami válasza csabeszq hozzászólására (») Hé, 10:55 /
 
Köszi, az ST-Link Utility alatt már működik, most ráálltam az openocd hekkelésére, hogy debuggolni is tudjam a "System Workbench for STM32 (alias eclipse)" alól.
(#) benjami válasza benjami hozzászólására (») Hé, 15:01 /
 
Sikerült az openocd-t is meghekkelni. A "stm32f1x.cfg"-ben kell a következő sor lecserélni:
  1. flash bank $_FLASHNAME stm32f1x 0x08000000 0 0 0 $_TARGETNAME

erre:
  1. flash bank $_FLASHNAME stm32f1x 0 0x20000 0 0 $_TARGETNAME
(#) csabeszq válasza benjami hozzászólására (») Hé, 21:59 /
 
Nem értem, amit csináltál. Én magát az openocd kódját patcheltem meg.
Megnézi az IC típusát és 128k-ra állítja a memóriát.

  1. diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c
  2. index d4467076..3d33599a 100644
  3. --- a/src/flash/nor/stm32f1x.c
  4. +++ b/src/flash/nor/stm32f1x.c
  5. @@ -962,6 +962,8 @@ static int stm32x_probe(struct flash_bank *bank)
  6.  
  7.         /* get flash size from target. */
  8.         retval = stm32x_get_flash_size(bank, &flash_size_in_kb);
  9. +       if( device_id == 0x20036410 )
  10. +               flash_size_in_kb = max_flash_size_in_kb;
  11.  
  12.         /* failed reading flash size or flash size invalid (early silicon),
  13.          * default to max target family */
(#) csabeszq hozzászólása Hé, 22:07 /
 
Az ST-Link V2.1-hez egy javított hex fájlt küldenék.

A régivel az volt a baj, hogy az ST-Link Utility-vel nem ment, a többi programmal igen.
A most csatolt hex fájlt már rendesen kezeli az ST-Link utility.

A firmware frissítés továbbra sem fog menni, de nem érdekel egyelőre. Akinek nem tetszik vegyen STM32F103RBT6-os chipet, ne blue pillen futtassa.

Ez az áramkör 2.1-es bootloadert használ, amihez a fentebb linkelt kapcsolási rajzon szükséges az USB re-enumerationt megcsinálni. Megy anélkül is, csak kevésbé. Én az USB DP-t (PA12) blue pill-lel összekötöttem a PA15-tel egy 1.5 kohm-os ellenálláson keresztül. Működik, de normális panelre ilyet lehetőleg ne.

A lényeg: amikor PA15 alacsony, az USB D+-t alacsonyra húzza, mikor visszakerül magasba, akkor elindul az enumeration (ilyenkor nem piszkálja a D+-t).
A hozzászólás módosítva: Hé, 22:10
(#) benjami válasza csabeszq hozzászólására (») Hé, 23:50 /
 
Ja, hogy te az openocd forráskódjába nyúltál bele és újrafordítottad? Elég csak az openocd konfigurációs fájlokba belenyúlni, az egyszerűbb: pl. így .
(#) roleez válasza csatti2 hozzászólására (») Kedd, 7:41 /
 
Köszönöm!
CP2102-vel közvetlenül a uC lábairól megy!
(#) roleez hozzászólása 8:55 /
 
Olyat vettem észre, hogy kiküldöm az adatokat PC-ről, és mintha a board nem venné, nem történik semmi (20-ből kb. kettőt figyelmen kívül hagy; 1 db csomagméret 3 byte)
IRQ-ban van a soros. (USB->CP2102->uC)
Ha a végtelen hurokba (ahol meghívom a soros adatainak feldolgozását) beteszek egy delay-t (~100 ms) akkor sokkal kevesebbszer "veszti" el a bejövő adatokat, mint ha nem lenne delay.
Nem értem.
Találkoztatok már ilyennel?
(#) csatti2 válasza roleez hozzászólására (») 10:00 /
 
Több problémát is látok a kódoddal (feltéve, ha még mindig nagyjából az, amit múltkor feltettél).
1, Az olyan változókat, amiket megszakításokban kezelsz volatile-nak kell deklarálni.
2, Minek deklarálsz változókat globálisnak, ha lokálisan használod csak? (pl. rxchar)
3, Folyamatosan nullázod a hol változót a Sorostask elején, miközben ez adja meg a csomag aktuális byte-jának pozicióját a pufferben (ennek így semmi értelme, hmm, talán a Soros-terv része? ). Tedd az első sorba a readRX változó ellenőrzését és ugorj ki a függvényből ha igaz.

4, Felejtsd el a régi reflexeidet és használd a DMA-t az adatküldésre és fogadásra, sima pufferrel az adatküldésre és körkörös puffer-el a fogadásra. Jól megválasztott puffer esetén nem lesz többet csomagvesztés.
(#) roleez válasza csatti2 hozzászólására (») 10:31 /
 
igen, még az a kód.
Köszönöm. Az első 3 pontot azonnal átnézem.
A 4-ről semmi infóm. DMA nem fix számú adat mozgatására van? Itt meg lesz 4 byte hosszú
parancs is. ( nem csak 3) Van erre vmi kód példád?
(#) csatti2 válasza roleez hozzászólására (») 11:02 / 1
 
A körkörös puffer esetén addig tölti, amíg be nem telik, majd kezdi az elejétől. Feldolgozásához használhatod a puffer tele, illetve félig tele megszakításokat, ha ennél gyakrabban akarod kezelni, akkor pedig a DMA számlálójából kiolvashatod, az aktuális pozíciót és ebből, illetve a legutóbbi feldolgozás pozíciójából megkapható az újonnan érkezett szakasz.

Mintát nem tudok adni, mert te még a régi már nem támogatott SPL-t használod az én jelenlegi kódjaim pedig már a LowLayer-en alapszanak RTOS beágyazással.

Van viszont régről némi körkörös ADC kódom, illetve nem blokkoló (bizonyos határok között) debug üzengetőm:

  1. Definíciók:
  2. #define CHARGE_GPIO                       GPIOC
  3. #define CHARGE_GPIO_CLK                   RCC_APB2Periph_GPIOC
  4. #define CHARGE_Enable_Pin                 GPIO_Pin_14
  5. #define CHARGE_ADC_GPIO                   GPIOB
  6. #define CHARGE_ADC_GPIO_CLK               RCC_APB2Periph_GPIOB
  7. #define CHARGE_ADC_Voltage_Pin            GPIO_Pin_0
  8. #define CHARGE_ADC_Current_Pin            GPIO_Pin_1
  9. #define CHARGE_ADC_MASTER                 ADC1              // Dual ADC mode
  10. #define CHARGE_ADC_MASTER_CLK             RCC_APB2Periph_ADC1
  11. #define CHARGE_ADC_SLAVE                  ADC2              // Dual ADC mode
  12. #define CHARGE_ADC_SLAVE_CLK              RCC_APB2Periph_ADC2
  13. #define CHARGE_ADC_SampleTime             ADC_SampleTime_41Cycles5
  14. #define CHARGE_ADC_DMA                    DMA1
  15. #define CHARGE_ADC_DMA_CLK                RCC_AHBPeriph_DMA1
  16. #define CHARGE_ADC_DMA_Channel            DMA1_Channel1
  17. #define CHARGE_ADC_DMA_IRQn               DMA1_Channel1_IRQn
  18. #define CHARGE_ADC_DMA_IRQHandler         DMA1_Channel1_IRQHandler
  19. #define CHARGE_ADC_DMA_FLAG               DMA1_FLAG_TC1
  20. #define CHARGE_ADC_DR_Base                0x4001244C        // &ADC1->DR
  21. #define CHARGE_ADC_Channel_Vrefint        ADC_Channel_17
  22. #define CHARGE_ADC_Channel_Tempref        ADC_Channel_16
  23. #define CHARGE_ADC_Channel_Voltage        ADC_Channel_8
  24. #define CHARGE_ADC_Channel_Current        ADC_Channel_9
  25. #define CHARGE_PWM_Frequency              12000
  26. #define CHARGE_PWM                        TIM1
  27. #define CHARGE_PWM_CLK                    RCC_APB2Periph_TIM1
  28. #define CHARGE_PWM_GPIO                   GPIOA
  29. #define CHARGE_PWM_GPIO_CLK               (RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO)
  30. #define CHARGE_PWM_VoltageCtrl_Pin        GPIO_Pin_11
  31. #define CHARGE_PWM_DutyCycle              TIM1->CCR4


Konfiguráció némi hulladékkal:
  1. GPIO_InitTypeDef GPIO_InitStructure;
  2.   DMA_InitTypeDef DMA_InitStructure;
  3.   ADC_InitTypeDef ADC_InitStructure;
  4.   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  5.   TIM_OCInitTypeDef  TIM_OCInitStructure;
  6.   TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
  7.   uint16_t prescalerValue, period;
  8.  
  9.   // Enable PWM timer clock
  10.   RCC_APB2PeriphClockCmd(CHARGE_PWM_CLK, ENABLE);
  11.  
  12.   // Enable PWM GPIO clock
  13.   RCC_APB2PeriphClockCmd(CHARGE_PWM_GPIO_CLK, ENABLE);
  14.  
  15.   // PWM voltage control
  16.   GPIO_InitStructure.GPIO_Pin = CHARGE_PWM_VoltageCtrl_Pin;
  17.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  18.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  19.  
  20.   GPIO_Init(CHARGE_PWM_GPIO, &GPIO_InitStructure);
  21.  
  22.   // Compute the prescaler value
  23.   prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
  24.   // Compute the period
  25.   period = (uint16_t)(24000000 / CHARGE_PWM_Frequency) - 1;
  26.   Charge_SetVoltageCtrlPWMPeriod(period);
  27.  
  28.   // Time base configuration
  29.   TIM_TimeBaseStructure.TIM_Period = period;
  30.   TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue;
  31.   TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  32.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  33.   TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  34.  
  35.   TIM_TimeBaseInit(CHARGE_PWM, &TIM_TimeBaseStructure);
  36.  
  37.   // PWM Mode configuration
  38.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  39.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  40.   TIM_OCInitStructure.TIM_Pulse = period;
  41.  
  42.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  43.  
  44.   TIM_OC4Init(CHARGE_PWM, &TIM_OCInitStructure);
  45.  
  46.   TIM_OC4PreloadConfig(CHARGE_PWM, TIM_OCPreload_Enable);
  47.  
  48.   TIM_ARRPreloadConfig(CHARGE_PWM, ENABLE);
  49.  
  50.   // Automatic Output enable, Break, dead time and lock configuration
  51.   TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
  52.   TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
  53.   TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
  54.   TIM_BDTRInitStructure.TIM_DeadTime = 0x05;
  55.   TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
  56.   TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
  57.   TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
  58.   TIM_BDTRConfig(CHARGE_PWM, &TIM_BDTRInitStructure);
  59.  
  60.   // Enable counter
  61.   TIM_Cmd(CHARGE_PWM, ENABLE);
  62.   CHARGE_PWM_DutyCycle = period;
  63.   TIM_CtrlPWMOutputs(CHARGE_PWM, ENABLE);
  64.  
  65.   /*
  66.         Analog input and ADC configuration
  67.   */
  68.   // Analog inputs
  69.   GPIO_InitStructure.GPIO_Pin = CHARGE_ADC_Voltage_Pin | CHARGE_ADC_Current_Pin;
  70.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  71.   GPIO_Init(CHARGE_ADC_GPIO, &GPIO_InitStructure);
  72.  
  73.   // Enable ADC DMA clock
  74.   RCC_AHBPeriphClockCmd(CHARGE_ADC_DMA_CLK, ENABLE);
  75.  
  76.   // Enable master and slave ADCs and GPIO clock
  77.   RCC_APB2PeriphClockCmd(CHARGE_ADC_MASTER_CLK | CHARGE_ADC_SLAVE_CLK |
  78.                          CHARGE_ADC_GPIO_CLK, ENABLE);
  79.  
  80.   // ADC DMA configuration
  81.   DMA_DeInit(CHARGE_ADC_DMA_Channel);
  82.   DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&CHARGE_ADC_MASTER->DR;//CHARGE_ADC_DR_Base
  83.   DMA_InitStructure.DMA_MemoryBaseAddr = bufferAddr;
  84.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  85.   DMA_InitStructure.DMA_BufferSize = ADC_BUFFSIZE;
  86.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  87.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  88.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  89.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  90.   DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  91.   DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  92.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  93.   DMA_Init(CHARGE_ADC_DMA_Channel, &DMA_InitStructure);
  94.   // ADC DMA interrupt configuration
  95.   //DMA_ITConfig(CHARGE_ADC_DMA_Channel, DMA_IT_TC, ENABLE);
  96.   //CHARGE_ADC_DMA_NVIC_Configuration();
  97.   // Enable ADC DMA Channel
  98.   DMA_Cmd(CHARGE_ADC_DMA_Channel, ENABLE);
  99.  
  100.   // Master ADC configuration
  101.   ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
  102.   ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  103.   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  104.   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  105.   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  106.   ADC_InitStructure.ADC_NbrOfChannel = 2;
  107.   ADC_Init(CHARGE_ADC_MASTER, &ADC_InitStructure);
  108.   // Regular channels configuration
  109.   ADC_RegularChannelConfig(CHARGE_ADC_MASTER, CHARGE_ADC_Channel_Vrefint, 1, CHARGE_ADC_SampleTime);
  110.   ADC_RegularChannelConfig(CHARGE_ADC_MASTER, CHARGE_ADC_Channel_Tempref, 2, CHARGE_ADC_SampleTime);
  111.   // Enable master ADC DMA
  112.   ADC_DMACmd(CHARGE_ADC_MASTER, ENABLE);
  113.  
  114.   // Slave ADC configuration
  115.   ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
  116.   ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  117.   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  118.   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  119.   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  120.   ADC_InitStructure.ADC_NbrOfChannel = 2;
  121.   ADC_Init(CHARGE_ADC_SLAVE, &ADC_InitStructure);
  122.   // Regular channels configuration
  123.   ADC_RegularChannelConfig(CHARGE_ADC_SLAVE, CHARGE_ADC_Channel_Voltage, 1, CHARGE_ADC_SampleTime);
  124.   ADC_RegularChannelConfig(CHARGE_ADC_SLAVE, CHARGE_ADC_Channel_Current, 2, CHARGE_ADC_SampleTime);
  125.   // Enable slave ADC external trigger conversion
  126.   ADC_ExternalTrigConvCmd(CHARGE_ADC_SLAVE, ENABLE);
  127.  
  128.   // Enable master ADC
  129.   ADC_Cmd(CHARGE_ADC_MASTER, ENABLE);
  130.   // Enable Vrefint and temperature
  131.   ADC_TempSensorVrefintCmd(ENABLE);
  132.  
  133.   // Reset master ADC calibration
  134.   ADC_ResetCalibration(CHARGE_ADC_MASTER);
  135.   // Wait until reset done
  136.   while(ADC_GetResetCalibrationStatus(CHARGE_ADC_MASTER));
  137.   // Start master ADC calibration
  138.   ADC_StartCalibration(CHARGE_ADC_MASTER);
  139.   // Check the end of master ADC calibration
  140.   while(ADC_GetCalibrationStatus(CHARGE_ADC_MASTER));
  141.  
  142.   // Enable slave ADC
  143.   ADC_Cmd(CHARGE_ADC_SLAVE, ENABLE);
  144.  
  145.   // Reset slave ADC calibration
  146.   ADC_ResetCalibration(CHARGE_ADC_SLAVE);
  147.   // Wait until reset done
  148.   while(ADC_GetResetCalibrationStatus(CHARGE_ADC_SLAVE));
  149.   // Start slave ADC calibration
  150.   ADC_StartCalibration(CHARGE_ADC_SLAVE);
  151.   // Check the end of slave ADC calibration
  152.   while(ADC_GetCalibrationStatus(CHARGE_ADC_SLAVE));
  153.  
  154.   // Start master ADC Software Conversion
  155.   ADC_SoftwareStartConvCmd(CHARGE_ADC_MASTER, ENABLE);
  156.  
  157.   /*
  158.         DC/DC Converter enable and voltage control
  159.   */
  160.  
  161.   RCC_APB2PeriphClockCmd(CHARGE_GPIO_CLK, ENABLE);
  162.  
  163.   // DC/DC converter enable
  164.   GPIO_InitStructure.GPIO_Pin = CHARGE_Enable_Pin;
  165.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  166.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  167.   GPIO_Init(CHARGE_GPIO, &GPIO_InitStructure);


Ez itt a feldolgozó rész egy darabkája, hagyd figyelmen kívül a nem használt változókat (lusta vagyok). A kód feldolgozza a DMA által az ADC-től érkezett adatokat (szummázza csatornánként majd osztja a mintavételek számával ezzel egy szimpla szűrést végezve), majd eltolja a feldolgozottságot jelző pointert.
  1. uint16_t V, I, i;
  2.   static uint16_t sp = VOUT_SP;
  3.   static uint16_t adcPos = 0;
  4.   uint16_t dmaCount = ((ADC_BUFFSIZE - (uint16_t)(CHARGE_ADC_DMA_Channel->CNDTR)) / 2);
  5.   uint32_t cVal1 = 0, cVal2 = 0, cVal3 = 0, cVal4 = 0;
  6.   __IO uint32_t *adcBuff;
  7.   uint16_t cnt = 0;
  8.   static uint32_t srcnt = 0;
  9.   static uint32_t currentSum = 0, voltageSum = 0, powerSum = 0;
  10.   static uint16_t displayCnt = 0;
  11.  
  12.   Watchdog_LoopMonitoringReset();
  13.  
  14.   adcBuff = _adcRAW + (adcPos * 2);
  15.   if (dmaCount < adcPos) {
  16.     for (i = adcPos; i < ADC_BUFFSIZE / 2; i++)
  17.     {
  18.       cVal1+= *adcBuff >> 16;
  19.       cVal2+= *adcBuff++ & 0xFFFF;
  20.       cVal3+= *adcBuff >> 16;
  21.       cVal4+= *adcBuff++ & 0xFFFF;
  22.       cnt++;
  23.     }
  24.     adcPos = 0;
  25.     adcBuff = _adcRAW;
  26.   }
  27.   for (i = adcPos; i < dmaCount; i++)
  28.   {
  29.     cVal1+= *adcBuff >> 16;
  30.     cVal2+= *adcBuff++ & 0xFFFF;
  31.     cVal3+= *adcBuff >> 16;
  32.     cVal4+= *adcBuff++ & 0xFFFF;
  33.     cnt++;
  34.   }
  35.   _filteredVoltageRAW = (uint16_t)(cVal1 / cnt);
  36.   _filteredVrefRAW =    (uint16_t)(cVal2 / cnt);
  37.   _filteredCurrentRAW = (uint16_t)(cVal3 / cnt);
  38.   if (_filteredCurrentRAW > ZEROCURRENTOFFSET) _filteredCurrentRAW-= ZEROCURRENTOFFSET;
  39.   else _filteredCurrentRAW = 0;
  40.   _filteredTempRAW =    (uint16_t)(cVal4 / cnt);
  41.   adcPos = dmaCount;


USART példa:
  1. #define USART_DEBUG                       USART1
  2. #define USART_DEBUG_GPIO                  GPIOA
  3. #define USART_DEBUG_CLK                   RCC_APB2Periph_USART1
  4. #define USART_DEBUG_GPIO_CLK              RCC_APB2Periph_GPIOA
  5. #define USART_DEBUG_RxPin                 GPIO_Pin_10
  6. #define USART_DEBUG_TxPin                 GPIO_Pin_9
  7. #define USART_DEBUG_IRQn                  USART1_IRQn
  8. #define USART_DEBUG_IRQHandler            USART1_IRQHandler
  9. #define USART_DEBUG_DMA_CLK               RCC_AHBPeriph_DMA1
  10. #define USART_DEBUG_DMA_Channel           DMA1_Channel4     // Depends on USART! See DMA request mapping
  11. #define USART_DEBUG_DMA_IRQn              DMA1_Channel4_IRQn
  12. #define USART_DEBUG_DMA_IRQHandler        DMA1_Channel4_IRQHandler
  13. #define USART_DEBUG_DMA_FLAG              DMA1_FLAG_TC4


  1. void USART_DEBUG_DMA_NVIC_Configuration(void)
  2. {
  3.   NVIC_InitTypeDef  NVIC_InitStructure;
  4.  
  5.   NVIC_InitStructure.NVIC_IRQChannel = USART_DEBUG_DMA_IRQn;
  6.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
  7.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  8.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  9.   NVIC_Init(&NVIC_InitStructure);
  10. }
  11.  
  12. // USART - DEBUG interrupt
  13.  
  14. void USART_DEBUG_NVIC_Configuration(void)
  15. {
  16.   NVIC_InitTypeDef  NVIC_InitStructure;
  17.  
  18.   NVIC_InitStructure.NVIC_IRQChannel = USART_DEBUG_IRQn;
  19.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
  20.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  21.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  22.   NVIC_Init(&NVIC_InitStructure);
  23. }
  24.  
  25. void USART_DEBUG_Config(uint32_t bufferAddr)
  26. {
  27.   GPIO_InitTypeDef GPIO_InitStruct;
  28.   USART_InitTypeDef USART_InitStruct;
  29.   DMA_InitTypeDef DMA_InitStructure;
  30.  
  31.   RCC_APB2PeriphClockCmd(USART_DEBUG_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);
  32.   RCC_APB2PeriphClockCmd(USART_DEBUG_CLK, ENABLE);
  33.  
  34.   //USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
  35.  
  36.  
  37.   // PA.09(Tx)
  38.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
  39.   GPIO_InitStruct.GPIO_Pin = USART_DEBUG_TxPin;
  40.   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  41.   GPIO_Init(USART_DEBUG_GPIO, &GPIO_InitStruct);
  42.  
  43.   // PA.10(Rx)
  44.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  45.   GPIO_InitStruct.GPIO_Pin = USART_DEBUG_RxPin;
  46.   GPIO_Init(USART_DEBUG_GPIO, &GPIO_InitStruct);
  47.  
  48.   // Enable the DMA Clock
  49.   RCC_AHBPeriphClockCmd(USART_DEBUG_DMA_CLK, ENABLE);
  50.   DMA_DeInit(USART_DEBUG_DMA_Channel);
  51.   DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART_DEBUG->DR;//USART_DEBUG_DR_Base;
  52.   DMA_InitStructure.DMA_MemoryBaseAddr = bufferAddr;
  53.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  54.   DMA_InitStructure.DMA_BufferSize = 0;
  55.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  56.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  57.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  58.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  59.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  60.   DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
  61.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  62.   DMA_Init(USART_DEBUG_DMA_Channel, &DMA_InitStructure);
  63.   DMA_ITConfig(USART_DEBUG_DMA_Channel, DMA_IT_TC, ENABLE);
  64.   USART_DEBUG_DMA_NVIC_Configuration();
  65.   USART_InitStruct.USART_BaudRate = USART_DEBUG_BAUDRATE;
  66.   USART_InitStruct.USART_StopBits = USART_StopBits_1;
  67.   USART_InitStruct.USART_WordLength = USART_WordLength_8b;
  68.   USART_InitStruct.USART_Parity = USART_Parity_No;
  69.   USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  70.   USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
  71.   USART_Init(USART_DEBUG, &USART_InitStruct);
  72.   USART_DMACmd(USART_DEBUG, USART_DMAReq_Tx, ENABLE);
  73.   USART_ITConfig(USART_DEBUG,USART_IT_RXNE,ENABLE);
  74.   USART_DEBUG_NVIC_Configuration();
  75.   USART_Cmd(USART_DEBUG, ENABLE);
  76. }


  1. uint8_t _silent;
  2. static __IO uint16_t _usartBufferPos;
  3. static __IO uint16_t _usartSending;
  4. static __IO uint8_t _usartBuffer;
  5.  
  6. static char __IO _debugBuffer1[USART_DEBUG_BUFFERSIZE / 2];
  7. static char __IO _debugBuffer2[USART_DEBUG_BUFFERSIZE / 2];
  8.  
  9.  
  10. #ifdef USARTDEBUG
  11. static void _usartSend(const char *str)
  12. {
  13.   char *target;
  14.  
  15.   DisableIRQ();
  16.   size_t l = strlen(str);
  17.   if (!l) {
  18.     EnableIRQ();
  19.     return;
  20.   }
  21.  
  22.   if ((l + _usartBufferPos + 1) > (USART_DEBUG_BUFFERSIZE/2)) {
  23.     EnableIRQ();
  24.     return; // Drop messages
  25.   }
  26.  
  27.   if (_usartBuffer) target = (char*)_debugBuffer2;
  28.   else target = (char*)_debugBuffer1;
  29.   target += _usartBufferPos;
  30.   strcpy(target, str);
  31.  
  32.   _usartBufferPos += l;
  33.   if (_usartSending) {
  34.     EnableIRQ();
  35.     return;
  36.   }
  37.   DMA_ClearFlag(USART_DEBUG_DMA_FLAG);
  38.   DMA_Cmd(USART_DEBUG_DMA_Channel, DISABLE);
  39.   DMA_SetCurrDataCounter(USART_DEBUG_DMA_Channel, l);
  40.   if (_usartBuffer) {
  41.     USART_DEBUG_DMA_Channel->CMAR = (uint32_t)_debugBuffer2;
  42.   } else {
  43.     USART_DEBUG_DMA_Channel->CMAR = (uint32_t)_debugBuffer1;
  44.   }
  45.   _usartSending = l;
  46.   _usartBufferPos = 0;
  47.   _usartBuffer = !_usartBuffer;
  48.   DMA_ITConfig(USART_DEBUG_DMA_Channel, DMA_IT_TC, ENABLE);
  49.   DMA_Cmd(USART_DEBUG_DMA_Channel, ENABLE);
  50.   EnableIRQ();
  51. }
  52.  
  53. void DBG_BlockPrint(const char *str)
  54. {
  55.   DisableIRQ();
  56.   size_t l = strlen(str);
  57.   int i;
  58.   for (i = 0; i < l; i++) {
  59.     USART_SendData(USART1,*(char *)(str + i));
  60.     while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
  61.   }
  62.   EnableIRQ();
  63. }
  64.  
  65. ISR(USART_DEBUG_DMA_IRQHandler)
  66. {
  67.   DisableIRQ();
  68.   DMA_ClearFlag(USART_DEBUG_DMA_FLAG);
  69.   DMA_Cmd(USART_DEBUG_DMA_Channel, DISABLE);
  70.   if (!_usartBufferPos) {
  71.     _usartSending = 0;
  72.     DMA_ITConfig(USART_DEBUG_DMA_Channel, DMA_IT_TC, DISABLE);
  73.     EnableIRQ();
  74.     __DSB();
  75.     return;
  76.   }
  77.   DMA_SetCurrDataCounter(USART_DEBUG_DMA_Channel, _usartBufferPos);
  78.   if (_usartBuffer) {
  79.     USART_DEBUG_DMA_Channel->CMAR = (uint32_t)_debugBuffer2;
  80.   } else {
  81.     USART_DEBUG_DMA_Channel->CMAR = (uint32_t)_debugBuffer1;
  82.   }
  83.   _usartSending = _usartBufferPos;
  84.   _usartBufferPos = 0;
  85.   _usartBuffer = !_usartBuffer;
  86.   DMA_Cmd(USART_DEBUG_DMA_Channel, ENABLE);
  87.   EnableIRQ();
  88.   __DSB();
  89. }
  90.  
  91. void DBG_Init(void)
  92. {
  93.   USART_DEBUG_Config((uint32_t)_debugBuffer1);
  94.   _usartSend(TXT("*** LOG STARTED ***\r\n"));
  95. }
  96.  
  97. void DBG_PrintC(const char *str, uint16_t color)
  98. {
  99.   char escstr[8] = "\x1B[36;1m";
  100.   switch (color) {
  101.     case LCD_BLACK:
  102.       escstr[3] = '0';
  103.       break;
  104.     case LCD_RED:
  105.       escstr[3] = '1';
  106.       break;
  107.     case LCD_GREEN:
  108.       escstr[3] = '2';
  109.       break;
  110.     case LCD_YELLOW:
  111.       escstr[3] = '3';
  112.       break;
  113.     case LCD_BLUE:
  114.       escstr[3] = '4';
  115.       break;
  116.     case LCD_CYAN:
  117.       escstr[3] = '6';
  118.       break;
  119.     case LCD_WHITE:
  120.       escstr[3] = '7';
  121.       break;
  122.     default:
  123.       escstr[3] = '5';
  124.       break;
  125.   }
  126.   _usartSend(escstr);
  127.   _usartSend(str);
  128.   _usartSend(TXT("\x1B[0m"));
  129. }
  130.  
  131. void DBG_Print(const char *str)
  132. {
  133.   _usartSend(str);
  134. }
  135.  
  136. void DBG_PrintLn(const char *str)
  137. {
  138.   _usartSend(str);
  139.   _usartSend(TXT("\r\n"));
  140. }
  141.  
  142. void DBG_PrintLnC(const char *str, uint16_t color)
  143. {
  144.   DBG_PrintC(str, color);
  145.   _usartSend(TXT("\r\n"));
  146. }
  147.  
  148. void DBG_TimeRef(void)
  149. {
  150.   char str[20];
  151.  
  152.   ltoa(str, SysTick_GetReference(), 10);
  153.   DBG_Print(TXT("["));
  154.   DBG_PrintC(str, LCD_YELLOW);
  155.   DBG_Print(TXT("]:"));
  156. #ifdef SCHEDULER_NAMEDTASKS
  157.   DBG_PrintC(Scheduler_GetActiveTaskName(), LCD_WHITE);
  158.   DBG_Print(TXT(":"));
  159. #endif
  160. }
  161.  
  162. void DBG_PrintChar(char c)
  163. {
  164.   char s[2];
  165.  
  166.   s[0] = c;
  167.   s[1] = 0;
  168.   _usartSend(s);
  169. }
  170.  
  171. void DBG_Ok(void)
  172. {
  173.   _usartSend(TXT("\x1B[32;1mOk!\x1B[0m\r\n"));
  174. }
  175.  
  176. void DBG_Fail(void)
  177. {
  178.   _usartSend(TXT("\x1B[31;1mFailed!\x1B[0m\r\n"));
  179. }
  180. #endif
A hozzászólás módosítva: 11:04
(#) roleez válasza csatti2 hozzászólására (») 12:10 /
 
Köszönöm.
Lesz mit értelmeznem.
Következő: »»   106 / 106
Bejelentkezés

Belépés

Hirdetés
Frissek
2017. Nov, 22. Sze
15:46:26
Jelenleg 346 fő olvassa az oldalt
Online tagok:
Lapoda.hu     XDT.hu     HEStore.hu