You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
388 lines
13 KiB
388 lines
13 KiB
#include <stdio.h>
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/semphr.h"
|
|
|
|
#include "driver/gpio.h"
|
|
|
|
#include "driver/spi_master.h"
|
|
#include <string.h>
|
|
|
|
// definicion de pines
|
|
// Definir los pines utilizados para MOSI, MISO, SCLK y CS
|
|
#define PIN_NUM_MOSI 13
|
|
#define PIN_NUM_MISO 12
|
|
#define PIN_NUM_CLK 14
|
|
#define PIN_NUM_CS 15
|
|
#define IRQ_PIN 26
|
|
|
|
// parámetros ADC
|
|
#define LEN_MAP_bytes 24 // cantidad de bitts en la memoria desde 0x1 a 0xD, adicionando 8 bits para el comando
|
|
|
|
#define FAST_COMMAND 0b00
|
|
#define STATIC_READ 0b01
|
|
#define INCREMENTAL_WRITE 0b10
|
|
#define INCREMENTAL_READ 0b11
|
|
|
|
uint8_t register_map[LEN_MAP_bytes] = {0};
|
|
#define ADCDATA_index 0
|
|
#define CONFIG0_index 1
|
|
#define CONFIG1_index 2
|
|
#define CONFIG2_index 3
|
|
#define CONFIG3_index 4
|
|
#define IRQ_index 5
|
|
#define MUX_index 6
|
|
#define SCAN_index 7
|
|
#define TIMER_index 10
|
|
#define OFFSETCAL_index 13
|
|
#define GAINCAL_index 16
|
|
#define LOCK_index 23
|
|
|
|
#define ADC_CONV_START_FC 0b1010
|
|
#define ADC_STBY_MODE_FC 0b1011
|
|
#define ADC_SHDN_MODE_FC 0b1100
|
|
#define FULL_SHDN_MODE_FC 0b1101
|
|
#define FULL_RESET_FC 0b1110
|
|
|
|
#define COMMAND_READ_ADC 0b01000001
|
|
|
|
// variables SPI
|
|
spi_device_handle_t *spi_handle;
|
|
spi_bus_config_t *bus_cfg_SPI;
|
|
spi_device_interface_config_t *mcp3561_cfg_SPI;
|
|
|
|
spi_transaction_t trans_read_ADC;
|
|
|
|
uint32_t data_ADC;
|
|
uint8_t* dir_data_ADC;
|
|
|
|
bool flag_IRQ = false;
|
|
|
|
uint8_t data_read_ADC[4] = {0};
|
|
|
|
// Declaración de la cola de semáforo
|
|
SemaphoreHandle_t xSemaphore;
|
|
|
|
// funciones SPI
|
|
esp_err_t SPI_begin(spi_device_handle_t* _spi_handle, spi_bus_config_t *_bus_cfg){
|
|
// trabajo con el handle
|
|
if(_spi_handle == NULL){
|
|
_spi_handle = malloc(sizeof(spi_device_handle_t));
|
|
}
|
|
|
|
// trabajo con la configuracion
|
|
spi_bus_config_t bus_cfg = { // genero la configuracion
|
|
.mosi_io_num = PIN_NUM_MOSI,
|
|
.miso_io_num = PIN_NUM_MISO,
|
|
.sclk_io_num = PIN_NUM_CLK,
|
|
.quadwp_io_num = -1,
|
|
.quadhd_io_num = -1,
|
|
.max_transfer_sz = 1024*8,
|
|
};
|
|
|
|
if(_bus_cfg == NULL){
|
|
_bus_cfg = malloc(sizeof(spi_bus_config_t));
|
|
}
|
|
|
|
memcpy(_bus_cfg, &bus_cfg, sizeof(spi_bus_config_t));
|
|
|
|
esp_err_t _err;
|
|
_err = spi_bus_initialize(HSPI_HOST, &bus_cfg, 1);
|
|
// spi_bus_add_device(HSPI_HOST, &dev_cfg, &spi_handle);
|
|
|
|
return(_err);
|
|
}
|
|
|
|
|
|
|
|
esp_err_t mcp3561_begin(spi_device_handle_t* _spi_handle, spi_bus_config_t *_bus_cfg, gpio_num_t _cs, spi_device_interface_config_t *_dev_cfg){
|
|
|
|
if(_spi_handle == NULL){
|
|
return(ESP_FAIL);
|
|
}
|
|
|
|
spi_device_interface_config_t dev_cfg = {
|
|
.command_bits = 0,
|
|
.address_bits = 0,
|
|
.dummy_bits = 0,
|
|
.clock_speed_hz = 20000000, // Velocidad en Hz
|
|
.duty_cycle_pos = 128,
|
|
.mode = 0, // Modo SPI
|
|
.spics_io_num = _cs,
|
|
.queue_size = 7,
|
|
};
|
|
|
|
if(_dev_cfg == NULL){
|
|
_dev_cfg = malloc(sizeof(spi_device_interface_config_t));
|
|
}
|
|
|
|
memcpy(_dev_cfg, &dev_cfg, sizeof(spi_device_interface_config_t));
|
|
|
|
esp_err_t _err;
|
|
|
|
// spi_bus_initialize(HSPI_HOST, &bus_cfg, 1);
|
|
_err = spi_bus_add_device(HSPI_HOST, &dev_cfg, _spi_handle);
|
|
|
|
if(_err == ESP_OK){
|
|
register_map[0] |= (0x1 << 6); // dirección del dispositivo
|
|
register_map[0] |= (0x1 << 2); // dirección en la que arranca a leer
|
|
register_map[0] |= INCREMENTAL_READ;
|
|
|
|
uint8_t rx_data[LEN_MAP_bytes] = {0};
|
|
spi_transaction_t trans_desc;
|
|
|
|
memset(&trans_desc, 0, sizeof(trans_desc));
|
|
trans_desc.length = 8 * LEN_MAP_bytes;
|
|
trans_desc.tx_buffer = register_map;
|
|
trans_desc.rx_buffer = rx_data; // Configuración para recibir datos
|
|
|
|
_err = spi_device_polling_transmit(*_spi_handle, &trans_desc);
|
|
if (_err != ESP_OK) {
|
|
printf("Error al enviar la trama SPI. Código de error: 0x%x\n", _err);
|
|
} else {
|
|
printf("Trama SPI enviada con éxito.\n");
|
|
// Ahora, rx_data contiene los datos recibidos
|
|
printf("Datos recibidos: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", rx_data[0], rx_data[1], rx_data[2], rx_data[3], rx_data[4], rx_data[5], rx_data[6], rx_data[7], rx_data[8], rx_data[9], rx_data[10], rx_data[11], rx_data[12], rx_data[13], rx_data[14], rx_data[15], rx_data[16], rx_data[17], rx_data[18], rx_data[19], rx_data[20], rx_data[21], rx_data[22], rx_data[23]);
|
|
|
|
for(int i=1; i<LEN_MAP_bytes; i++){
|
|
register_map[i] = rx_data[i];
|
|
}
|
|
|
|
printf("register_map: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", register_map[0], register_map[1], register_map[2], register_map[3], register_map[4], register_map[5], register_map[6], register_map[7], register_map[8], register_map[9], register_map[10], register_map[11], register_map[12], register_map[13], register_map[14], register_map[15], register_map[16], register_map[17], register_map[18], register_map[19], register_map[20], register_map[21], register_map[22], register_map[23]);
|
|
|
|
}
|
|
}
|
|
return(_err);
|
|
}
|
|
|
|
|
|
esp_err_t mcp3561_write_reg(spi_device_handle_t* _spi_handle, uint8_t _reg_index, uint8_t *_data, size_t _len_data){
|
|
uint8_t aux = register_map[_reg_index];
|
|
|
|
memcpy(®ister_map[_reg_index], _data, _len_data);
|
|
|
|
register_map[0] = 0;
|
|
register_map[0] |= (0x1 << 6); // dirección del dispositivo
|
|
register_map[0] |= (0x1 << 2); // dirección en la que arranca a leer
|
|
register_map[0] |= INCREMENTAL_WRITE;
|
|
|
|
printf("register_map : [ ");
|
|
for(int i = 0; i<LEN_MAP_bytes; i++){
|
|
printf("%02x ", register_map[i]);
|
|
}
|
|
printf("]\n");
|
|
|
|
uint8_t rx_data[1] = {0};
|
|
spi_transaction_t trans_desc;
|
|
|
|
memset(&trans_desc, 0, sizeof(trans_desc));
|
|
trans_desc.length = 8 * LEN_MAP_bytes;
|
|
trans_desc.tx_buffer = register_map;
|
|
trans_desc.rx_buffer = rx_data; // Configuración para recibir datos
|
|
// trans_desc.rxlength = 8;
|
|
// trans_desc.
|
|
|
|
esp_err_t _err = spi_device_polling_transmit(*_spi_handle, &trans_desc);//spi_device_transmit(*spi_handle, &trans_desc);
|
|
if (_err != ESP_OK) {
|
|
printf("Error al enviar la trama SPI. Código de error: 0x%x\n", _err);
|
|
} else {
|
|
printf("Trama SPI enviada con éxito.\n");
|
|
// Ahora, rx_data contiene los datos recibidos
|
|
printf("Datos recibidos: %02x\n", rx_data[0]);
|
|
|
|
// for(int i=1; i<LEN_MAP_bytes; i++){
|
|
// register_map[i] = rx_data[i];
|
|
// }
|
|
|
|
// printf("register_map: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", register_map[0], register_map[1], register_map[2], register_map[3], register_map[4], register_map[5], register_map[6], register_map[7], register_map[8], register_map[9], register_map[10], register_map[11], register_map[12], register_map[13], register_map[14], register_map[15], register_map[16], register_map[17], register_map[18], register_map[19], register_map[20], register_map[21], register_map[22], register_map[23]);
|
|
|
|
}
|
|
return(_err);
|
|
}
|
|
|
|
esp_err_t mcp3561_read_reg(spi_device_handle_t* _spi_handle, uint8_t _reg_index, uint8_t *_data, size_t _len_data){
|
|
uint8_t command[1] = {0};
|
|
|
|
command[0] |= (0x1 << 6); // dirección del dispositivo
|
|
command[0] |= (_reg_index << 2); // dirección en la que arranca a leer
|
|
command[0] |= STATIC_READ;
|
|
|
|
// uint8_t len_data = (uint8_t)_len_data;
|
|
|
|
uint8_t rx_data[_len_data + 1];
|
|
// _data = &rx_data[0];
|
|
spi_transaction_t trans_desc;
|
|
|
|
memset(&trans_desc, 0, sizeof(trans_desc));
|
|
trans_desc.length = 8*(_len_data + 1);
|
|
trans_desc.tx_buffer = command;
|
|
trans_desc.rx_buffer = rx_data;
|
|
|
|
esp_err_t _err = spi_device_transmit(*_spi_handle, &trans_desc);//spi_device_transmit(*spi_handle, &trans_desc);
|
|
if (_err != ESP_OK) {
|
|
printf("Error al enviar la trama SPI. Código de error: 0x%x\n", _err);
|
|
} else {
|
|
printf("Trama SPI enviada con éxito.\n");
|
|
memcpy(_data, &rx_data[1], _len_data);
|
|
// Ahora, rx_data contiene los datos recibidos
|
|
printf("Datos recibidos: [ ");
|
|
for(int i=0;i<(_len_data + 1);i++){
|
|
printf("%02x ", rx_data[i]);//rx_data[i]
|
|
}
|
|
printf("]\n");
|
|
|
|
// _data = &rx_data[0];
|
|
}
|
|
return(_err);
|
|
}
|
|
|
|
|
|
esp_err_t mcp3561_start_conversion(spi_device_handle_t* _spi_handle){
|
|
uint8_t command[1] = {0};
|
|
|
|
command[0] |= (0x1 << 6); // dirección del dispositivo
|
|
command[0] |= (ADC_CONV_START_FC << 2); // dirección en la que arranca a leer
|
|
command[0] |= FAST_COMMAND;
|
|
|
|
uint8_t rx_data[1] = {0};
|
|
spi_transaction_t trans_desc;
|
|
|
|
memset(&trans_desc, 0, sizeof(trans_desc));
|
|
trans_desc.length = 8;
|
|
trans_desc.tx_buffer = command;
|
|
trans_desc.rx_buffer = rx_data;
|
|
|
|
esp_err_t _err = spi_device_polling_transmit(*_spi_handle, &trans_desc);//spi_device_transmit(*spi_handle, &trans_desc);
|
|
if (_err != ESP_OK) {
|
|
printf("Error al enviar la trama SPI. Código de error: 0x%x\n", _err);
|
|
} else {
|
|
printf("Trama SPI enviada con éxito.\n");
|
|
// Ahora, rx_data contiene los datos recibidos
|
|
printf("Datos recibidos: %02x\n", rx_data[0]);
|
|
}
|
|
return(_err);
|
|
}
|
|
|
|
esp_err_t mcp3561_reset(spi_device_handle_t* _spi_handle){
|
|
uint8_t command[1] = {0};
|
|
|
|
command[0] |= (0x1 << 6); // dirección del dispositivo
|
|
command[0] |= (FULL_RESET_FC << 2); // dirección en la que arranca a leer
|
|
command[0] |= FAST_COMMAND;
|
|
|
|
uint8_t rx_data[1] = {0};
|
|
spi_transaction_t trans_desc;
|
|
|
|
memset(&trans_desc, 0, sizeof(trans_desc));
|
|
trans_desc.length = 8;
|
|
trans_desc.tx_buffer = command;
|
|
trans_desc.rx_buffer = rx_data;
|
|
|
|
esp_err_t _err = spi_device_polling_transmit(*_spi_handle, &trans_desc);//spi_device_transmit(*spi_handle, &trans_desc);
|
|
if (_err != ESP_OK) {
|
|
printf("Error al enviar la trama SPI. Código de error: 0x%x\n", _err);
|
|
} else {
|
|
printf("Trama SPI enviada con éxito.\n");
|
|
// Ahora, rx_data contiene los datos recibidos
|
|
printf("Datos recibidos: %02x\n", rx_data[0]);
|
|
}
|
|
return(_err);
|
|
}
|
|
|
|
|
|
|
|
esp_err_t mcp3561_config(void){
|
|
uint8_t reg_cfg[6] = {0};
|
|
reg_cfg[0] = 0b11110011; // CONFIG0
|
|
reg_cfg[1] = 0b00001000; // CONFIG1
|
|
reg_cfg[2] = 0b10001011; // CONFIG2
|
|
reg_cfg[3] = 0b11000000; // CONFIG3
|
|
reg_cfg[4] = 0b00000111; // IRQ
|
|
reg_cfg[5] = 0b00000001; // MUX
|
|
|
|
esp_err_t _err = mcp3561_write_reg(spi_handle, CONFIG0_index, ®_cfg[0], sizeof(reg_cfg));
|
|
return _err;
|
|
}
|
|
|
|
// Interrupciones
|
|
void IRAM_ATTR isr_IRQ_handler(void *arg) {
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken);
|
|
// if (xHigherPriorityTaskWoken == pdTRUE) {
|
|
// portYIELD_FROM_ISR();
|
|
// }
|
|
}
|
|
|
|
// Tarea de base (bare-metal)
|
|
void base_task(void *pvParameters) {
|
|
while (1) {
|
|
// Espera al semáforo
|
|
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
|
|
// La tarea responde al semáforo aquí
|
|
// Realiza el trabajo necesario
|
|
printf("| ");
|
|
}
|
|
}
|
|
}
|
|
|
|
void app_main() {
|
|
// Inicializa el semáforo
|
|
xSemaphore = xSemaphoreCreateBinary();
|
|
|
|
// Crea la tarea de base
|
|
// xTaskCreate(base_task, "base_task", 2048, NULL, 15, NULL);
|
|
xTaskCreatePinnedToCore(base_task, "base_task", 2048, NULL, 15, NULL, 0);
|
|
|
|
// configuracion SPI
|
|
spi_handle = malloc(sizeof(spi_device_handle_t));
|
|
bus_cfg_SPI = malloc(sizeof(spi_bus_config_t));
|
|
mcp3561_cfg_SPI = malloc(sizeof(spi_device_interface_config_t));
|
|
|
|
// spi_semaphore = xSemaphoreCreateBinary();
|
|
|
|
dir_data_ADC = (uint8_t*)(data_ADC) + 1; // apunto al bit 23 de data_ADC
|
|
data_ADC = 0;
|
|
|
|
// configuro la transmición para el ADC
|
|
memset(&trans_read_ADC, 0, sizeof(trans_read_ADC));
|
|
trans_read_ADC.length = 8*(sizeof(data_read_ADC));
|
|
trans_read_ADC.tx_data[0] = COMMAND_READ_ADC;
|
|
trans_read_ADC.rx_buffer = data_read_ADC;
|
|
////////////////////////////////////////
|
|
|
|
ESP_ERROR_CHECK(SPI_begin(spi_handle, bus_cfg_SPI));
|
|
ESP_ERROR_CHECK(mcp3561_begin(spi_handle, bus_cfg_SPI, PIN_NUM_CS, mcp3561_cfg_SPI));
|
|
ESP_ERROR_CHECK(mcp3561_config());
|
|
|
|
|
|
// configuración PIN
|
|
gpio_config_t irq_config;
|
|
irq_config.intr_type = GPIO_INTR_POSEDGE;
|
|
irq_config.mode = GPIO_MODE_INPUT;
|
|
irq_config.pin_bit_mask = (1ULL << IRQ_PIN);
|
|
irq_config.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
|
irq_config.pull_up_en = GPIO_PULLDOWN_ENABLE;
|
|
gpio_config(&irq_config);
|
|
|
|
gpio_install_isr_service(0); // Instala el servicio de interrupción en el núcleo 0
|
|
gpio_isr_handler_add(IRQ_PIN, isr_IRQ_handler, NULL); // Asocia la función de interrupción al pin
|
|
|
|
// Configura la rutina de interrupción para activar el semáforo
|
|
// ...
|
|
|
|
|
|
|
|
// Inicia el sistema operativo en tiempo real
|
|
// vTaskStartScheduler();
|
|
|
|
while(1){
|
|
vTaskDelay(1000);
|
|
// Espera al semáforo
|
|
// if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
|
|
// // La tarea responde al semáforo aquí
|
|
// // Realiza el trabajo necesario
|
|
// printf("- ");
|
|
// }
|
|
}
|
|
}
|
|
|