class pah8011 for mbed

Committer:
bell_huang
Date:
Wed Jan 23 08:01:57 2019 +0000
Revision:
6:d196b612b14a
Parent:
0:242cf8f28bf2
Remove mbed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bell_huang 0:242cf8f28bf2 1 /*==============================================================================
bell_huang 0:242cf8f28bf2 2 * Edit History
bell_huang 0:242cf8f28bf2 3 *
bell_huang 0:242cf8f28bf2 4 * This section contains comments describing changes made to the module. Notice
bell_huang 0:242cf8f28bf2 5 * that changes are listed in reverse chronological order. Please use ISO format
bell_huang 0:242cf8f28bf2 6 * for dates.
bell_huang 0:242cf8f28bf2 7 *
bell_huang 0:242cf8f28bf2 8 * when version who what, where, why
bell_huang 0:242cf8f28bf2 9 * ---------- ------ --- -----------------------------------------------------------
bell_huang 0:242cf8f28bf2 10 * 2016-11-09 1009 bh - Update pah_driver_8011_reg.h.
bell_huang 0:242cf8f28bf2 11 * -- Fix green LEDs were turned on weakly when touch mode.
bell_huang 0:242cf8f28bf2 12 * 2016-10-20 1008 bh - Merge v1007 + v10052.
bell_huang 0:242cf8f28bf2 13 * -- Move some code to new file pah_8011_internal for reuse.
bell_huang 0:242cf8f28bf2 14 * -- Support variable channel number settings.
bell_huang 0:242cf8f28bf2 15 * -- Support ET device package (former driver support ES device package only).
bell_huang 0:242cf8f28bf2 16 * -- Add function: pah_get_fifo_ch_num().
bell_huang 0:242cf8f28bf2 17 * -- Add flags: pah_stream_e, pah_intshape_pulse_type_e, pah_powerdown_int_status_e.
bell_huang 0:242cf8f28bf2 18 * -- Remove debug_trace debug log because it's rare to disable.
bell_huang 0:242cf8f28bf2 19 * 2016-10-18 10052 bh - Fix pah_init didn't shutdown.
bell_huang 0:242cf8f28bf2 20 * 2016-09-08 10051 bh - Created branch v10051
bell_huang 0:242cf8f28bf2 21 * - Add functions: pah_init_with_flags().
bell_huang 0:242cf8f28bf2 22 * - Add pah_ppg_led_on_e flag.
bell_huang 0:242cf8f28bf2 23 * - Replace all update flag reg setting with _pah8011_update_flag().
bell_huang 0:242cf8f28bf2 24 * - Remove useless comments
bell_huang 0:242cf8f28bf2 25 * 2016-07-07 1004 bh - Move reg array settings to new source files.
bell_huang 0:242cf8f28bf2 26 * 2016-07-01 1003 bh - Fix undefined behaviors when the device wakes up from power down mode. Delay is necessary for the internal controller to reset the whole system and then the device is ready for the upcoming operations.
bell_huang 0:242cf8f28bf2 27 * 2016-06-07 1002 bh - Add functions: pah_set_mode(), pah_run_device().
bell_huang 0:242cf8f28bf2 28 * - Add enum: pah_device.
bell_huang 0:242cf8f28bf2 29 * 2016-04-29 1001 bh - Add PPG 200Hz modes.
bell_huang 0:242cf8f28bf2 30 * - Add helper functions: pah_is_ppg_mode(), pah_is_ppg_20hz_mode(), pah_fifo_data_num_per_ch().
bell_huang 0:242cf8f28bf2 31 * - Add pah_stop_mode
bell_huang 0:242cf8f28bf2 32 * - Remove pah_suspend_mode.
bell_huang 0:242cf8f28bf2 33 * - Fix setting pah_set_report_sample_num_per_ch() after enter_mode() causes bad behavior.
bell_huang 0:242cf8f28bf2 34 * 2016-04-14 1000 bh - Add version.
bell_huang 0:242cf8f28bf2 35 * 2016-04-12 bh - Add license information and revision information.
bell_huang 0:242cf8f28bf2 36 * - Modify to reduce the reaction time of touch/no-touch detect.
bell_huang 0:242cf8f28bf2 37 * 2016-04-07 bh - Initial revision.
bell_huang 0:242cf8f28bf2 38 ==============================================================================*/
bell_huang 0:242cf8f28bf2 39
bell_huang 0:242cf8f28bf2 40 #include "pah_driver.h"
bell_huang 0:242cf8f28bf2 41
bell_huang 0:242cf8f28bf2 42 // pah
bell_huang 0:242cf8f28bf2 43 #include "pah_driver_8011_reg_array.h"
bell_huang 0:242cf8f28bf2 44 #include "pah_8011_internal.h"
bell_huang 0:242cf8f28bf2 45 #include "pah_comm.h"
bell_huang 0:242cf8f28bf2 46
bell_huang 0:242cf8f28bf2 47 // platform support
bell_huang 0:242cf8f28bf2 48 #include "pah_platform_functions.h"
bell_huang 0:242cf8f28bf2 49
bell_huang 0:242cf8f28bf2 50
bell_huang 0:242cf8f28bf2 51 /*============================================================================
bell_huang 0:242cf8f28bf2 52 VALUE MACRO DEFINITIONS
bell_huang 0:242cf8f28bf2 53 ============================================================================*/
bell_huang 0:242cf8f28bf2 54 #define PAH_DRIVER_8011_VERSION 1009
bell_huang 0:242cf8f28bf2 55
bell_huang 0:242cf8f28bf2 56 #define DEFAULT_REPORT_SAMPLE_NUM_PER_CH 20
bell_huang 0:242cf8f28bf2 57
bell_huang 0:242cf8f28bf2 58 #define MAX_SAMPLES_PER_READ 396
bell_huang 0:242cf8f28bf2 59 #define MAX_CH_NUM 3
bell_huang 0:242cf8f28bf2 60 #define BYTES_PER_SAMPLE 4
bell_huang 0:242cf8f28bf2 61
bell_huang 0:242cf8f28bf2 62 #define PPG_FRAME_INTERVAL_MS 60 // 50 * 120%
bell_huang 0:242cf8f28bf2 63
bell_huang 0:242cf8f28bf2 64
bell_huang 0:242cf8f28bf2 65 /*============================================================================
bell_huang 0:242cf8f28bf2 66 OPTION MACRO DEFINITIONS
bell_huang 0:242cf8f28bf2 67 ============================================================================*/
bell_huang 0:242cf8f28bf2 68 //#define ENABLE_FIFO_CHECKSUM
bell_huang 0:242cf8f28bf2 69
bell_huang 0:242cf8f28bf2 70
bell_huang 0:242cf8f28bf2 71 /*============================================================================
bell_huang 0:242cf8f28bf2 72 TYPE DEFINITIONS
bell_huang 0:242cf8f28bf2 73 ============================================================================*/
bell_huang 0:242cf8f28bf2 74 typedef enum {
bell_huang 0:242cf8f28bf2 75
bell_huang 0:242cf8f28bf2 76 pah_fifo_freq_none,
bell_huang 0:242cf8f28bf2 77 pah_fifo_freq_20hz,
bell_huang 0:242cf8f28bf2 78 pah_fifo_freq_200hz,
bell_huang 0:242cf8f28bf2 79
bell_huang 0:242cf8f28bf2 80 } pah_fifo_freq;
bell_huang 0:242cf8f28bf2 81
bell_huang 0:242cf8f28bf2 82
bell_huang 0:242cf8f28bf2 83 typedef struct {
bell_huang 0:242cf8f28bf2 84
bell_huang 0:242cf8f28bf2 85 uint32_t report_sample_num_per_ch;
bell_huang 0:242cf8f28bf2 86 uint8_t is_int2_as_touch_flag;
bell_huang 0:242cf8f28bf2 87
bell_huang 0:242cf8f28bf2 88 } pah8011_property_s;
bell_huang 0:242cf8f28bf2 89
bell_huang 0:242cf8f28bf2 90
bell_huang 0:242cf8f28bf2 91 typedef struct {
bell_huang 0:242cf8f28bf2 92
bell_huang 0:242cf8f28bf2 93 // fifo data
bell_huang 0:242cf8f28bf2 94 uint8_t fifo_data[MAX_SAMPLES_PER_READ * BYTES_PER_SAMPLE];
bell_huang 0:242cf8f28bf2 95
bell_huang 0:242cf8f28bf2 96 // update every task
bell_huang 0:242cf8f28bf2 97 uint32_t fifo_data_num_per_ch;
bell_huang 0:242cf8f28bf2 98
bell_huang 0:242cf8f28bf2 99 // flags
bell_huang 0:242cf8f28bf2 100 pah_flags_s flags;
bell_huang 0:242cf8f28bf2 101
bell_huang 0:242cf8f28bf2 102 // report ppg data
bell_huang 0:242cf8f28bf2 103 void* user_data;
bell_huang 0:242cf8f28bf2 104 pah_report_fifo_handle fp_report_fifo_handler;
bell_huang 0:242cf8f28bf2 105
bell_huang 0:242cf8f28bf2 106 // private members
bell_huang 0:242cf8f28bf2 107 uint8_t has_started_tg;
bell_huang 0:242cf8f28bf2 108 uint8_t has_started_ppg;
bell_huang 0:242cf8f28bf2 109 uint8_t has_started_touch;
bell_huang 0:242cf8f28bf2 110 uint8_t fifo_data_contain_touch_bit;
bell_huang 0:242cf8f28bf2 111
bell_huang 0:242cf8f28bf2 112 // read only properties
bell_huang 0:242cf8f28bf2 113 pah_mode mode;
bell_huang 0:242cf8f28bf2 114 uint8_t touch_flag;
bell_huang 0:242cf8f28bf2 115
bell_huang 0:242cf8f28bf2 116 //// flag options
bell_huang 0:242cf8f28bf2 117 // pah_ppg_led_on_e
bell_huang 0:242cf8f28bf2 118 uint8_t is_led_on;
bell_huang 0:242cf8f28bf2 119
bell_huang 0:242cf8f28bf2 120 // properties
bell_huang 0:242cf8f28bf2 121 pah8011_property_s prop_curr;
bell_huang 0:242cf8f28bf2 122 pah8011_property_s prop_next;
bell_huang 0:242cf8f28bf2 123
bell_huang 0:242cf8f28bf2 124 } pah8011_state_s;
bell_huang 0:242cf8f28bf2 125
bell_huang 0:242cf8f28bf2 126
bell_huang 0:242cf8f28bf2 127 /*============================================================================
bell_huang 0:242cf8f28bf2 128 PRIVATE GLOBAL VARIABLES
bell_huang 0:242cf8f28bf2 129 ============================================================================*/
bell_huang 0:242cf8f28bf2 130 static bool g_init = false;
bell_huang 0:242cf8f28bf2 131 static pah8011_state_s g_state;
bell_huang 0:242cf8f28bf2 132
bell_huang 0:242cf8f28bf2 133
bell_huang 0:242cf8f28bf2 134 /*============================================================================
bell_huang 0:242cf8f28bf2 135 PRIVATE FUNCTION PROTOTYPES
bell_huang 0:242cf8f28bf2 136 ============================================================================*/
bell_huang 0:242cf8f28bf2 137 //// pure functions
bell_huang 0:242cf8f28bf2 138 static bool _pah_is_ppg_mode(pah_mode mode);
bell_huang 0:242cf8f28bf2 139 static pah_fifo_freq _pah_mode_to_freq(pah_mode mode);
bell_huang 0:242cf8f28bf2 140 static bool _pah_is_diff_fifo_freq(pah_mode lhs_mode, pah_mode rhs_mode);
bell_huang 0:242cf8f28bf2 141
bell_huang 0:242cf8f28bf2 142 //// pah8011
bell_huang 0:242cf8f28bf2 143 static bool _pah8011_init(void);
bell_huang 0:242cf8f28bf2 144
bell_huang 0:242cf8f28bf2 145 static bool _pah8011_shutdown(void);
bell_huang 0:242cf8f28bf2 146 static bool _pah8011_startup(void);
bell_huang 0:242cf8f28bf2 147
bell_huang 0:242cf8f28bf2 148 static bool _pah8011_start_tg(void);
bell_huang 0:242cf8f28bf2 149
bell_huang 0:242cf8f28bf2 150 static bool _pah8011_start_ppg(void);
bell_huang 0:242cf8f28bf2 151 static bool _pah8011_stop_ppg(void);
bell_huang 0:242cf8f28bf2 152 static bool _pah8011_start_touch(void);
bell_huang 0:242cf8f28bf2 153 static bool _pah8011_stop_touch(void);
bell_huang 0:242cf8f28bf2 154
bell_huang 0:242cf8f28bf2 155 static bool _pah8011_clear_fifo_and_int_req(void);
bell_huang 0:242cf8f28bf2 156 static bool _pah8011_update_report_num(void);
bell_huang 0:242cf8f28bf2 157 static bool _pah8011_set_report_num(uint32_t samples_per_read);
bell_huang 0:242cf8f28bf2 158 static bool _pah8011_turn_led(bool on);
bell_huang 0:242cf8f28bf2 159
bell_huang 0:242cf8f28bf2 160 #if defined(ENABLE_FIFO_CHECKSUM)
bell_huang 0:242cf8f28bf2 161 static bool _pah8011_cks(uint8_t *fifo, uint32_t samples_read, uint32_t cks_read);
bell_huang 0:242cf8f28bf2 162 #endif // ENABLE_FIFO_CHECKSUM
bell_huang 0:242cf8f28bf2 163
bell_huang 0:242cf8f28bf2 164 static bool _pah8011_read_touch_flag(uint8_t *touch_flag);
bell_huang 0:242cf8f28bf2 165
bell_huang 0:242cf8f28bf2 166 static pah_ret _pah8011_task_dri(uint8_t int_req, uint32_t ch_num);
bell_huang 0:242cf8f28bf2 167 static pah_ret _pah8011_task_polling(uint8_t int_req, uint32_t ch_num);
bell_huang 0:242cf8f28bf2 168
bell_huang 0:242cf8f28bf2 169
bell_huang 0:242cf8f28bf2 170 /*============================================================================
bell_huang 0:242cf8f28bf2 171 PUBLIC FUNCTION DEFINITIONS
bell_huang 0:242cf8f28bf2 172 ============================================================================*/
bell_huang 0:242cf8f28bf2 173 void pah_flags_default(pah_flags_s *flags)
bell_huang 0:242cf8f28bf2 174 {
bell_huang 0:242cf8f28bf2 175 if (!flags)
bell_huang 0:242cf8f28bf2 176 return;
bell_huang 0:242cf8f28bf2 177
bell_huang 0:242cf8f28bf2 178 memset(flags, 0, sizeof(*flags));
bell_huang 0:242cf8f28bf2 179 }
bell_huang 0:242cf8f28bf2 180
bell_huang 0:242cf8f28bf2 181 bool pah_init(void)
bell_huang 0:242cf8f28bf2 182 {
bell_huang 0:242cf8f28bf2 183 pah_flags_s flags;
bell_huang 0:242cf8f28bf2 184
bell_huang 0:242cf8f28bf2 185 pah_flags_default(&flags);
bell_huang 0:242cf8f28bf2 186
bell_huang 0:242cf8f28bf2 187 return pah_init_with_flags(&flags);
bell_huang 0:242cf8f28bf2 188 }
bell_huang 0:242cf8f28bf2 189
bell_huang 0:242cf8f28bf2 190 bool pah_init_with_flags(const pah_flags_s *flags)
bell_huang 0:242cf8f28bf2 191 {
bell_huang 0:242cf8f28bf2 192 pah_ret ret = pah_err_unknown;
bell_huang 0:242cf8f28bf2 193
bell_huang 0:242cf8f28bf2 194 debug_printf(">>>> pah_init() \n");
bell_huang 0:242cf8f28bf2 195
bell_huang 0:242cf8f28bf2 196 if (!flags)
bell_huang 0:242cf8f28bf2 197 {
bell_huang 0:242cf8f28bf2 198 ret = pah_err_invalid_argument;
bell_huang 0:242cf8f28bf2 199 goto FAIL;
bell_huang 0:242cf8f28bf2 200 }
bell_huang 0:242cf8f28bf2 201
bell_huang 0:242cf8f28bf2 202 pah_deinit();
bell_huang 0:242cf8f28bf2 203
bell_huang 0:242cf8f28bf2 204 memset(&g_state, 0, sizeof(g_state));
bell_huang 0:242cf8f28bf2 205
bell_huang 0:242cf8f28bf2 206 // set flags
bell_huang 0:242cf8f28bf2 207 memcpy(&g_state.flags, flags, sizeof(g_state.flags));
bell_huang 0:242cf8f28bf2 208
bell_huang 0:242cf8f28bf2 209 // set default mode
bell_huang 0:242cf8f28bf2 210 g_state.mode = pah_stop_mode;
bell_huang 0:242cf8f28bf2 211
bell_huang 0:242cf8f28bf2 212 // properties
bell_huang 0:242cf8f28bf2 213 g_state.prop_curr.report_sample_num_per_ch = 0;
bell_huang 0:242cf8f28bf2 214 g_state.prop_next.report_sample_num_per_ch = DEFAULT_REPORT_SAMPLE_NUM_PER_CH;
bell_huang 0:242cf8f28bf2 215
bell_huang 0:242cf8f28bf2 216 ret = pah_8011_verify_product_id();
bell_huang 0:242cf8f28bf2 217 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 218 {
bell_huang 0:242cf8f28bf2 219 ret = pah_8011_startup();
bell_huang 0:242cf8f28bf2 220 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 221 goto FAIL;
bell_huang 0:242cf8f28bf2 222 ret = pah_8011_verify_product_id();
bell_huang 0:242cf8f28bf2 223 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 224 goto FAIL;
bell_huang 0:242cf8f28bf2 225 }
bell_huang 0:242cf8f28bf2 226
bell_huang 0:242cf8f28bf2 227 // register arrays
bell_huang 0:242cf8f28bf2 228 if (!pah8011_reg_array_init())
bell_huang 0:242cf8f28bf2 229 {
bell_huang 0:242cf8f28bf2 230 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 231 goto FAIL;
bell_huang 0:242cf8f28bf2 232 }
bell_huang 0:242cf8f28bf2 233
bell_huang 0:242cf8f28bf2 234 // init then shutdown
bell_huang 0:242cf8f28bf2 235 ret = pah_8011_device_init();
bell_huang 0:242cf8f28bf2 236 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 237 goto FAIL;
bell_huang 0:242cf8f28bf2 238 ret = pah_8011_shutdown(g_state.flags.powerdown_int_status);
bell_huang 0:242cf8f28bf2 239 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 240 goto FAIL;
bell_huang 0:242cf8f28bf2 241
bell_huang 0:242cf8f28bf2 242 g_init = true;
bell_huang 0:242cf8f28bf2 243
bell_huang 0:242cf8f28bf2 244 debug_printf("<<<< pah_init() \n");
bell_huang 0:242cf8f28bf2 245 return true;
bell_huang 0:242cf8f28bf2 246
bell_huang 0:242cf8f28bf2 247 FAIL:
bell_huang 0:242cf8f28bf2 248 debug_printf_1("pah_init() faied. ret = %d \n", ret);
bell_huang 0:242cf8f28bf2 249 return false;
bell_huang 0:242cf8f28bf2 250 }
bell_huang 0:242cf8f28bf2 251
bell_huang 0:242cf8f28bf2 252 void pah_deinit(void)
bell_huang 0:242cf8f28bf2 253 {
bell_huang 0:242cf8f28bf2 254 if (!g_init)
bell_huang 0:242cf8f28bf2 255 return;
bell_huang 0:242cf8f28bf2 256
bell_huang 0:242cf8f28bf2 257 debug_printf(">>>> pah_deinit() \n");
bell_huang 0:242cf8f28bf2 258
bell_huang 0:242cf8f28bf2 259 _pah8011_shutdown();
bell_huang 0:242cf8f28bf2 260
bell_huang 0:242cf8f28bf2 261 g_init = false;
bell_huang 0:242cf8f28bf2 262
bell_huang 0:242cf8f28bf2 263 debug_printf("<<<< pah_deinit() \n");
bell_huang 0:242cf8f28bf2 264 }
bell_huang 0:242cf8f28bf2 265
bell_huang 0:242cf8f28bf2 266 bool pah_enter_mode(pah_mode mode)
bell_huang 0:242cf8f28bf2 267 {
bell_huang 0:242cf8f28bf2 268 if (!pah_set_mode(mode))
bell_huang 0:242cf8f28bf2 269 goto FAIL;
bell_huang 0:242cf8f28bf2 270
bell_huang 0:242cf8f28bf2 271 switch (mode)
bell_huang 0:242cf8f28bf2 272 {
bell_huang 0:242cf8f28bf2 273 case pah_touch_mode:
bell_huang 0:242cf8f28bf2 274 if (!pah_run_device(pah_device_touch, true))
bell_huang 0:242cf8f28bf2 275 goto FAIL;
bell_huang 0:242cf8f28bf2 276 break;
bell_huang 0:242cf8f28bf2 277
bell_huang 0:242cf8f28bf2 278 case pah_ppg_mode:
bell_huang 0:242cf8f28bf2 279 case pah_ppg_200hz_mode:
bell_huang 0:242cf8f28bf2 280 if (!pah_run_device(pah_device_ppg, true))
bell_huang 0:242cf8f28bf2 281 goto FAIL;
bell_huang 0:242cf8f28bf2 282 break;
bell_huang 0:242cf8f28bf2 283
bell_huang 0:242cf8f28bf2 284 case pah_ppg_touch_mode:
bell_huang 0:242cf8f28bf2 285 case pah_ppg_200hz_touch_mode:
bell_huang 0:242cf8f28bf2 286 if (!pah_run_device(pah_device_ppg, true))
bell_huang 0:242cf8f28bf2 287 goto FAIL;
bell_huang 0:242cf8f28bf2 288 if (!pah_run_device(pah_device_touch, true))
bell_huang 0:242cf8f28bf2 289 goto FAIL;
bell_huang 0:242cf8f28bf2 290 break;
bell_huang 0:242cf8f28bf2 291
bell_huang 0:242cf8f28bf2 292 default:
bell_huang 0:242cf8f28bf2 293 break;
bell_huang 0:242cf8f28bf2 294 }
bell_huang 0:242cf8f28bf2 295
bell_huang 0:242cf8f28bf2 296 return true;
bell_huang 0:242cf8f28bf2 297
bell_huang 0:242cf8f28bf2 298 FAIL:
bell_huang 0:242cf8f28bf2 299 debug_printf("pah_enter_mode(). fail \n");
bell_huang 0:242cf8f28bf2 300 return false;
bell_huang 0:242cf8f28bf2 301 }
bell_huang 0:242cf8f28bf2 302
bell_huang 0:242cf8f28bf2 303 bool pah_set_mode(pah_mode mode)
bell_huang 0:242cf8f28bf2 304 {
bell_huang 0:242cf8f28bf2 305 pah_ret ret = pah_err_unknown;
bell_huang 0:242cf8f28bf2 306
bell_huang 0:242cf8f28bf2 307 debug_printf_2(">>>> pah_set_mode(), mode = %d -> %d \n", g_state.mode, mode);
bell_huang 0:242cf8f28bf2 308
bell_huang 0:242cf8f28bf2 309 if (g_state.mode == mode)
bell_huang 0:242cf8f28bf2 310 {
bell_huang 0:242cf8f28bf2 311 debug_printf("<<<< pah_set_mode() \n");
bell_huang 0:242cf8f28bf2 312 return true;
bell_huang 0:242cf8f28bf2 313 }
bell_huang 0:242cf8f28bf2 314
bell_huang 0:242cf8f28bf2 315 if (g_state.mode == pah_stop_mode)
bell_huang 0:242cf8f28bf2 316 {
bell_huang 0:242cf8f28bf2 317 if (!_pah8011_startup())
bell_huang 0:242cf8f28bf2 318 goto FAIL;
bell_huang 0:242cf8f28bf2 319 if (!_pah8011_init())
bell_huang 0:242cf8f28bf2 320 goto FAIL;
bell_huang 0:242cf8f28bf2 321
bell_huang 0:242cf8f28bf2 322 // update properties
bell_huang 0:242cf8f28bf2 323 if (!_pah8011_update_report_num())
bell_huang 0:242cf8f28bf2 324 goto FAIL;
bell_huang 0:242cf8f28bf2 325 g_state.prop_curr.is_int2_as_touch_flag = g_state.prop_next.is_int2_as_touch_flag;
bell_huang 0:242cf8f28bf2 326 }
bell_huang 0:242cf8f28bf2 327
bell_huang 0:242cf8f28bf2 328 if (pah_stop_mode == mode)
bell_huang 0:242cf8f28bf2 329 {
bell_huang 0:242cf8f28bf2 330 if (!_pah8011_shutdown())
bell_huang 0:242cf8f28bf2 331 goto FAIL;
bell_huang 0:242cf8f28bf2 332 }
bell_huang 0:242cf8f28bf2 333 else
bell_huang 0:242cf8f28bf2 334 {
bell_huang 0:242cf8f28bf2 335 switch (mode)
bell_huang 0:242cf8f28bf2 336 {
bell_huang 0:242cf8f28bf2 337 case pah_touch_mode:
bell_huang 0:242cf8f28bf2 338 {
bell_huang 0:242cf8f28bf2 339 _pah8011_stop_ppg();
bell_huang 0:242cf8f28bf2 340
bell_huang 0:242cf8f28bf2 341 if (_pah_is_ppg_mode(g_state.mode) && !_pah8011_clear_fifo_and_int_req())
bell_huang 0:242cf8f28bf2 342 goto FAIL;
bell_huang 0:242cf8f28bf2 343
bell_huang 0:242cf8f28bf2 344 if (!pah8011_reg_array_load_mode(pah8011_reg_array_mode_touch))
bell_huang 0:242cf8f28bf2 345 goto FAIL;
bell_huang 0:242cf8f28bf2 346 }
bell_huang 0:242cf8f28bf2 347 break;
bell_huang 0:242cf8f28bf2 348
bell_huang 0:242cf8f28bf2 349 case pah_ppg_mode:
bell_huang 0:242cf8f28bf2 350 {
bell_huang 0:242cf8f28bf2 351 _pah8011_stop_touch();
bell_huang 0:242cf8f28bf2 352
bell_huang 0:242cf8f28bf2 353 if (_pah_is_diff_fifo_freq(g_state.mode, mode))
bell_huang 0:242cf8f28bf2 354 {
bell_huang 0:242cf8f28bf2 355 if (!_pah8011_stop_ppg())
bell_huang 0:242cf8f28bf2 356 goto FAIL;
bell_huang 0:242cf8f28bf2 357 if (!_pah8011_clear_fifo_and_int_req())
bell_huang 0:242cf8f28bf2 358 goto FAIL;
bell_huang 0:242cf8f28bf2 359 }
bell_huang 0:242cf8f28bf2 360
bell_huang 0:242cf8f28bf2 361 if (!pah8011_reg_array_load_mode(pah8011_reg_array_mode_ppg_20hz))
bell_huang 0:242cf8f28bf2 362 goto FAIL;
bell_huang 0:242cf8f28bf2 363 if (!_pah8011_update_report_num())
bell_huang 0:242cf8f28bf2 364 goto FAIL;
bell_huang 0:242cf8f28bf2 365 }
bell_huang 0:242cf8f28bf2 366 break;
bell_huang 0:242cf8f28bf2 367
bell_huang 0:242cf8f28bf2 368 case pah_ppg_200hz_mode:
bell_huang 0:242cf8f28bf2 369 {
bell_huang 0:242cf8f28bf2 370 _pah8011_stop_touch();
bell_huang 0:242cf8f28bf2 371
bell_huang 0:242cf8f28bf2 372 if (_pah_is_diff_fifo_freq(g_state.mode, mode))
bell_huang 0:242cf8f28bf2 373 {
bell_huang 0:242cf8f28bf2 374 if (!_pah8011_stop_ppg())
bell_huang 0:242cf8f28bf2 375 goto FAIL;
bell_huang 0:242cf8f28bf2 376 if (!_pah8011_clear_fifo_and_int_req())
bell_huang 0:242cf8f28bf2 377 goto FAIL;
bell_huang 0:242cf8f28bf2 378 }
bell_huang 0:242cf8f28bf2 379
bell_huang 0:242cf8f28bf2 380 if (!pah8011_reg_array_load_mode(pah8011_reg_array_mode_ppg_200hz))
bell_huang 0:242cf8f28bf2 381 goto FAIL;
bell_huang 0:242cf8f28bf2 382 if (!_pah8011_update_report_num())
bell_huang 0:242cf8f28bf2 383 goto FAIL;
bell_huang 0:242cf8f28bf2 384 }
bell_huang 0:242cf8f28bf2 385 break;
bell_huang 0:242cf8f28bf2 386
bell_huang 0:242cf8f28bf2 387 case pah_ppg_touch_mode:
bell_huang 0:242cf8f28bf2 388 {
bell_huang 0:242cf8f28bf2 389 if (_pah_is_diff_fifo_freq(g_state.mode, mode))
bell_huang 0:242cf8f28bf2 390 {
bell_huang 0:242cf8f28bf2 391 if (!_pah8011_stop_ppg())
bell_huang 0:242cf8f28bf2 392 goto FAIL;
bell_huang 0:242cf8f28bf2 393 if (!_pah8011_clear_fifo_and_int_req())
bell_huang 0:242cf8f28bf2 394 goto FAIL;
bell_huang 0:242cf8f28bf2 395 }
bell_huang 0:242cf8f28bf2 396
bell_huang 0:242cf8f28bf2 397 if (!pah8011_reg_array_load_mode(pah8011_reg_array_mode_ppg_20hz))
bell_huang 0:242cf8f28bf2 398 goto FAIL;
bell_huang 0:242cf8f28bf2 399 if (!_pah8011_update_report_num())
bell_huang 0:242cf8f28bf2 400 goto FAIL;
bell_huang 0:242cf8f28bf2 401 }
bell_huang 0:242cf8f28bf2 402 break;
bell_huang 0:242cf8f28bf2 403
bell_huang 0:242cf8f28bf2 404 case pah_ppg_200hz_touch_mode:
bell_huang 0:242cf8f28bf2 405 {
bell_huang 0:242cf8f28bf2 406 if (_pah_is_diff_fifo_freq(g_state.mode, mode))
bell_huang 0:242cf8f28bf2 407 {
bell_huang 0:242cf8f28bf2 408 if (!_pah8011_stop_ppg())
bell_huang 0:242cf8f28bf2 409 goto FAIL;
bell_huang 0:242cf8f28bf2 410 if (!_pah8011_clear_fifo_and_int_req())
bell_huang 0:242cf8f28bf2 411 goto FAIL;
bell_huang 0:242cf8f28bf2 412 }
bell_huang 0:242cf8f28bf2 413
bell_huang 0:242cf8f28bf2 414 if (!pah8011_reg_array_load_mode(pah8011_reg_array_mode_ppg_200hz))
bell_huang 0:242cf8f28bf2 415 goto FAIL;
bell_huang 0:242cf8f28bf2 416 if (!_pah8011_update_report_num())
bell_huang 0:242cf8f28bf2 417 goto FAIL;
bell_huang 0:242cf8f28bf2 418 }
bell_huang 0:242cf8f28bf2 419 break;
bell_huang 0:242cf8f28bf2 420
bell_huang 0:242cf8f28bf2 421 default:
bell_huang 0:242cf8f28bf2 422 goto FAIL;
bell_huang 0:242cf8f28bf2 423 }
bell_huang 0:242cf8f28bf2 424
bell_huang 0:242cf8f28bf2 425 // pah_ppg_led_on_e flag
bell_huang 0:242cf8f28bf2 426 if (g_state.flags.ppg_led_on == pah_ppg_led_on_deferred)
bell_huang 0:242cf8f28bf2 427 {
bell_huang 0:242cf8f28bf2 428 if (!_pah_is_ppg_mode(g_state.mode) && _pah_is_ppg_mode(mode))
bell_huang 0:242cf8f28bf2 429 {
bell_huang 0:242cf8f28bf2 430 if (!_pah8011_turn_led(false))
bell_huang 0:242cf8f28bf2 431 goto FAIL;
bell_huang 0:242cf8f28bf2 432 g_state.is_led_on = false;
bell_huang 0:242cf8f28bf2 433 }
bell_huang 0:242cf8f28bf2 434 }
bell_huang 0:242cf8f28bf2 435
bell_huang 0:242cf8f28bf2 436 ret = pah_8011_update_flag();
bell_huang 0:242cf8f28bf2 437 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 438 goto FAIL;
bell_huang 0:242cf8f28bf2 439 }
bell_huang 0:242cf8f28bf2 440
bell_huang 0:242cf8f28bf2 441 g_state.mode = mode;
bell_huang 0:242cf8f28bf2 442
bell_huang 0:242cf8f28bf2 443 debug_printf("<<<< pah_set_mode() \n");
bell_huang 0:242cf8f28bf2 444 return true;
bell_huang 0:242cf8f28bf2 445
bell_huang 0:242cf8f28bf2 446 FAIL:
bell_huang 0:242cf8f28bf2 447 debug_printf("pah_set_mode(). fail \n");
bell_huang 0:242cf8f28bf2 448 return false;
bell_huang 0:242cf8f28bf2 449 }
bell_huang 0:242cf8f28bf2 450
bell_huang 0:242cf8f28bf2 451 bool pah_run_device(pah_device device, bool enable)
bell_huang 0:242cf8f28bf2 452 {
bell_huang 0:242cf8f28bf2 453 pah_ret ret = pah_err_unknown;
bell_huang 0:242cf8f28bf2 454
bell_huang 0:242cf8f28bf2 455 debug_printf_2(">>>> pah_run_device(), device = %d, enable = %d \n", device, enable);
bell_huang 0:242cf8f28bf2 456
bell_huang 0:242cf8f28bf2 457 switch (device)
bell_huang 0:242cf8f28bf2 458 {
bell_huang 0:242cf8f28bf2 459 case pah_device_ppg:
bell_huang 0:242cf8f28bf2 460 if (enable)
bell_huang 0:242cf8f28bf2 461 {
bell_huang 0:242cf8f28bf2 462 if (!_pah8011_update_report_num())
bell_huang 0:242cf8f28bf2 463 goto FAIL;
bell_huang 0:242cf8f28bf2 464 if (!_pah8011_start_ppg())
bell_huang 0:242cf8f28bf2 465 goto FAIL;
bell_huang 0:242cf8f28bf2 466 }
bell_huang 0:242cf8f28bf2 467 else
bell_huang 0:242cf8f28bf2 468 {
bell_huang 0:242cf8f28bf2 469 if (!_pah8011_stop_ppg())
bell_huang 0:242cf8f28bf2 470 goto FAIL;
bell_huang 0:242cf8f28bf2 471 }
bell_huang 0:242cf8f28bf2 472 break;
bell_huang 0:242cf8f28bf2 473
bell_huang 0:242cf8f28bf2 474 case pah_device_touch:
bell_huang 0:242cf8f28bf2 475 if (enable)
bell_huang 0:242cf8f28bf2 476 {
bell_huang 0:242cf8f28bf2 477 if (!_pah8011_start_touch())
bell_huang 0:242cf8f28bf2 478 goto FAIL;
bell_huang 0:242cf8f28bf2 479 }
bell_huang 0:242cf8f28bf2 480 else
bell_huang 0:242cf8f28bf2 481 {
bell_huang 0:242cf8f28bf2 482 if (!_pah8011_stop_touch())
bell_huang 0:242cf8f28bf2 483 goto FAIL;
bell_huang 0:242cf8f28bf2 484 }
bell_huang 0:242cf8f28bf2 485 break;
bell_huang 0:242cf8f28bf2 486
bell_huang 0:242cf8f28bf2 487 default:
bell_huang 0:242cf8f28bf2 488 goto FAIL;
bell_huang 0:242cf8f28bf2 489 }
bell_huang 0:242cf8f28bf2 490
bell_huang 0:242cf8f28bf2 491 ret = pah_8011_update_flag();
bell_huang 0:242cf8f28bf2 492 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 493 goto FAIL;
bell_huang 0:242cf8f28bf2 494
bell_huang 0:242cf8f28bf2 495 if (enable)
bell_huang 0:242cf8f28bf2 496 {
bell_huang 0:242cf8f28bf2 497 if (!_pah8011_start_tg())
bell_huang 0:242cf8f28bf2 498 goto FAIL;
bell_huang 0:242cf8f28bf2 499 }
bell_huang 0:242cf8f28bf2 500
bell_huang 0:242cf8f28bf2 501 debug_printf("<<<< pah_run_device() \n");
bell_huang 0:242cf8f28bf2 502 return true;
bell_huang 0:242cf8f28bf2 503
bell_huang 0:242cf8f28bf2 504 FAIL:
bell_huang 0:242cf8f28bf2 505 debug_printf("pah_run_device(). fail \n");
bell_huang 0:242cf8f28bf2 506 return false;
bell_huang 0:242cf8f28bf2 507 }
bell_huang 0:242cf8f28bf2 508
bell_huang 0:242cf8f28bf2 509 pah_mode pah_query_mode(void)
bell_huang 0:242cf8f28bf2 510 {
bell_huang 0:242cf8f28bf2 511 return g_state.mode;
bell_huang 0:242cf8f28bf2 512 }
bell_huang 0:242cf8f28bf2 513
bell_huang 0:242cf8f28bf2 514 bool pah_is_ppg_mode(void)
bell_huang 0:242cf8f28bf2 515 {
bell_huang 0:242cf8f28bf2 516 return _pah_is_ppg_mode(g_state.mode);
bell_huang 0:242cf8f28bf2 517 }
bell_huang 0:242cf8f28bf2 518
bell_huang 0:242cf8f28bf2 519 bool pah_is_ppg_20hz_mode(void)
bell_huang 0:242cf8f28bf2 520 {
bell_huang 0:242cf8f28bf2 521 return g_state.mode == pah_ppg_mode
bell_huang 0:242cf8f28bf2 522 || g_state.mode == pah_ppg_touch_mode;
bell_huang 0:242cf8f28bf2 523 }
bell_huang 0:242cf8f28bf2 524
bell_huang 0:242cf8f28bf2 525 pah_ret pah_task(void)
bell_huang 0:242cf8f28bf2 526 {
bell_huang 0:242cf8f28bf2 527 pah_ret ret = pah_err_unknown;
bell_huang 0:242cf8f28bf2 528 uint8_t int_req = 0;
bell_huang 0:242cf8f28bf2 529
bell_huang 0:242cf8f28bf2 530 debug_printf(">>>> pah_task() \n");
bell_huang 0:242cf8f28bf2 531
bell_huang 0:242cf8f28bf2 532 // reset
bell_huang 0:242cf8f28bf2 533 g_state.fifo_data_num_per_ch = 0;
bell_huang 0:242cf8f28bf2 534
bell_huang 0:242cf8f28bf2 535 // read interrupt
bell_huang 0:242cf8f28bf2 536 if (!pah_comm_write(0x7F, 0x02)) //Bank 2
bell_huang 0:242cf8f28bf2 537 {
bell_huang 0:242cf8f28bf2 538 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 539 goto FAIL;
bell_huang 0:242cf8f28bf2 540 }
bell_huang 0:242cf8f28bf2 541 if (!pah_comm_read(0x1B, &int_req)) //read interrupt status
bell_huang 0:242cf8f28bf2 542 {
bell_huang 0:242cf8f28bf2 543 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 544 goto FAIL;
bell_huang 0:242cf8f28bf2 545 }
bell_huang 0:242cf8f28bf2 546
bell_huang 0:242cf8f28bf2 547 debug_printf_1("pah_task(). int_req = %d \n", int_req);
bell_huang 0:242cf8f28bf2 548
bell_huang 0:242cf8f28bf2 549 // fifo overflow
bell_huang 0:242cf8f28bf2 550 if (int_req & 0x04)
bell_huang 0:242cf8f28bf2 551 {
bell_huang 0:242cf8f28bf2 552 // Usually happens when pah_task() was too late to be called.
bell_huang 0:242cf8f28bf2 553 // Troubleshooting: Record timestamps before every pah_task() calls, the interval of
bell_huang 0:242cf8f28bf2 554 // different pah_task() calls should be regular.
bell_huang 0:242cf8f28bf2 555
bell_huang 0:242cf8f28bf2 556 debug_printf("pah_task(). fifo overflow \n");
bell_huang 0:242cf8f28bf2 557 ret = pah_err_fifo_overflow;
bell_huang 0:242cf8f28bf2 558 goto FAIL;
bell_huang 0:242cf8f28bf2 559 }
bell_huang 0:242cf8f28bf2 560
bell_huang 0:242cf8f28bf2 561 // underflow interrupt
bell_huang 0:242cf8f28bf2 562 if (int_req & 0x08)
bell_huang 0:242cf8f28bf2 563 {
bell_huang 0:242cf8f28bf2 564 debug_printf("pah_task(). fifo underflow \n");
bell_huang 0:242cf8f28bf2 565 ret = pah_err_fifo_underflow;
bell_huang 0:242cf8f28bf2 566 goto FAIL;
bell_huang 0:242cf8f28bf2 567 }
bell_huang 0:242cf8f28bf2 568
bell_huang 0:242cf8f28bf2 569 // task
bell_huang 0:242cf8f28bf2 570 {
bell_huang 0:242cf8f28bf2 571 uint32_t ch_num = pah_get_fifo_ch_num();
bell_huang 0:242cf8f28bf2 572
bell_huang 0:242cf8f28bf2 573 if (!ch_num)
bell_huang 0:242cf8f28bf2 574 {
bell_huang 0:242cf8f28bf2 575 debug_printf("pah_task(). ch_num should never be 0 \n");
bell_huang 0:242cf8f28bf2 576 ret = pah_err_invalid_program;
bell_huang 0:242cf8f28bf2 577 goto FAIL;
bell_huang 0:242cf8f28bf2 578 }
bell_huang 0:242cf8f28bf2 579
bell_huang 0:242cf8f28bf2 580 if (pah_stream_polling == g_state.flags.stream)
bell_huang 0:242cf8f28bf2 581 ret = _pah8011_task_polling(int_req, ch_num);
bell_huang 0:242cf8f28bf2 582 else
bell_huang 0:242cf8f28bf2 583 ret = _pah8011_task_dri(int_req, ch_num);
bell_huang 0:242cf8f28bf2 584 }
bell_huang 0:242cf8f28bf2 585
bell_huang 0:242cf8f28bf2 586 if (ret != pah_success && ret != pah_pending)
bell_huang 0:242cf8f28bf2 587 goto FAIL;
bell_huang 0:242cf8f28bf2 588
bell_huang 0:242cf8f28bf2 589 if (int_req)
bell_huang 0:242cf8f28bf2 590 {
bell_huang 0:242cf8f28bf2 591 // clear interrupt
bell_huang 0:242cf8f28bf2 592 if (!pah_comm_write(0x7F, 0x02)) //Bank 2
bell_huang 0:242cf8f28bf2 593 {
bell_huang 0:242cf8f28bf2 594 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 595 goto FAIL;
bell_huang 0:242cf8f28bf2 596 }
bell_huang 0:242cf8f28bf2 597 if (!pah_comm_write(0x1b, int_req)) //clear interrupt
bell_huang 0:242cf8f28bf2 598 {
bell_huang 0:242cf8f28bf2 599 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 600 goto FAIL;
bell_huang 0:242cf8f28bf2 601 }
bell_huang 0:242cf8f28bf2 602
bell_huang 0:242cf8f28bf2 603 //debug_printf("pah_task(). clear interrupt, int_req = %d \n", int_req);
bell_huang 0:242cf8f28bf2 604 }
bell_huang 0:242cf8f28bf2 605
bell_huang 0:242cf8f28bf2 606 // update properties
bell_huang 0:242cf8f28bf2 607 if (!_pah8011_update_report_num())
bell_huang 0:242cf8f28bf2 608 {
bell_huang 0:242cf8f28bf2 609 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 610 goto FAIL;
bell_huang 0:242cf8f28bf2 611 }
bell_huang 0:242cf8f28bf2 612
bell_huang 0:242cf8f28bf2 613 // pah_ppg_led_on_e flag
bell_huang 0:242cf8f28bf2 614 if (g_state.flags.ppg_led_on == pah_ppg_led_on_deferred && !g_state.is_led_on)
bell_huang 0:242cf8f28bf2 615 {
bell_huang 0:242cf8f28bf2 616 if (g_state.touch_flag && pah_is_ppg_mode())
bell_huang 0:242cf8f28bf2 617 {
bell_huang 0:242cf8f28bf2 618 if (!_pah8011_turn_led(true))
bell_huang 0:242cf8f28bf2 619 {
bell_huang 0:242cf8f28bf2 620 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 621 goto FAIL;
bell_huang 0:242cf8f28bf2 622 }
bell_huang 0:242cf8f28bf2 623 ret = pah_8011_update_flag();
bell_huang 0:242cf8f28bf2 624 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 625 goto FAIL;
bell_huang 0:242cf8f28bf2 626
bell_huang 0:242cf8f28bf2 627 g_state.is_led_on = true;
bell_huang 0:242cf8f28bf2 628 }
bell_huang 0:242cf8f28bf2 629 }
bell_huang 0:242cf8f28bf2 630
bell_huang 0:242cf8f28bf2 631 debug_printf("<<<< pah_task() \n");
bell_huang 0:242cf8f28bf2 632 return ret;
bell_huang 0:242cf8f28bf2 633
bell_huang 0:242cf8f28bf2 634 FAIL:
bell_huang 0:242cf8f28bf2 635 debug_printf_1("pah_task(). fail, ret = %d \n", ret);
bell_huang 0:242cf8f28bf2 636 return ret;
bell_huang 0:242cf8f28bf2 637 }
bell_huang 0:242cf8f28bf2 638
bell_huang 0:242cf8f28bf2 639 uint8_t* pah_get_fifo_data(void)
bell_huang 0:242cf8f28bf2 640 {
bell_huang 0:242cf8f28bf2 641 return g_state.fifo_data;
bell_huang 0:242cf8f28bf2 642 }
bell_huang 0:242cf8f28bf2 643
bell_huang 0:242cf8f28bf2 644 uint32_t pah_fifo_data_num_per_ch(void)
bell_huang 0:242cf8f28bf2 645 {
bell_huang 0:242cf8f28bf2 646 return g_state.fifo_data_num_per_ch;
bell_huang 0:242cf8f28bf2 647 }
bell_huang 0:242cf8f28bf2 648
bell_huang 0:242cf8f28bf2 649 bool pah_has_fifo_data(void)
bell_huang 0:242cf8f28bf2 650 {
bell_huang 0:242cf8f28bf2 651 return g_state.fifo_data_num_per_ch > 0;
bell_huang 0:242cf8f28bf2 652 }
bell_huang 0:242cf8f28bf2 653
bell_huang 0:242cf8f28bf2 654 uint32_t pah_get_fifo_ch_num(void)
bell_huang 0:242cf8f28bf2 655 {
bell_huang 0:242cf8f28bf2 656 return pah8011_get_ppg_ch_num();
bell_huang 0:242cf8f28bf2 657 }
bell_huang 0:242cf8f28bf2 658
bell_huang 0:242cf8f28bf2 659 bool pah_is_touched(void)
bell_huang 0:242cf8f28bf2 660 {
bell_huang 0:242cf8f28bf2 661 return g_state.touch_flag > 0;
bell_huang 0:242cf8f28bf2 662 }
bell_huang 0:242cf8f28bf2 663
bell_huang 0:242cf8f28bf2 664 void pah_clear_fifo_data(void)
bell_huang 0:242cf8f28bf2 665 {
bell_huang 0:242cf8f28bf2 666 memset(g_state.fifo_data, 0, sizeof(g_state.fifo_data));
bell_huang 0:242cf8f28bf2 667 }
bell_huang 0:242cf8f28bf2 668
bell_huang 0:242cf8f28bf2 669 void pah_set_report_fifo_callback(pah_report_fifo_handle fp_handler, void* user_data)
bell_huang 0:242cf8f28bf2 670 {
bell_huang 0:242cf8f28bf2 671 debug_printf("==== pah_set_report_fifo_callback() \n");
bell_huang 0:242cf8f28bf2 672
bell_huang 0:242cf8f28bf2 673 g_state.fp_report_fifo_handler = fp_handler;
bell_huang 0:242cf8f28bf2 674 g_state.user_data = user_data;
bell_huang 0:242cf8f28bf2 675 }
bell_huang 0:242cf8f28bf2 676
bell_huang 0:242cf8f28bf2 677 uint16_t pah_get_i2c_slave_addr(void)
bell_huang 0:242cf8f28bf2 678 {
bell_huang 0:242cf8f28bf2 679 debug_printf("==== pah_get_i2c_slave_addr() \n");
bell_huang 0:242cf8f28bf2 680
bell_huang 0:242cf8f28bf2 681 return PAH_I2C_SLAVE_ID;
bell_huang 0:242cf8f28bf2 682 }
bell_huang 0:242cf8f28bf2 683
bell_huang 0:242cf8f28bf2 684 bool pah_set_int2_as_touch_flag(bool enable)
bell_huang 0:242cf8f28bf2 685 {
bell_huang 0:242cf8f28bf2 686 debug_printf_1("==== pah_set_int2_as_touch_flag(). enable = %d \n", enable);
bell_huang 0:242cf8f28bf2 687
bell_huang 0:242cf8f28bf2 688 g_state.prop_next.is_int2_as_touch_flag = enable;
bell_huang 0:242cf8f28bf2 689 return true;
bell_huang 0:242cf8f28bf2 690 }
bell_huang 0:242cf8f28bf2 691
bell_huang 0:242cf8f28bf2 692 void pah_set_report_sample_num_per_ch(uint32_t report_sample_num_per_ch)
bell_huang 0:242cf8f28bf2 693 {
bell_huang 0:242cf8f28bf2 694 static const uint32_t MIN_REPORT_SAMPLE_NUM_PER_CH = 1;
bell_huang 0:242cf8f28bf2 695 const uint32_t MAX_REPORT_SAMPLE_NUM_PER_CH = pah_get_max_report_sample_num_per_ch();
bell_huang 0:242cf8f28bf2 696
bell_huang 0:242cf8f28bf2 697 if (report_sample_num_per_ch < MIN_REPORT_SAMPLE_NUM_PER_CH)
bell_huang 0:242cf8f28bf2 698 report_sample_num_per_ch = MIN_REPORT_SAMPLE_NUM_PER_CH;
bell_huang 0:242cf8f28bf2 699 else if (report_sample_num_per_ch > MAX_REPORT_SAMPLE_NUM_PER_CH)
bell_huang 0:242cf8f28bf2 700 report_sample_num_per_ch = MAX_REPORT_SAMPLE_NUM_PER_CH;
bell_huang 0:242cf8f28bf2 701 g_state.prop_next.report_sample_num_per_ch = report_sample_num_per_ch;
bell_huang 0:242cf8f28bf2 702
bell_huang 0:242cf8f28bf2 703 debug_printf_1("pah_set_report_sample_num_per_ch(). report_sample_num_per_ch = %d \n", report_sample_num_per_ch);
bell_huang 0:242cf8f28bf2 704 }
bell_huang 0:242cf8f28bf2 705 uint32_t pah_get_report_sample_num_per_ch(void)
bell_huang 0:242cf8f28bf2 706 {
bell_huang 0:242cf8f28bf2 707 return g_state.prop_curr.report_sample_num_per_ch;
bell_huang 0:242cf8f28bf2 708 }
bell_huang 0:242cf8f28bf2 709 uint32_t pah_get_max_report_sample_num_per_ch(void)
bell_huang 0:242cf8f28bf2 710 {
bell_huang 0:242cf8f28bf2 711 return MAX_SAMPLES_PER_READ / MAX_CH_NUM;
bell_huang 0:242cf8f28bf2 712 }
bell_huang 0:242cf8f28bf2 713
bell_huang 0:242cf8f28bf2 714 uint32_t pah_get_bytes_per_sample(void)
bell_huang 0:242cf8f28bf2 715 {
bell_huang 0:242cf8f28bf2 716 return BYTES_PER_SAMPLE;
bell_huang 0:242cf8f28bf2 717 }
bell_huang 0:242cf8f28bf2 718
bell_huang 0:242cf8f28bf2 719 bool pah_verify_product_id(void)
bell_huang 0:242cf8f28bf2 720 {
bell_huang 0:242cf8f28bf2 721 uint8_t data = 0;
bell_huang 0:242cf8f28bf2 722
bell_huang 0:242cf8f28bf2 723 debug_printf(">>>> pah_verify_product_id() \n");
bell_huang 0:242cf8f28bf2 724
bell_huang 0:242cf8f28bf2 725 if (!pah_comm_write(0x7F, 0x00)) //bank0
bell_huang 0:242cf8f28bf2 726 goto FAIL;
bell_huang 0:242cf8f28bf2 727 if (!pah_comm_read(0x00, &data))
bell_huang 0:242cf8f28bf2 728 goto FAIL;
bell_huang 0:242cf8f28bf2 729 if (data != 0x11)
bell_huang 0:242cf8f28bf2 730 {
bell_huang 0:242cf8f28bf2 731 debug_printf_1("pah_verify_product_id() fail. data = %d \n", data);
bell_huang 0:242cf8f28bf2 732 goto FAIL;
bell_huang 0:242cf8f28bf2 733 }
bell_huang 0:242cf8f28bf2 734
bell_huang 0:242cf8f28bf2 735 debug_printf("<<<< pah_verify_product_id() \n");
bell_huang 0:242cf8f28bf2 736 return true;
bell_huang 0:242cf8f28bf2 737
bell_huang 0:242cf8f28bf2 738 FAIL:
bell_huang 0:242cf8f28bf2 739 debug_printf("pah_verify_product_id error \n");
bell_huang 0:242cf8f28bf2 740 return false;
bell_huang 0:242cf8f28bf2 741 }
bell_huang 0:242cf8f28bf2 742
bell_huang 0:242cf8f28bf2 743 pah_ret pah_read_touch_flag(bool *is_touched)
bell_huang 0:242cf8f28bf2 744 {
bell_huang 0:242cf8f28bf2 745 uint8_t touch_flag = 0;
bell_huang 0:242cf8f28bf2 746
bell_huang 0:242cf8f28bf2 747 debug_printf(">>>> pah_read_touch_flag() \n");
bell_huang 0:242cf8f28bf2 748
bell_huang 0:242cf8f28bf2 749 if (!is_touched)
bell_huang 0:242cf8f28bf2 750 {
bell_huang 0:242cf8f28bf2 751 debug_printf("pah_read_touch_flag() fail. invalid argument \n");
bell_huang 0:242cf8f28bf2 752 return pah_err_invalid_argument;
bell_huang 0:242cf8f28bf2 753 }
bell_huang 0:242cf8f28bf2 754
bell_huang 0:242cf8f28bf2 755 if (!_pah8011_read_touch_flag(&touch_flag))
bell_huang 0:242cf8f28bf2 756 return pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 757
bell_huang 0:242cf8f28bf2 758 *is_touched = touch_flag > 0;
bell_huang 0:242cf8f28bf2 759
bell_huang 0:242cf8f28bf2 760 debug_printf_1("<<<< pah_read_touch_flag(). is_touched = %d \n", *is_touched);
bell_huang 0:242cf8f28bf2 761 return pah_success;
bell_huang 0:242cf8f28bf2 762 }
bell_huang 0:242cf8f28bf2 763
bell_huang 0:242cf8f28bf2 764 /*============================================================================
bell_huang 0:242cf8f28bf2 765 Pure functions
bell_huang 0:242cf8f28bf2 766 ============================================================================*/
bell_huang 0:242cf8f28bf2 767 static bool _pah_is_ppg_mode(pah_mode mode)
bell_huang 0:242cf8f28bf2 768 {
bell_huang 0:242cf8f28bf2 769 return mode == pah_ppg_mode
bell_huang 0:242cf8f28bf2 770 || mode == pah_ppg_200hz_mode
bell_huang 0:242cf8f28bf2 771 || mode == pah_ppg_touch_mode
bell_huang 0:242cf8f28bf2 772 || mode == pah_ppg_200hz_touch_mode;
bell_huang 0:242cf8f28bf2 773 }
bell_huang 0:242cf8f28bf2 774
bell_huang 0:242cf8f28bf2 775 static pah_fifo_freq _pah_mode_to_freq(pah_mode mode)
bell_huang 0:242cf8f28bf2 776 {
bell_huang 0:242cf8f28bf2 777 pah_fifo_freq result = pah_fifo_freq_none;
bell_huang 0:242cf8f28bf2 778 switch (mode)
bell_huang 0:242cf8f28bf2 779 {
bell_huang 0:242cf8f28bf2 780 case pah_ppg_mode:
bell_huang 0:242cf8f28bf2 781 case pah_ppg_touch_mode:
bell_huang 0:242cf8f28bf2 782 result = pah_fifo_freq_20hz;
bell_huang 0:242cf8f28bf2 783 break;
bell_huang 0:242cf8f28bf2 784
bell_huang 0:242cf8f28bf2 785 case pah_ppg_200hz_mode:
bell_huang 0:242cf8f28bf2 786 case pah_ppg_200hz_touch_mode:
bell_huang 0:242cf8f28bf2 787 result = pah_fifo_freq_200hz;
bell_huang 0:242cf8f28bf2 788 break;
bell_huang 0:242cf8f28bf2 789
bell_huang 0:242cf8f28bf2 790 default:
bell_huang 0:242cf8f28bf2 791 result = pah_fifo_freq_none;
bell_huang 0:242cf8f28bf2 792 break;
bell_huang 0:242cf8f28bf2 793 }
bell_huang 0:242cf8f28bf2 794 return result;
bell_huang 0:242cf8f28bf2 795 }
bell_huang 0:242cf8f28bf2 796
bell_huang 0:242cf8f28bf2 797 static bool _pah_is_diff_fifo_freq(pah_mode lhs_mode, pah_mode rhs_mode)
bell_huang 0:242cf8f28bf2 798 {
bell_huang 0:242cf8f28bf2 799 pah_fifo_freq lhs_freq = _pah_mode_to_freq(lhs_mode);
bell_huang 0:242cf8f28bf2 800 pah_fifo_freq rhs_freq = _pah_mode_to_freq(rhs_mode);
bell_huang 0:242cf8f28bf2 801
bell_huang 0:242cf8f28bf2 802 if (lhs_freq == pah_fifo_freq_none
bell_huang 0:242cf8f28bf2 803 || rhs_freq == pah_fifo_freq_none)
bell_huang 0:242cf8f28bf2 804 return false;
bell_huang 0:242cf8f28bf2 805
bell_huang 0:242cf8f28bf2 806 return lhs_freq != rhs_freq;
bell_huang 0:242cf8f28bf2 807 }
bell_huang 0:242cf8f28bf2 808
bell_huang 0:242cf8f28bf2 809 /*============================================================================
bell_huang 0:242cf8f28bf2 810 PRIVATE FUNCTION DEFINITIONS
bell_huang 0:242cf8f28bf2 811 ============================================================================*/
bell_huang 0:242cf8f28bf2 812 static bool _pah8011_init(void)
bell_huang 0:242cf8f28bf2 813 {
bell_huang 0:242cf8f28bf2 814 pah_ret ret = pah_err_unknown;
bell_huang 0:242cf8f28bf2 815 uint8_t data = 0;
bell_huang 0:242cf8f28bf2 816
bell_huang 0:242cf8f28bf2 817 debug_printf_1("_pah8011_init(), PAH8011 driver[v%d] \n", PAH_DRIVER_8011_VERSION);
bell_huang 0:242cf8f28bf2 818
bell_huang 0:242cf8f28bf2 819 //// reg init settings
bell_huang 0:242cf8f28bf2 820 pah8011_reg_array_load_init();
bell_huang 0:242cf8f28bf2 821
bell_huang 0:242cf8f28bf2 822 //// touch init
bell_huang 0:242cf8f28bf2 823 ret = pah_8011_write_touch_package_setting();
bell_huang 0:242cf8f28bf2 824 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 825 goto FAIL;
bell_huang 0:242cf8f28bf2 826
bell_huang 0:242cf8f28bf2 827 //// other init settings
bell_huang 0:242cf8f28bf2 828 if (!pah_comm_write(0x7F, 0x01)) //bank1
bell_huang 0:242cf8f28bf2 829 goto FAIL;
bell_huang 0:242cf8f28bf2 830
bell_huang 0:242cf8f28bf2 831 // disable ch a
bell_huang 0:242cf8f28bf2 832 if (!pah_comm_read(0x21, &data))
bell_huang 0:242cf8f28bf2 833 goto FAIL;
bell_huang 0:242cf8f28bf2 834 PAH_CLEAR_BIT(data, 0);
bell_huang 0:242cf8f28bf2 835 if (!pah_comm_write(0x21, data))
bell_huang 0:242cf8f28bf2 836 goto FAIL;
bell_huang 0:242cf8f28bf2 837
bell_huang 0:242cf8f28bf2 838 // disable ch b
bell_huang 0:242cf8f28bf2 839 if (!pah_comm_read(0x23, &data))
bell_huang 0:242cf8f28bf2 840 goto FAIL;
bell_huang 0:242cf8f28bf2 841 PAH_CLEAR_BIT(data, 0);
bell_huang 0:242cf8f28bf2 842 if (!pah_comm_write(0x23, data))
bell_huang 0:242cf8f28bf2 843 goto FAIL;
bell_huang 0:242cf8f28bf2 844
bell_huang 0:242cf8f28bf2 845 // disable ch c
bell_huang 0:242cf8f28bf2 846 if (!pah_comm_read(0x25, &data))
bell_huang 0:242cf8f28bf2 847 goto FAIL;
bell_huang 0:242cf8f28bf2 848 PAH_CLEAR_BIT(data, 0);
bell_huang 0:242cf8f28bf2 849 if (!pah_comm_write(0x25, data))
bell_huang 0:242cf8f28bf2 850 goto FAIL;
bell_huang 0:242cf8f28bf2 851
bell_huang 0:242cf8f28bf2 852 // touch interrupt
bell_huang 0:242cf8f28bf2 853 if (!pah_comm_read(0x36, &data))
bell_huang 0:242cf8f28bf2 854 goto FAIL;
bell_huang 0:242cf8f28bf2 855 PAH_SET_BIT(data, 0);
bell_huang 0:242cf8f28bf2 856 PAH_CLEAR_BIT(data, 1);
bell_huang 0:242cf8f28bf2 857 if (!pah_comm_write(0x36, data))
bell_huang 0:242cf8f28bf2 858 goto FAIL;
bell_huang 0:242cf8f28bf2 859
bell_huang 0:242cf8f28bf2 860 // mask
bell_huang 0:242cf8f28bf2 861 if (!pah_comm_read(0x37, &data))
bell_huang 0:242cf8f28bf2 862 goto FAIL;
bell_huang 0:242cf8f28bf2 863 PAH_SET_BIT(data, 1);
bell_huang 0:242cf8f28bf2 864 if (!pah_comm_write(0x37, data))
bell_huang 0:242cf8f28bf2 865 goto FAIL;
bell_huang 0:242cf8f28bf2 866
bell_huang 0:242cf8f28bf2 867 // touch bit
bell_huang 0:242cf8f28bf2 868 if (!pah_comm_read(0x5A, &data))
bell_huang 0:242cf8f28bf2 869 goto FAIL;
bell_huang 0:242cf8f28bf2 870 g_state.fifo_data_contain_touch_bit = PAH_CHECK_BIT(data, 0);
bell_huang 0:242cf8f28bf2 871
bell_huang 0:242cf8f28bf2 872 // intshape_pulse_type
bell_huang 0:242cf8f28bf2 873 if (g_state.flags.intshape_pulse_type == pah_intshape_pulse_type_level)
bell_huang 0:242cf8f28bf2 874 {
bell_huang 0:242cf8f28bf2 875 if (!pah_comm_write(0x7F, 0x01)) //Bank 1
bell_huang 0:242cf8f28bf2 876 goto FAIL;
bell_huang 0:242cf8f28bf2 877 if (!pah_comm_read(0x35, &data))
bell_huang 0:242cf8f28bf2 878 goto FAIL;
bell_huang 0:242cf8f28bf2 879 PAH_CLEAR_BIT(data, 1);
bell_huang 0:242cf8f28bf2 880 if (!pah_comm_write(0x35, data))
bell_huang 0:242cf8f28bf2 881 goto FAIL;
bell_huang 0:242cf8f28bf2 882 }
bell_huang 0:242cf8f28bf2 883
bell_huang 0:242cf8f28bf2 884 ret = pah_8011_update_flag();
bell_huang 0:242cf8f28bf2 885 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 886 goto FAIL;
bell_huang 0:242cf8f28bf2 887
bell_huang 0:242cf8f28bf2 888 return true;
bell_huang 0:242cf8f28bf2 889
bell_huang 0:242cf8f28bf2 890 FAIL:
bell_huang 0:242cf8f28bf2 891 debug_printf("_pah8011_init fail \n");
bell_huang 0:242cf8f28bf2 892 return false;
bell_huang 0:242cf8f28bf2 893 }
bell_huang 0:242cf8f28bf2 894
bell_huang 0:242cf8f28bf2 895 static bool _pah8011_shutdown(void)
bell_huang 0:242cf8f28bf2 896 {
bell_huang 0:242cf8f28bf2 897 pah_ret ret = pah_err_unknown;
bell_huang 0:242cf8f28bf2 898
bell_huang 0:242cf8f28bf2 899 debug_printf("_pah8011_shutdown() \n");
bell_huang 0:242cf8f28bf2 900
bell_huang 0:242cf8f28bf2 901 ret = pah_8011_shutdown(g_state.flags.powerdown_int_status);
bell_huang 0:242cf8f28bf2 902 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 903 goto FAIL;
bell_huang 0:242cf8f28bf2 904
bell_huang 0:242cf8f28bf2 905 // reset states
bell_huang 0:242cf8f28bf2 906 g_state.has_started_tg = 0;
bell_huang 0:242cf8f28bf2 907 g_state.has_started_ppg = 0;
bell_huang 0:242cf8f28bf2 908 g_state.has_started_touch = 0;
bell_huang 0:242cf8f28bf2 909
bell_huang 0:242cf8f28bf2 910 // reset properties
bell_huang 0:242cf8f28bf2 911 g_state.prop_curr.report_sample_num_per_ch = 0;
bell_huang 0:242cf8f28bf2 912
bell_huang 0:242cf8f28bf2 913 return true;
bell_huang 0:242cf8f28bf2 914
bell_huang 0:242cf8f28bf2 915 FAIL:
bell_huang 0:242cf8f28bf2 916 debug_printf("_pah8011_shutdown error \n");
bell_huang 0:242cf8f28bf2 917 return false;
bell_huang 0:242cf8f28bf2 918 }
bell_huang 0:242cf8f28bf2 919
bell_huang 0:242cf8f28bf2 920 static bool _pah8011_startup(void)
bell_huang 0:242cf8f28bf2 921 {
bell_huang 0:242cf8f28bf2 922 pah_ret ret = pah_err_unknown;
bell_huang 0:242cf8f28bf2 923
bell_huang 0:242cf8f28bf2 924 debug_printf("_pah8011_startup() \n");
bell_huang 0:242cf8f28bf2 925
bell_huang 0:242cf8f28bf2 926 ret = pah_8011_startup();
bell_huang 0:242cf8f28bf2 927 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 928 goto FAIL;
bell_huang 0:242cf8f28bf2 929
bell_huang 0:242cf8f28bf2 930 return true;
bell_huang 0:242cf8f28bf2 931
bell_huang 0:242cf8f28bf2 932 FAIL:
bell_huang 0:242cf8f28bf2 933 debug_printf("_pah8011_startup error \n");
bell_huang 0:242cf8f28bf2 934 return false;
bell_huang 0:242cf8f28bf2 935 }
bell_huang 0:242cf8f28bf2 936
bell_huang 0:242cf8f28bf2 937 static bool _pah8011_start_tg(void)
bell_huang 0:242cf8f28bf2 938 {
bell_huang 0:242cf8f28bf2 939 uint8_t data = 0;
bell_huang 0:242cf8f28bf2 940
bell_huang 0:242cf8f28bf2 941 if (g_state.has_started_tg)
bell_huang 0:242cf8f28bf2 942 return true;
bell_huang 0:242cf8f28bf2 943
bell_huang 0:242cf8f28bf2 944 debug_printf("_pah8011_start_tg() \n");
bell_huang 0:242cf8f28bf2 945
bell_huang 0:242cf8f28bf2 946 // must sleep between update flag and TG enable.
bell_huang 0:242cf8f28bf2 947 delay_ms(1);
bell_huang 0:242cf8f28bf2 948
bell_huang 0:242cf8f28bf2 949 // mask
bell_huang 0:242cf8f28bf2 950 if (!pah_comm_write(0x7f, 0x01))
bell_huang 0:242cf8f28bf2 951 goto FAIL;
bell_huang 0:242cf8f28bf2 952 if (!pah_comm_read(0x37, &data)) //mask
bell_huang 0:242cf8f28bf2 953 goto FAIL;
bell_huang 0:242cf8f28bf2 954 PAH_CLEAR_BIT(data, 0); // IntSramFIFO_MaskInt
bell_huang 0:242cf8f28bf2 955 PAH_CLEAR_BIT(data, 2); // int_sramfifo_overflow_mask
bell_huang 0:242cf8f28bf2 956 PAH_CLEAR_BIT(data, 3); // int_sramfifo_underflow_mask
bell_huang 0:242cf8f28bf2 957 if (!pah_comm_write(0x37, data))
bell_huang 0:242cf8f28bf2 958 goto FAIL;
bell_huang 0:242cf8f28bf2 959
bell_huang 0:242cf8f28bf2 960 // TG enable
bell_huang 0:242cf8f28bf2 961 if (!pah_comm_write(0x30, 0x01)) //TG enable
bell_huang 0:242cf8f28bf2 962 goto FAIL;
bell_huang 0:242cf8f28bf2 963
bell_huang 0:242cf8f28bf2 964 // wait for clk
bell_huang 0:242cf8f28bf2 965 delay_ms(1);
bell_huang 0:242cf8f28bf2 966
bell_huang 0:242cf8f28bf2 967 // clear int_req
bell_huang 0:242cf8f28bf2 968 if (!pah_comm_write(0x7F, 0x02)) //Bank 2
bell_huang 0:242cf8f28bf2 969 goto FAIL;
bell_huang 0:242cf8f28bf2 970 if (!pah_comm_write(0x1B, 0xFF)) //int_req_array
bell_huang 0:242cf8f28bf2 971 goto FAIL;
bell_huang 0:242cf8f28bf2 972
bell_huang 0:242cf8f28bf2 973 // mask
bell_huang 0:242cf8f28bf2 974 if (!pah_comm_write(0x7f, 0x01))
bell_huang 0:242cf8f28bf2 975 goto FAIL;
bell_huang 0:242cf8f28bf2 976 if (!pah_comm_read(0x37, &data)) //mask
bell_huang 0:242cf8f28bf2 977 goto FAIL;
bell_huang 0:242cf8f28bf2 978 PAH_CLEAR_BIT(data, 4); // AllInt_MaskInt
bell_huang 0:242cf8f28bf2 979 if (!pah_comm_write(0x37, data))
bell_huang 0:242cf8f28bf2 980 goto FAIL;
bell_huang 0:242cf8f28bf2 981
bell_huang 0:242cf8f28bf2 982 g_state.has_started_tg = 1;
bell_huang 0:242cf8f28bf2 983 return true;
bell_huang 0:242cf8f28bf2 984
bell_huang 0:242cf8f28bf2 985 FAIL:
bell_huang 0:242cf8f28bf2 986 debug_printf("_pah8011_start_tg error \n");
bell_huang 0:242cf8f28bf2 987 return false;
bell_huang 0:242cf8f28bf2 988 }
bell_huang 0:242cf8f28bf2 989
bell_huang 0:242cf8f28bf2 990 static bool _pah8011_start_ppg(void)
bell_huang 0:242cf8f28bf2 991 {
bell_huang 0:242cf8f28bf2 992 uint8_t data = 0;
bell_huang 0:242cf8f28bf2 993 uint8_t ppg_ch_enabled[pah8011_ppg_ch_num];
bell_huang 0:242cf8f28bf2 994
bell_huang 0:242cf8f28bf2 995 if (g_state.has_started_ppg)
bell_huang 0:242cf8f28bf2 996 return true;
bell_huang 0:242cf8f28bf2 997
bell_huang 0:242cf8f28bf2 998 debug_printf("_pah8011_start_ppg() \n");
bell_huang 0:242cf8f28bf2 999
bell_huang 0:242cf8f28bf2 1000 pah8011_get_ppg_ch_enabled(ppg_ch_enabled);
bell_huang 0:242cf8f28bf2 1001
bell_huang 0:242cf8f28bf2 1002 if (!pah_comm_write(0x7F, 0x01)) //bank1
bell_huang 0:242cf8f28bf2 1003 goto FAIL;
bell_huang 0:242cf8f28bf2 1004
bell_huang 0:242cf8f28bf2 1005 //channel a
bell_huang 0:242cf8f28bf2 1006 if (ppg_ch_enabled[pah8011_ppg_ch_a])
bell_huang 0:242cf8f28bf2 1007 {
bell_huang 0:242cf8f28bf2 1008 if (!pah_comm_read(0x21, &data))
bell_huang 0:242cf8f28bf2 1009 goto FAIL;
bell_huang 0:242cf8f28bf2 1010 PAH_SET_BIT(data, 0);
bell_huang 0:242cf8f28bf2 1011 if (!pah_comm_write(0x21, data))
bell_huang 0:242cf8f28bf2 1012 goto FAIL;
bell_huang 0:242cf8f28bf2 1013 }
bell_huang 0:242cf8f28bf2 1014
bell_huang 0:242cf8f28bf2 1015 //channel b
bell_huang 0:242cf8f28bf2 1016 if (ppg_ch_enabled[pah8011_ppg_ch_b])
bell_huang 0:242cf8f28bf2 1017 {
bell_huang 0:242cf8f28bf2 1018 if (!pah_comm_read(0x23, &data))
bell_huang 0:242cf8f28bf2 1019 goto FAIL;
bell_huang 0:242cf8f28bf2 1020 PAH_SET_BIT(data, 0);
bell_huang 0:242cf8f28bf2 1021 if (!pah_comm_write(0x23, data))
bell_huang 0:242cf8f28bf2 1022 goto FAIL;
bell_huang 0:242cf8f28bf2 1023 }
bell_huang 0:242cf8f28bf2 1024
bell_huang 0:242cf8f28bf2 1025 //channel c
bell_huang 0:242cf8f28bf2 1026 if (ppg_ch_enabled[pah8011_ppg_ch_c])
bell_huang 0:242cf8f28bf2 1027 {
bell_huang 0:242cf8f28bf2 1028 if (!pah_comm_read(0x25, &data))
bell_huang 0:242cf8f28bf2 1029 goto FAIL;
bell_huang 0:242cf8f28bf2 1030 PAH_SET_BIT(data, 0);
bell_huang 0:242cf8f28bf2 1031 if (!pah_comm_write(0x25, data))
bell_huang 0:242cf8f28bf2 1032 goto FAIL;
bell_huang 0:242cf8f28bf2 1033 }
bell_huang 0:242cf8f28bf2 1034
bell_huang 0:242cf8f28bf2 1035 g_state.has_started_ppg = 1;
bell_huang 0:242cf8f28bf2 1036 return true;
bell_huang 0:242cf8f28bf2 1037
bell_huang 0:242cf8f28bf2 1038 FAIL:
bell_huang 0:242cf8f28bf2 1039 debug_printf("_pah8011_start_ppg error \n");
bell_huang 0:242cf8f28bf2 1040 return false;
bell_huang 0:242cf8f28bf2 1041 }
bell_huang 0:242cf8f28bf2 1042
bell_huang 0:242cf8f28bf2 1043 static bool _pah8011_stop_ppg(void)
bell_huang 0:242cf8f28bf2 1044 {
bell_huang 0:242cf8f28bf2 1045 uint8_t data = 0;
bell_huang 0:242cf8f28bf2 1046
bell_huang 0:242cf8f28bf2 1047 if (!g_state.has_started_ppg)
bell_huang 0:242cf8f28bf2 1048 return true;
bell_huang 0:242cf8f28bf2 1049
bell_huang 0:242cf8f28bf2 1050 debug_printf("_pah8011_stop_ppg() \n");
bell_huang 0:242cf8f28bf2 1051
bell_huang 0:242cf8f28bf2 1052 if (!pah_comm_write(0x7F, 0x01)) //bank1
bell_huang 0:242cf8f28bf2 1053 goto FAIL;
bell_huang 0:242cf8f28bf2 1054
bell_huang 0:242cf8f28bf2 1055 //channel a
bell_huang 0:242cf8f28bf2 1056 if (!pah_comm_read(0x21, &data))
bell_huang 0:242cf8f28bf2 1057 goto FAIL;
bell_huang 0:242cf8f28bf2 1058 PAH_CLEAR_BIT(data, 0);
bell_huang 0:242cf8f28bf2 1059 if (!pah_comm_write(0x21, data))
bell_huang 0:242cf8f28bf2 1060 goto FAIL;
bell_huang 0:242cf8f28bf2 1061
bell_huang 0:242cf8f28bf2 1062 //channel b
bell_huang 0:242cf8f28bf2 1063 if (!pah_comm_read(0x23, &data))
bell_huang 0:242cf8f28bf2 1064 goto FAIL;
bell_huang 0:242cf8f28bf2 1065 PAH_CLEAR_BIT(data, 0);
bell_huang 0:242cf8f28bf2 1066 if (!pah_comm_write(0x23, data))
bell_huang 0:242cf8f28bf2 1067 goto FAIL;
bell_huang 0:242cf8f28bf2 1068
bell_huang 0:242cf8f28bf2 1069 //channel c
bell_huang 0:242cf8f28bf2 1070 if (!pah_comm_read(0x25, &data))
bell_huang 0:242cf8f28bf2 1071 goto FAIL;
bell_huang 0:242cf8f28bf2 1072 PAH_CLEAR_BIT(data, 0);
bell_huang 0:242cf8f28bf2 1073 if (!pah_comm_write(0x25, data))
bell_huang 0:242cf8f28bf2 1074 goto FAIL;
bell_huang 0:242cf8f28bf2 1075
bell_huang 0:242cf8f28bf2 1076 g_state.has_started_ppg = 0;
bell_huang 0:242cf8f28bf2 1077 return true;
bell_huang 0:242cf8f28bf2 1078 FAIL:
bell_huang 0:242cf8f28bf2 1079 debug_printf("_pah8011_stop_ppg error \n");
bell_huang 0:242cf8f28bf2 1080 return false;
bell_huang 0:242cf8f28bf2 1081 }
bell_huang 0:242cf8f28bf2 1082
bell_huang 0:242cf8f28bf2 1083 static bool _pah8011_start_touch(void)
bell_huang 0:242cf8f28bf2 1084 {
bell_huang 0:242cf8f28bf2 1085 uint8_t data = 0;
bell_huang 0:242cf8f28bf2 1086
bell_huang 0:242cf8f28bf2 1087 if (g_state.has_started_touch)
bell_huang 0:242cf8f28bf2 1088 return true;
bell_huang 0:242cf8f28bf2 1089
bell_huang 0:242cf8f28bf2 1090 debug_printf("_pah8011_start_touch() \n");
bell_huang 0:242cf8f28bf2 1091
bell_huang 0:242cf8f28bf2 1092 if (!pah_comm_write(0x7F, 0x01)) //bank1
bell_huang 0:242cf8f28bf2 1093 goto FAIL;
bell_huang 0:242cf8f28bf2 1094
bell_huang 0:242cf8f28bf2 1095 // 0x36
bell_huang 0:242cf8f28bf2 1096 if (!pah_comm_read(0x36, &data))
bell_huang 0:242cf8f28bf2 1097 goto FAIL;
bell_huang 0:242cf8f28bf2 1098 if (g_state.prop_curr.is_int2_as_touch_flag)
bell_huang 0:242cf8f28bf2 1099 {
bell_huang 0:242cf8f28bf2 1100 PAH_CLEAR_BIT(data, 0);
bell_huang 0:242cf8f28bf2 1101 PAH_SET_BIT(data, 1);
bell_huang 0:242cf8f28bf2 1102 }
bell_huang 0:242cf8f28bf2 1103 else
bell_huang 0:242cf8f28bf2 1104 {
bell_huang 0:242cf8f28bf2 1105 PAH_SET_BIT(data, 0);
bell_huang 0:242cf8f28bf2 1106 PAH_CLEAR_BIT(data, 1);
bell_huang 0:242cf8f28bf2 1107 }
bell_huang 0:242cf8f28bf2 1108 if (!pah_comm_write(0x36, data))
bell_huang 0:242cf8f28bf2 1109 goto FAIL;
bell_huang 0:242cf8f28bf2 1110
bell_huang 0:242cf8f28bf2 1111 // 0x37
bell_huang 0:242cf8f28bf2 1112 if (!pah_comm_read(0x37, &data))
bell_huang 0:242cf8f28bf2 1113 goto FAIL;
bell_huang 0:242cf8f28bf2 1114 if (g_state.prop_curr.is_int2_as_touch_flag)
bell_huang 0:242cf8f28bf2 1115 {
bell_huang 0:242cf8f28bf2 1116 PAH_SET_BIT(data, 1);
bell_huang 0:242cf8f28bf2 1117 }
bell_huang 0:242cf8f28bf2 1118 else
bell_huang 0:242cf8f28bf2 1119 {
bell_huang 0:242cf8f28bf2 1120 PAH_CLEAR_BIT(data, 1);
bell_huang 0:242cf8f28bf2 1121 }
bell_huang 0:242cf8f28bf2 1122 if (!pah_comm_write(0x37, data))
bell_huang 0:242cf8f28bf2 1123 goto FAIL;
bell_huang 0:242cf8f28bf2 1124
bell_huang 0:242cf8f28bf2 1125 g_state.has_started_touch = 1;
bell_huang 0:242cf8f28bf2 1126 return true;
bell_huang 0:242cf8f28bf2 1127
bell_huang 0:242cf8f28bf2 1128 FAIL:
bell_huang 0:242cf8f28bf2 1129 debug_printf("_pah8011_start_touch error \n");
bell_huang 0:242cf8f28bf2 1130 return false;
bell_huang 0:242cf8f28bf2 1131 }
bell_huang 0:242cf8f28bf2 1132 static bool _pah8011_stop_touch(void)
bell_huang 0:242cf8f28bf2 1133 {
bell_huang 0:242cf8f28bf2 1134 uint8_t data = 0;
bell_huang 0:242cf8f28bf2 1135
bell_huang 0:242cf8f28bf2 1136 if (!g_state.has_started_touch)
bell_huang 0:242cf8f28bf2 1137 return true;
bell_huang 0:242cf8f28bf2 1138
bell_huang 0:242cf8f28bf2 1139 debug_printf("_pah8011_stop_touch() \n");
bell_huang 0:242cf8f28bf2 1140
bell_huang 0:242cf8f28bf2 1141 if (!pah_comm_write(0x7F, 0x01)) //bank1
bell_huang 0:242cf8f28bf2 1142 goto FAIL;
bell_huang 0:242cf8f28bf2 1143
bell_huang 0:242cf8f28bf2 1144 // 0x36
bell_huang 0:242cf8f28bf2 1145 if (!pah_comm_read(0x36, &data))
bell_huang 0:242cf8f28bf2 1146 goto FAIL;
bell_huang 0:242cf8f28bf2 1147 PAH_SET_BIT(data, 0);
bell_huang 0:242cf8f28bf2 1148 PAH_CLEAR_BIT(data, 1);
bell_huang 0:242cf8f28bf2 1149 if (!pah_comm_write(0x36, data))
bell_huang 0:242cf8f28bf2 1150 goto FAIL;
bell_huang 0:242cf8f28bf2 1151
bell_huang 0:242cf8f28bf2 1152 // 0x37
bell_huang 0:242cf8f28bf2 1153 if (!pah_comm_read(0x37, &data))
bell_huang 0:242cf8f28bf2 1154 goto FAIL;
bell_huang 0:242cf8f28bf2 1155 if (g_state.prop_curr.is_int2_as_touch_flag)
bell_huang 0:242cf8f28bf2 1156 {
bell_huang 0:242cf8f28bf2 1157 // empty
bell_huang 0:242cf8f28bf2 1158 }
bell_huang 0:242cf8f28bf2 1159 else
bell_huang 0:242cf8f28bf2 1160 {
bell_huang 0:242cf8f28bf2 1161 PAH_SET_BIT(data, 1);
bell_huang 0:242cf8f28bf2 1162 }
bell_huang 0:242cf8f28bf2 1163 if (!pah_comm_write(0x37, data))
bell_huang 0:242cf8f28bf2 1164 goto FAIL;
bell_huang 0:242cf8f28bf2 1165
bell_huang 0:242cf8f28bf2 1166 g_state.has_started_touch = 0;
bell_huang 0:242cf8f28bf2 1167 return true;
bell_huang 0:242cf8f28bf2 1168
bell_huang 0:242cf8f28bf2 1169 FAIL:
bell_huang 0:242cf8f28bf2 1170 debug_printf("_pah8011_stop_touch error \n");
bell_huang 0:242cf8f28bf2 1171 return false;
bell_huang 0:242cf8f28bf2 1172 }
bell_huang 0:242cf8f28bf2 1173
bell_huang 0:242cf8f28bf2 1174 static bool _pah8011_clear_fifo_and_int_req(void)
bell_huang 0:242cf8f28bf2 1175 {
bell_huang 0:242cf8f28bf2 1176 pah_ret ret = pah_err_unknown;
bell_huang 0:242cf8f28bf2 1177 uint8_t int_req = 0;
bell_huang 0:242cf8f28bf2 1178
bell_huang 0:242cf8f28bf2 1179 debug_printf("_pah8011_clear_fifo_and_int_req() \n");
bell_huang 0:242cf8f28bf2 1180
bell_huang 0:242cf8f28bf2 1181 if (!pah_comm_write(0x7F, 0x01)) //bank1
bell_huang 0:242cf8f28bf2 1182 goto FAIL;
bell_huang 0:242cf8f28bf2 1183
bell_huang 0:242cf8f28bf2 1184 // clear FIFO
bell_huang 0:242cf8f28bf2 1185 if (!pah_comm_write(0x70, 0x01)) // clear FIFO
bell_huang 0:242cf8f28bf2 1186 goto FAIL;
bell_huang 0:242cf8f28bf2 1187 ret = pah_8011_update_flag();
bell_huang 0:242cf8f28bf2 1188 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 1189 goto FAIL;
bell_huang 0:242cf8f28bf2 1190 delay_ms(PPG_FRAME_INTERVAL_MS);
bell_huang 0:242cf8f28bf2 1191 if (!pah_comm_write(0x70, 0x00)) // clear FIFO
bell_huang 0:242cf8f28bf2 1192 goto FAIL;
bell_huang 0:242cf8f28bf2 1193 ret = pah_8011_update_flag();
bell_huang 0:242cf8f28bf2 1194 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 1195 goto FAIL;
bell_huang 0:242cf8f28bf2 1196
bell_huang 0:242cf8f28bf2 1197 //clear interrupt
bell_huang 0:242cf8f28bf2 1198 if (!pah_comm_write(0x7F, 0x02)) //Bank 2
bell_huang 0:242cf8f28bf2 1199 goto FAIL;
bell_huang 0:242cf8f28bf2 1200 if (!pah_comm_read(0x1B, &int_req)) //read interrupt status
bell_huang 0:242cf8f28bf2 1201 goto FAIL;
bell_huang 0:242cf8f28bf2 1202 if (int_req > 0)
bell_huang 0:242cf8f28bf2 1203 {
bell_huang 0:242cf8f28bf2 1204 if (!pah_comm_write(0x1B, int_req)) //clear interrupt
bell_huang 0:242cf8f28bf2 1205 goto FAIL;
bell_huang 0:242cf8f28bf2 1206 }
bell_huang 0:242cf8f28bf2 1207
bell_huang 0:242cf8f28bf2 1208 return true;
bell_huang 0:242cf8f28bf2 1209
bell_huang 0:242cf8f28bf2 1210 FAIL:
bell_huang 0:242cf8f28bf2 1211 debug_printf("_pah8011_clear_fifo_and_int_req() error \n");
bell_huang 0:242cf8f28bf2 1212 return false;
bell_huang 0:242cf8f28bf2 1213 }
bell_huang 0:242cf8f28bf2 1214
bell_huang 0:242cf8f28bf2 1215 static bool _pah8011_update_report_num(void)
bell_huang 0:242cf8f28bf2 1216 {
bell_huang 0:242cf8f28bf2 1217 if (g_state.prop_curr.report_sample_num_per_ch != g_state.prop_next.report_sample_num_per_ch)
bell_huang 0:242cf8f28bf2 1218 {
bell_huang 0:242cf8f28bf2 1219 debug_printf_2("_pah8011_update_report_num(). report_sample_num_per_ch %d -> %d \n", g_state.prop_curr.report_sample_num_per_ch, g_state.prop_next.report_sample_num_per_ch);
bell_huang 0:242cf8f28bf2 1220
bell_huang 0:242cf8f28bf2 1221 if (!_pah8011_set_report_num(g_state.prop_next.report_sample_num_per_ch * pah_get_fifo_ch_num()))
bell_huang 0:242cf8f28bf2 1222 goto FAIL;
bell_huang 0:242cf8f28bf2 1223 g_state.prop_curr.report_sample_num_per_ch = g_state.prop_next.report_sample_num_per_ch;
bell_huang 0:242cf8f28bf2 1224 }
bell_huang 0:242cf8f28bf2 1225
bell_huang 0:242cf8f28bf2 1226 return true;
bell_huang 0:242cf8f28bf2 1227
bell_huang 0:242cf8f28bf2 1228 FAIL:
bell_huang 0:242cf8f28bf2 1229 debug_printf("_pah8011_update_report_num() fail \n");
bell_huang 0:242cf8f28bf2 1230 return false;
bell_huang 0:242cf8f28bf2 1231 }
bell_huang 0:242cf8f28bf2 1232
bell_huang 0:242cf8f28bf2 1233 static bool _pah8011_set_report_num(uint32_t samples_per_read)
bell_huang 0:242cf8f28bf2 1234 {
bell_huang 0:242cf8f28bf2 1235 pah_ret ret = pah_err_unknown;
bell_huang 0:242cf8f28bf2 1236 uint8_t data = 0;
bell_huang 0:242cf8f28bf2 1237 uint32_t samples_per_read_plus1 = samples_per_read + 1;
bell_huang 0:242cf8f28bf2 1238
bell_huang 0:242cf8f28bf2 1239 debug_printf_1("_pah8011_set_report_num(). samples_per_read_plus1 = %d \n", samples_per_read_plus1);
bell_huang 0:242cf8f28bf2 1240
bell_huang 0:242cf8f28bf2 1241 if (!pah_comm_write(0x7F, 0x01)) //bank1
bell_huang 0:242cf8f28bf2 1242 goto FAIL;
bell_huang 0:242cf8f28bf2 1243
bell_huang 0:242cf8f28bf2 1244 //Rpt num. write MSB first.
bell_huang 0:242cf8f28bf2 1245 data = (((samples_per_read_plus1) >> 8) & 0x01);
bell_huang 0:242cf8f28bf2 1246 if (!pah_comm_write(0x57, data))
bell_huang 0:242cf8f28bf2 1247 goto FAIL;
bell_huang 0:242cf8f28bf2 1248
bell_huang 0:242cf8f28bf2 1249 //Rpt num. write LSB last.
bell_huang 0:242cf8f28bf2 1250 data = ((samples_per_read_plus1)& 0xFF);
bell_huang 0:242cf8f28bf2 1251 if (!pah_comm_write(0x56, data))
bell_huang 0:242cf8f28bf2 1252 goto FAIL;
bell_huang 0:242cf8f28bf2 1253
bell_huang 0:242cf8f28bf2 1254 ret = pah_8011_update_flag();
bell_huang 0:242cf8f28bf2 1255 if (PAH_FAILED(ret))
bell_huang 0:242cf8f28bf2 1256 goto FAIL;
bell_huang 0:242cf8f28bf2 1257
bell_huang 0:242cf8f28bf2 1258 return true;
bell_huang 0:242cf8f28bf2 1259
bell_huang 0:242cf8f28bf2 1260 FAIL:
bell_huang 0:242cf8f28bf2 1261 debug_printf("_pah8011_set_report_num() fail \n");
bell_huang 0:242cf8f28bf2 1262 return false;
bell_huang 0:242cf8f28bf2 1263 }
bell_huang 0:242cf8f28bf2 1264
bell_huang 0:242cf8f28bf2 1265 static bool _pah8011_turn_led(bool on)
bell_huang 0:242cf8f28bf2 1266 {
bell_huang 0:242cf8f28bf2 1267 debug_printf_1(">>>> _pah8011_turn_led(), on = %d \n", on);
bell_huang 0:242cf8f28bf2 1268
bell_huang 0:242cf8f28bf2 1269 if (!pah_comm_write(0x7F, 0x00)) //bank0
bell_huang 0:242cf8f28bf2 1270 goto FAIL;
bell_huang 0:242cf8f28bf2 1271 if (on)
bell_huang 0:242cf8f28bf2 1272 {
bell_huang 0:242cf8f28bf2 1273 if (!pah_comm_write(0x70, 0x01))
bell_huang 0:242cf8f28bf2 1274 goto FAIL;
bell_huang 0:242cf8f28bf2 1275 if (!pah_comm_write(0x71, 0x02))
bell_huang 0:242cf8f28bf2 1276 goto FAIL;
bell_huang 0:242cf8f28bf2 1277 if (!pah_comm_write(0x72, 0x04))
bell_huang 0:242cf8f28bf2 1278 goto FAIL;
bell_huang 0:242cf8f28bf2 1279 }
bell_huang 0:242cf8f28bf2 1280 else
bell_huang 0:242cf8f28bf2 1281 {
bell_huang 0:242cf8f28bf2 1282 if (!pah_comm_write(0x70, 0x00))
bell_huang 0:242cf8f28bf2 1283 goto FAIL;
bell_huang 0:242cf8f28bf2 1284 if (!pah_comm_write(0x71, 0x00))
bell_huang 0:242cf8f28bf2 1285 goto FAIL;
bell_huang 0:242cf8f28bf2 1286 if (!pah_comm_write(0x72, 0x00))
bell_huang 0:242cf8f28bf2 1287 goto FAIL;
bell_huang 0:242cf8f28bf2 1288 }
bell_huang 0:242cf8f28bf2 1289
bell_huang 0:242cf8f28bf2 1290 debug_printf("<<<< _pah8011_turn_led() \n");
bell_huang 0:242cf8f28bf2 1291 return true;
bell_huang 0:242cf8f28bf2 1292
bell_huang 0:242cf8f28bf2 1293 FAIL:
bell_huang 0:242cf8f28bf2 1294 debug_printf("_pah8011_turn_led error \n");
bell_huang 0:242cf8f28bf2 1295 return false;
bell_huang 0:242cf8f28bf2 1296 }
bell_huang 0:242cf8f28bf2 1297
bell_huang 0:242cf8f28bf2 1298 #if defined(ENABLE_FIFO_CHECKSUM)
bell_huang 0:242cf8f28bf2 1299 static bool _pah8011_cks(uint8_t *fifo, uint32_t samples_read, uint32_t cks_read)
bell_huang 0:242cf8f28bf2 1300 {
bell_huang 0:242cf8f28bf2 1301 uint32_t *s = (uint32_t *)fifo;
bell_huang 0:242cf8f28bf2 1302 uint32_t raw;
bell_huang 0:242cf8f28bf2 1303 uint32_t cks_cal = 0;
bell_huang 0:242cf8f28bf2 1304 uint32_t i;
bell_huang 0:242cf8f28bf2 1305
bell_huang 0:242cf8f28bf2 1306 //checksum compare
bell_huang 0:242cf8f28bf2 1307 for (i = 0; i < samples_read; i++)
bell_huang 0:242cf8f28bf2 1308 {
bell_huang 0:242cf8f28bf2 1309 raw = *(s);
bell_huang 0:242cf8f28bf2 1310 cks_cal = cks_cal ^ raw;
bell_huang 0:242cf8f28bf2 1311 s++;
bell_huang 0:242cf8f28bf2 1312 }
bell_huang 0:242cf8f28bf2 1313
bell_huang 0:242cf8f28bf2 1314 if (cks_cal != cks_read)
bell_huang 0:242cf8f28bf2 1315 {
bell_huang 0:242cf8f28bf2 1316 s = (uint32_t *)fifo;
bell_huang 0:242cf8f28bf2 1317
bell_huang 0:242cf8f28bf2 1318 debug_printf("fifo = { \n");
bell_huang 0:242cf8f28bf2 1319 for (i = 0; i < samples_read; i++)
bell_huang 0:242cf8f28bf2 1320 {
bell_huang 0:242cf8f28bf2 1321 raw = *(s);
bell_huang 0:242cf8f28bf2 1322 debug_printf_1("%X, ", raw);
bell_huang 0:242cf8f28bf2 1323 s++;
bell_huang 0:242cf8f28bf2 1324 }
bell_huang 0:242cf8f28bf2 1325 debug_printf("} \n");
bell_huang 0:242cf8f28bf2 1326 debug_printf_2("cks_cal == %X, cks_read == %X \n", cks_cal, cks_read);
bell_huang 0:242cf8f28bf2 1327
bell_huang 0:242cf8f28bf2 1328 return false;
bell_huang 0:242cf8f28bf2 1329 }
bell_huang 0:242cf8f28bf2 1330 return true;
bell_huang 0:242cf8f28bf2 1331 }
bell_huang 0:242cf8f28bf2 1332 #endif // ENABLE_FIFO_CHECKSUM
bell_huang 0:242cf8f28bf2 1333
bell_huang 0:242cf8f28bf2 1334 static bool _pah8011_read_touch_flag(uint8_t *touch_flag)
bell_huang 0:242cf8f28bf2 1335 {
bell_huang 0:242cf8f28bf2 1336 uint8_t data = 0;
bell_huang 0:242cf8f28bf2 1337
bell_huang 0:242cf8f28bf2 1338 if (!touch_flag)
bell_huang 0:242cf8f28bf2 1339 goto FAIL;
bell_huang 0:242cf8f28bf2 1340
bell_huang 0:242cf8f28bf2 1341 if (!pah_comm_write(0x7F, 0x02)) //Bank 2
bell_huang 0:242cf8f28bf2 1342 goto FAIL;
bell_huang 0:242cf8f28bf2 1343 if (!pah_comm_read(0x00, &data))
bell_huang 0:242cf8f28bf2 1344 goto FAIL;
bell_huang 0:242cf8f28bf2 1345
bell_huang 0:242cf8f28bf2 1346 *touch_flag = data & 0x01;
bell_huang 0:242cf8f28bf2 1347
bell_huang 0:242cf8f28bf2 1348 return true;
bell_huang 0:242cf8f28bf2 1349
bell_huang 0:242cf8f28bf2 1350 FAIL:
bell_huang 0:242cf8f28bf2 1351 debug_printf("_pah8011_read_touch_flag() fail \n");
bell_huang 0:242cf8f28bf2 1352 return false;
bell_huang 0:242cf8f28bf2 1353 }
bell_huang 0:242cf8f28bf2 1354
bell_huang 0:242cf8f28bf2 1355 static bool _pah8011_enable_fifo_clk(bool enable)
bell_huang 0:242cf8f28bf2 1356 {
bell_huang 0:242cf8f28bf2 1357 if (enable)
bell_huang 0:242cf8f28bf2 1358 {
bell_huang 0:242cf8f28bf2 1359 if (!pah_comm_write(0x7F, 0x01)) //Bank 1
bell_huang 0:242cf8f28bf2 1360 goto FAIL;
bell_huang 0:242cf8f28bf2 1361 if (!pah_comm_write(0x71, 0x00))
bell_huang 0:242cf8f28bf2 1362 goto FAIL;
bell_huang 0:242cf8f28bf2 1363 if (!pah_comm_write(0x7F, 0x00)) //Bank 0
bell_huang 0:242cf8f28bf2 1364 goto FAIL;
bell_huang 0:242cf8f28bf2 1365 if (!pah_comm_write(0x10, 0x03))
bell_huang 0:242cf8f28bf2 1366 goto FAIL;
bell_huang 0:242cf8f28bf2 1367 }
bell_huang 0:242cf8f28bf2 1368 else // disable
bell_huang 0:242cf8f28bf2 1369 {
bell_huang 0:242cf8f28bf2 1370 if (!pah_comm_write(0x7F, 0x01)) //Bank 1
bell_huang 0:242cf8f28bf2 1371 goto FAIL;
bell_huang 0:242cf8f28bf2 1372 if (!pah_comm_write(0x71, 0x01))
bell_huang 0:242cf8f28bf2 1373 goto FAIL;
bell_huang 0:242cf8f28bf2 1374 if (!pah_comm_write(0x7F, 0x00)) //Bank 0
bell_huang 0:242cf8f28bf2 1375 goto FAIL;
bell_huang 0:242cf8f28bf2 1376 if (!pah_comm_write(0x10, 0x00))
bell_huang 0:242cf8f28bf2 1377 goto FAIL;
bell_huang 0:242cf8f28bf2 1378 }
bell_huang 0:242cf8f28bf2 1379
bell_huang 0:242cf8f28bf2 1380 return true;
bell_huang 0:242cf8f28bf2 1381
bell_huang 0:242cf8f28bf2 1382 FAIL:
bell_huang 0:242cf8f28bf2 1383 debug_printf("_pah8011_enable_fifo_clk error \n");
bell_huang 0:242cf8f28bf2 1384 return false;
bell_huang 0:242cf8f28bf2 1385 }
bell_huang 0:242cf8f28bf2 1386
bell_huang 0:242cf8f28bf2 1387 static pah_ret _pah8011_read_ppg_fifo(uint32_t samples_per_read_per_ch, uint32_t ch_num)
bell_huang 0:242cf8f28bf2 1388 {
bell_huang 0:242cf8f28bf2 1389 pah_ret ret = pah_err_unknown;
bell_huang 0:242cf8f28bf2 1390 uint32_t samples_per_read = samples_per_read_per_ch * ch_num;
bell_huang 0:242cf8f28bf2 1391
bell_huang 0:242cf8f28bf2 1392 //debug_printf_1("_pah8011_read_ppg_fifo(). samples_per_read = %d \n", samples_per_read);
bell_huang 0:242cf8f28bf2 1393
bell_huang 0:242cf8f28bf2 1394 // read fifo
bell_huang 0:242cf8f28bf2 1395 if (!pah_comm_write(0x7F, 0x03)) //Bank 3
bell_huang 0:242cf8f28bf2 1396 {
bell_huang 0:242cf8f28bf2 1397 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 1398 goto FAIL;
bell_huang 0:242cf8f28bf2 1399 }
bell_huang 0:242cf8f28bf2 1400 else if (!pah_comm_burst_read(0, g_state.fifo_data, samples_per_read * 4)) //read FIFO
bell_huang 0:242cf8f28bf2 1401 {
bell_huang 0:242cf8f28bf2 1402 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 1403 goto FAIL;
bell_huang 0:242cf8f28bf2 1404 }
bell_huang 0:242cf8f28bf2 1405 else
bell_huang 0:242cf8f28bf2 1406 {
bell_huang 0:242cf8f28bf2 1407 uint32_t *s = (uint32_t *)g_state.fifo_data;
bell_huang 0:242cf8f28bf2 1408
bell_huang 0:242cf8f28bf2 1409 // update touch_flag
bell_huang 0:242cf8f28bf2 1410 if (g_state.fifo_data_contain_touch_bit)
bell_huang 0:242cf8f28bf2 1411 {
bell_huang 0:242cf8f28bf2 1412 g_state.touch_flag = s[(samples_per_read - 1)] & 0x01;
bell_huang 0:242cf8f28bf2 1413 }
bell_huang 0:242cf8f28bf2 1414 else
bell_huang 0:242cf8f28bf2 1415 {
bell_huang 0:242cf8f28bf2 1416 if (!_pah8011_read_touch_flag(&g_state.touch_flag))
bell_huang 0:242cf8f28bf2 1417 {
bell_huang 0:242cf8f28bf2 1418 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 1419 goto FAIL;
bell_huang 0:242cf8f28bf2 1420 }
bell_huang 0:242cf8f28bf2 1421 }
bell_huang 0:242cf8f28bf2 1422
bell_huang 0:242cf8f28bf2 1423 #if defined(ENABLE_FIFO_CHECKSUM)
bell_huang 0:242cf8f28bf2 1424 {
bell_huang 0:242cf8f28bf2 1425 uint8_t cks[8] = { 0 };
bell_huang 0:242cf8f28bf2 1426 if (!pah_comm_write(0x7F, 0x02))
bell_huang 0:242cf8f28bf2 1427 {
bell_huang 0:242cf8f28bf2 1428 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 1429 goto FAIL;
bell_huang 0:242cf8f28bf2 1430 }
bell_huang 0:242cf8f28bf2 1431 if (!pah_comm_burst_read(0x1C, cks, 4)) //checksum
bell_huang 0:242cf8f28bf2 1432 {
bell_huang 0:242cf8f28bf2 1433 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 1434 goto FAIL;
bell_huang 0:242cf8f28bf2 1435 }
bell_huang 0:242cf8f28bf2 1436 if (!_pah8011_cks(g_state.fifo_data, samples_per_read, *(uint32_t *)cks))
bell_huang 0:242cf8f28bf2 1437 {
bell_huang 0:242cf8f28bf2 1438 debug_printf("_pah8011_read_ppg_fifo(). _pah8011_cks fail\n");
bell_huang 0:242cf8f28bf2 1439 ret = pah_err_fifo_checksum_fail;
bell_huang 0:242cf8f28bf2 1440 goto FAIL;
bell_huang 0:242cf8f28bf2 1441 }
bell_huang 0:242cf8f28bf2 1442 debug_printf("_pah8011_read_ppg_fifo(). _pah8011_cks success\n");
bell_huang 0:242cf8f28bf2 1443 }
bell_huang 0:242cf8f28bf2 1444 #endif // ENABLE_FIFO_CHECKSUM
bell_huang 0:242cf8f28bf2 1445
bell_huang 0:242cf8f28bf2 1446 // report fifo
bell_huang 0:242cf8f28bf2 1447 if (g_state.fp_report_fifo_handler)
bell_huang 0:242cf8f28bf2 1448 {
bell_huang 0:242cf8f28bf2 1449 pah_report_fifo fifo;
bell_huang 0:242cf8f28bf2 1450 fifo.data = g_state.fifo_data;
bell_huang 0:242cf8f28bf2 1451 fifo.touch_flag = g_state.touch_flag;
bell_huang 0:242cf8f28bf2 1452 g_state.fp_report_fifo_handler(g_state.user_data, &fifo);
bell_huang 0:242cf8f28bf2 1453 }
bell_huang 0:242cf8f28bf2 1454
bell_huang 0:242cf8f28bf2 1455 g_state.fifo_data_num_per_ch = samples_per_read_per_ch;
bell_huang 0:242cf8f28bf2 1456 }
bell_huang 0:242cf8f28bf2 1457
bell_huang 0:242cf8f28bf2 1458 return pah_success;
bell_huang 0:242cf8f28bf2 1459
bell_huang 0:242cf8f28bf2 1460 FAIL:
bell_huang 0:242cf8f28bf2 1461 debug_printf_1("_pah8011_read_ppg_fifo(). fail, ret = %d \n", ret);
bell_huang 0:242cf8f28bf2 1462 return ret;
bell_huang 0:242cf8f28bf2 1463 }
bell_huang 0:242cf8f28bf2 1464
bell_huang 0:242cf8f28bf2 1465 static pah_ret _pah8011_task_dri(uint8_t int_req, uint32_t ch_num)
bell_huang 0:242cf8f28bf2 1466 {
bell_huang 0:242cf8f28bf2 1467 pah_ret ret = pah_err_unknown;
bell_huang 0:242cf8f28bf2 1468
bell_huang 0:242cf8f28bf2 1469 // no interrupt
bell_huang 0:242cf8f28bf2 1470 if (!int_req)
bell_huang 0:242cf8f28bf2 1471 {
bell_huang 0:242cf8f28bf2 1472 // ignore
bell_huang 0:242cf8f28bf2 1473 debug_printf("_pah8011_task_dri(). No interrupt. \n");
bell_huang 0:242cf8f28bf2 1474 return pah_pending;
bell_huang 0:242cf8f28bf2 1475 }
bell_huang 0:242cf8f28bf2 1476
bell_huang 0:242cf8f28bf2 1477 // fifo interrupt
bell_huang 0:242cf8f28bf2 1478 if (int_req & 0x01)
bell_huang 0:242cf8f28bf2 1479 {
bell_huang 0:242cf8f28bf2 1480 uint32_t samples_per_read = g_state.prop_curr.report_sample_num_per_ch * ch_num;
bell_huang 0:242cf8f28bf2 1481 uint16_t fifo_data_number = 0;
bell_huang 0:242cf8f28bf2 1482
bell_huang 0:242cf8f28bf2 1483 if (!pah_comm_write(0x7F, 0x02)) //Bank 2
bell_huang 0:242cf8f28bf2 1484 {
bell_huang 0:242cf8f28bf2 1485 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 1486 goto FAIL;
bell_huang 0:242cf8f28bf2 1487 }
bell_huang 0:242cf8f28bf2 1488 if (!pah_comm_burst_read(0x25, (uint8_t*)&fifo_data_number, 2))
bell_huang 0:242cf8f28bf2 1489 {
bell_huang 0:242cf8f28bf2 1490 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 1491 goto FAIL;
bell_huang 0:242cf8f28bf2 1492 }
bell_huang 0:242cf8f28bf2 1493
bell_huang 0:242cf8f28bf2 1494 //debug_printf("_pah8011_task_dri(). fifo_data_number = %d, samples_per_read = %d. \n", fifo_data_number, samples_per_read);
bell_huang 0:242cf8f28bf2 1495
bell_huang 0:242cf8f28bf2 1496 if (fifo_data_number < samples_per_read)
bell_huang 0:242cf8f28bf2 1497 return pah_pending;
bell_huang 0:242cf8f28bf2 1498
bell_huang 0:242cf8f28bf2 1499 ret = _pah8011_read_ppg_fifo(g_state.prop_curr.report_sample_num_per_ch, ch_num);
bell_huang 0:242cf8f28bf2 1500 if (ret != pah_success)
bell_huang 0:242cf8f28bf2 1501 goto FAIL;
bell_huang 0:242cf8f28bf2 1502 }
bell_huang 0:242cf8f28bf2 1503
bell_huang 0:242cf8f28bf2 1504 // touch interrupt
bell_huang 0:242cf8f28bf2 1505 if (int_req & 0x02)
bell_huang 0:242cf8f28bf2 1506 {
bell_huang 0:242cf8f28bf2 1507 if (!_pah8011_read_touch_flag(&g_state.touch_flag))
bell_huang 0:242cf8f28bf2 1508 {
bell_huang 0:242cf8f28bf2 1509 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 1510 goto FAIL;
bell_huang 0:242cf8f28bf2 1511 }
bell_huang 0:242cf8f28bf2 1512 }
bell_huang 0:242cf8f28bf2 1513
bell_huang 0:242cf8f28bf2 1514 return pah_success;
bell_huang 0:242cf8f28bf2 1515
bell_huang 0:242cf8f28bf2 1516 FAIL:
bell_huang 0:242cf8f28bf2 1517 debug_printf_1("_pah8011_task_dri(). fail, ret = %d \n", ret);
bell_huang 0:242cf8f28bf2 1518 return ret;
bell_huang 0:242cf8f28bf2 1519 }
bell_huang 0:242cf8f28bf2 1520
bell_huang 0:242cf8f28bf2 1521 static pah_ret _pah8011_task_polling(uint8_t int_req, uint32_t ch_num)
bell_huang 0:242cf8f28bf2 1522 {
bell_huang 0:242cf8f28bf2 1523 pah_ret ret = pah_err_unknown;
bell_huang 0:242cf8f28bf2 1524 uint16_t fifo_data_number = 0;
bell_huang 0:242cf8f28bf2 1525 uint32_t samples_per_read_per_ch = 0;
bell_huang 0:242cf8f28bf2 1526
bell_huang 0:242cf8f28bf2 1527 if (!pah_comm_write(0x7F, 0x02)) //Bank 2
bell_huang 0:242cf8f28bf2 1528 {
bell_huang 0:242cf8f28bf2 1529 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 1530 goto FAIL;
bell_huang 0:242cf8f28bf2 1531 }
bell_huang 0:242cf8f28bf2 1532 if (!pah_comm_burst_read(0x25, (uint8_t*)&fifo_data_number, 2))
bell_huang 0:242cf8f28bf2 1533 {
bell_huang 0:242cf8f28bf2 1534 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 1535 goto FAIL;
bell_huang 0:242cf8f28bf2 1536 }
bell_huang 0:242cf8f28bf2 1537
bell_huang 0:242cf8f28bf2 1538 if (fifo_data_number == 0)
bell_huang 0:242cf8f28bf2 1539 return pah_pending;
bell_huang 0:242cf8f28bf2 1540
bell_huang 0:242cf8f28bf2 1541 debug_printf_1("_pah8011_task_polling(). fifo_data_number = %d \n", fifo_data_number);
bell_huang 0:242cf8f28bf2 1542
bell_huang 0:242cf8f28bf2 1543 samples_per_read_per_ch = (fifo_data_number - 1) / ch_num;
bell_huang 0:242cf8f28bf2 1544 if (samples_per_read_per_ch < 1)
bell_huang 0:242cf8f28bf2 1545 return pah_pending;
bell_huang 0:242cf8f28bf2 1546
bell_huang 0:242cf8f28bf2 1547 // enable clk
bell_huang 0:242cf8f28bf2 1548 if (!_pah8011_enable_fifo_clk(true))
bell_huang 0:242cf8f28bf2 1549 {
bell_huang 0:242cf8f28bf2 1550 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 1551 goto FAIL;
bell_huang 0:242cf8f28bf2 1552 }
bell_huang 0:242cf8f28bf2 1553
bell_huang 0:242cf8f28bf2 1554 ret = _pah8011_read_ppg_fifo(samples_per_read_per_ch, ch_num);
bell_huang 0:242cf8f28bf2 1555
bell_huang 0:242cf8f28bf2 1556 // disable clk
bell_huang 0:242cf8f28bf2 1557 if (!_pah8011_enable_fifo_clk(false))
bell_huang 0:242cf8f28bf2 1558 {
bell_huang 0:242cf8f28bf2 1559 ret = pah_err_platform_fail;
bell_huang 0:242cf8f28bf2 1560 goto FAIL;
bell_huang 0:242cf8f28bf2 1561 }
bell_huang 0:242cf8f28bf2 1562
bell_huang 0:242cf8f28bf2 1563 if (ret != pah_success)
bell_huang 0:242cf8f28bf2 1564 goto FAIL;
bell_huang 0:242cf8f28bf2 1565
bell_huang 0:242cf8f28bf2 1566 return pah_success;
bell_huang 0:242cf8f28bf2 1567
bell_huang 0:242cf8f28bf2 1568 FAIL:
bell_huang 0:242cf8f28bf2 1569 debug_printf_1("_pah8011_task_polling(). fail, ret = %d \n", ret);
bell_huang 0:242cf8f28bf2 1570 return ret;
bell_huang 0:242cf8f28bf2 1571 }