ftf mbed os semaphores lab

Dependencies:   ST7567

Committer:
uLipe
Date:
Sun Nov 06 00:56:46 2016 +0000
Revision:
0:30211b394890
first working version;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uLipe 0:30211b394890 1 /**
uLipe 0:30211b394890 2 * @brief NXP FTF LAB3 - Mbed OS Semaphore lab
uLipe 0:30211b394890 3 */
uLipe 0:30211b394890 4
uLipe 0:30211b394890 5
uLipe 0:30211b394890 6 #include "mbed.h"
uLipe 0:30211b394890 7 #include "ST7567.h"
uLipe 0:30211b394890 8 #include "rtos.h"
uLipe 0:30211b394890 9
uLipe 0:30211b394890 10 /* LCD screen dimensions */
uLipe 0:30211b394890 11 #define LCD_HEIGHT 64
uLipe 0:30211b394890 12 #define LCD_WIDTH 128
uLipe 0:30211b394890 13
uLipe 0:30211b394890 14 /* LCD font dimensions */
uLipe 0:30211b394890 15 #define FONT_HEIGHT 10
uLipe 0:30211b394890 16 #define FONT_WIDTH 5
uLipe 0:30211b394890 17
uLipe 0:30211b394890 18 /* defines the axis for acc */
uLipe 0:30211b394890 19 #define ACC_NOOF_AXIS 3
uLipe 0:30211b394890 20
uLipe 0:30211b394890 21 /* defines the time of acquisition in ms */
uLipe 0:30211b394890 22 #define ACC_SAMPLE_RATE 200
uLipe 0:30211b394890 23
uLipe 0:30211b394890 24 /* acc event flags */
uLipe 0:30211b394890 25 #define ACC_EVENT 0x00000001
uLipe 0:30211b394890 26
uLipe 0:30211b394890 27 /* bmi160 slave address */
uLipe 0:30211b394890 28 #define BMI160_ADDR ((0x68)<<1)
uLipe 0:30211b394890 29
uLipe 0:30211b394890 30 /* bmi160 g conversion factor */
uLipe 0:30211b394890 31 #define ACC_2G_SCALE_FACTOR (0.0000610f)
uLipe 0:30211b394890 32
uLipe 0:30211b394890 33
uLipe 0:30211b394890 34
uLipe 0:30211b394890 35 /** Instance a on board GLCD object */
uLipe 0:30211b394890 36 ST7567 glcd(D11, D13, D12, D9, D10);
uLipe 0:30211b394890 37
uLipe 0:30211b394890 38
uLipe 0:30211b394890 39 /* allocate statically stacks for the shell task */
uLipe 0:30211b394890 40 unsigned char shell_stk[4096];
uLipe 0:30211b394890 41 Thread shell_thread(osPriorityRealtime, 4096, &shell_stk[0]);
uLipe 0:30211b394890 42
uLipe 0:30211b394890 43 /* thread for accelerometer and LCD */
uLipe 0:30211b394890 44 unsigned char acc_stack[1024];
uLipe 0:30211b394890 45 unsigned char lcd_stack[1024];
uLipe 0:30211b394890 46 unsigned char align_stack[2048];
uLipe 0:30211b394890 47 Thread acc_thread(osPriorityHigh, 1024 ,&acc_stack[0]);
uLipe 0:30211b394890 48 Thread lcd_thread(osPriorityNormal, 1024, &lcd_stack[0]);
uLipe 0:30211b394890 49 Thread align_thread(osPriorityRealtime, 2048, &align_stack[0]);
uLipe 0:30211b394890 50
uLipe 0:30211b394890 51 /* semaphore to sync acc reading to lcd printing */
uLipe 0:30211b394890 52 Semaphore acc_sema;
uLipe 0:30211b394890 53 Semaphore align_event_sema;
uLipe 0:30211b394890 54
uLipe 0:30211b394890 55 /* buffer to store acc samples */
uLipe 0:30211b394890 56 int16_t acc_sample_buffer[ACC_NOOF_AXIS] = {0x0, 0x0, 0x0};
uLipe 0:30211b394890 57 uint8_t acc_status = 0;
uLipe 0:30211b394890 58
uLipe 0:30211b394890 59
uLipe 0:30211b394890 60 /** Instance a UART class to communicate with pc */
uLipe 0:30211b394890 61 Serial pc_serial(USBTX,USBRX);
uLipe 0:30211b394890 62
uLipe 0:30211b394890 63
uLipe 0:30211b394890 64 /**
uLipe 0:30211b394890 65 * @brief accelerometer processing task
uLipe 0:30211b394890 66 */
uLipe 0:30211b394890 67 static void acc_task(void) {
uLipe 0:30211b394890 68 I2C *imu_comm = new I2C(P2_3, P2_4);
uLipe 0:30211b394890 69 char i2c_reg_buffer[2] = {0};
uLipe 0:30211b394890 70
uLipe 0:30211b394890 71 /* setup the frequency */
uLipe 0:30211b394890 72 imu_comm->frequency(20000);
uLipe 0:30211b394890 73
uLipe 0:30211b394890 74 /* issue a sw reset */
uLipe 0:30211b394890 75 i2c_reg_buffer[0] = 0x7E;
uLipe 0:30211b394890 76 i2c_reg_buffer[1] = 0xB6;
uLipe 0:30211b394890 77 imu_comm->write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
uLipe 0:30211b394890 78
uLipe 0:30211b394890 79 /* wait property time for device reset */
uLipe 0:30211b394890 80 Thread::wait(200);
uLipe 0:30211b394890 81
uLipe 0:30211b394890 82 /* enable the accelerometer */
uLipe 0:30211b394890 83 i2c_reg_buffer[0] = 0x7E;
uLipe 0:30211b394890 84 i2c_reg_buffer[1] = 0x11;
uLipe 0:30211b394890 85 imu_comm->write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
uLipe 0:30211b394890 86
uLipe 0:30211b394890 87 /* sets the output data rate to 100 Hz */
uLipe 0:30211b394890 88 i2c_reg_buffer[0] = 0x40;
uLipe 0:30211b394890 89 i2c_reg_buffer[1] = 0x28;
uLipe 0:30211b394890 90 imu_comm->write(BMI160_ADDR, i2c_reg_buffer, sizeof(i2c_reg_buffer), false);
uLipe 0:30211b394890 91
uLipe 0:30211b394890 92 for(;;) {
uLipe 0:30211b394890 93 int err = 0;
uLipe 0:30211b394890 94
uLipe 0:30211b394890 95 /* reads status register */
uLipe 0:30211b394890 96 i2c_reg_buffer[0] = 0x1B;
uLipe 0:30211b394890 97 err = imu_comm->write(BMI160_ADDR, i2c_reg_buffer, 1, true);
uLipe 0:30211b394890 98 err = imu_comm->read(BMI160_ADDR, (char *)&acc_status, sizeof(acc_status), false);
uLipe 0:30211b394890 99
uLipe 0:30211b394890 100 /* reads the acc register */
uLipe 0:30211b394890 101 i2c_reg_buffer[0] = 0x12;
uLipe 0:30211b394890 102 err = imu_comm->write(BMI160_ADDR, i2c_reg_buffer, 1, true);
uLipe 0:30211b394890 103 err = imu_comm->read(BMI160_ADDR, (char *)&acc_sample_buffer, sizeof(acc_sample_buffer), false);
uLipe 0:30211b394890 104 /* notify a new reading */
uLipe 0:30211b394890 105 acc_sema.release();
uLipe 0:30211b394890 106 /* notify a align event */
uLipe 0:30211b394890 107 align_event_sema.release();
uLipe 0:30211b394890 108 Thread::wait(ACC_SAMPLE_RATE);
uLipe 0:30211b394890 109 }
uLipe 0:30211b394890 110 }
uLipe 0:30211b394890 111
uLipe 0:30211b394890 112
uLipe 0:30211b394890 113 static void align_event_task(void)
uLipe 0:30211b394890 114 {
uLipe 0:30211b394890 115 DigitalOut led1(LED1);
uLipe 0:30211b394890 116 DigitalOut led2(LED2);
uLipe 0:30211b394890 117 DigitalOut led3(LED3);
uLipe 0:30211b394890 118
uLipe 0:30211b394890 119 float x,y,z;
uLipe 0:30211b394890 120
uLipe 0:30211b394890 121 for(;;) {
uLipe 0:30211b394890 122 align_event_sema.wait();
uLipe 0:30211b394890 123
uLipe 0:30211b394890 124 /* new reading, check for event */
uLipe 0:30211b394890 125 x = (float)acc_sample_buffer[0] * ACC_2G_SCALE_FACTOR;
uLipe 0:30211b394890 126 y = (float)acc_sample_buffer[1] * ACC_2G_SCALE_FACTOR;
uLipe 0:30211b394890 127 z = (float)acc_sample_buffer[2] * ACC_2G_SCALE_FACTOR;
uLipe 0:30211b394890 128
uLipe 0:30211b394890 129 /* light led of correspondign axis alignment */
uLipe 0:30211b394890 130 if(x > 0.90f || x < -0.90) {
uLipe 0:30211b394890 131 led1 = 0;
uLipe 0:30211b394890 132 } else {
uLipe 0:30211b394890 133 led1 = 1;
uLipe 0:30211b394890 134 }
uLipe 0:30211b394890 135 if(y > 0.90f || y < -0.90) {
uLipe 0:30211b394890 136 led2 = 0;
uLipe 0:30211b394890 137
uLipe 0:30211b394890 138 }else {
uLipe 0:30211b394890 139 led2 = 1;
uLipe 0:30211b394890 140
uLipe 0:30211b394890 141 }
uLipe 0:30211b394890 142 if(z > 0.90f || z < -0.90) {
uLipe 0:30211b394890 143 led3 = 0;
uLipe 0:30211b394890 144
uLipe 0:30211b394890 145 }else {
uLipe 0:30211b394890 146 led3 = 1;
uLipe 0:30211b394890 147 }
uLipe 0:30211b394890 148
uLipe 0:30211b394890 149 }
uLipe 0:30211b394890 150
uLipe 0:30211b394890 151 }
uLipe 0:30211b394890 152
uLipe 0:30211b394890 153
uLipe 0:30211b394890 154 /**
uLipe 0:30211b394890 155 * @brief lcd update task
uLipe 0:30211b394890 156 */
uLipe 0:30211b394890 157 static void lcd_task(void) {
uLipe 0:30211b394890 158 const char banner[] = {"FTF IMU demo\0"};
uLipe 0:30211b394890 159 float x, y,z ;
uLipe 0:30211b394890 160
uLipe 0:30211b394890 161
uLipe 0:30211b394890 162 glcd.set_contrast(0x35);
uLipe 0:30211b394890 163 glcd.cls();
uLipe 0:30211b394890 164
uLipe 0:30211b394890 165 for(;;) {
uLipe 0:30211b394890 166 /* wait for accelerometer event */
uLipe 0:30211b394890 167 acc_sema.wait();
uLipe 0:30211b394890 168
uLipe 0:30211b394890 169 /* format the readings */
uLipe 0:30211b394890 170 x = (float)acc_sample_buffer[0] * ACC_2G_SCALE_FACTOR;
uLipe 0:30211b394890 171 y = (float)acc_sample_buffer[1] * ACC_2G_SCALE_FACTOR;
uLipe 0:30211b394890 172 z = (float)acc_sample_buffer[2] * ACC_2G_SCALE_FACTOR;
uLipe 0:30211b394890 173
uLipe 0:30211b394890 174
uLipe 0:30211b394890 175 glcd.locate((LCD_WIDTH - (sizeof(banner) * FONT_WIDTH))/2,1);
uLipe 0:30211b394890 176 glcd.printf(banner);
uLipe 0:30211b394890 177
uLipe 0:30211b394890 178
uLipe 0:30211b394890 179 /* new samples arrived, format and prints on lcd */
uLipe 0:30211b394890 180 glcd.locate(0, FONT_HEIGHT * 2);
uLipe 0:30211b394890 181 glcd.printf("x axis: %f",x);
uLipe 0:30211b394890 182
uLipe 0:30211b394890 183 glcd.locate(0, FONT_HEIGHT * 3);
uLipe 0:30211b394890 184 glcd.printf("y axis: %f",y);
uLipe 0:30211b394890 185
uLipe 0:30211b394890 186 glcd.locate(0, FONT_HEIGHT * 4);
uLipe 0:30211b394890 187 glcd.printf("z axis: %f",z);
uLipe 0:30211b394890 188
uLipe 0:30211b394890 189 glcd.locate(0, FONT_HEIGHT * 5);
uLipe 0:30211b394890 190 glcd.printf("acc status: 0x%x",acc_status);
uLipe 0:30211b394890 191
uLipe 0:30211b394890 192 }
uLipe 0:30211b394890 193 }
uLipe 0:30211b394890 194
uLipe 0:30211b394890 195
uLipe 0:30211b394890 196
uLipe 0:30211b394890 197 /**
uLipe 0:30211b394890 198 * @brief thread_command interpreter
uLipe 0:30211b394890 199 */
uLipe 0:30211b394890 200 void shell_execute_command(int argc, char **argv){
uLipe 0:30211b394890 201
uLipe 0:30211b394890 202
uLipe 0:30211b394890 203 }
uLipe 0:30211b394890 204
uLipe 0:30211b394890 205
uLipe 0:30211b394890 206 /**
uLipe 0:30211b394890 207 * @brief show help menu
uLipe 0:30211b394890 208 */
uLipe 0:30211b394890 209 static void print_usage(void) {
uLipe 0:30211b394890 210 pc_serial.printf("## use with the syntax below: \n\r");
uLipe 0:30211b394890 211 pc_serial.printf("## command <arg1> <arg2> ... <arg16> \n\r");
uLipe 0:30211b394890 212 pc_serial.printf("## Available commands: \n\r");
uLipe 0:30211b394890 213 }
uLipe 0:30211b394890 214
uLipe 0:30211b394890 215
uLipe 0:30211b394890 216 /**
uLipe 0:30211b394890 217 * @brief parse the command received via comport
uLipe 0:30211b394890 218 */
uLipe 0:30211b394890 219 static void shell_parser (char *cmd, int size) {
uLipe 0:30211b394890 220 int cmd_ptr = 0;
uLipe 0:30211b394890 221 int arg_ptr = 0;
uLipe 0:30211b394890 222 int cmd_size = 0;
uLipe 0:30211b394890 223 char command_buffer[256];
uLipe 0:30211b394890 224
uLipe 0:30211b394890 225 int argc = 0;
uLipe 0:30211b394890 226 char *argv[16];
uLipe 0:30211b394890 227
uLipe 0:30211b394890 228 /* copy to the root command */
uLipe 0:30211b394890 229 memset(&command_buffer, 0, sizeof(command_buffer));
uLipe 0:30211b394890 230
uLipe 0:30211b394890 231 /* find the root command terminator (space) */
uLipe 0:30211b394890 232 while(cmd_ptr < size) {
uLipe 0:30211b394890 233 if(cmd[cmd_ptr] == ' ') break;
uLipe 0:30211b394890 234 cmd_ptr++;
uLipe 0:30211b394890 235 }
uLipe 0:30211b394890 236 cmd_size = size - cmd_ptr;
uLipe 0:30211b394890 237
uLipe 0:30211b394890 238
uLipe 0:30211b394890 239 /* extract command arguments */
uLipe 0:30211b394890 240 strncpy(&command_buffer[0], &cmd[cmd_ptr + 1], (size - cmd_ptr));
uLipe 0:30211b394890 241
uLipe 0:30211b394890 242 /* terminates the root command */
uLipe 0:30211b394890 243 cmd[cmd_ptr] = 0;
uLipe 0:30211b394890 244 arg_ptr = 0;
uLipe 0:30211b394890 245
uLipe 0:30211b394890 246 //pc_serial.printf("## command: %s \n\r", cmd);
uLipe 0:30211b394890 247 //pc_serial.printf("## arguments: %s \n\r", command_buffer);
uLipe 0:30211b394890 248
uLipe 0:30211b394890 249
uLipe 0:30211b394890 250 /* extract the further arguments */
uLipe 0:30211b394890 251 while(arg_ptr < (cmd_size)) {
uLipe 0:30211b394890 252
uLipe 0:30211b394890 253 argc++;
uLipe 0:30211b394890 254 *(argv + (argc- 1)) = &command_buffer[arg_ptr];
uLipe 0:30211b394890 255
uLipe 0:30211b394890 256 /* find terminator */
uLipe 0:30211b394890 257 while(command_buffer[arg_ptr] != ' ') {
uLipe 0:30211b394890 258 arg_ptr++;
uLipe 0:30211b394890 259 }
uLipe 0:30211b394890 260
uLipe 0:30211b394890 261 /* adds to argument list */
uLipe 0:30211b394890 262 command_buffer[arg_ptr] = 0;
uLipe 0:30211b394890 263 arg_ptr++;
uLipe 0:30211b394890 264 // pc_serial.printf("## argument no: %d : %s \n\r", argc, argv[argc-1]);
uLipe 0:30211b394890 265 }
uLipe 0:30211b394890 266
uLipe 0:30211b394890 267
uLipe 0:30211b394890 268
uLipe 0:30211b394890 269 /* finds and execute the command table */
uLipe 0:30211b394890 270 }
uLipe 0:30211b394890 271
uLipe 0:30211b394890 272
uLipe 0:30211b394890 273
uLipe 0:30211b394890 274
uLipe 0:30211b394890 275 /**
uLipe 0:30211b394890 276 * @brief shell commands processing thread
uLipe 0:30211b394890 277 */
uLipe 0:30211b394890 278 static void shell_task(void)
uLipe 0:30211b394890 279 {
uLipe 0:30211b394890 280 char serial_buffer[1024] = {0};
uLipe 0:30211b394890 281 int read_ptr = 0;
uLipe 0:30211b394890 282 const char msg[] = {"Welcome to NXP FTF !\0"};
uLipe 0:30211b394890 283
uLipe 0:30211b394890 284 /* setup the serial as 115200 bps */
uLipe 0:30211b394890 285 pc_serial.baud(115200);
uLipe 0:30211b394890 286
uLipe 0:30211b394890 287 /* setup our on-board glcd */
uLipe 0:30211b394890 288 glcd.set_contrast(0x35);
uLipe 0:30211b394890 289 glcd.cls();
uLipe 0:30211b394890 290
uLipe 0:30211b394890 291 /* Center the LCD cursor based on message size*/
uLipe 0:30211b394890 292 glcd.locate(LCD_WIDTH - (sizeof(msg) * FONT_WIDTH),
uLipe 0:30211b394890 293 (LCD_HEIGHT - FONT_HEIGHT) / 2);
uLipe 0:30211b394890 294
uLipe 0:30211b394890 295
uLipe 0:30211b394890 296 /* prints a welcome message */
uLipe 0:30211b394890 297 glcd.printf(msg);
uLipe 0:30211b394890 298
uLipe 0:30211b394890 299 glcd.cls();
uLipe 0:30211b394890 300 Thread::wait(1000);
uLipe 0:30211b394890 301
uLipe 0:30211b394890 302
uLipe 0:30211b394890 303 pc_serial.printf("******************************************************************\n\r");
uLipe 0:30211b394890 304 pc_serial.printf("*** Welcome to NXP FTF Simple Shell application ****\n\r");
uLipe 0:30211b394890 305 pc_serial.printf("*** Type some commands or just Enter key to see the available ****\n\r");
uLipe 0:30211b394890 306 pc_serial.printf("******************************************************************\n\r");
uLipe 0:30211b394890 307 pc_serial.printf(">>");
uLipe 0:30211b394890 308
uLipe 0:30211b394890 309 for(;;Thread::wait(50)) {
uLipe 0:30211b394890 310 /* check if we have character available */
uLipe 0:30211b394890 311 if(pc_serial.readable()) {
uLipe 0:30211b394890 312 bool new_cmd = false;
uLipe 0:30211b394890 313
uLipe 0:30211b394890 314 /* get the incoming character */
uLipe 0:30211b394890 315 char c = pc_serial.getc();
uLipe 0:30211b394890 316
uLipe 0:30211b394890 317 if( (c == '\n') || (c == '\r')) {
uLipe 0:30211b394890 318 /* handle enter key */
uLipe 0:30211b394890 319 new_cmd = true;
uLipe 0:30211b394890 320 pc_serial.printf("\n\r");
uLipe 0:30211b394890 321
uLipe 0:30211b394890 322 }else if( (c == 0x7F) || (c == 0x08)){
uLipe 0:30211b394890 323 /* handle backspace and del keys */
uLipe 0:30211b394890 324 pc_serial.printf("\033[1D");
uLipe 0:30211b394890 325 pc_serial.putc(' ');
uLipe 0:30211b394890 326 pc_serial.printf("\033[1D");
uLipe 0:30211b394890 327
uLipe 0:30211b394890 328 read_ptr--;
uLipe 0:30211b394890 329 if(read_ptr < -1) read_ptr = 1023;
uLipe 0:30211b394890 330 serial_buffer[read_ptr] = ' ';
uLipe 0:30211b394890 331
uLipe 0:30211b394890 332
uLipe 0:30211b394890 333 } else {
uLipe 0:30211b394890 334 /* loopback the pressed key */
uLipe 0:30211b394890 335 pc_serial.putc(c);
uLipe 0:30211b394890 336
uLipe 0:30211b394890 337 /* store the incoming character on command circular buffer */
uLipe 0:30211b394890 338 serial_buffer[read_ptr] = c;
uLipe 0:30211b394890 339 read_ptr = (read_ptr + 1) % 1024;
uLipe 0:30211b394890 340 }
uLipe 0:30211b394890 341
uLipe 0:30211b394890 342
uLipe 0:30211b394890 343
uLipe 0:30211b394890 344 if(new_cmd != false) {
uLipe 0:30211b394890 345 /* command arrived, has other characters? */
uLipe 0:30211b394890 346 if(read_ptr != 0) {
uLipe 0:30211b394890 347 shell_parser(&serial_buffer[0], read_ptr);
uLipe 0:30211b394890 348 } else {
uLipe 0:30211b394890 349 print_usage();
uLipe 0:30211b394890 350 }
uLipe 0:30211b394890 351 /* reset the buffer command */
uLipe 0:30211b394890 352 memset(&serial_buffer, 0, sizeof(serial_buffer));
uLipe 0:30211b394890 353 read_ptr = 0;
uLipe 0:30211b394890 354 pc_serial.printf(">>");
uLipe 0:30211b394890 355 }
uLipe 0:30211b394890 356
uLipe 0:30211b394890 357 }
uLipe 0:30211b394890 358 }
uLipe 0:30211b394890 359 }
uLipe 0:30211b394890 360
uLipe 0:30211b394890 361 /**
uLipe 0:30211b394890 362 * @brief main application loop
uLipe 0:30211b394890 363 */
uLipe 0:30211b394890 364 int main(void)
uLipe 0:30211b394890 365 {
uLipe 0:30211b394890 366
uLipe 0:30211b394890 367 glcd.cls();
uLipe 0:30211b394890 368
uLipe 0:30211b394890 369 /* starts the shell task and applications task*/
uLipe 0:30211b394890 370 shell_thread.start(shell_task);
uLipe 0:30211b394890 371 acc_thread.start(acc_task);
uLipe 0:30211b394890 372 lcd_thread.start(lcd_task);
uLipe 0:30211b394890 373 align_thread.start(align_event_task);
uLipe 0:30211b394890 374
uLipe 0:30211b394890 375 return 0;
uLipe 0:30211b394890 376 }