8 #include "DigitalModule.h"
9 #include "NetworkCommunication/UsageReporting.h"
10 #include "Synchronized.h"
11 #include "WPIErrors.h"
14 SEM_ID I2C::m_semaphore = NULL;
15 uint32_t I2C::m_objCount = 0;
25 , m_deviceAddress (deviceAddress)
26 , m_compatibilityMode (true)
28 if (m_semaphore == NULL)
30 m_semaphore = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
34 nUsageReporting::report(nUsageReporting::kResourceType_I2C, deviceAddress, module->GetNumber() - 1);
45 semDelete(m_semaphore);
61 bool I2C::Transaction(uint8_t *dataToSend, uint8_t sendSize, uint8_t *dataReceived, uint8_t receiveSize)
65 wpi_setWPIErrorWithContext(ParameterOutOfRange,
"sendSize");
70 wpi_setWPIErrorWithContext(ParameterOutOfRange,
"receiveSize");
77 for(i=0; i<sendSize && i<
sizeof(data); i++)
79 data |= (uint32_t)dataToSend[i] << (8*i);
81 for(; i<sendSize; i++)
83 dataHigh |= (uint32_t)dataToSend[i] << (8*(i-
sizeof(data)));
87 tRioStatusCode localStatus = NiFpga_Status_Success;
90 m_module->m_fpgaDIO->writeI2CConfig_Address(m_deviceAddress, &localStatus);
91 m_module->m_fpgaDIO->writeI2CConfig_BytesToWrite(sendSize, &localStatus);
92 m_module->m_fpgaDIO->writeI2CConfig_BytesToRead(receiveSize, &localStatus);
93 if (sendSize > 0) m_module->m_fpgaDIO->writeI2CDataToSend(data, &localStatus);
94 if (sendSize >
sizeof(data)) m_module->m_fpgaDIO->writeI2CConfig_DataToSendHigh(dataHigh, &localStatus);
95 m_module->m_fpgaDIO->writeI2CConfig_BitwiseHandshake(m_compatibilityMode, &localStatus);
96 uint8_t transaction = m_module->m_fpgaDIO->readI2CStatus_Transaction(&localStatus);
97 m_module->m_fpgaDIO->strobeI2CStart(&localStatus);
98 while(transaction == m_module->m_fpgaDIO->readI2CStatus_Transaction(&localStatus)) taskDelay(1);
99 while(!m_module->m_fpgaDIO->readI2CStatus_Done(&localStatus)) taskDelay(1);
100 aborted = m_module->m_fpgaDIO->readI2CStatus_Aborted(&localStatus);
101 if (receiveSize > 0) data = m_module->m_fpgaDIO->readI2CDataReceived(&localStatus);
102 if (receiveSize >
sizeof(data)) dataHigh = m_module->m_fpgaDIO->readI2CStatus_DataReceivedHigh(&localStatus);
104 wpi_setError(localStatus);
106 for(i=0; i<receiveSize && i<
sizeof(data); i++)
108 dataReceived[i] = (data >> (8*i)) & 0xFF;
110 for(; i<receiveSize; i++)
112 dataReceived[i] = (dataHigh >> (8*(i-
sizeof(data)))) & 0xFF;
143 buffer[0] = registerAddress;
145 return Transaction(buffer,
sizeof(buffer), NULL, 0);
161 bool I2C::Read(uint8_t registerAddress, uint8_t count, uint8_t *buffer)
163 if (count < 1 || count > 7)
165 wpi_setWPIErrorWithContext(ParameterOutOfRange,
"count");
170 wpi_setWPIErrorWithContext(NullParameter,
"buffer");
174 return Transaction(®isterAddress,
sizeof(registerAddress), buffer, count);
199 m_compatibilityMode = enable;
201 const char *cm = NULL;
202 if (m_compatibilityMode) cm =
"C";
203 nUsageReporting::report(nUsageReporting::kResourceType_I2C, m_deviceAddress, m_module->GetNumber() - 1, cm);
222 uint8_t deviceData[4];
223 for (uint8_t i=0, curRegisterAddress = registerAddress; i < count; i+=4, curRegisterAddress+=4)
225 uint8_t toRead = count - i < 4 ? count - i : 4;
227 if (
Read(curRegisterAddress, toRead, deviceData))
return false;
229 for (uint8_t j=0; j<toRead; j++)
231 if(deviceData[j] != expected[i + j])
return false;
void Broadcast(uint8_t registerAddress, uint8_t data)
bool Transaction(uint8_t *dataToSend, uint8_t sendSize, uint8_t *dataReceived, uint8_t receiveSize)
void SetCompatibilityMode(bool enable)
bool Read(uint8_t registerAddress, uint8_t count, uint8_t *data)
bool VerifySensor(uint8_t registerAddress, uint8_t count, const uint8_t *expected)
bool Write(uint8_t registerAddress, uint8_t data)