Felipe Neves
/
lpc4337_acc_demo
Demonstration of mbed os Threading capabilities using LPC4337 board and the general purpose shield
main.cpp@1:b4065d4d692a, 2016-09-19 (annotated)
- Committer:
- uLipe
- Date:
- Mon Sep 19 21:01:30 2016 +0000
- Revision:
- 1:b4065d4d692a
- Parent:
- 0:0dc9a3be9863
- Child:
- 2:8595c827daa9
mbed rtos demo with lpc4337 + general purpose shield
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
uLipe | 0:0dc9a3be9863 | 1 | /** |
uLipe | 0:0dc9a3be9863 | 2 | * @brief simple accelerometer reading demo |
uLipe | 0:0dc9a3be9863 | 3 | */ |
uLipe | 0:0dc9a3be9863 | 4 | #include "mbed.h" |
uLipe | 0:0dc9a3be9863 | 5 | #include "rtos.h" |
uLipe | 0:0dc9a3be9863 | 6 | #include "ST7567.h" |
uLipe | 0:0dc9a3be9863 | 7 | |
uLipe | 0:0dc9a3be9863 | 8 | /* defines the axis for acc */ |
uLipe | 0:0dc9a3be9863 | 9 | #define ACC_NOOF_AXIS 3 |
uLipe | 0:0dc9a3be9863 | 10 | |
uLipe | 0:0dc9a3be9863 | 11 | /* defines the time of acquisition in ms */ |
uLipe | 0:0dc9a3be9863 | 12 | #define ACC_SAMPLE_RATE 200 |
uLipe | 0:0dc9a3be9863 | 13 | |
uLipe | 0:0dc9a3be9863 | 14 | /* acc event flags */ |
uLipe | 0:0dc9a3be9863 | 15 | #define ACC_EVENT 0x00000001 |
uLipe | 0:0dc9a3be9863 | 16 | |
uLipe | 0:0dc9a3be9863 | 17 | /* bmi160 slave address */ |
uLipe | 0:0dc9a3be9863 | 18 | #define BMI160_ADDR ((0x68)<<1) |
uLipe | 0:0dc9a3be9863 | 19 | |
uLipe | 0:0dc9a3be9863 | 20 | /* LCD parameters */ |
uLipe | 0:0dc9a3be9863 | 21 | #define LCD_HEIGHT 64 |
uLipe | 0:0dc9a3be9863 | 22 | #define LCD_WIDTH 128 |
uLipe | 0:0dc9a3be9863 | 23 | #define FONT_HEIGHT 10 |
uLipe | 0:0dc9a3be9863 | 24 | #define FONT_WIDTH 5 |
uLipe | 0:0dc9a3be9863 | 25 | |
uLipe | 0:0dc9a3be9863 | 26 | /* Debug LED */ |
uLipe | 0:0dc9a3be9863 | 27 | DigitalOut debug_led(LED1); |
uLipe | 0:0dc9a3be9863 | 28 | |
uLipe | 0:0dc9a3be9863 | 29 | /* thread for accelerometer and LCD */ |
uLipe | 0:0dc9a3be9863 | 30 | |
uLipe | 0:0dc9a3be9863 | 31 | unsigned char acc_stack[1024]; |
uLipe | 0:0dc9a3be9863 | 32 | unsigned char lcd_stack[1024]; |
uLipe | 0:0dc9a3be9863 | 33 | Thread acc_thread(osPriorityRealtime, 1024 ,&acc_stack[0]); |
uLipe | 0:0dc9a3be9863 | 34 | Thread lcd_thread(osPriorityNormal, 1024, &lcd_stack[0]); |
uLipe | 0:0dc9a3be9863 | 35 | |
uLipe | 0:0dc9a3be9863 | 36 | /* semaphore to sync acc reading to lcd printing */ |
uLipe | 0:0dc9a3be9863 | 37 | Semaphore acc_sema; |
uLipe | 0:0dc9a3be9863 | 38 | |
uLipe | 0:0dc9a3be9863 | 39 | /* buffer to store acc samples */ |
uLipe | 0:0dc9a3be9863 | 40 | int16_t acc_sample_buffer[ACC_NOOF_AXIS] = {0x5555, 0x5555, 0x5555}; |
uLipe | 0:0dc9a3be9863 | 41 | uint8_t acc_status = 0; |
uLipe | 0:0dc9a3be9863 | 42 | |
uLipe | 0:0dc9a3be9863 | 43 | |
uLipe | 0:0dc9a3be9863 | 44 | |
uLipe | 0:0dc9a3be9863 | 45 | /** |
uLipe | 0:0dc9a3be9863 | 46 | * @brief i2c event callback |
uLipe | 0:0dc9a3be9863 | 47 | */ |
uLipe | 0:0dc9a3be9863 | 48 | |
uLipe | 0:0dc9a3be9863 | 49 | /** |
uLipe | 0:0dc9a3be9863 | 50 | * @brief accelerometer processing task |
uLipe | 0:0dc9a3be9863 | 51 | */ |
uLipe | 0:0dc9a3be9863 | 52 | static void acc_task(void) { |
uLipe | 0:0dc9a3be9863 | 53 | I2C *imu_comm = new I2C(P2_3, P2_4); |
uLipe | 0:0dc9a3be9863 | 54 | char i2c_reg_buffer[2] = {0}; |
uLipe | 0:0dc9a3be9863 | 55 | |
uLipe | 0:0dc9a3be9863 | 56 | /* setup the frequency */ |
uLipe | 0:0dc9a3be9863 | 57 | imu_comm->frequency(20000); |
uLipe | 0:0dc9a3be9863 | 58 | |
uLipe | 0:0dc9a3be9863 | 59 | /* issue a sw reset */ |
uLipe | 0:0dc9a3be9863 | 60 | i2c_reg_buffer[0] = 0x7E; |
uLipe | 0:0dc9a3be9863 | 61 | i2c_reg_buffer[1] = 0xB6; |
uLipe | 0:0dc9a3be9863 | 62 | imu_comm->write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false); |
uLipe | 0:0dc9a3be9863 | 63 | |
uLipe | 0:0dc9a3be9863 | 64 | /* wait property time for device reset */ |
uLipe | 0:0dc9a3be9863 | 65 | Thread::wait(200); |
uLipe | 0:0dc9a3be9863 | 66 | |
uLipe | 0:0dc9a3be9863 | 67 | /* enable the accelerometer */ |
uLipe | 0:0dc9a3be9863 | 68 | i2c_reg_buffer[0] = 0x7E; |
uLipe | 0:0dc9a3be9863 | 69 | i2c_reg_buffer[1] = 0x11; |
uLipe | 0:0dc9a3be9863 | 70 | imu_comm->write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false); |
uLipe | 0:0dc9a3be9863 | 71 | |
uLipe | 0:0dc9a3be9863 | 72 | /* sets the output data rate to 100 Hz */ |
uLipe | 0:0dc9a3be9863 | 73 | i2c_reg_buffer[0] = 0x40; |
uLipe | 0:0dc9a3be9863 | 74 | i2c_reg_buffer[1] = 0x28; |
uLipe | 0:0dc9a3be9863 | 75 | imu_comm->write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false); |
uLipe | 0:0dc9a3be9863 | 76 | |
uLipe | 1:b4065d4d692a | 77 | for(;;) { |
uLipe | 0:0dc9a3be9863 | 78 | /* reads status register */ |
uLipe | 1:b4065d4d692a | 79 | i2c_reg_buffer[0] = 0x1B; |
uLipe | 0:0dc9a3be9863 | 80 | err = imu_comm->write(BMI160_ADDR, i2c_reg_buffer, 1, true); |
uLipe | 0:0dc9a3be9863 | 81 | err = imu_comm->read(BMI160_ADDR, (char *)&acc_status, sizeof(acc_status), false); |
uLipe | 0:0dc9a3be9863 | 82 | |
uLipe | 0:0dc9a3be9863 | 83 | /* reads the acc register */ |
uLipe | 0:0dc9a3be9863 | 84 | i2c_reg_buffer[0] = 0x12; |
uLipe | 0:0dc9a3be9863 | 85 | err = imu_comm->write(BMI160_ADDR, i2c_reg_buffer, 1, true); |
uLipe | 0:0dc9a3be9863 | 86 | err = imu_comm->read(BMI160_ADDR, (char *)&acc_sample_buffer, sizeof(acc_sample_buffer), false); |
uLipe | 0:0dc9a3be9863 | 87 | acc_sema.release(); |
uLipe | 1:b4065d4d692a | 88 | Thread::wait(ACC_SAMPLE_RATE); |
uLipe | 0:0dc9a3be9863 | 89 | } |
uLipe | 0:0dc9a3be9863 | 90 | } |
uLipe | 0:0dc9a3be9863 | 91 | |
uLipe | 0:0dc9a3be9863 | 92 | |
uLipe | 0:0dc9a3be9863 | 93 | /** |
uLipe | 0:0dc9a3be9863 | 94 | * @brief lcd update task |
uLipe | 0:0dc9a3be9863 | 95 | */ |
uLipe | 0:0dc9a3be9863 | 96 | static void lcd_task(void) { |
uLipe | 0:0dc9a3be9863 | 97 | const char banner[] = {"Embarcados IMU demo\0"}; |
uLipe | 0:0dc9a3be9863 | 98 | const char x_axis_text[] = {"x raw axis:\0"}; |
uLipe | 0:0dc9a3be9863 | 99 | const char y_axis_text[] = {"y raw axis:\0"}; |
uLipe | 0:0dc9a3be9863 | 100 | const char z_axis_text[] = {"z raw axis:\0"}; |
uLipe | 0:0dc9a3be9863 | 101 | const char status_text[] = {"acc status:\0"}; |
uLipe | 0:0dc9a3be9863 | 102 | DigitalOut *lcd_led = new DigitalOut(LED3); |
uLipe | 0:0dc9a3be9863 | 103 | |
uLipe | 0:0dc9a3be9863 | 104 | char acc_buffer[8] = {0}; |
uLipe | 0:0dc9a3be9863 | 105 | |
uLipe | 0:0dc9a3be9863 | 106 | *lcd_led = 1; |
uLipe | 0:0dc9a3be9863 | 107 | |
uLipe | 0:0dc9a3be9863 | 108 | /* creates an spi lcd object */ |
uLipe | 0:0dc9a3be9863 | 109 | ST7567 *lcd = new ST7567(D11, D13, D12, D9, D10); |
uLipe | 0:0dc9a3be9863 | 110 | lcd->set_contrast(0x35); |
uLipe | 0:0dc9a3be9863 | 111 | lcd->cls(); |
uLipe | 0:0dc9a3be9863 | 112 | |
uLipe | 0:0dc9a3be9863 | 113 | /* center the text banner */ |
uLipe | 0:0dc9a3be9863 | 114 | lcd->locate((LCD_WIDTH - (sizeof(banner) * FONT_WIDTH))/2,1); |
uLipe | 0:0dc9a3be9863 | 115 | lcd->printf(banner); |
uLipe | 0:0dc9a3be9863 | 116 | |
uLipe | 0:0dc9a3be9863 | 117 | lcd->locate(0, FONT_HEIGHT * 2); |
uLipe | 0:0dc9a3be9863 | 118 | lcd->printf(x_axis_text); |
uLipe | 0:0dc9a3be9863 | 119 | lcd->locate(0, FONT_HEIGHT * 3); |
uLipe | 0:0dc9a3be9863 | 120 | lcd->printf(y_axis_text); |
uLipe | 0:0dc9a3be9863 | 121 | lcd->locate(0, FONT_HEIGHT * 4); |
uLipe | 0:0dc9a3be9863 | 122 | lcd->printf(z_axis_text); |
uLipe | 0:0dc9a3be9863 | 123 | lcd->locate(0, FONT_HEIGHT * 5); |
uLipe | 0:0dc9a3be9863 | 124 | lcd->printf(status_text); |
uLipe | 0:0dc9a3be9863 | 125 | |
uLipe | 0:0dc9a3be9863 | 126 | |
uLipe | 0:0dc9a3be9863 | 127 | for(;;) { |
uLipe | 0:0dc9a3be9863 | 128 | /* wait for accelerometer event */ |
uLipe | 0:0dc9a3be9863 | 129 | acc_sema.wait(); |
uLipe | 0:0dc9a3be9863 | 130 | |
uLipe | 0:0dc9a3be9863 | 131 | *lcd_led = 0; |
uLipe | 0:0dc9a3be9863 | 132 | |
uLipe | 0:0dc9a3be9863 | 133 | /* new samples arrived, format and prints on lcd */ |
uLipe | 0:0dc9a3be9863 | 134 | sprintf(&acc_buffer[0],"%d", acc_sample_buffer[0]); |
uLipe | 0:0dc9a3be9863 | 135 | lcd->locate(sizeof(x_axis_text)*FONT_WIDTH, FONT_HEIGHT * 2); |
uLipe | 0:0dc9a3be9863 | 136 | lcd->printf(acc_buffer); |
uLipe | 0:0dc9a3be9863 | 137 | |
uLipe | 0:0dc9a3be9863 | 138 | sprintf(&acc_buffer[0],"%d", acc_sample_buffer[1]); |
uLipe | 0:0dc9a3be9863 | 139 | lcd->locate(sizeof(y_axis_text)*FONT_WIDTH, FONT_HEIGHT * 3); |
uLipe | 0:0dc9a3be9863 | 140 | lcd->printf(acc_buffer); |
uLipe | 0:0dc9a3be9863 | 141 | |
uLipe | 0:0dc9a3be9863 | 142 | sprintf(&acc_buffer[0],"%d", acc_sample_buffer[2]); |
uLipe | 0:0dc9a3be9863 | 143 | lcd->locate(sizeof(z_axis_text)*FONT_WIDTH, FONT_HEIGHT * 4); |
uLipe | 0:0dc9a3be9863 | 144 | lcd->printf(acc_buffer); |
uLipe | 0:0dc9a3be9863 | 145 | |
uLipe | 0:0dc9a3be9863 | 146 | sprintf(&acc_buffer[0],"%x", acc_status); |
uLipe | 0:0dc9a3be9863 | 147 | lcd->locate(sizeof(status_text)*FONT_WIDTH, FONT_HEIGHT * 5); |
uLipe | 0:0dc9a3be9863 | 148 | lcd->printf(acc_buffer); |
uLipe | 0:0dc9a3be9863 | 149 | |
uLipe | 0:0dc9a3be9863 | 150 | *lcd_led = 1; |
uLipe | 0:0dc9a3be9863 | 151 | /* block this task until the next semaphore trigger */ |
uLipe | 0:0dc9a3be9863 | 152 | } |
uLipe | 0:0dc9a3be9863 | 153 | } |
uLipe | 0:0dc9a3be9863 | 154 | |
uLipe | 1:b4065d4d692a | 155 | |
uLipe | 0:0dc9a3be9863 | 156 | /** |
uLipe | 0:0dc9a3be9863 | 157 | * @brief main application entry point |
uLipe | 0:0dc9a3be9863 | 158 | */ |
uLipe | 0:0dc9a3be9863 | 159 | int main(void) { |
uLipe | 0:0dc9a3be9863 | 160 | |
uLipe | 0:0dc9a3be9863 | 161 | debug_led = 1; |
uLipe | 0:0dc9a3be9863 | 162 | |
uLipe | 0:0dc9a3be9863 | 163 | /* starts the two threads of this app */ |
uLipe | 0:0dc9a3be9863 | 164 | acc_thread.start(acc_task); |
uLipe | 0:0dc9a3be9863 | 165 | lcd_thread.start(lcd_task); |
uLipe | 0:0dc9a3be9863 | 166 | debug_led = 0; |
uLipe | 0:0dc9a3be9863 | 167 | } |