![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
uart
Dependencies: MAX32620FTHR USBDevice
Revision 0:c62425b2f286, committed 2022-10-16
- Comitter:
- rsjawale24
- Date:
- Sun Oct 16 15:35:01 2022 +0000
- Commit message:
- ok
Changed in this revision
diff -r 000000000000 -r c62425b2f286 MAX32620FTHR.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MAX32620FTHR.lib Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/teams/MaximIntegrated/code/MAX32620FTHR/#7fb8d4388fe1
diff -r 000000000000 -r c62425b2f286 USBDevice.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice.lib Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/psionprime/code/USBDevice/#6ef9c5c0250e
diff -r 000000000000 -r c62425b2f286 cmd.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmd.cpp Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,283 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#include "cmd.h" +#include <stdlib.h> +#include <string.h> +#include "USBSerial.h" +#include "controller.h" +#include "interface.h" +#include "gesture_lib.h" +#include "config.h" + +extern const char *version_string; + +#if ENABLE_USER_FRAMES +extern uint32_t userDataFrameFlag; +extern int user_pixels[60]; +int cmd_frame(char *toks[], const unsigned int tokCount); +#endif + +#if USE_UART_INTERFACE +extern Serial *serial; +#else +extern USBSerial *serial; +#endif + +commandTable cmdTable[] = +{ + {"ping","Ping the processor.", cmd_ping}, + {"help","Display help.", cmd_help}, + {"ver","Display firmware version", cmd_ver}, + {"reg", "reg <read/write> <addr> <num/value>. Read or write to a device register.", cmd_reg}, + {"stream", "stream <on/off> [nopixels]. Enable data streaming mode. Use nopixels parameter to suppress pixel data.", cmd_stream}, + {"forcecal", "Force bias calibration (tracking mode).", cmd_force_tracking_cal}, + {"reset", "reset device register settings.", cmd_reset}, + {"poll", "Request gesture results", cmd_poll}, + {CMD_TABLE_END, "", NULL} // last command must be NULL +}; + +// Parses command string and calls appropriate function, passing arguments +int processCmdString(char *st) +{ + char *toks[MAX_TOKENS]; + unsigned int tokCount = 0; + int cmdIndex = 0; + + // Get tokens + toks[tokCount] = strtok(st, " "); + while((toks[tokCount] != NULL) && (tokCount < MAX_TOKENS)) { + tokCount++; + toks[tokCount] = strtok(NULL, " "); + } + + // Find a valid command + cmdIndex = lookupCmd(toks[0]); + + // If command found call the function + if(cmdIndex >= 0) { + return cmdTable[cmdIndex].fp(toks, tokCount); + } + return CMD_NACK; +} + +// Returns index of command if found. Returns -1 if no command found +int lookupCmd(const char *str) +{ + int i = 0; + while(1) { + if(strcmp(cmdTable[i].cmd, CMD_TABLE_END) == 0) // no command found + return -1; + if(strcmp(str, cmdTable[i].cmd) == 0) + return(i); + i++; + } +} + +// Custom implementation of polling of serial port +// to build a command string and pass it to processCmdString() +int checkUserCmd() +{ + static int index = 0; + static char cmdString[CMD_BUFFER_SIZE]; + int status = 0; + while ((*serial).readable()) { + char ch = (char)(*serial).getc(); + if (ch == 0x08 && index > 0) { // got a backspace, delete the previous character + index--; + } + else if (ch == '\r') {/*ignore*/} + else if (ch == '\n') { // Command string is ready to be processed + cmdString[index] = 0; // NULL terminate the string + index = 0; // reset the index + if (processCmdString(cmdString) == CMD_NACK) { + (*serial).printf("Invalid command received: %s\n", cmdString); + } + else { + status = 1; + } + } + else { + cmdString[index++] = ch; + } + } + return status; +} + +int cmd_ping(char *toks[], const unsigned int tokCount) +{ + (*serial).puts("ack\n"); + return CMD_ACK; +} + +int cmd_ver(char *toks[], const unsigned int tokCount) +{ + (*serial).puts(version_string); + (*serial).puts("\n"); + return CMD_ACK; +} + +int cmd_help(char *toks[], const unsigned int tokCount) +{ + if (tokCount == 1) { + (*serial).printf("Commands available. Type 'help <command>' for additional info: "); + int i = 0; + while (strcmp(cmdTable[i].cmd, CMD_TABLE_END) != 0) { + (*serial).printf("%s ", cmdTable[i++].cmd); + } + (*serial).printf("\n"); + } + else { + int cmdIndex = lookupCmd(toks[1]); + if(cmdIndex == -1) { + (*serial).printf("No help on that topic. Type 'help' for list of commands\n"); + } + else { + (*serial).printf("%s: ", cmdTable[cmdIndex].cmd); + (*serial).printf(cmdTable[cmdIndex].helpStr); + (*serial).printf("\n"); + } + } + return CMD_ACK; +} + +int cmd_reg(char *toks[], const unsigned int tokCount) +{ + if (tokCount < 4) + return CMD_NACK; + char * cmd = toks[1]; + uint8_t reg_addr = strtoul(toks[2], NULL, 0); + + if (strcmp(cmd, "read") == 0) { + uint8_t num_bytes = strtoul(toks[3], NULL, 0); + uint8_t reg_vals[MAX_REG_READ_SIZE]; + uint8_t output[MAX_REG_OUTPUT_LENGTH]; // char array to store string output + char *output_idx = (char*) output; // used to iterate through char array, must be a char for sprintf + + reg_read(reg_addr, num_bytes, reg_vals); + for(int i=0; i<num_bytes; i++) { + sprintf(output_idx, "%02X", reg_vals[i]); + output_idx += 2; // increment by two characters + if (i<num_bytes-1) { + sprintf(output_idx++, " "); // values separated by a space + } + } + sprintf(output_idx, "\n"); // add a newline to indicate end-of-frame + + sendDataStream(output, num_bytes * 3); // Send as a data stream for better speed, in case application is polling frame data. + } + else if (strcmp(cmd, "write") == 0) { + uint8_t reg_val = strtoul(toks[3], NULL, 0); + reg_write(reg_addr, reg_val); + } + else { + return CMD_NACK; + } + return CMD_ACK; +} + +// Enable data streaming mode, based on hardware interrupt from the INTb pin */ +int cmd_stream(char *toks[], const unsigned int tokCount) +{ + if (tokCount < 2) { + return CMD_NACK; + } + char * enable_stream = toks[1]; + if (strcmp(enable_stream, "on") == 0) { + if (tokCount > 2) { + char * no_data_parameter = toks[2]; + if (strcmp(no_data_parameter, "nopixels") == 0) { + set_stream_on(0); + } + else { + return CMD_NACK; + } + } + else { + set_stream_on(1); + } + } + else if (strcmp(enable_stream, "off") == 0) { + set_stream_off(); + } + else { + return CMD_NACK; + } + return CMD_ACK; +} + +int cmd_track(char *toks[], const unsigned int tokCount) +{ + uint32_t cols, rows; + if (tokCount < 2) { + cols = 3; + rows = 2; + } + else { + cols = strtoul(toks[1], NULL, 0); + rows = strtoul(toks[2], NULL, 0); + } + return CMD_ACK; +} + +int cmd_force_tracking_cal(char *toks[], const unsigned int tokCount) +{ + forceTrackingCalibration(); + return CMD_ACK; +} + +int cmd_reset(char *toks[], const unsigned int tokCount) +{ + set_default_register_settings(); + return CMD_ACK; +} + +extern GestureResult gesResult; +extern GestureEvent latched_gesture; +int cmd_poll(char *toks[], const unsigned int tokCount) +{ + (*serial).printf("%d,%d,%d,%d,%.2f,%.2f,%.2f,%d,%d,%d\n", + gesResult.int_placeholder, + gesResult.state, + gesResult.n_sample, + gesResult.maxpixel, + gesResult.x, + gesResult.y, + gesResult.float_placeholder, + gesResult.int_placeholder, + gesResult.int_placeholder, + gesResult.int_placeholder + ); +}
diff -r 000000000000 -r c62425b2f286 cmd.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmd.h Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#ifndef CMDS_H_INCLUDED +#define CMDS_H_INCLUDED + +#include "mbed.h" + +#define MAX_TOKENS 16 /*Increased for frame read over usb. Can reduce to 10*/ +#define CMD_BUFFER_SIZE 129 /*Increased size for frame read over usb. Can reduce to 65*/ +#define CMD_TABLE_END "NULL" +#define CMD_ACK 0 +#define CMD_NACK 1 + +#define MAX_REG_OUTPUT_LENGTH 512 +#define MAX_REG_READ_SIZE 256 + +extern void enable_read_sensor_frames(); +extern void disable_read_sensor_frames(); +extern void set_stream_on(uint32_t send_pixel_data); +extern void set_stream_off(); +extern void set_default_register_settings(); + +typedef struct { + char cmd[128]; + const char *helpStr; + int (*fp)(char *toks[], const unsigned int tokCount); +}commandTable; + +int processCmdString(char *st); +int lookupCmd(const char *str); +int checkUserCmd(); + +int cmd_ping(char *toks[], const unsigned int tokCount); +int cmd_ver(char *toks[], const unsigned int tokCount); +int cmd_help(char *toks[], const unsigned int tokCount); +int cmd_reg(char *toks[], const unsigned int tokCount); +int cmd_stream(char *toks[], const unsigned int tokCount); +int cmd_force_tracking_cal(char *toks[], const unsigned int tokCount); +int cmd_poll(char *toks[], const unsigned int tokCount); +int cmd_reset(char *toks[], const unsigned int tokCount); +#endif
diff -r 000000000000 -r c62425b2f286 config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config.h Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,45 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +// Uncomment one device option +//#define MAX25205_DEVICE +#define MAX25405_DEVICE + +// Uncomment one platform option +//#define COMPILE_FOR_MAX32630 +#define COMPILE_FOR_MAX32620 + +// With EVKIT hardware, cannot instantiate SPI and also use I2C (these share clk and data lines on HW) +#define USE_SPI 1
diff -r 000000000000 -r c62425b2f286 controller.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/controller.cpp Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,151 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#include "mbed.h" +#include "controller.h" +#include "config.h" + +static uint32_t i2c_device_addr = 0x9E; // LSB justified + +#define I2C_ADDR_SELECT 0 + +void i2c_init() +{ + if (I2C_ADDR_SELECT) { + csb = 0; // set low for default i2c address + i2c_device_addr = 0x9E; + } + else { + csb = 1; + i2c_device_addr = 0xA0; + } + sel = 1; // set high for i2c +} + +void spi_init() +{ + sel = 0; // set low for SPI +} + +int reg_read(const uint8_t reg_addr, const uint8_t num_bytes, uint8_t reg_vals[]) +{ + if (serial_mode == SPI_MODE) { + spi_read(reg_addr, num_bytes, reg_vals); + } + else { + i2c_read(reg_addr, num_bytes, reg_vals); + } + return 0; +} + +int reg_write(const uint8_t reg_addr, const uint8_t reg_val) +{ + int result = (serial_mode == SPI_MODE ? spi_write(reg_addr, reg_val) : i2c_write(reg_addr, reg_val)); + return result; +} + +int i2c_read(const uint8_t reg_addr, const uint8_t num_bytes, uint8_t reg_vals[]) +{ + #if !USE_SPI + char read_addr = (char)reg_addr; + i2c.write(i2c_device_addr, &read_addr, 1); + i2c.read(i2c_device_addr, (char*)reg_vals, (int)num_bytes); + #endif + return 0; +} + +int i2c_write(const uint8_t reg_addr, const uint8_t reg_val) +{ + #if !USE_SPI + char data[2]; + data[0] = reg_addr; + data[1] = reg_val; + i2c.write(i2c_device_addr, data, 2); + #endif + return 0; +} + +int spi_read(const uint8_t reg_addr, const uint8_t num_bytes, uint8_t reg_vals[]) +{ + #if USE_SPI + csb = 0; + spi.write(reg_addr); // byte 1: register address + spi.write(0x80); // byte 2: read command 0x80 + for(int i=0; i<num_bytes; i++) { + reg_vals[i] = spi.write(0x00); // byte3: read byte + } + csb = 1; + #endif + return 0; +} + +int spi_write(const uint8_t reg_addr, const uint8_t reg_val) +{ + #if USE_SPI + csb = 0; + spi.write(reg_addr); // byte1: register address + spi.write(0x00); // byte2: write command 0x00 + spi.write(reg_val); // byte3: write byte + csb = 1; + #endif + return 0; +} + +void getSensorPixels(int pixels[], const uint8_t flip_sensor_pixels) +{ + unsigned char reg_vals[NUM_SENSOR_PIXELS*2]; + reg_read(0x10, NUM_SENSOR_PIXELS*2, reg_vals); + + for (int i = 0; i < NUM_SENSOR_PIXELS; i++) { + pixels[i] = convertTwoUnsignedBytesToInt(reg_vals[2 * i], reg_vals[2 * i + 1]); + } + + if (flip_sensor_pixels) { + for (int i = 0; i < NUM_SENSOR_PIXELS/2; i++) { + int temp = pixels[i]; + pixels[i] = pixels[NUM_SENSOR_PIXELS-1-i]; + pixels[NUM_SENSOR_PIXELS-1-i] = temp; + } + } +} + +int convertTwoUnsignedBytesToInt(uint8_t hi_byte, uint8_t lo_byte) +{ + int intval = (int)(hi_byte << 8 | lo_byte); + // Convert unsigned to 2's complement + if ((1 << 15) < intval) + intval -= (1 << 16); + return intval; +}
diff -r 000000000000 -r c62425b2f286 controller.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/controller.h Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#ifndef CONTROLLER_H_INCLUDED +#define CONTROLLER_H_INCLUDED + +#include "gesture_common.h" + +extern DigitalOut rLED; +extern DigitalOut gLED; +extern DigitalOut csb; // sensor 1 +extern DigitalOut sel; + +enum ser_modes {SPI_MODE, I2C_MODE}; +extern uint32_t serial_mode; + +// Serial Interfaces to device +extern I2C i2c; +extern SPI spi; + +void i2c_init(); +void spi_init(); +int reg_read(const uint8_t reg_addr, const uint8_t num_bytes, uint8_t reg_vals[]); +int reg_write(const uint8_t reg_addr, const uint8_t reg_val); +int i2c_read(const uint8_t reg_addr, uint8_t const num_bytes, uint8_t reg_vals[]); +int i2c_write(const uint8_t reg_addr, const uint8_t reg_val); +int spi_read(const uint8_t reg_addr, const uint8_t num_bytes, uint8_t reg_vals[]); +int spi_write(const uint8_t reg_addr, const uint8_t reg_val); +void getSensorPixels(int pixels[], const uint8_t flip_sensor_pixels); +int convertTwoUnsignedBytesToInt(const unsigned char hi_byte, const unsigned char lo_byte); + +#endif
diff -r 000000000000 -r c62425b2f286 gesture.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gesture.c Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,203 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#include "gesture_common.h" + +// Gesture states +typedef enum {STATE_INACTIVE, GESTURE_IN_PROGRESS} GestureState; + +static uint32_t reset_flag = TRUE; + +// Create a static instance of the configuration to maintain current config parameters +static GestureConfig gestCfg; + +static void runDynamicGesture(const GestureConfig *cfg, int _pixels[], DynamicGestureResult *gesResult); +void noiseWindow3Filter(int pixels[], const float alpha, const uint32_t reset_flag); + +void resetGesture() +{ + reset_flag = TRUE; + // Reset submodules + resetTracking(); +} + +// Get a copy of the config struct +void getGestureConfig(GestureConfig *_cfg) +{ + *_cfg = gestCfg; +} + +// Get a pointer to the config struct +GestureConfig * getGestureConfigPtr() +{ + return &gestCfg; +} + +// Copy the user's config struct to the local struct, and initialize calculated values +void configGesture(const GestureConfig *_cfg) +{ + if (!_cfg) { + initConfigStructToDefaults(&gestCfg); // Use default configuration if pointer is NULL + } + else { + gestCfg = *_cfg; // make a copy of the struct + } + + configTracking(gestCfg.sample_period_ms, gestCfg.adc_full_scale, &gestCfg.trackingConfig); + + resetGesture(); +} + +void runGesture(int pixels[], GestureResult *gesResult) +{ + // Initialize result structure + memset(gesResult, 0, sizeof(GestureResult)); + gesResult->state = STATE_INACTIVE; + gesResult->gesture = GEST_NONE; + + // Noise filter + if (gestCfg.enable_window_filter) { + noiseWindow3Filter(pixels, gestCfg.window_filter_alpha, reset_flag); + } + + // Process pixels for dynamic gesture + if (1) { + DynamicGestureResult dynamicResult; + runDynamicGesture(&gestCfg, pixels, &dynamicResult); + gesResult->state = dynamicResult.state; + gesResult->n_sample = dynamicResult.n_sample; + gesResult->maxpixel = dynamicResult.maxpixel; + gesResult->x = dynamicResult.x; + gesResult->y = dynamicResult.y; + } + // Process pixels for tracking + if (0) { + TrackingResult trackResult; + runTracking(&gestCfg.trackingConfig, pixels, &trackResult); + gesResult->state = trackResult.state; + gesResult->maxpixel = trackResult.maxpixel; // Will override dynamic result if any + gesResult->x = trackResult.x; // Will override dynamic result if any + gesResult->y = trackResult.y; // Will override dynamic result if any + } +} + +static void runDynamicGesture(const GestureConfig *cfg, int pixels[], DynamicGestureResult *gesResult) +{ + memset(gesResult, 0, sizeof(DynamicGestureResult)); + + static GestureState state = STATE_INACTIVE; + GestureEvent gest_event = GEST_NONE; + static uint32_t n_sample = 0, n_frame =0; + + if (reset_flag) { + state = STATE_INACTIVE; + } + + int rawmaxpixel = getMaxPixelValue(pixels, NUM_SENSOR_PIXELS); + + // Static background subtraction + { + static float foreground_pixels[NUM_SENSOR_PIXELS], background_pixels[NUM_SENSOR_PIXELS]; + if (reset_flag) { + for(uint32_t i=0; i<NUM_SENSOR_PIXELS; i++) { + foreground_pixels[i] = pixels[i]; // clear the filter + background_pixels[i] = pixels[i]; // clear the filter + } + } + + float background_alpha = cfg->background_filter_alpha; + + subtractBackground(pixels, foreground_pixels, background_pixels, NUM_SENSOR_PIXELS, cfg->low_pass_filter_alpha, background_alpha); + } + + // Clear the reset flag. All reset activity should be done by now + if (reset_flag) { + reset_flag = FALSE; + } + + // Find post-filter max pixel + int maxpixel=getMaxPixelValue(pixels, NUM_SENSOR_PIXELS); + + float cmx,cmy; + { + #if INTERP_FACTOR == 1 + int *interp_pixels; + interp_pixels = pixels; + #else + static int interp_pixels[NUM_INTERP_PIXELS]; + interpn(pixels, interp_pixels, SENSOR_XRES, SENSOR_YRES, INTERP_FACTOR); + #endif + + // Thresholding + zeroPixelsBelowThreshold(interp_pixels,NUM_INTERP_PIXELS,(int)(maxpixel/cfg->zero_clamp_threshold_factor)); // zero out pixels below some percent of peak + zeroPixelsBelowThreshold(interp_pixels,NUM_INTERP_PIXELS,cfg->zero_clamp_threshold); // and also zero out below fixed threshold + + // Center of mass + int totalmass=0; + if (maxpixel >= cfg->end_detection_threshold) { + calcCenterOfMass(interp_pixels, INTERP_XRES, INTERP_YRES, &cmx, &cmy, &totalmass); // Only calculate COM if there is a pixel above the noise (avoid divide-by-zero) + cmx = cmx/INTERP_FACTOR; + cmy = cmy/INTERP_FACTOR * DY_PIXEL_SCALE; // scale y so it has same unit dimension as x + } + } + + n_frame++; + + gesResult->n_sample = n_sample; + gesResult->maxpixel = maxpixel; //rawmaxpixel; + gesResult->state = maxpixel >= cfg->end_detection_threshold ? GESTURE_IN_PROGRESS : STATE_INACTIVE; + gesResult->x = maxpixel >= cfg->end_detection_threshold ? cmx : -1.00; + gesResult->y = maxpixel >= cfg->end_detection_threshold ? cmy : -1.00; +} + +void noiseWindow3Filter(int pixels[], const float alpha, const uint32_t reset_flag) +{ + static int nwin[3][NUM_SENSOR_PIXELS]; + if (reset_flag) { + for(uint32_t i=0; i<NUM_SENSOR_PIXELS; i++) { + nwin[0][i] = pixels[i]; // clear the filter + nwin[1][i] = pixels[i]; // clear the filter + nwin[2][i] = pixels[i]; // clear the filter + } + } + else { + for (uint32_t i=0; i<NUM_SENSOR_PIXELS; i++) { + nwin[0][i] = nwin[1][i]; + nwin[1][i] = nwin[2][i]; + nwin[2][i] = pixels[i]; + pixels[i] = alpha * nwin[1][i] + (1-alpha)*(nwin[0][i] + nwin[2][i])/2; + } + } +}
diff -r 000000000000 -r c62425b2f286 gesture_common.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gesture_common.h Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,95 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#ifndef GESTURE_COMMON_H_INCLUDED +#define GESTURE_COMMON_H_INCLUDED + +#include "img_utils.h" +#include "gesture_lib.h" + +//#define USE_MBED + +#ifdef USE_MBED + #include "mbed.h" +#else + #include <math.h> + #include <string.h> + #include <stdlib.h> + #define TRUE 1 + #define FALSE 0 +#endif + +// Sensor constants. Declared as constants so arrays can be statically sized +#define SENSOR_XRES 10 +#define SENSOR_YRES 6 +#define NUM_SENSOR_PIXELS (SENSOR_XRES * SENSOR_YRES) + +// Interpolation used in gesture algorithm +#define INTERP_FACTOR 4 +#define INTERP_XRES ((SENSOR_XRES-1)*INTERP_FACTOR+1) +#define INTERP_YRES ((SENSOR_YRES-1)*INTERP_FACTOR+1) +#define NUM_INTERP_PIXELS (INTERP_XRES*INTERP_YRES) + +#define DY_PIXEL_SCALE 1.42857f /*10.0f/7.0f*/ + + +// Error condition constants +static const float MAX_ABS_ACCUM_DX = SENSOR_XRES*2; // Total x motion should not exceed 2x the screen size +static const float MAX_ABS_ACCUM_DY = SENSOR_YRES*2 * DY_PIXEL_SCALE; // Total x motion should not exceed 2x the screen size + +// Structure to store tracking results +typedef struct { + uint32_t state; // 0: inactive; 1: object detected + int maxpixel; // Maximum pixel value for this frame + float x; // Object x-position + float y; // Object y-position +} TrackingResult; + +// Functions in tracking.cpp +void configTracking(const uint32_t _sampleT, const uint32_t _adc_full_scale, const TrackingConfig *cfg); +void runTracking(const TrackingConfig *cfg, int in_pixels[], TrackingResult *gesResult); +void resetTracking(); +void clearTrackingCalibration(); + +// Structure to store dynamic gesture results +typedef struct { + uint32_t state; // 0: inactive; 1: object detected; 2: rotation in progress + uint32_t n_sample; // The current sample number of this gesture + int maxpixel; // Maximum pixel value for this frame + float x; // Object x-position + float y; // Object y-position +} DynamicGestureResult; + +#endif
diff -r 000000000000 -r c62425b2f286 gesture_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gesture_config.h Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + + /* Paramaters for gesture configuration */ + #define FLIP_SENSOR_PIXELS 0 + #define PIXEL_DATA_MODE 0 + #define SAMPLE_PERIOD_MS 19.8F /*Changed from 12.5f for 400um device*/ + #define ADC_FULL_SCALE 16384 /*Changed from 8192 for 400um device*/ + #define BACKGROUND_FILTER_ALPHA 0.05F /*Changed from 0.10f for 400um device*/ + #define LOW_PASS_FILTER_ALPHA 1.0F + #define ZERO_CLAMP_THRESHOLD 10 + #define ZERO_CLAMP_THRESHOLD_FACTOR 6 + #define ENABLE_WINDOW_FILTER 1 + #define WINDOW_FILTER_ALPHA 0.5F + #define START_DETECTION_THRESHOLD 150 /*Changed from 400 for 400um device*/ + #define END_DETECTION_THRESHOLD 50 /*Changed from 250 for 400um device*/ + + + + /* Paramaters for tracking configuration */ + #define ENABLE_AUTO_BIAS_CALIBRATION 1 + #define STATIC_STATE_BIAS_MS 2000 + #define TRACKING_LOW_PASS_FILTER_ALPHA 1.0F + #define TRACKING_ZERO_CLAMP_THRESHOLD 50 + #define TRACKING_ZERO_CLAMP_THRESHOLD_FACTOR 6 + #define TRACKING_START_DETECTION_THRESHOLD 400 + #define TRACKING_END_DETECTION_THRESHOLD 300 + #define STATIC_STATE_BIAS_DELTA_MAX 200 + #define BIAS_FULLSCALE_FACTOR_MAX 2 + #define TRACK_WIDTH 6.0F + #define TRACK_HEIGHT 3.0F + #define ENABLE_GAIN_CORRECTION 1 + #define GAIN_FACTOR_0 0.5; + #define GAIN_FACTOR_1 0.75; + #define GAIN_FACTOR_2 1.0;
diff -r 000000000000 -r c62425b2f286 gesture_init.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gesture_init.c Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#include "gesture_lib.h" +#include "config.h" +#include "gesture_config.h" + +// Initialize configuration structs to default values + +void initTrackingConfigStructToDefaults(TrackingConfig *cfg) +{ + cfg->enable_auto_bias_calibration = ENABLE_AUTO_BIAS_CALIBRATION; + cfg->static_state_bias_ms = STATIC_STATE_BIAS_MS; + cfg->low_pass_filter_alpha = TRACKING_LOW_PASS_FILTER_ALPHA; + cfg->zero_clamp_threshold = TRACKING_ZERO_CLAMP_THRESHOLD; + cfg->zero_clamp_threshold_factor = TRACKING_ZERO_CLAMP_THRESHOLD_FACTOR; + cfg->start_detection_threshold = TRACKING_START_DETECTION_THRESHOLD; + cfg->end_detection_threshold = TRACKING_END_DETECTION_THRESHOLD; + cfg->static_state_bias_delta_max = STATIC_STATE_BIAS_DELTA_MAX; + cfg->bias_fullscale_factor_max = BIAS_FULLSCALE_FACTOR_MAX; + cfg->track_width = TRACK_WIDTH; + cfg->track_height = TRACK_HEIGHT; + cfg->enable_gain_correction = ENABLE_GAIN_CORRECTION; + cfg->gain_factor_0 = GAIN_FACTOR_0; + cfg->gain_factor_1 = GAIN_FACTOR_1; + cfg->gain_factor_2 = GAIN_FACTOR_2; +} + +void initConfigStructToDefaults(GestureConfig *cfg) +{ + cfg->flip_sensor_pixels = FLIP_SENSOR_PIXELS; + cfg->pixel_data_mode = PIXEL_DATA_MODE; + cfg->sample_period_ms = SAMPLE_PERIOD_MS; + cfg->adc_full_scale = ADC_FULL_SCALE; + cfg->background_filter_alpha = BACKGROUND_FILTER_ALPHA; + cfg->low_pass_filter_alpha = LOW_PASS_FILTER_ALPHA; + cfg->zero_clamp_threshold = ZERO_CLAMP_THRESHOLD; + cfg->zero_clamp_threshold_factor = ZERO_CLAMP_THRESHOLD_FACTOR; + cfg->enable_window_filter = ENABLE_WINDOW_FILTER; + cfg->window_filter_alpha = WINDOW_FILTER_ALPHA; + cfg->start_detection_threshold = START_DETECTION_THRESHOLD; + cfg->end_detection_threshold = END_DETECTION_THRESHOLD; + + // Initialize tracking config strucutre + initTrackingConfigStructToDefaults(&cfg->trackingConfig); +}
diff -r 000000000000 -r c62425b2f286 gesture_lib.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gesture_lib.h Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,209 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#ifndef GESTURE_LIB_H_INCLUDED +#define GESTURE_LIB_H_INCLUDED + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* +* Enumerate gesture events here +*/ +typedef enum { + GEST_NONE, + GEST_PLACEHOLDER +} GestureEvent; + +/* +* Structure to store gesture results. +*/ +typedef struct { + GestureEvent gesture; // Gesture event reported for this processed frame + uint32_t state; // 0: inactive; 1: object detected; 2: rotation in progress + uint32_t n_sample; // The current sample number of the gesture in progress + int maxpixel; // Maximum pixel value for this frame + float x; // Object x-position. Only accurate if TRACKING_ENABLE mask is set. + float y; // Object y-position. Only accurate if TRACKING_ENABLE mask is set. + float float_placeholder; + uint32_t int_placeholder; + +} GestureResult; + + +/* +* Structure for configuration parameters that apply to tracking mode, region selection, and linger-to-click. +* An instance of this structure is a member of the GestureConfig stucture. +*/ +typedef struct { + uint32_t enable_auto_bias_calibration; // Enable automatic bias calibration + uint32_t static_state_bias_ms; // How many milliseconds of static condition before performing an automoatic bias calibration + float low_pass_filter_alpha; // Smoothing factor for low pass filter. The lower the value, the more low pass filtering + int zero_clamp_threshold; // Any pixel below this value is clamped to zero. Must be less than detection thresholds + float zero_clamp_threshold_factor; // Any pixel below maxpixel divided by this factor is clamped to zero. This is to reduce optical clutter and background noise + int start_detection_threshold; // Pixel activation (bias corrected) to start gesture tracking + int end_detection_threshold; // Pixel activation (bias corrected) to stop gesture tracking + uint32_t static_state_bias_delta_max; // Max current pixel to reference delta to be considered static state for bias calibration + uint32_t bias_fullscale_factor_max; // Only calibrate if raw pixel range below this factor of ADC FS + float track_width; // Width (in pixels) of sensor array over which to scale tracking cursor (thereby ignoring edge pixels) + float track_height; // Height (in pixels) of sensor array over which to scale tracking cursor (thereby ignoring edge pixels) + uint32_t enable_gain_correction; // Enable pixel gain correction + float gain_factor_0; // Inner gain factor + float gain_factor_1; // Mid gain factor + float gain_factor_2; // Outer gain factor +} TrackingConfig; + +/* +* Struture for gesture configuration parameters +* An instance of this structure can be modified by the application and passed to the configGesture function +*/ +typedef struct { + uint32_t flip_sensor_pixels; // Set true to if device is mounted upside-down + uint32_t pixel_data_mode; // Set to 0 for raw data, 1 for bias-compensated pixels, 2 for background subtracted (gesture) pixels + float sample_period_ms; // Sample period of sensor in milliseconds + uint32_t adc_full_scale; // ADC full scale of sensor for current register configuration + float background_filter_alpha; // Smoothing factor for dynamic background cancellation. Larger value results in more aggressive high pass filtering + float low_pass_filter_alpha; // Smoothing factor for low pass filter. Set to 1 for no filtering + int zero_clamp_threshold; // Any pixel below this value (background corrected) is clamped to zero. Must be less than detection thresholds + float zero_clamp_threshold_factor; // Any pixel below maxpixel/x is clamped to zero. This is to reduce optical clutter and background noise + uint32_t enable_window_filter; + float window_filter_alpha; + int start_detection_threshold; // Pixel activation level (background corrected) to start gesture tracking + int end_detection_threshold; // Pixel threshold (background corrected) to end gesture tracking + TrackingConfig trackingConfig; +} GestureConfig; + + +/** +* This function obtains a copy of the GestureConfig structure. +* Obtain a copy in order to modify parameters and then pass the struct back using configGesture. +* +* Parameters +* cfg: A pointer to a GestureConfig structure +* +* Return Value +* None +*/ +void getGestureConfig(GestureConfig *_cfg); + +/** +* This function obtains a pointer to the GestureConfig structure. +* Obtain a pointer to use the VALUE of specific parameter. Parameters should never be SET directly using the pointer +* to the Config struct. Instead use getGestureConfig() above. +* +* Parameters +* none +* +* Return Value +* cfg: A pointer to the GestureConfig structure contained in the gesture library +*/ + +GestureConfig * getGestureConfigPtr(); + + +/** +* This function initializes the gesture algorithm with the parameters defined in the GestureConfig structure. +* +* Parameters +* cfg: A pointer to the GestureConfig structure. If the pointer is NULL, the algorithm will be configured with default values. +* +* Return Value +* None +*/ +void configGesture(const GestureConfig *cfg); + + +/** +* This function initializes an instance of a GestureConfig structure to the default values. +* After calling this function, the structure instance can then be modified selectively by the application +* and passed into the configGesture function to implement a custom configuration. +* +* Parameters +* cfg: A pointer to the GestureConfig structure +* +* Return Value +* None +*/ +void initConfigStructToDefaults(GestureConfig *cfg); + + +/** +* This function executes the algorithm for a single frame. This function should be called for every sample period of the sensor. +* +* Parameters +* pixels: An integer array of sensor pixel data; length is determined by the sensor resolution defined in gesture_common.h +* gesResult: A pointer to a GestureResult struct instance; this instance will be populated with results by the algorithm. +* +* Return Value +* None +*/ +void runGesture(int pixels[], GestureResult *gesResult); + + +/** +* This function resets the gesture algorithm by resetting the state machine and clearing filters. +* Note that the initialization parameters are not changed +* +* Parameters +* None +* +* Return Value +* None +*/ +void resetGesture(); + + +/** +* This function forces a tracking mode calibration. +* Note that the calibration only applies to tracking mode (region selection and linger to click); it is not used +* for dynamic gesture mode. +* +* Parameters +* None +* +* Return Value +* None +*/ +void forceTrackingCalibration(); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif
diff -r 000000000000 -r c62425b2f286 img_utils.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/img_utils.c Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,155 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#include "img_utils.h" + +int getMaxPixelValue(const int pixels[], const unsigned int num_pixels) +{ + int maxpixel=-99999; + for (unsigned int i = 0; i < num_pixels; i++) { + if (maxpixel < pixels[i]) { + maxpixel = pixels[i]; + } + } + return maxpixel; +} + +int getMinPixelValue(const int pixels[], const unsigned int num_pixels) +{ + int minpixel=99999; + for (unsigned int i = 0; i < num_pixels; i++) { + if (minpixel > pixels[i]) { + minpixel = pixels[i]; + } + } + return minpixel; +} + +// Zero out pixels below threshold value. Returns the number of pixels above the threshold +unsigned int zeroPixelsBelowThreshold(int pixels[], const unsigned int num_pixels, const int threshold) +{ + int pixelsAboveThresholdCount = num_pixels; + for (unsigned int i = 0; i < num_pixels; i++) { + if (pixels[i] < threshold) { + pixels[i] = 0; + pixelsAboveThresholdCount--; + } + } + return pixelsAboveThresholdCount; +} + +// Caller must keep static filtpixels array +void filterLowPassPixels(int pixels[], float filtpixels[], const unsigned int num_pixels, const float alpha) +{ + for (unsigned int i=0; i< num_pixels; i++) { + filtpixels[i] = (1.0 - alpha) * filtpixels[i] + alpha * pixels[i]; + } + for (unsigned int i=0; i< num_pixels; i++) { + pixels[i] = (int)filtpixels[i]; + } +} + +// Implement background subtraction by subtracting long exponential smoothing average from a shorter one +// (or simply the current pixel if alpha_short_avg is set to 1.0) +// alpha_long_avg should be smaller than alpha_short_avg +// Caller must keep static shart_avg_pixels[] and long_avg_pixels[] +// The bigger alpha long is, the more aggressive the high pass filter. +void subtractBackground(int pixels[], float short_avg_pixels[], float long_avg_pixels[], const unsigned int num_pixels, const float alpha_short_avg, const float alpha_long_avg) +{ + for (unsigned int i=0; i< num_pixels; i++) { + long_avg_pixels[i] = (1.0f - alpha_long_avg) * long_avg_pixels[i] + alpha_long_avg * pixels[i]; + } + for (unsigned int i=0; i< num_pixels; i++) { + short_avg_pixels[i] = (1.0f - alpha_short_avg) * short_avg_pixels[i] + alpha_short_avg * pixels[i]; + } + for (unsigned int i=0; i< num_pixels; i++) { + pixels[i] = short_avg_pixels[i] - (int)long_avg_pixels[i]; + } +} + +void calcCenterOfMass(const int pixels[], const unsigned int xres, const unsigned int yres, float *cmx, float *cmy, int *totalmass) +{ + int cmx_numer=0, cmy_numer=0; + for (unsigned int i = 0; i < xres*yres; i++) { + cmx_numer += (i%xres)*pixels[i]; + cmy_numer += (i/xres)*pixels[i]; + *totalmass += pixels[i]; + } + if (*totalmass == 0) { + *totalmass = 1; // avoid NaN + } + *cmx = (float)cmx_numer/(float)(*totalmass); + *cmy = (float)cmy_numer/(float)(*totalmass); +} + +void interpn(const int pixels[], int interp_pixels[], const int w, const int h, const int interpolation_factor) +{ + int w2 = (w - 1) * interpolation_factor + 1; + int h2 = (h - 1) * interpolation_factor + 1; + int A, B, C, x, y; + float x_ratio = 1.0f / (float)interpolation_factor; + float y_ratio = 1.0f / (float)interpolation_factor; + + // First stretch in x-direction, index through each pixel of destination array. Skip rows in destination array + for (int i = 0; i < h; i++) { + for (int j = 0; j < w2; j++) { + x = (int)(x_ratio * j); // x index of original frame + int index = i * w + x; // pixel index of original frame + if (x == w - 1) // last pixel on right edge of original frame + interp_pixels[i * w2 * interpolation_factor + j] = pixels[index]; // skip rows in dest array + else { + A = pixels[index]; + B = pixels[index + 1]; + float x_diff = (x_ratio * j) - x; // For 2x interpolation, will be 0, 1/2, 0, 1/2... + interp_pixels[i * w2 * interpolation_factor + j] = (int)(A + (B - A) * x_diff); // skip rows in dest array + } + } + } + // Then stretch in y-direction, index through each pixel of destination array + for (int i = 0; i < h2; i++) { + for (int j = 0; j < w2; j++) { + y = (int)(y_ratio * i); // y index of original frame + int index = y * w2 * interpolation_factor + j; // pixel index of frame + if (y == h - 1) // pixel on bottom of original frame + interp_pixels[i * w2 + j] = interp_pixels[index]; + else { + A = interp_pixels[index]; + C = interp_pixels[index + w2 * interpolation_factor]; + float y_diff = (y_ratio * i) - y; + interp_pixels[i * w2 + j] = (int)(A + (C - A) * y_diff); + } + } + } +}
diff -r 000000000000 -r c62425b2f286 img_utils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/img_utils.h Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,49 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#ifndef IMG_UTILS_H_INCLUDED +#define IMG_UTILS_H_INCLUDED + +#include <stdint.h> + +int getMaxPixelValue(const int pixels[], const unsigned int num_pixels); +int getMinPixelValue(const int pixels[], const unsigned int num_pixels); +unsigned int zeroPixelsBelowThreshold(int pixels[], const unsigned int num_pixels, const int threshold); +void filterLowPassPixels(int pixels[], float filtpixels[], const unsigned int num_pixels, const float alpha); +void subtractBackground(int pixels[], float short_avg_pixels[], float long_avg_pixels[], const unsigned int num_pixels, const float alpha_short_avg, const float alpha_long_avg); +void calcCenterOfMass(const int pixels[], const unsigned int xres, const unsigned int yres, float *cmx, float *cmy, int *totalmass); +void interpn(const int pixels[], int interp_pixels[], const int w, const int h, const int interpolation_factor); + +#endif
diff -r 000000000000 -r c62425b2f286 interface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/interface.cpp Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#include "interface.h" +#include "USBSerial.h" +#include "controller.h" +#include "config.h" + +// Serial port for full interface with streaming data. Select USB or UART with USE_UART_INTERFACE constant. +// Files that use these objects should declare them as externs. +#if USE_UART_INTERFACE +Serial *serial = new Serial(P3_1,P3_0,UART_BAUD_RATE); +#else +USBSerial *serial = new USBSerial(0x0b6a, 0x4360, 0x0001, false); +#endif + +// UART over daplink, 9600 baud. This can be used for debugging +//Serial daplink(P2_1, P2_0); + +// USBSerial putc and printf are slow. Use writeBlock to stream data over USB +void sendDataStream(uint8_t *str, const unsigned int num_chars) +{ +#if USE_UART_INTERFACE + + for (int i=0; i<num_chars; i++) { + (*serial).putc(str[i]); + } + +#else // This section needs to be #defined because writeBlock does not exist for UART serial object + uint8_t *output_ptr = (uint8_t *)str; // writeBlock requires pointer to uint8_t + unsigned int bytes_remaining = num_chars; + + while (bytes_remaining > 0) { + if (bytes_remaining < USB_BLOCK_SIZE) { + (*serial).writeBlock(output_ptr, bytes_remaining); + bytes_remaining = 0; + } + else { + (*serial).writeBlock(output_ptr, USB_BLOCK_SIZE); + bytes_remaining -= USB_BLOCK_SIZE; + output_ptr += USB_BLOCK_SIZE; + } + } +#endif +}
diff -r 000000000000 -r c62425b2f286 interface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/interface.h Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,54 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#ifndef INTERFACE_H_INCLUDED +#define INTERFACE_H_INCLUDED + +#include "mbed.h" +#include "gesture_lib.h" + +// Option to implement serial API over UART instead of USB +#define USE_UART_INTERFACE 1 +#define UART_BAUD_RATE 115200 + +// Bytes prefixed to pixel data to create data frame +const int NUM_INFO_BYTES = 40; + +const unsigned int USB_BLOCK_SIZE = 64; + +// Data streaming over USB or UART, depending on which is enabled +void sendDataStream(uint8_t *str, const unsigned int num_chars); + +#endif
diff -r 000000000000 -r c62425b2f286 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,256 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#include "mbed.h" +#include "USBSerial.h" + +#include "config.h" +#include "gesture_lib.h" +#include "interface.h" +#include "controller.h" +#include "cmd.h" + +#if defined(COMPILE_FOR_MAX32630) + #include "max32630fthr.h" + MAX32630FTHR fthr(MAX32630FTHR::VIO_3V3); +#elif defined(COMPILE_FOR_MAX32620) + #include "MAX32620FTHR.h" + MAX32620FTHR fthr(MAX32620FTHR::VIO_3V3); +#endif + +const char *version_string = "gesture firmware framework version 1.0"; + +// MCU board status LEDs +DigitalOut rLED(LED1); +DigitalOut gLED(LED2); + +// Device pins +DigitalOut csb(P5_5); // sensor 1 +//DigitalOut csb2(P54); // sensor 2 +DigitalOut sel(P3_2); + +InterruptIn intb(P5_3); // sensor 1 +//InterruptIn intb2(P3_3); // sensor 2 + +#if USE_SPI + SPI spi(P5_1, P5_2, P5_0); +#else + I2C i2c(P3_4, P3_5); +#endif + +uint32_t i2c_addr_select = 0; + +uint32_t serial_mode = SPI_MODE; + +static uint32_t read_sensor_frames_enabled = 0; +static uint32_t data_stream_enabled = 0; + +static uint32_t send_pixel_data_with_stream = 1; + +// Data ready flags +static uint32_t sensorDataReadyFlag = 0; // Data ready flag, set by the end-of-conversion interrupt + +// Declare functions called in main +static void processFrame(int pixels[]); +void set_default_register_settings(); + +int main() +{ + static int pixels[NUM_SENSOR_PIXELS]; + gLED = LED_OFF; + rLED = LED_ON; + + #if USE_SPI + spi.frequency(6e6); + serial_mode = SPI_MODE; + spi_init(); + #else + i2c.frequency(400e3); + serial_mode = I2C_MODE; + i2c_init(); + #endif + + // Write register settings to device + set_default_register_settings(); + + // Set FTHR board status LEDs + gLED = LED_ON; + rLED = LED_OFF; + + // Configure gesture library + // Declare a configuration object + GestureConfig gestCfg; + // First get a GestureConfig struct that is populated with default values + initConfigStructToDefaults(&gestCfg); + // Then pass this struct to the configGesture function to initialize the gesture library + configGesture(&gestCfg); + //configGesture(NULL); // If configGesture is called with NULL, then default parameters will be used. + + // Enable reading of sensor frames + enable_read_sensor_frames(); + + while (1) { + // Check if a command was received over the serial interface + checkUserCmd(); + + // If using INTB interrupt, the sensorDataReadyFlag will be set when the end-of-conversion occurs + if (sensorDataReadyFlag) { + getSensorPixels(pixels, getGestureConfigPtr()->flip_sensor_pixels); + processFrame(pixels); + sensorDataReadyFlag = 0; + } + } +} + +/* +* This function calls the gesture library for a single sensor frame +* It builds a data stream frame from the gesture results +* And sends the stream over the serial connection +*/ +GestureResult gesResult; +void processFrame(int pixels[]) +{ + runGesture(pixels, &gesResult); + // For raw pixels, instead uncomment out the following line + //memset(&gesResult, 0, sizeof(GestureResult)); + + if (data_stream_enabled) { + + uint8_t frm_data[NUM_SENSOR_PIXELS*2+NUM_INFO_BYTES]; + + // The frame data is per the serial API used by the gesture EVKit GUI + // SYNC bits are used by receiver to know the start of frame + frm_data[0] = 255; // SYNC + frm_data[1] = 255; // SYNC2 + frm_data[3] = gesResult.state; + frm_data[4] = gesResult.n_sample; + frm_data[6] = (gesResult.maxpixel>>8) & 0xFF; // maxpixel high byte + frm_data[7] = gesResult.maxpixel & 0xFF; // maxpixel low byte + float x = gesResult.x; + memcpy(frm_data+10, &x, 4); + float y = gesResult.y; + memcpy(frm_data+15, &y, 4); + + for (uint32_t i=0; i<NUM_SENSOR_PIXELS; i++) { + frm_data[2*i + NUM_INFO_BYTES] = (pixels[i]>>8) & 0xFF; + frm_data[2*i+1 + NUM_INFO_BYTES] = pixels[i] & 0xFF; + } + + if (send_pixel_data_with_stream) + sendDataStream(frm_data, NUM_SENSOR_PIXELS*2 + NUM_INFO_BYTES); + else + sendDataStream(frm_data, NUM_INFO_BYTES); + } +} + + +void set_default_register_settings() +{ + uint32_t ledDrvLevel = 0x0F; + reg_write(0x01, 0x04); + reg_write(0x02, 0x02); + #if defined(MAX25405_DEVICE) + reg_write(0x03, 0x24); // SDLY=2, TIM=2 + reg_write(0x04, 0x8C); // NRPT=4, NCDS=3 + #elif defined(MAX25205_DEVICE) + reg_write(0x03, 0x04); // SDLY=0, TIM=2 + reg_write(0x04, 0xAC); // NRPT=5, NCDS=3 + ledDrvLevel = 0x0A; + #endif + reg_write(0x05, 0x08); + reg_write(0x06, ledDrvLevel); // LED power + reg_write(0xa5, 0x88); + reg_write(0xa6, 0x88); + reg_write(0xa7, 0x88); + reg_write(0xa8, 0x88); + reg_write(0xa9, 0x88); + reg_write(0xc1, 0x0A); // PWM LED driver +} + +/* +* This is the interrupt handler to handle end-of-conversion interrupts on the INTB pin +*/ +void intb_handler() +{ + sensorDataReadyFlag = 1; +} + +/* +* This function starts the monitoring of the INTB interrupt +*/ +void enable_read_sensor_frames() +{ + resetGesture(); + + intb.fall(&intb_handler); // Add INTB interrupt handler + + // Read status reg to clear interrupt + uint8_t status_reg; + reg_read(0x00, 1, &status_reg); + + // Turn off the status LEDs on the MCU board + gLED = LED_OFF; + rLED = LED_OFF; + read_sensor_frames_enabled = 1; +} + +/* +* This function stops the monitoring of the INTB interrupt or polling +*/ +void disable_read_sensor_frames() +{ + intb.fall(0); // Remove interrupt handler + + // Turn on the status LEDs on the MCU board + gLED = LED_ON; + rLED = LED_OFF; + read_sensor_frames_enabled = 0; +} + +/* +* These functions set the data reporting mode and starts sending of data +*/ +void set_stream_on(uint32_t send_pixel_data) +{ + send_pixel_data_with_stream = send_pixel_data; + data_stream_enabled = 1; + if (read_sensor_frames_enabled == 0) + enable_read_sensor_frames(); // make sure +} + +void set_stream_off() +{ + data_stream_enabled = 0; +}
diff -r 000000000000 -r c62425b2f286 mbed-os.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#0fdfcf7350896a9c0b57c4a18237677abfe25f1a
diff -r 000000000000 -r c62425b2f286 readme.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/readme.txt Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,61 @@ + +# Application files: + +main.cpp: Top level source file +controller.cpp / controller.h: These files handle low level communication to the sensor device +cmd.cpp / cmd.h: These files are for the command-line interface over the USB serial +interface.cpp / interface.h: These files handle communications over the serial connection + +# Gesture Library Files: + +gesture_lib.h: defines the Gesture Library API + +Other gesture library source files: + gesture.cpp + gesture_init.cpp + gesture_config.h + gesture_common.h + img_utils.cpp / img_utils.h + +# Setup with mbed CLI + +This project was compiled under mbed CLI. + +*Installing mbed CLI* +Follow the mbed CLI installation instructions on the mbed site: +https://os.mbed.com/docs/mbed-os/v6.6/quick-start/build-with-mbed-cli.html + +*Initialize a new mbed project* +Add the mbed-os library to the directory containing the source files with the following command (note the period): + mbed new . +Use the "--scm none" option to prevent revision control initialization + +*Add required libraries* +Add libraries to support the MAX32630FTHR or MAX32620FTHR development. In the same directory, type: + mbed add https://os.mbed.com/teams/MaximIntegrated/code/max32630fthr/ +or + mbed add https://os.mbed.com/teams/MaximIntegrated/code/MAX32620FTHR/ + +And library to support the USB serial interface. In same directory type: + mbed add https://os.mbed.com/teams/MaximIntegrated/code/USBDevice/ + + +# Configuration + +Stack size needs to be increased from the default of 4k. +The stack size is defined by an mbed_app.json file in the root directory of your project. + +mbed_app.json should contain: + +{ + "config": { + "main-stack-size": { + "value": 65536 + } + } +} + +# Compiling + mbed compile -t GCC_ARM -m MAX32630FTHR +or + mbed compile -t GCC_ARM -m MAX32620FTHR
diff -r 000000000000 -r c62425b2f286 tracking.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tracking.c Sun Oct 16 15:35:01 2022 +0000 @@ -0,0 +1,258 @@ +/******************************************************************************* +* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. +* +* This software is protected by copyright laws of the United States and +* of foreign countries. This material may also be protected by patent laws +* and technology transfer regulations of the United States and of foreign +* countries. This software is furnished under a license agreement and/or a +* nondisclosure agreement and may only be used or reproduced in accordance +* with the terms of those agreements. Dissemination of this information to +* any party or parties not specified in the license agreement and/or +* nondisclosure agreement is expressly prohibited. +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ + +#include "gesture_common.h" + +static uint32_t reset_flag = TRUE; +static uint32_t reset_bias_flag = TRUE; + +// Calculated from parameters +static uint32_t sampleT; +static uint32_t adc_full_scale; +static uint32_t static_state_bias_n; + +static uint32_t force_calibration_flag = FALSE; + +typedef enum { INACTIVE_STATE, TRACKING_STATE } TrackingState; + +void configTracking(const uint32_t _sampleT, const uint32_t _adc_full_scale, const TrackingConfig *cfg) +{ + sampleT = _sampleT; + adc_full_scale = _adc_full_scale; + static_state_bias_n = cfg->static_state_bias_ms/sampleT; + resetTracking(); + + // Reset calibration only if sample period or full-scale changed, so calibration is not cleared. + static uint32_t last_sampleT = 0; + static uint32_t last_adc_full_scale = 0; + if ((sampleT != last_sampleT) || (adc_full_scale != last_adc_full_scale)) { + clearTrackingCalibration(); + } + last_sampleT = sampleT; + last_adc_full_scale = adc_full_scale; +} + +// Force a single bias configuration +void forceTrackingCalibration() +{ + force_calibration_flag = TRUE; +} + +void clearTrackingCalibration() +{ + reset_bias_flag = TRUE; +} + +// Reset the state machine and clear the filter +void resetTracking() +{ + reset_flag = TRUE; +} + +void runTracking(const TrackingConfig *cfg, int pixels[], TrackingResult *gesResult) +{ + static TrackingState state = INACTIVE_STATE; + static uint32_t calibration_done = FALSE; + static uint32_t static_state_bias_count = 0; + + static uint32_t reset_filter_flag = TRUE; + static uint32_t reset_linger_flag = TRUE; + + memset(gesResult, 0, sizeof(TrackingResult)); + + // A reset will reset the calibration, so filters and static state counters must also be reset once a calibration is performed + if (reset_flag) { + state = INACTIVE_STATE; + static_state_bias_count = 0; // Reset the bias calibration counter but don't clear the bias cal. + reset_filter_flag = TRUE; + reset_flag = FALSE; + } + + // ----------------------------------------- + // Bias Compenstation + // ----------------------------------------- + { + static int biaspixels[NUM_SENSOR_PIXELS]; + static float refpixels[NUM_SENSOR_PIXELS]; + + int max_raw_pixel=getMaxPixelValue(pixels, NUM_SENSOR_PIXELS); + int min_raw_pixel=getMinPixelValue(pixels, NUM_SENSOR_PIXELS); + + if (reset_bias_flag) { + for(uint32_t i=0; i<NUM_SENSOR_PIXELS; i++) { + biaspixels[i] = 0; // clear the bias compensation + refpixels[i] = pixels[i]; // reset reference pixels + } + static_state_bias_count = 0; + reset_bias_flag = FALSE; + calibration_done = FALSE; + } + + if (cfg->enable_auto_bias_calibration) { + // Compare current pixel to reference + int maxdelta = -99999; + for (uint32_t i = 0; i < NUM_SENSOR_PIXELS; i++) { + int delta = abs(pixels[i] - refpixels[i]); + if (maxdelta < delta) { + maxdelta = delta; + } + } + // Check for static condition + if (maxdelta < (int)cfg->static_state_bias_delta_max + && max_raw_pixel-min_raw_pixel < (int)adc_full_scale/(int)cfg->bias_fullscale_factor_max + && state != TRACKING_STATE) + { + static_state_bias_count++; + } + else { + // Sensor not static, reset the counter and set new reference + static_state_bias_count = 0; + for(uint32_t i=0; i<NUM_SENSOR_PIXELS; i++) { + refpixels[i] = pixels[i]; + } + } + // If static condition, recalculate bias compenstation + if (static_state_bias_count > static_state_bias_n) { + for (uint32_t i = 0; i < NUM_SENSOR_PIXELS; i++) { + biaspixels[i] = refpixels[i]; + } + static_state_bias_count = 0; + calibration_done = TRUE; + } + } + // If force_calibration_flag is set, set bias to current pixel values + if (force_calibration_flag) { + for (uint32_t i = 0; i < NUM_SENSOR_PIXELS; i++) { + biaspixels[i] = pixels[i]; + } + calibration_done = TRUE; + force_calibration_flag = FALSE; + } + // Apply bias compensation + for (uint32_t i = 0; i < NUM_SENSOR_PIXELS; i++) { + pixels[i] -= biaspixels[i]; + } + } + + // ----------------------------------------- + // Low pass filter + // ----------------------------------------- + if (calibration_done) { + static float filtpixels[NUM_SENSOR_PIXELS]; + if (reset_filter_flag) { + for(uint32_t i=0; i<NUM_SENSOR_PIXELS; i++) + { + filtpixels[i] = pixels[i]; // Clear the filter + } + reset_filter_flag = FALSE; + } + filterLowPassPixels(pixels, filtpixels, NUM_SENSOR_PIXELS, cfg->low_pass_filter_alpha); + } + + // ----------------------------------------- + // Software gain + // ----------------------------------------- + { + double gain_factor = 0.0f; + for (uint32_t i = 0; i < NUM_SENSOR_PIXELS; i++) { + if (i%SENSOR_XRES == 0 || i%SENSOR_XRES == 9 || i%SENSOR_XRES == 1 || i%SENSOR_XRES == 8 || i/SENSOR_XRES == 0 || i/SENSOR_XRES == 5) + gain_factor = cfg->gain_factor_2; + else if (i%SENSOR_XRES == 2 || i%SENSOR_XRES == 7 || i/SENSOR_XRES == 1 || i/SENSOR_XRES == 4) + gain_factor = cfg->gain_factor_1; + else if (i%SENSOR_XRES == 3 || i%SENSOR_XRES == 6 || i%SENSOR_XRES == 4 || i%SENSOR_XRES == 5) + gain_factor = cfg->gain_factor_0; + + pixels[i] *= gain_factor; + } + } + + // ----------------------------------------- + // Determine tracking state + // ----------------------------------------- + + // Get max/min pixel after applying bias compensation and filtering + int maxpixel=getMaxPixelValue(pixels, NUM_SENSOR_PIXELS); + + // Determine state + if (calibration_done + && ((state == INACTIVE_STATE + && maxpixel > cfg->start_detection_threshold) || (state == TRACKING_STATE + && maxpixel > cfg->end_detection_threshold))) + { + state = TRACKING_STATE; + } + else { + state = INACTIVE_STATE; + } + + // ----------------------------------------- + // Object position + // ----------------------------------------- + float x_scaled = -1.0, y_scaled = -1.0; + if (state == TRACKING_STATE) { + #if INTERP_FACTOR == 1 + int *interp_pixels; + interp_pixels = pixels; + #else + int interp_pixels[NUM_INTERP_PIXELS]; + interpn(pixels, interp_pixels, SENSOR_XRES, SENSOR_YRES, INTERP_FACTOR); + #endif + + // Zero out low pixels to reduce artifacts and noise + zeroPixelsBelowThreshold(interp_pixels,NUM_INTERP_PIXELS,(int)(maxpixel/cfg->zero_clamp_threshold_factor)); // zero out pixels below some percent of peak + zeroPixelsBelowThreshold(interp_pixels,NUM_INTERP_PIXELS,cfg->zero_clamp_threshold); + + // Find center of mass. + float cmx,cmy; + if (maxpixel > 0) { + int totalmass=0; + calcCenterOfMass(interp_pixels, INTERP_XRES, INTERP_YRES, &cmx, &cmy, &totalmass); // only calculate COM if there is a pixel above the noise (avoid divide-by-zero) + cmx = cmx/(float)INTERP_FACTOR; + cmy = cmy/(float)INTERP_FACTOR; + } + + // Scale position according to tracking width/height parameter. This scales to values (0,9) in x, (0,5) in y + x_scaled = (cmx - ((float)SENSOR_XRES - cfg->track_width)/2.0f) * (SENSOR_XRES-1)/(cfg->track_width-1); + x_scaled = x_scaled >= (SENSOR_XRES-1) ? SENSOR_XRES - 1.001 : x_scaled < 0.0f ? 0.0f : x_scaled; + y_scaled = (cmy - ((float)SENSOR_YRES - cfg->track_height)/2.0f) * (SENSOR_YRES-1)/(cfg->track_height-1); + y_scaled = y_scaled >= (SENSOR_YRES-1) ? SENSOR_YRES - 1.001 : y_scaled < 0.0f ? 0.0f : y_scaled; + } + + // Update gesture result struct + gesResult->state = state == TRACKING_STATE ? 1 : 0; + gesResult->x = state == TRACKING_STATE ? x_scaled : -1.00f; + gesResult->y = state == TRACKING_STATE ? y_scaled : -1.00f; + gesResult->maxpixel = maxpixel; +}