/*============================================================================ MBED_MAX21105_2IMU_Burst Read data from 2 MAX21105 IMU Data return by serial command in burst mode Visarute Pinrod SonicMEMS Laboratory, ECE, Cornell University, Ithaca, NY, USA Novemver 16, 2015 ============================================================================*/

Dependencies:   mbed

Revision:
0:ee6b1953c19a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Jan 25 03:44:30 2016 +0000
@@ -0,0 +1,455 @@
+/*============================================================================
+ MBED_MAX21105_2IMU_Burst
+ Read data from 2 MAX21105 IMU 
+ Data return by serial command in burst mode
+ Visarute Pinrod
+ SonicMEMS Laboratory, ECE, Cornell University, Ithaca, NY, USA
+Novemver 16, 2015 
+============================================================================*/
+
+// Import library
+#include "mbed.h"
+#include "SPI.h"
+#include "DigitalOut.h"
+
+// Define pinout
+SPI spi1(p5, p6, p7);           //mosi, miso, sck
+SPI spi2(p11, p12, p13);           //mosi, miso, sck
+DigitalOut cs_MAX21105(p8);     //cs for MAX21105 6Dof IMU
+DigitalOut cs_MAX21105_2(p9);     //cs for MAX21105 6Dof IMU
+DigitalOut cs_MCP4921(p14);      //cs for MCP4921 DAC for heater
+DigitalOut cs_TSYS01st(p15);    //cs for TSYS01 Temperature sensor for stage
+
+
+// Object
+Serial pc(USBTX, USBRX); // tx, rx
+Timer t;
+
+// get value from command format
+int getVal(char *cmd){
+    int val=-1;
+    char valC[4];
+    valC[0]=cmd[3];
+    valC[1]=cmd[4];
+    valC[2]=cmd[5];
+    valC[3]=cmd[6];
+    sscanf(valC,"%4x",&val);
+    return val;
+}
+
+// Start SPI connection
+void startSPI(){
+    spi1.format(8,3);
+    spi1.frequency(1000000);
+    spi2.format(8,3);
+    spi2.frequency(1000000);
+    cs_MAX21105 = 1;
+    cs_MAX21105_2 = 1;
+    cs_MCP4921 = 1;
+    cs_TSYS01st = 1;
+}
+
+// SPI write data to MAX21105
+void writeMAX21105(char addr, char value){
+    cs_MAX21105 = 0;
+    spi1.write(addr); // MAX21100 Writing scheme
+    spi1.write(value); // MAX21100 Writing scheme
+    cs_MAX21105 = 1;
+}
+
+// SPI read and return 8 bits data to MBED
+char readMAX21105(char addr){
+    char buf_u8;
+    cs_MAX21105 = 0;
+    spi1.write(0x80|addr); // MAX21100 Reading scheme
+    buf_u8 = spi1.write(0x0); // MAX21100 Reading scheme
+    cs_MAX21105 = 1;
+    return(buf_u8);
+}
+
+// SPI write data to MAX21105
+void writeMAX21105_2(char addr, char value){
+    cs_MAX21105_2 = 0;
+    spi2.write(addr); // MAX21100 Writing scheme
+    spi2.write(value); // MAX21100 Writing scheme
+    cs_MAX21105_2 = 1;
+}
+
+// SPI read and return 8 bits data to MBED
+char readMAX21105_2(char addr){
+    char buf_u8;
+    cs_MAX21105_2 = 0;
+    spi2.write(0x80|addr); // MAX21100 Reading scheme
+    buf_u8 = spi2.write(0x0); // MAX21100 Reading scheme
+    cs_MAX21105_2 = 1;
+    return(buf_u8);
+}
+
+void startMAX21105(){
+    // Check MAX21105 conditions
+    char whoami = readMAX21105(0x20); // WHOAMI register
+    char buf = readMAX21105(0x21); // SILICON_REV_OTP register
+   
+    // Set MAX21105 options
+    writeMAX21105(0x00, 0x00);  // SET_PWR 0x00 - Power down,
+    writeMAX21105(0x01, 0x03);  // SNS_CFG_1 0x03 - LPF = 2kHz, SNS_DOUT_FSC=125 dps
+    writeMAX21105(0x02, 0x22);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=2000Hz
+ //   writeMAX21105(0x02, 0x25); // SNS_CFG_2 0x25 - sns_gyr_ois_lpf=on, sns_odr=200Hz
+//    writeMAX21105(0x02, 0x06); // SNS_CFG_2 0x06 - sns_odr=100Hz
+    writeMAX21105(0x03, 0x00); // SNS_CFG_3 0x00 - sns_hpf_co = 0.08 Hz
+    writeMAX21105(0x04, 0xC0); // SET_ACC_PWR 0xC0 - sns_acc_fsc=2g
+    writeMAX21105(0x05, 0x30); // ACC_CFG1 0x30 acc_odr = 2000 Hz
+ //   writeMAX21105(0x05, 0x33); // ACC_CFG1 0x33 acc_odr = 200 Hz
+ //   writeMAX21105(0x05, 0x01); // ACC_CFG1 0x01 - acc_odr = 800 Hz
+    writeMAX21105(0x06, 0x01); // ACC_CFG2 0x01 Unfiltered
+    writeMAX21105(0x00, 0x78); // POWER_CFG 0x78 - accelero,gyro low noise 
+    
+    writeMAX21105(0x13, 0x01); // SET_TEMP_DR 0x01 - enable temp, fine, dataready all
+    writeMAX21105(0x00, 0x78); // POWER_CFG 0x78 - accelero,gyro low noise 
+    
+    pc.printf("[IMU_INITIAL_ST]");
+    pc.printf("WHOAMI = 0x%X (MAX21105: B4)", whoami); //WhoAmI MAX21105 = B4
+    pc.printf("REVISION_ID = 0x%X", buf); // Should be 0x00
+    pc.printf("[IMU_INITIAL_ED]\n");
+}
+
+
+void startMAX21105_2(){
+    // Check MAX21105 conditions
+    char whoami = readMAX21105_2(0x20); // WHOAMI register
+    whoami = readMAX21105_2(0x20);
+    char buf = readMAX21105_2(0x21); // SILICON_REV_OTP register
+    
+    // Set MAX21105 options
+    writeMAX21105_2(0x00, 0x00);  // SET_PWR 0x00 - Power down,
+    writeMAX21105_2(0x01, 0x03);  // SNS_CFG_1 0x03 - LPF = 2kHz, SNS_DOUT_FSC=125 dps
+    writeMAX21105_2(0x02, 0x22);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=2000Hz
+    writeMAX21105_2(0x03, 0x00); // SNS_CFG_3 0x00 - sns_hpf_co = 0.08 Hz
+    writeMAX21105_2(0x04, 0xC0); // SET_ACC_PWR 0xC0 - sns_acc_fsc=2g
+    writeMAX21105_2(0x05, 0x30); // ACC_CFG1 0x30 acc_odr = 2000 Hz
+    writeMAX21105_2(0x06, 0x01); // ACC_CFG2 0x01 Unfiltered
+    writeMAX21105_2(0x00, 0x78); // POWER_CFG 0x78 - accelero,gyro low noise 
+    writeMAX21105_2(0x13, 0x01); // SET_TEMP_DR 0x01 - enable temp, fine, dataready all
+    writeMAX21105_2(0x00, 0x78); // POWER_CFG 0x78 - accelero,gyro low noise 
+    
+    pc.printf("[IMU_INITIAL_ST]");
+    pc.printf("WHOAMI = 0x%X (MAX21105: B4)", whoami); //WhoAmI MAX21105 = B4
+    pc.printf("REVISION_ID = 0x%X", buf); // Should be 0x00
+    pc.printf("[IMU_INITIAL_ED]\n");
+}
+
+// Read 6 axis data
+// See MAX21105 User guide for address and bit field description
+void readMAX21105All(char *imuBuf,short imuCnt){
+    // Variables for data from IMU
+    char con; // IMU status
+    short i;  // Data point measurement loop variable
+    int time;
+    // Wait for connection and return data
+    t.start();
+    t.reset();
+    for(i=0;i<imuCnt;i++) {
+        while ((con = readMAX21105(0x23))==0); // wait until DATA_READY
+        imuBuf[0+18*i] = con;
+        imuBuf[1+18*i] = readMAX21105(0x24); // wX_H MSB Angular speed  X
+        imuBuf[2+18*i] = readMAX21105(0x25); // wX_L LSB Angular speed  X
+        imuBuf[3+18*i] = readMAX21105(0x26); // wY_H MSB Angular speed  Y
+        imuBuf[4+18*i] = readMAX21105(0x27); // wY_L LSB Angular speed  Y
+        imuBuf[5+18*i] = readMAX21105(0x28); // wZ_H MSB Angular speed  Z
+        imuBuf[6+18*i] = readMAX21105(0x29); // wZ_L LSB Angular speed  Z
+        
+        imuBuf[7+18*i] = readMAX21105(0x2A); // aX_H MSB Acceleration  X
+        imuBuf[8+18*i] = readMAX21105(0x2B); // aX_L LSB Acceleration  X
+        imuBuf[9+18*i] = readMAX21105(0x2C); //aY_H MSB Acceleration  Y
+        imuBuf[10+18*i] = readMAX21105(0x2D); //aY_L LSB Acceleration  Y
+        imuBuf[11+18*i] = readMAX21105(0x2E); //aZ_H MSB Acceleration  Z
+        imuBuf[12+18*i] = readMAX21105(0x2F); //aZ_L LSB Acceleration  Z
+        imuBuf[13+18*i] = readMAX21105(0x30); //TEMP_H MSB Temperature
+        imuBuf[14+18*i] = readMAX21105(0x31); //TEMP_L LSB Temperature
+        time=t.read_us();
+        imuBuf[15+18*i] = (char)(time>>16&0xFF); //TEMP_L LSB Temperature
+        imuBuf[16+18*i] = (char)(time>>8&0xFF); //TEMP_L LSB Temperature
+        imuBuf[17+18*i] = (char)(time&0xFF); //TEMP_L LSB Temperature
+    }
+    t.stop();
+}
+
+// Send all axis data to PC
+void sendPCAll(char *imuBuf,short imuCnt){
+    pc.printf("[IMU_READALL_ST]");
+    // Variables for data from IMU
+    char con; // IMU status
+    short i;  // Data point measurement loop variable
+    
+    uint8_t wX_H, wX_L, wY_H, wY_L, wZ_H, wZ_L; // Angular speed MSB&LSB x,y,z
+    uint8_t aX_H, aX_L, aY_H, aY_L, aZ_H, aZ_L; // Acceleration  MSB&LSB x,y,z
+    uint8_t temp_H, temp_L;
+    uint8_t time_H, time_M, time_L;
+    uint16_t wx, wy, wz, ax, ay, az, temp; // Full angular speed & acceleration
+    int time;
+    
+    // Wait for connection and return data
+    for(i=0;i<imuCnt;i++) {
+        con=imuBuf[0+18*i];
+        wX_H = imuBuf[1+18*i]; // MSB Angular speed  X
+        wX_L = imuBuf[2+18*i]; // LSB Angular speed  X
+        wY_H = imuBuf[3+18*i]; // MSB Angular speed  Y
+        wY_L = imuBuf[4+18*i]; // LSB Angular speed  Y
+        wZ_H = imuBuf[5+18*i]; // MSB Angular speed  Z
+        wZ_L = imuBuf[6+18*i]; // LSB Angular speed  Z
+        
+        aX_H = imuBuf[7+18*i]; // MSB Acceleration  X
+        aX_L = imuBuf[8+18*i]; // LSB Acceleration  X
+        aY_H = imuBuf[9+18*i]; // MSB Acceleration  Y
+        aY_L = imuBuf[10+18*i]; // LSB Acceleration  Y
+        aZ_H = imuBuf[11+18*i]; // MSB Acceleration  Z
+        aZ_L = imuBuf[12+18*i]; // LSB Acceleration  Z
+        
+        temp_H = imuBuf[13+18*i]; // MSB Temperature
+        temp_L = imuBuf[14+18*i]; // LSB Temperature
+        
+        time_H = imuBuf[15+18*i]; // MSB Time
+        time_M = imuBuf[16+18*i]; // middle Time
+        time_L = imuBuf[17+18*i]; // LSB Time
+
+        // Stack MSB and LSB together and send out thru serialPC
+        wx = (uint16_t)((uint16_t)wX_H<<8|(wX_L));
+        wy = (uint16_t)((uint16_t)wY_H<<8|(wY_L));
+        wz = (uint16_t)((uint16_t)wZ_H<<8|(wZ_L));
+        ax = (uint16_t)((uint16_t)aX_H<<8|(aX_L));
+        ay = (uint16_t)((uint16_t)aY_H<<8|(aY_L));
+        az = (uint16_t)((uint16_t)aZ_H<<8|(aZ_L));
+        temp = (uint16_t)((uint16_t)temp_H<<8|(temp_L));
+        time = (int)((int)time_H<<16|(int)time_M<<8|(time_L));
+        pc.printf("ST%01X%04X%04X%04X%04X%04X%04X%04X%06XED",
+            con, wx, wy, wz, ax, ay, az,temp,time); 
+    }
+    pc.printf("[IMU_READALL_ED]");
+}
+
+void burstGMAX21105(){
+    writeMAX21105(0x02, 0x24);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=2000Hz
+    writeMAX21105(0x05, 0x32);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=2000Hz
+    writeMAX21105(0x02, 0x24);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=2000Hz
+    writeMAX21105(0x05, 0x32);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=2000Hz
+    char con; // IMU status
+    char wX_H, wX_L, wY_H, wY_L, wZ_H, wZ_L; // Angular speed MSB&LSB x,y,z
+    char aX_H, aX_L, aY_H, aY_L, aZ_H, aZ_L; // Accel MSB&LSB x,y,z
+    int time;
+    t.start();
+    t.reset();
+    while(1){
+        while ((con = readMAX21105(0x23))==0); // wait until DATA_READY
+        time=t.read_us();
+        wX_H = readMAX21105(0x24); // wX_H MSB Angular speed  X
+        wX_L = readMAX21105(0x25); // wX_L LSB Angular speed  X
+        wY_H = readMAX21105(0x26); // wY_H MSB Angular speed  Y
+        wY_L = readMAX21105(0x27); // wY_L LSB Angular speed  Y
+        wZ_H = readMAX21105(0x28); // wZ_H MSB Angular speed  Z
+        wZ_L = readMAX21105(0x29); // wZ_L LSB Angular speed  Z
+        aX_H = readMAX21105(0x2A); // aX_H MSB Acceleration  X
+        aX_L = readMAX21105(0x2B); // aX_L LSB Acceleration  X
+        aY_H = readMAX21105(0x2C); //aY_H MSB Acceleration  Y
+        aY_L = readMAX21105(0x2D); //aY_L LSB Acceleration  Y
+        aZ_H = readMAX21105(0x2E); //aZ_H MSB Acceleration  Z
+        aZ_L = readMAX21105(0x2F); //aZ_L LSB Acceleration  Z
+        pc.printf("ST%01X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%08XED\n",con,wX_H,wX_L,wY_H,wY_L,wZ_H,wZ_L,aX_H,aX_L,aY_H,aY_L,aZ_H,aZ_L,time);
+    }
+    t.stop();
+}
+
+void burstMAX21105_2(){
+    writeMAX21105(0x02, 0x24);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=400Hz
+    writeMAX21105(0x05, 0x32);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=400Hz
+    writeMAX21105(0x02, 0x24);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=400Hz
+    writeMAX21105(0x05, 0x32);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=400Hz
+    writeMAX21105_2(0x02, 0x24);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=400Hz
+    writeMAX21105_2(0x05, 0x32);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=400Hz
+    writeMAX21105_2(0x02, 0x24);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=400Hz
+    writeMAX21105_2(0x05, 0x32);  // SNS_CFG_2 0x22 - sns_gyr_ois_lpf=on, sns_odr=400Hz
+    
+    char con; // IMU status
+    char wX_H, wX_L, wY_H, wY_L, wZ_H, wZ_L; // Angular speed MSB&LSB x,y,z
+    char aX_H, aX_L, aY_H, aY_L, aZ_H, aZ_L; // Accel MSB&LSB x,y,z
+    int time;
+    t.start();
+    t.reset();
+    while(1){
+        con = readMAX21105(0x23);
+        if(con!=0){ // wait until DATA_READY
+        time=t.read_us();
+        wX_H = readMAX21105(0x24); // wX_H MSB Angular speed  X
+        wX_L = readMAX21105(0x25); // wX_L LSB Angular speed  X
+        wY_H = readMAX21105(0x26); // wY_H MSB Angular speed  Y
+        wY_L = readMAX21105(0x27); // wY_L LSB Angular speed  Y
+        wZ_H = readMAX21105(0x28); // wZ_H MSB Angular speed  Z
+        wZ_L = readMAX21105(0x29); // wZ_L LSB Angular speed  Z
+        aX_H = readMAX21105(0x2A); // aX_H MSB Acceleration  X
+        aX_L = readMAX21105(0x2B); // aX_L LSB Acceleration  X
+        aY_H = readMAX21105(0x2C); //aY_H MSB Acceleration  Y
+        aY_L = readMAX21105(0x2D); //aY_L LSB Acceleration  Y
+        aZ_H = readMAX21105(0x2E); //aZ_H MSB Acceleration  Z
+        aZ_L = readMAX21105(0x2F); //aZ_L LSB Acceleration  Z
+        pc.printf("ST1%01X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%08XED\n",con,wX_H,wX_L,wY_H,wY_L,wZ_H,wZ_L,aX_H,aX_L,aY_H,aY_L,aZ_H,aZ_L,time);
+        }
+        
+        con = readMAX21105_2(0x23);
+        if(con!=0){ // wait until DATA_READY
+        time=t.read_us();
+        wX_H = readMAX21105_2(0x24); // wX_H MSB Angular speed  X
+        wX_L = readMAX21105_2(0x25); // wX_L LSB Angular speed  X
+        wY_H = readMAX21105_2(0x26); // wY_H MSB Angular speed  Y
+        wY_L = readMAX21105_2(0x27); // wY_L LSB Angular speed  Y
+        wZ_H = readMAX21105_2(0x28); // wZ_H MSB Angular speed  Z
+        wZ_L = readMAX21105_2(0x29); // wZ_L LSB Angular speed  Z
+        aX_H = readMAX21105_2(0x2A); // aX_H MSB Acceleration  X
+        aX_L = readMAX21105_2(0x2B); // aX_L LSB Acceleration  X
+        aY_H = readMAX21105_2(0x2C); //aY_H MSB Acceleration  Y
+        aY_L = readMAX21105_2(0x2D); //aY_L LSB Acceleration  Y
+        aZ_H = readMAX21105_2(0x2E); //aZ_H MSB Acceleration  Z
+        aZ_L = readMAX21105_2(0x2F); //aZ_L LSB Acceleration  Z
+        pc.printf("ST2%01X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%08XED\n",con,wX_H,wX_L,wY_H,wY_L,wZ_H,wZ_L,aX_H,aX_L,aY_H,aY_L,aZ_H,aZ_L,time);
+        }
+
+    }
+    t.stop();
+}
+
+void setMCP4921(int val){
+    cs_MCP4921 = 0;         // Select the device by seting chip select low
+    spi1.write(0x70|(0xF&(val>>8)));// Set MCP4921 value. 0x7000 prefix
+    spi1.write(0xFF&val);   // Set MCP4921 value. 0x7000 prefix
+    cs_MCP4921 = 1;         // Deselect the device
+}
+
+void startTSYS01st(){
+    // Select the device by seting chip select low
+    cs_TSYS01st = 0;
+    spi1.write(0x1E); // Reset
+    cs_TSYS01st=1;
+    wait(0.1); //2.8 ms reload
+    
+    uint8_t kH, kL, kA[8];
+    char i;
+    
+    kA[0]=0xAA;
+    kA[1]=0xA8;
+    kA[2]=0xA6;
+    kA[3]=0xA4;
+    kA[4]=0xA2;
+    kA[5]=0xAC;
+    kA[6]=0xAE;
+    kA[7]=0xA0;
+    pc.printf("[TEMPS_COEFF_ST]");
+    for(i=0;i<8;i++){
+        cs_TSYS01st = 0;
+        spi1.write(kA[i]); // k0 read
+        kH=spi1.write(0x00); // k0_MSB
+        kL=spi1.write(0x00); // k0_LSB
+        pc.printf("%02X%02X",kH,kL);
+        cs_TSYS01st = 1;
+    }
+    pc.printf("[TEMPS_COEFF_ED]");
+}
+
+void readTSYS01st(){
+    uint8_t t[3];
+    cs_TSYS01st = 0;
+    spi1.write(0x48); // k0 read
+    wait(0.1);
+    cs_TSYS01st = 1;
+    
+    cs_TSYS01st = 0;
+    spi1.write(0x00); // k0 read
+    t[0]=spi1.write(0x00); // k0 read
+    t[1]=spi1.write(0x00); // k0 read
+    t[2]=spi1.write(0x00); // k0 read
+    cs_TSYS01st = 1;
+    pc.printf("[TEMPS_VALUE_ST]");
+    pc.printf("%02X%02X%02X",t[0],t[1],t[2]);
+    pc.printf("[TEMPS_VALUE_ED]");
+}
+
+// Start connection
+void initialization(){
+    //pc.baud(921600);
+    pc.baud(460800);
+    
+    startSPI(); // Start SPI connection 
+    startMAX21105();  // Connect to MAX21105
+    startMAX21105_2();
+}
+
+int main(){
+    // Variable for main function
+    char buf[16];       // Buffer for the command from PC
+    char imuBuf[28800]; // Buffer for IMU output
+    short imuCnt=1600;  // # of Point read from imu
+    int val;          // Value from command
+    
+    // Start system
+    initialization();
+    // Infinite loop: listen to serial command
+    while(1) {
+        if (pc.readable()) {
+            //Command format: Start Mode Submode VALUe enD   S F F FFFF D
+            pc.gets(buf, 16);
+            //pc.printf("Get buf: %s\n",buf);
+            if ((buf[0] == 'S')&&(buf[7] == 'D')) {
+                //Mode switch
+                switch(buf[1]) { 
+                //read all axis mode
+                case 'r': 
+                    // Submode switch
+                    switch(buf[2]) { 
+                    case 'a':
+                        readMAX21105All(imuBuf,imuCnt);
+                        sendPCAll(imuBuf,imuCnt);
+                        pc.printf("\n");
+                        break;
+                    case 'm':
+                        readMAX21105All(imuBuf,imuCnt);
+                        sendPCAll(imuBuf,imuCnt);
+                        readTSYS01st();
+                        pc.printf("\n");
+                        break;
+                    case 'b':
+                        burstGMAX21105();
+                        break;
+                    case '2':
+                        burstMAX21105_2();
+                        break;
+                    default:
+                        break;
+                    }
+                //stage temperature
+                case 's': 
+                    // Submode switch
+                    switch(buf[2]) { 
+                    case 's':
+                        startTSYS01st();
+                        pc.printf("\n");
+                        break;
+                    case 'r':
+                        readTSYS01st();
+                        pc.printf("\n");
+                        break;
+                    default:
+                        break;
+                    }
+                    break;
+                //set heater
+                case 'h': 
+                    val = getVal(buf);
+                    if(val!=-1){
+                        setMCP4921(val);
+                    }                  
+                    break;
+                default:
+                    break;
+                }
+            }
+        }     
+    }
+    return 0;
+}
\ No newline at end of file