Compare commits

..

7 Commits

Author SHA1 Message Date
rkcf a0bc9cbce6 Docs: add function description to dac_out_test
Refs: #8
2023-02-20 07:17:35 -06:00
rkcf 41c2aa3586 Docs: add section with hardware and dac info
Refs: #8
2023-02-20 07:12:11 -06:00
rkcf c1e497c643 Refactor: move dac output test loop to function
Refs: #8
2023-02-20 06:57:09 -06:00
rkcf b3f4a14697 Feat: add DAC multiwrite loop to test output
Refs: #8
2023-02-20 06:37:37 -06:00
rkcf 0d7c2a6cc1 Feat: add i2c dac device connection test
Refs: #8
2023-02-20 04:50:47 -06:00
rkcf 92e5de269e Feat: add dac ldac pin gpio setup
Refs: #8
2023-02-19 19:46:46 -06:00
rkcf e53dc953c4 Feat: add dac i2c master init
Refs: #8
2023-02-19 19:15:16 -06:00
4 changed files with 124 additions and 62 deletions

12
.gitignore vendored
View File

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

View File

@ -1,7 +0,0 @@
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,11 +1,5 @@
#+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.
* Specs
@ -13,44 +7,13 @@ This project aims to create a generic esp32-s3 based eurorack modular unit—rep
- I/O
- 4 channel input
- 4 channel output
- Output signal 0 -> +5V
- Output signal 0 -> ~+5V
- 2 Rotary encoder switches
- 4 buttons
- 2.2in TFT LCD Display
* Project Setup
Clone the repository over ssh.
#+BEGIN_SRC shell
git clone git@gitea.rkcf.me/rkcf/esp32_eurorack_generic.git
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]]
* Hardware
** MCP4728 Quad 12bit I2C DAC
- [[https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/22187E.pdf][Datasheet]]
- [[https://learn.adafruit.com/adafruit-mcp4728-i2c-quad-dac][Adafruit Info Page]]
- 0 -> ~+5V out

View File

@ -1,6 +1,124 @@
#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)
{
/* 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();
}
}