www.gusucode.com > Arduino_Engineering_Kit_Hardware_Support 工具箱matlab源码程序 > Arduino_Engineering_Kit_Hardware_Support/simulink/+codertarget/+arduinobase/+internal/arduinoBNO055.m

    classdef arduinoBNO055 < matlab.System & ...
                          matlab.system.mixin.Propagates & ...
                          coder.ExternalDependency & ...
                          matlabshared.svd.BlockSampleTime & ...
                          matlab.system.mixin.internal.CustomIcon
    %BNO055 IMU sensor.
    %
    % <a href="https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST_BNO055_DS000_14.pdf ">Device Datasheet</a>
    
    % Copyright 2018 The MathWorks, Inc.
    %#codegen
      
    properties(Nontunable)
        %SlaveAddress - I2C address
        SlaveAddress = '0x28';
        %OperationMode - Operation mode
        OperationMode = 'Fusion'; 
        %SlaveAddress_ (Not used. Only for compatibilty with I2C blocks)
        SlaveAddress_ = hex2dec('28');
    end
    
    properties(Nontunable, Logical)    
     %Acceleration (m/s^2)
     Accel   
     %Angular rate (dps)
     AngularRate
     %Magnetic field (uT)
     MagField
     %Euler angles (degrees)
     EulerAngles
     %Quaternion (quaternion)
     Quat
     %Linear Acceleration (m/s^2)
     LinearAccel
     %Gravity Vector (m/s^2)
     GravityVector
    end
        
    properties(Nontunable)
        % Accelerometer range
        AccelRange = '4G';
        % Accelerometer bandwidth
        AccelBW = '62.5 Hz';
        % Gyroscope range
        GyroRange = '2000 dps';
        % Gyroscope bandwidth
        GyroBW = '32 Hz';
        % Magnetic output data range
        MagODR = '10 Hz';
    end
    
    properties (Access = private,Logical)        
        %isBNOcorrect
        isBNOcorrect = false;
    end
    
    properties (Dependent,Hidden)                
        % Get corresponding number for selected range, bandwidth, ODR
        AccelRangeNum
        AccelBWNum 
        GyroRangeNum 
        GyroBWNum 
        MagODRNum 
    end
    
      
    properties(Constant, Hidden)
        SlaveAddressSet = matlab.system.StringSet({'0x28', '0x29'});
        OperationModeSet = matlab.system.StringSet({'Fusion', 'Non-Fusion'});
        AccelRangeSet    = matlab.system.StringSet({'2G', '4G', '8G', '16G'});
        AccelBWSet       = matlab.system.StringSet({'7.81 Hz', '15.63 Hz', '31.25 Hz', '62.5 Hz', '125 Hz', '250 Hz', '500 Hz', '1000 Hz'}); 
        GyroRangeSet     = matlab.system.StringSet({'125 dps', '250 dps', '500 dps', '1000 dps', '2000 dps'});
        GyroBWSet        = matlab.system.StringSet({'12 Hz', '23 Hz', '32 Hz', '47 Hz', '64 Hz', '116 Hz', '230 Hz', '523 Hz'});
        MagODRSet        = matlab.system.StringSet({'2 Hz', '6 Hz', '8 Hz', '10 Hz', '15 Hz', '20 Hz', '25 Hz' '30 Hz'}); 
        
        %------ Register Access flag ------------------------
        RegisterAddress_flag = 1;
        
        %--------------BNO055 Registers----------------------
        % Register                            Value               Default value        Type 
        BNO055_REGISTER_CHIP_ID             = hex2dec('00');      %00000000             r                        
        BNO055_PAGE_ID_ADDR                 = hex2dec('07');      %00000000             rw
        BNO055_REGISTER_ACC_DATA_X_LSB      = hex2dec('08');      %00000000             r
        BNO055_REGISTER_MAG_DATA_X_LSB      = hex2dec('0E');      %00000000             r
        BNO055_REGISTER_GYR_DATA_X_LSB      = hex2dec('14');      %00000000             r
        BNO055_REGISTER_EUL_DATA_X_LSB      = hex2dec('1A');      %00000000             r        
        BNO055_REGISTER_QUA_DATA_W_LSB      = hex2dec('20');      %00000000             r
        BNO055_REGISTER_LIA_DATA_X_LSB      = hex2dec('28');      %00000000             r
        BNO055_REGISTER_GRV_DATA_X_LSB      = hex2dec('2E');      %00000000             r
        BNO055_REGISTER_CALIB_STAT          = hex2dec('35');      %00000000             r
        BNO055_REGISTER_UNIT_SEL            = hex2dec('3B');      %0xx0x000             rw
        BNO055_REGISTER_OPR_MODE            = hex2dec('3D');      %x???????             rw
        BNO055_REGISTER_PWR_MODE            = hex2dec('3E');      %xxxxxx??             rw
        BNO055_REGISTER_SYS_TRIGGER         = hex2dec('3F');      %000xxxx0             w
        
        % Page 1 registers
        BNO055_REGISTER_ACC_CONFIG          = hex2dec('08');      %00001101             rw
        BNO055_REGISTER_MAG_CONFIG          = hex2dec('09');      %00001011             rw
        BNO055_REGISTER_GYR_CONFIG_0        = hex2dec('0A');      %00111000             rw
        
        %---------BNO055 defines-----------------------------
        BNO055_ID                           = hex2dec('A0');
        INIT_DELAY                          = 600; %ms
        NORMAL_POWER_MODE                   = hex2dec('00');
       
        %--------BNO055 operation modes----------------------
        CONFIGMODE                          = hex2dec('00');
        AMG                                 = hex2dec('07'); % Non-fusion mode
        NDOF                                = hex2dec('0C'); % Fusion mode
    end
      
    methods %constructor
        function obj = arduinoBNO055(varargin)
             %This would allow the code generation to proceed with the
            %p-files in the installed location of the support package.
            coder.allowpcode('plain');
        end
                
        %-------Set the BNO055 address string---------------
        function set.SlaveAddress(obj,value)
            obj.SlaveAddress = value;
        end
        
        %--------Accelerometer settings--------------------
        function val = get.AccelRangeNum(obj)
            switch obj.AccelRange
                case '2G'
                    val = 0;
                case '4G'
                    val = 1;
                case '8G'
                    val = 2;
                case '16G'
                    val = 3;
            end
        end
        
        function val = get.AccelBWNum(obj)
            switch obj.AccelBW
                case '7.81 Hz'
                    val = 0;
                case '15.63 Hz'
                    val = 1;
                case '31.25 Hz'
                    val = 2;
                case '62.5 Hz'
                    val = 3;
                case '125 Hz'
                    val = 4;
                case '250 Hz'
                    val = 5;
                case '500 Hz'
                    val = 6;
                case '1000 Hz'
                    val = 7;
            end
        end
        
        %--------Gyroscope settings--------------------
        function val = get.GyroRangeNum(obj)
            switch obj.GyroRange
                case '125 dps'
                    val = 4;
                case '250 dps'
                    val = 3;
                case '500 dps'
                    val = 2;
                case '1000 dps'
                    val = 1;
                case '2000 dps'
                    val = 0; 
            end
        end
        
        function val = get.GyroBWNum(obj)
            switch obj.GyroBW
                case '12 Hz'
                    val = 5;
                case '23 Hz'
                    val = 4;
                case '32 Hz'
                    val = 7;
                case '47 Hz'
                    val = 3;
                case '64 Hz'
                    val = 6;
                case '116 Hz'
                    val = 2;
                case '230 Hz'
                    val = 1;
                case '523 Hz'
                    val = 0;
            end
        end
        
        %--------Magnetometer settings--------------------
        function val = get.MagODRNum(obj)
            switch obj.MagODR
                case '2 Hz' 
                    val = 0;
                case '6 Hz'
                    val = 1;
                case '8 Hz'
                    val = 2;
                case '10 Hz'
                    val = 3;
                case '15 Hz'
                    val = 4;
                case '20 Hz'
                    val = 5;
                case '25 Hz'
                    val = 6;
                case '30 Hz'
                    val = 7;
            end
        end
    end
    
    methods (Access = protected)        
        % Check the chip ID of BNO055. This ensures BNO055 address is 
        % correct and  connections are fine.
        function ret = check_BNO055_ChipID(obj)
            chip_id = BNO055_ReadRegister(obj, obj.BNO055_REGISTER_CHIP_ID, 1, 'uint8');
            ret =  (chip_id == obj.BNO055_ID);
        end
               
        % BNO055 register write 
        function BNO055_WriteRegister(obj,RegisterAddress,RegisterValue,DataType)
            validateattributes(RegisterAddress,{'numeric'},{'scalar','integer','>=',0,'<=',255},'','RegisterAddress');
            % Get the BNO055 address in numeric
            if strcmp(obj.SlaveAddress, '0x28')
                 BNO055_address = hex2dec('28');
            else
                 BNO055_address = hex2dec('29');
            end  
            % Cast the RegisterValue into specified DataType
            casted_data  =  cast(RegisterValue, DataType);
            % Typecast to uint8 if DataType is different
            if strcmpi('uint8', DataType)
                data_to_write   =  casted_data;
            else
                data_to_write   =  typecast(casted_data, 'uint8');
            end            
            datalength_in_bytes = numel(casted_data) * get_datatype_size(DataType);
            
            if coder.target('Rtw')% done only for code gen
                coder.cinclude('MW_arduinoI2C.h');
                coder.ceval('MW_i2cWriteLoop', uint8(BNO055_address), ...
                    obj.RegisterAddress_flag, RegisterAddress, ...
                    coder.rref(data_to_write), datalength_in_bytes);
            elseif ( coder.target('RtwForRapid') || coder.target('RtwForSfun') )
            end
        end
        
        % BNO055 register read 
        function RegisterValue = BNO055_ReadRegister(obj,RegisterAddress,DataLength,DataType)
            validateattributes(RegisterAddress,{'numeric'},{'scalar','integer','>=',0,'<=',255},'','RegisterAddress');
             % Get the BNO055 address in numeric
            if strcmp(obj.SlaveAddress, '0x28')
                 BNO055_address = hex2dec('28');
            else
                 BNO055_address = hex2dec('29');
            end 
            
            % Allocate raw output
            out_raw = coder.nullcopy(zeros(DataLength, 1, DataType));
            datalength_in_bytes = DataLength * get_datatype_size(DataType);
            if coder.target('Rtw')% done only for code gen
                coder.cinclude('MW_arduinoI2C.h');
                coder.ceval('MW_i2cReadLoop', uint8(BNO055_address),...
                    obj.RegisterAddress_flag, RegisterAddress, uint8(datalength_in_bytes),...
                    coder.wref(out_raw));
            elseif ( coder.target('RtwForRapid') || coder.target('RtwForSfun') )
            end
            % Concatenate received bytes to get  value in specified DataType
            RegisterValue = typecast(out_raw, DataType);
        end
        
        % BNO055 init
        function initSensor(obj)           
           % Init delay 
           delay_in_milliseconds(uint32(obj.INIT_DELAY));
           
           % Check if the BNO055 connection
           obj.isBNOcorrect = check_BNO055_ChipID(obj);
           
           % If BNO is correct then proceed
           if obj.isBNOcorrect
                % Set the operation mode to Config mode
                BNO055_WriteRegister(obj, obj.BNO055_REGISTER_OPR_MODE, obj.CONFIGMODE, 'uint8');
                delay_in_milliseconds(uint32(25));
                % Reset the sensor
                BNO055_WriteRegister(obj, obj.BNO055_REGISTER_SYS_TRIGGER, hex2dec('20'), 'uint8');
                % Wait for boot
                obj.isBNOcorrect = check_BNO055_ChipID(obj);
                while (~obj.isBNOcorrect)
                    delay_in_milliseconds(uint32(10));
                    obj.isBNOcorrect = check_BNO055_ChipID(obj);
                end
                
                delay_in_milliseconds(uint32(50));
                
                % Set power mode to normal
                BNO055_WriteRegister(obj, obj.BNO055_REGISTER_PWR_MODE, obj.NORMAL_POWER_MODE, 'uint8');
                BNO055_WriteRegister(obj, obj.BNO055_REGISTER_SYS_TRIGGER, hex2dec('00'), 'uint8');
                BNO055_WriteRegister(obj, obj.BNO055_PAGE_ID_ADDR, hex2dec('00'), 'uint8');
                delay_in_milliseconds(uint32(10));
                % Set the unit select register to 0x80 for
                % Orientation          - Android format,
                % Temperature unit     - degree celsius,
                % Euler angles unit    - Degrees
                % Gyro unit            - dps
                % Accel unit           - m/s^2
                BNO055_WriteRegister(obj, obj.BNO055_REGISTER_UNIT_SEL, hex2dec('80'), 'uint8');
                % Set desired operation mode
                if strcmp(obj.OperationMode, 'Fusion')
                    operation_mode = obj.NDOF;
                else
                    operation_mode = obj.AMG;
                end
                BNO055_WriteRegister(obj, obj.BNO055_REGISTER_OPR_MODE, operation_mode, 'uint8');
                delay_in_milliseconds(uint32(25));
           else
               return
           end
        end %initSensor               
        
        % Set the sensor config registers
        function BNO055_WriteSensorConfigRegister(obj)
            % Get the current operation mode
            current_opr_mode = BNO055_ReadRegister(obj, obj.BNO055_REGISTER_OPR_MODE, 1, 'uint8');
            
            % Set the operation mode to Config mode
            BNO055_WriteRegister(obj, obj.BNO055_REGISTER_OPR_MODE, obj.CONFIGMODE, 'uint8');
            delay_in_milliseconds(uint32(25));
            
            % Save the selected PAGE_ID then change to PAGE 1
            selected_page = BNO055_ReadRegister(obj, obj.BNO055_PAGE_ID_ADDR, 1, 'uint8');
            BNO055_WriteRegister(obj, obj.BNO055_PAGE_ID_ADDR, hex2dec('01'), 'uint8');
            
            % Value to set for accel config register                                      
            %BNO055_REGISTER_ACC_CONFIG has
            %bits 7:5 - PWR mode (Normal - 000), 4:2 - BW, 1:0 - range
            required_accel_config = bitshift(obj.AccelBWNum, 2, 'uint8') + uint8(obj.AccelRangeNum);            
            BNO055_WriteRegister(obj, obj.BNO055_REGISTER_ACC_CONFIG, required_accel_config, 'uint8');
            % Value to set for mag config register
            %BNO055_REGISTER_MAG_CONFIG has
            %bits 7 - reserved, 6:5 - PWR mode (Normal - 00) 4:3 - OPR mode ( Regular - 01), 2:0 - ODR                               
            required_mag_config = uint8(bin2dec('00001000')) + uint8(obj.MagODRNum);         
            BNO055_WriteRegister(obj, obj.BNO055_REGISTER_MAG_CONFIG, required_mag_config, 'uint8');
            % Value to set for gyro_config0 register
            %BNO055_REGISTER_GYR_CONFIG_0 has
            %bits 7:6 - reserved, 5:3 - BW, 2:0 - range                               
            required_gyro_config = bitshift(obj.GyroBWNum, 3, 'uint8') + uint8(obj.GyroRangeNum);                     
            BNO055_WriteRegister(obj, obj.BNO055_REGISTER_GYR_CONFIG_0, required_gyro_config, 'uint8');
           
            delay_in_milliseconds(uint32(10));
            
            % Restore PAGE_ID and operation mode
            BNO055_WriteRegister(obj, obj.BNO055_PAGE_ID_ADDR, selected_page, 'uint8');
            BNO055_WriteRegister(obj, obj.BNO055_REGISTER_OPR_MODE, current_opr_mode, 'uint8');
            delay_in_milliseconds(uint32(20));
         end %BNO055_WriteSensorConfigRegister
        
         % Read the sensor settings (Can be used to read values from 
         % accel, mag, gyro config registers during debugging).
         function sensor_config_data = BNO055_ReadSensorConfigRegister(obj)
             % Save the selected PAGE_ID then change to PAGE 1
            selected_page = BNO055_ReadRegister(obj, obj.BNO055_PAGE_ID_ADDR, 1, 'uint8');
            BNO055_WriteRegister(obj, obj.BNO055_PAGE_ID_ADDR, hex2dec('01'), 'uint8');
            % Read the config registers values
            sensor_config_data = BNO055_ReadRegister(obj, obj.BNO055_REGISTER_ACC_CONFIG, 3, 'uint8');            
             % Restore PAGE_ID and operation mode
            BNO055_WriteRegister(obj, obj.BNO055_PAGE_ID_ADDR, selected_page, 'uint8');                        
         end
         
        % Read Accelerometer
        function accel_data =  BNO055_ReadAccel(obj)
            RegisterValue = BNO055_ReadRegister(obj, obj.BNO055_REGISTER_ACC_DATA_X_LSB, 3, 'int16');
            accel_data = double(RegisterValue) /100.0;
        end %BNO055_ReadAccel
        
        % Read Magnetometer
        function mag_data =  BNO055_ReadMag(obj)
            RegisterValue = BNO055_ReadRegister(obj, obj.BNO055_REGISTER_MAG_DATA_X_LSB, 3, 'int16');
            mag_data = double(RegisterValue) /16.0;            
        end %BNO055_ReadMag
        
        % Read Gyroscope
        function gyro_data =  BNO055_ReadGyro(obj)
            RegisterValue = BNO055_ReadRegister(obj, obj.BNO055_REGISTER_GYR_DATA_X_LSB, 3, 'int16');
            gyro_data = double(RegisterValue) /16.0; % for degrees per second
        end %BNO055_ReadGyro
        
        % Read Euler angles
        function euler_angles =  BNO055_ReadEulerAngles(obj)
            RegisterValue = BNO055_ReadRegister(obj, obj.BNO055_REGISTER_EUL_DATA_X_LSB, 3, 'int16');
            euler_angles = double(RegisterValue) /16.0;            
        end %BNO055_ReadEulerAngles
        
        % Read Quaternion
        function quaternion =  BNO055_ReadQuaternion(obj)
            RegisterValue = BNO055_ReadRegister(obj, obj.BNO055_REGISTER_QUA_DATA_W_LSB, 4, 'int16');
            quaternion = double(RegisterValue) * (1.0/bitshift(1,14));
        end %BNO055_ReadQuaternion
        
        % Read Linear Acceleration
        function linear_accel =  BNO055_ReadLinearAccel(obj)
            RegisterValue = BNO055_ReadRegister(obj, obj.BNO055_REGISTER_LIA_DATA_X_LSB, 3, 'int16');
            linear_accel = double(RegisterValue)/ 100.0;
        end %BNO055_ReadLinearAccel
        
        % Read Gravity Vector
        function gravity_vector =  BNO055_ReadGravityVector(obj)
            RegisterValue = BNO055_ReadRegister(obj, obj.BNO055_REGISTER_GRV_DATA_X_LSB, 3, 'int16');
            gravity_vector = double(RegisterValue)/ 100.0;
        end %BNO055_ReadGravityVector
        
        % Read Calibration status
        function calibration_status =  BNO055_CalibrationStatus(obj)
            if obj.isBNOcorrect
                RegisterValue = BNO055_ReadRegister(obj, obj.BNO055_REGISTER_CALIB_STAT, 1, 'uint8');
                mag_calib            = int8(bitand(RegisterValue,3,'uint8'));                         %Mag calibration status
                accel_calib          = int8(bitshift(bitand(RegisterValue,12,'uint8'),-2,'uint8'));   %Accel calibration status
                gyro_calib           = int8(bitshift(bitand(RegisterValue,48,'uint8'),-4,'uint8'));   %Gyro calibration status
                sys_calib            = int8(bitshift(bitand(RegisterValue,192,'uint8'),-6,'uint8'));  %System calibration status
                calibration_status   = [sys_calib; gyro_calib; accel_calib; mag_calib;];
            else
                % Output calibration status as -1 when BNO055 connections
                % are wrong or chip ID does not match
                calibration_status = ones(4,1,'int8') * -1; 
            end            
        end %BNO055_CalibrationStatus
        
    end
    
    methods (Access = protected)
        %% Common functions
        function setupImpl(obj)    
            initSensor(obj);
            %Apply the accel, gyro, and mag settings in Non-fusion mode
            if strcmp('Non-Fusion', obj.OperationMode)
                BNO055_WriteSensorConfigRegister(obj);
            end
        end
        
        
        function [varargout] = stepImpl(obj)
            if obj.Accel
             Accel_data             = zeros(3,1,'double');
            end
            if obj.AngularRate
             AngularRate_data       = zeros(3,1,'double');
            end
            if obj.MagField
             MagField_data          = zeros(3,1,'double');
            end
            if strcmp(obj.OperationMode, 'Fusion')
                if obj.EulerAngles
                 EulerAngles_data       = zeros(3,1,'double');
                end
                if obj.Quat
                 Quat_data              = zeros(4,1,'double');
                end
                if obj.LinearAccel
                 LinearAccel_data       = zeros(3,1,'double');
                end
                if obj.GravityVector
                 GravityVector_data     = zeros(3,1,'double');
                end
                CalibStatus_data        = zeros(4,1,'int8');
            end
            

            if obj.Accel
                % Acceleration 3x1 output:
                % 1 - X
                % 2 - Y
                % 3 - Z
               Accel_data = BNO055_ReadAccel(obj);
            end
            if obj.AngularRate
                % Angular rate 3x1 output:
                % 1 - X
                % 2 - Y
                % 3 - Z                    
               AngularRate_data = BNO055_ReadGyro(obj);
            end
            if obj.MagField
                % Magnetic Field 3x1 output:
                % 1 - X
                % 2 - Y
                % 3 - Z                    
               MagField_data = BNO055_ReadMag(obj);
            end
             if strcmp(obj.OperationMode, 'Fusion')
                 if obj.EulerAngles
                    % Euler angles 3x1 output:
                    % 1 - Heading
                    % 2 - Roll
                    % 3 - Pitch
                    EulerAngles_data = BNO055_ReadEulerAngles(obj);
                 end
                 if obj.Quat
                    % Quaternion 4x1 output:
                    % 1 - w
                    % 2 - x
                    % 3 - y
                    % 4 - z
                    Quat_data = BNO055_ReadQuaternion(obj);
                 end
                 if obj.LinearAccel
                    % Linear Acceleration 3x1 output:
                    % 1 - X
                    % 2 - Y
                    % 3 - Z
                    LinearAccel_data = BNO055_ReadLinearAccel(obj);
                 end
                 if obj.GravityVector
                    % Gravity Vector 3x1 output:
                    % 1 - X
                    % 2 - Y
                    % 3 - Z
                    GravityVector_data = BNO055_ReadGravityVector(obj);
                 end

                % Calibration_data 4x1 output order as below:
                % 1 - System calibration
                % 2 - Gyroscope calibration
                % 3 - Accelerometer calibration
                % 4 - Magnetometer calibration
                CalibStatus_data = BNO055_CalibrationStatus(obj); 
             end     
            
            idx = 1;
            if obj.Accel
                varargout{idx} = Accel_data;
                idx = idx + 1;
            end
            if obj.AngularRate
                varargout{idx} = AngularRate_data;
                idx = idx + 1;
            end 
            if obj.MagField
                varargout{idx} = MagField_data;
                idx = idx + 1;
            end 
            if strcmp(obj.OperationMode, 'Fusion')
                if obj.EulerAngles
                    varargout{idx} = EulerAngles_data;
                    idx = idx + 1;
                end 
                if obj.Quat
                    varargout{idx} = Quat_data;
                    idx = idx + 1;
                end 
                if obj.LinearAccel
                    varargout{idx} = LinearAccel_data;
                    idx = idx + 1;
                end 
                if obj.GravityVector
                    varargout{idx} = GravityVector_data;
                    idx = idx + 1;
                end 
                varargout{idx} = CalibStatus_data;
            end
        end
        
        function releaseImpl(~)        
        end
        
        function N = getNumInputsImpl(~)
            % Specify number of System inputs
            N = 0;
        end
        
        function N = getNumOutputsImpl(obj)
            % Specify number of System outputs
            N = 0;     
            if obj.Accel
                N = N + 1;
            end
            if obj.AngularRate
                N = N + 1;
            end 
            if obj.MagField
                N = N + 1;
            end 
            if strcmp(obj.OperationMode, 'Fusion')
                if obj.EulerAngles
                    N = N + 1;
                end 
                if obj.Quat
                    N = N + 1;
                end 
                if obj.LinearAccel
                    N = N + 1;
                end 
                if obj.GravityVector
                    N = N + 1;
                end 
                N = N + 1; % for Calibration status output
            end
        end
        
        function varargout = getOutputNamesImpl(obj)
            % Return output port names for System block
            N = 1;     
            if obj.Accel
                varargout{N} = 'Accel';
                N = N + 1;
            end
            if obj.AngularRate
                varargout{N} = 'Ang rate';
                N = N + 1;
            end 
            if obj.MagField
                varargout{N} = 'Mag field';
                N = N + 1;
            end 
            if strcmp(obj.OperationMode, 'Fusion')
                if obj.EulerAngles
                    varargout{N} = 'Euler';
                    N = N + 1;
                end 
                if obj.Quat
                    varargout{N} = 'Quat';
                    N = N + 1;
                end 
                if obj.LinearAccel
                    varargout{N} = 'Lin accel';
                    N = N + 1;
                end 
                if obj.GravityVector
                    varargout{N} = 'Gravity';
                    N = N + 1;
                end 
                varargout{N} = 'Status';
            end                        
        end %getOutputNamesImpl
        
        function varargout= getOutputSizeImpl(obj)
            % Return size for each output port
            N = 1;     
            if obj.Accel
                varargout{N} = [3 1];
                N = N + 1;
            end
            if obj.AngularRate
                varargout{N} = [3 1];
                N = N + 1;
            end 
            if obj.MagField
                varargout{N} = [3 1];
                N = N + 1;
            end 
            if strcmp(obj.OperationMode, 'Fusion')
                if obj.EulerAngles
                    varargout{N} = [3 1];
                    N = N + 1;
                end 
                if obj.Quat
                    varargout{N} = [4 1];
                    N = N + 1;
                end 
                if obj.LinearAccel
                    varargout{N} = [3 1];
                    N = N + 1;
                end 
                if obj.GravityVector
                    varargout{N} = [3 1];
                    N = N + 1;
                end 
                varargout{N} = [4 1];
            end    
        end
        
        function varargout = getOutputDataTypeImpl(obj)
            N = 1;     
            if obj.Accel
                varargout{N} = 'double';
                N = N + 1;
            end
            if obj.AngularRate
                varargout{N} = 'double';
                N = N + 1;
            end 
            if obj.MagField
                varargout{N} = 'double';
                N = N + 1;
            end 
            if strcmp(obj.OperationMode, 'Fusion')
                if obj.EulerAngles
                    varargout{N} = 'double';
                    N = N + 1;
                end 
                if obj.Quat
                    varargout{N} = 'double';
                    N = N + 1;
                end 
                if obj.LinearAccel
                    varargout{N} = 'double';
                    N = N + 1;
                end 
                if obj.GravityVector
                    varargout{N} = 'double';
                    N = N + 1;
                end 
                varargout{N} = 'int8'; % for Calibration Status
            end    
        end
        
        function varargout  = isOutputComplexImpl(obj)
           for N = 1 : obj.getNumOutputsImpl
               varargout{N} = false;
           end
        end
        
        function varargout   = isOutputFixedSizeImpl(obj)
           for N = 1 : obj.getNumOutputsImpl
               varargout{N} = true;
           end
        end
        
        function st = getSampleTimeImpl(obj)
            st = obj.SampleTime;
        end
        
        function flag = isInactivePropertyImpl(obj,prop)
            % Return false if property is visible based on object 
            % configuration, for the command line and System block dialog
            flag = false;
            if strcmp(prop, 'EulerAngles')
                flag = strcmp(obj.OperationMode, 'Non-Fusion');            
            end
            if strcmp(prop, 'Quat')
                flag = strcmp(obj.OperationMode, 'Non-Fusion');            
            end
            if strcmp(prop, 'LinearAccel')
                flag = strcmp(obj.OperationMode, 'Non-Fusion');            
            end
            if strcmp(prop, 'GravityVector')
                flag = strcmp(obj.OperationMode, 'Non-Fusion');            
            end
            if strcmp(prop, 'AccelRange')
                flag = strcmp(obj.OperationMode, 'Fusion') ;
            end
            if strcmp(prop, 'AccelBW')
                flag = strcmp(obj.OperationMode, 'Fusion');
            end
            if strcmp(prop, 'GyroRange')
                flag = strcmp(obj.OperationMode, 'Fusion');
            end
            if strcmp(prop, 'GyroBW')
                flag = strcmp(obj.OperationMode, 'Fusion'); 
            end
            if strcmp(prop, 'MagODR')
                flag = strcmp(obj.OperationMode, 'Fusion');
            end
        end
        
        function maskDisplayCmds = getMaskDisplayImpl(obj)          
            outport_label = [];
            num = getNumOutputsImpl(obj);
            if num > 0
                outputs = cell(1,num);
                [outputs{1:num}] = getOutputNamesImpl(obj);
                for i = 1:num
                    outport_label = [outport_label 'port_label(''output'',' num2str(i) ',''' outputs{i} ''');' ]; %#ok<AGROW>
                end
            end
            maskDisplayCmds = { ...
                'color(''white'');',...
                'plot([100,100,100,100]*1,[100,100,100,100]*1);',...
                'plot([100,100,100,100]*0,[100,100,100,100]*0);',...
                'color(''blue'');', ...
                'text(99, 92, '' ARDUINO '', ''horizontalAlignment'', ''right'');',   ...
                'color(''black'');', ...
                'sppkgroot = strrep(motorcarrier.internal.getSpPkgRootDir(),''\'',''/'');',...
                'image(fullfile(sppkgroot,''resources'',''imu.png''),''center'')', ...
                outport_label
                };
        end
    end
    
    methods (Static)
        function name = getDescriptiveName(~)
            name = 'BNO055 IMU sensor';
        end
        
        function b = isSupportedContext(context)
            b = context.isCodeGenTarget('rtw');
        end
        
        function updateBuildInfo(buildInfo, context)           
             codertarget.arduinobase.internal.arduinoI2CWrite.updateBuildInfo(buildInfo, context);
             sppkgRoot = motorcarrier.internal.getSpPkgRootDir;  
             % Include Paths
             addIncludePaths(buildInfo, fullfile(sppkgRoot, 'include'));
             addIncludeFiles(buildInfo,'MW_delay_millis.h');
             % Source Files
             systemTargetFile = get_param(buildInfo.ModelName,'SystemTargetFile');
             if isequal(systemTargetFile,'ert.tlc')
                 % Add the following when not in rapid-accel simulation
                 addSourceFiles(buildInfo,'MW_delay_millis.cpp', fullfile(sppkgRoot,'src'),'BlockModules');
             end
        end
    end
    
    methods(Access = protected, Static)
        function simMode = getSimulateUsingImpl
            % Return only allowed simulation mode in System block dialog
            simMode = 'Interpreted execution';
        end
        
        function flag = showSimulateUsingImpl
            % Return false if simulation mode hidden in System block dialog
            flag = false;
        end
        
        function groups = getPropertyGroupsImpl
           SlaveAddressProp = matlab.system.display.internal.Property(...
                'SlaveAddress', 'Description', 'I2C address');
           SlaveAddress_Prop = matlab.system.display.internal.Property(...
                'SlaveAddress_', 'IsGraphical', false);
           OperationModeProp = matlab.system.display.internal.Property(...
                'OperationMode', 'Description', 'Operation mode');
           AccelProp = matlab.system.display.internal.Property(...
                'Accel', 'Description', 'Acceleration (m/s^2)');
           AngularRateProp = matlab.system.display.internal.Property(...
                'AngularRate', 'Description', 'Angular rate (dps)');
           MagFieldProp = matlab.system.display.internal.Property(...
                'MagField', 'Description', 'Magnetic field (uT)');
           EulerAnglesProp = matlab.system.display.internal.Property(...
                'EulerAngles', 'Description', 'Euler angles (degrees)');
           QuatProp = matlab.system.display.internal.Property(...
                'Quat', 'Description', 'Quaternion (quaternion)');
           LinearAccelProp = matlab.system.display.internal.Property(...
                'LinearAccel', 'Description', 'Linear Acceleration (m/s^2)');
           GravityVectorProp = matlab.system.display.internal.Property(...
                'GravityVector', 'Description', 'Gravity Vector (m/s^2)');
           AccelRangeProp = matlab.system.display.internal.Property(...
                'AccelRange', 'Description', 'Accelerometer range');
           AccelBWProp = matlab.system.display.internal.Property(...
                'AccelBW', 'Description', 'Accelerometer bandwidth');
           GyroRangeProp = matlab.system.display.internal.Property(...
                'GyroRange', 'Description', 'Gyroscope range');
           GyroBWProp = matlab.system.display.internal.Property(...
                'GyroBW', 'Description', 'Gyroscope bandwidth');
           MagODRProp = matlab.system.display.internal.Property(...
                'MagODR', 'Description', 'Magnetic output data range');
           SampleTimeProp = matlab.system.display.internal.Property(...
                'SampleTime', 'Description', 'Sample time');
           
           topSettingsGroup = matlab.system.display.Section(...
                'PropertyList',{SlaveAddressProp, OperationModeProp, SlaveAddress_Prop});
            
           outputGroup = matlab.system.display.Section(...
                'Title','Select outputs',...
                'PropertyList',{AccelProp, AngularRateProp, MagFieldProp, ...
                EulerAnglesProp, QuatProp, LinearAccelProp, GravityVectorProp});

           sensorSettingsGroup = matlab.system.display.Section(...
                'Title','Advanced sensor settings (optional)',...
                'PropertyList',{AccelRangeProp, AccelBWProp, GyroRangeProp, ...
                GyroBWProp, MagODRProp});
            
           bottomSettingsGroup = matlab.system.display.Section(...
                'PropertyList',{SampleTimeProp});            
            
           groups = matlab.system.display.SectionGroup(...
               'Title','Parameters',...
                'Sections',[topSettingsGroup, outputGroup, sensorSettingsGroup,bottomSettingsGroup]);

        end %getPropertyGroupsImpl
         
        function header = getHeaderImpl
            %getHeaderImpl Create mask header
            %   This only has an effect on the base mask.
            header = matlab.system.display.Header(mfilename('class'), ...
                'Title', 'BNO055', ...
                'Text', ['Measure acceleration, angular rate, and magnetic field along X, Y, and Z axis and ',...
                'calculate fusion values such as Euler angles, Quaternion, Linear Acceleration, and Gravity Vector.',...
                newline, 'The block outputs all values except for Quaternion and Status output as 3x1 array of ',...
                'double-precision datatype. The Quaternion values are 4x1 array of double-precision while the Status ',...
                'output is 4x1 array of int8 datatype.'], ...
                'ShowSourceLink', false);
        end
        
    end % methods(Access = protected, Static)
end %arduinoBNO055

%--------Local functions-----------
% Delay method
function delay_in_milliseconds(time)
   if coder.target('Rtw')% done only for code gen
        coder.cinclude('MW_delay_millis.h');
        coder.ceval('MW_delay_in_milliseconds', uint32(time));
   elseif ( coder.target('RtwForRapid') || coder.target('RtwForSfun') )
       % nothing
   end 
end

% Get datatype size

function out = get_datatype_size(datatype)
    switch datatype
        case {'uint8', 'int8'}
            out = 1;
        case {'uint16', 'int16'}
            out = 2;
    end
end
%--------End of Local functions----