This is a complete listing of the RS-EDP software for the mbed module to support the RS-EDP platform.

Dependencies:   mbed

SourceFiles/RSEDP_Test_MC2.cpp

Committer:
DavidGilesHitex
Date:
2010-11-19
Revision:
0:5b7639d1f2c4

File content as of revision 0:5b7639d1f2c4:

/* Test Menu For I2C Master Mode System Controller */
/* *********************************************** */


/* Include Files Here */
#include "mbed.h"                            /* Header file for mbed module */
#include "misra_types.h"                     /* MISRA Types */
#include "defines.h"                        /* User defines */
#include "RSEDP_Slave_Address_Defines.h"    /* Slave address of I2C Devices defined hhere */

#include "RSEDP_Mbed_Module.h"                /* all the low level peripheral drivers on te mbed module - IO ports, UART, SPI, I2C etc */
#include "RSEDP_Base_Board.h"                /* All the base board functions - EEPROM and erial latch */
#include "RSEDP_Comms_Module.h"                /* Functions to control the real time clock */
#include "RSEDP_Digital_IO_Module.h"        /* All the functions to control the serial input and output latches */
#include "RSEDP_Analogue_Module.h"            /* Functions to control digital pot and serial ADC */
#include "RSEDP_MC1.h"                        /* Brushed DC Motor Drive MC1 Module */


#include "MC2_Motor_Driver_I2C_Master.h"


#define MOTOR_SPEED_DEMAND_FORWARD_MAX 1023u
#define MOTOR_SPEED_DEMAND_FORWARD_MIN 1u
#define MOTOR_SPEED_DEMAND_REVERSE_MAX 1023u
#define MOTOR_SPEED_DEMAND_REVERSE_MIN 1u
#define RAMP_UP_SPEED_MAX 1023u
#define RAMP_UP_SPEED_MIN 1u
#define RAMP_DOWN_SPEED_MAX 1023u
#define RAMP_DOWN_SPEED_MIN 1u


/* Global Function Prototypes here */
void I2C_MMSC_Test_Suite(void);                                                            /* Suites of tests for Master Mode Control */



/* Local Static Function Prototypes Here */
static void i2C_control_submenu(void);
static sint32_t i2C_cs_ping(void);
static sint32_t i2C_cs_reset(void);
static sint32_t i2C_cs_emergency_stop(void);
static sint32_t i2C_cs_normal_stop(void);
static sint32_t i2C_cs_set_new_direction_forward(void);
static sint32_t i2C_cs_set_new_direction_reverse(void);
static sint32_t choose_the_ramp_up_speed(void);
static sint32_t i2C_cs_set_ramp_up_speed(uint16_t rampup);
static sint32_t choose_the_ramp_down_speed(void);
static sint32_t i2C_cs_set_ramp_down_speed(uint16_t rampdown);
static sint32_t choose_the_motor_demand_forward(void);
static sint32_t i2C_cs_set_motor_demand_forward(uint16_t demandforward);
static sint32_t choose_the_motor_demand_reverse(void);
static sint32_t i2C_cs_set_motor_demand_reverse(uint16_t demandreverse);
static sint32_t choose_the_rotary_encoder_counts(void);
static sint32_t i2C_cs_set_rotary_encoder_counts(uint32_t rotary_encoder_counter);
static sint32_t i2C_cs_start_rotation(void);
static sint32_t i2C_cs_goto_home(void);

static sint32_t i2C_cs_read_RPMs(void);
static sint32_t i2C_cs_read_motor_currents(void);
static sint32_t i2C_cs_read_Vbus_voltages(void);
static sint32_t i2C_cs_read_demand_speed_potRPM(void);
static sint32_t i2C_cs_read_hall_sensors(void);
static sint32_t i2C_cs_read_status_flags(void);
static sint32_t i2C_cs_read_Maximum_RPM(void);
static sint32_t i2C_cs_read_Rotary_Encoder(void);


static void i2C_cs_execute_sequence(void);
static uint8_t get_a_number_digit(void);
static uint32_t get_a_complete_number(void);


/* Static Variables available at File Scope */
static uint8_t Slave_Address = DSPIC_SLAVE_ADDRESS_MIN;



/*This funtciton will control the other PIC on the board via I2C command */
void I2C_MMSC_Test_Suite(void)
    {
        uint16_t keypress = 0u;


        Slave_Address = DSPIC_SLAVE_ADDRESS_MIN;                                    /* 7 bit slave address */


        setup_CNTRL_I2C_Master_Mode();                                                    /* Setup the I2C Peripheral for master mode */

        pc.printf("\n\n\n\rI2C Master Mode Controller.\n\r");
        pc.printf("This module will communicate and control the dsPIC I2C Slave devices\n\r");

        do    {
                pc.printf("\n\rChoose the I2C Slave Address you want to control from this device\n\r");
                pc.printf("Press the + and - key to increase and decrease the selection\n\r");
                pc.printf("& then Return to finish.\n\r");
                pc.printf("or Q to quit and return to main menu.\n\r");
                pc.printf("\rNew Value is: %03d",Slave_Address);

                do    {
                        keypress = pc.getc();                                /* Read character from PC keyboard */
                                if ((Slave_Address < DSPIC_SLAVE_ADDRESS_MAX) && (keypress == '+'))
                                    {
                                        Slave_Address++;
                                    }
                                if ((Slave_Address > DSPIC_SLAVE_ADDRESS_MIN) && (keypress == '-'))
                                    {
                                        Slave_Address--;
                                    }


                                pc.printf("\rNew Value is: %03d",Slave_Address);

                    } while ((keypress != 'q') && (keypress != '\r'));

                if (keypress == '\r')
                    {
                        i2C_control_submenu();
                    }

            } while (keypress != 'q');
    }






/* Sub Menu */
static void i2C_control_submenu(void)
    {
        uint8_t temp8 = 0u;
        uint16_t temp16 = 0u;

        do
            {
                pc.printf("\n\n\n\rTest Menu for Slave Address:%d\n\r", Slave_Address, 3u);
                pc.printf("0 - Ping The Slave Address and Test For Acknowledge\n\r");
                pc.printf("1 - RESET the Slave Address MCU\n\r");
                pc.printf("2 - Emergency Stop\n\r");
                pc.printf("3 - Normal Stop\n\r");
                pc.printf("4 - Set New Direction As Forward\n\r");
                pc.printf("5 - Set New Direction As Reverse\n\r");
                pc.printf("6 - Set The Ramp Up Speed\n\r");
                pc.printf("7 - Set The Ramp Down Speed\n\r");
                pc.printf("8 - Set The Maximum Motor Demand Speed Forward/Clockwise\n\r");
                pc.printf("9 - Set The Maximum Motor Demand Speed Backward/Counter Clockwise\n\r");
                pc.printf("a - Set The Number of Rotary Encoder Pulses You Want To move\n\r");
                pc.printf("b - Start The Motor Turning\n\r");
                pc.printf("c - Goto/Locate Home Position\n\r");

                pc.printf("d - Read The Tacho RPM Speeds\n\r");
                pc.printf("e - Read The Motor Currents\n\r");
                pc.printf("f - Read The Vbus Voltages\n\r");
                pc.printf("g - Read The Demand Speed Pot\n\r");
                pc.printf("h - Read The Hall Sensors\n\r");
                pc.printf("i - Read The Motor Status Flags\n\r");
                pc.printf("j - Read The Maximum RPM Speed OF The Motor\n\r");
                pc.printf("k - Read The Rotary Encoder Difference/Overshoot Value\n\r");

                pc.printf("z - Execute A Sequence Of Tests\n\r");

                pc.printf("RETURN - Quit this menu and return to Sub Menu\n\r");

                pc.printf("Please select the test option\n\r");

                temp16 = pc.getc();

                temp8 = (uint8_t) (temp16);

                if (temp8 == '0')
                    {
                        i2C_cs_ping();
                    }
                if (temp8 == '1')
                    {
                        i2C_cs_reset();
                    }
                if (temp8 == '2')
                    {
                        i2C_cs_emergency_stop();
                    }
                if (temp8 == '3')
                    {
                        i2C_cs_normal_stop();
                    }
                if (temp8 == '4')
                    {
                        i2C_cs_set_new_direction_forward();
                    }
                if (temp8 == '5')
                    {
                        i2C_cs_set_new_direction_reverse();
                    }
                if (temp8 == '6')
                    {
                        choose_the_ramp_up_speed();
                    }
                if (temp8 == '7')
                    {
                        choose_the_ramp_down_speed();
                    }
                if (temp8 == '8')
                    {
                        choose_the_motor_demand_forward();
                    }
                if (temp8 == '9')
                    {
                        choose_the_motor_demand_reverse();
                    }
                if (temp8 == 'a')
                    {
                        choose_the_rotary_encoder_counts();
                    }
                if (temp8 == 'b')
                    {
                        i2C_cs_start_rotation();
                    }

                if (temp8 == 'c')
                    {
                        i2C_cs_goto_home();
                    }



                if (temp8 == 'd')
                    {
                        i2C_cs_read_RPMs();
                    }
                if (temp8 == 'e')
                    {
                        i2C_cs_read_motor_currents();
                    }
                if (temp8 == 'f')
                    {
                        i2C_cs_read_Vbus_voltages();
                    }
                if (temp8 == 'g')
                    {
                        i2C_cs_read_demand_speed_potRPM();
                    }
                if (temp8 == 'h')
                    {
                        i2C_cs_read_hall_sensors();
                    }
                if (temp8 == 'i')
                    {
                        i2C_cs_read_status_flags();
                    }
                if (temp8 == 'j')
                    {
                        i2C_cs_read_Maximum_RPM();
                    }
                if (temp8 == 'k')
                    {
                        i2C_cs_read_Rotary_Encoder();
                    }




                if (temp8 == 'z')
                    {
                        i2C_cs_execute_sequence();
                    }

            } while (temp8 != '\r');

        pc.printf("Returning to main menu...\n\r");
    }




/* Ping The I2C Slave Address */
static sint32_t i2C_cs_ping(void)
    {
        sint32_t Ack_Status = 0u;
        uint16_t keypress = 0u;

        pc.printf("\n\rPinging the I2C Slave Address:%d\r\n", Slave_Address, 3u);
        do    {

                Ack_Status = I2C0_dsPIC_Ping(Slave_Address);
                if (Ack_Status != ACK)
                    {
                        pc.printf("NO Acknowledge received\n\r");
                    }
                else{
                        pc.printf("Acknowledge received\n\r");
                    }
                wait(1.0);
                keypress = pc.getc();

            } while ((Ack_Status != ACK) && (keypress != '\r'));                /* Loop until keypress or we get an Ack */
        return Ack_Status;
    }


/* Reset The MCU at the I2C Slave Address */
static sint32_t i2C_cs_reset(void)
    {
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rResetting the target MCU at the I2C Slave Address:%03d\r\n", Slave_Address);

        Ack_Status = I2C0_dsPIC_Reset(Slave_Address);
        return Ack_Status;
    }


/* Emergency Stop */
static sint32_t i2C_cs_emergency_stop(void)
    {
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rEmergency Stop the motor - command sent\n\r");
        Ack_Status = I2C0_dsPIC_Emergency_Stop(Slave_Address);
        return Ack_Status;
    }


/* Normal Stop */
static sint32_t i2C_cs_normal_stop(void)
    {
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rNormal Stop the motor - command sent\n\r");
        Ack_Status = I2C0_dsPIC_Normal_Stop(Slave_Address);
        return Ack_Status;
    }


/* Set The direction as Forward/Clockwise */
static sint32_t i2C_cs_set_new_direction_forward(void)
    {
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rSetting The Motor Direction - FORWARD - command sent\n\r");
        Ack_Status = I2C0_dsPIC_Set_Motor_Direction(Slave_Address, CLOCKWISE);
        return Ack_Status;
    }


/* Set The direction as reverse or counter clockwise */
static sint32_t i2C_cs_set_new_direction_reverse(void)
    {
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rSetting The Motor Direction - REVERSE - command sent\n\r");
        Ack_Status = I2C0_dsPIC_Set_Motor_Direction(Slave_Address, COUNTER_CLOCKWISE);
        return Ack_Status;
    }



/* Choose the Ramp Up Speed */
static sint32_t choose_the_ramp_up_speed(void)
    {
        uint16_t static rampup = RAMP_UP_SPEED_MIN;
        uint16_t keypress = 0u;
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rSelect the ramp up speed using the + and - keys. Press Return when done.\n\r");
        pc.printf("\rNew Value is: %04d", rampup);

        do    {
                keypress = pc.getc();

                if ((rampup < RAMP_UP_SPEED_MAX) && (keypress == '+'))
                                {
                                        rampup++;
                                }
                if ((rampup > RAMP_UP_SPEED_MIN) && (keypress == '-'))
                                {
                                    rampup--;
                                }

                pc.printf("\rNew Value is: %04d", rampup);


            } while (keypress != '\r');

        Ack_Status = i2C_cs_set_ramp_up_speed(rampup);
        return Ack_Status;
    }



/* Set the ramp up speed */
static sint32_t i2C_cs_set_ramp_up_speed(uint16_t rampup)
    {
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rSetting The Ramp Up Speed to %04d - command sent\n\r", rampup);
        Ack_Status = I2C0_dsPIC_Set_Ramp_Up_Speed(Slave_Address, rampup);
        return Ack_Status;
    }



/* Choose the Ramp down Speed */
static sint32_t choose_the_ramp_down_speed(void)
    {
        uint16_t static rampdown = RAMP_DOWN_SPEED_MIN;
        uint16_t keypress = 0u;
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rSelect the ramp down speed using the + and - keys. Press Return when done.\n\r");
        pc.printf("\rNew Value is: %04d", rampdown);

        do    {
                keypress = pc.getc();

                            if ((rampdown < RAMP_DOWN_SPEED_MAX) && (keypress == '+'))
                                        {
                                            rampdown++;
                                        }
                            if ((rampdown > RAMP_DOWN_SPEED_MIN) && (keypress == '-'))
                                        {
                                            rampdown--;
                                        }

                            pc.printf("\rNew Value is: %04d", rampdown);

            } while (keypress != '\r');

        Ack_Status = i2C_cs_set_ramp_down_speed(rampdown);
        return Ack_Status;
    }



/* Set The Ramp Down Speed */
static sint32_t i2C_cs_set_ramp_down_speed(uint16_t rampdown)
    {
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rSetting The Ramp Down Speed to %04d - command sent\n\r", rampdown);
        Ack_Status = I2C0_dsPIC_Set_Ramp_Down_Speed(Slave_Address, rampdown);
        return Ack_Status;
    }



/* Choose the Motor Demand Forward Speed */
static sint32_t choose_the_motor_demand_forward(void)
    {
        uint16_t static forwarddemand = MOTOR_SPEED_DEMAND_FORWARD_MIN;
        uint16_t keypress = 0u;
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rSelect the Forward Motor Demand speed using the + and - keys. Press Return when done.\n\r");
        pc.printf("\rNew Value is: %04d", forwarddemand);

        do    {
                keypress = pc.getc();
                            if ((forwarddemand < MOTOR_SPEED_DEMAND_FORWARD_MAX) && (keypress == '+'))
                                        {
                                            forwarddemand += 9u;
                                            if (forwarddemand > MOTOR_SPEED_DEMAND_FORWARD_MAX)
                                                {
                                                    forwarddemand = MOTOR_SPEED_DEMAND_FORWARD_MAX;
                                                }
                                        }
                            if ((forwarddemand > MOTOR_SPEED_DEMAND_FORWARD_MIN) && (keypress == '-'))
                                        {
                                            if (forwarddemand <= 8u)
                                                {
                                                    forwarddemand = MOTOR_SPEED_DEMAND_FORWARD_MIN;
                                                }
                                            else{
                                                    forwarddemand-= 8u;
                                                }

                                        }
                            pc.printf("\rNew Value is: %04d", forwarddemand);

            } while (keypress != '\r');

        Ack_Status = i2C_cs_set_motor_demand_forward(forwarddemand);
        return Ack_Status;
    }



/* Set the motor demand Speed */
static sint32_t i2C_cs_set_motor_demand_forward(uint16_t demandforward)
    {
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rSetting The Forward Motor Demand Speed to %04d - command sent\n\r",demandforward);
        Ack_Status = I2C0_dsPIC_Set_Motor_Speed_Demand_Forward(Slave_Address, demandforward);
        return Ack_Status;
    }



/* Choose the Motor Demand Reverse Speed */
static sint32_t choose_the_motor_demand_reverse(void)
    {
        uint16_t static reversedemand = MOTOR_SPEED_DEMAND_REVERSE_MIN;
        uint16_t keypress = 0u;
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rSelect the Reverse Motor Demand speed using the + and - keys. Press Return when done.\n\r");
        pc.printf("\rNew Value is: %04d", reversedemand);

        do    {
                keypress = pc.getc();
                            if ((reversedemand < MOTOR_SPEED_DEMAND_REVERSE_MAX) && (keypress == '+'))
                                        {
                                            reversedemand += 9u;
                                            if (reversedemand > MOTOR_SPEED_DEMAND_REVERSE_MAX)
                                                {
                                                    reversedemand = MOTOR_SPEED_DEMAND_REVERSE_MAX;
                                                }
                                        }
                            if ((reversedemand > MOTOR_SPEED_DEMAND_REVERSE_MIN) && (keypress == '-'))
                                        {
                                            if (reversedemand <= 8)
                                                {
                                                    reversedemand = MOTOR_SPEED_DEMAND_REVERSE_MIN;
                                                }
                                            else{
                                                    reversedemand -= 8u;
                                                }
                                        }

                            pc.printf("\rNew Value is: %04d", reversedemand);
            } while (keypress != '\r');

        Ack_Status = i2C_cs_set_motor_demand_reverse(reversedemand);
        return Ack_Status;
    }



/* Set the Reverse motor demand speed */
static sint32_t i2C_cs_set_motor_demand_reverse(uint16_t demandreverse)
    {
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rSetting The Reverse Motor Demand Speed to %04d - command sent\n\r",demandreverse);
        Ack_Status = I2C0_dsPIC_Set_Motor_Speed_Demand_Reverse(Slave_Address, demandreverse);
        return Ack_Status;
    }




/* Select the number of rotart encoder counts you want to move */
static sint32_t choose_the_rotary_encoder_counts(void)
    {
        uint32_t static encoder_counts = 25000u;
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rType In The Target Number of Rotary Encoder Counts you want the motor to move. \n\rPress Return when done.\n\r");

        encoder_counts = get_a_complete_number();
        pc.printf("\rNew Value is: %010d", encoder_counts);

        Ack_Status = i2C_cs_set_rotary_encoder_counts(encoder_counts);
        return Ack_Status;
    }


/* Set the number of counts you want to move - send to the Slave unit */
static sint32_t i2C_cs_set_rotary_encoder_counts(uint32_t rotary_encoder_counter)
    {
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rSetting The Rotary Encoder Counter Target to %010d - command sent\n\r", rotary_encoder_counter);
        Ack_Status = I2C0_dsPIC_Set_Rotation_Counts(Slave_Address, rotary_encoder_counter);
        return Ack_Status;
    }


/* Start Rotation */
static sint32_t i2C_cs_start_rotation(void)
    {
        sint32_t Ack_Status = 0u;

        pc.printf("\n\rRun The Motor - command sent\n\r");
        Ack_Status = I2C0_dsPIC_Start_Motor_Rotation(Slave_Address);
        return Ack_Status;
    }


static sint32_t i2C_cs_goto_home(void)
    {
        sint32_t Ack_Status = 0u;
        uint8_t rx_array[2] = {0u, 0u};
        uint8_t temp8 = 0u;
        uint8_t abort_flag = 0u;
        uint16_t keypress = 0u;

        pc.printf("\n\rGoto Home - command sent\n\r");
        pc.printf("CLOCKWISE direction - Home Speed 100\n\r");
        Ack_Status = I2C0_dsPIC_Goto_Home(Slave_Address, CLOCKWISE, 100u);                                    /* Goto home, run until sensor, CLOCKWISE, speed 100 */
        pc.printf("Waiting for the sensor to reach the home position\n\r");

        wait(0.5);

        do    {
                Ack_Status = I2C0_dsPIC_Read_Motor_Status(Slave_Address, rx_array);
                keypress = pc.getc();

                if (keypress == '2')
                    {
                        i2C_cs_emergency_stop();
                        abort_flag = 1u;
                    }
                if (keypress == '3')
                    {
                        i2C_cs_normal_stop();
                        abort_flag = 1u;
                    }
                wait(0.1);

            }    while (rx_array[1]    == GOTO_HOME);

        temp8 = (rx_array[0] & 0x3cu);                                /* Strip out the fault flags bits */

        if ((temp8 == 0x3cu) && (abort_flag == 0u))
            {
                pc.printf("Home position detected\n\r");
                pc.printf("Backing off 1/2 rev\n\r");
                Ack_Status = I2C0_dsPIC_Set_Motor_Direction(Slave_Address, COUNTER_CLOCKWISE);
                Ack_Status = I2C0_dsPIC_Set_Ramp_Up_Speed(Slave_Address, 1u);
                Ack_Status = I2C0_dsPIC_Set_Motor_Speed_Demand_Reverse(Slave_Address, 5u);
                Ack_Status = I2C0_dsPIC_Set_Rotation_Counts(Slave_Address, 500u);
                Ack_Status = I2C0_dsPIC_Start_Motor_Rotation(Slave_Address);
                wait(0.5);
                do    {
                        Ack_Status = I2C0_dsPIC_Read_Motor_Status(Slave_Address, rx_array);
                        keypress = pc.getc();                                    /* Read character from PC keyboard */

                        if (keypress == '2')
                            {
                                i2C_cs_emergency_stop();
                                abort_flag = 1u;
                            }
                        if (keypress == '3')
                            {
                                i2C_cs_normal_stop();
                                abort_flag = 1u;
                            }


                        wait(0.1);
                    }    while (rx_array[1]    != STOPPED);

                temp8 = (rx_array[0] & 0x3cu);                                /* Strip out the fault flags bits */
            }

        if ((temp8 == 0x3cu) && (abort_flag == 0u))
            {
                pc.printf("Finished backing off\n\r");
                pc.printf("Slow close...\n\r");
                Ack_Status = I2C0_dsPIC_Goto_Home(Slave_Address, CLOCKWISE, 1u);                                    /* Goto home, run until sensor, CLOCKWISE, speed 100 */
                pc.printf("Waiting for the sensor to reach home position\n\r");

                wait(0.25);

                do    {
                        Ack_Status = I2C0_dsPIC_Read_Motor_Status(Slave_Address, rx_array);
                        wait(0.1);
                    }    while (rx_array[1]    == GOTO_HOME);

                temp8 = (rx_array[0] & 0x3cu);                                /* Strip out the fault flags bits */
            }

        if ((temp8 == 0x3cu)  && (abort_flag == 0u))
            {
                pc.printf("All done home position achieved\n\r");
            }
        if (temp8 != 0x3cu)
            {
                pc.printf("Fault detected - goto home aborted\n\r");
            }
        if (abort_flag == 1u)
            {
                pc.printf("Motor stopped - goto home aborted\n\r");
            }

        return Ack_Status;
    }





/* Read the RPM's */
static sint32_t i2C_cs_read_RPMs(void)
    {
        sint32_t Ack_Status = 0u;
        uint16_t keypress = 0u;
        uint8_t rx_array[2] = {0u, 0u};

        pc.printf("\n\rReading the RPM's from the target drive\n\r");
        pc.printf("Press any key to continue\n\r");

        do    {
                pc.printf("RPM  ");
                Ack_Status = I2C0_dsPIC_Read_Tacho_Speed_Instantaneous(Slave_Address, rx_array);        /* Instantaneous first */
                pc.printf("%05d  ",((rx_array[0] * 256u) + rx_array[1]));
                Ack_Status = I2C0_dsPIC_Read_Tacho_Speed_Average(Slave_Address, rx_array);                /* then Average next */
                pc.printf("%05d\r",((rx_array[0] * 256u) + rx_array[1]));
                keypress = pc.getc();
            } while (keypress != '\r');

        pc.printf("\n\r");
        return Ack_Status;
    }



/* Read The Motor Current Signals */
static sint32_t i2C_cs_read_motor_currents(void)
    {
        sint32_t Ack_Status = 0u;
        uint16_t keypress = 0u;
        uint8_t rx_array[2] = {0u, 0u};

        pc.printf("\n\rReading the Motor Current signals from the target drive\n\r");
        pc.printf("Press any key to continue\n\r");

        do    {
                pc.printf("Motor Current  ");
                Ack_Status = I2C0_dsPIC_Read_Motor_Current_Instantaneous(Slave_Address, rx_array);        /* Instantaneous first */
                pc.printf("%05dmA  ",((rx_array[0] * 256u) + rx_array[1]));

                Ack_Status = I2C0_dsPIC_Read_Motor_Current_Average(Slave_Address, rx_array);            /* then Average next */
                pc.printf("%05dmA\r",((rx_array[0] * 256u) + rx_array[1]));
                wait(0.1);
                keypress = pc.getc();
            } while (keypress != '\r');

        pc.printf("\n\r");
        return Ack_Status;
    }



/* Reading The Vbus voltage */
static sint32_t i2C_cs_read_Vbus_voltages(void)
    {
        sint32_t Ack_Status = 0u;
        uint16_t keypress = 0u;
        uint16_t temp16 = 0u;
        uint8_t rx_array[2] = {0u, 0u};

        pc.printf("\n\rReading the Vbus Voltage levels from the target drive\n\r");
        pc.printf("Press any key to continue\n\r");

        do    {
                pc.printf("Vbus Voltage  ");

                Ack_Status = I2C0_dsPIC_Read_Vbus_Instantaneous(Slave_Address, rx_array);                /* Instantaneous Voltage first */
                temp16 = ((rx_array[0] * 256u) + rx_array[1]);
                pc.printf("%05dmV  ",temp16);

                Ack_Status = I2C0_dsPIC_Read_Vbus_Average(Slave_Address, rx_array);                    /* then Average next */
                temp16 = ((rx_array[0] *256u) + rx_array[1]);
                pc.printf("%05dmV\r",temp16);

                wait(0.1);
                keypress = pc.getc();
            } while (keypress != '\r');

        pc.printf("\n\r");
        return Ack_Status;
    }


/* Motor Demand Speed Pot */
static sint32_t i2C_cs_read_demand_speed_potRPM(void)
    {
        sint32_t Ack_Status = 0u;
        uint16_t keypress = 0u;
        uint8_t rx_array[2] = {0u, 0u};

        pc.printf("\n\rReading the Motor Speed Demand Pot\n\r");
        pc.printf("Press any key to continue\n\r");

        do    {
                pc.printf("Demand Pot  ");
                Ack_Status = I2C0_dsPIC_Read_Demand_Pot_Instantaneous(Slave_Address, rx_array);        /* Instantaneous Voltage first */
                pc.printf("%05d  ",((rx_array[0] * 256u) + rx_array[1]));

                Ack_Status = I2C0_dsPIC_Read_Demand_Pot_Average(Slave_Address, rx_array);                /* then Average next */
                pc.printf("%05d\r",((rx_array[0] * 256u) + rx_array[1]));
                wait(0.1);
                keypress = pc.getc();
            } while (keypress != '\r');


        pc.printf("\n\r");
        return Ack_Status;
    }


/* Read the Hall Sensors */
static sint32_t i2C_cs_read_hall_sensors(void)
    {
        sint32_t Ack_Status = 0u;
        uint16_t keypress = 0u;
        uint8_t rx_array[2] = {0u, 0u};

        pc.printf("\n\rReading the Hall Switches \n\r");
        pc.printf("Press any key to continue\n\r");

        do    {
                pc.printf("Hall Sensors  ");
                Ack_Status = I2C0_dsPIC_Read_Hall_Sensor_Positions(Slave_Address, rx_array);
                pc.printf("%05d\r",((rx_array[0] * 256u) + rx_array[1]));

                wait(0.1);
                keypress = pc.getc();
            } while (keypress != '\r');

        pc.printf("\n\r");
        return Ack_Status;
    }



/* Read The Status Register */
static sint32_t i2C_cs_read_status_flags(void)
    {
        sint32_t Ack_Status = 0u;
        uint16_t keypress = 0u;
        uint8_t rx_array[2] = {0u, 0u};

        union u_type
            {
                struct bit_structure
                    {
                        unsigned bit7: 1u;            /* Motor Run Flag */
                        unsigned bit6: 1u;            /* Direction */
                        unsigned bit5: 1u;            /* RPM Fault Flag */
                        unsigned bit4: 1u;            /* Inst Current Fault Flag */
                        unsigned bit3: 1u;            /* Ave Current Fault Flag */
                        unsigned bit2: 1u;            /* Ext Comparator Fault Flag */
                        unsigned bit1: 1u;            /* spare1 */
                        unsigned bit0: 1u;            /* spare2 */
                    } temp8;
                uint8_t temp8_byte;
            } status_flag_bits;



        pc.printf("\n\rReading the Status Flags And State Machine \n\r");
        pc.printf("Press any key to continue\n\r");
        pc.printf("Run/Stop  Direction RPM Flt  InstCur  AveCur   ExtCom   Current State\n\r");

        do    {
                Ack_Status = I2C0_dsPIC_Read_Motor_Status(Slave_Address, rx_array);

                status_flag_bits.temp8_byte = rx_array[0];

                if (status_flag_bits.temp8.bit7 == MOTOR_RUNNING)
                    {
                        pc.printf("RUNNING   ");
                    }
                else{
                        pc.printf("STOPPED   ");
                    }

                if (status_flag_bits.temp8.bit6 == CLOCKWISE)
                    {
                        pc.printf("Clockwise ");
                    }
                else{
                        pc.printf("Anti CW   ");
                    }

                if (status_flag_bits.temp8.bit5 == FAULT_PRESENT)
                    {
                        pc.printf("FAULT    ");
                    }
                else{
                        pc.printf("NO FAULT ");
                    }

                if (status_flag_bits.temp8.bit4 == FAULT_PRESENT)
                    {
                        pc.printf("FAULT    ");
                    }
                else{
                        pc.printf("NO FAULT ");
                    }

                if (status_flag_bits.temp8.bit3 == FAULT_PRESENT)
                    {
                        pc.printf("FAULT    ");
                    }
                else{
                        pc.printf("NO FAULT ");
                    }

                if (status_flag_bits.temp8.bit2 == FAULT_PRESENT)
                    {
                        pc.printf("FAULT    ");
                    }
                else{
                        pc.printf("NO FAULT ");
                    }


                if (rx_array[1]    == STOPPED)
                    {
                        pc.printf("Stopped           ");
                    }
                if (rx_array[1]    == STOPPING)
                    {
                        pc.printf("Stopping          ");
                    }
                if (rx_array[1]    == NEW_MOTOR_DEMAND_FORWARD)
                    {
                        pc.printf("New Demand Forward");
                    }
                if (rx_array[1]    == NEW_MOTOR_DEMAND_REVERSE)
                    {
                        pc.printf("New Demand Reverse");
                    }
                if (rx_array[1]    == NORMAL_RUNNING)
                    {
                        pc.printf("Normal Running    ");
                    }
                if (rx_array[1]    == ROTATE_X_QUAD_COUNTS)
                    {
                        pc.printf("Rotating X Counts ");
                    }
                if (rx_array[1]    == LAST_REVOLUTION)
                    {
                        pc.printf("Last Revolution   ");
                    }
                if (rx_array[1]    == GOTO_HOME)
                    {
                        pc.printf("Goto Home Position");
                    }


                pc.printf("\r");

                wait(0.1);
                keypress = pc.getc();
            } while (keypress != '\r');

        pc.printf("\n\r");
        return Ack_Status;
    }




/* Read The Maximum RPM Speed of the motor */
static sint32_t i2C_cs_read_Maximum_RPM(void)
    {
        sint32_t Ack_Status = 0u;
        uint16_t keypress = 0u;
        uint8_t rx_array[2] = {0u, 0u};

        pc.printf("\n\rReading the Maximum RPM from the target drive\n\r");
        pc.printf("Press any key to continue\n\r");

        Ack_Status = I2C0_dsPIC_Read_Maximum_RPM(Slave_Address, rx_array);                /* Maximum RPM */
        pc.printf("Maximum RPM: %05d\n\r",((rx_array[0] * 256u) + rx_array[1]));

        do  {
                wait(0.1);
                keypress = pc.getc();
            } while (keypress != '\r');

        return Ack_Status;
    }



/* Read The Difference and overshoot of the rotary encoder on the Slave */
static sint32_t i2C_cs_read_Rotary_Encoder(void)
    {
        sint32_t Ack_Status = 0u;
        uint16_t keypress = 0u;
        uint8_t rx_array[4] = {0u, 0u, 0u, 0u};
        sint32_t quad_encoder_difference = 0u;
        uint32_t temp32 = 0u;

        pc.printf("\n\rReading the Rotary Encoder Difference/Overshoot from the target drive\n\r");
        pc.printf("Press any key to continue\n\r");

        do  {
                Ack_Status = I2C0_dsPIC_Read_Quad_Encoder_Counter(Slave_Address, rx_array);

                quad_encoder_difference = rx_array[0];
                quad_encoder_difference = (quad_encoder_difference << 8u);
                quad_encoder_difference = (quad_encoder_difference + rx_array[1]);
                quad_encoder_difference = (quad_encoder_difference << 8u);
                quad_encoder_difference = (quad_encoder_difference + rx_array[2]);
                quad_encoder_difference = (quad_encoder_difference << 8u);
                quad_encoder_difference = (quad_encoder_difference + rx_array[3]);

                temp32 = ((~quad_encoder_difference) + 1u);

                pc.printf("\rDifference/Overshoot:");
                if (quad_encoder_difference == 0u)
                    {
                        pc.printf(" %010d", quad_encoder_difference);
                    }
                else if(quad_encoder_difference > 0u)
                    {
                        pc.printf("+%010d", quad_encoder_difference);
                    }
                else
                    {
                        pc.printf("-%010d", temp32);
                    }



                wait(0.1);
                keypress = pc.getc();
            } while (keypress != '\r');

        return Ack_Status;
    }










/* Execute a sequence of instruction */
static void i2C_cs_execute_sequence(void)
    {
        sint32_t Ack_Status = 0u;

        pc.printf("\n\n\rTransmitting data From Master I2C to Slave...");

        Ack_Status = i2C_cs_ping();

        if (Ack_Status == ACK)
            {
                pc.printf("Setting up the slave motor parameters...\n\r");

                i2C_cs_set_new_direction_forward();            /* Motor direction forward */
                i2C_cs_set_ramp_up_speed(5u);                /* Set the Ramp up speed */
                i2C_cs_set_ramp_down_speed(25u);               /* Set the ramp down speed */
                i2C_cs_set_motor_demand_forward(400u);        /* Set the target speed forward */
                i2C_cs_set_rotary_encoder_counts(50000u);    /* Set the number of rotary encoder countes we want to move */

                i2C_cs_start_rotation();                                    /* Start Rotation */
                pc.printf("Slave Motor is running...\n\r");
                i2C_cs_read_status_flags();                                    /* Display the fault/status information */

                i2C_cs_set_rotary_encoder_counts(150000ul);    /* Set the number of rotary encoder countes we want to move */
                i2C_cs_set_motor_demand_forward(750u);        /* Increase the target speed forward */
                i2C_cs_start_rotation();                    /* Start Rotation */
                i2C_cs_read_status_flags();                    /* Display the fault/status information */

                pc.printf("Reading some of the motor characteristics...\n\r");

                i2C_cs_read_RPMs();                            /* Display The RPM Figures from the slave */

                i2C_cs_read_motor_currents();                /* Display The Motor Currents */

                i2C_cs_read_Vbus_voltages();                /* Display the Vbus voltage */

                i2C_cs_read_demand_speed_potRPM();            /* Display the demand pot */

                i2C_cs_read_status_flags();                    /* Display the fault information */

                pc.printf("Stopping the motor\n\r");
                i2C_cs_normal_stop();                            /* Soft Stop motor rotation */

                pc.printf("Press any key to skip to next section\n\r");

                pc.getc();


                pc.printf("Setting the new direction Reverse/Counter clockwise\n\r");
                i2C_cs_set_new_direction_reverse();
                i2C_cs_set_motor_demand_reverse(1023u);        /* Demand speed in reverse */
                i2C_cs_set_rotary_encoder_counts(40250ul);    /* Set the number of rotary encoder countes we want to move */
                i2C_cs_start_rotation();                    /* Start the motor rotating */
                i2C_cs_read_status_flags();                    /* Display the fault/status information */



                pc.printf("Press any key to skip to next section\n\r");

                pc.getc();

                pc.printf("\n\rTests Complete\n\r");        /* Tests Complete */
            }

    }






/* Get a single number (0-9) from the host PC terminal */
static uint8_t get_a_number_digit(void)
    {
        sint8_t temp8 = 0u;
        uint8_t break_flag = 0u;

        do    {

                temp8 = pc.getc();                                            /* Get a character first of all */

                if ((temp8 > 0x2fu) && (temp8 < 0x3au))
                    {
                        break_flag = 1u;                                    /* Check for valid number digit 0-9 */
                    }
                if (temp8 == '\r')
                    {
                        break_flag = 1u;
                    }
            }    while (break_flag == 0u);

        /* We have valid number key press */
        pc.printf("%c", temp8);

        if (temp8 != '\r')
            {
                temp8 = temp8 - 48;                                        /* convert to number from ASCII to decimal */
            }

        return temp8;                                                        /* Retrun with a number or '\r' */
    }




/* Get a complete number 32 bit from the host terminal */
static uint32_t get_a_complete_number(void)
    {
        uint8_t n = 0u;
        uint32_t number_input = 0u;

        do    {
                n = get_a_number_digit();
                if (n != '\r')
                    {
                        number_input = (number_input * 10u) + n;
                    }
            } while (n != '\r');
        return number_input;
    }