Compare commits

..

6 Commits

Author SHA1 Message Date
rkcf 883e431ce3 Chore: add .gdbinit to .gitignore 2023-02-25 03:49:49 -06:00
rkcf e8eff42a93 Docs: add latest version header to README 2023-02-20 08:55:28 -06:00
rkcf 9c043785d2 Add: .gitignore 2023-02-20 08:23:56 -06:00
rkcf f960dba5a8 Docs: add project setup section to README 2023-02-20 08:18:05 -06:00
rkcf 3287956c5d Docs: add contributing and license sections to README 2023-02-20 08:14:08 -06:00
rkcf 6945c7bc0c Add: LICENSE 2023-02-20 08:13:34 -06:00
7 changed files with 63 additions and 172 deletions

12
.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
# schematic files
hardware/
# compiler data
build/
src/.cache/
src/.gdbinit
src/compile_commands.json
# local configs
src/sdkconfig
src/sdkconfig.old

7
LICENSE Normal file
View File

@ -0,0 +1,7 @@
Copyright © 2023 Andrew Steinke <rkcf@rkcf.me>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,5 +1,11 @@
#+TITLE: ESP32 Eurorack Generic Module #+TITLE: ESP32 Eurorack Generic Module
--------------------------------------------------------------------------------
#+BEGIN_CENTER
*Latest Schematic Version: 0.2.0* || *Latest Code Version: Rolling*
#+END_CENTER
--------------------------------------------------------------------------------
This project aims to create a generic esp32-s3 based eurorack modular unit—reprogramable to allow for multiple modular possibilities. This project aims to create a generic esp32-s3 based eurorack modular unit—reprogramable to allow for multiple modular possibilities.
* Specs * Specs
@ -7,13 +13,44 @@ This project aims to create a generic esp32-s3 based eurorack modular unit—rep
- I/O - I/O
- 4 channel input - 4 channel input
- 4 channel output - 4 channel output
- Output signal 0 -> ~+5V - Output signal 0 -> +5V
- 2 Rotary encoder switches - 2 Rotary encoder switches
- 4 buttons - 4 buttons
- 2.2in TFT LCD Display - 2.2in TFT LCD Display
* Hardware * Project Setup
** MCP4728 Quad 12bit I2C DAC Clone the repository over ssh.
- [[https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/22187E.pdf][Datasheet]] #+BEGIN_SRC shell
- [[https://learn.adafruit.com/adafruit-mcp4728-i2c-quad-dac][Adafruit Info Page]] git clone git@gitea.rkcf.me/rkcf/esp32_eurorack_generic.git
- 0 -> ~+5V out cd esp32_eurorack_generic
#+END_SRC
Source idf path. Assumes [[https://docs.espressif.com/projects/esp-idf/en/v5.0/esp32s3/get-started/index.html#installation][ESP-IDF]] properly configured on system.
#+BEGIN_SRC shell
. $YOUR_PATH_TO_ESP_IDF/export.sh
#+END_SRC
Set the target chip and configure the project. NOTE: Running menuconfig is not currently necessary for this project.
#+BEGIN_SRC shell
idf.py set-target esp32s3
idf.py menuconfig
#+END_SRC
Building and flashing the project. Where $PORT is the boards serial port system address (e.g. /dev/ttyUSB0).
#+BEGIN_SRC shell
idf.py build
idf.py -p $PORT flash
idf.py -p $PORT monitor
#+END_SRC
Or do all of this in one go with:
#+BEGIN_SRC shell
idf.py -p $PORT flash monitor
#+END_SRC
* Contributing
- Currently this branch is bleeding edge for rapid prototyping. In the future, a design will be homolugated and [[https://semver.org/][Semantic Versioning 2.0.0]] will be used. Note that schematics have their own versioning seperate from the code base.
- Commit messages should follow [[https:www.conventionalcommits.org/en/v1.0.0/][Conventional Commits 1.0.0]]
* License
This project is licensed under the [[https://choosealicense.com/licenses/mit/][MIT License]]

View File

@ -1,2 +1,2 @@
idf_component_register(SRCS "esp32_eurorack_generic.c" "wavetable.c" idf_component_register(SRCS "esp32_eurorack_generic.c"
INCLUDE_DIRS ".") INCLUDE_DIRS ".")

View File

@ -1,129 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdint.h>
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/portmacro.h"
#include "hal/i2c_types.h"
#include "wavetable.h"
/* DAC Peripheral Config */
#define DAC_SCL_PIN 12
#define DAC_SDA_PIN 13
#define DAC_LDAC_PIN 14
#define DAC_ADDR 0x64 /* I2C Address of DAC */
#define DAC_VREF 0x00 /* Use Vdd as reference voltage */
#define DAC_PD 0x00 /* Full power mode */
#define DAC_GAIN 0x00 /* Since we use external Vref, this doesn't matter */
#define ACK_EN 0x1 /* Enable i2c acknowledgment check */
#define ACK_DIS 0x0 /* Disable i2c acknowledgment check */
#define ACK_VAL 0x0 /* i2c acknowledgment value */
#define NACK_VAL 0x1 /* i2c negative-acknowledgment value */
static const i2c_port_t I2C_MASTER_PORT = 0;
static const char *TAG = "EERG";
/* Initialize and configure I2C DAC */
static void dac_init(void)
{
ESP_LOGI(TAG, "Initializing DAC I2C connection");
/* Configure µC as I2C master */
i2c_config_t i2c_conf = {
.mode = I2C_MODE_MASTER,
.scl_io_num = DAC_SCL_PIN,
.sda_io_num = DAC_SDA_PIN,
.master.clk_speed = 400000 /* 400kHz for i2c fast mode */
};
i2c_param_config(I2C_MASTER_PORT, &i2c_conf);
/* Install i2c driver */
ESP_ERROR_CHECK(i2c_driver_install(I2C_MASTER_PORT, i2c_conf.mode, 0, 0, 0));
/* Setup LDAC pin with GPIO. Tied low */
gpio_reset_pin(DAC_LDAC_PIN);
gpio_set_direction(DAC_LDAC_PIN, GPIO_MODE_OUTPUT);
gpio_set_level(DAC_LDAC_PIN, 0);
}
/* Tests for acknowledgment of i2c DAC. Return ESP_OK if so */
static esp_err_t dac_ack_test(void)
{
ESP_LOGI(TAG, "Testing I2C DAC");
/* Create i2c command handle */
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (DAC_ADDR << 1) | I2C_MASTER_READ, ACK_EN); /* R/W byte is LSB of DAC address */
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_PORT, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
return ret;
}
/* Brings all DAC output channels from 0 -> ~+5V */
static esp_err_t dac_out_test(void)
{
esp_err_t ret;
uint16_t test_value = 0; /* The value sent to DAC input registers */
i2c_cmd_handle_t cmd;
for (uint16_t i = 0; i < 4096; i++){
test_value = i;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (DAC_ADDR << 1) | I2C_MASTER_WRITE, ACK_EN); /* R/W byte is LSB of DAC address */
i2c_master_write_byte(cmd, 0x50, ACK_EN); /* Multi-write to all channels */
/* For each channel [A-D] write 2 bytes to input register */
/* V_ref + PD1 + PD0 + Gx + D11-D8 | D7-D0 */
for (uint8_t i = 0; i < 4; i++) {
uint8_t bytes[2];
bytes[0] = ((uint8_t) DAC_VREF << 7) | ((uint8_t) DAC_PD << 5) | ((uint8_t) DAC_GAIN << 4) | (test_value >> 8);
bytes[1] = test_value;
i2c_master_write_byte(cmd, bytes[0], ACK_EN);
i2c_master_write_byte(cmd, bytes[1], ACK_EN);
}
i2c_master_stop(cmd);
/* Issue the multi-write command */
/* TODO need to create array of returns and check them for error */
ret = i2c_master_cmd_begin(I2C_MASTER_PORT, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
}
return ret;
}
/* Main application entrance */
void app_main(void) void app_main(void)
{ {
/* Initialize and configure I2C DAC */
dac_init();
/* Test DAC */
esp_err_t ret = dac_ack_test();
if (ret != ESP_OK){
ESP_LOGE(TAG, "Failed to initialize DAC");
} else {
ESP_LOGI(TAG, "Sucessfully initialized DAC");
}
/* Generate wave tables */
gen_wavetables();
/* Loop to test DAC output */
while (1) {
dac_out_test();
}
} }

View File

@ -1,35 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <sys/types.h>
#include "esp_log.h"
#include "wavetable.h"
#define SAMPLE_RATE 22000 /* 22kHz */
#define FREQ 440
#define TIME 1
float_t *sin_tbl;
static const char *TAG = "wavetable";
static void gen_sin_table(void)
{
/* Allocate memory */
uint16_t table_length = 1024; /* TODO make this accurate to sample rate and frequency */
sin_tbl = (float *)malloc(sizeof(float) * table_length);
/* Loop through values and store in table */
for (uint16_t i = 0; i < table_length; i++) {
sin_tbl[i] = sin((2 * M_PI * i) / table_length);
}
}
void gen_wavetables(void)
{
ESP_LOGI(TAG, "Generating sine wavetable");
gen_sin_table();
}

View File

@ -1,7 +0,0 @@
#ifndef WAVETABLE_H_ /* Guard */
#define WAVETABLE_H_
/* Generates all wavetables */
void gen_wavetables(void);
#endif