Demonstration of mbed os Threading capabilities using LPC4337 board and the general purpose shield

Dependencies:   ST7567

main.cpp

Committer:
uLipe
Date:
2016-09-19
Revision:
2:8595c827daa9
Parent:
1:b4065d4d692a

File content as of revision 2:8595c827daa9:

/**
 *  @brief simple accelerometer reading demo
 */
#include "mbed.h"
#include "rtos.h"
#include "ST7567.h"

/* defines the axis for acc */
#define ACC_NOOF_AXIS       3

/* defines the time of acquisition in ms */
#define ACC_SAMPLE_RATE     200

/* acc event flags */
#define ACC_EVENT           0x00000001

/* bmi160 slave address */
#define BMI160_ADDR         ((0x68)<<1)

/* LCD parameters */
#define LCD_HEIGHT          64
#define LCD_WIDTH           128
#define FONT_HEIGHT         10
#define FONT_WIDTH          5

/* Debug LED */
DigitalOut debug_led(LED1);

/* thread for accelerometer and LCD */

unsigned char acc_stack[1024];
unsigned char lcd_stack[1024];
Thread acc_thread(osPriorityRealtime, 1024 ,&acc_stack[0]);
Thread lcd_thread(osPriorityNormal, 1024, &lcd_stack[0]);

/* semaphore to sync acc reading to lcd printing */
Semaphore acc_sema;

/* buffer to store acc samples */
int16_t acc_sample_buffer[ACC_NOOF_AXIS] = {0x5555, 0x5555, 0x5555};
uint8_t acc_status = 0;



/**
 * @brief i2c event callback
 */

/**
 * @brief accelerometer processing task 
 */
static void acc_task(void) {
    I2C *imu_comm = new I2C(P2_3, P2_4);
    char i2c_reg_buffer[2] = {0};
    
    /* setup the frequency */
    imu_comm->frequency(20000);

    /* issue a sw reset */
    i2c_reg_buffer[0] = 0x7E;
    i2c_reg_buffer[1] = 0xB6;    
    imu_comm->write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);

    /* wait property time for device reset */
    Thread::wait(200);

    /* enable the accelerometer */
    i2c_reg_buffer[0] = 0x7E;
    i2c_reg_buffer[1] = 0x11;    
    imu_comm->write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
 
    /* sets the output data rate to 100 Hz */
    i2c_reg_buffer[0] = 0x40;
    i2c_reg_buffer[1] = 0x28;    
    imu_comm->write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
 
    for(;;) { 
        int err = 0;
         
        /* reads status register */
        i2c_reg_buffer[0] = 0x1B;
        err = imu_comm->write(BMI160_ADDR, i2c_reg_buffer, 1, true);
        err = imu_comm->read(BMI160_ADDR, (char *)&acc_status, sizeof(acc_status), false);
        
        /* reads the acc register */
        i2c_reg_buffer[0] = 0x12;
        err = imu_comm->write(BMI160_ADDR, i2c_reg_buffer, 1, true);
        err = imu_comm->read(BMI160_ADDR, (char *)&acc_sample_buffer, sizeof(acc_sample_buffer), false);
        acc_sema.release();
        Thread::wait(ACC_SAMPLE_RATE);
    }    
}


/**
 * @brief lcd update task 
 */
static void lcd_task(void) {
    const char banner[] = {"Embarcados IMU demo\0"};
    const char x_axis_text[] = {"x raw axis:\0"};
    const char y_axis_text[] = {"y raw axis:\0"};
    const char z_axis_text[] = {"z raw axis:\0"};
    const char status_text[] = {"acc status:\0"};
    DigitalOut *lcd_led = new DigitalOut(LED3);
    
    char acc_buffer[8] = {0}; 
    
    *lcd_led = 1;
    
    /* creates an spi lcd object */
    ST7567 *lcd = new ST7567(D11, D13, D12, D9, D10);
    lcd->set_contrast(0x35); 
    lcd->cls();  
    
    /* center the text banner */
    lcd->locate((LCD_WIDTH - (sizeof(banner) * FONT_WIDTH))/2,1); 
    lcd->printf(banner);
    
    lcd->locate(0, FONT_HEIGHT * 2);
    lcd->printf(x_axis_text);
    lcd->locate(0, FONT_HEIGHT * 3);
    lcd->printf(y_axis_text);
    lcd->locate(0, FONT_HEIGHT * 4);
    lcd->printf(z_axis_text);    
    lcd->locate(0, FONT_HEIGHT * 5);
    lcd->printf(status_text);


    for(;;) {
        /* wait for accelerometer event */
        acc_sema.wait();
        
        *lcd_led = 0;
        
        /* new samples arrived, format and prints on lcd */
        sprintf(&acc_buffer[0],"%d", acc_sample_buffer[0]);
        lcd->locate(sizeof(x_axis_text)*FONT_WIDTH, FONT_HEIGHT * 2);
        lcd->printf(acc_buffer);
        
        sprintf(&acc_buffer[0],"%d", acc_sample_buffer[1]);
        lcd->locate(sizeof(y_axis_text)*FONT_WIDTH, FONT_HEIGHT * 3);
        lcd->printf(acc_buffer);

        sprintf(&acc_buffer[0],"%d", acc_sample_buffer[2]);
        lcd->locate(sizeof(z_axis_text)*FONT_WIDTH, FONT_HEIGHT * 4);
        lcd->printf(acc_buffer);
        
        sprintf(&acc_buffer[0],"%x", acc_status);
        lcd->locate(sizeof(status_text)*FONT_WIDTH, FONT_HEIGHT * 5);
        lcd->printf(acc_buffer);
        
        *lcd_led = 1;
        /* block this task until the next semaphore trigger */
    }
}


/**
 * @brief main application entry point
 */
int main(void) {
    
    debug_led = 1;
    
    /* starts the two threads of this app */
    acc_thread.start(acc_task);
    lcd_thread.start(lcd_task);
    debug_led = 0;
}