1 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #ifndef TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_HIMAX_DRIVER_HM01B0_H_
17 #define TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_HIMAX_DRIVER_HM01B0_H_
18 
19 #if defined(ARDUINO) && !defined(ARDUINO_SFE_EDGE)
20 #define ARDUINO_EXCLUDE_CODE
21 #endif  // defined(ARDUINO) && !defined(ARDUINO_SFE_EDGE)
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 #ifndef ARDUINO_EXCLUDE_CODE
28 #include "am_bsp.h"         // NOLINT
29 #include "am_mcu_apollo.h"  // NOLINT
30 #include "am_util.h"        // NOLINT
31 #endif                      // ARDUINO_EXCLUDE_CODE
32 
33 #if defined(ARDUINO)
34 #include "tensorflow/lite/micro/examples/person_detection/arduino/HM01B0_platform.h"
35 #endif  // defined(ARDUINO)
36 
37 #define HM01B0_DRV_VERSION (0)
38 #define HM01B0_DRV_SUBVERSION (3)
39 
40 #define HM01B0_DEFAULT_ADDRESS (0x24)
41 
42 #define HM01B0_PIXEL_X_NUM (324)
43 #define HM01B0_PIXEL_Y_NUM (244)
44 
45 #define HM01B0_REG_MODEL_ID_H (0x0000)
46 #define HM01B0_REG_MODEL_ID_L (0x0001)
47 #define HM01B0_REG_SILICON_REV (0x0002)
48 #define HM01B0_REG_FRAME_COUNT (0x0005)
49 #define HM01B0_REG_PIXEL_ORDER (0x0006)
50 
51 #define HM01B0_REG_MODE_SELECT (0x0100)
52 #define HM01B0_REG_IMAGE_ORIENTATION (0x0101)
53 #define HM01B0_REG_SW_RESET (0x0103)
54 #define HM01B0_REG_GRP_PARAM_HOLD (0x0104)
55 
56 #define HM01B0_REG_I2C_ID_SEL (0x3400)
57 #define HM01B0_REG_I2C_ID_REG (0x3401)
58 
59 #define HM01B0_REG_PMU_PROGRAMMABLE_FRAMECNT (0x3020)
60 
61 // #define HM01B0_REG_MODE_SELECT (0x0100)
62 #define HM01B0_REG_MODE_SELECT_STANDBY (0x00)
63 #define HM01B0_REG_MODE_SELECT_STREAMING (0x01)
64 #define HM01B0_REG_MODE_SELECT_STREAMING_NFRAMES (0x03)
65 #define HM01B0_REG_MODE_SELECT_STREAMING_HW_TRIGGER (0x05)
66 
67 // #define HM01B0_REG_IMAGE_ORIENTATION                    (0x0101)
68 #define HM01B0_REG_IMAGE_ORIENTATION_DEFAULT (0x00)
69 #define HM01B0_REG_IMAGE_ORIENTATION_HMIRROR (0x01)
70 #define HM01B0_REG_IMAGE_ORIENTATION_VMIRROR (0x02)
71 #define HM01B0_REG_IMAGE_ORIENTATION_HVMIRROR \
72   (HM01B0_REG_IMAGE_ORIENTATION_HMIRROR | HM01B0_REG_IMAGE_ORIENTATION_HVMIRROR)
73 
74 // #define HM01B0_REG_GRP_PARAM_HOLD                       (0x0104)
75 #define HM01B0_REG_GRP_PARAM_HOLD_CONSUME (0x00)
76 #define HM01B0_REG_GRP_PARAM_HOLD_HOLD (0x01)
77 
78 // Helpers for reading raw values from the camera.
79 #define read_vsync() \
80   (AM_REGVAL(AM_REGADDR(GPIO, RDA)) & (1 << HM01B0_PIN_VSYNC))
81 #define read_hsync() \
82   (AM_REGVAL(AM_REGADDR(GPIO, RDA)) & (1 << HM01B0_PIN_HSYNC))
83 #define read_pclk() (AM_REGVAL(AM_REGADDR(GPIO, RDA)) & (1 << HM01B0_PIN_PCLK))
84 #define read_byte() (APBDMA->BBINPUT)
85 
86 enum {
87   HM01B0_ERR_OK = 0x00,
88   HM01B0_ERR_I2C,
89   HM01B0_ERR_MODE,
90 };
91 
92 typedef struct {
93   uint16_t ui16Reg;
94   uint8_t ui8Val;
95 } hm_script_t;
96 
97 typedef struct {
98   uint16_t ui16SlvAddr;
99   am_hal_iom_mode_e eIOMMode;
100   uint32_t ui32IOMModule;
101   am_hal_iom_config_t sIOMCfg;
102   void* pIOMHandle;
103 
104   uint32_t ui32CTimerModule;
105   uint32_t ui32CTimerSegment;
106   uint32_t ui32CTimerOutputPin;
107 
108   uint8_t ui8PinSCL;
109   uint8_t ui8PinSDA;
110   uint8_t ui8PinD0;
111   uint8_t ui8PinD1;
112   uint8_t ui8PinD2;
113   uint8_t ui8PinD3;
114   uint8_t ui8PinD4;
115   uint8_t ui8PinD5;
116   uint8_t ui8PinD6;
117   uint8_t ui8PinD7;
118   uint8_t ui8PinVSYNC;
119   uint8_t ui8PinHSYNC;
120   uint8_t ui8PinPCLK;
121 
122   uint8_t ui8PinTrig;
123   uint8_t ui8PinInt;
124   void (*pfnGpioIsr)(void);
125 } hm01b0_cfg_t;
126 
127 //*****************************************************************************
128 //
129 //! @brief Write HM01B0 registers
130 //!
131 //! @param psCfg                - Pointer to HM01B0 configuration structure.
132 //! @param ui16Reg              - Register address.
133 //! @param pui8Value            - Pointer to the data to be written.
134 //! @param ui32NumBytes         - Length of the data in bytes to be written.
135 //!
136 //! This function writes value to HM01B0 registers.
137 //!
138 //! @return Error code.
139 //
140 //*****************************************************************************
141 static uint32_t hm01b0_write_reg(hm01b0_cfg_t* psCfg, uint16_t ui16Reg,
142                                  uint8_t* pui8Value, uint32_t ui32NumBytes);
143 
144 //*****************************************************************************
145 //
146 //! @brief Read HM01B0 registers
147 //!
148 //! @param psCfg                - Pointer to HM01B0 configuration structure.
149 //! @param ui16Reg              - Register address.
150 //! @param pui8Value            - Pointer to the buffer for read data to be put
151 //! into.
152 //! @param ui32NumBytes         - Length of the data to be read.
153 //!
154 //! This function reads value from HM01B0 registers.
155 //!
156 //! @return Error code.
157 //
158 //*****************************************************************************
159 static uint32_t hm01b0_read_reg(hm01b0_cfg_t* psCfg, uint16_t ui16Reg,
160                                 uint8_t* pui8Value, uint32_t ui32NumBytes);
161 
162 //*****************************************************************************
163 //
164 //! @brief Load HM01B0 a given script
165 //!
166 //! @param psCfg                - Pointer to HM01B0 configuration structure.
167 //! @param psScrip              - Pointer to the script to be loaded.
168 //! @param ui32ScriptCmdNum     - Number of entries in a given script.
169 //!
170 //! This function loads HM01B0 a given script.
171 //!
172 //! @return Error code.
173 //
174 //*****************************************************************************
175 static uint32_t hm01b0_load_script(hm01b0_cfg_t* psCfg, hm_script_t* psScript,
176                                    uint32_t ui32ScriptCmdNum);
177 
178 //*****************************************************************************
179 //
180 //! @brief Power up HM01B0
181 //!
182 //! @param psCfg                - Pointer to HM01B0 configuration structure.
183 //!
184 //! This function powers up HM01B0.
185 //!
186 //! @return none.
187 //
188 //*****************************************************************************
189 void hm01b0_power_up(hm01b0_cfg_t* psCfg);
190 
191 //*****************************************************************************
192 //
193 //! @brief Power down HM01B0
194 //!
195 //! @param psCfg                - Pointer to HM01B0 configuration structure.
196 //!
197 //! This function powers up HM01B0.
198 //!
199 //! @return none.
200 //
201 //*****************************************************************************
202 void hm01b0_power_down(hm01b0_cfg_t* psCfg);
203 
204 //*****************************************************************************
205 //
206 //! @brief Enable MCLK
207 //!
208 //! @param psCfg                - Pointer to HM01B0 configuration structure.
209 //!
210 //! This function utilizes CTimer to generate MCLK for HM01B0.
211 //!
212 //! @return none.
213 //
214 //*****************************************************************************
215 void hm01b0_mclk_enable(hm01b0_cfg_t* psCfg);
216 
217 //*****************************************************************************
218 //
219 //! @brief Disable MCLK
220 //!
221 //! @param psCfg                - Pointer to HM01B0 configuration structure.
222 //!
223 //! This function disable CTimer to stop MCLK for HM01B0.
224 //!
225 //! @return none.
226 //
227 //*****************************************************************************
228 void hm01b0_mclk_disable(hm01b0_cfg_t* psCfg);
229 
230 //*****************************************************************************
231 //
232 //! @brief Initialize interfaces
233 //!
234 //! @param psCfg                - Pointer to HM01B0 configuration structure.
235 //!
236 //! This function initializes interfaces.
237 //!
238 //! @return Error code.
239 //
240 //*****************************************************************************
241 uint32_t hm01b0_init_if(hm01b0_cfg_t* psCfg);
242 
243 //*****************************************************************************
244 //
245 //! @brief Deinitialize interfaces
246 //!
247 //! @param psCfg                - Pointer to HM01B0 configuration structure.
248 //!
249 //! This function deinitializes interfaces.
250 //!
251 //! @return Error code.
252 //
253 //*****************************************************************************
254 uint32_t hm01b0_deinit_if(hm01b0_cfg_t* psCfg);
255 
256 //*****************************************************************************
257 //
258 //! @brief Get HM01B0 Model ID
259 //!
260 //! @param psCfg                - Pointer to HM01B0 configuration structure.
261 //! @param pui16MID             - Pointer to buffer for the read back model ID.
262 //!
263 //! This function reads back HM01B0 model ID.
264 //!
265 //! @return Error code.
266 //
267 //*****************************************************************************
268 uint32_t hm01b0_get_modelid(hm01b0_cfg_t* psCfg, uint16_t* pui16MID);
269 
270 //*****************************************************************************
271 //
272 //! @brief Initialize HM01B0
273 //!
274 //! @param psCfg                - Pointer to HM01B0 configuration structure.
275 //! @param psScript             - Pointer to HM01B0 initialization script.
276 //! @param ui32ScriptCmdNum     - No. of commands in HM01B0 initialization
277 //! script.
278 //!
279 //! This function initializes HM01B0 with a given script.
280 //!
281 //! @return Error code.
282 //
283 //*****************************************************************************
284 uint32_t hm01b0_init_system(hm01b0_cfg_t* psCfg, hm_script_t* psScript,
285                             uint32_t ui32ScriptCmdNum);
286 
287 //*****************************************************************************
288 //
289 //! @brief Set HM01B0 in the walking 1s test mode
290 //!
291 //! @param psCfg                - Pointer to HM01B0 configuration structure.
292 //!
293 //! This function sets HM01B0 in the walking 1s test mode.
294 //!
295 //! @return Error code.
296 //
297 //*****************************************************************************
298 uint32_t hm01b0_test_walking1s(hm01b0_cfg_t* psCfg);
299 
300 //*****************************************************************************
301 //
302 //! @brief Software reset HM01B0
303 //!
304 //! @param psCfg        - Pointer to HM01B0 configuration structure.
305 //!
306 //! This function resets HM01B0 by issuing a reset command.
307 //!
308 //! @return Error code.
309 //
310 //*****************************************************************************
311 uint32_t hm01b0_reset_sw(hm01b0_cfg_t* psCfg);
312 
313 //*****************************************************************************
314 //
315 //! @brief Get current HM01B0 operation mode.
316 //!
317 //! @param psCfg        - Pointer to HM01B0 configuration structure.
318 //! @param pui8Mode     - Pointer to buffer
319 //!                     - for the read back operation mode to be put into
320 //!
321 //! This function get HM01B0 operation mode.
322 //!
323 //! @return Error code.
324 //
325 //*****************************************************************************
326 uint32_t hm01b0_get_mode(hm01b0_cfg_t* psCfg, uint8_t* pui8Mode);
327 
328 //*****************************************************************************
329 //
330 //! @brief Set HM01B0 operation mode.
331 //!
332 //! @param psCfg        - Pointer to HM01B0 configuration structure.
333 //! @param ui8Mode      - Operation mode. One of:
334 //!     HM01B0_REG_MODE_SELECT_STANDBY
335 //!     HM01B0_REG_MODE_SELECT_STREAMING
336 //!     HM01B0_REG_MODE_SELECT_STREAMING_NFRAMES
337 //!     HM01B0_REG_MODE_SELECT_STREAMING_HW_TRIGGER
338 //! @param framecnt     - Frame count for
339 //! HM01B0_REG_MODE_SELECT_STREAMING_NFRAMES.
340 //!                     - Discarded if other modes.
341 //!
342 //! This function set HM01B0 operation mode.
343 //!
344 //! @return Error code.
345 //
346 //*****************************************************************************
347 uint32_t hm01b0_set_mode(hm01b0_cfg_t* psCfg, uint8_t ui8Mode,
348                          uint8_t framecnt);
349 
350 //*****************************************************************************
351 //
352 //! @brief Hardware trigger HM01B0 to stream.
353 //!
354 //! @param psCfg        - Pointer to HM01B0 configuration structure.
355 //! @param bTrigger     - True to start streaming
356 //!                     - False to stop streaming
357 //!
358 //! This function triggers HM01B0 to stream by toggling the TRIG pin.
359 //!
360 //! @return Error code.
361 //
362 //*****************************************************************************
363 uint32_t hm01b0_hardware_trigger_streaming(hm01b0_cfg_t* psCfg, bool bTrigger);
364 
365 //*****************************************************************************
366 //
367 //! @brief Set HM01B0 mirror mode.
368 //!
369 //! @param psCfg        - Pointer to HM01B0 configuration structure.
370 //! @param bHmirror     - Horizontal mirror
371 //! @param bVmirror     - Vertical mirror
372 //!
373 //! This function set HM01B0 mirror mode.
374 //!
375 //! @return Error code.
376 //
377 //*****************************************************************************
378 uint32_t hm01b0_set_mirror(hm01b0_cfg_t* psCfg, bool bHmirror, bool bVmirror);
379 
380 //*****************************************************************************
381 //
382 //! @brief Read data of one frame from HM01B0.
383 //!
384 //! @param psCfg            - Pointer to HM01B0 configuration structure.
385 //! @param pui8Buffer       - Pointer to the frame buffer.
386 //! @param ui32BufferLen    - Framebuffer size.
387 //!
388 //! This function read data of one frame from HM01B0.
389 //!
390 //! @return Error code.
391 //
392 //*****************************************************************************
393 uint32_t hm01b0_blocking_read_oneframe(hm01b0_cfg_t* psCfg, uint8_t* pui8Buffer,
394                                        uint32_t ui32BufferLen);
395 
396 //*****************************************************************************
397 //
398 //! @brief Read data of one frame from HM01B0.
399 //!
400 //! @param psCfg            - Pointer to HM01B0 configuration structure.
401 //!
402 //! This function wakes up the camera and captures a single frame.
403 //!
404 //! @return Error code.
405 //
406 //*****************************************************************************
407 uint32_t hm01b0_single_frame_capture(hm01b0_cfg_t* psCfg);
408 
409 #ifdef __cplusplus
410 }
411 #endif
412 
413 #endif  // TENSORFLOW_LITE_MICRO_EXAMPLES_PERSON_DETECTION_HIMAX_DRIVER_HM01B0_H_
414