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
C++
188 lines
4.6 KiB
C++
|
|
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();
|
|
}
|
|
|