You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
4.6 KiB
Arduino

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) * 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();
}