LabArm.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. #include "event.h"
  2. #include "n3310.h"
  3. #include "LabArm.h"
  4. uint16_t AdcOutArray[ADC_ARRAY_SIZE];
  5. static uint32_t ADCVoltageSum;
  6. static uint32_t ADCCurrentSum;
  7. static uint8_t DMACounter;
  8. uint32_t ADCVoltage;
  9. uint32_t ADCCurrent;
  10. #if defined(__GNUC__)
  11. void DMA1_Channel1_IRQHandler()
  12. #else
  13. void DMAChannel1_IRQHandler(void) /* Read ADC values */
  14. #endif
  15. {
  16. if (DMA1->ISR & DMA_ISR_HTIF1 && /* Half Transfer complete */
  17. (DMA1_Channel1->CCR & DMA_CCR1_HTIE) /* Half traisfer interrupt enabled */
  18. )
  19. {
  20. int i;
  21. /* HTIF is set every time when transfer interrupt > half !!! */
  22. DMA1_Channel1->CCR &= ~DMA_CCR1_HTIE; /* disable Half traisfer interrupt !!!! */
  23. for (i = 0; i < ADC_ARRAY_SIZE/2; i = i+2)
  24. {
  25. ADCVoltageSum += AdcOutArray[i];
  26. ADCCurrentSum += AdcOutArray[i+1];
  27. }
  28. } else if (DMA1->ISR & DMA_ISR_TCIF1 ) /* transfer complete */
  29. {
  30. int i;
  31. /* transfer complete */
  32. DMA1->IFCR |= DMA_IFCR_CGIF1; /* Clear all interrupt flags */
  33. DMA1_Channel1->CCR |= DMA_CCR1_HTIE; /* enable Half traisfer interrupt */
  34. for (i=ADC_ARRAY_SIZE/2; i< ADC_ARRAY_SIZE; i=i+2)
  35. {
  36. ADCVoltageSum += AdcOutArray[i];
  37. ADCCurrentSum += AdcOutArray[i+1];
  38. }
  39. DMACounter++;
  40. if (DMACounter == 16) /* 2Mhz/195/ADC_ARRAY_SIZE*2/16 - refresh frenq = 5 Hz */
  41. {
  42. DMACounter = 0;
  43. ADCVoltage = ADCVoltageSum;
  44. ADCCurrent = ADCCurrentSum;
  45. NVIC_SetPendingIRQ(EXTI4_IRQn);
  46. ADCVoltageSum = 0;
  47. ADCCurrentSum = 0;
  48. if ( EventQueue == 0 ) /* Lowest priority */
  49. EventQueue = EV_KEY_PRESSED|KEY_ADC;
  50. }
  51. }
  52. DMA1->IFCR |= DMA_IFCR_CGIF1; /* Clear all interrupt flags */
  53. }
  54. #if defined(__GNUC__)
  55. void ADC1_IRQHandler(void)
  56. #else
  57. void ADC_IRQHandler(void) /* Watchdog */
  58. #endif
  59. {
  60. DAC_V = 0; /* OFF output */
  61. DAC_I = 0;
  62. ADC1->CR2 = 0; /* Adc Off */
  63. GPIOB->BRR = GPIO_BRR_BR0|GPIO_BRR_BR1;
  64. GPIOB->CRL &= ~(GPIO_CRL_CNF0|GPIO_CRL_CNF1); /* PUSH pull */
  65. DAC->CR = 0; /* Dac OFF */
  66. /* Save current settings */
  67. SaveSettings(0);
  68. LcdInit(Contrast*3+42);
  69. LcdChr(Y_POSITION*3+X_POSITION*0+14+INVERSE, "Power fault" );
  70. NVIC->ICER[(ADC1_IRQn >> 0x05)] = (u32)0x01 << (ADC1_IRQn & (u8)0x1F); /* Off ADC interrupt */
  71. NVIC->ICPR[(ADC1_IRQn >> 0x05)] = (u32)0x01 << (ADC1_IRQn & (u8)0x1F); /* Clear pend ADC interrupt */
  72. { /* Waiting for power off */
  73. __IO uint32_t Delay = 5000000;
  74. while (Delay--) ;
  75. }
  76. /* Reboot */
  77. NVIC_SystemReset();
  78. }
  79. void LcdBlank(void)
  80. {
  81. LcdInit(42+Contrast*3);
  82. LcdClear();
  83. }
  84. int16_t HumanV;
  85. int16_t HumanI;
  86. void EXTI4_IRQHandler(void)
  87. {
  88. HumanV = VoltageFromAdc();
  89. HumanI = CurrentFromAdc();
  90. #if defined(GRAPH)
  91. {
  92. static Graph_t I = {32000,-32000};
  93. static Graph_t V = {32000,-32000};
  94. static uint16_t Time;
  95. if ( HumanI < I.Min )
  96. I.Min = HumanI;
  97. if ( HumanI > I.Max )
  98. I.Max = HumanI;
  99. if (HumanV < V.Min)
  100. V.Min = HumanV;
  101. if (HumanV > V.Max)
  102. V.Max = HumanV;
  103. Time++;
  104. if (Time >= TimeInterval)
  105. {
  106. Time = 0;
  107. GraphCurrentPoint++;
  108. if (GraphCurrentPoint == GRAPH_SIZE)
  109. GraphCurrentPoint = 0;
  110. IGraphArray[GraphCurrentPoint] = I;
  111. VGraphArray[GraphCurrentPoint] = V;
  112. I.Min = 32000;
  113. I.Max = -32000;
  114. V.Min = 32000;
  115. V.Max = -32000;
  116. }
  117. }
  118. #endif
  119. }
  120. #if 1
  121. void SystemInit()
  122. {};
  123. int main()
  124. {
  125. /* init hardware */
  126. SCB->VTOR = FLASH_BASE;
  127. NVIC_EnableIRQ(DMA1_Channel1_IRQn); /* Enable DMA interrupt */
  128. NVIC_EnableIRQ(ADC1_IRQn); /* Enable ADC interrupt */
  129. NVIC_EnableIRQ(EXTI4_IRQn); /*Additional IRQ to calculate V and I */
  130. NVIC_SetPriority(EXTI4_IRQn, 12); /* Low priority */
  131. /* CLOCK = 8MHz / 8 = 1 MHz */
  132. RCC->CFGR |= RCC_CFGR_HPRE_DIV2|RCC_CFGR_PPRE1_DIV4|RCC_CFGR_PPRE2_DIV2; /* APB1 - 1MHz, AHB - 4MHz, APB2 - 2MHz, ADC - 1MHz */
  133. /* Enable peripery clock */
  134. RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN |RCC_APB2ENR_ADC1EN|RCC_APB2ENR_TIM1EN;
  135. RCC->APB1ENR |= RCC_APB1ENR_TIM3EN|RCC_APB1ENR_TIM2EN|RCC_APB1ENR_DACEN|RCC_APB1ENR_PWREN|RCC_APB1ENR_BKPEN;
  136. RCC->AHBENR |= RCC_AHBENR_DMA1EN|RCC_AHBENR_CRCEN;
  137. /* Unlock the backup domain */
  138. PWR->CR |= PWR_CR_DBP;
  139. /* GPIO configure */
  140. /* PB12 - PB14 - LCD, PA0 - PA2 - encoder(TIM2), PA4-PA5 - DAC Out, PB0-PB1 - ADC(8-9channel), PA7 - ADC power measure */
  141. /* PB0 - Voltage IN, PB1 - CurrentIN, PA4 - VoltageOut, PA5 - CurrentOut */
  142. GPIOB->CRH |= GPIO_CRH_MODE12_1|GPIO_CRH_MODE13_1|GPIO_CRH_MODE14_1|GPIO_CRH_MODE15_1; /* Output 2MHz */
  143. GPIOB->CRH &= ~(GPIO_CRH_CNF12|GPIO_CRH_CNF13|GPIO_CRH_CNF14|GPIO_CRH_CNF15); /* Output Push-pull */
  144. GPIOB->CRL |= GPIO_CRL_MODE0_1 |GPIO_CRL_MODE1_1;
  145. GPIOB->CRL &= ~(GPIO_CRL_CNF0|GPIO_CRL_CNF1); /* PUSH pull */
  146. GPIOA->CRL |= GPIO_CRL_MODE4_1 |GPIO_CRL_MODE5_1|GPIO_CRL_MODE6_1|GPIO_CRL_MODE7_1; /* Out 2 MHZ*/
  147. GPIOA->CRL &= ~(GPIO_CRL_CNF4|GPIO_CRL_CNF5|GPIO_CRL_CNF6|GPIO_CRL_CNF7); /* PUSH pull */
  148. GPIOA->BSRR = GPIO_BSRR_BS6;
  149. LcdBlank();
  150. /* Enable the programmable voltage detector */
  151. PWR->CR |= PWR_CR_PLS_2|PWR_CR_PLS_1; /* 2.8 V */
  152. PWR->CR |= PWR_CR_PVDE; /* Enable the PVD */
  153. { /* Waiting for power stabilize */
  154. __IO uint32_t Delay = 1000000;
  155. while (Delay--) ;
  156. }
  157. /* Check power supply */
  158. while ( (PWR->CSR & PWR_CSR_PVDO ) != 0 )
  159. ; /* BLANK */
  160. /* Power is OK for ADC */
  161. /* Waiting for stabilize power voltage. It should be more then 1.2 V on the PB5 pin */
  162. {
  163. /* Measure PB5 and Vint by injected group */
  164. GPIOA->CRL &= ~GPIO_CRL_MODE7; /* Input, Analog*/
  165. ADC1->CR1 |= ADC_CR1_SCAN;
  166. ADC1->CR2 |= ADC_CR2_TSVREFE|ADC_CR2_JEXTTRIG | ADC_CR2_JEXTSEL; /* injected start by JSWSTART */
  167. ADC1->SMPR1 |= ADC_SMPR1_SMP17; /* Internal Vref, max sampling time */
  168. ADC1->SMPR2 |= ADC_SMPR2_SMP7; /* max sampling time */
  169. ADC1->CR2 |= ADC_CR2_ADON; /* On the ADC */
  170. /* Additional delay to Vref on */
  171. Delay(10000);
  172. /* Calibration */
  173. ADC1->CR2 |= ADC_CR2_RSTCAL;
  174. while ( ADC1->CR2 & ADC_CR2_RSTCAL )
  175. ; /* BLANK */
  176. ADC1->CR2 |= ADC_CR2_CAL;
  177. while ( ADC1->CR2 & ADC_CR2_CAL )
  178. ; /* BLANK */
  179. Delay(10000);
  180. }
  181. /* theck the power voltage */
  182. /* 2 conversions. 7-th channels, 17-th channel */
  183. ADC1->JSQR |= ADC_JSQR_JL_0| /* 2 conversion */
  184. ADC_JSQR_JSQ3_0|ADC_JSQR_JSQ3_1|ADC_JSQR_JSQ3_2| /* CH 7 */
  185. ADC_JSQR_JSQ4_4|ADC_JSQR_JSQ4_0; /* CH 17 */
  186. do
  187. {
  188. ADC1->SR &= ~ADC_SR_JEOC; /* Reset convertion flag */
  189. ADC1->CR2 |= ADC_CR2_JSWSTART; /* Start the convertion for two channels */
  190. while ((ADC1->SR & ADC_SR_JEOC) == 0) /* Waiting end of convertion */
  191. ; /* BLANK */
  192. #if defined(AWD_ENABLED)
  193. } while ( ADC1->JDR1/* Vin */ < ADC1->JDR2/* Vref */ );
  194. #else
  195. }
  196. while ( 0 );
  197. #endif
  198. {
  199. uint16_t SavedVRef = ADC1->JDR2;
  200. /* Set up analog watch dog */
  201. ADC1->CR2 = 0; /* Power off */
  202. /* Reset the ADC */
  203. RCC->APB2RSTR |= RCC_APB2RSTR_ADC1RST;
  204. RCC->APB2RSTR &= ~RCC_APB2RSTR_ADC1RST;
  205. ADC1->HTR = 0xFFF; /* Max value for HIGHT threshold*/
  206. ADC1->LTR = SavedVRef/6*5; /* 1 V */
  207. }
  208. /* Set up ADC, TIM1, DMA for conversion */
  209. ADC1->CR1 |=
  210. #if defined(AWD_ENABLED)
  211. ADC_CR1_JAWDEN|ADC_CR1_AWDIE| /* AWD on injected channels whith interrupt */
  212. #endif
  213. ADC_CR1_JAUTO|ADC_CR1_SCAN; /* Scan mode + auto injection */
  214. ADC1->SMPR2 = ADC_SMPR2_SMP7_0|ADC_SMPR2_SMP8_0|ADC_SMPR2_SMP9_0; /* 7.5 sampling time, 20 - adc time, 5,6,7 ch */
  215. ADC1->SQR1 = ADC_SQR1_L_0; /* 2 conversion */
  216. ADC1->SQR3 = ADC_SQR3_SQ1_3| /* 8 channel - voltage*/
  217. ADC_SQR3_SQ2_3|ADC_SQR3_SQ2_0; /* 9- channel - current */
  218. ADC1->JSQR = ADC_JSQR_JSQ4_2|ADC_JSQR_JSQ4_1|ADC_JSQR_JSQ4_0; /* 1 conversion by 7-th channel in inj */
  219. ADC1->CR2 |= ADC_CR2_EXTTRIG|ADC_CR2_DMA; /* External trigger by T1 CC1, DMA */
  220. GPIOA->CRL &= ~(GPIO_CRL_MODE4_1|GPIO_CRL_MODE5_1|GPIO_CRL_MODE7_1); /* Analog IN */
  221. GPIOB->CRL &= ~(GPIO_CRL_MODE0_1|GPIO_CRL_MODE1_1); /* Analog IN */
  222. /* TIM1 is configyred to trigger the ADC */
  223. TIM1->ARR = 194; /* 2MHz / 200 = 10KHz */
  224. TIM1->CCMR1 |= TIM_CCMR1_OC1M; /* PWM 2 mode */
  225. TIM1->CCR1 = 99;
  226. TIM1->BDTR |= TIM_BDTR_MOE; /* Only for TIM1 - MAIN OUTPUT ENABLE!!! */
  227. TIM1->CCER |= TIM_CCER_CC1E; /* Output enable */
  228. /* DMA configuring */
  229. DMA1_Channel1->CCR |= DMA_CCR1_PL|DMA_CCR1_MSIZE_0|DMA_CCR1_PSIZE_0| /*Hight pry, 16 byte mem, 16 byte pereph */
  230. DMA_CCR1_MINC|DMA_CCR1_CIRC|DMA_CCR1_HTIE|DMA_CCR1_TCIE; /* mem inc, circular, enterrupts by Half and End of conv */
  231. DMA1_Channel1->CNDTR = ADC_ARRAY_SIZE;
  232. DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;
  233. DMA1_Channel1->CMAR = (uint32_t)&AdcOutArray[0];
  234. /* On converting */
  235. ADC1->CR2 |= ADC_CR2_ADON; /* Adc ON */
  236. /* Additional delay to Vref on */
  237. Delay(10000);
  238. /* Calibration */
  239. ADC1->CR2 |= ADC_CR2_RSTCAL;
  240. while ( ADC1->CR2 & ADC_CR2_RSTCAL )
  241. ; /* BLANK */
  242. ADC1->CR2 |= ADC_CR2_CAL;
  243. while ( ADC1->CR2 & ADC_CR2_CAL )
  244. ; /* BLANK */
  245. Delay(10000);
  246. DMA1_Channel1->CCR |= DMA_CCR1_EN; /* Enable DMA */
  247. TIM1->CR1 |= TIM_CR1_CEN; /* start TIM1 */
  248. /* DAC Init */
  249. DAC_V = 0;
  250. DAC_I = 0;
  251. DAC->CR |= DAC_CR_BOFF2|DAC_CR_BOFF1; /* Disable buffers */
  252. DAC->CR |= DAC_CR_EN1|DAC_CR_EN2; /* On DAC */
  253. LcdBlank();
  254. EventInit();
  255. #if defined(GRAPH)
  256. ClearGraph();
  257. #endif
  258. if ( RestoreConfig() != 0 || (GPIOA->IDR & KEY_ENTER) == 0 )
  259. {
  260. AfterContrast = CalibrationMenu;
  261. Contrast = 7;
  262. CurrentFunc(ContrastMenu);
  263. // CurrentFunc(StartFunction);
  264. }
  265. else
  266. {
  267. CurrentFunc(StartFunction);
  268. }
  269. #if defined(CLOCK_ENABLED)
  270. if ( IS_ON_CLOCK ) /* RTC clock is on */
  271. {
  272. SwitchOnTheClock();
  273. }
  274. #endif
  275. do
  276. EventCheck();
  277. while(1);
  278. }
  279. #endif