Computer Course
//
//
// 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);
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--;
}
}