Showing posts with label LPSTK-CC1352R. Show all posts
Showing posts with label LPSTK-CC1352R. Show all posts

Thursday, August 10, 2023

LPSTK-CC1352R/HDC2080 measurement

Use the following code relacing mainThread in i2copt3001_cpp.cpp of i2copt3001_cpp example to read LPSTK-CC1352R/HDC2080 temperature/humidity measurement

/*
 *  ======== mainThread ========
 */
uint8_t reg_addr, high_id, low_id, drdy, high_temp, low_temp, high_humi, low_humi;
uint16_t temp16, humi16;
float temperature, humidity;
uint8_t drdy_int_conf[2];

void *mainThread(void *arg0)
{
    uint16_t sample;
    int32_t luxValue;
    uint8_t data;
    uint8_t addr;

    /* I2C structures*/
    I2C_Handle      i2c;
    I2C_Params      i2cParams;
    I2C_Transaction i2cTransaction;

    /* Call driver init functions */
    Display_init();
    GPIO_init();
    I2C_init();

    /* Open the UART display for output */
    display = Display_open(Display_Type_UART, NULL);
    if (display == NULL) {
        while (1);
    }

    /* Create I2C for usage */
    I2C_Params_init(&i2cParams);
    i2cParams.bitRate = I2C_400kHz;
    i2c = I2C_open(CONFIG_I2C_OPT3001, &i2cParams);
    if (i2c == NULL) {
        Display_printf(display, 0, 0, (char *)"Error Initializing I2C!\n");
        while (1);
    }
    else {
        Display_printf(display, 0, 0, (char *)"I2C Initialized!");
    }

    i2cTransaction.targetAddress=0x41; //HDC2080 device address

    /* Read Device ID High byte */
    reg_addr=0xFF;
    i2cTransaction.writeBuf = &reg_addr;
    i2cTransaction.writeCount = 1;
    i2cTransaction.readBuf = &high_id;
    i2cTransaction.readCount = 1;
    if (I2C_transfer(i2c, &i2cTransaction)){
        Display_printf(display, 0, 0,
                        (char *)"I2C device High ID 0x%x!", high_id);
    }

    /* Read Device ID Low byte */
    reg_addr=0xFE;
    i2cTransaction.writeBuf = &reg_addr;
    i2cTransaction.writeCount = 1;
    i2cTransaction.readBuf = &low_id;
    i2cTransaction.readCount = 1;
    if (I2C_transfer(i2c, &i2cTransaction)){
        Display_printf(display, 0, 0,
                        (char *)"I2C device Low ID 0x%x!", low_id);
    }

    while(1)
    {
        //Write drdy_int_conf to 5 samples per second
        drdy_int_conf[0]=0x0F;
        drdy_int_conf[1]=0x01;
        i2cTransaction.writeBuf = drdy_int_conf;
        i2cTransaction.writeCount = 2;
        i2cTransaction.readBuf = &drdy;
        i2cTransaction.readCount = 0;
        if (I2C_transfer(i2c, &i2cTransaction)){
            Display_printf(display, 0, 0,
                            (char *)"Data ready byte? 0x%x", drdy);
        }

        //read if data is ready
        reg_addr=0x04;
        i2cTransaction.writeBuf = &reg_addr;
        i2cTransaction.writeCount = 1;
        i2cTransaction.readBuf = &drdy;
        i2cTransaction.readCount = 1;
        if (I2C_transfer(i2c, &i2cTransaction)){
            Display_printf(display, 0, 0,
                            (char *)"Data ready byte? 0x%x", drdy);
        }

        if(drdy&0x80)
        {
            //Data is ready and start to read temperature and temperature data
            /* Read Temperature Low byte */
            reg_addr=0x00;
            i2cTransaction.writeBuf = &reg_addr;
            i2cTransaction.writeCount = 1;
            i2cTransaction.readBuf = &low_temp;
            i2cTransaction.readCount = 1;
            if (I2C_transfer(i2c, &i2cTransaction)){
                Display_printf(display, 0, 0,
                                (char *)"Temperature Low byte 0x%x!", low_temp);
            }

            /* Read Temperature High byte */
            reg_addr=0x01;
            i2cTransaction.writeBuf = &reg_addr;
            i2cTransaction.writeCount = 1;
            i2cTransaction.readBuf = &high_temp;
            i2cTransaction.readCount = 1;
            if (I2C_transfer(i2c, &i2cTransaction)){
                Display_printf(display, 0, 0,
                                (char *)"Temperature high byte 0x%x!", high_temp);
            }

            temp16=(uint16_t)high_temp;
            temp16=(temp16<<8)|((uint16_t)low_temp);
            temperature = (((float)temp16)/65535)*165-40.5;
            Display_printf(display, 0, 0,(char *)"Temperature: %.1f", temperature);

            /* Read Humidity Low byte */
            reg_addr=0x02;
            i2cTransaction.writeBuf = &reg_addr;
            i2cTransaction.writeCount = 1;
            i2cTransaction.readBuf = &low_humi;
            i2cTransaction.readCount = 1;
            if (I2C_transfer(i2c, &i2cTransaction)){
                Display_printf(display, 0, 0,
                                (char *)"Temperature Low byte 0x%x.1!", low_humi);
            }

            /* Read Humidity High byte */
            reg_addr=0x03;
            i2cTransaction.writeBuf = &reg_addr;
            i2cTransaction.writeCount = 1;
            i2cTransaction.readBuf = &high_humi;
            i2cTransaction.readCount = 1;
            if (I2C_transfer(i2c, &i2cTransaction)){
                Display_printf(display, 0, 0,
                                (char *)"Temperature high byte 0x%x!", high_humi);
            }

            humi16=(uint16_t)high_humi;
            humi16=(humi16<<8)|((uint16_t)low_humi);
            humidity = (((float)humi16)/65535)*100;
            Display_printf(display, 0, 0,(char *)"Humidity: %f", humidity);
        }
    }
    return (NULL);
}
 

Tuesday, September 1, 2020

How to remove OAD feature on CC26x2/CC13x2 project_zero

 The following steps show you how to remove OAD feature on CC26x2/CC13x2 project_zero

 1. Replace C:\ti\simplelink_cc13x2_26x2_sdk_4_10_03_02_eng\examples\rtos\CC26X2R1_LAUNCHXL\ble5stack\project_zero\tirtos\ccs\cc13x2_cc26x2_app.cmd
   with C:\ti\simplelink_cc13x2_26x2_sdk_4_10_03_02_eng\examples\rtos\CC26X2R1_LAUNCHXL\ble5stack\simple_peripheral\tirtos\ccs\cc13x2_cc26x2_app.cmd
   
2. Check "Exclude from build" on project_zero OAD folder in CCS Project Explorer.

3. Remove all OAD_xxx related code from projec_zero.c and _imgHdr

4. Change project_zero_app.cfg

m3Hwi.nvicCCR.UNALIGN_TRP = 0;
//m3Hwi.nvicCCR.UNALIGN_TRP = 1;

/* Put reset vector after OAD metadata */
var compilerOpts = prog.build.target.ccOpts.prefix; // Get the target compiler options
var regex = /(?:\-\-define\=)(\w*)(?:\=*\w*\s)/g;
var compilerDefs = [];
while ((tmp = regex.exec(compilerOpts)) !== null) compilerDefs.push(tmp[1]); // Parse compiler symbols

if (compilerDefs.indexOf('SECURITY') > -1) { // Check for SECURITY compiler symbol
    m3Hwi.resetVectorAddress = 0x90; // Image B Reset Vector Address
}
else {
    m3Hwi.resetVectorAddress = 0x50; // Image A Reset Vector Address
}

/* Put interrupt vector at start of RAM so interrupts can be configured at runtime */
m3Hwi.vectorTableAddress  = 0x20000000;

To

m3Hwi.nvicCCR.UNALIGN_TRP = 0;
//m3Hwi.nvicCCR.UNALIGN_TRP = 1;

/* Put reset vector at start of Flash */
m3Hwi.resetVectorAddress  = 0x0;

/* Put interrupt vector at start of RAM so interrupts can be configured at runtime */
m3Hwi.vectorTableAddress  = 0x20000000;

Monday, May 18, 2020

SwitchBot DIY using LPSTK-CC1352R , SG90 servo motor, and ProjectZero to away from COVID-19.

Due to COVID-19, people don't want to touch anything such as light switch arbitrarily and it is any super easy to DIY light switch robot to allow you to turn on or off light through BLE of you SmartPhone instead of touching the switch directly.

The follow steps show you how to DIY SwitchBot using Texas Instruments LPSTK-CC1352R, SG90 servo motor, and ProjectZero.

1. Add CONFIG_PWM_0 and use DIO22 as PWM output pin in project_zero.syscfg



2. Add "#include < ti/drivers/PWM.h >" and the following global variables in project_zero.c to use PWM related APIs later.

/* Period and duty in microseconds */
int16_t   pwmPeriod = 20000;
int16_t   duty = 1500;
int16_t   dutyInc = 500;

int16_t i=0;

/* Sleep time in microseconds */
PWM_Handle pwm1 = NULL;
PWM_Params params;

3. Add the following PZ_SERVO_EVT, servoClock, and Servo_clockHandler to send PZ_SERVO_EVT.

#define PZ_SERVO_EVT         11
static Clock_Struct servoClock;static void Servo_clockHandler(UArg arg);

static void Servo_clockHandler(UArg arg)
{
    //PWM_setDuty(pwm1, duty);
    pzButtonState_t *pButtonState = ICall_malloc(sizeof(pzButtonState_t));
            if(pButtonState != NULL)
            {
                //*pButtonState = buttonMsg;
                if(ProjectZero_enqueueMsg(PZ_SERVO_EVT, pButtonState) != SUCCESS)
                {
                  ICall_free(pButtonState);
                }
            }
}

4. Add "case PZ_SERVO_EVT:" in ProjectZero_processApplicationMessage to put SG90 back to original position after writing ON/OFF characteristics

      case PZ_SERVO_EVT:
      {
          PWM_setDuty(pwm1, duty);
          break;
      }


5.  Init/start servoClock and PWM in ProjectZero_init.

    Util_constructClock(&servoClock, Servo_clockHandler, 300, 0, false, 0);
    Util_startClock(&servoClock);

    PWM_init();
    PWM_Params_init(&params);
    params.dutyUnits = PWM_DUTY_US;
    params.dutyValue = 0;
    params.periodUnits = PWM_PERIOD_US;
    params.periodValue = pwmPeriod;
    pwm1 = PWM_open(CONFIG_PWM_0, &params);
    if (pwm1 == NULL) {
        /* CONFIG_PWM_0 did not open */
        while (1);
    }

    PWM_start(pwm1);
    PWM_setDuty(pwm1, duty);

6. In "case LS_LED0_ID:..." section of ProjectZero_LedService_ValueChangeHandler. Add the following code to set PWM to rotate SG90 servo motor according to ON/OFF characteristics writing.

        if (pCharData->data[0]!=0){
            PWM_setDuty(pwm1, duty-500);
            Util_startClock(&servoClock);
        }
        else{
            PWM_setDuty(pwm1, duty+800);
            Util_startClock(&servoClock);
        }


7. Build and download firmware into LPSTK-CC1352R

8. Connect GND/3V3/DIO22 pins on LPSTK-CC1352R to BROWN(GND)/RED(PWR)/ORANGE(PWM) on SG90.

9. Power on LPSTK-CC1352R and use TI SimpleLink Starter App to connect to Project Zero to toggle ON/OFF.