From 7779553efdb04a7184e8e882f98dc871d68ef927 Mon Sep 17 00:00:00 2001 From: AntonJ Date: Mon, 5 May 2025 16:37:04 +0300 Subject: [PATCH] Added Lab5 and neccessary files in common/ --- common/motor.c | 47 +++++++++++++++++++++++++++ common/motor.h | 13 ++++++++ common/pwm.c | 50 ++++++++++++++++++++++++++++ common/pwm.h | 10 ++++++ common/timer_a1.c | 15 +++++++++ common/timer_a1.h | 9 +++++ lab5/Makefile | 77 +++++++++++++++++++++++++++++++++++++++++++ lab5/main.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 304 insertions(+) create mode 100644 common/motor.c create mode 100644 common/motor.h create mode 100644 common/pwm.c create mode 100644 common/pwm.h create mode 100644 common/timer_a1.c create mode 100644 common/timer_a1.h create mode 100644 lab5/Makefile create mode 100644 lab5/main.c diff --git a/common/motor.c b/common/motor.c new file mode 100644 index 0000000..ee79d7c --- /dev/null +++ b/common/motor.c @@ -0,0 +1,47 @@ +#include "motor.h" +#include "pwm.h" + +#include "inc/msp432p401r.h" + +// Initialize GPIO pins for output, which will be +// used to control the direction of the motors and +// to enable or disable the drivers. +// The motors are initially stopped, the drivers +// are initially powered down, and the PWM speed +// control is uninitialized. +void MotorInit(void) { + // write this code +} + +// Stop the motors, power down the drivers, and +// set the PWM speed control to 0% duty cycle. +void MotorStop(void) { + P2->OUT &= ~0xC0; // off + P3->OUT &= ~0xC0; // low current sleep mode + SetPWMDutyLeftMotor(0); + SetPWMDutyRightMotor(0); +} + +// Left and right wheels forward with the given duty cycles. +// Duty cycle is 0 to 14,998. +void MotorForward(uint16_t left_duty, uint16_t right_duty) { + // write this code +} + +// Left and right wheels backward with the given duty cycles. +// Duty cycle is 0 to 14,998. +void MotorBackward(uint16_t left_duty, uint16_t right_duty) { + // write this code +} + +// Left wheel backward, right wheel forward with the given duty cycles. +// Duty cycle is 0 to 14,998. +void MotorLeft(uint16_t left_duty, uint16_t right_duty) { + // write this code +} + +// Left wheel forward, right wheel backward with the given duty cycles. +// Duty cycle is 0 to 14,998. +void MotorRight(uint16_t left_duty, uint16_t right_duty) { + // write this code +} diff --git a/common/motor.h b/common/motor.h new file mode 100644 index 0000000..29daa4c --- /dev/null +++ b/common/motor.h @@ -0,0 +1,13 @@ +#ifndef MOTOR_H +#define MOTOR_H + +#include + +void MotorInit(void); +void MotorStop(void); +void MotorForward(uint16_t left_duty, uint16_t right_duty); +void MotorBackward(uint16_t left_duty, uint16_t right_duty); +void MotorLeft(uint16_t left_duty, uint16_t right_duty); +void MotorRight(uint16_t left_duty, uint16_t right_duty); + +#endif /* MOTOR_H */ \ No newline at end of file diff --git a/common/pwm.c b/common/pwm.c new file mode 100644 index 0000000..97fd15a --- /dev/null +++ b/common/pwm.c @@ -0,0 +1,50 @@ +#include "pwm.h" + +#include "inc/msp432p401r.h" + +// PWM on P2.4/.5 using TimerA0 TA0.CCR1/2 +// period is 1.333us (1.333us = 2 * 666.7ns because of up/down) +// SMCLK = 48MHz/4 = 12 MHz, 83.33ns +// Let Timerclock period T = 8/12MHz = 666.7ns +// P2.4/.5 = 1 when timer equals TA0CCR1/2 on way down, +// P2.4/.5 = 0 when timer equals TA0CCR1/2 on way up +void PWMInitP2_4_P2_5(uint16_t period) { + P2->DIR |= 0x30; + P2->SEL0 |= 0x30; // Timer0A functions + P2->SEL1 &= ~0x30; + TIMER_A0->CCR[0] = period; + TIMER_A0->EX0 = 0; // Divide by 1 + TIMER_A0->CCTL[1] = 0x40; // Toggle/reset + TIMER_A0->CCTL[2] = 0x40; + TIMER_A0->CCR[1] = 0; // Initial duty cycle to 0 + TIMER_A0->CCR[2] = 0; + TIMER_A0->CTL = 0x2F0; // SMCLK = 12MHz, divide by 8, up-down mode +} + +void SetPWMDutyP2_4(uint16_t duty) { + if (duty >= TIMER_A0->CCR[0]) return; + TIMER_A0->CCR[1] = duty; +} + +void SetPWMDutyP2_5(uint16_t duty) { + if (duty >= TIMER_A0->CCR[0]) return; + TIMER_A0->CCR[2] = duty; +} + +// PWM on P2.6/.7 using TimerA0 TA0.CCR3/4 +// SMCLK = 48MHz/4 = 12 MHz, 83.33ns +// period is 1.333us +// Let Timerclock period T = 8/12MHz = 666.7ns +// P2.6/.7 = 1 when timer equals TA0CCR3/4 on way down, +// P2.6/.7 = 0 when timer equals TA0CCR3/4 on way up +void PWMInitMotor(uint16_t period) { + // write this code +} + +void SetPWMDutyRightMotor(uint16_t duty) { + // write this code +} + +void SetPWMDutyLeftMotor(uint16_t duty) { + // write this code +} diff --git a/common/pwm.h b/common/pwm.h new file mode 100644 index 0000000..c8220cc --- /dev/null +++ b/common/pwm.h @@ -0,0 +1,10 @@ +#ifndef PWM_H +#define PWM_H + +#include + +void PWMInitMotor(uint16_t period); +void SetPWMDutyRightMotor(uint16_t duty); +void SetPWMDutyLeftMotor(uint16_t duty); + +#endif /* PWM_H */ \ No newline at end of file diff --git a/common/timer_a1.c b/common/timer_a1.c new file mode 100644 index 0000000..80ea00c --- /dev/null +++ b/common/timer_a1.c @@ -0,0 +1,15 @@ +#include "timer_a1.h" + +#include "inc/msp432p401r.h" + +void (*timer_a1_task)(void); // user function + +// Activate Timer A1 interrupts to run user task periodically +// 16 bits period in units (24/SMCLK, with SMCLK 12 MHz -> 2us) +void TimerA1Init(void (*task)(void), uint16_t period) { + // write this code +} + +void TA1_0_IRQHandler(void) { + // write this code +} diff --git a/common/timer_a1.h b/common/timer_a1.h new file mode 100644 index 0000000..08a7f9e --- /dev/null +++ b/common/timer_a1.h @@ -0,0 +1,9 @@ +#ifndef TIMER_A1_H +#define TIMER_A1_H + +#include + +void TimerA1Init(void (*task)(void), uint16_t period); +void TimerA1Stop(void); + +#endif /* TIMER_A1_H */ \ No newline at end of file diff --git a/lab5/Makefile b/lab5/Makefile new file mode 100644 index 0000000..53e6f59 --- /dev/null +++ b/lab5/Makefile @@ -0,0 +1,77 @@ +CC = arm-none-eabi-gcc + +# The location of the C compiler +# ARMGCC_ROOT is used by some makefiles that need to know where the compiler +# is installed. +ARMGCC_BIN := ${shell which ${CC}} +ifeq (${shell test -h ${ARMGCC_BIN} && echo "true" || echo "false"}, true) + ARMGCC_ROOT := ${shell dirname ${shell readlink ${ARMGCC_BIN}}}/.. +else + ARMGCC_ROOT := ${shell dirname ${ARMGCC_BIN}}/.. +endif + +# Search for source files that are not in this directory +VPATH = ../common/ + +OBJECTS = main.o timer_a1.o delay.o motor.o pwm.o bump.o cpu.o clock.o system.o startup.o syscalls.o + +NAME = lab + +CFLAGS = -I.. -I../inc -I../common \ + -D__MSP432P401R__ \ + -DDeviceFamily_MSP432P401x \ + -mcpu=cortex-m4 \ + -march=armv7e-m \ + -mthumb \ + -std=c99 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -ffunction-sections \ + -fdata-sections \ + -gstrict-dwarf \ + -Wall \ + -I$(ARMGCC_ROOT)/arm-none-eabi/include/newlib-nano \ + -I$(ARMGCC_ROOT)/arm-none-eabi/include + +LFLAGS = -Wl,-T,../config.lds \ + -Wl,-Map,$(NAME).map \ + -march=armv7e-m \ + -mthumb \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -static \ + -Wl,--gc-sections \ + -lgcc \ + -lc \ + -lm \ + -lnosys \ + --specs=nano.specs + +all: $(NAME).out + @echo "SUCCESS: Compilation completed successfully." + +%.o: %.c + @$(CC) $(CFLAGS) -g $< -c -o $@ + +cpu.o: ../common/cpu.c + @$(CC) $(CFLAGS) $< -c -o $@ + +clock.o: ../common/clock.c + @$(CC) $(CFLAGS) $< -c -o $@ + +system.o: ../system.c + @$(CC) $(CFLAGS) $< -c -o $@ + +startup.o: ../startup.c + @$(CC) $(CFLAGS) $< -c -o $@ + +syscalls.o: ../syscalls.c + @$(CC) $(CFLAGS) $< -c -o $@ + +$(NAME).out: $(OBJECTS) + @$(CC) $(OBJECTS) $(LFLAGS) -o $(NAME).out + +clean: # Redirecting both the stderr and stdout to /dev/null + @rm -f $(OBJECTS) > /dev/null 2>&1 + @rm -f $(NAME).out > /dev/null 2>&1 + @rm -f $(NAME).map > /dev/null 2>&1 diff --git a/lab5/main.c b/lab5/main.c new file mode 100644 index 0000000..11f41d0 --- /dev/null +++ b/lab5/main.c @@ -0,0 +1,83 @@ +#include +#include + +#include "timer_a1.h" +#include "pwm.h" +#include "motor.h" +#include "clock.h" +#include "cpu.h" +#include "bump.h" +#include "delay.h" + +#include "inc/msp432p401r.h" + +// bit-banded addresses, positive logic +#define SW2IN ((*((volatile uint8_t *)(0x42098010)))^1) +#define SW1IN ((*((volatile uint8_t *)(0x42098004)))^1) + +#define REDLED (*((volatile uint8_t *)(0x42098040))) + +void TimedWaitTouchRelease(uint32_t time) { + Delay1ms(time); // run for a while and then stop + MotorStop(); + while (!(SW1IN || SW2IN)) {} // wait for touch + while (SW1IN || SW2IN) {} // wait for release +} + +void RedLEDInit(void) { + P1->SEL0 &= ~0x01; + P1->SEL1 &= ~0x01; // 1) configure P1.0 as GPIO + P1->DIR |= 0x01; // 2) make P1.0 out +} + +void SwitchInit(void) { + P1->SEL0 &= ~0x12; + P1->SEL1 &= ~0x12; // 1) configure P1.4 and P1.1 as GPIO + P1->DIR &= ~0x12; // 2) make P1.4 and P1.1 in + P1->REN |= 0x12; // 3) enable pull resistors on P1.4 and P1.1 + P1->OUT |= 0x12; // P1.4 and P1.1 are pull-up +} + +void Task(void) { + static uint32_t time; + ++time; + REDLED ^= 1; +} + +int main_periodic_test(void) { + ClockInit48MHz(); + RedLEDInit(); + TimerA1Init(&Task, 500); // 1000 Hz + CPU_cpsie(); // Enable interrupts + while (true) {} +} + +int main_motor_test(void) { + ClockInit48MHz(); + SwitchInit(); + PWMInitMotor(7502); // your function + MotorInit(); // your function + while (true) { + TimedWaitTouchRelease(1000); + MotorForward(1500, 1500); // your function + TimedWaitTouchRelease(2000); + MotorBackward(1500, 1500); // your function + TimedWaitTouchRelease(2000); + MotorLeft(1200, 1200); // your function + TimedWaitTouchRelease(1000); + MotorRight(1200, 1200); // your function + } +} + +// Write a program that uses PWM to move the robot +// but uses TimerA1 to periodically check the bump switches, +// stopping the robot on collision +int main(void) { + ClockInit48MHz(); + // write code here + CPU_cpsie(); // Enable interrupts + while (true) { + // write code here + } +} +