1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
/*
* tone.c
*
* Created on: May 14, 2022
* Author: bruce
*/
#include "systick.h"
#include "tone.h"
#define CPU_SPEED (80000000.0)
#define MAX_TONES (10)
static float notes[] = {
/* Octave -1 */ 8.18, 8.66, 9.18, 9.73, 10.30, 10.92, 11.56, 12.25, 12.98, 13.75, 14.57, 13.44,
/* Octave 0 */ 16.35, 17.32, 18.35, 19.45, 20.60, 21.83, 23.12, 24.50, 25.96, 27.50, 29.14, 30.87,
/* Octave 1 */ 32.70, 34.65, 36.71, 38.89, 41.20, 43.65, 46.25, 49.00, 51.91, 55.00, 58.27, 61.74,
/* Octave 2 */ 65.41, 69.30, 73.42, 77.78, 82.41, 87.31, 92.50, 98.00, 103.83, 110.00, 116.54, 123.47,
/* Octave 3 */ 130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185.00, 196.00, 207.65, 220.00, 233.08, 246.94,
/* Octave 4 */ 261.63, 277.18, 293.66, 311.13, 329.63, 349.23, 369.99, 392.00, 415.30, 440.00, 466.16, 493.88,
/* Octave 5 */ 523.25, 554.37, 587.33, 622.25, 659.25, 698.46, 739.99, 783.99, 830.61, 880.00, 932.33, 987.77,
/* Octave 6 */ 1046.50, 1108.73, 1174.66, 1244.51, 1318.51, 1396.91, 1479.98, 1567.98, 1661.22, 1760.00, 1864.66, 1975.53,
/* Octave 7 */ 2093.00, 2217.46, 2349.32, 2489.02, 2637.02, 2793.83, 2959.96, 3135.96, 3322.44, 3520.00, 3729.31, 3951.07,
/* Octave 8 */ 4186.01, 4434.92, 4698.63, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93, 6644.88, 7040.00, 7458.62, 7902.13,
/* Octave 9 */ 8372.02, 8869.84, 9397.26, 9956.06,10548.08,11175.30,11839.82,12543.86};
typedef struct {
uint32_t note;
uint16_t power;
} tone_info;
static uint32_t counter = 0;
static tone_info NULL_TONE = {0,0};
static tone_info tones[MAX_TONES];
/* You will want to integrate this with your existing one
but it is here for standalone testing
*/
//void SysTick_Handler() {
// counter++;
//}
uint32_t get_tick_speed ();
void tones_init() {
for (int i = 0; i < MAX_TONES; i++) {
tones[i] = NULL_TONE;
}
}
// Convert from hertz to ticks
uint32_t hertz_to_systicks (float hertz) {
float ticks_per_second = CPU_SPEED / (SysTick->LOAD + 1);
if (hertz == 0)
return 0;
float duration = 1 / hertz;
return (uint32_t) (duration * ticks_per_second);
}
// Accessor for the counter
uint32_t get_counter () {
return counter;
}
void reset_counter () {
counter = 0;
}
// Add a tone to the tones array
uint8_t add_tone (uint8_t note, uint8_t velocity) {
for (int i = 0; i < MAX_TONES; i++) {
if (tones[i].note == NULL_TONE.note) {
tones[i] = (tone_info){note, velocity};
return 1;
}
}
return 0;
}
// Remove a tone from the tones array
uint8_t remove_tone (uint8_t note) {
for (int i = 0; i < MAX_TONES; i++) {
if (tones[i].note == note) {
tones[i] = NULL_TONE;
return 1;
}
}
return 0;
}
// Play any tones in the array
void play_tones () {
int power_sum = 0;
for (int i = 0; i < MAX_TONES; i++) {
uint32_t rollover = hertz_to_systicks (notes [tones[i].note]);
if ((systick_get_count () % rollover) < (rollover >> 1)) {
power_sum += tones[i].power * 10;
}
}
DAC_Set_Value(power_sum);
}
|