main.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424
  1. /*
  2. drv8871 DC motor
  3. Example for the STM32L031 Eval Board with 128x64 OLED at PA13/PA14
  4. IN_A: PA1 / AF2: TIM2_CH2
  5. IN_B: PB1 / AF?: TIM2_CH4
  6. VarRes: PA5 / ADC CH5
  7. Voltage sense: PA6 / ADC CH6
  8. 0.2ms IRQ: PA7 (TIM22_CH2) (optional)
  9. IN_A IN_B OUT_A OUT_B
  10. 1 0 1 0
  11. 0 1 0 1
  12. 0 0 0 0
  13. 1 1 HiZ HiZ
  14. state machine
  15. */
  16. #include <stdio.h>
  17. #include "stm32l031xx.h"
  18. #include "delay.h"
  19. #include "u8g2.h"
  20. /*=======================================================================*/
  21. /* external functions */
  22. uint8_t u8x8_gpio_and_delay_stm32l0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
  23. /*=======================================================================*/
  24. /* global variables */
  25. u8g2_t u8g2; // u8g2 object
  26. uint8_t u8g2_x, u8g2_y; // current position on the screen
  27. volatile unsigned long SysTickCount = 0;
  28. /*=======================================================================*/
  29. /* I2C */
  30. volatile unsigned char i2c_mem[256]; /* contains data, which read or written */
  31. volatile unsigned char i2c_idx; /* the current index into i2c_mem */
  32. volatile unsigned char i2c_is_write_idx; /* write state */
  33. /*
  34. i2c_mem[0] input: speed
  35. i2c_mem[1] not used
  36. i2c_mem[2] = adc_diff_noise_per_sample_raw & 255 // small value: stop, high value: running
  37. i2c_mem[3] = adc_diff_noise_per_sample_raw>>8;
  38. i2c_mem[4] = adc_diff_noise_per_sample_filt & 255 // small value: stop, high value: running
  39. i2c_mem[5] = adc_diff_noise_per_sample_filt>>8;
  40. i2c_mem[6] = adc_max_raw & 255; // speed value, higher values are slower
  41. i2c_mem[7] = adc_max_raw>>8; // speed value, higher values are slower
  42. i2c_mem[8] = adc_max_filt & 255; // speed value, higher values are slower
  43. i2c_mem[9] = adc_max_filt>>8; // speed value, higher values are slower
  44. */
  45. /*=======================================================================*/
  46. void __attribute__ ((interrupt, used)) SysTick_Handler(void)
  47. {
  48. SysTickCount++;
  49. }
  50. void setHSIClock()
  51. {
  52. /* test if the current clock source is something else than HSI */
  53. if ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
  54. {
  55. /* enable HSI */
  56. RCC->CR |= RCC_CR_HSION;
  57. /* wait until HSI becomes ready */
  58. while ( (RCC->CR & RCC_CR_HSIRDY) == 0 )
  59. ;
  60. /* enable the HSI "divide by 4" bit */
  61. RCC->CR |= (uint32_t)(RCC_CR_HSIDIVEN);
  62. /* wait until the "divide by 4" flag is enabled */
  63. while((RCC->CR & RCC_CR_HSIDIVF) == 0)
  64. ;
  65. /* then use the HSI clock */
  66. RCC->CFGR = (RCC->CFGR & (uint32_t) (~RCC_CFGR_SW)) | RCC_CFGR_SW_HSI;
  67. /* wait until HSI clock is used */
  68. while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
  69. ;
  70. }
  71. /* disable PLL */
  72. RCC->CR &= (uint32_t)(~RCC_CR_PLLON);
  73. /* wait until PLL is inactive */
  74. while((RCC->CR & RCC_CR_PLLRDY) != 0)
  75. ;
  76. /* set latency to 1 wait state */
  77. FLASH->ACR |= FLASH_ACR_LATENCY;
  78. /* At this point the HSI runs with 4 MHz */
  79. /* Multiply by 16 device by 2 --> 32 MHz */
  80. RCC->CFGR = (RCC->CFGR & (~(RCC_CFGR_PLLMUL| RCC_CFGR_PLLDIV ))) | (RCC_CFGR_PLLMUL16 | RCC_CFGR_PLLDIV2);
  81. /* enable PLL */
  82. RCC->CR |= RCC_CR_PLLON;
  83. /* wait until the PLL is ready */
  84. while ((RCC->CR & RCC_CR_PLLRDY) == 0)
  85. ;
  86. /* use the PLL has clock source */
  87. RCC->CFGR |= (uint32_t) (RCC_CFGR_SW_PLL);
  88. /* wait until the PLL source is active */
  89. while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
  90. ;
  91. SystemCoreClockUpdate(); /* Update SystemCoreClock global variable */
  92. }
  93. /*
  94. Enable several power regions: PWR, GPIOA
  95. This must be executed after each reset.
  96. */
  97. void startUp(void)
  98. {
  99. RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
  100. RCC->APB1ENR |= RCC_APB1ENR_PWREN; /* enable power interface (PWR) */
  101. PWR->CR |= PWR_CR_DBP; /* activate write access to RCC->CSR and RTC */
  102. SysTick->LOAD = (SystemCoreClock/1000)*50 - 1; /* 50ms task */
  103. SysTick->VAL = 0;
  104. SysTick->CTRL = 7; /* enable, generate interrupt (SysTick_Handler), do not divide by 2 */
  105. }
  106. /*=======================================================================*/
  107. /* u8x8 display procedures */
  108. void initDisplay(void)
  109. {
  110. /* setup display */
  111. u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R2, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_stm32l0);
  112. u8g2_InitDisplay(&u8g2);
  113. u8g2_SetPowerSave(&u8g2, 0);
  114. u8g2_SetFont(&u8g2, u8g2_font_6x12_tf);
  115. u8g2_ClearBuffer(&u8g2);
  116. u8g2_DrawStr(&u8g2, 0,12, "STM32L031");
  117. u8g2_DrawStr(&u8g2, 0,24, u8x8_u8toa(SystemCoreClock/1000000, 2));
  118. u8g2_DrawStr(&u8g2, 20,24, "MHz");
  119. u8g2_SendBuffer(&u8g2);
  120. u8g2_x = 0;
  121. u8g2_y = 0;
  122. }
  123. void outChar(uint8_t c)
  124. {
  125. u8g2_x+=u8g2_DrawGlyph(&u8g2, u8g2_x, u8g2_y, c);
  126. }
  127. void outStr(const char *s)
  128. {
  129. while( *s )
  130. outChar(*s++);
  131. }
  132. void outHexHalfByte(uint8_t b)
  133. {
  134. b &= 0x0f;
  135. if ( b < 10 )
  136. outChar(b+'0');
  137. else
  138. outChar(b+'a'-10);
  139. }
  140. void outHex8(uint8_t b)
  141. {
  142. outHexHalfByte(b >> 4);
  143. outHexHalfByte(b);
  144. }
  145. void outHex16(uint16_t v)
  146. {
  147. outHex8(v>>8);
  148. outHex8(v);
  149. }
  150. void outHex32(uint32_t v)
  151. {
  152. outHex16(v>>16);
  153. outHex16(v);
  154. }
  155. void setRow(uint8_t r)
  156. {
  157. u8g2_x = 0;
  158. u8g2_y = r;
  159. }
  160. /*=======================================================================*/
  161. /* ADC Init */
  162. void initADC(void)
  163. {
  164. //__disable_irq();
  165. /* ADC and DMA Clock Enable */
  166. RCC->APB2ENR |= RCC_APB2ENR_ADCEN; /* enable ADC clock */
  167. RCC->AHBENR |= RCC_AHBENR_DMAEN; /* enable DMA clock */
  168. __NOP(); /* let us wait for some time */
  169. __NOP(); /* let us wait for some time */
  170. /* ADC Reset */
  171. RCC->APB2RSTR |= RCC_APB2RSTR_ADCRST;
  172. __NOP(); /* let us wait for some time */
  173. __NOP(); /* let us wait for some time */
  174. RCC->APB2RSTR &= ~RCC_APB2RSTR_ADCRST;
  175. __NOP(); /* let us wait for some time */
  176. __NOP(); /* let us wait for some time */
  177. /* ADC Basic Setup */
  178. ADC1->IER = 0; /* do not allow any interrupts */
  179. ADC1->CFGR2 &= ~ADC_CFGR2_CKMODE; /* select HSI16 clock */
  180. ADC1->CFGR1 = ADC_CFGR1_RES_1; /* 8 bit resolution */
  181. ADC1->CR |= ADC_CR_ADVREGEN; /* enable ADC voltage regulator, probably not required, because this is automatically activated */
  182. ADC->CCR |= ADC_CCR_VREFEN; /* Wake-up the VREFINT */
  183. ADC->CCR |= ADC_CCR_TSEN; /* Wake-up the temperature sensor */
  184. __NOP(); /* let us wait for some time */
  185. __NOP(); /* let us wait for some time */
  186. /* CALIBRATION */
  187. if ((ADC1->CR & ADC_CR_ADEN) != 0) /* clear ADEN flag if required */
  188. {
  189. /* is this correct? i think we must use the disable flag here */
  190. ADC1->CR &= (uint32_t)(~ADC_CR_ADEN);
  191. }
  192. ADC1->CR |= ADC_CR_ADCAL; /* start calibration */
  193. while ((ADC1->ISR & ADC_ISR_EOCAL) == 0) /* wait for clibration finished */
  194. {
  195. }
  196. ADC1->ISR |= ADC_ISR_EOCAL; /* clear the status flag, by writing 1 to it */
  197. __NOP(); /* not sure why, but some nop's are required here, at least 4 of them */
  198. __NOP();
  199. __NOP();
  200. __NOP();
  201. __NOP();
  202. __NOP();
  203. }
  204. /*=======================================================================*/
  205. /* ADC Subtasks */
  206. #define ADC_SUB_TASK_NONE 0
  207. #define ADC_SUB_TASK_STOP_ADC 1
  208. #define ADC_SUB_TASK_ENABLE_ADC 2
  209. #define ADC_SUB_TASK_DISABLE_ADC 3
  210. #define ADC_SUB_TASK_CONVERSION 4
  211. #define ADC_SUB_STATE_INIT 0
  212. #define ADC_SUB_STATE_ACTIVE 1
  213. #define ADC_SUB_STATE_DONE 2
  214. volatile uint8_t adc_sub_task = ADC_SUB_TASK_NONE;
  215. volatile uint8_t adc_sub_state = ADC_SUB_STATE_INIT;
  216. uint16_t adc_result = 0;
  217. int adcIsSubDone(void)
  218. {
  219. if ( adc_sub_state == ADC_SUB_STATE_DONE )
  220. return 1;
  221. if ( adc_sub_task == ADC_SUB_TASK_NONE )
  222. return 1;
  223. return 0;
  224. }
  225. /*
  226. int adcStartSubTask(uint8_t msg)
  227. Args:
  228. msg: One of ADC_SUB_TASK_STOP_ADC, ADC_SUB_TASK_ENABLE_ADC, ADC_SUB_TASK_DISABLE_ADC
  229. Returns:
  230. 0 if there is any other subtask active
  231. */
  232. int adcStartSubTask(uint8_t msg)
  233. {
  234. if ( adcIsSubDone() == 0 )
  235. return 0;
  236. adc_sub_task = msg;
  237. adc_sub_state = ADC_SUB_STATE_INIT;
  238. return 1;
  239. }
  240. /*
  241. void adcExecSub(void)
  242. Desc:
  243. Executes any active ADC subtask. This can be executed inside an interrupt.
  244. */
  245. void adcExecSub(void)
  246. {
  247. switch(adc_sub_task)
  248. {
  249. case ADC_SUB_TASK_STOP_ADC:
  250. switch(adc_sub_state)
  251. {
  252. case ADC_SUB_STATE_INIT:
  253. /* STOP ANY ADC CONVERSION */
  254. ADC1->CR |= ADC_CR_ADSTP;
  255. adc_sub_state = ADC_SUB_STATE_ACTIVE;
  256. /* fall through */
  257. case ADC_SUB_STATE_ACTIVE:
  258. if ( (ADC1->CR & ADC_CR_ADSTP) == 0 )
  259. adc_sub_state = ADC_SUB_STATE_DONE;
  260. break;
  261. }
  262. break;
  263. case ADC_SUB_TASK_ENABLE_ADC:
  264. switch(adc_sub_state)
  265. {
  266. case ADC_SUB_STATE_INIT:
  267. /* ENABLE ADC (but do not start) */
  268. /* after the ADC is enabled, it must not be reconfigured */
  269. ADC1->ISR |= ADC_ISR_ADRDY; /* clear ready flag */
  270. ADC1->CR |= ADC_CR_ADEN; /* enable ADC */
  271. adc_sub_state = ADC_SUB_STATE_ACTIVE;
  272. /* fall through */
  273. case ADC_SUB_STATE_ACTIVE:
  274. if ( (ADC1->ISR & ADC_ISR_ADRDY) != 0 )
  275. adc_sub_state = ADC_SUB_STATE_DONE;
  276. break;
  277. }
  278. break;
  279. case ADC_SUB_TASK_DISABLE_ADC:
  280. switch(adc_sub_state)
  281. {
  282. case ADC_SUB_STATE_INIT:
  283. /* required to change the configuration of the ADC */
  284. /* Check for the ADEN flag. */
  285. /* Setting ADDIS will fail if the ADC is alread disabled. */
  286. if ((ADC1->CR & ADC_CR_ADEN) == 0)
  287. {
  288. adc_sub_state = ADC_SUB_STATE_DONE;
  289. }
  290. else
  291. {
  292. ADC1->CR |= ADC_CR_ADDIS;
  293. if ( (ADC1->CR & ADC_CR_ADDIS) == 0 )
  294. adc_sub_state = ADC_SUB_STATE_DONE;
  295. else
  296. adc_sub_state = ADC_SUB_STATE_ACTIVE;
  297. }
  298. break;
  299. case ADC_SUB_STATE_ACTIVE:
  300. if ((ADC1->CR & ADC_CR_ADEN) == 0)
  301. {
  302. adc_sub_state = ADC_SUB_STATE_DONE;
  303. }
  304. if ( (ADC1->CR & ADC_CR_ADDIS) == 0 )
  305. {
  306. adc_sub_state = ADC_SUB_STATE_DONE;
  307. }
  308. break;
  309. }
  310. break;
  311. case ADC_SUB_TASK_CONVERSION:
  312. switch(adc_sub_state)
  313. {
  314. case ADC_SUB_STATE_INIT:
  315. ADC1->CR |= ADC_CR_ADSTART; /* start the ADC conversion */
  316. adc_sub_state = ADC_SUB_STATE_ACTIVE;
  317. /* fall through */
  318. case ADC_SUB_STATE_ACTIVE:
  319. if ( (ADC1->ISR & ADC_ISR_EOC) != 0 )
  320. {
  321. adc_sub_state = ADC_SUB_STATE_DONE;
  322. adc_result = ADC1->DR;
  323. }
  324. break;
  325. }
  326. break;
  327. }
  328. }
  329. /* STOP ANY ADC CONVERSION */
  330. void stopADC(void)
  331. {
  332. //ADC1->CR |= ADC_CR_ADSTP;
  333. //while(ADC1->CR & ADC_CR_ADSTP)
  334. // ;
  335. while( adcStartSubTask(ADC_SUB_TASK_STOP_ADC) == 0 )
  336. adcExecSub();
  337. while( adcIsSubDone() == 0 )
  338. adcExecSub();
  339. }
  340. /* CONFIGURATION with ADEN=0 */
  341. /* required to change the configuration of the ADC */
  342. void disableADC(void)
  343. {
  344. /* Check for the ADEN flag. */
  345. /* Setting ADDIS will fail if the ADC is alread disabled: The while loop will not terminate */
  346. #ifdef xxxx
  347. if ((ADC1->CR & ADC_CR_ADEN) != 0)
  348. {
  349. /* is this correct? i think we must use the disable flag here */
  350. ADC1->CR |= ADC_CR_ADDIS;
  351. while(ADC1->CR & ADC_CR_ADDIS)
  352. ;
  353. }
  354. #endif
  355. while( adcStartSubTask(ADC_SUB_TASK_DISABLE_ADC) == 0 )
  356. adcExecSub();
  357. while( adcIsSubDone() == 0 )
  358. adcExecSub();
  359. }
  360. /* ENABLE ADC (but do not start) */
  361. /* after the ADC is enabled, it must not be reconfigured */
  362. void enableADC(void)
  363. {
  364. //ADC1->ISR |= ADC_ISR_ADRDY; /* clear ready flag */
  365. //ADC1->CR |= ADC_CR_ADEN; /* enable ADC */
  366. //while ((ADC1->ISR & ADC_ISR_ADRDY) == 0) /* wait for ADC */
  367. //{
  368. //}
  369. while( adcStartSubTask(ADC_SUB_TASK_ENABLE_ADC) == 0 )
  370. adcExecSub();
  371. while( adcIsSubDone() == 0 )
  372. adcExecSub();
  373. }
  374. /*=======================================================================*/
  375. /* ADC Single Conversion: 8 bit resolution */
  376. /*
  377. ch0 PA0 pin 6
  378. ch1 PA1 pin 7
  379. ch2 PA2 pin 8
  380. ch3 PA3 pin 9
  381. ch4 PA4 pin 10
  382. ch5 PA5 pin 11
  383. ch6 PA6 pin 12
  384. ch7 PA7 pin 13
  385. ch8 PB0 -
  386. ch9 PB1 pin 14
  387. ch 0..15: GPIO
  388. ch 16: ???
  389. ch 17: vref (bandgap)
  390. ch18: temperature sensor
  391. returns 8 bit result, right aligned
  392. */
  393. uint8_t adc_single_conversion_channel = 5;
  394. volatile uint8_t adc_single_conversion_state = 0;
  395. uint16_t adc_single_conversion_result;
  396. int adcStartSingleConversion(uint8_t channel)
  397. {
  398. if ( adc_single_conversion_state != 0 )
  399. return 0;
  400. adc_single_conversion_state = 1;
  401. adc_single_conversion_channel = channel;
  402. return 1;
  403. }
  404. void adcExecSingleConversion(void)
  405. {
  406. switch(adc_single_conversion_state)
  407. {
  408. case 1:
  409. if ( adcStartSubTask(ADC_SUB_TASK_STOP_ADC) == 0 )
  410. {
  411. adcExecSub();
  412. break;
  413. }
  414. adc_single_conversion_state++;
  415. /* fall through */
  416. case 2:
  417. if ( adcIsSubDone() == 0 )
  418. {
  419. adcExecSub();
  420. break;
  421. }
  422. adc_single_conversion_state++;
  423. /* fall through */
  424. case 3:
  425. if ( adcStartSubTask(ADC_SUB_TASK_DISABLE_ADC) == 0 )
  426. {
  427. adcExecSub();
  428. break;
  429. }
  430. adc_single_conversion_state++;
  431. /* fall through */
  432. case 4:
  433. if ( adcIsSubDone() == 0 )
  434. {
  435. adcExecSub();
  436. break;
  437. }
  438. /* CONFIGURE ADC */
  439. //ADC1->CFGR1 &= ~ADC_CFGR1_EXTEN; /* software enabled conversion start */
  440. //ADC1->CFGR1 &= ~ADC_CFGR1_ALIGN; /* right alignment */
  441. ADC1->CFGR1 = ADC_CFGR1_RES_1; /* 8 bit resolution */
  442. //ADC1->SMPR |= ADC_SMPR_SMP_0 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_2; /* Select a sampling mode of 111 (very slow)*/
  443. ADC1->SMPR = 0;
  444. adc_single_conversion_state++;
  445. /* fall through */
  446. case 5:
  447. if ( adcStartSubTask(ADC_SUB_TASK_ENABLE_ADC) == 0 )
  448. {
  449. adcExecSub();
  450. break;
  451. }
  452. adc_single_conversion_state++;
  453. /* fall through */
  454. case 6:
  455. if ( adcIsSubDone() == 0 )
  456. {
  457. adcExecSub();
  458. break;
  459. }
  460. ADC1->CHSELR = 1<<adc_single_conversion_channel; /* Select channel (can be done also if ADC is enabled) */
  461. adc_single_conversion_state++;
  462. /* fall through */
  463. case 7:
  464. if ( adcStartSubTask(ADC_SUB_TASK_CONVERSION) == 0 )
  465. {
  466. adcExecSub();
  467. break;
  468. }
  469. adc_single_conversion_state++;
  470. /* fall through */
  471. case 8:
  472. if ( adcIsSubDone() == 0 )
  473. {
  474. adcExecSub();
  475. break;
  476. }
  477. adc_single_conversion_result = adc_result;
  478. adc_single_conversion_state = 0;
  479. break;
  480. }
  481. }
  482. uint16_t getADC(uint8_t ch)
  483. {
  484. while( adcStartSingleConversion(ch) == 0)
  485. adcExecSingleConversion();
  486. while( adc_single_conversion_state != 0 )
  487. adcExecSingleConversion();
  488. return adc_single_conversion_result;
  489. }
  490. /*=======================================================================*/
  491. /* ADC Multi (DMA) Conversion: 12 bit resolution */
  492. uint8_t adc_multi_conversion_channel = 6;
  493. volatile uint8_t adc_multi_conversion_state = 0;
  494. uint16_t adc_multi_conversion_count = 256;
  495. uint16_t *adc_multi_conversion_buffer = NULL;
  496. int adcStartMultiConversion(uint8_t channel, uint16_t cnt, uint16_t *buf)
  497. {
  498. if ( adc_multi_conversion_state != 0 )
  499. return 0;
  500. adc_multi_conversion_state = 1;
  501. adc_multi_conversion_channel = channel;
  502. adc_multi_conversion_count = cnt;
  503. adc_multi_conversion_buffer = buf;
  504. return 1;
  505. }
  506. void adcExecMultiConversion(void)
  507. {
  508. switch(adc_multi_conversion_state)
  509. {
  510. case 1:
  511. if ( adcStartSubTask(ADC_SUB_TASK_STOP_ADC) == 0 )
  512. {
  513. adcExecSub();
  514. break;
  515. }
  516. adc_multi_conversion_state++;
  517. /* fall through */
  518. case 2:
  519. if ( adcIsSubDone() == 0 )
  520. {
  521. adcExecSub();
  522. break;
  523. }
  524. adc_multi_conversion_state++;
  525. /* fall through */
  526. case 3:
  527. if ( adcStartSubTask(ADC_SUB_TASK_DISABLE_ADC) == 0 )
  528. {
  529. adcExecSub();
  530. break;
  531. }
  532. adc_multi_conversion_state++;
  533. /* fall through */
  534. case 4:
  535. if ( adcIsSubDone() == 0 )
  536. {
  537. adcExecSub();
  538. break;
  539. }
  540. /* CONFIGURE ADC */
  541. /* disable and reset to defaults */
  542. DMA1_Channel1->CCR = 0;
  543. /* defaults:
  544. - 8 Bit access --> will be changed below
  545. - read from peripheral --> ok
  546. - none-circular mode --> ok
  547. - no increment mode --> will be changed below
  548. */
  549. DMA1_Channel1->CNDTR = adc_multi_conversion_count; /* buffer size */
  550. DMA1_Channel1->CPAR = (uint32_t)&(ADC1->DR); /* source value */
  551. // DMA1_Channel1->CPAR = (uint32_t)&(GPIOA->ODR); /* source value */
  552. DMA1_Channel1->CMAR = (uint32_t)adc_multi_conversion_buffer; /* destination memory */
  553. DMA1_CSELR->CSELR &= ~DMA_CSELR_C1S; /* 0000: select ADC for DMA CH 1 (this is reset default) */
  554. DMA1_CSELR->CSELR &= ~DMA_CSELR_C2S; /* 0000: select ADC for DMA CH 2 (this is reset default) */
  555. DMA1_Channel1->CCR |= DMA_CCR_MINC; /* increment memory */
  556. DMA1_Channel1->CCR |= DMA_CCR_MSIZE_0; /* 01: 16 Bit access */
  557. DMA1_Channel1->CCR |= DMA_CCR_PSIZE_0; /* 01: 16 Bit access */
  558. DMA1_Channel1->CCR |= DMA_CCR_EN; /* enable */
  559. /*
  560. detect rising edge on external trigger (ADC_CFGR1_EXTEN_0)
  561. recive trigger from TIM2 (ADC_CFGR1_EXTSEL_1)
  562. 8 Bit resolution (ADC_CFGR1_RES_1)
  563. Use DMA one shot mode and enable DMA (ADC_CFGR1_DMAEN)
  564. Once DMA is finished, it will disable continues mode (ADC_CFGR1_CONT)
  565. */
  566. ADC1->CFGR1 =
  567. ADC_CFGR1_CONT /* continues mode */
  568. | ADC_CFGR1_EXTEN_0 /* rising edge */
  569. // | ADC_CFGR1_EXTEN_1 /* */
  570. | ADC_CFGR1_EXTSEL_1 /* TIM2 */
  571. // | ADC_CFGR1_RES_1 /* 8 Bit resolution, no value means 12 bit */
  572. | ADC_CFGR1_DMAEN; /* enable generation of DMA requests */
  573. //ADC1->SMPR |= ADC_SMPR_SMP_0 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_2;
  574. //ADC1->SMPR = ADC_SMPR_SMP_1 ;
  575. //ADC1->SMPR = ADC_SMPR_SMP_0 | ADC_SMPR_SMP_1 ;
  576. ADC1->SMPR = ADC_SMPR_SMP_2 ;
  577. /*
  578. 12.5 + 8.5 = 21 ADC Cycles pre ADC sampling
  579. 4 MHz / 21 cycle / 256 = 744 Hz
  580. */
  581. adc_multi_conversion_state++;
  582. /* fall through */
  583. case 5:
  584. if ( adcStartSubTask(ADC_SUB_TASK_ENABLE_ADC) == 0 )
  585. {
  586. adcExecSub();
  587. break;
  588. }
  589. adc_multi_conversion_state++;
  590. /* fall through */
  591. case 6:
  592. if ( adcIsSubDone() == 0 )
  593. {
  594. adcExecSub();
  595. break;
  596. }
  597. ADC1->CHSELR = 1<<adc_multi_conversion_channel; /* Select channel (can be done also if ADC is enabled) */
  598. /* conversion will be started automatically with rising edge of TIM2, yet ADSTART is still required */
  599. ADC1->CR |= ADC_CR_ADSTART; /* start the ADC conversion */
  600. adc_multi_conversion_state++;
  601. /* fall through */
  602. case 7:
  603. if ( DMA1_Channel1->CNDTR > 0 )
  604. break;
  605. adc_multi_conversion_state = 0;
  606. break;
  607. }
  608. }
  609. /* 12 bit resolution */
  610. void scanADC(uint8_t ch, uint16_t cnt, uint16_t *buf)
  611. {
  612. while( adcStartMultiConversion(ch, cnt, buf) == 0)
  613. adcExecMultiConversion();
  614. while( adc_multi_conversion_state != 0 )
  615. adcExecMultiConversion();
  616. }
  617. /*=======================================================================*/
  618. /*
  619. 5000Hz Data Acquisition
  620. Acqusition:
  621. 1./2. Read DC Motor Voltage into buffer 1
  622. 3./4. Read DC Motor Voltage into buffer 2
  623. 5./6. Read signle ADC from the variable resistor
  624. parallel: Calculate noise via difference signal
  625. */
  626. volatile uint16_t adc_variable_resistor_value = 0;
  627. volatile uint8_t adc_acquisition_state = 0;
  628. volatile uint8_t adc_calculation_state = 0;
  629. #define BUF_MUL 2
  630. uint16_t adc_buf[128*BUF_MUL];
  631. uint16_t adc_buf2[128*BUF_MUL];
  632. uint16_t adc_diff[128*BUF_MUL];
  633. uint32_t adc_diff_sum_tmp = 0;
  634. uint16_t adc_diff_sum_cnt = 0;
  635. volatile uint32_t adc_diff_sum = 0;
  636. volatile uint16_t adc_diff_noise_per_sample_raw = 0; // scaled by 8 bits
  637. volatile uint16_t adc_diff_noise_per_sample_filt = 0; // scaled by 8 bits
  638. volatile uint16_t adc_max_tmp = 0;
  639. volatile uint16_t adc_max_raw = 0;
  640. volatile uint16_t adc_max_filt = 0;
  641. volatile uint16_t adc_calculation_pos;
  642. /* 128*BUF_MUL / ADC_CALC_PER_STEP must have no reminder */
  643. #define ADC_CALC_PER_STEP 32
  644. void adcExecAcquisition(void)
  645. {
  646. uint16_t i;
  647. uint16_t a, b, d, z;
  648. switch(adc_acquisition_state)
  649. {
  650. case 1:
  651. if ( adcStartMultiConversion(6, 128*BUF_MUL, adc_buf) == 0)
  652. {
  653. adcExecMultiConversion();
  654. break;
  655. }
  656. adc_acquisition_state++;
  657. /* fall through */
  658. case 2:
  659. if ( adc_multi_conversion_state != 0 )
  660. {
  661. adcExecMultiConversion();
  662. break;
  663. }
  664. adc_acquisition_state++;
  665. /* fall through */
  666. case 3:
  667. if ( adcStartMultiConversion(6, 128*BUF_MUL, adc_buf2) == 0)
  668. {
  669. adcExecMultiConversion();
  670. break;
  671. }
  672. adc_acquisition_state++;
  673. /* fall through */
  674. case 4:
  675. if ( adc_multi_conversion_state != 0 )
  676. {
  677. adcExecMultiConversion();
  678. break;
  679. }
  680. adc_acquisition_state++;
  681. adc_calculation_state = 1;
  682. adc_calculation_pos = 0;
  683. adc_diff_sum_tmp = 0;
  684. adc_diff_sum_cnt = 0;
  685. adc_max_tmp = 0;
  686. /* fall through */
  687. case 5:
  688. if ( adcStartSingleConversion(5) == 0)
  689. {
  690. adcExecSingleConversion();
  691. break;
  692. }
  693. adc_acquisition_state++;
  694. /* fall through */
  695. case 6:
  696. if ( adc_single_conversion_state != 0 )
  697. {
  698. adcExecSingleConversion();
  699. break;
  700. }
  701. adc_variable_resistor_value = adc_single_conversion_result;
  702. adc_acquisition_state++;
  703. /* fall through */
  704. case 7:
  705. if ( adc_calculation_state >= 2 ) // wait for calculation
  706. {
  707. adc_acquisition_state = 1;
  708. adc_calculation_state = 0;
  709. }
  710. break;
  711. }
  712. switch(adc_calculation_state)
  713. {
  714. case 1:
  715. i = adc_calculation_pos;
  716. adc_calculation_pos += ADC_CALC_PER_STEP;
  717. if ( adc_calculation_pos >= 128U*BUF_MUL )
  718. adc_calculation_pos = 128U*BUF_MUL;
  719. while( i < adc_calculation_pos )
  720. {
  721. a = adc_buf[i];
  722. b = adc_buf2[i];
  723. if ( a > b )
  724. d = a - b;
  725. else
  726. d = b - a;
  727. /* ignore values around 0 and very large differences (spikes)
  728. At least values 0 and 1 for a should be ignored.
  729. Height of the spices is not really clear.
  730. */
  731. if ( a > 4 && b > 4 && d < 24)
  732. {
  733. adc_diff_sum_tmp += d;
  734. adc_diff_sum_cnt++;
  735. z = a + b;
  736. z >>= 1;
  737. if ( adc_max_tmp < z )
  738. adc_max_tmp = z;
  739. }
  740. adc_diff[i] = d;
  741. i++;
  742. }
  743. if ( adc_calculation_pos >= 128U*BUF_MUL )
  744. {
  745. adc_calculation_pos = 0;
  746. adc_diff_sum = adc_diff_sum_tmp;
  747. adc_diff_noise_per_sample_raw = (adc_diff_sum_tmp * 256UL)/adc_diff_sum_cnt;
  748. i2c_mem[2] = adc_diff_noise_per_sample_raw & 255;
  749. i2c_mem[3] = adc_diff_noise_per_sample_raw>>8;
  750. /*
  751. this is a strong low-pass filter
  752. currently the filter value is calculated with 100Hz (every 5th duty cycle)
  753. 3V DC Motor: adc_diff_noise_per_sample_filt < 0x0600 stop, adc_diff_noise_per_sample_filt > 0x0700 running
  754. */
  755. adc_diff_noise_per_sample_filt = (((((1UL<<5) - 1)*(uint32_t)adc_diff_noise_per_sample_filt)) + (uint32_t)((1*adc_diff_noise_per_sample_raw)))>>5;
  756. i2c_mem[4] = adc_diff_noise_per_sample_filt & 255;
  757. i2c_mem[5] = adc_diff_noise_per_sample_filt>>8;
  758. /*
  759. low-pass filter for the max value of the ADC.
  760. If the DC motor rotates, then the max value indicates speed: lower values are faster, higher values are slower
  761. 3V DC Motor: values are from 0x0160 (fastest) to >0x4b0 (almost stopped)
  762. */
  763. adc_max_raw = adc_max_tmp;
  764. i2c_mem[6] = adc_max_raw & 255;
  765. i2c_mem[7] = adc_max_raw>>8;
  766. adc_max_filt = (((((1UL<<5) - 1)*(uint32_t)adc_max_filt)) + (uint32_t)((1*adc_max_raw))) >> 5;
  767. i2c_mem[8] = adc_max_filt & 255;
  768. i2c_mem[9] = adc_max_filt>>8;
  769. adc_calculation_state++;
  770. }
  771. break;
  772. }
  773. }
  774. /*=======================================================================*/
  775. /* TIM2: PWM signal for the DC Motor */
  776. //#define TIM_CYCLE_TIME 5355
  777. /* 7950 --> 500Hz */
  778. #define TIM_CYCLE_TIME 7950
  779. #define TIM_CYCLE_UPPER_SKIP 100
  780. #define TIM_CYCLE_LOWER_SKIP 200
  781. void initTIM2(uint8_t is_gpio_a)
  782. {
  783. /* enable clock for TIM2 */
  784. RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
  785. /* prescalar for AHB and APB1 */
  786. /* reselt defaults for HPRE and PPRE1: no clock division */
  787. // RCC->CFGR &= ~RCC_CFGR_HPRE;
  788. // RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
  789. // RCC->CFGR &= ~RCC_CFGR_PPRE1;
  790. // RCC->CFGR |= RCC_CFGR_PPRE1_DIV1;
  791. /* configure GPIOA PA1 for TIM2 */
  792. GPIOA->MODER &= ~GPIO_MODER_MODE1; /* clear mode for PA1 */
  793. GPIOA->MODER |= GPIO_MODER_MODE1_1; /* alt fn */
  794. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_1; /* push-pull */
  795. GPIOA->AFR[0] &= ~(15<<4); /* Clear Alternate Function PA1 */
  796. GPIOA->AFR[0] |= 2<<4; /* AF2 Alternate Function PA1 */
  797. /* configure GPIOA PB1 for TIM2 */
  798. GPIOB->MODER &= ~GPIO_MODER_MODE1; /* clear mode for PB1 */
  799. GPIOB->MODER |= GPIO_MODER_MODE1_1; /* alt fn */
  800. GPIOB->OTYPER &= ~GPIO_OTYPER_OT_1; /* push-pull */
  801. GPIOB->AFR[0] &= ~(15<<4); /* Clear Alternate Function PB1 */
  802. GPIOB->AFR[0] |= 5<<4; /* AF5 Alternate Function PB1 */
  803. /* TIM2 configure */
  804. /* disable all interrupts */
  805. //TIM2->DIER = 0; /* 0 is reset default value */
  806. /* clear everything, including the "Update disable" flag, so that updates */
  807. /* are generated */
  808. // TIM2->CR1 = 0; /* 0 is reset default value */
  809. //TIM2->CR1 |= TIM_CR1_ARPE; // ARR is not modified so constant update is ok
  810. /* Update request by manual UG bit setting or slave controller */
  811. /* both is not required here */
  812. /* so, update request by couter over/underflow remains */
  813. //TIM2->CR1 |= TIM_CR1_URS; /* only udf/ovf generae events */
  814. TIM2->CR2 |= TIM_CR2_MMS_1; /* Update event for TRGO */
  815. TIM2->ARR = TIM_CYCLE_TIME; /* total cycle count */
  816. TIM2->CCR2 = 1024; /* duty cycle for channel 2 (PA1) */
  817. TIM2->CCR4 = 1024; /* duty cycle for channel 4 (PB1) */
  818. //TIM2->CCMR1 &= ~TIM_CCMR1_OC2CE; /* disable clear output compare 2 **/
  819. TIM2->CCMR1 |= TIM_CCMR1_OC2M; /* all 3 bits set: PWM Mode 2 */
  820. TIM2->CCMR1 |= TIM_CCMR1_OC2PE; /* preload enable CCR2 is preloaded*/
  821. TIM2->CCER |= TIM_CCER_CC2P; /* polarity 0: normal (reset default) / 1: inverted*/
  822. TIM2->CCMR2 |= TIM_CCMR2_OC4M; /* all 3 bits set: PWM Mode 2 */
  823. TIM2->CCMR2 |= TIM_CCMR2_OC4PE; /* preload enable CCR2 is preloaded*/
  824. TIM2->CCER |= TIM_CCER_CC4P; /* polarity 0: normal (reset default) / 1: inverted*/
  825. if ( is_gpio_a )
  826. TIM2->CCER |= TIM_CCER_CC2E; /* set output enable for channel 2 */
  827. else
  828. TIM2->CCER |= TIM_CCER_CC4E; /* set output enable for channel 4 */
  829. TIM2->PSC = 7; /* divide by 8 */
  830. TIM2->CR1 |= TIM_CR1_CEN; /* counter enable */
  831. /*
  832. TIM2 cycle:
  833. 32000000Hz / 5355 / 8 = 747 Hz
  834. */
  835. }
  836. void setTIM2RawDuty(uint32_t duty_cycle, uint8_t is_gpio_a)
  837. {
  838. TIM2->CCR2 = duty_cycle;
  839. TIM2->CCR4 = duty_cycle;
  840. if ( is_gpio_a )
  841. {
  842. TIM2->CCMR1 |= TIM_CCMR1_OC2M; /* all 3 bits set: PWM Mode 2 */
  843. TIM2->CCER |= TIM_CCER_CC2E; /* set output enable for channel 2 */
  844. //TIM2->CCER &= ~TIM_CCER_CC4E; /* set output disable for channel 4 */
  845. TIM2->CCMR2 &= ~TIM_CCMR2_OC4M_1; /* Mode 101 force high */
  846. }
  847. else
  848. {
  849. TIM2->CCMR2 |= TIM_CCMR2_OC4M; /* all 3 bits set: PWM Mode 2 */
  850. TIM2->CCER |= TIM_CCER_CC4E; /* set output enable for channel 4 */
  851. //TIM2->CCER &= ~TIM_CCER_CC2E; /* set output disable for channel 2 */
  852. TIM2->CCMR1 &= ~TIM_CCMR1_OC2M_1; /* Mode 101 force high */
  853. }
  854. }
  855. /*=======================================================================*/
  856. /* TIM22 */
  857. /*
  858. TIM22: 0.2ms IRQ
  859. Assumptions:
  860. APB2: 32MHz
  861. GPIO A anabled
  862. */
  863. void initTIM22(void)
  864. {
  865. RCC->APB2ENR |= RCC_APB2ENR_TIM22EN;
  866. /* configure GPIOA PA7 for TIM2 CH2*/
  867. GPIOA->MODER &= ~GPIO_MODER_MODE7; /* clear mode for PA1 */
  868. GPIOA->MODER |= GPIO_MODER_MODE7_1; /* alt fn */
  869. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_7; /* push-pull */
  870. GPIOA->AFR[0] &= ~(15<<28); /* Clear Alternate Function PA7 */
  871. //GPIOA->AFR[0] |= 5<<28; /* AF5 Alternate Function PA7 NOTE: OUTPUT at PA7 influences ADC! */
  872. TIM22->CR2 |= TIM_CR2_MMS_1; /* Update event for TRGO */
  873. TIM22->ARR = 6400; /* 0.2ms (5000Hz) with 32MHz */
  874. TIM22->CCR2 = 2000; /* duty cycle for channel 2 (PA7) */
  875. TIM22->CCMR1 |= TIM_CCMR1_OC2M; /* all 3 bits set: PWM Mode 2 */
  876. TIM22->CCMR1 |= TIM_CCMR1_OC2PE; /* preload enable --> more accurate duty cycle visible */
  877. TIM22->CCER |= TIM_CCER_CC2E; /* set output enable for channel 2 */
  878. TIM22->CCER |= TIM_CCER_CC2P; /* polarity 0: normal (reset default) / 1: inverted*/
  879. TIM22->PSC = 0; /* divide by 1 */
  880. TIM22->DIER |= TIM_DIER_UIE; /* enable TIM22 update interrupt: call TIM22_IRQHandler on reload */
  881. /* enable IRQ in NVIC */
  882. NVIC_SetPriority(TIM22_IRQn, 0);
  883. NVIC_EnableIRQ(TIM22_IRQn);
  884. TIM22->CR1 |= TIM_CR1_CEN; /* counter enable */
  885. adc_acquisition_state = 1; /* enable data acquisition */
  886. }
  887. volatile uint16_t adc_max;
  888. void __attribute__ ((interrupt, used)) TIM22_IRQHandler(void)
  889. {
  890. /*
  891. the following loop requires about 5000 clock cycles 1/3 of the IRQ time:
  892. uint16_t i;
  893. adc_max = 0;
  894. for( i = 0; i < 256; i++ )
  895. {
  896. adc_max += TIM22->CNT;
  897. }
  898. */
  899. adcExecAcquisition();
  900. TIM22->CCR2 = TIM22->CNT; /* store the current count value in compare register: duty cycle signals load */
  901. TIM22->SR &= ~TIM_SR_UIF; /* clear interrupt */
  902. }
  903. /*=======================================================================*/
  904. /* I2C */
  905. volatile uint16_t i2c_total_irq_cnt;
  906. volatile uint16_t i2c_TXIS_cnt;
  907. volatile uint16_t i2c_RXNE_cnt;
  908. void i2c_mem_reset_write(void)
  909. {
  910. i2c_is_write_idx = 1;
  911. }
  912. void i2c_mem_init(void)
  913. {
  914. i2c_idx = 0;
  915. i2c_mem_reset_write();
  916. }
  917. void i2c_mem_set_index(unsigned char value)
  918. {
  919. i2c_idx = value;
  920. i2c_is_write_idx = 0;
  921. }
  922. void i2c_mem_write_via_index(unsigned char value)
  923. {
  924. if ( i2c_idx == 0 )
  925. {
  926. /* additionall put this byte into the queue */
  927. //addCmdToGPIOQueue(value);
  928. }
  929. i2c_mem[i2c_idx++] = value;
  930. }
  931. unsigned char i2c_mem_read(void)
  932. {
  933. i2c_mem_reset_write();
  934. i2c_idx++;
  935. return i2c_mem[i2c_idx];
  936. }
  937. void i2c_mem_write(unsigned char value)
  938. {
  939. if ( i2c_is_write_idx != 0 )
  940. {
  941. i2c_mem_set_index(value);
  942. }
  943. else
  944. {
  945. i2c_is_write_idx = 0;
  946. i2c_mem_write_via_index(value);
  947. }
  948. }
  949. /* address: I2C address multiplied by 2 */
  950. /* Pins PA9 (SCL) and PA10 (SDA) */
  951. void i2c_hw_init(unsigned char address)
  952. {
  953. RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; /* Enable clock for I2C */
  954. RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
  955. __NOP(); /* extra delay for clock stabilization required? */
  956. __NOP();
  957. /* configure io */
  958. GPIOA->MODER &= ~GPIO_MODER_MODE9; /* clear mode for PA9 */
  959. GPIOA->MODER |= GPIO_MODER_MODE9_1; /* alt fn */
  960. GPIOA->OTYPER |= GPIO_OTYPER_OT_9; /* open drain */
  961. GPIOA->AFR[1] &= ~(15<<4); /* Clear Alternate Function PA9 */
  962. GPIOA->AFR[1] |= 1<<4; /* I2C Alternate Function PA9 */
  963. GPIOA->MODER &= ~GPIO_MODER_MODE10; /* clear mode for PA10 */
  964. GPIOA->MODER |= GPIO_MODER_MODE10_1; /* alt fn */
  965. GPIOA->OTYPER |= GPIO_OTYPER_OT_10; /* open drain */
  966. GPIOA->AFR[1] &= ~(15<<8); /* Clear Alternate Function PA10 */
  967. GPIOA->AFR[1] |= 1<<8; /* I2C Alternate Function PA10 */
  968. RCC->CCIPR &= ~RCC_CCIPR_I2C1SEL; /* write 00 to the I2C clk selection register */
  969. RCC->CCIPR |= RCC_CCIPR_I2C1SEL_0; /* select system clock (01) */
  970. /* I2C init flow chart: Clear PE bit */
  971. I2C1->CR1 &= ~I2C_CR1_PE;
  972. /* I2C init flow chart: Configure filter */
  973. /* leave at defaults */
  974. /* I2C init flow chart: Configure timing */
  975. /*
  976. standard mode 100kHz configuration
  977. SYSCLK = I2CCLK = 32 MHz
  978. PRESC = 6 bits 28..31
  979. SCLL = 0x13 bits 0..7
  980. SCLH = 0x0f bits 8..15
  981. SDADEL = 0x02 bits 16..19
  982. SCLDEL = 0x04 bits 20..23
  983. */
  984. I2C1->TIMINGR = 0x60420f13;
  985. /* I2C init flow chart: Configure NOSTRECH */
  986. I2C1->CR1 |= I2C_CR1_NOSTRETCH;
  987. /* I2C init flow chart: Enable I2C */
  988. I2C1->CR1 |= I2C_CR1_PE;
  989. /* disable OAR1 for reconfiguration */
  990. I2C1->OAR1 &= ~I2C_OAR1_OA1EN;
  991. I2C1->OAR1 = address;
  992. I2C1->OAR1 |= I2C_OAR1_OA1EN;
  993. /* enable interrupts */
  994. I2C1->CR1 |= I2C_CR1_STOPIE;
  995. I2C1->CR1 |= I2C_CR1_NACKIE;
  996. //I2C1->CR1 |= I2C_CR1_ADDRIE;
  997. I2C1->CR1 |= I2C_CR1_RXIE;
  998. I2C1->CR1 |= I2C_CR1_TXIE;
  999. /* load first value into TXDR register */
  1000. I2C1->TXDR = i2c_mem[i2c_idx];
  1001. /* enable IRQ in NVIC */
  1002. NVIC_SetPriority(I2C1_IRQn, 0);
  1003. NVIC_EnableIRQ(I2C1_IRQn);
  1004. }
  1005. void i2c_init(unsigned char address)
  1006. {
  1007. i2c_mem_init();
  1008. i2c_mem[0] = 0x080; /* stop */
  1009. i2c_hw_init(address);
  1010. }
  1011. void __attribute__ ((interrupt, used)) I2C1_IRQHandler(void)
  1012. {
  1013. unsigned long isr = I2C1->ISR;
  1014. i2c_total_irq_cnt ++;
  1015. if ( isr & I2C_ISR_TXIS )
  1016. {
  1017. i2c_TXIS_cnt++;
  1018. I2C1->TXDR = i2c_mem_read();
  1019. }
  1020. else if ( isr & I2C_ISR_RXNE )
  1021. {
  1022. i2c_RXNE_cnt++;
  1023. i2c_mem_write(I2C1->RXDR);
  1024. I2C1->ISR |= I2C_ISR_TXE; // allow overwriting the TCDR with new data
  1025. I2C1->TXDR = i2c_mem[i2c_idx];
  1026. }
  1027. else if ( isr & I2C_ISR_STOPF )
  1028. {
  1029. I2C1->ICR = I2C_ICR_STOPCF;
  1030. I2C1->ISR |= I2C_ISR_TXE; // allow overwriting the TCDR with new data
  1031. I2C1->TXDR = i2c_mem[i2c_idx];
  1032. i2c_mem_reset_write();
  1033. }
  1034. else if ( isr & I2C_ISR_NACKF )
  1035. {
  1036. I2C1->ICR = I2C_ICR_NACKCF;
  1037. I2C1->ISR |= I2C_ISR_TXE; // allow overwriting the TCDR with new data
  1038. I2C1->TXDR = i2c_mem[i2c_idx];
  1039. i2c_mem_reset_write();
  1040. }
  1041. else if ( isr & I2C_ISR_ADDR )
  1042. {
  1043. /* not required, the addr match interrupt is not enabled */
  1044. I2C1->ICR = I2C_ICR_ADDRCF;
  1045. I2C1->ISR |= I2C_ISR_TXE; // allow overwriting the TCDR with new data
  1046. I2C1->TXDR = i2c_mem[i2c_idx];
  1047. i2c_mem_reset_write();
  1048. }
  1049. /* if at any time the addr match is set, clear the flag */
  1050. /* not sure, whether this is required */
  1051. if ( isr & I2C_ISR_ADDR )
  1052. {
  1053. I2C1->ICR = I2C_ICR_ADDRCF;
  1054. }
  1055. }
  1056. /*=======================================================================*/
  1057. int main()
  1058. {
  1059. uint16_t adc_value = 0x80;
  1060. uint16_t old_adc_value = 0x0ffff;
  1061. uint16_t tim_duty;
  1062. uint16_t zero_pos;
  1063. uint16_t i;
  1064. u8g2_uint_t y, yy;
  1065. uint8_t is_i2c = 0;
  1066. setHSIClock(); /* enable 32 MHz Clock */
  1067. startUp(); /* enable systick irq and several power regions */
  1068. i2c_init(40*2); /* activage I2C, adr = 40 */
  1069. initDisplay(); /* aktivate display */
  1070. initADC();
  1071. RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
  1072. RCC->IOPENR |= RCC_IOPENR_IOPBEN; /* Enable clock for GPIO Port B */
  1073. __NOP();
  1074. __NOP();
  1075. GPIOA->MODER &= ~GPIO_MODER_MODE1; /* clear mode for PA1 */
  1076. GPIOA->MODER |= GPIO_MODER_MODE1_0; /* Output mode for PA1 */
  1077. GPIOA->OTYPER &= ~GPIO_OTYPER_OT_1; /* no Push/Pull for PA1 */
  1078. GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED1; /* low speed for PA1 */
  1079. GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD1; /* no pullup/pulldown for PA1 */
  1080. GPIOA->BSRR = GPIO_BSRR_BS_1; /* atomic set PA1 */
  1081. GPIOB->MODER &= ~GPIO_MODER_MODE1; /* clear mode for PB1 */
  1082. GPIOB->MODER |= GPIO_MODER_MODE1_0; /* Output mode for PB1 */
  1083. //GPIOB->OTYPER &= ~GPIO_OTYPER_OT_1; /* no Push/Pull for PB1 */
  1084. GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED1; /* low speed for PB1 */
  1085. GPIOB->PUPDR &= ~GPIO_PUPDR_PUPD1; /* no pullup/pulldown for PB1 */
  1086. GPIOB->BSRR = GPIO_BSRR_BR_1; /* atomic reset PB1 */
  1087. initTIM2(1);
  1088. initTIM22();
  1089. for(;;)
  1090. {
  1091. u8g2_ClearBuffer(&u8g2);
  1092. if ( is_i2c != 0 )
  1093. {
  1094. adc_value = i2c_mem[0];
  1095. }
  1096. else
  1097. {
  1098. if ( i2c_mem[0] != 0x080 )
  1099. {
  1100. adc_value = i2c_mem[0];
  1101. is_i2c = 1;
  1102. }
  1103. else
  1104. {
  1105. adc_value = adc_variable_resistor_value;
  1106. }
  1107. }
  1108. if ( old_adc_value != adc_value )
  1109. {
  1110. if ( adc_value >= 0x080 )
  1111. {
  1112. tim_duty = ((uint32_t)((adc_value-0x080)*2)*((uint32_t)TIM_CYCLE_TIME-TIM_CYCLE_UPPER_SKIP-TIM_CYCLE_LOWER_SKIP))>>8;
  1113. tim_duty += TIM_CYCLE_LOWER_SKIP;
  1114. setTIM2RawDuty(tim_duty, 1);
  1115. }
  1116. else
  1117. {
  1118. tim_duty = ((uint32_t)((0x080 - adc_value)*2)*((uint32_t)TIM_CYCLE_TIME-TIM_CYCLE_UPPER_SKIP-TIM_CYCLE_LOWER_SKIP))>>8;
  1119. tim_duty += TIM_CYCLE_LOWER_SKIP;
  1120. setTIM2RawDuty(tim_duty, 0);
  1121. }
  1122. old_adc_value = adc_value;
  1123. }
  1124. yy = 60;
  1125. zero_pos = ((uint32_t)tim_duty * (uint32_t)256) / (uint32_t)TIM_CYCLE_TIME;
  1126. zero_pos +=4;
  1127. zero_pos += (256-zero_pos)>>6;
  1128. setRow(10); outHex16(adc_value);
  1129. outStr(" "); outHex16(adc_diff_noise_per_sample_filt);
  1130. //outStr(" "); outHex16(adc_diff_sum_cnt);
  1131. outStr(" "); outHex16(adc_max_raw);
  1132. outStr(" "); outHex16(adc_max_filt);
  1133. //outStr("|"); outHex8(adc_buf[zero_pos/2]); outStr("|"); outHex8(adc_buf[zero_pos]);
  1134. u8g2_DrawVLine(&u8g2, zero_pos/2, yy-7, 15);
  1135. u8g2_DrawVLine(&u8g2, zero_pos/4, yy-7, 15);
  1136. for( i = 0; i < 128; i++ )
  1137. {
  1138. y = 60-(adc_buf[i*BUF_MUL]>>5);
  1139. //y = 60-(adc_diff[i*BUF_MUL]>>2);
  1140. u8g2_DrawPixel(&u8g2, i, y);
  1141. if ( y < yy )
  1142. u8g2_DrawVLine(&u8g2, i, y, yy-y+1);
  1143. else
  1144. u8g2_DrawVLine(&u8g2, i, yy, y-yy+1);
  1145. yy = y;
  1146. }
  1147. u8g2_SendBuffer(&u8g2);
  1148. }
  1149. return 0;
  1150. }