Compare commits
6 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
883e431ce3 | |
|
|
e8eff42a93 | |
|
|
9c043785d2 | |
|
|
f960dba5a8 | |
|
|
3287956c5d | |
|
|
6945c7bc0c |
|
|
@ -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
|
||||||
|
|
@ -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.
|
||||||
49
README.org
49
README.org
|
|
@ -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]]
|
||||||
|
|
|
||||||
|
|
@ -1,124 +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"
|
|
||||||
|
|
||||||
/* 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");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop to test DAC output */
|
|
||||||
while (1) {
|
|
||||||
dac_out_test();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue