Computer Course

profileiMozzie
Lab1.docx

//

//

// Lab 1: Startup code

// 1 - Initialize Core

// 2 - Initialize LEDs

// 3 - Initialize buttons

// 4 - logic to control the LEDs based on buttons:

//     If Right_button (SW2) is pressed, activate the RED LED

//     If Left_button (SW1) is pressed, activate the GREEN LED

//     If Both_buttons are pressed, activate the BLUE LED

//

//     Lab assignment:

//     1- Import the startup project into your workspace, and verify the startup code is working as expected, i.e. as it was demonstrated during the lab

//        Modify the code as follows, using the provided 1ms delay function:

//     2- When the Right_button (SW2) is pressed (and held), RED LED starts flashing at 2 HZ

//     3- When the LEFT_button (SW1) is pressed (and held), GREEN LED start flashing at 1 HZ

//     4- When Both buttons are Right_button (SW2) is pressed, WHITE LED (Combination of the 3 LEDs start flashing at 5 HZ)

//     5- Create a short video demonstrating the functionality by describing the code implementation along with the behavior

//     6- Create the lab report based on the report template, describe the implemented features in full detail by creating a professional documentation

//     7- Upload the report, video, and your modified code to CANVAS

#include <stdint.h>

#include "inc\tm4c123gh6pm.h"

// Red LED connected to PF1 on the Launchpad

// Blue LED connected to PF2 on the Launchpad

// Green LED connected to PF3 on the Launchpad

#define RED_LED     0x02  // PF1

#define BLUE_LED    0x04  // PF2

#define GREEN_LED   0x08  // PF3

// Color    LED(s) PortF

// dark     ---    0

// red      R--    0x02

// blue     --B    0x04

// green    -G-    0x08

// yellow   RG-    0x0A

// sky blue -GB    0x0C

// white    RGB    0x0E

// pink     R-B    0x06

#define YELLOW_LED            (RED_LED   | GREEN_LED)

#define SKY_BLUE_LED          (GREEN_LED | BLUE_LED)

#define WHITE_LED             (RED_LED   | GREEN_LED | BLUE_LED)

#define PINK_LED              (RED_LED   | BLUE_LED)

#define LED_OFF               (0)

#define TRUE  1

#define FALSE 0

// Negative logic switches connected to PF0 and PF4 on the Launchpad

#define SW1         0x10  // PF0: on the left side of the Launchpad board

#define SW2         0x01  // PF4: on the right side of the Launchpad board

// functions prototypes:

void PortF_Init(void);

uint32_t PortF_Input(void);

void PortF_Output(uint32_t data);

void delay_1ms (uint32_t delay);

// Button states:

uint8_t ButtonState_L;

uint8_t ButtonState_R;

uint8_t ButtonState_RL;

// ButtonStates variable:

uint32_t ButtonStates;

// LED Command

uint32_t LED_Command;

int main(void)

{

    PortF_Init();   // initialize PF0 and PF4 and make them inputs

                    // make PF3-1 outputs, PF3-1 built-in LEDs)

    // do forever, same as for(;;)

    while(1)

    {

        ButtonStates = PortF_Input();

        // switches are negative logic on PF0 and PF4

        // Check if RIGHT button, LEFT button, or BOTH(RL) buttons are pressed:

        ButtonState_R  = ((ButtonStates == SW1)  ? TRUE : FALSE);

        ButtonState_L  = ((ButtonStates == SW2)  ? TRUE : FALSE);

        ButtonState_RL = ((ButtonStates == (SW1 & SW2))  ? TRUE : FALSE);

        // control the LED control based on the pressed button

        LED_Command  = ((ButtonState_R)  ? RED_LED   : LED_OFF);

        LED_Command |= ((ButtonState_L)  ? GREEN_LED : LED_OFF);

        LED_Command |= ((ButtonState_RL) ? BLUE_LED  : LED_OFF);

        if(LED_Command == LED_OFF)

        {

            LED_Command = WHITE_LED;

        }

        PortF_Output(LED_Command);

        switch(ButtonStates)

        {

            //1-SW1 pressed SW1 = 0x01

            case (SW1):

                PortF_Output(RED_LED);

                delay_1ms(625);        

                PortF_Output(LED_OFF);

                delay_1ms(625);

                break;

            //2-SW2 pressed SW2 = 0x10

            case (SW2):

                PortF_Output(GREEN_LED);

                delay_1ms(250);

                PortF_Output(LED_OFF);

                delay_1ms(250);

                break;

            //3-SW1 & SW2 pressed SW1 & SW2 = 0x11

            case (SW1 & SW2):

                 PortF_Output(WHITE_LED);

                 delay_1ms(150);

                 PortF_Output(LED_OFF);

                 delay_1ms(150);

                 break;

        }

    } //while loop

} // main function

////////////////////////////////////////

//

// void PortF_Init(void)

//

///////////////////////////////////////

void PortF_Init(void)

{

    SYSCTL_RCGCGPIO_R |= 0x00000020;  // 1) activate clock for Port F         a= a | b      a|=b  ;

    // NOTE: The NMI (non-maskable interrupt) is on PF0.

    // That means that the Alternate Function Select,

    // Pull-Up Resistor, Pull-Down Resistor, and Digital Enable are all locked for PF0

    // To unlock it, a value of 0x4C4F434B must be written to the Port F GPIO Lock Register.

    // After Port F is unlocked, bit 0 of the Port F GPIO Commit Register must be set to

    // allow access to PF0's control registers.

    GPIO_PORTF_LOCK_R = 0x4C4F434B;   // 2) unlock GPIO Port F

    GPIO_PORTF_CR_R   = 0x1F;         // allow changes to PF4-0

    // only PF0 needs to be unlocked, other bits can't be locked

    GPIO_PORTF_AMSEL_R = 0x00;        // 3) disable analog on PF

    GPIO_PORTF_PCTL_R  = 0x00000000;  // 4) PCTL GPIO on PF4-0

    GPIO_PORTF_DIR_R   = 0x0E;        // 5) PF4,PF0 in, PF3-1 out

    GPIO_PORTF_AFSEL_R = 0x00;        // 6) disable alt funct on PF7-0

    GPIO_PORTF_PUR_R   = 0x11;        // enable pull-up on PF0 and PF4

    GPIO_PORTF_DEN_R   = 0x1F;        // 7) enable digital I/O on PF4-0

}

////////////////////////////////////////

//

// uint32_t PortF_Input(void)

//

///////////////////////////////////////

uint32_t PortF_Input(void)

{

    // read PF4,PF0 inputs

    return (GPIO_PORTF_DATA_R & (SW1|SW2));

}

////////////////////////////////////////

//

// PortF_Output(uint32_t data)

//

///////////////////////////////////////

void PortF_Output(uint32_t data)

{

    // write PF3-PF1 outputs

    GPIO_PORTF_DATA_R = data;

}

////////////////////////////////////////

//

// delay_1ms (uint32_t delay)

//

///////////////////////////////////////

// Delay estimation:

// Each delay loop will take roughly 160 cycles

// Each cycle takes 1/16MHZ = 62.5ns

// We need to create a 1ms delay

//#define DELAY_1ms  (1000000)/(10*62.5) // approximately 1ms delay at ~16 MHz clock

#define DELAY_1ms  1000000/(625) // approximately 1ms delay at ~16 MHz clock   1500

// Please Note: Of course Spin loop delay IS NOT the preferred way to create delays,

// This method is used for now only to demonstrate the LED functionality

// Timers will be used instead (Hardware and/or Software timers are used to manage time-based delays)

void delay_1ms (uint32_t delay)

{

    uint32_t loopDelay=0;

    while(delay)

    {

        while(loopDelay < DELAY_1ms)

        {

            loopDelay++; // spinloop wait delay (do nothing for 1ms)

        }

        loopDelay = 0;

        delay--;

    }

 }