/* ----------------------------------------------------------------------------*
 *
 *  Function Name : setMode(uint8_t mode, uint8_t enable)
 *
 *  Description  :Reads and returns the contents of the ENABLE register
 *
 *  Input : mode which feature to enable,enable ON (1) or OFF (0)
 *
 *  Output : None
 *
 *  Return : Contents of the ENABLE register. 0xFF if error.
 * ----------------------------------------------------------------------------*
 * Authors: Sarath S
 * Date: May 17, 2017
 * ---------------------------------------------------------------------------*/
uint8_t getMode(void)
{
  uint8_t enable_value;
    
    /* Read current ENABLE register */
    if( !i2c1_read(APDS9960_ENABLE,&enable_value,1) ) 
    {
        return ERROR;
    }
    
    return enable_value;
}/* End of this function */
예제 #2
0
void task_telemetry(void){
    OS_Stop();
   user_debug_msg(STR_TELEMETRY_QA  "Starting.");
   
   #if 1
  OS_Delay(250);
    // structure that will contain the results
    typedef struct{
        uint64_t passed;    
        uint64_t failed;
        uint16_t test_num;      // Last test number 
        uint16_t failed_num;        
        uint16_t failed_res; // Non-zero when/if test fails
    }selftest_res_t;

    selftest_res_t test;

    //unsigned char TestData[sizeof(selftest_res)+13];
    
    supmcu_selftest_start(TRUE);
    OS_Delay(250); 
    
    supmcu_selftest_tel(TRUE);
    
    i2c1_read(I2C_ADDR.g, &TEL_DATA[0], sizeof(test)+13);
    memcpy(&test.passed, &TEL_DATA[5],sizeof(uint64_t));
    memcpy(&test.failed, &TEL_DATA[5+8],sizeof(uint64_t));
    memcpy(&test.test_num, &TEL_DATA[5+8+8],sizeof(uint16_t));
    memcpy(&test.failed_num, &TEL_DATA[5+8+8+2],sizeof(uint16_t));
    memcpy(&test.failed_res, &TEL_DATA[5+8+8+2+2],sizeof(uint16_t));   
    //sprintf(strTmp,"pass %llu ; fail %llu; num %u; num_fail %u; res_fail %u",test.passed,test.failed, test.test_num, test.failed_num,test.failed_res);
    //user_debug_msg(strTmp);
    
    if(test.failed == 0){
        sprintf(strTmp,"All selftests passed");
        user_debug_msg(STR_TELEMETRY_QA "All selftests passed");
    }
    else{
        sprintf(strTmp,STR_TELEMETRY_QA "Failed %llu tests, last failed %u",test.failed,test.failed_num);
        user_debug_msg(strTmp);
    }
 
 while(1) { 
    OS_Delay(250);
 }
#endif
    
}
예제 #3
0
파일: cs8556.c 프로젝트: josh64x2/apc-rock
// return: the read data
int cs8556_i2c_read(int addr)
{

#ifdef CONFIG_KERNEL
//  return i2c_api_register_read(CS8556_ADDR, 2, addr);
    char buf = 0;
    
    vpp_i2c_read(CS8556_ID, CS8556_ADDR, addr, &buf, 1);
    return buf;
#else
  uchar data = 0;
  i2c1_read(CS8556_ADDR, addr, 2, &data, 1);
  return data;
#endif

}
/* ----------------------------------------------------------------------------*
 *
 *  Function Name : isGestureAvailable(void)
 *
 *  Description  :Determines if there is a gesture available for reading
 *
 *  Input : None
 *
 *  Output : None
 *
 *  Return : True if gesture available. False otherwise.
 * ----------------------------------------------------------------------------*
 * Authors: Sarath S
 * Date: May 17, 2017
 * ---------------------------------------------------------------------------*/
int isGestureAvailable(void)
{
    uint8_t val;
    /* Read value from GSTATUS register */
    if( !i2c1_read(APDS9960_GSTATUS, &val,1) ) {
        return ERROR;
    }
    
    /* Shift and mask out GVALID bit */
    val &= APDS9960_GVALID;
    
    /* Return true/false based on GVALID bit */
    if( val == 1) {
        return true;
    } else {
        return false;
    }
}/* End of this function */
/* ----------------------------------------------------------------------------*
 *
 *  Function Name : setGestureMode(uint8_t mode)
 *
 *  Description  :Tells the state machine to either enter or exit gesture state machine
 *
 *  Input : mode 1 to enter gesture state machine, 0 to exit.
 *
 *  Output : None
 *
 *  Return : True if operation successful. False otherwise.
 * ----------------------------------------------------------------------------*
 * Authors: Sarath S
 * Date: May 17, 2017
 * ---------------------------------------------------------------------------*/
int setGestureMode(uint8_t mode)
{
    uint8_t val;
    
    /* Read value from GCONF4 register */
    if( !i2c1_read(APDS9960_GCONF4, &val,1) ) {
        return false;
    }
    
    /* Set bits in register to given value */
    mode &= 0x01;
    val &= 0xFE;
    val |= mode;
    
    /* Write register value back into GCONF4 register */
    if( !i2c1_write(APDS9960_GCONF4, val) ) {
        return false;
    }
    
    return true;
}/* End of this function */
/* ----------------------------------------------------------------------------*
 *
 *  Function Name : setGestureWaitTime(uint8_t time)
 *
 *  Description  :Sets the time in low power mode between gesture detections
 *  Value    Wait time
 *   0          0 ms
 *   1          2.8 ms
 *   2          5.6 ms
 *   3          8.4 ms
 *   4         14.0 ms
 *   5         22.4 ms
 *   6         30.8 ms
 *   7         39.2 ms
 *  Input : the value for the wait time
 *
 *  Output : None
 *
 *  Return : True if operation successful. False otherwise.
 * ----------------------------------------------------------------------------*
 * Authors: Sarath S
 * Date: May 17, 2017
 * ---------------------------------------------------------------------------*/
int setGestureWaitTime(uint8_t time)
{
    uint8_t val;
    
    /* Read value from GCONF2 register */
    if( !i2c1_read(APDS9960_GCONF2, &val,1) ) {
        return false;
    }
    
    /* Set bits in register to given value */
    time &= 0x07;
    val &= 0xF8;
    val |= time;
    
    /* Write register value back into GCONF2 register */
    if( !i2c1_write(APDS9960_GCONF2, val) ) {
        return false;
    }
    
    return true;
}/* End of this function */
/* ----------------------------------------------------------------------------*
 *
 *  Function Name : setAmbientLightGain(uint8_t drive)
 *
 *  Description  :Sets the receiver gain for the ambient light sensor (ALS)
 *  Value    Gain
 *   0        1x
 *   1        4x
 *   2       16x
 *   3       64x
 *  Input : drive the value (0-3) for the gain
 *
 *  Output : None
 *
 *  Return : True if operation successful. False otherwise.
 * ----------------------------------------------------------------------------*
 * Authors: Sarath S
 * Date: May 17, 2017
 * ---------------------------------------------------------------------------*/
int setAmbientLightGain(uint8_t drive)
{
    uint8_t val;
    
    /* Read value from CONTROL register */
    if( !i2c1_read(APDS9960_CONTROL, &val,1) ) {
        return false;
    }
    
    /* Set bits in register to given value */
    drive &= 0x03;
    val &= 0xFC;
    val |= drive;
    
    /* Write register value back into CONTROL register */
    if( !i2c1_write(APDS9960_CONTROL, val) ) {
        return false;
    }
    
    return true;
}/* End of this function */
/* ----------------------------------------------------------------------------*
 *
 *  Function Name : setLEDBoost(uint8_t boost)
 *
 *  Description  :Sets the LED current boost value
 * Value  Boost Current
 *   0        100%
 *   1        150%
 *   2        200%
 *   3        300%
 *  Input : drive the value (0-3) for current boost (100-300%)
 *
 *  Output : None
 *
 *  Return : True if operation successful. False otherwise.
 * ----------------------------------------------------------------------------*
 * Authors: Sarath S
 * Date: May 17, 2017
 * ---------------------------------------------------------------------------*/
int setLEDBoost(uint8_t boost)
{
    uint8_t val;
    
    /* Read value from CONFIG2 register */
    if( !i2c1_read(APDS9960_CONFIG2, &val,1) ) {
        return false;
    }
    
    /* Set bits in register to given value */
    boost &= 0x03;
    boost = boost << 4;
    val &= 0xCF;
    val |= boost;
    
    /* Write register value back into CONFIG2 register */
    if( !i2c1_write(APDS9960_CONFIG2, val) ) {
        return false;
    }
    
    return true;
}/* End of this function */    
/* ----------------------------------------------------------------------------*
 *
 *  Function Name : setGestureGain(uint8_t gain)
 *
 *  Description  :Sets the gain of the photodiode during gesture mode
 * Value    Gain
 *   0       1x
 *   1       2x
 *   2       4x
 *   3       8x
 *  Input : gain the value for the photodiode gain
 *
 *  Output : None
 *
 *  Return : True if operation successful. False otherwise.
 * ----------------------------------------------------------------------------*
 * Authors: Sarath S
 * Date: May 17, 2017
 * ---------------------------------------------------------------------------*/
int setGestureGain(uint8_t gain)
{
    uint8_t val;
    
    /* Read value from GCONF2 register */
    if( !i2c1_read(APDS9960_GCONF2, &val,1) ) {
        return false;
    }
    
    /* Set bits in register to given value */
    gain &= 0x03;
    gain = gain << 5;
    val &= 0x9F;
    val |= gain;
    
    /* Write register value back into GCONF2 register */
    if( !i2c1_write(APDS9960_GCONF2, val) ) {
        return false;
    }
    
    return true;
}/* End of this function */
/* ----------------------------------------------------------------------------*
 *
 *  Function Name : setGestureLEDDrive(uint8_t drive)
 *
 *  Description  :Sets the LED drive current during gesture mode
 * Value    LED Current
 *   0        100 mA
 *   1         50 mA
 *   2         25 mA
 *   3         12.5 mA
 *
 *  Input : drive the value for the LED drive current
 *
 *  Output : None
 *
 *  Return : True if operation successful. False otherwise.
 * ----------------------------------------------------------------------------*
 * Authors: Sarath S
 * Date: May 17, 2017
 * ---------------------------------------------------------------------------*/
int setGestureLEDDrive(uint8_t drive)
{
    uint8_t val;
    
    /* Read value from GCONF2 register */
    if( !i2c1_read(APDS9960_GCONF2, &val,1) ) {
        return false;
    }
    
    /* Set bits in register to given value */
    drive &= 0x03;
    drive = drive << 3;
    val &= 0xE7;
    val |= drive;
    
    /* Write register value back into GCONF2 register */
    if( !i2c1_write(APDS9960_GCONF2, val) ) {
        return false;
    }
    
    return true;
}/* End of this function */
/* ----------------------------------------------------------------------------*
 *
 *  Function Name : setGestureIntEnable(uint8_t enable)
 *
 *  Description  :Turns gesture-related interrupts on or off
 *
 *  Input : enable 1 to enable interrupts, 0 to turn them off
 *
 *  Output : None
 *
 *  Return : True if operation successful. False otherwise.
 * ----------------------------------------------------------------------------*
 * Authors: Sarath S
 * Date: May 17, 2017
 * ---------------------------------------------------------------------------*/
int setGestureIntEnable(uint8_t enable)
{
    uint8_t val;
    
    /* Read value from GCONF4 register */
    if( !i2c1_read(APDS9960_GCONF4, &val,1) ) {
        return false;
    }
    
    /* Set bits in register to given value */
    enable &= 0x01;
    enable = enable << 1;
    val &= 0xFD;
    val |= enable;
    
    /* Write register value back into GCONF4 register */
    if( !i2c1_write(APDS9960_GCONF4, val) ) {
        return false;
    }
    
    return true;
}/* End of this function */
/* ----------------------------------------------------------------------------*
 *
 *  Function Name : readGesture(void)
 *
 *  Description  :Processes a gesture event and returns best guessed gesture
 *
 *  Input : None
 *
 *  Output : None
 *
 *  Return : Number corresponding to gesture. -1 on error.
 * ----------------------------------------------------------------------------*
 * Authors: Sarath S
 * Date: May 17, 2017
 * ---------------------------------------------------------------------------*/
int readGesture(void)
{
    uint8_t fifo_level = 0;
    int bytes_read = 0;
    uint8_t fifo_data[128];
    uint8_t gstatus;
    int motion;
    int i;
    
    /* Make sure that power and gesture is on and data is valid */
    if( !isGestureAvailable() || !(getMode() & 0x41) ) {
        return DIR_NONE;
    }
    
    /* Keep looping as long as gesture data is valid */
    while(1) {
    
        /* Wait some time to collect next batch of FIFO data */
        delayms(FIFO_PAUSE_TIME);
        
        /* Get the contents of the STATUS register. Is data still valid? */
        if( !i2c1_read(APDS9960_GSTATUS, &gstatus,1) ) {
            return ERROR;
        }
        
        /* If we have valid data, read in FIFO */
        if( (gstatus & APDS9960_GVALID) == APDS9960_GVALID ) {
        
            /* Read the current FIFO level */
            if( !i2c1_read(APDS9960_GFLVL, &fifo_level,1) ) {
                return ERROR;
            }

#if DEBUGPRINT
            debugPutString("FIFO Level: ");
            debugPutChar(fifo_level);
#endif

            /* If there's stuff in the FIFO, read it into our data block */
            if( fifo_level > 0) {
                bytes_read = i2c1_read(APDS9960_GFIFO_U, 
                                                fifo_data, 
                                                (fifo_level * 4) );
                if( bytes_read == -1 ) {
                    return ERROR;
                }
#if DEBUGPRINT
                debugPutString("FIFO Dump: ");
                for ( i = 0; i < bytes_read; i++ ) {
                    debugPutChar(fifo_data[i]);
                    debugPutString(" ");
                }
                debugPutString("\r\n");
#endif

                /* If at least 1 set of data, sort the data into U/D/L/R */
                if( bytes_read >= 4 ) {
                    for( i = 0; i < bytes_read; i += 4 ) {
                        gesture_data_.u_data[gesture_data_.index] = \
                                                            fifo_data[i + 0];
                        gesture_data_.d_data[gesture_data_.index] = \
                                                            fifo_data[i + 1];
                        gesture_data_.l_data[gesture_data_.index] = \
                                                            fifo_data[i + 2];
                        gesture_data_.r_data[gesture_data_.index] = \
                                                            fifo_data[i + 3];
                        gesture_data_.index++;
                        gesture_data_.total_gestures++;
                    }
                    
#if DEBUGPRINT
                debugPutString("Up Data: ");
                for ( i = 0; i < gesture_data_.total_gestures; i++ ) {
                    debugPutChar(gesture_data_.u_data[i]);
                    debugPutString(" ");
                }
                debugPutString("\r\n");
#endif

                    /* Filter and process gesture data. Decode near/far state */
                    if( processGestureData() ) {
                        if( decodeGesture() ) {
                            //***TODO: U-Turn Gestures
#if DEBUGPRINT
                           debugPutChar(gesture_motion_);
#endif
                        }
                    }
                    
                    /* Reset data */
                    gesture_data_.index = 0;
                    gesture_data_.total_gestures = 0;
                }
            }
        } else {
    
            /* Determine best guessed gesture and clean up */
            delayms(FIFO_PAUSE_TIME);
            decodeGesture();
            motion = gesture_motion_;
#if DEBUGPRINT
            debugPutString("END: ");
            debugPutChar(gesture_motion_);
#endif
            resetGestureParameters();
            return motion;
        }
    }
}
/* ----------------------------------------------------------------------------*
 *
 *  Function Name : apds9960init
 *
 *  Description  : Configures I2C communications and initializes registers to defaults
 *
 *  Input : None
 *
 *  Output : None
 *
 *  Return : True if initialized successfully. False otherwise
 * ----------------------------------------------------------------------------*
 * Authors: Sarath S
 * Date: May 17, 2017
 * ---------------------------------------------------------------------------*/
int apds9960init(void)
{
    uint8_t id;
    //ledSetLeftLed(LED_ON);  

    /* Initialize I2C */
    I2C1_init();
    delayms(700);
    /* Read ID register and check against known values for APDS-9960 */
    if( !i2c1_read(APDS9960_ID, &id,1) ) {
       ledSetRightLed(LED_ON);  
      return false;
        
    }
    ledSetLeftLed(LED_ON);  
    if( !(id == APDS9960_ID_1 || id == APDS9960_ID_2) ) {
        return false;
    }
     
    /* Set ENABLE register to 0 (disable all features) */
    if( !setMode(ALL, OFF) ) {
        return false;
    }
    
    /* Set default values for ambient light and proximity registers */
    if( !i2c1_write(APDS9960_ATIME, DEFAULT_ATIME) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_WTIME, DEFAULT_WTIME) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_PPULSE, DEFAULT_PROX_PPULSE) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_POFFSET_UR, DEFAULT_POFFSET_UR) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_POFFSET_DL, DEFAULT_POFFSET_DL) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_CONFIG1, DEFAULT_CONFIG1) ) {
        return false;
    }
    if( !setLEDDrive(DEFAULT_LDRIVE) ) {
        return false;
    }
    if( !setProximityGain(DEFAULT_PGAIN) ) {
        return false;
    }
    if( !setAmbientLightGain(DEFAULT_AGAIN) ) {
        return false;
    }
    if( !setProxIntLowThresh(DEFAULT_PILT) ) {
        return false;
    }
    if( !setProxIntHighThresh(DEFAULT_PIHT) ) {
        return false;
    }
    if( !setLightIntLowThreshold(DEFAULT_AILT) ) {
        return false;
    }
    if( !setLightIntHighThreshold(DEFAULT_AIHT) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_PERS, DEFAULT_PERS) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_CONFIG2, DEFAULT_CONFIG2) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_CONFIG3, DEFAULT_CONFIG3) ) {
        return false;
    }
    
    /* Set default values for gesture sense registers */
    if( !setGestureEnterThresh(DEFAULT_GPENTH) ) {
        return false;
    }
    if( !setGestureExitThresh(DEFAULT_GEXTH) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_GCONF1, DEFAULT_GCONF1) ) {
        return false;
    }
    if( !setGestureGain(DEFAULT_GGAIN) ) {
        return false;
    }
    if( !setGestureLEDDrive(DEFAULT_GLDRIVE) ) {
        return false;
    }
    if( !setGestureWaitTime(DEFAULT_GWTIME) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_GOFFSET_U, DEFAULT_GOFFSET) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_GOFFSET_D, DEFAULT_GOFFSET) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_GOFFSET_L, DEFAULT_GOFFSET) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_GOFFSET_R, DEFAULT_GOFFSET) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_GPULSE, DEFAULT_GPULSE) ) {
        return false;
    }
    if( !i2c1_write(APDS9960_GCONF3, DEFAULT_GCONF3) ) {
        return false;
    }
    if( !setGestureIntEnable(DEFAULT_GIEN) ) {
        return false;
    }
    
#if 0
    /* Gesture config register dump */
    uint8_t reg;
    uint8_t val;
  
    for(reg = 0x80; reg <= 0xAF; reg++) {
        if( (reg != 0x82) && \
            (reg != 0x8A) && \
            (reg != 0x91) && \
            (reg != 0xA8) && \
            (reg != 0xAC) && \
            (reg != 0xAD) )
        {
            i2c1_read(reg, val,1);
            //debugPutChar(reg);
            debugPutString(": 0x");
            //debugPutChar(val);

        }
    }

    for(reg = 0xE4; reg <= 0xE7; reg++) {
        i2c1_read(reg, val,1);
        //debugPutChar(reg);
        debugPutString(": 0x");
        //debugPutChar(val);
    }
#endif

    return true;
}/* End of this function */