imc_api.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /*
  2. * imc_api.c
  3. *
  4. * Created on: Jul 21, 2022
  5. * Author: yoojin.lim (yoojin.lim@etri.re.kr)
  6. */
  7. #include <stdio.h>
  8. #include "cmsis_os.h"
  9. #include "ImC/imc_api.h"
  10. #include "sc03mpd/sc03mpd.h"
  11. #include "ImC/decoder.h"
  12. /**
  13. * @brief turn Set of 4 LEDs ON and OFF after msec
  14. * @param argument:
  15. * ledSet : indicates LED 0~3
  16. * e.g. {1,0,1,0} for LED 0 and LED 2 are ON
  17. * length : number of LEDs (ledSet)
  18. * msec : ON duration
  19. * @retval None
  20. */
  21. void imc_led_on (uint8_t ledSet[], uint8_t length, uint32_t msec)
  22. {
  23. HAL_GPIO_WritePin(LED0_GPIO, LED0_GPIO_PIN, GPIO_PIN_RESET); // LED0 OFF
  24. HAL_GPIO_WritePin(LED1_GPIO, LED1_GPIO_PIN, GPIO_PIN_RESET); // LED1 OFF
  25. HAL_GPIO_WritePin(LED2_GPIO, LED2_GPIO_PIN, GPIO_PIN_RESET); // LED2 OFF
  26. HAL_GPIO_WritePin(LED3_GPIO, LED3_GPIO_PIN, GPIO_PIN_RESET); // LED3 OFF
  27. for ( uint8_t i = 0; i < length ; i++ ) {
  28. if ( ledSet[i] )
  29. {
  30. switch (i) { // LED ON
  31. case 0: HAL_GPIO_WritePin(LED0_GPIO, LED0_GPIO_PIN, GPIO_PIN_SET); break;
  32. case 1: HAL_GPIO_WritePin(LED1_GPIO, LED1_GPIO_PIN, GPIO_PIN_SET); break;
  33. case 2: HAL_GPIO_WritePin(LED2_GPIO, LED2_GPIO_PIN, GPIO_PIN_SET); break;
  34. case 3: HAL_GPIO_WritePin(LED3_GPIO, LED3_GPIO_PIN, GPIO_PIN_SET); break;
  35. }
  36. }
  37. }
  38. osDelay(msec);
  39. HAL_GPIO_WritePin(LED0_GPIO, LED0_GPIO_PIN, GPIO_PIN_RESET); // LED0 OFF
  40. HAL_GPIO_WritePin(LED1_GPIO, LED1_GPIO_PIN, GPIO_PIN_RESET); // LED1 OFF
  41. HAL_GPIO_WritePin(LED2_GPIO, LED2_GPIO_PIN, GPIO_PIN_RESET); // LED2 OFF
  42. HAL_GPIO_WritePin(LED3_GPIO, LED3_GPIO_PIN, GPIO_PIN_RESET); // LED3 OFF
  43. }
  44. /**
  45. * @brief turn Set of 4 LEDs ON and OFF after msec
  46. * @param argument:
  47. * ledSet : indicates LED 0~3
  48. * e.g. {1,0,1,0} for LED 0 and LED 2 are ON
  49. * length : number of LEDs (ledSet)
  50. * msec : blink period
  51. * @retval None
  52. */
  53. void imc_led_blink (uint8_t ledSet[], uint8_t length, uint32_t msec)
  54. {
  55. imc_led_on (ledSet, length, msec);
  56. osDelay(msec);
  57. }
  58. int32_t imc_sc03mpd_init (sc03mpd_ifx_t* ifx)
  59. {
  60. /* initial operation process :
  61. * 1) power up
  62. * 2) delay 2.5s
  63. * 3) reset command
  64. * 4) set image resolution command (currently 160x120)
  65. * 5) set image compressibility command
  66. * 6) reset command
  67. * Note: after setting the desired image size, you need to reset the camera first,
  68. * and then the new setting would be enabled.
  69. * OPTION for SKKU) manually step color, select black-white
  70. */
  71. /* //move to main.c
  72. #if !CAM_FAST_READY
  73. printf("[CAM] wait %dms for boot-up\r\n", DELAY_AFTER_POWERUP);
  74. osDelay (DELAY_AFTER_POWERUP);
  75. #endif
  76. //printf("[SC03MPD] init CAM ...\r\n");
  77. MX_USART3_UART_Init();
  78. */
  79. SC03MPD_ASSERT(sc03mpd_reset(ifx), "[CAM] FAILED reset", INIT_ERROR)
  80. SC03MPD_ASSERT(sc03mpd_set_ires(ifx, IMAGE_RESOLUTION), "[CAM] FAILED set resolution", INIT_ERROR)
  81. SC03MPD_ASSERT(sc03mpd_reset(ifx), "[CAM] FAILED reset for image setting", INIT_ERROR)
  82. SC03MPD_ASSERT(sc03mpd_set_icmp(ifx, 0x00), "[CAM] FAILED set compression rate", INIT_ERROR)
  83. #if CAM_BLACK_WHITE
  84. // after reset color mode setting is initialized
  85. SC03MPD_ASSERT(sc03mpd_reset(ifx), "[CAM] FAILED reset for image setting", INIT_ERROR)
  86. SC03MPD_ASSERT(sc03mpd_set_clr(ifx, SC03MPD_CLR_BW), "[CAM] FAILED set black-white", INIT_ERROR)
  87. #endif
  88. printf("[CAM] OK init\r\n");
  89. return CAM_STS_ENON;
  90. INIT_ERROR:
  91. return CAM_STS_EINI;
  92. }
  93. uint16_t ilen = 0;
  94. uint8_t buf[4096];
  95. /* 2022. 8. 25. fix logical seq. error under V0706 protocol; stop -> read length -> read data -> resume */
  96. int32_t imc_sc03mpd_capture (sc03mpd_ifx_t* ifx) {
  97. //printf("[SC03MPD] start capture ...\r\n");
  98. /* CAPTURE */
  99. SC03MPD_ASSERT(sc03mpd_capture(ifx), "[CAM] FAILED capture", CAPTURE_ERROR)
  100. osDelay (DELAY_AFTER_CAPTURE);
  101. /* GET length */
  102. ilen = 0;
  103. SC03MPD_ASSERT(sc03mpd_get_ilen(ifx, &ilen), "[CAM] FAILED get length", CAPTURE_ERROR)
  104. printf("[CAM] OK capture (length = %d, %04X)\r\n", ilen, ilen);
  105. osDelay (DELAY_AFTER_LENGTH);
  106. /* READ image data */
  107. //printf("[SC03MPD] download to 0x%08X\r\n", IMG_RAM_ADDR);
  108. // uint8_t* imem = (uint8_t*)IMG_RAM_ADDR;
  109. uint8_t* imem = (uint8_t*)buf;
  110. uint16_t addr = 0;
  111. uint16_t nreq = 0;
  112. uint16_t rest = ilen;
  113. uint32_t tsStart = 0;
  114. uint32_t tsEnd = 0;
  115. tsStart = HAL_GetTick();
  116. while (rest > 0)
  117. {
  118. nreq = (rest > IMG_BLK_SIZE)? IMG_BLK_SIZE : rest;
  119. if (sc03mpd_get_idat(ifx, addr, nreq, imem))
  120. {
  121. printf("[CAM] FAILED download: %04X (%d)\r\n", addr, nreq);
  122. goto CAPTURE_ERROR;
  123. }
  124. //printf ("#READ: %04X (%d), DATA: %02X\r\n", addr, nreq, *imem);
  125. rest -= nreq;
  126. addr += nreq;
  127. imem += nreq;
  128. //osDelay(DELAY_DURING_DOWNLOAD);
  129. }
  130. tsEnd = HAL_GetTick();
  131. printf("[CAM] OK download; %lu ticks, 0x%08X to 0x%08X\r\n", tsEnd-tsStart, IMG_RAM_ADDR, IMG_RAM_ADDR+ilen);
  132. #if CAM_IMAGE_FIRST_TWO_BYTES
  133. /* Note: JPEG IMAGE DATA must be FF D8 in first and FF D9 in end.
  134. * 2022. 7. 20. ETRI can not assure that the EOI is FF D9.
  135. * */
  136. printf("[SC03MPD] image data (first 2 bytes): ");
  137. uint8_t* aimg = (uint8_t*)IMG_RAM_ADDR;
  138. for ( uint16_t i = 0; i < 2; i++, aimg++ )
  139. printf("%02X ", *aimg);
  140. printf("\r\n");
  141. printf("\r\n");
  142. #endif
  143. /* STOP CAPTURE = RESUME */
  144. SC03MPD_ASSERT(sc03mpd_stop(ifx), "[CAM] FAILED stop", CAPTURE_ERROR)
  145. printf("[CAM] OK stop capture\r\n");
  146. return CAM_STS_ENON;
  147. CAPTURE_ERROR:
  148. return CAM_STS_ECAP;
  149. }
  150. int32_t imc_sc03mpd_reset (sc03mpd_ifx_t* ifx)
  151. {
  152. SC03MPD_ASSERT(sc03mpd_reset(ifx), "[CAM] FAILED reset", RESET_ERROR)
  153. printf("[CAM] OK reset\r\n");
  154. return CAM_STS_ENON;
  155. RESET_ERROR:
  156. return CAM_STS_EINI;
  157. }
  158. void imc_sbc_power_off ()
  159. {
  160. // printf("[EPS] SBC OFF\r\n");
  161. HAL_GPIO_WritePin(SBC_POWER_GPIO, SBC_POWER_GPIO_PIN, POWER_OFF_SBC);
  162. }
  163. void imc_sbc_power_on ()
  164. {
  165. printf("[EPS] SBC on\r\n");
  166. HAL_GPIO_WritePin(SBC_POWER_GPIO, SBC_POWER_GPIO_PIN, POWER_ON_SBC);
  167. }
  168. void imc_cam_power_off ()
  169. {
  170. printf("[EPS] CAM OFF\r\n");
  171. HAL_GPIO_WritePin(CAM_POWER_GPIO, CAM_POWER_GPIO_PIN, POWER_OFF);
  172. }
  173. void imc_cam_power_on ()
  174. {
  175. printf("[EPS] CAM ON\r\n");
  176. HAL_GPIO_WritePin(CAM_POWER_GPIO, CAM_POWER_GPIO_PIN, POWER_ON);
  177. }
  178. #if (EPS_CAP_VOLT_GPIO)
  179. /*
  180. * energy level : 0~7 with 3bits of GPIO pins
  181. * ignore level update between reading each pin
  182. *
  183. * (2022.11.10.) read the level three times (per 3ms), and return lower level
  184. *
  185. */
  186. uint8_t imc_get_energy_level ()
  187. {
  188. uint8_t curr = 8;
  189. uint8_t bigger = 0;
  190. for (uint8_t i = 0; i < 3; i ++)
  191. {
  192. curr = (HAL_GPIO_ReadPin(ENERGY_LV0_GPIO, ENERGY_LV0_GPIO_PIN)
  193. + (HAL_GPIO_ReadPin(ENERGY_LV1_GPIO, ENERGY_LV1_GPIO_PIN) << 1)
  194. + (HAL_GPIO_ReadPin(ENERGY_LV2_GPIO, ENERGY_LV2_GPIO_PIN) << 2));
  195. if ( (curr > bigger) && (curr > 0) )
  196. bigger = curr;
  197. osDelay(DELAY_GET_ENERGY_LEVEL);
  198. }
  199. return bigger;
  200. }
  201. #endif
  202. #if (EPS_CAP_VOLT_ADC)
  203. int compare(const void *a, const void *b) {
  204. return (*(int*)a - *(int*)b);
  205. }
  206. int medianCalc(int* input, int arr_size){
  207. qsort(input, arr_size, sizeof(int), compare);
  208. if (arr_size%2)
  209. return input[arr_size/2];
  210. else
  211. return (input[arr_size/2-1] + input[arr_size/2])/2;
  212. }
  213. // uint16_t MEAS_COEF[2] = {812, 782}; // for EPS CAP ch0 and ch1
  214. // uint16_t MEAS_COEF[2] = {700, 782}; // imc, 10mF
  215. // uint16_t MEAS_COEF[2] = {765, 782}; // imc, 4.7mF, voltage divider
  216. // uint16_t MEAS_COEF[2] = {771, 782}; // imc, 4.7mF, voltage divider
  217. uint16_t MEAS_COEF[2] = {1050, 782}; // imc, 4.7mF, voltage divider
  218. int measure_voltage(ADC_HandleTypeDef hadc, uint8_t ch){
  219. int val;
  220. // for(int i=0; i<100; i++) { __ASM(" nop"); }
  221. // osDelay(1);
  222. HAL_ADC_Start(&hadc);
  223. // Poll ADC Peripheral & TimeOut = 1mSec
  224. HAL_ADC_PollForConversion(&hadc, 1);
  225. val = HAL_ADC_GetValue(&hadc);
  226. HAL_ADC_Stop(&hadc);
  227. return val * MEAS_COEF[ch] / 500;
  228. int n_evals = 5;
  229. int res_value[n_evals];
  230. /* UCR ref.
  231. #define MEAS_COEF 3051 // UCR 2790, ETRI 3051
  232. int v_value = ((uint32_t)medianCalc(res_value, 5))*5000/MEAS_COEF; // in milliVolt
  233. */
  234. for (int i=0; i<n_evals; i++)
  235. {
  236. HAL_ADC_Start(&hadc);
  237. // Poll ADC Peripheral & TimeOut = 1mSec
  238. HAL_ADC_PollForConversion(&hadc, 1);
  239. res_value[i] = HAL_ADC_GetValue(&hadc);
  240. HAL_ADC_Stop(&hadc);
  241. }
  242. int v_value = ((uint32_t)medianCalc(res_value, n_evals)) * MEAS_COEF[ch] / 500; //
  243. // int voltage_d = v_value/1000;
  244. // int voltage_f = v_value%1000;
  245. // printf("ADC Value: %d.%03d \r\n", voltage_d, voltage_f);
  246. return v_value;
  247. }
  248. int32_t imc_sc03mpd_cap_check (ADC_HandleTypeDef hadc)
  249. {
  250. int count = 0;
  251. int capacitor_voltage = measure_voltage(hadc, EPS_CAP_ID_CAM);
  252. if (capacitor_voltage < EPS_CAP_VOLT_LOW_THRESHOLD_CAM)
  253. {
  254. imc_cam_power_off();
  255. printf ("[CAM] CAP#%d < %dmV\r\n", EPS_CAP_ID_CAM, EPS_CAP_VOLT_LOW_THRESHOLD_CAM);
  256. while (capacitor_voltage < EPS_CAP_VOLT_HIGH_THRESHOLD_CAM) {
  257. printf ("\twait(%2d) %dmV\r\n", count, capacitor_voltage);
  258. osDelay (DELAY_WAIT_CAP_CHECK);
  259. if (count >= COUNTER_WAIT_CAP_CHECK){
  260. return CAM_STS_EINI;
  261. }
  262. capacitor_voltage = measure_voltage(hadc, EPS_CAP_ID_CAM);
  263. count++;
  264. }
  265. printf ("[CAM] CAP#%d > %dV\r\n", EPS_CAP_ID_CAM, EPS_CAP_VOLT_HIGH_THRESHOLD_CAM);
  266. }
  267. return CAM_STS_ENON;
  268. }
  269. #endif