parent
103eba589e
commit
daf596e541
@ -0,0 +1,104 @@
|
|||||||
|
/*!
|
||||||
|
** Modified by Scitech Korea Inc., Changwoo Park
|
||||||
|
* @file DFRobot_GP8403.h
|
||||||
|
* @brief This is a method description file for the DAC module
|
||||||
|
* @copyright Copyright (c) 2021 DFRobot Co.Ltd (http://www.dfrobot.com)
|
||||||
|
* @license The MIT License (MIT)
|
||||||
|
* @author [TangJie](jie.tang@dfrobot.com)
|
||||||
|
* @version V1.0
|
||||||
|
* @date 2022-03-07
|
||||||
|
* @url https://github.com/DFRobot/DFRobot_Microphone
|
||||||
|
*/
|
||||||
|
#ifndef _DFROBOT_GP8403_H_
|
||||||
|
#define _DFROBOT_GP8403_H
|
||||||
|
|
||||||
|
|
||||||
|
#define GP8302_STORE_TIMING_HEAD 0x02 ///< Store function timing start head
|
||||||
|
#define GP8302_STORE_TIMING_ADDR 0x10 ///< The first address for entering store timing
|
||||||
|
#define GP8302_STORE_TIMING_CMD1 0x03 ///< The command 1 to enter store timing
|
||||||
|
#define GP8302_STORE_TIMING_CMD2 0x00 ///< The command 2 to enter store timing
|
||||||
|
#define GP8302_STORE_TIMING_DELAY 10 ///< Store procedure interval delay time: 10ms, more than 7ms
|
||||||
|
#define GP8302_STORE_TIMING_DELAY 10 ///< Store procedure interval delay time: 10ms, more than 7ms
|
||||||
|
#define I2C_CYCLE_TOTAL 5 ///< Total I2C communication cycle
|
||||||
|
#define I2C_CYCLE_BEFORE 1 ///< The first half cycle 2 of the total I2C communication cycle
|
||||||
|
#define I2C_CYCLE_AFTER 2 ///< The second half cycle 3 of the total I2C communication cycle
|
||||||
|
|
||||||
|
|
||||||
|
//#define ENABLE_DBG //!< Open the macro and you can see the detailed procedure of the program
|
||||||
|
#ifdef ENABLE_DBG
|
||||||
|
#define DBG(...) {Serial.print("[");Serial.print(__FUNCTION__); Serial.print("(): "); Serial.print(__LINE__); Serial.print(" ] "); Serial.println(__VA_ARGS__);}
|
||||||
|
#else
|
||||||
|
#define DBG(...)
|
||||||
|
#endif
|
||||||
|
#define GP8302_CONFIG_CURRENT_REG 0x02
|
||||||
|
#define OUTPUT_RANGE 0X00
|
||||||
|
class DFRobot_GP8403
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @enum eOutPutRange_t
|
||||||
|
* @brief Analog voltage output range select
|
||||||
|
*/
|
||||||
|
typedef enum{
|
||||||
|
eOutputRange5V = 0X00,
|
||||||
|
eOutputRange10V = 0X11,
|
||||||
|
}eOutPutRange_t;
|
||||||
|
/**
|
||||||
|
* @brief DFRobot_GP8403 constructor
|
||||||
|
* @param pWire I2C object
|
||||||
|
* @param addr I2C address
|
||||||
|
*/
|
||||||
|
DFRobot_GP8403(TwoWire *pWire = &Wire,uint8_t addr = 0x58);
|
||||||
|
/**
|
||||||
|
* @fn begin
|
||||||
|
* @brief Initialize the module
|
||||||
|
*/
|
||||||
|
uint8_t begin(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn setDACOutRange
|
||||||
|
* @brief Set DAC output range
|
||||||
|
* @param range DAC output range
|
||||||
|
* @return NONE
|
||||||
|
*/
|
||||||
|
void setDACOutRange(eOutPutRange_t range);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn setDACOutVoltage
|
||||||
|
* @brief Set output DAC voltage of different channels
|
||||||
|
* @param data The voltage value to be output
|
||||||
|
* @param channel Output channel. 0: channel 0; 1: channel 1; 2: all the channels
|
||||||
|
* @return NONE
|
||||||
|
*/
|
||||||
|
void setDACOutVoltage(uint16_t data,uint8_t channel);
|
||||||
|
/**
|
||||||
|
* @brief Save the set voltage in the chip
|
||||||
|
*/
|
||||||
|
void store(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void startSignal(void);
|
||||||
|
void stopSignal(void);
|
||||||
|
uint8_t recvAck(uint8_t ack);
|
||||||
|
uint8_t sendByte(uint8_t data, uint8_t ack = 0, uint8_t bits = 8, bool flag = true);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @fn writeReg
|
||||||
|
* @brief Write register value through IIC bus
|
||||||
|
* @param reg Register address 8bits
|
||||||
|
* @param pBuf Storage cache to write data in
|
||||||
|
* @param size The length of data to be written
|
||||||
|
*/
|
||||||
|
void writeReg(uint8_t reg, void *pBuf, size_t size);
|
||||||
|
TwoWire *_pWire;
|
||||||
|
uint8_t _addr;
|
||||||
|
uint16_t voltage = 0;
|
||||||
|
int _scl= SCL;
|
||||||
|
int _sda = SDA;
|
||||||
|
void sendData(uint16_t data, uint8_t channel);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,217 @@
|
|||||||
|
|
||||||
|
void GP8403_setup() {
|
||||||
|
|
||||||
|
while(AO_0.begin()!=0){
|
||||||
|
Serial.println("AO_0 init error");
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
Serial.println("AO_0 init succeed");
|
||||||
|
//Set DAC output range
|
||||||
|
AO_0.setDACOutRange(AO_0.eOutputRange5V);
|
||||||
|
//Set the output value for DAC channel 0, range 0-5000
|
||||||
|
AO_0.setDACOutVoltage(0, 0);
|
||||||
|
delay(100);
|
||||||
|
//Store data in the chip
|
||||||
|
AO_0.store();
|
||||||
|
|
||||||
|
|
||||||
|
while(AO_1.begin()!=0){
|
||||||
|
Serial.println("AO_1 init error");
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
Serial.println("AO_1 init succeed");
|
||||||
|
//Set DAC output range
|
||||||
|
AO_1.setDACOutRange(AO_0.eOutputRange10V);
|
||||||
|
//Set the output value for DAC channel 0, range 0-5000
|
||||||
|
AO_1.setDACOutVoltage(0, 0);
|
||||||
|
delay(100);
|
||||||
|
//Store data in the chip
|
||||||
|
AO_1.store();
|
||||||
|
}
|
||||||
|
|
||||||
|
DFRobot_GP8403::DFRobot_GP8403(TwoWire *pWire,uint8_t addr)
|
||||||
|
{
|
||||||
|
_pWire = pWire;
|
||||||
|
_addr = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t DFRobot_GP8403::begin(void)
|
||||||
|
{
|
||||||
|
_pWire->begin();
|
||||||
|
_pWire->setClock(400000);
|
||||||
|
_pWire->beginTransmission(_addr);
|
||||||
|
_pWire->write(OUTPUT_RANGE);
|
||||||
|
if(_pWire->endTransmission() != 0){
|
||||||
|
Serial.println(_pWire->endTransmission());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFRobot_GP8403::setDACOutRange(eOutPutRange_t range)
|
||||||
|
{
|
||||||
|
if(range == eOutPutRange_t::eOutputRange5V)
|
||||||
|
{
|
||||||
|
voltage = 5000;
|
||||||
|
}else{
|
||||||
|
voltage = 10000;
|
||||||
|
}
|
||||||
|
writeReg(OUTPUT_RANGE,&range,1);
|
||||||
|
}
|
||||||
|
void DFRobot_GP8403::setDACOutVoltage(uint16_t data, uint8_t channel)
|
||||||
|
{
|
||||||
|
uint16_t dataTransmission = (uint16_t)(((float)data / (voltage + voltOffset)) * 4095);
|
||||||
|
DBG(dataTransmission);
|
||||||
|
dataTransmission = dataTransmission << 4;
|
||||||
|
sendData(dataTransmission,channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DFRobot_GP8403::sendData(uint16_t data, uint8_t channel)
|
||||||
|
{
|
||||||
|
if(channel == 0){
|
||||||
|
_pWire->beginTransmission(_addr);
|
||||||
|
_pWire->write(GP8302_CONFIG_CURRENT_REG);
|
||||||
|
_pWire->write(data & 0xff);
|
||||||
|
_pWire->write((data >>8) & 0xff);
|
||||||
|
_pWire->endTransmission();
|
||||||
|
DBG(channel);
|
||||||
|
}else if(channel == 1){
|
||||||
|
_pWire->beginTransmission(_addr);
|
||||||
|
_pWire->write(GP8302_CONFIG_CURRENT_REG<<1);
|
||||||
|
_pWire->write(data & 0xff);
|
||||||
|
_pWire->write((data >>8) & 0xff);
|
||||||
|
_pWire->endTransmission();
|
||||||
|
DBG(channel);
|
||||||
|
}else{
|
||||||
|
_pWire->beginTransmission(_addr);
|
||||||
|
_pWire->write(GP8302_CONFIG_CURRENT_REG);
|
||||||
|
_pWire->write(data & 0xff);
|
||||||
|
_pWire->write((data >>8) & 0xff);
|
||||||
|
_pWire->write(data & 0xff);
|
||||||
|
_pWire->write((data >>8) & 0xff);
|
||||||
|
_pWire->endTransmission();
|
||||||
|
DBG(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DFRobot_GP8403::store(){
|
||||||
|
#if defined(ESP32)
|
||||||
|
_pWire->~TwoWire();
|
||||||
|
#elif !defined(ESP8266)
|
||||||
|
_pWire->end();
|
||||||
|
#endif
|
||||||
|
pinMode(_scl, OUTPUT);
|
||||||
|
pinMode(_sda, OUTPUT);
|
||||||
|
digitalWrite(_scl, HIGH);
|
||||||
|
digitalWrite(_sda, HIGH);
|
||||||
|
startSignal();
|
||||||
|
sendByte(GP8302_STORE_TIMING_HEAD, 0, 3, false);
|
||||||
|
stopSignal();
|
||||||
|
startSignal();
|
||||||
|
sendByte(GP8302_STORE_TIMING_ADDR);
|
||||||
|
sendByte(GP8302_STORE_TIMING_CMD1);
|
||||||
|
stopSignal();
|
||||||
|
|
||||||
|
startSignal();
|
||||||
|
sendByte(_addr<<1, 1);
|
||||||
|
sendByte(GP8302_STORE_TIMING_CMD2, 1);
|
||||||
|
sendByte(GP8302_STORE_TIMING_CMD2, 1);
|
||||||
|
sendByte(GP8302_STORE_TIMING_CMD2, 1);
|
||||||
|
sendByte(GP8302_STORE_TIMING_CMD2, 1);
|
||||||
|
sendByte(GP8302_STORE_TIMING_CMD2, 1);
|
||||||
|
sendByte(GP8302_STORE_TIMING_CMD2, 1);
|
||||||
|
sendByte(GP8302_STORE_TIMING_CMD2, 1);
|
||||||
|
sendByte(GP8302_STORE_TIMING_CMD2, 1);
|
||||||
|
stopSignal();
|
||||||
|
|
||||||
|
delay(GP8302_STORE_TIMING_DELAY);
|
||||||
|
|
||||||
|
startSignal();
|
||||||
|
sendByte(GP8302_STORE_TIMING_HEAD, 0, 3, false);
|
||||||
|
stopSignal();
|
||||||
|
startSignal();
|
||||||
|
sendByte(GP8302_STORE_TIMING_ADDR);
|
||||||
|
sendByte(GP8302_STORE_TIMING_CMD2);
|
||||||
|
stopSignal();
|
||||||
|
_pWire->begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFRobot_GP8403::startSignal(void){
|
||||||
|
digitalWrite(_scl,HIGH);
|
||||||
|
digitalWrite(_sda,HIGH);
|
||||||
|
delayMicroseconds(I2C_CYCLE_BEFORE);
|
||||||
|
digitalWrite(_sda,LOW);
|
||||||
|
delayMicroseconds(I2C_CYCLE_AFTER);
|
||||||
|
digitalWrite(_scl,LOW);
|
||||||
|
delayMicroseconds(I2C_CYCLE_TOTAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFRobot_GP8403::stopSignal(void){
|
||||||
|
digitalWrite(_sda,LOW);
|
||||||
|
delayMicroseconds(I2C_CYCLE_BEFORE);
|
||||||
|
digitalWrite(_scl,HIGH);
|
||||||
|
delayMicroseconds(I2C_CYCLE_TOTAL);
|
||||||
|
digitalWrite(_sda,HIGH);
|
||||||
|
delayMicroseconds(I2C_CYCLE_TOTAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t DFRobot_GP8403::sendByte(uint8_t data, uint8_t ack, uint8_t bits, bool flag){
|
||||||
|
for(int i=bits-1; i>=0;i--){
|
||||||
|
if(data & (1<<i)){
|
||||||
|
digitalWrite(_sda,HIGH);//Change the status of sda level during scl low level, and it lasts for some time
|
||||||
|
}else{
|
||||||
|
digitalWrite(_sda,LOW);
|
||||||
|
}
|
||||||
|
delayMicroseconds(I2C_CYCLE_BEFORE);
|
||||||
|
digitalWrite(_scl,HIGH);
|
||||||
|
delayMicroseconds(I2C_CYCLE_TOTAL);
|
||||||
|
//while(digitalRead(_scl) == 0){
|
||||||
|
//delayMicroseconds(1);
|
||||||
|
//}
|
||||||
|
digitalWrite(_scl,LOW);
|
||||||
|
delayMicroseconds(I2C_CYCLE_AFTER);
|
||||||
|
}
|
||||||
|
if(flag) return recvAck(ack);
|
||||||
|
else {
|
||||||
|
digitalWrite(_sda,LOW);//
|
||||||
|
digitalWrite(_scl,HIGH);//
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t DFRobot_GP8403::recvAck(uint8_t ack){
|
||||||
|
uint8_t ack_=0;
|
||||||
|
uint16_t errorTime = 0;
|
||||||
|
pinMode(_sda,INPUT_PULLUP);
|
||||||
|
digitalWrite(_sda,HIGH);
|
||||||
|
delayMicroseconds(I2C_CYCLE_BEFORE);
|
||||||
|
digitalWrite(_scl,HIGH);
|
||||||
|
delayMicroseconds(I2C_CYCLE_AFTER);
|
||||||
|
while(digitalRead(_sda) != ack){
|
||||||
|
delayMicroseconds(1);
|
||||||
|
errorTime++;
|
||||||
|
if(errorTime > 250) break;
|
||||||
|
}
|
||||||
|
ack_=digitalRead(_sda);
|
||||||
|
delayMicroseconds(I2C_CYCLE_BEFORE);
|
||||||
|
digitalWrite(_scl,LOW);
|
||||||
|
delayMicroseconds(I2C_CYCLE_AFTER);
|
||||||
|
pinMode(_sda,OUTPUT);
|
||||||
|
return ack_;
|
||||||
|
}
|
||||||
|
void DFRobot_GP8403::writeReg(uint8_t reg, void *pBuf, size_t size)
|
||||||
|
{
|
||||||
|
uint8_t *_pBuf = (uint8_t*)pBuf;
|
||||||
|
_pWire->beginTransmission(_addr);
|
||||||
|
_pWire->write(reg);
|
||||||
|
|
||||||
|
for(size_t i = 0; i < size; i++){
|
||||||
|
_pWire->write(_pBuf[i]);
|
||||||
|
}
|
||||||
|
_pWire->endTransmission();
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue