Compare commits

...

8 Commits

Author SHA1 Message Date
rkcf 210dc81b25 Feat: add sine wave lookup table generation
Refs: #12
2023-02-24 17:56:27 -06:00
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
5 changed files with 174 additions and 3 deletions

View File

@ -7,7 +7,13 @@ 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
** 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,2 +1,2 @@
idf_component_register(SRCS "esp32_eurorack_generic.c" idf_component_register(SRCS "esp32_eurorack_generic.c" "wavetable.c"
INCLUDE_DIRS ".") INCLUDE_DIRS ".")

View File

@ -1,6 +1,129 @@
#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();
}
} }

35
src/main/wavetable.c Normal file
View File

@ -0,0 +1,35 @@
#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();
}

7
src/main/wavetable.h Normal file
View File

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