// // MA120x0P ESP32 Driver // // Merus Audio - September 2018 // Written by Joergen Kragh Jakobsen, jkj@myrun.dk // // Register interface thrugh I2C for MA12070P and MA12040P // Support a single amplifier/i2c address // // #include #include #include "esp_log.h" #include "driver/i2c.h" #include "MerusAudio.h" #include "ma120x0.h" //#include "ma120_rev1_all.h" #define MA_NENABLE_IO CONFIG_MA120X0_NENABLE_PIN #define MA_ENABLE_IO CONFIG_MA120X0_ENABLE_PIN #define MA_NMUTE_IO CONFIG_MA120X0_NMUTE_PIN #define MA_NERR_IO CONFIG_MA120X0_NERR_PIN #define MA_NCLIP_IO CONFIG_MA120X0_NCLIP_PIN static const char* I2C_TAG = "i2c"; #define I2C_CHECK(a, str, ret) if(!(a)) { \ ESP_LOGE(I2C_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ return (ret); \ } #define I2C_MASTER_SCL_IO CONFIG_MA120X0_SCL_PIN //4 /*!< gpio number for I2C master clock */ #define I2C_MASTER_SDA_IO CONFIG_MA120X0_SDA_PIN //0 /*!< gpio number for I2C master data */ #define I2C_MASTER_NUM I2C_NUM_0 /*!< I2C port number for master dev */ #define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master do not need buffer */ #define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master do not need buffer */ #define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */ #define MA120X0_ADDR CONFIG_MA120X0_I2C_ADDR /*!< slave address for MA120X0 amplifier */ #define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ #define READ_BIT I2C_MASTER_READ /*!< I2C master read */ #define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ #define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ #define ACK_VAL 0x0 /*!< I2C ack value */ #define NACK_VAL 0x1 /*!< I2C nack value */ void setup_ma120x0() { // Setup control pins nEnable and nMute gpio_config_t io_conf; io_conf.intr_type = GPIO_PIN_INTR_DISABLE; io_conf.mode = GPIO_MODE_OUTPUT; io_conf.pin_bit_mask = (1ULL< GEN2 ,",addr); //printf("Scan i2c address 0x%02x read address 0 : 0x%02x \n", addr ,res); } printf("\n"); uint8_t rxbuf[32]; uint8_t otp[1024]; for (uint8_t i=0;i<16; i++) { ma_read(0x20,2,0x8000+i*32,rxbuf,32); //printf("%04x : ",0x8000+i*32 ); for (uint8_t j=0; j<32 ; j++ ) { otp[i*32+j] = rxbuf[j]; } } for (uint16_t i=0;i<16*32; i++) { if (i%32==0) { printf("\n0x%04x : ",0x8000+i); } printf("%02x ",otp[i]); } res = ma_write_byte(0x20,2,0x060c,0); res = ma_read_byte(0x20,2,0x060c); printf("\nHardware version: 0x%02x\n",res); printf("\n"); } uint8_t b[32]; #define CHECK(ADDR,L) ma_read(0x20,2,ADDR,b,L); printf("Check 0x%04x :",ADDR); for (int ci=0;ci>8), ACK_VAL); i2c_master_write_byte(cmd, (uint8_t)(address&0x00ff), ACK_VAL); } else { i2c_master_write_byte(cmd, (uint8_t) address, ACK_VAL); } for (int i=0 ; i>8), ACK_VAL); i2c_master_write_byte(cmd, (uint8_t)(address&0x00ff), ACK_VAL); } else { i2c_master_write_byte(cmd, (uint8_t) address, ACK_VAL); } i2c_master_write_byte(cmd, value, ACK_VAL); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); if (ret == ESP_FAIL) { printf("ESP_I2C_WRITE ERROR : %d\n",ret); return ret; } return ESP_OK; } esp_err_t ma_read(uint8_t i2c_addr, uint8_t prot, uint16_t address, uint8_t *rbuf, uint8_t n) { esp_err_t ret; i2c_cmd_handle_t cmd = i2c_cmd_link_create(); if (cmd == NULL ) { printf("ERROR handle null\n"); } i2c_master_start(cmd); i2c_master_write_byte(cmd, (i2c_addr<<1) | WRITE_BIT, ACK_CHECK_EN); if (prot == 2) { i2c_master_write_byte(cmd, (uint8_t)((address&0xff00)>>8), ACK_VAL); i2c_master_write_byte(cmd, (uint8_t)(address&0x00ff), ACK_VAL); } else { i2c_master_write_byte(cmd, (uint8_t) address, ACK_VAL); } i2c_master_start(cmd); i2c_master_write_byte(cmd, (i2c_addr<<1) | READ_BIT, ACK_CHECK_EN); i2c_master_read(cmd, rbuf, n-1 ,ACK_VAL); // for (uint8_t i = 0;i>8), ACK_VAL); i2c_master_write_byte(cmd, (uint8_t)(address&0x00ff), ACK_VAL); } else { i2c_master_write_byte(cmd, (uint8_t) address, ACK_VAL); } i2c_master_start(cmd); // Repeated start i2c_master_write_byte(cmd, (i2c_addr<<1) | READ_BIT, ACK_CHECK_EN); i2c_master_read_byte(cmd, &value, NACK_VAL); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); if (ret == ESP_FAIL) { printf("i2c Error read - readback\n"); return ESP_FAIL; } return value; }