#include "Peripherals.h"
-Potentiometer::Potentiometer(const int min, const int max, update_callback_t update_ntfy)
+gpio_config_t btn_config = {
+ .pin_bit_mask = (uint64_t) 0,
+ .mode = GPIO_MODE_INPUT,
+ .pull_up_en = GPIO_PULLUP_DISABLE,
+ .pull_down_en = GPIO_PULLDOWN_ENABLE,
+ .intr_type = GPIO_INTR_ANYEDGE
+};
+
+static void btn_isr_handler(void*);
+
+void btn_isr_handler(void *args) {
+ Button* obj = (Button*) args;
+ if (obj->on_change != NULL) {
+ bool state = obj->getPressed();
+ (*obj->on_change)(state);
+ }
+}
+
+Potentiometer::Potentiometer(const int min, const int max, pot_update_callback_t update_ntfy)
: Potentiometer(ADC_UNIT_1, ADC_CHANNEL_1, min, max, update_ntfy) {}
-Potentiometer::Potentiometer(const adc_unit_t unit, const adc_channel_t channel, const int min, const int max, update_callback_t update_ntfy)
+Potentiometer::Potentiometer(const adc_unit_t unit, const adc_channel_t channel, const int min, const int max, pot_update_callback_t update_ntfy)
: adc_unit(unit),
adc_channel(channel),
min_raw(min),
int raw = get_raw();
return ((float)raw / (4096)) * 100;
}
+
+Button::Button(gpio_num_t gpio_pin, btn_update_callback_t update_ntfy)
+ : on_change(update_ntfy),
+ gpio_pin(gpio_pin) {
+ gpio_config_t config = btn_config;
+ config.pin_bit_mask = (1 << gpio_pin);
+ gpio_config(&config);
+
+ // static esp_err_t isr_service_init = gpio_install_isr_service(0);
+ // gpio_isr_handler_add(gpio_pin, btn_isr_handler, this);
+}
+
+bool Button::getPressed() {
+ return (bool) gpio_get_level(gpio_pin);
+}
+
+bool Button::getPressedSingle() {
+ bool state = (bool) gpio_get_level(gpio_pin);
+ bool ret = state && !lastState;
+ lastState = state;
+ return ret;
+}
#define INPUT_TIMER TIMER_0
#define DISPLAY_TIMER TIMER_1
-#define SCREENWIDTH 128
-#define SCREENHEIGHT 32
+#define SCREEN_WIDTH 128
+#define SCREEN_HEIGHT 32
+#define INPUT_INTERVAL_S 0.01
+#define DISPLAY_INTERVAL_S 0.09
+#define POT1_CHANNEL ADC_CHANNEL_5
+
+#define BTN1_PIN GPIO_NUM_4
+#define BTN2_PIN GPIO_NUM_2
+#define BTN3_PIN GPIO_NUM_15
+
+// -------------- Flags --------------
enum StatusBM {
BT = 1,
PLAY = 2,
STOP = 4,
PAUSE = 8
};
-
enum eventBM {
DISPLAY = 1,
INPUT = 2,
};
+// -----------------------------------
-
+// -------------- Configs --------------
timer_config_t timer_config = {
.alarm_en = TIMER_ALARM_EN,
.counter_en = TIMER_PAUSE,
+ .intr_type = TIMER_INTR_LEVEL,
.counter_dir = TIMER_COUNT_UP,
.auto_reload = TIMER_AUTORELOAD_EN,
.divider = TIMER_DIVIDER,
};
+// -------------------------------------
u8g2_t u8g2;
u8g2_esp32_hal_t u8g2_esp32_hal;
+xQueueHandle event_queue;
+// -------------- Global tracking vars --------------
char* titleText = (char*) "";
char* artistText = (char*) "";
-xQueueHandle event_queue;
-
int8_t displayStatus = 0;
int8_t event = 0;
-
-double input_timer_interval = 0.01; // seconds
-double display_timer_interval = 0.1; // seconds
int x = 0;
+// --------------------------------------------------
+// -------------- Function definitions --------------
void update_display(al_event_cb_t, al_event_cb_param_t*);
-void draw();
-void thisfunc();
+void IRAM_ATTR draw();
bool IRAM_ATTR input_timer_cb(void* args);
bool IRAM_ATTR display_timer_cb(void* args);
+// --------------------------------------------------
-
+// -------------- Object definitions --------------
Audiolib Audiosource = Audiolib("HESA FREDRIK", &update_display);
-//void updateFilter(const uint8_t, float*, float*, CombinedChannelFilter*);
-Potentiometer* pot1 = new Potentiometer(ADC_UNIT_2, ADC_CHANNEL_5, 70, 1010); //65/66 -> 572/573 -> 1019
+Potentiometer* pot1 = new Potentiometer(ADC_UNIT_2, POT1_CHANNEL, 70, 1010); //65/66 -> 572/573 -> 1019
//Potentiometer* pot2 = new Potentiometer(ADC1_CHANNEL_4, 41, 988);
//Potentiometer* pot3 = new Potentiometer(ADC1_CHANNEL_6, 38, 988);
//Potentiometer* pot4 = new Potentiometer(ADC1_CHANNEL_7, 29, 990);
+Button* btn1 = new Button(BTN1_PIN);
+Button* btn2 = new Button(BTN2_PIN);
+Button* btn3 = new Button(BTN3_PIN);
+
CombinedChannelFilter* highshelf_filter = new CombinedChannelFilter(new Filter(HIGHSHELF, 2000, 44100, 0.8, 0), new Filter(HIGHSHELF, 2000, 44100, 0.8, 0));
CombinedChannelFilter* lowshelf_filter = new CombinedChannelFilter(new Filter(LOWSHELF, 250, 44100, 0.8, 0), new Filter(LOWSHELF, 250, 44100, 0.8, 0));
CombinedChannelFilter* highpass_filter = new CombinedChannelFilter(new Filter(LOWPASS, 8000, 44100, 0.75, 0), new Filter(LOWPASS, 8000, 44100, 0.75, 0));
CombinedChannelFilter* lowpass_filter = new CombinedChannelFilter(new Filter(HIGHPASS, 60, 44100, 0.75, 0), new Filter(HIGHPASS, 60, 44100, 0.75, 0));
CombinedChannelFilter* peak_filter = new CombinedChannelFilter(new Filter(PEAK, 700, 44100, 0.8, 0), new Filter(PEAK, 700, 44100, 0.8, 0));
+// ------------------------------------------------
extern "C" {
void app_main(void){
- // -------------- U8G2 Setup --------------
+ // -------------- U8G2 setup --------------
u8g2_esp32_hal.sda = GPIO_NUM_32;
u8g2_esp32_hal.scl = GPIO_NUM_33;
u8g2_esp32_hal_init(u8g2_esp32_hal);
event_queue = xQueueCreate(10, 1);
- // -------------- Audiosource Setup --------------
+ // -------------- Audiosource setup --------------
Audiosource.set_I2S(26, 27, 25);
Audiosource.add_combined_filter(highpass_filter);
Audiosource.add_combined_filter(lowshelf_filter);
Audiosource.start();
// -----------------------------------------------
- // -------------- Timer Setup --------------
+ // -------------- Timer setup --------------
timer_init(TIMER_GROUP_0, INPUT_TIMER, &timer_config);
timer_set_counter_value(TIMER_GROUP_0, INPUT_TIMER, 0);
- timer_set_alarm_value(TIMER_GROUP_0, INPUT_TIMER, input_timer_interval * TIMER_SCALE);
+ timer_set_alarm_value(TIMER_GROUP_0, INPUT_TIMER, INPUT_INTERVAL_S * TIMER_SCALE);
timer_enable_intr(TIMER_GROUP_0, INPUT_TIMER);
timer_isr_callback_add(TIMER_GROUP_0, INPUT_TIMER, &input_timer_cb, nullptr, 0);
timer_init(TIMER_GROUP_0, DISPLAY_TIMER, &timer_config);
timer_set_counter_value(TIMER_GROUP_0, DISPLAY_TIMER, 0);
- timer_set_alarm_value(TIMER_GROUP_0, DISPLAY_TIMER, display_timer_interval * TIMER_SCALE);
+ timer_set_alarm_value(TIMER_GROUP_0, DISPLAY_TIMER, DISPLAY_INTERVAL_S * TIMER_SCALE);
timer_enable_intr(TIMER_GROUP_0, DISPLAY_TIMER);
timer_isr_callback_add(TIMER_GROUP_0, DISPLAY_TIMER, &display_timer_cb, nullptr, 0);
if (event & DISPLAY) {
draw();
}
-
-
-
+ if (event & INPUT) {
+ if (btn1->getPressedSingle()){
+ Audiosource.previous();
+ }
+ if (btn2->getPressedSingle()) {
+ if (displayStatus & PLAY) {
+ Audiosource.pause();
+ }
+ else if (displayStatus & (PAUSE | STOP)){
+ Audiosource.play();
+ }
+ }
+ if (btn3->getPressedSingle()) {
+ Audiosource.next();
+ }
+ }
}
}
}
-void IRAM_ATTR draw() {
+void draw() {
if (displayStatus & BT) {
- u8g2_DrawGlyph(&u8g2, 0, SCREENHEIGHT/2, 127);
+ u8g2_DrawGlyph(&u8g2, 0, SCREEN_HEIGHT/2, 127);
}
if (displayStatus & STOP) {
- u8g2_DrawGlyph(&u8g2, 12, SCREENHEIGHT/2, 129);
+ u8g2_DrawGlyph(&u8g2, 12, SCREEN_HEIGHT/2, 129);
}
else if (displayStatus & PAUSE) {
- u8g2_DrawGlyph(&u8g2, 12, SCREENHEIGHT/2, 130);
+ u8g2_DrawGlyph(&u8g2, 12, SCREEN_HEIGHT/2, 130);
}
else if (displayStatus & PLAY) {
- u8g2_DrawGlyph(&u8g2, 12, SCREENHEIGHT/2, 128);
+ u8g2_DrawGlyph(&u8g2, 12, SCREEN_HEIGHT/2, 128);
}
if ((displayStatus & PLAY) || (displayStatus & STOP) || (displayStatus & PAUSE)) {
- u8g2_DrawStr(&u8g2, 23, SCREENHEIGHT/2, artistText);
- u8g2_DrawStr(&u8g2, x, SCREENHEIGHT, titleText);
+ u8g2_DrawStr(&u8g2, 23, SCREEN_HEIGHT/2, artistText);
+ u8g2_DrawStr(&u8g2, x, SCREEN_HEIGHT, titleText);
x += 1;
- if (x == SCREENWIDTH) x = 0;
+ if (x == SCREEN_WIDTH) x = 0;
}
else {
- u8g2_DrawStr(&u8g2, 0, SCREENHEIGHT/2, "Disconnected!");
- u8g2_DrawStr(&u8g2, 0, SCREENHEIGHT, "Connect Device!");
+ u8g2_DrawStr(&u8g2, 0, SCREEN_HEIGHT/2, "Disconnected!");
+ u8g2_DrawStr(&u8g2, 0, SCREEN_HEIGHT, "Connect Device!");
}
u8g2_SendBuffer(&u8g2);
u8g2_ClearBuffer(&u8g2);
if ((*artistText == '\0') || (*titleText == '\0')) {
displayStatus = BT | STOP;
}
+ x = 0;
printf("AL, Meta_Update\n");
break;
}