Now you can download a copy of these docs so you can use them offline! Download now
I2C.cpp
00001 /*----------------------------------------------------------------------------*/ 00002 /* Copyright (c) FIRST 2008. All Rights Reserved. */ 00003 /* Open Source Software - may be modified and shared by FRC teams. The code */ 00004 /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */ 00005 /*----------------------------------------------------------------------------*/ 00006 00007 #include "I2C.h" 00008 #include "DigitalModule.h" 00009 #include "Synchronized.h" 00010 #include "WPIErrors.h" 00011 #include <taskLib.h> 00012 00013 SEM_ID I2C::m_semaphore = NULL; 00014 UINT32 I2C::m_objCount = 0; 00015 00022 I2C::I2C(DigitalModule *module, UINT8 deviceAddress) 00023 : m_module (module) 00024 , m_deviceAddress (deviceAddress) 00025 , m_compatibilityMode (false) 00026 { 00027 if (m_semaphore == NULL) 00028 { 00029 m_semaphore = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE); 00030 } 00031 m_objCount++; 00032 } 00033 00037 I2C::~I2C() 00038 { 00039 m_objCount--; 00040 if (m_objCount <= 0) 00041 { 00042 semDelete(m_semaphore); 00043 m_semaphore = NULL; 00044 } 00045 } 00046 00058 bool I2C::Transaction(UINT8 *dataToSend, UINT8 sendSize, UINT8 *dataReceived, UINT8 receiveSize) 00059 { 00060 if (sendSize > 6) 00061 { 00062 wpi_setWPIErrorWithContext(ParameterOutOfRange, "sendSize"); 00063 return true; 00064 } 00065 if (receiveSize > 7) 00066 { 00067 wpi_setWPIErrorWithContext(ParameterOutOfRange, "receiveSize"); 00068 return true; 00069 } 00070 00071 UINT32 data=0; 00072 UINT32 dataHigh=0; 00073 UINT32 i; 00074 for(i=0; i<sendSize && i<sizeof(data); i++) 00075 { 00076 data |= (UINT32)dataToSend[i] << (8*i); 00077 } 00078 for(; i<sendSize; i++) 00079 { 00080 dataHigh |= (UINT32)dataToSend[i] << (8*(i-sizeof(data))); 00081 } 00082 00083 bool aborted = true; 00084 tRioStatusCode localStatus = NiFpga_Status_Success; 00085 { 00086 Synchronized sync(m_semaphore); 00087 m_module->m_fpgaDIO->writeI2CConfig_Address(m_deviceAddress, &localStatus); 00088 m_module->m_fpgaDIO->writeI2CConfig_BytesToWrite(sendSize, &localStatus); 00089 m_module->m_fpgaDIO->writeI2CConfig_BytesToRead(receiveSize, &localStatus); 00090 if (sendSize > 0) m_module->m_fpgaDIO->writeI2CDataToSend(data, &localStatus); 00091 if (sendSize > sizeof(data)) m_module->m_fpgaDIO->writeI2CConfig_DataToSendHigh(dataHigh, &localStatus); 00092 m_module->m_fpgaDIO->writeI2CConfig_BitwiseHandshake(m_compatibilityMode, &localStatus); 00093 UINT8 transaction = m_module->m_fpgaDIO->readI2CStatus_Transaction(&localStatus); 00094 m_module->m_fpgaDIO->strobeI2CStart(&localStatus); 00095 while(transaction == m_module->m_fpgaDIO->readI2CStatus_Transaction(&localStatus)) taskDelay(1); 00096 while(!m_module->m_fpgaDIO->readI2CStatus_Done(&localStatus)) taskDelay(1); 00097 aborted = m_module->m_fpgaDIO->readI2CStatus_Aborted(&localStatus); 00098 if (receiveSize > 0) data = m_module->m_fpgaDIO->readI2CDataReceived(&localStatus); 00099 if (receiveSize > sizeof(data)) dataHigh = m_module->m_fpgaDIO->readI2CStatus_DataReceivedHigh(&localStatus); 00100 } 00101 wpi_setError(localStatus); 00102 00103 for(i=0; i<receiveSize && i<sizeof(data); i++) 00104 { 00105 dataReceived[i] = (data >> (8*i)) & 0xFF; 00106 } 00107 for(; i<receiveSize; i++) 00108 { 00109 dataReceived[i] = (dataHigh >> (8*(i-sizeof(data)))) & 0xFF; 00110 } 00111 return aborted; 00112 } 00113 00122 bool I2C::AddressOnly() 00123 { 00124 return Transaction(NULL, 0, NULL, 0); 00125 } 00126 00137 bool I2C::Write(UINT8 registerAddress, UINT8 data) 00138 { 00139 UINT8 buffer[2]; 00140 buffer[0] = registerAddress; 00141 buffer[1] = data; 00142 return Transaction(buffer, sizeof(buffer), NULL, 0); 00143 } 00144 00158 bool I2C::Read(UINT8 registerAddress, UINT8 count, UINT8 *buffer) 00159 { 00160 if (count < 1 || count > 7) 00161 { 00162 wpi_setWPIErrorWithContext(ParameterOutOfRange, "count"); 00163 return true; 00164 } 00165 if (buffer == NULL) 00166 { 00167 wpi_setWPIErrorWithContext(NullParameter, "buffer"); 00168 return true; 00169 } 00170 00171 return Transaction(®isterAddress, sizeof(registerAddress), buffer, count); 00172 } 00173 00182 void I2C::Broadcast(UINT8 registerAddress, UINT8 data) 00183 { 00184 } 00185 00194 void I2C::SetCompatibilityMode(bool enable) 00195 { 00196 m_compatibilityMode = enable; 00197 } 00198 00212 bool I2C::VerifySensor(UINT8 registerAddress, UINT8 count, const UINT8 *expected) 00213 { 00214 // TODO: Make use of all 7 read bytes 00215 UINT8 deviceData[4]; 00216 for (UINT8 i=0, curRegisterAddress = registerAddress; i < count; i+=4, curRegisterAddress+=4) 00217 { 00218 UINT8 toRead = count - i < 4 ? count - i : 4; 00219 // Read the chunk of data. Return false if the sensor does not respond. 00220 if (Read(curRegisterAddress, toRead, deviceData)) return false; 00221 00222 for (UINT8 j=0; j<toRead; j++) 00223 { 00224 if(deviceData[j] != expected[i + j]) return false; 00225 } 00226 } 00227 return true; 00228 } 00229
Generated on Thu Jan 12 2012 22:35:20 for WPILibC++ by
1.7.1