From 94e486f67cd354767cb7882c228dbf2516c940be Mon Sep 17 00:00:00 2001 From: Skot Croshere Date: Mon, 16 Jan 2023 17:55:16 -0500 Subject: [PATCH] added i2c-test branch --- .gitignore | 11 ++++ CMakeLists.txt | 6 ++ Makefile | 8 +++ main/CMakeLists.txt | 2 + main/DS4432U.c | 75 ++++++++++++++++++++++++ main/DS4432U.h | 10 ++++ main/Kconfig.projbuild | 17 ++++++ main/component.mk | 3 + main/i2c_simple_main.c | 73 ++++++++++++++++++++++++ main/led_controller.c | 126 +++++++++++++++++++++++++++++++++++++++++ main/led_controller.h | 8 +++ readme.md | 57 ++++++++++++------- 12 files changed, 376 insertions(+), 20 deletions(-) create mode 100644 .gitignore create mode 100755 CMakeLists.txt create mode 100755 Makefile create mode 100755 main/CMakeLists.txt create mode 100644 main/DS4432U.c create mode 100644 main/DS4432U.h create mode 100755 main/Kconfig.projbuild create mode 100755 main/component.mk create mode 100755 main/i2c_simple_main.c create mode 100644 main/led_controller.c create mode 100644 main/led_controller.h mode change 100644 => 100755 readme.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e9af52c --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# Configuration files +sdkconfig +sdkconfig.old + +# Production folder +build/ + +# HTML documentation +html_doc/ + +components/components/* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..bcfe27c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(I2c_test) diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..f8be8b9 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := i2c-simple + +include $(IDF_PATH)/make/project.mk diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100755 index 0000000..6000d28 --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "i2c_simple_main.c" "led_controller.c" "DS4432U.c" + INCLUDE_DIRS ".") diff --git a/main/DS4432U.c b/main/DS4432U.c new file mode 100644 index 0000000..b737423 --- /dev/null +++ b/main/DS4432U.c @@ -0,0 +1,75 @@ +#include +#include "esp_log.h" +#include "driver/i2c.h" + +#define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< GPIO number used for I2C master clock */ +#define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< GPIO number used for I2C master data */ +#define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */ +#define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */ +#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ +#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ +#define I2C_MASTER_TIMEOUT_MS 1000 + + +//DS4432U+ -- Adjustable current DAC for use with the TPS40305 voltage regulator +//address: 0x90 +#define DS4432U_SENSOR_ADDR 0x48 //Slave address of the DS4432U+ +#define DS4432U_OUT0_REG 0xF8 //register for current output 0 +#define DS4432U_OUT1_REG 0xF9 //register for current output 1 + +static const char *TAG = "DS4432U.c"; + +/** + * @brief i2c master initialization + */ +esp_err_t i2c_master_init(void) { + int i2c_master_port = I2C_MASTER_NUM; + + i2c_config_t conf = { + .mode = I2C_MODE_MASTER, + .sda_io_num = I2C_MASTER_SDA_IO, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = I2C_MASTER_FREQ_HZ, + }; + + i2c_param_config(i2c_master_port, &conf); + + return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); +} + +/** + * @brief i2c master delete + */ +esp_err_t i2c_master_delete(void) { + return i2c_driver_delete(I2C_MASTER_NUM); +} + + +/** + * @brief Read a sequence of I2C bytes + */ +static esp_err_t register_read(uint8_t i2c_address, uint8_t reg_addr, uint8_t *data, size_t len) { + return i2c_master_write_read_device(I2C_MASTER_NUM, i2c_address, ®_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); +} + +/** + * @brief Write a byte to a I2C register + */ +// static esp_err_t register_write_byte(uint8_t i2c_address, uint8_t reg_addr, uint8_t data) { +// int ret; +// uint8_t write_buf[2] = {reg_addr, data}; + +// ret = i2c_master_write_to_device(I2C_MASTER_NUM, i2c_address, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); + +// return ret; +// } + +void DS4432U_read(void) { + uint8_t data[3]; + + /* Read the DS4432U+ WHO_AM_I register, on power up the register should have the value 0x00 */ + ESP_ERROR_CHECK(register_read(DS4432U_SENSOR_ADDR, DS4432U_OUT1_REG, data, 1)); + ESP_LOGI(TAG, "DS4432U+ OUT1 = 0x%02X", data[0]); +} \ No newline at end of file diff --git a/main/DS4432U.h b/main/DS4432U.h new file mode 100644 index 0000000..b51a2dc --- /dev/null +++ b/main/DS4432U.h @@ -0,0 +1,10 @@ +#ifndef DS4432U_H_ +#define DS4432U_H_ + +#include "driver/i2c.h" + +esp_err_t i2c_master_init(void); +esp_err_t i2c_master_delete(void); +void DS4432U_read(void); + +#endif /* DS4432U_H_ */ \ No newline at end of file diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild new file mode 100755 index 0000000..dc9568c --- /dev/null +++ b/main/Kconfig.projbuild @@ -0,0 +1,17 @@ +menu "Example Configuration" + + config I2C_MASTER_SCL + int "SCL GPIO Num" + default 6 if IDF_TARGET_ESP32C3 + default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + help + GPIO number for I2C Master clock line. + + config I2C_MASTER_SDA + int "SDA GPIO Num" + default 5 if IDF_TARGET_ESP32C3 + default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + help + GPIO number for I2C Master data line. + +endmenu diff --git a/main/component.mk b/main/component.mk new file mode 100755 index 0000000..87e0813 --- /dev/null +++ b/main/component.mk @@ -0,0 +1,3 @@ +# +# Main Makefile. This is basically the same as a component makefile . +# diff --git a/main/i2c_simple_main.c b/main/i2c_simple_main.c new file mode 100755 index 0000000..c1c9b70 --- /dev/null +++ b/main/i2c_simple_main.c @@ -0,0 +1,73 @@ +/* i2c - Simple example + + Simple I2C example that shows how to initialize I2C + as well as reading and writing from and to registers for a sensor connected over I2C. + + For other examples please check: + https://github.com/espressif/esp-idf/tree/master/examples + + See README.md file to get detailed usage of this example. + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "esp_log.h" +#include "driver/i2c.h" + +#include "led_controller.h" +#include "DS4432U.h" + +static const char *TAG = "i2c-test"; + +//INA260 -- Power meter +//address: 0x40 +#define INA260_SENSOR_ADDR 0x40 //Slave address of the INA260 +#define INA260_MANFID_REG 0xFE //should be 0x5449 + +//EMC2101 -- Fan and temp sensor controller +//address: 0x4C +#define EMC2101_SENSOR_ADDR 0x4C //Slave address of the EMC2101 +#define EMC2101_PRODUCTID_REG 0xFD //should be 0x16 or 0x28 + + + + + +void app_main(void) { + + //test the LEDs + ESP_LOGI(TAG, "Init LEDs!"); + initLEDs(); + // gpio_set_level(LEDX_R, 1); + // gpio_set_level(LEDZ_R, 1); + + ledc_init(); + led_set(); + + ESP_ERROR_CHECK(i2c_master_init()); + ESP_LOGI(TAG, "I2C initialized successfully"); + + DS4432U_read(); + + // /* Read the EMC2101 WHO_AM_I register, on power up the register should have the value 0x16 or 0x28 */ + // ESP_ERROR_CHECK(register_read(EMC2101_SENSOR_ADDR, EMC2101_PRODUCTID_REG, data, 1)); + // ESP_LOGI(TAG, "EMC2101 PRODUCT ID = 0x%02X", data[0]); + + // /* Read the INA260 WHO_AM_I register, on power up the register should have the value 0x5449 */ + // ESP_ERROR_CHECK(register_read(INA260_SENSOR_ADDR, INA260_MANFID_REG, data, 2)); + // ESP_LOGI(TAG, "INA260 MANF ID = 0x%02X%02X", data[0], data[1]); + + // /* Read the DS4432U+ WHO_AM_I register, on power up the register should have the value 0x00 */ + // ESP_ERROR_CHECK(register_read(DS4432U_SENSOR_ADDR, DS4432U_OUT1_REG, data, 1)); + // ESP_LOGI(TAG, "DS4432U+ OUT1 = 0x%02X", data[0]); + + // /* Demonstrate writing by reseting the MPU9250 */ + // ESP_ERROR_CHECK(mpu9250_register_write_byte(MPU9250_PWR_MGMT_1_REG_ADDR, 1 << MPU9250_RESET_BIT)); + + ESP_ERROR_CHECK(i2c_master_delete()); + ESP_LOGI(TAG, "I2C unitialized successfully"); +} diff --git a/main/led_controller.c b/main/led_controller.c new file mode 100644 index 0000000..8179e96 --- /dev/null +++ b/main/led_controller.c @@ -0,0 +1,126 @@ +#include +#include "esp_err.h" +#include "driver/ledc.h" +#include "driver/gpio.h" + +//LEDS +#define LEDX_R GPIO_NUM_35 +#define LEDX_G GPIO_NUM_36 +#define LEDX_B GPIO_NUM_37 +#define LEDZ_R GPIO_NUM_38 +#define LEDZ_G GPIO_NUM_39 +#define LEDZ_B GPIO_NUM_40 + +void initLEDs(void) { + gpio_set_direction(LEDX_R, GPIO_MODE_OUTPUT); + gpio_set_direction(LEDX_G, GPIO_MODE_OUTPUT); + gpio_set_direction(LEDX_B, GPIO_MODE_OUTPUT); + gpio_set_direction(LEDZ_R, GPIO_MODE_OUTPUT); + gpio_set_direction(LEDZ_G, GPIO_MODE_OUTPUT); + gpio_set_direction(LEDZ_B, GPIO_MODE_OUTPUT); + + gpio_set_level(LEDX_R, 0); + gpio_set_level(LEDX_G, 0); + gpio_set_level(LEDX_B, 0); + gpio_set_level(LEDZ_R, 0); + gpio_set_level(LEDZ_G, 0); + gpio_set_level(LEDZ_B, 0); +} + +void ledc_init(void) { + // Prepare and then apply the LEDC PWM timer configuration + ledc_timer_config_t ledc_timer = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .timer_num = LEDC_TIMER_0, + .duty_resolution = LEDC_TIMER_12_BIT, // Set duty resolution to 12 bits + .freq_hz = 5000, // Set output frequency at 5 kHz + .clk_cfg = LEDC_AUTO_CLK + }; + ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); + + // Prepare and then apply the LEDC PWM channel configuration + ledc_channel_config_t ledc_channel0 = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = LEDC_CHANNEL_0, + .timer_sel = LEDC_TIMER_0, + .intr_type = LEDC_INTR_DISABLE, + .gpio_num = 35, // Define the output GPIO + .duty = 0, // Set duty to 0% + .hpoint = 0 + }; + ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel0)); + + ledc_channel_config_t ledc_channel1 = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = LEDC_CHANNEL_1, + .timer_sel = LEDC_TIMER_0, + .intr_type = LEDC_INTR_DISABLE, + .gpio_num = 36, // Define the output GPIO + .duty = 0, // Set duty to 0% + .hpoint = 0 + }; + ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel1)); + + ledc_channel_config_t ledc_channel2 = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = LEDC_CHANNEL_2, + .timer_sel = LEDC_TIMER_0, + .intr_type = LEDC_INTR_DISABLE, + .gpio_num = 37, // Define the output GPIO + .duty = 0, // Set duty to 0% + .hpoint = 0 + }; + ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel2)); + + ledc_channel_config_t ledc_channel3 = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = LEDC_CHANNEL_3, + .timer_sel = LEDC_TIMER_0, + .intr_type = LEDC_INTR_DISABLE, + .gpio_num = 38, // Define the output GPIO + .duty = 0, // Set duty to 0% + .hpoint = 0 + }; + ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel3)); + + ledc_channel_config_t ledc_channel4 = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = LEDC_CHANNEL_4, + .timer_sel = LEDC_TIMER_0, + .intr_type = LEDC_INTR_DISABLE, + .gpio_num = 39, // Define the output GPIO + .duty = 0, // Set duty to 0% + .hpoint = 0 + }; + ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel4)); + + ledc_channel_config_t ledc_channel5 = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = LEDC_CHANNEL_5, + .timer_sel = LEDC_TIMER_0, + .intr_type = LEDC_INTR_DISABLE, + .gpio_num = 40, // Define the output GPIO + .duty = 0, // Set duty to 0% + .hpoint = 0 + }; + ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel5)); +} + +void led_set(void) { + ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 3000)); //r + ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1, 1000)); //g + ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_2, 0)); //b + + ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_3, 3000)); //r + ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_4, 1000)); //g + ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_5, 0)); //b + + // Update duty to apply the new value + ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0)); + ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1)); + ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_2)); + + ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_3)); + ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_4)); + ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_5)); +} \ No newline at end of file diff --git a/main/led_controller.h b/main/led_controller.h new file mode 100644 index 0000000..bdf2002 --- /dev/null +++ b/main/led_controller.h @@ -0,0 +1,8 @@ +#ifndef LED_CONTROLLER_H_ +#define LED_CONTROLLER_H_ + +void initLEDs(void); +void ledc_init(void); +void led_set(void); + +#endif /* LED_CONTROLLER_H_ */ \ No newline at end of file diff --git a/readme.md b/readme.md old mode 100644 new mode 100755 index 80bdac1..27ceffb --- a/readme.md +++ b/readme.md @@ -1,18 +1,8 @@ -## ESP-Miner +# ESP-Miner ESP-Miner is bitcoin miner software designed to run on the ESP32. It mines on ASICs such as the Bitmain BM1397. The [Bitaxe](https://github.com/skot/bitaxe/) is a handy board for this! -![esp-miner block diagram](doc/diagram.png) - -## Architecture -- Uses the ESP-IDF Framework, which is based on FreeRTOS (no Linux involved) -- Uses the ESP32 WiFi to connect to the network -- The ESP32 is provisioned to the local WiFi over BLE using ESP SmartConfig - -### Firmware -- ESP-Miner connects to and verifies the attached mining ASIC. - - Setting the baud rate, hashing frequency, and filling in some other mystery registers - - This startup sequence for the BM1387 and BM1397 can be found in cgminer the Kano edition in [driver-gekko.c](https://github.com/kanoi/cgminer/blob/master/driver-gekko.c) +## Overview - ESP-Miner connects to your pool or stratum server and subscribes to get the latest work. - This is done with [JSON-RPC](https://www.jsonrpc.org) @@ -25,13 +15,40 @@ ESP-Miner is bitcoin miner software designed to run on the ESP32. It mines on AS - I have started on this.. [check this](bm1397_protocol.md) - ESP-Miner sends this work to the mining ASIC over serial. -- The Mining ASIC will report back any when it finds a hash over the difficulty (which)? - - The catch here is that if it doesn't find a hash over the difficulty, it will not report back at all. So you need to keep track of the hashing frequency and the time so that you can send a new block header to be hashed. +### Hardware Required -- ESP-Miner will report back to the pool over Stratum the results of mining. +To run this example, you should have one ESP32, ESP32-S or ESP32-C based development board as well as a MPU9250. MPU9250 is a inertial measurement unit, which contains a accelerometer, gyroscope as well as a magnetometer, for more information about it, you can read the [PDF](https://invensense.tdk.com/wp-content/uploads/2015/02/PS-MPU-9250A-01-v1.1.pdf) of this sensor. -- All of the administrative stuff of running a miner like; - - Set the BM1397 core voltage and current. - - check the fan speed - - check the BM1397 temperature - - optimize the hashing frequency and core voltage for max efficiency +#### Pin Assignment: + +**Note:** The following pin assignments are used by default, you can change these in the `menuconfig` . + +| | SDA | SCL | +| ---------------- | -------------- | -------------- | +| ESP I2C Master | I2C_MASTER_SDA | I2C_MASTER_SCL | +| MPU9250 Sensor | SDA | SCL | + + +For the actual default value of `I2C_MASTER_SDA` and `I2C_MASTER_SCL` see `Example Configuration` in `menuconfig`. + +**Note: ** There’s no need to add an external pull-up resistors for SDA/SCL pin, because the driver will enable the internal pull-up resistors. + +### Build and Flash + +Enter `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +```bash +I (328) i2c-simple-example: I2C initialized successfully +I (338) i2c-simple-example: WHO_AM_I = 71 +I (338) i2c-simple-example: I2C unitialized successfully +``` + +## Troubleshooting + +(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.)