-
Notifications
You must be signed in to change notification settings - Fork 0
/
mm.txt
154 lines (125 loc) · 3.54 KB
/
mm.txt
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <stdio.h>
#include <time.h>
#include <math.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "hardware/irq.h"
#include "hardware/adc.h"
#include "hardware/gpio.h"
#include "pico/util/queue.h"
#include "pico/multicore.h"
/*
PIN 13: Modulation-Enable Switch
PIN 15: PWM for controlling the time
PIN 26: Delay-Time potentiometer
PIN 27: Mod-Freq potentiometer
PIN 28: Mod-Amp potentiometer
*/
#define MOD_SWT 13 // Swtch for toggling modulation
#define PWM_PIN 0
#define DTIM_PIN 26 // Mod OFF: Delay Time; MOD ON: Timeoffset in modulation
#define MFRQ_PIN 27 // MOD ON: Frequency of modulation
#define MAMP_PIN 28 // MOD ON: Amplitude of modulation
static const uint adc_res = 4096;
static const uint maxCounter = 0xffff;
typedef struct {
uint slice;
uint16_t adcVal[2];
uint val;
} pwmdata;
static pwmdata modPWM;
clock_t getClock() {
return (clock_t) time_us_64() / 1e4;
}
/* Interrupt routine for setting the duty cycle ratio */
void pwm_out() {
pwm_clear_irq(pwm_gpio_to_slice_num(PWM_PIN));
pwm_set_gpio_level(PWM_PIN, modPWM.val);
}
void setupPWM() {
gpio_set_function(PWM_PIN, GPIO_FUNC_PWM);
modPWM.slice = pwm_gpio_to_slice_num(PWM_PIN);
pwm_clear_irq(modPWM.slice);
pwm_set_irq_enabled(modPWM.slice, true);
irq_set_exclusive_handler(PWM_IRQ_WRAP, pwm_out);
irq_set_enabled(PWM_IRQ_WRAP, true);
pwm_config config = pwm_get_default_config();
pwm_config_set_clkdiv(&config, 4.f);
// Load the configuration into our PWM slice, and set it running.
pwm_init(modPWM.slice, &config, true);
modPWM.val = 60e3;
}
void setPWMnoMod(uint16_t* adcData) {
float d = ((float)(*adcData)/(float)adc_res) * (float)maxCounter; // For using the whole value range of the PWM counter
printf("%d\n", (uint)d);
modPWM.val = (uint) d;
}
void setPWMMod(uint16_t* adcData) {
float a = (float) *(adcData + 2);
float b = (float) *(adcData + 1);
float d = ((float)(*adcData)/(float)adc_res) * (float)maxCounter; // For using the whole value range of the PWM counter
clock_t t1 = getClock();
float modulation = 4 * a * sin(b/2 * t1) + d; // Range the period should be between ~0.05Hz and 50Hz; b therefore must be in the range of 7.2 to 7.2e3 (2*adcRes)
//printf("Mod Value: %f = %f * sin(2 * %f * t) + %f\n", modulation, a, b, d);
// Catch over or underflows
if (modulation > (float)maxCounter) {
modulation = maxCounter;
}
else if (modulation < 0.0f) {
modulation = 0;
}
printf("%d\n", (uint) modulation);
modPWM.val = (uint) modulation;
}
void setupADC() {
adc_init();
adc_gpio_init(DTIM_PIN);
adc_gpio_init(MFRQ_PIN);
adc_gpio_init(MAMP_PIN);
}
void loopADC() {
uint16_t dat[2] = {0};
int cnt = 0;
adc_select_input(cnt);
while (true) {
*(dat+cnt) = adc_read();
modPWM.adcVal[cnt] = *(dat+cnt);
cnt++;
if (cnt > 2) {
cnt = 0;
}
adc_select_input(cnt);
}
}
void setupGPIO() {
gpio_init(MOD_SWT);
gpio_set_dir(MOD_SWT, GPIO_IN);
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
gpio_put(PICO_DEFAULT_LED_PIN, 1);
sleep_ms(1e3);
gpio_put(PICO_DEFAULT_LED_PIN, 0);
}
void thread_modcalc() {
bool enabled;
while (true)
{
enabled = gpio_get(MOD_SWT);
if (enabled) {
gpio_put(PICO_DEFAULT_LED_PIN, 1);
setPWMMod(modPWM.adcVal);
}
else {
gpio_put(PICO_DEFAULT_LED_PIN, 0);
setPWMnoMod(modPWM.adcVal);
}
}
}
int main() {
stdio_init_all();
multicore_launch_core1(thread_modcalc);
setupPWM();
setupGPIO();
setupADC();
loopADC();
}