some stuff
This commit is contained in:
28
labW6barnestr/Src/delay.c
Normal file
28
labW6barnestr/Src/delay.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* delay.c
|
||||
*
|
||||
* Created on: Dec 10, 2021
|
||||
* Author: Trevor Barnes
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "delay.h" //include declaration header file
|
||||
|
||||
void delay_1ms(uint32_t n){
|
||||
|
||||
// 1ms = 16,000 ticks
|
||||
for (int i = n ; i > 0 ; i--) {
|
||||
// Clear value register
|
||||
*STK_VAL = 0x0000;
|
||||
// Store 16,000 in STK_LOAD
|
||||
*STK_LOAD = 16000;
|
||||
// Enable clock, no prescaler, no interrupt
|
||||
*STK_CTRL |= CLKSOURCE;
|
||||
*STK_CTRL |= EN;
|
||||
// Loop n times: Wait for countflag high
|
||||
int flag;
|
||||
do {
|
||||
flag = ((*STK_CTRL & (1<<16))>>16);
|
||||
} while (flag != 1);
|
||||
}
|
||||
}
|
||||
147
labW6barnestr/Src/led.c
Normal file
147
labW6barnestr/Src/led.c
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* led.c
|
||||
*
|
||||
* Created on: Dec 10, 2021
|
||||
* Author: Trevor Barnes
|
||||
*/
|
||||
|
||||
#include "led.h"
|
||||
#include "delay.h"
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int ledSpeed = 5;
|
||||
|
||||
void led_init(){
|
||||
// Initialize corresponding RCC and GPIO registers
|
||||
*RCC_AHB1ENR |= (1<<GPIOBEN);
|
||||
|
||||
*GPIOB_MODER &= ~(0x3FFF<<10);
|
||||
*GPIOB_MODER |= (0x555<<10);
|
||||
|
||||
*GPIOB_MODER &= ~(0xFF<<24);
|
||||
*GPIOB_MODER |= (0x55<<24);
|
||||
}
|
||||
|
||||
void led_allOn(){
|
||||
// Set all LED Bits
|
||||
*GPIOB_ODR |= ALL_LEDS;
|
||||
}
|
||||
|
||||
|
||||
void led_allOff(){
|
||||
// Reset all LED bits
|
||||
*GPIOB_ODR &= ~(ALL_LEDS);
|
||||
|
||||
}
|
||||
|
||||
void led_on(uint8_t ledIndex){
|
||||
// Set individual LED based on passed in index
|
||||
switch (ledIndex) {
|
||||
case 0:
|
||||
*GPIOB_BSRR = (1<<5);
|
||||
break;
|
||||
case 1:
|
||||
*GPIOB_BSRR = (1<<6);
|
||||
break;
|
||||
case 2:
|
||||
*GPIOB_BSRR = (1<<7);
|
||||
break;
|
||||
case 3:
|
||||
*GPIOB_BSRR = (1<<8);
|
||||
break;
|
||||
case 4:
|
||||
*GPIOB_BSRR = (1<<9);
|
||||
break;
|
||||
case 5:
|
||||
*GPIOB_BSRR = (1<<10);
|
||||
break;
|
||||
case 6:
|
||||
*GPIOB_BSRR = (1<<12);
|
||||
break;
|
||||
case 7:
|
||||
*GPIOB_BSRR = (1<<13);
|
||||
break;
|
||||
case 8:
|
||||
*GPIOB_BSRR = (1<<14);
|
||||
break;
|
||||
case 9:
|
||||
*GPIOB_BSRR = (1<<15);
|
||||
break;
|
||||
default:
|
||||
printf("LED index out of range\n\r");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void led_off(uint8_t ledIndex){
|
||||
// Reset individual LED based on passed in index
|
||||
if (ledIndex < 6) {
|
||||
*GPIOB_BSRR = (1<<(21+ledIndex));
|
||||
} else if (ledIndex >= 6) {
|
||||
// Add pin offset to index
|
||||
*GPIOB_BSRR = (1<<(22+ledIndex));
|
||||
} else {
|
||||
printf("LED index out of range\n\r");
|
||||
}
|
||||
}
|
||||
|
||||
void led_scan(){
|
||||
led_allOff();
|
||||
// Right to left each LED
|
||||
for (int i = 0; i <= 9 ; i++) {
|
||||
// Scaled Delay
|
||||
delay_1ms(50+(ledSpeed*50));
|
||||
if(i != 0){
|
||||
led_off(i-1);
|
||||
}
|
||||
led_on(i);
|
||||
}
|
||||
// Left to right each LED
|
||||
for (int i = 9; i >= 0; i--) {
|
||||
if(i != 9){
|
||||
led_off(i+1);
|
||||
}
|
||||
led_on(i);
|
||||
// Scaled Delay
|
||||
delay_1ms(50+(ledSpeed*50));
|
||||
}
|
||||
led_off(0);
|
||||
}
|
||||
|
||||
void led_flash(){
|
||||
// Flash LED on and off 10 times at a speed between 0-1 seconds
|
||||
for (int i = 0; i < 10; i++) {
|
||||
led_allOn();
|
||||
delay_1ms(100+(ledSpeed*100));
|
||||
led_allOff();
|
||||
delay_1ms(100+(ledSpeed*100));
|
||||
}
|
||||
}
|
||||
|
||||
void led_setSpeed(uint8_t speed){
|
||||
ledSpeed = speed;
|
||||
}
|
||||
|
||||
void led_incSpeed(){
|
||||
if (ledSpeed == 0){
|
||||
printf("Speed too fast\n\r");
|
||||
} else {
|
||||
ledSpeed--;
|
||||
}
|
||||
}
|
||||
|
||||
void led_decSpeed(){
|
||||
if (ledSpeed == 9){
|
||||
printf("Speed too slow\n\r");
|
||||
} else {
|
||||
ledSpeed++;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t getCurrentSpeed()
|
||||
{
|
||||
return ledSpeed;
|
||||
}
|
||||
|
||||
|
||||
122
labW6barnestr/Src/main.c
Normal file
122
labW6barnestr/Src/main.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* main.c
|
||||
*
|
||||
* Created on: January 12, 2022
|
||||
* Author: Trevor Barnes
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "uart_driver.h"
|
||||
#include "memory.h"
|
||||
#include "led.h"
|
||||
#include "delay.h"
|
||||
#include "piezoSpeaker.h"
|
||||
|
||||
#define F_CPU 16000000UL
|
||||
|
||||
// Super Mario "Flagpole Fanfare"
|
||||
Note songSMFF[66]= { {G3, S/3}, {Ab3,S/3}, {A3, S/3}, {Bb3,S/3}, {B3,S/3},
|
||||
{C4, S/3}, {Db4,S/3}, {D4, S/3}, {Eb4,S/3}, {E4,S/3},
|
||||
{F4, S/3}, {Gb4,S/3}, {G4, S/3}, {Ab4,S/3}, {A4,S/3},
|
||||
{Bb4,S/3}, {B4, S/3}, {C5, S/3}, {Db5,S/3}, {D5,S/3},
|
||||
{Eb5,S/3}, {E5, S/3}, {F5, S/3}, {Gb5,S/3}, {G5,S/3},
|
||||
{Ab5,S/3}, {A5, S/3}, {Bb5,S/3}, {B5, S/3}, {C6,S/3},
|
||||
{Db6,S/3}, {D6, S/3}, {Eb6,S/3}, {E6, S/3}, {F6,S/3},
|
||||
{Eb6,S/3}, {G6, S/3}, {r, 7*S}, {G3, Q}, {C4, Q},
|
||||
{E4, Q}, {G4, Q}, {C5, Q}, {E5, Q}, {G5, H},
|
||||
{E5, H}, {Ab3, Q}, {C4, Q}, {Eb4, Q}, {Ab4, Q},
|
||||
{C5, Q}, {Eb5, Q}, {Ab6, H}, {Eb5, H}, {Bb3, Q},
|
||||
{D4, Q}, {F4, Q}, {Bb4, Q}, {D5, Q}, {F5, Q},
|
||||
{Bb5, W}, {B5, Q}, {B5, Q}, {B5, Q}, {C6, W}, {T, Q} };
|
||||
|
||||
// Imperial March
|
||||
Note songIM[138] = { {A3, Q}, {r, Q}, {A3, Q}, {r, Q}, {A3, Q}, {r, Q},
|
||||
{F3,E+S}, {r, E+S}, {C4, S}, {r, S}, {A3, Q}, {r, Q},
|
||||
{F3,E+S}, {r, E+S}, {C4, S}, {r, S}, {A3, H}, {r, H},
|
||||
{E4, Q}, {r, Q}, {E4, Q}, {r, Q}, {E4, Q}, {r, Q},
|
||||
{F4,E+S}, {r, E+S}, {C4, S}, {r, S}, {Ab3, Q}, {r, Q},
|
||||
{F3,E+S}, {r, E+S}, {C4, S}, {r, S}, {A3, H}, {r, H},
|
||||
{A4, Q}, {r, Q}, {A3, E+S}, {r, E+S}, {A3, S}, {r, S},
|
||||
{A4, Q}, {r, Q}, {Ab4,E+S}, {r, E+S}, {G4, S}, {r, S},
|
||||
{Gb4, Q}, {r, S}, {E4, S}, {r, S}, {F4, E}, {r, E},
|
||||
{r, E}, {Bb3, E}, {r, E}, {Eb4, Q}, {r, Q}, {D4,E+S},
|
||||
{r, E+S}, {Db4, S}, {r, H}, {C4, S}, {r, S}, {B3, S},
|
||||
{r, S}, {C4, E}, {r, E}, {r, E}, {F3, E}, {r, E},
|
||||
{Ab3, Q}, {r, Q}, {F3, E+S}, {r, E+S}, {A3, S}, {r, S},
|
||||
{C4, Q}, {r, Q}, {A3, E+S}, {r, E+S}, {C4, S}, {r, S},
|
||||
{E4, H}, {r, H}, {A4, Q}, {r, Q}, {A3, E+S}, {r, E+S},
|
||||
{A3, S}, {r, S}, {A4, Q}, {r, S}, {Ab4,E+S}, {r, E+S},
|
||||
{G4, S}, {r, S}, {Gb4, S}, {r, S}, {E4, S}, {r, S},
|
||||
{F4, E}, {r, E}, {r, E}, {Bb3, E}, {r, E}, {Eb4, Q},
|
||||
{r, Q}, {D4,E+S}, {r, E+S}, {Db4, S}, {r, S}, {C4, S},
|
||||
{r, S}, {B3, S}, {r, S}, {C4, E}, {r, E}, {r, E},
|
||||
{F3, E}, {r, E}, {Ab3, Q}, {r, Q}, {F3, E+S}, {r, E+S},
|
||||
{C4, S}, {r, S}, {A3, Q}, {r, Q}, {F3, E+S}, {r, E+S},
|
||||
{C4, S}, {r, S}, {A3, H}, {r, H}, {T, Q} };
|
||||
|
||||
void printHelp() {
|
||||
printf("*Commands*\n\r");
|
||||
printf("'rmw {hex address}' - Reads mem at a given address\n\r");
|
||||
printf("'wmw {hex address} {value}' - Writes the given value as a word to the given address\n\r");
|
||||
printf("'dm {hex address} {length}' - Dumps the memory at a given address. Defaults to 16 B if no "
|
||||
"length is given\n\r");
|
||||
printf("'ps {song choice}' - Plays a song with the given selection\n\r");
|
||||
printf("'songs' - Prints info about each song selection\n\r");
|
||||
}
|
||||
void songInfo() {
|
||||
printf("Type 1 or 2 to play a song!\n\r");
|
||||
printf("Song 1: Imperial March\n\r");
|
||||
printf("Song 2: Super Mario Bros Flagpole Fanfare\n\r");
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
init_usart2(57600, F_CPU);
|
||||
piezo_init();
|
||||
led_init();
|
||||
char line[50];
|
||||
char command[10];
|
||||
int address;
|
||||
int data;
|
||||
int length;
|
||||
int songSelection;
|
||||
// play_note(261.63, 10000.00);
|
||||
for(;;) {
|
||||
// Get command from user
|
||||
fgets(line, 100, stdin);
|
||||
// Parse only the command for strcmp
|
||||
sscanf(line, "%s", command);
|
||||
if (!strcmp(command, "help")) {
|
||||
printHelp();
|
||||
} else if (!strcmp(command, "songs")) {
|
||||
songInfo();
|
||||
} else if (!strcmp(command, "rmw")) {
|
||||
sscanf(line, "%s %X", command, &address);
|
||||
readMem(address);
|
||||
} else if (!strcmp(command, "wmw")) {
|
||||
sscanf(line, "%s %X %u", command, &address, &data);
|
||||
writeMem(address, data);
|
||||
} else if (!strcmp(command, "dm")) {
|
||||
sscanf(line, "%s %X %u", command, &address, &length);
|
||||
dumpMem(address, length);
|
||||
} else if (!strcmp(command, "ps")) {
|
||||
sscanf(line, "%s %u", command, &songSelection);
|
||||
switch(songSelection) {
|
||||
case 1:
|
||||
printf("Playing Imperial March\n\r");
|
||||
play_song(&songIM[0]);
|
||||
break;
|
||||
case 2:
|
||||
printf("Playing Super Mario Bros Flagpole Fanfare\n\r");
|
||||
play_song(&songSMFF[0]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
printf("Invalid input, type 'help' for instructions\n\r");
|
||||
}
|
||||
}
|
||||
}
|
||||
66
labW6barnestr/Src/memory.c
Normal file
66
labW6barnestr/Src/memory.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @file memory.c
|
||||
* @author Trevor Barnes
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2022-01-19
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "memory.h"
|
||||
|
||||
#define F_CPU 16000000UL
|
||||
|
||||
void initMemConsole() {
|
||||
init_usart2(57600, F_CPU);
|
||||
printf("Memory Console Initialized! Type 'help' for info.\n\r");
|
||||
}
|
||||
|
||||
void readMem(uint32_t addr) {
|
||||
// Assign and casts a new int pointer the value of addr
|
||||
uint32_t * memPtr = (uint32_t *)addr;
|
||||
// Formatted print with both hex and decimal values
|
||||
printf("Memory Value at %#08x\n\r"
|
||||
"Hex: %#08x\n\r"
|
||||
"Decimal: %d\n\r", addr, *memPtr, *memPtr);
|
||||
return;
|
||||
}
|
||||
|
||||
void writeMem(uint32_t addr, uint32_t data) {
|
||||
// Assign and casts a new int pointer the value of addr
|
||||
uint32_t * memPtr = (uint32_t *)addr;
|
||||
// Write data
|
||||
*memPtr = data;
|
||||
// Confirmation printout showing the new value and address
|
||||
printf("Value written at %#08x: %u \n\r", addr, data);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void dumpMem(uint32_t addr, int length) {
|
||||
// Set length to default value if length is negative
|
||||
// (No limit or protection for large, overflow values yet)
|
||||
if(length <= 0) {
|
||||
length = 16;
|
||||
printf("Length set to default! (16)\n\r");
|
||||
}
|
||||
// Assign and casts a new int pointer the value of addr
|
||||
uint8_t * memPtr = (uint8_t *)addr;
|
||||
// Loop that executes each read and print operation
|
||||
for(int i=0 ; i < length ; i++) {
|
||||
// Print newline and memory location every 16 bytes
|
||||
if((i % 16) == 0) {
|
||||
printf("\n\r%p:", memPtr);
|
||||
}
|
||||
// Print each byte
|
||||
printf(" %02X", *memPtr);
|
||||
// Iterate pointer to next byte
|
||||
memPtr++;
|
||||
}
|
||||
printf("\n\r");
|
||||
return;
|
||||
}
|
||||
0
labW6barnestr/Src/piezoInt.c
Normal file
0
labW6barnestr/Src/piezoInt.c
Normal file
82
labW6barnestr/Src/piezoSpeaker.c
Normal file
82
labW6barnestr/Src/piezoSpeaker.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* @file piezoSpeaker.c
|
||||
* @author Trevor Barnes
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2022-01-19
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "piezoSpeaker.h"
|
||||
#include "delay.h"
|
||||
|
||||
|
||||
void piezo_init(){
|
||||
|
||||
//enable GPIOB and Timer 3 RCC
|
||||
*RCC_AHB1ENR |= (1<<GPIOBEN);
|
||||
*RCC_APB1ENR |= (1<<TIM3_EN);
|
||||
|
||||
//set GPIO B to alternate function (0b10<<9)
|
||||
//clears the two bits and then set it
|
||||
*GPIOB_MODER = (*GPIOB_MODER&~(0b11<<8)) | (PB4_AF_V<<8);
|
||||
|
||||
//set alternate function low register to TIM3
|
||||
*GPIOB_AFRL |= (1<<AFRL_TIM3_CH1_EN);
|
||||
|
||||
//Configure capture/compare mode register configuration
|
||||
//to enable preload and set to pwm
|
||||
*TIM3_CCMR1 |= OC1M_PWM2;
|
||||
*TIM3_CCMR1 |= (1<<OC1PE);
|
||||
|
||||
//Configure CCER to enable timer 3 as output capture
|
||||
*TIM3_CCER |= CCER_CC1E;
|
||||
|
||||
//Configure control register to enable preload
|
||||
*TIM3_CR1 |= (1<<CR_ARPE_EN);
|
||||
|
||||
}
|
||||
|
||||
play_note(Note noteToPlay) {
|
||||
|
||||
//void play_note(double playFrequency, double playDuration) {
|
||||
|
||||
double freq = noteToPlay.noteFrequency;
|
||||
double dur = noteToPlay.noteDuration;
|
||||
|
||||
*TIM3_PSC = 15;
|
||||
//Divisor controls pitch
|
||||
*TIM3_ARR = mil/freq;
|
||||
|
||||
//Loudness (Smaller dividend = louder sound)
|
||||
freq = freq/10;
|
||||
|
||||
//clear ccr1
|
||||
*TIM3_CCR1 = (*TIM3_CCR1&~(0xFFFF));
|
||||
*TIM3_CCR1 = freq;
|
||||
|
||||
//set EGR (accept only a byte of info so steps)
|
||||
*TIM3_EGR |= EGR_UG;
|
||||
|
||||
//~~~Plays the notes
|
||||
//Enables enable bit control register
|
||||
*TIM3_CR1 |= 1;
|
||||
//delay that leaves the speaker on for desired amount of time
|
||||
delay_1ms(dur);
|
||||
//Disables enable bit
|
||||
*TIM3_CR1 &= ~1;
|
||||
}
|
||||
|
||||
|
||||
void play_song(Note *songToPlay){
|
||||
int i = 0;
|
||||
double freq = songToPlay[i].noteFrequency;
|
||||
while(freq != T) {
|
||||
play_note(songToPlay[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
92
labW6barnestr/Src/uart_driver.c
Normal file
92
labW6barnestr/Src/uart_driver.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* uart_driver.c
|
||||
*
|
||||
* Created on: Nov 8, 2016
|
||||
* Author: barnekow
|
||||
*/
|
||||
#include "uart_driver.h"
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
// These will override _read and _write in syscalls.c, which are
|
||||
// prototyped as weak
|
||||
int _read(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
// Modified the for loop in order to get the correct behavior for fgets
|
||||
int byteCnt = 0;
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
//*ptr++ = __io_getchar();
|
||||
byteCnt++;
|
||||
//*ptr++ = usart2_getch();
|
||||
*ptr = usart2_getch();
|
||||
if(*ptr == '\n') break;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
//return len;
|
||||
return byteCnt; // Return byte count
|
||||
}
|
||||
|
||||
int _write(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
usart2_putch(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char usart2_getch(){
|
||||
char c;
|
||||
while((*(USART_SR)&(1<<RXNE)) != (1<<RXNE));
|
||||
c = ((char) *USART_DR); // Read character from usart
|
||||
usart2_putch(c); // Echo back
|
||||
|
||||
if (c == '\r'){ // If character is CR
|
||||
usart2_putch('\n'); // send it
|
||||
c = '\n'; // Return LF. fgets is terminated by LF
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void usart2_putch(char c){
|
||||
while((*(USART_SR)&(1<<TXE)) != (1<<TXE));
|
||||
*(USART_DR) = c;
|
||||
}
|
||||
|
||||
void init_usart2(uint32_t baud, uint32_t sysclk){
|
||||
// Enable clocks for GPIOA and USART2
|
||||
*(RCC_AHB1ENR) |= (1<<GPIOAEN);
|
||||
*(RCC_APB1ENR) |= (1<<USART2EN);
|
||||
|
||||
// Function 7 of PORTA pins is USART
|
||||
*(GPIOA_AFRL) &= (0xFFFF00FF); // Clear the bits associated with PA3 and PA2
|
||||
*(GPIOA_AFRL) |= (0b01110111<<8); // Choose function 7 for both PA3 and PA2
|
||||
*(GPIOA_MODER) &= (0xFFFFFF0F); // Clear mode bits for PA3 and PA2
|
||||
*(GPIOA_MODER) |= (0b1010<<4); // Both PA3 and PA2 in alt function mode
|
||||
|
||||
// Set up USART2
|
||||
//USART2_init(); //8n1 no flow control
|
||||
// over8 = 0..oversample by 16
|
||||
// M = 0..1 start bit, data size is 8, 1 stop bit
|
||||
// PCE= 0..Parity check not enabled
|
||||
// no interrupts... using polling
|
||||
*(USART_CR1) = (1<<UE)|(1<<TE)|(1<<RE); // Enable UART, Tx and Rx
|
||||
*(USART_CR2) = 0; // This is the default, but do it anyway
|
||||
*(USART_CR3) = 0; // This is the default, but do it anyway
|
||||
*(USART_BRR) = sysclk/baud;
|
||||
|
||||
/* I'm not sure if this is needed for standard IO*/
|
||||
//setvbuf(stderr, NULL, _IONBF, 0);
|
||||
//setvbuf(stdin, NULL, _IONBF, 0);
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user