WICED Bluetooth Using the CYW20719

# Title Comment
0 A Two Hour WICED Bluetooth Class WICED Bluetooth Using the CYW20719 in all its glory
1 Resources Links to all of the Cypress WICED information including videos, application notes etc.
2 Your First Project Making Hello World & the Blinky LED
3 The Super Mux Tool Learning about platforms and the Super Mux Tool
4 Snips Using the example projects to learn Bluetooth
5 Bluetooth Designer Using the tool to customize a project and get going fast
6 The CCCD & Notification Writing back to the Central
7 Advertising  Beacon Building a beacon project to advertise your custom information 
8 Scanner Viewing the world around you
9 Bluetooth Classic SPP Using the Serial Port Profile to Transmit Lots of Data

Source code: 

  • git@github.com:iotexpert/wiced_bt_intro.git
  • https://github.com/iotexpert/wiced_bt_intro

 

Summary

In this lesson I am going to show you how to NOT write all of your own code and still get the job done.  In this lesson we are going to do three things.

  1. Examine & Run the hal_gpio snip
  2. Examine & Run the hal_i2c_master snip
  3. Copy the hal_i2c_master snip and make it “more better”

To modify the hal_i2c_master snip I will

  1. Make a new folder called L4_Accelerometer
  2. Copy the makefile.mk and hal_i2c_master.c into the L4_Accelerometer folder
  3. Create a new make target and make sure that things still work
  4. Look at the LSM9DS1 datasheet
  5. Update the function initialize_app to startup the Accelerometer and speed up the polling
  6. Update the function comboread_cb to read the Acceleration registers and print out the values

Run hal_gpio

If you dont already have a make target for snip.hal.hal_gpio create one and then program the board.

Notice that the light blinking will change speeds if you press the button.  Let’s look at the code that does this:

At the beginning it sets up a timer

        // Initialize timer to control the pin toggle frequency
        if (wiced_init_timer(&hal_gpio_app_timer, &hal_gpio_app_timer_cb, 0, WICED_SECONDS_PERIODIC_TIMER) == WICED_SUCCESS)
        {
            if (wiced_start_timer(&hal_gpio_app_timer, LED_BLINK_FREQ_A_IN_SECONDS) != WICED_SUCCESS)
            {
                WICED_BT_TRACE("Seconds Timer Error\n");
            }
        }

The timer calls this function each time the timer expires.

/*
 * The function invoked on timeout of app. seconds timer.
 */
void hal_gpio_app_timer_cb(uint32_t arg)
{
    static uint32_t wiced_seconds = 0; /* number of seconds elapsed */
    uint8_t index = 0;

    wiced_seconds++;

    if (wiced_seconds & 1)
    {
        for (index = 0; index < sizeof(output_pin_list); index++)
        {
            wiced_hal_gpio_set_pin_output(output_pin_list[index], GPIO_PIN_OUTPUT_LOW);
        }
    }
    else
    {
        for (index = 0; index < sizeof(output_pin_list); index++)
        {
            wiced_hal_gpio_set_pin_output(output_pin_list[index], GPIO_PIN_OUTPUT_HIGH);
        }
    }
}

And when the button is pressed all it does is switch back and forth between two different intervals for the timer.  And after the switch it restarts the timer.

/*
 * Handle interrupt generated due to change in the GPIO state
 */
void hal_gpio_app_interrrupt_handler(void *data, uint8_t pin)
{
    static uint32_t blink_freq = LED_BLINK_FREQ_A_IN_SECONDS;

    // toggle LED blink rate upon each button press
    if (blink_freq == LED_BLINK_FREQ_A_IN_SECONDS)
    {
        blink_freq = LED_BLINK_FREQ_B_IN_SECONDS;
    }
    else
    {
        blink_freq = LED_BLINK_FREQ_A_IN_SECONDS;
    }

    if (wiced_stop_timer(&hal_gpio_app_timer) == WICED_SUCCESS)
    {
        wiced_start_timer(&hal_gpio_app_timer, blink_freq);
    }

    // clear the interrupt status
    wiced_hal_gpio_clear_pin_interrupt_status(pin);
}

Run hal_i2c_master

This CYW920719Q40EVB_01 development kit has an I2C LSM9DS1 accelerometer on it.  And I noticed that when looking around in the snips that the Snip called “hal_i2c_master.c” appears to talk to the chip.  Here is a little section of the comments from the top of the snip

 *
 * WICED sample application for I2C Master usage
 *
 * This application demonstrates how to use I2C driver interface
 * to send and receive bytes or a stream of bytes over the I2C hardware as a master.
 * The on-board LSM9DS1 motion sensor acts as the I2C slave

So, lets run the snip and see what happens.  If you don’t have a make target… well then make one.

Then make the make target.

It turns out that “0” is a bug in the example project.  And printing out the WHO_AM_I register isnt really very interesting.

Modify the hal_i2c_master.c Create a Better Project

I don’t like making changes inside of the WICED SDK files.  But, I want to fix the bug and printout something more interesting.  So start by creating a new folder in the wiced_bt_class folder

Type in the directory name L4_Accelerometer (notice in the screenshot below I mistyped it)

Select the makefile.mk and the hal_i2c_master.c then right click copy the files.

Then select the L4_Accelerometer folder and pick paste.

Create a make target for the L4_Accelerometer

Build it to make sure it still works.

Now that we have a base to stand-on.  Let’s have a look at the data sheet.  I have used these before and I know that you need to turn on the Accelerometer to give you anything interesting.  Turns out CTRL_REG_6_XL is the control register we need.

The other interesting registers are the actual output of the accelerometer.  That is 0x28 –> 0x2D

Start by modifying the function initialize_app to turn on the accelerometer by writing 0x40 to register 0x20

uint8_t status;
    // Turn on Accelerometer - Register 0x20... 2g accelerometer on @ 50hz
    uint8_t data[] = {0x20, 0x40};
    status = wiced_hal_i2c_write(data,sizeof(data),LSM9DS1_ACC_GYRO_I2C_ADDRESS);

I dont really like printing the values every two seconds so I will modify the timer:

  • Make it a milisecond timer
  • Set it to print every 500ms
if ( WICED_SUCCESS == wiced_init_timer( &seconds_timer, &comboread_cb, 0, WICED_MILLI_SECONDS_PERIODIC_TIMER )) {
        if ( WICED_SUCCESS != wiced_start_timer( &seconds_timer, 500 )) {
            WICED_BT_TRACE( "Seconds Timer Error\n\r" );
        }
    }

Here is the whole function initialize_app together

void initialize_app( void )
{
    wiced_hal_i2c_init();
    uint8_t status;

    // Turn on Accelerometer - Register 0x20... 2g accelerometer on @ 50hz
    uint8_t data[] = {0x20, 0x40};
    status = wiced_hal_i2c_write(data,sizeof(data),LSM9DS1_ACC_GYRO_I2C_ADDRESS);


    /* register callback for button available on the platform */
    wiced_platform_register_button_callback( WICED_PLATFORM_BUTTON_1, button_cb, NULL, WICED_PLATFORM_BUTTON_RISING_EDGE);

    current_speed = wiced_hal_i2c_get_speed();

    WICED_BT_TRACE("Default I2C speed: %d KHz\n", (CLK_FREQ/current_speed));

    /*Start a timer for POLL_TIMER seconds*/

    if ( WICED_SUCCESS == wiced_init_timer( &seconds_timer, &comboread_cb, 0, WICED_MILLI_SECONDS_PERIODIC_TIMER )) {
        if ( WICED_SUCCESS != wiced_start_timer( &seconds_timer, 500 )) {
            WICED_BT_TRACE( "Seconds Timer Error\n\r" );
        }
    }

}

Next I need to modify the comboread_cb callback.  It will

  • Setup a structure to hold the three acceleration values (Line 145)
  • Then it will read from the LSM9DS1 (Line 152)
  • Then print them (Line 156)
/******************************************************************************
 * This function reads the value from I2C slave and prints it
 *****************************************************************************/

void comboread_cb (uint32_t arg)
{
    UINT8  status = 0xFF;
    UINT8 reg_add = 0x28; // Acceleromter register

    typedef struct {
        int16_t ax;
        int16_t ay;
        int16_t az;
    } __attribute__((packed)) accel_val_t;

    accel_val_t data;
    status = wiced_hal_i2c_combined_read((UINT8 *)&reg_add, sizeof(UINT8), (uint8_t *)&data, sizeof(data), LSM9DS1_ACC_GYRO_I2C_ADDRESS);

    if(I2CM_SUCCESS == status) {

        WICED_BT_TRACE("Ax=%d Ay=%d Az=%d\n",data.ax,data.ay,data.az);
    }else if(I2CM_OP_FAILED == status) {
        WICED_BT_TRACE("I2C comboread operation failed\r\n");
    }else if(I2CM_BUSY == status) {
        WICED_BT_TRACE("I2C busy\r\n");
    }else{
        WICED_BT_TRACE("Unknown status from I2C\r\n");
    }

}

Now double click the make target and make sure that everything is working.

Recommended Posts

No comment yet, add your voice below!


Add a Comment

Your email address will not be published. Required fields are marked *