From 7fb97bcab7202758221dc0747dd5b9fa42ff4450 Mon Sep 17 00:00:00 2001 From: Ondrej Hladuvka Date: Tue, 20 May 2025 16:05:29 +0300 Subject: [PATCH] lab6 fixpoint --- common/input_capture.c | 89 ++++++++----------- lab5/main.c | 191 ++++++++++++++++++++++++++--------------- lab6/main.c | 23 ++--- 3 files changed, 174 insertions(+), 129 deletions(-) diff --git a/common/input_capture.c b/common/input_capture.c index e94dae4..3f2b27d 100644 --- a/common/input_capture.c +++ b/common/input_capture.c @@ -9,16 +9,13 @@ void (*capture_task)(uint16_t time); // acknowledges the interrupt and calls a user function. void TimerA0CaptureInit(void (*task)(uint16_t time)) { capture_task = task; - P7->SEL0 |= 0x08; P7->SEL1 &= ~0x08; // configure P7.3 as TA0CCP0 P7->DIR &= ~0x08; TIMER_A0->CTL &= ~0x30; // halt Timer A0 TIMER_A0->CTL = 0x200; // SMCLK - TIMER_A0->CCTL[0] = 0x4910; // capture on rising edge, synchronous capture, capture mode, interrupt enabled - TIMER_A0->EX0 &= ~0x7; // input clock divider /1 NVIC->IP[2] = (NVIC->IP[2] & 0xFFFFFF00) | 0x00000002; // priority 2 @@ -51,69 +48,59 @@ void TimerA3CaptureInit(void (*task0)(uint16_t time), void (*task1)(uint16_t time)) { capture_task0 = task0; capture_task1 = task1; - - // Configure P10.4 and P10.5 as TA3.CCP0 and TA3.CCP1 P10->SEL0 |= 0x30; // Set SEL0 for bits 4 and 5 P10->SEL1 &= ~0x30; // Clear SEL1 for bits 4 and 5 P10->DIR &= ~0x30; // Set as inputs - // Halt Timer A3 and configure clock source - TIMER_A3->CTL &= ~0x0030; // Halt Timer A3 - TIMER_A3->CTL = 0x0200; // Use SMCLK (12 MHz) + TIMER_A3->CTL &= ~0x30; // halt Timer A3 + TIMER_A3->CTL = 0x200; // SMCLK + TIMER_A3->CCTL[0] = 0x4910; // rising, sync, capture, interrupt + TIMER_A3->CCTL[1] = 0x4910; + TIMER_A3->EX0 &= ~0x7; // input clock divider /1 - // Configure capture compare channels 0 and 1 - TIMER_A3->CCTL[0] = 0x4910; // Rising edge, sync, capture, interrupt - TIMER_A3->CCTL[1] = 0x4910; // Same for channel 1 + NVIC->IP[3] = (NVIC->IP[3] & 0xFF0000FF) | 0x00020300; // priority 2 and 3 + + //? enabling something different?? + NVIC->ISER[0] = (1 << 13) | (1 << 14); // enable 14 and 15 - // Set input clock divider to /1 - TIMER_A3->EX0 &= ~0x0007; // Clear TAIDEX bits - // TIMER_A3->EX0 = (TIMER_A3->EX0 & ~0x0007) | 0x0002; - - // Set NVIC priorities for TA3_0 and TA3_N interrupts to priority 2 - NVIC->IP[10] = (NVIC->IP[10] & 0xFFFF0000) | 0x00000202; - - // Enable interrupts in NVIC - NVIC->ISER[1] = 0x0300; // Enable IRQ40 and IRQ41 // Start Timer A3 in continuous mode with clear TIMER_A3->CTL |= 0x0024; // TACLR | MC__CONTINUOUS } -// // The rising edge of P10.4 will cause an interrupt +// The rising edge of P10.4 will cause an interrupt +void TA3_0_IRQHandler(void) { + TIMER_A3->CCTL[0] &= ~0x0001; // ack + capture_task0(TIMER_A3->CCR[0]); +} + +// The rising edge of P10.5 will cause an interrupt +void TA3_N_IRQHandler(void) { + TIMER_A3->CCTL[1] &= ~0x0001; // ack + capture_task1(TIMER_A3->CCR[1]); +} + +// #define PRESCALER_FACTOR 3 +// static uint16_t prev_capture0 = 0; +// static uint16_t prev_capture1 = 0; +// // ISR for TA3 CCR0 (P10.4 rising edge) // void TA3_0_IRQHandler(void) { +// uint16_t current_capture = TIMER_A3->CCR[0]; +// uint16_t period = current_capture - prev_capture0; +// prev_capture0 = current_capture; + // TIMER_A3->CCTL[0] &= ~0x0001; // Acknowledge interrupt -// capture_task0(TIMER_A3->CCR[0]); // Execute user task +// capture_task0(period * PRESCALER_FACTOR); // Apply prescaler // } -// // The rising edge of P10.5 will cause an interrupt +// // ISR for TA3 CCR1 (P10.5 rising edge) // void TA3_N_IRQHandler(void) { -// if (TIMER_A3->CCTL[1] & 0x0001) { // Check if CCIFG1 is set -// TIMER_A3->CCTL[1] &= ~0x0001; // Acknowledge interrupt -// capture_task1(TIMER_A3->CCR[1]); // Execute task +// if (TIMER_A3->CCTL[1] & 0x0001) { // Check CCIFG1 +// uint16_t current_capture = TIMER_A3->CCR[1]; +// uint16_t period = current_capture - prev_capture1; +// prev_capture1 = current_capture; + +// TIMER_A3->CCTL[1] &= ~0x0001; // Acknowledge interrupt +// capture_task1(period * PRESCALER_FACTOR); // Apply prescaler // } // } - -#define PRESCALER_FACTOR 3 -static uint16_t prev_capture0 = 0; -static uint16_t prev_capture1 = 0; -// ISR for TA3 CCR0 (P10.4 rising edge) -void TA3_0_IRQHandler(void) { - uint16_t current_capture = TIMER_A3->CCR[0]; - uint16_t period = current_capture - prev_capture0; - prev_capture0 = current_capture; - - TIMER_A3->CCTL[0] &= ~0x0001; // Acknowledge interrupt - capture_task0(period * PRESCALER_FACTOR); // Apply prescaler -} - -// ISR for TA3 CCR1 (P10.5 rising edge) -void TA3_N_IRQHandler(void) { - if (TIMER_A3->CCTL[1] & 0x0001) { // Check CCIFG1 - uint16_t current_capture = TIMER_A3->CCR[1]; - uint16_t period = current_capture - prev_capture1; - prev_capture1 = current_capture; - - TIMER_A3->CCTL[1] &= ~0x0001; // Acknowledge interrupt - capture_task1(period * PRESCALER_FACTOR); // Apply prescaler - } -} diff --git a/lab5/main.c b/lab5/main.c index c2f8cbc..dec59ac 100644 --- a/lab5/main.c +++ b/lab5/main.c @@ -1,92 +1,147 @@ #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 "../common/cpu.h" +#include "../common/motor.h" +#include "../common/pwm.h" +#include "../common/clock.h" +#include "../common/input_capture.h" +#include "../common/timer_a1.h" +#include "../common/tachometer.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 +// bit-banded address +#define REDLED (*((volatile uint8_t *)(0x42098040))) + +void ColorLEDInit(void) { + P2->SEL0 &= ~0x07; + P2->SEL1 &= ~0x07; // 1) configure P2.2-P2.0 as GPIO + P2->DIR |= 0x07; // 2) make P2.2-P2.0 out + P2->DS |= 0x07; // 3) activate increased drive strength + P2->OUT &= ~0x07; // all LEDs off } -void Task(void) { - static uint32_t time; - ++time; +// bit-banded addresses +#define BLUEOUT (*((volatile uint8_t *)(0x42098068))) +#define GREENOUT (*((volatile uint8_t *)(0x42098064))) +#define REDOUT (*((volatile uint8_t *)(0x42098060))) + +uint16_t period0, period1; // (1/SMCLK) units = 83.3 ns units +uint16_t first0, first1; // Timer A3 first edge, P10.4/.5 +bool done0, done1; // set each rising + +// max period is (2^16-1)*83.3 ns = 5.4612 ms +// min period determined by time to run ISR, which is about 1 us +void PeriodMeasure0(uint16_t time) { + REDOUT ^= 1; + period0 = time - first0; // 83.3 ns resolution + first0 = time; // setup for next + done0 = true; +} + +// max period is (2^16-1)*83.3 ns = 5.4612 ms +// min period determined by time to run ISR, which is about 1 us +void PeriodMeasure1(uint16_t time) { REDLED ^= 1; + period1 = time - first1; // 83.3 ns resolution + first1 = time; // setup for next + done1 = true; } -int main_f(void) { - ClockInit48MHz(); - RedLEDInit(); - TimerA1Init(&Task, 500); // 1000 Hz - CPU_cpsie(); // Enable interrupts - while (true) {} +void dummy() { + volatile int i = 1; + i = i + 2; + return; } - -int main_s(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 - } -} - -void checkBump() { -uint8_t bump = BumpRead(); - if (~bump & BUMP_PINS) - MotorStop(); -} - -// 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(); - BumpInit(); + CPU_cpsid(); // Disable interrupts + ClockInit48MHz(); // 48 MHz clock; 12 MHz Timer A clock + RedLEDInit(); + ColorLEDInit(); PWMInitMotor(7502); MotorInit(); - MotorForward(1500, 1500); - TimerA1Init(checkBump, 15000); + TimerA1Init(&dummy, 1000); + TimerA3CaptureInit(&PeriodMeasure0, &PeriodMeasure1); + // MotorForward(3751, 3751); // 50% + // MotorForward(1000, 1000); CPU_cpsie(); // Enable interrupts - - while (true); + CPU_wfi(); // Wait for interrupt + return 0; } +uint16_t speed_buf[500]; // RPM, radius 0.035m wheels +uint32_t period_buf[500]; // 1/12MHz = 0.083 usec +uint32_t duty; // 0 to 15000 +uint32_t time; // in 0.01 sec + +void Collect(void) { + GREENOUT ^= 1; + if (!done0) period0 = 0xFFFF - 1; // stopped + if (!done1) period1 = 0xFFFF - 1; + done0 = done1 = false; // set on subsequent + switch (time) { + case 0: + duty = 1875; // 25% + MotorForward(duty, duty); + break; + case 100: + duty = 3751; // 50% + MotorForward(duty, duty); + break; + case 200: + duty = 5626; // 75% + MotorForward(duty, duty); + break; + case 300: + duty = 3751; // 50% + MotorForward(duty, duty); + break; + case 400: + duty = 1875; // 25% + MotorForward(duty, duty); + break; + case 500: + MotorStop(); + TIMER_A1->CTL &= ~0x30; // Halt timer A1 + break; + default: + speed_buf[time] = 2000000 / period0; + period_buf[time] = period0; + break; + } + ++time; +} + +int main_collect(void) { + CPU_cpsid(); // Disable interrupts + ClockInit48MHz(); // 48 MHz clock; 12 MHz Timer A clock + RedLEDInit(); + ColorLEDInit(); + PWMInitMotor(7502); + MotorInit(); + TimerA3CaptureInit(&PeriodMeasure0, &PeriodMeasure1); + TimerA1Init(&Collect, 5000); // 100 Hz + CPU_cpsie(); // Enable interrupts + CPU_wfi(); // Wait for interrupt + return 0; +} + +int main_tach(void) { + CPU_cpsid(); // Disable interrupts + ClockInit48MHz(); + PWMInitMotor(7502); + MotorInit(); + TachometerInit(); + MotorForward(2000, 2000); // confirm if rotating forward + //MotorBackward(2000, 2000); // confirm if rotating backward + CPU_cpsie(); // Enable interrupts + CPU_wfi(); // Wait for interrupt + return 0; +} diff --git a/lab6/main.c b/lab6/main.c index b688c99..d638df2 100644 --- a/lab6/main.c +++ b/lab6/main.c @@ -1,13 +1,13 @@ #include #include -#include "cpu.h" -#include "motor.h" -#include "pwm.h" -#include "clock.h" -#include "input_capture.h" -#include "timer_a1.h" -#include "tachometer.h" +#include "../common/cpu.h" +#include "../common/motor.h" +#include "../common/pwm.h" +#include "../common/clock.h" +#include "../common/input_capture.h" +#include "../common/timer_a1.h" +#include "../common/tachometer.h" #include "inc/msp432p401r.h" @@ -56,8 +56,11 @@ void PeriodMeasure1(uint16_t time) { } void dummy() { - int i = 1; + volatile int i = 1; + i = i + 2; + return; } + int main(void) { CPU_cpsid(); // Disable interrupts ClockInit48MHz(); // 48 MHz clock; 12 MHz Timer A clock @@ -65,8 +68,8 @@ int main(void) { ColorLEDInit(); PWMInitMotor(7502); MotorInit(); - TimerA1Init(&dummy, 1000); - // TimerA3CaptureInit(&PeriodMeasure0, &PeriodMeasure1); + // TimerA1Init(&dummy, 1000); + TimerA3CaptureInit(&PeriodMeasure0, &PeriodMeasure1); // MotorForward(3751, 3751); // 50% // MotorForward(1000, 1000); CPU_cpsie(); // Enable interrupts