fix for cancelling arbitration
This commit is contained in:
+33
-10
@@ -192,11 +192,29 @@ result_t Device::send(symbol_t value) {
|
|||||||
#define ENHANCED_COMPLETE_WAIT_DURATION 3
|
#define ENHANCED_COMPLETE_WAIT_DURATION 3
|
||||||
|
|
||||||
|
|
||||||
|
bool Device::cancelRunningArbitration(ArbitrationState* arbitrationState) {
|
||||||
|
if (m_enhancedProto && m_arbitrationMaster != SYN) {
|
||||||
|
*arbitrationState = as_error;
|
||||||
|
m_arbitrationMaster = SYN;
|
||||||
|
m_arbitrationCheck = false;
|
||||||
|
write(SYN, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (m_enhancedProto || m_arbitrationMaster == SYN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*arbitrationState = as_error;
|
||||||
|
m_arbitrationMaster = SYN;
|
||||||
|
m_arbitrationCheck = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
result_t Device::recv(unsigned int timeout, symbol_t* value, ArbitrationState* arbitrationState) {
|
result_t Device::recv(unsigned int timeout, symbol_t* value, ArbitrationState* arbitrationState) {
|
||||||
if (m_arbitrationMaster!=SYN) {
|
if (m_arbitrationMaster!=SYN) {
|
||||||
*arbitrationState = as_running;
|
*arbitrationState = as_running;
|
||||||
}
|
}
|
||||||
if (!isValid()) {
|
if (!isValid()) {
|
||||||
|
cancelRunningArbitration(arbitrationState);
|
||||||
return RESULT_ERR_DEVICE;
|
return RESULT_ERR_DEVICE;
|
||||||
}
|
}
|
||||||
bool repeat = false;
|
bool repeat = false;
|
||||||
@@ -246,6 +264,7 @@ result_t Device::recv(unsigned int timeout, symbol_t* value, ArbitrationState* a
|
|||||||
fprintf(stdout, "poll error %d\n", errno);
|
fprintf(stdout, "poll error %d\n", errno);
|
||||||
#endif
|
#endif
|
||||||
close();
|
close();
|
||||||
|
cancelRunningArbitration(arbitrationState);
|
||||||
return RESULT_ERR_DEVICE;
|
return RESULT_ERR_DEVICE;
|
||||||
}
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
@@ -287,9 +306,7 @@ result_t Device::recv(unsigned int timeout, symbol_t* value, ArbitrationState* a
|
|||||||
m_listener->notifyDeviceData(*value, true);
|
m_listener->notifyDeviceData(*value, true);
|
||||||
}
|
}
|
||||||
if (!wrote) {
|
if (!wrote) {
|
||||||
*arbitrationState = as_error;
|
cancelRunningArbitration(arbitrationState);
|
||||||
m_arbitrationMaster = SYN;
|
|
||||||
m_arbitrationCheck = false;
|
|
||||||
return RESULT_OK;
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
if (m_listener != nullptr) {
|
if (m_listener != nullptr) {
|
||||||
@@ -302,13 +319,23 @@ result_t Device::recv(unsigned int timeout, symbol_t* value, ArbitrationState* a
|
|||||||
|
|
||||||
result_t Device::startArbitration(symbol_t masterAddress) {
|
result_t Device::startArbitration(symbol_t masterAddress) {
|
||||||
if (m_arbitrationCheck) {
|
if (m_arbitrationCheck) {
|
||||||
return RESULT_ERR_ARB_RUNNING; // should not occur
|
if (masterAddress != SYN) {
|
||||||
|
return RESULT_ERR_ARB_RUNNING; // should not occur
|
||||||
|
}
|
||||||
|
m_arbitrationCheck = false;
|
||||||
|
m_arbitrationMaster = SYN;
|
||||||
|
if (m_enhancedProto) {
|
||||||
|
// cancel running arbitration
|
||||||
|
if (!write(SYN, true)) {
|
||||||
|
return RESULT_ERR_SEND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RESULT_OK;
|
||||||
}
|
}
|
||||||
if (m_readOnly) {
|
if (m_readOnly) {
|
||||||
return RESULT_ERR_SEND;
|
return RESULT_ERR_SEND;
|
||||||
}
|
}
|
||||||
m_arbitrationMaster = masterAddress;
|
m_arbitrationMaster = masterAddress;
|
||||||
m_arbitrationCheck = false;
|
|
||||||
if (m_enhancedProto && masterAddress != SYN) {
|
if (m_enhancedProto && masterAddress != SYN) {
|
||||||
if (!write(masterAddress, true)) {
|
if (!write(masterAddress, true)) {
|
||||||
m_arbitrationMaster = SYN;
|
m_arbitrationMaster = SYN;
|
||||||
@@ -515,11 +542,7 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
|
|||||||
string str = stream.str();
|
string str = stream.str();
|
||||||
m_listener->notifyStatus(true, str.c_str());
|
m_listener->notifyStatus(true, str.c_str());
|
||||||
}
|
}
|
||||||
if (*arbitrationState != as_none) {
|
cancelRunningArbitration(arbitrationState);
|
||||||
*arbitrationState = as_error;
|
|
||||||
m_arbitrationMaster = SYN;
|
|
||||||
m_arbitrationCheck = false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (m_listener != nullptr) {
|
if (m_listener != nullptr) {
|
||||||
|
|||||||
@@ -207,6 +207,13 @@ class Device {
|
|||||||
*/
|
*/
|
||||||
virtual void checkDevice() = 0; // abstract
|
virtual void checkDevice() = 0; // abstract
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel a running arbitration.
|
||||||
|
* @param arbitrationState the reference in which @a as_error is stored when cancelled.
|
||||||
|
* @return true if it was cancelled, false if not.
|
||||||
|
*/
|
||||||
|
bool cancelRunningArbitration(ArbitrationState* arbitrationState);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a single byte.
|
* Write a single byte.
|
||||||
* @param value the byte value to write.
|
* @param value the byte value to write.
|
||||||
|
|||||||
Reference in New Issue
Block a user