An I2C Scanner, to test that your I2C can be detected. Works with the NRF51 Development Kit.
Dependencies: mbed-src-nrf51822
wire.cpp
00001 /* 00002 00003 Copyright (c) 2014 RedBearLab, All rights reserved. 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; either 00008 version 2.1 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00013 See the GNU Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the Free Software 00017 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00020 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00021 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00022 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 00023 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 00024 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 00025 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00026 00027 */ 00028 00029 #include "wire.h" 00030 #include "nrf_soc.h" 00031 #include "nrf_sdm.h" 00032 00033 //extern Serial pc; 00034 /********************************************************************** 00035 name : 00036 function : return: 0--SUCCESS, 1--FAIL 00037 **********************************************************************/ 00038 bool TwoWire::twi_master_clear_bus(void) 00039 { 00040 bool bus_clear; 00041 uint32_t twi_state; 00042 uint32_t sck_pin_config; 00043 uint32_t sda_pin_config; 00044 00045 twi_state = twi->ENABLE; 00046 twi->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; 00047 00048 sck_pin_config = NRF_GPIO->PIN_CNF[SCL_Pin]; 00049 NRF_GPIO->PIN_CNF[SCL_Pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) 00050 | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) 00051 | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) 00052 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) 00053 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); 00054 00055 sda_pin_config = NRF_GPIO->PIN_CNF[SDA_Pin]; 00056 NRF_GPIO->PIN_CNF[SDA_Pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) 00057 | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) 00058 | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) 00059 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) 00060 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); 00061 00062 NRF_GPIO->OUTSET = ( 1 << SCL_Pin ); 00063 NRF_GPIO->OUTSET = ( 1 << SDA_Pin ); 00064 TWI_DELAY(4); 00065 00066 if( ( (NRF_GPIO->IN >> SCL_Pin) & 0X1UL ) && ( (NRF_GPIO->IN >> SDA_Pin) & 0x1UL ) ) 00067 { 00068 bus_clear = 0; 00069 } 00070 else 00071 { 00072 uint_fast8_t index; 00073 bus_clear = 1; 00074 for( index=18; index--;) 00075 { 00076 NRF_GPIO->OUTCLR = ( 1 << SCL_Pin ); 00077 TWI_DELAY(4); 00078 NRF_GPIO->OUTSET = ( 1 << SDA_Pin ); 00079 TWI_DELAY(4); 00080 00081 if( (NRF_GPIO->IN >> SDA_Pin) & 0x1UL == 1 ) 00082 { 00083 bus_clear = 0; 00084 break; 00085 } 00086 } 00087 } 00088 00089 NRF_GPIO->PIN_CNF[SCL_Pin] = sck_pin_config; 00090 NRF_GPIO->PIN_CNF[SDA_Pin] = sda_pin_config; 00091 00092 twi->ENABLE = twi_state; 00093 00094 return bus_clear; 00095 } 00096 00097 /********************************************************************** 00098 name : 00099 function : return: 0--SUCCESS, 1--FAIL 00100 **********************************************************************/ 00101 bool TwoWire::twi_master_init(void) 00102 { 00103 uint8_t softdevice_enabled; 00104 //uint32_t err_code = NRF_SUCCESS; 00105 00106 NRF_GPIO->PIN_CNF[SCL_Pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) 00107 | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) 00108 | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) 00109 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) 00110 | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos); 00111 00112 NRF_GPIO->PIN_CNF[SDA_Pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) 00113 | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) 00114 | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) 00115 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) 00116 | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos); 00117 00118 twi->EVENTS_RXDREADY = 0; 00119 twi->EVENTS_TXDSENT = 0; 00120 twi->PSELSCL = SCL_Pin; 00121 twi->PSELSDA = SDA_Pin; 00122 twi->FREQUENCY = twi_frequency; //TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos; 00123 00124 sd_softdevice_is_enabled(&softdevice_enabled); 00125 //APP_ERROR_CHECK(err_code); 00126 if (softdevice_enabled == 0) 00127 { 00128 NRF_PPI->CH[7].EEP = (uint32_t)&twi->EVENTS_BB; 00129 NRF_PPI->CH[7].TEP = (uint32_t)&twi->TASKS_SUSPEND; 00130 NRF_PPI->CHEN &= ~(1 << 7); 00131 } 00132 else 00133 { 00134 sd_ppi_channel_assign(7, &twi->EVENTS_BB, &twi->TASKS_SUSPEND); 00135 //APP_ERROR_CHECK(err_code); 00136 sd_ppi_channel_enable_clr(1 << 7); 00137 //APP_ERROR_CHECK(err_code); 00138 } 00139 00140 twi->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos; 00141 00142 return twi_master_clear_bus(); 00143 } 00144 /********************************************************************** 00145 name : 00146 function : return: 0--SUCCESS, 1--FAIL 00147 **********************************************************************/ 00148 uint8_t TwoWire::twi_master_write(uint8_t *data, uint8_t data_length, uint8_t issue_stop_condition) 00149 { 00150 uint32_t timeout = MAX_TIMEOUT_LOOPS; 00151 00152 if(data_length == 0) 00153 { 00154 return 1; 00155 } 00156 twi->TXD = *data++; 00157 twi->TASKS_STARTTX = 1; 00158 while(1) 00159 { 00160 while( (twi->EVENTS_TXDSENT == 0) && (--timeout) );//&& (twi->EVENTS_ERROR == 0) ); 00161 00162 if( 0 == timeout )//|| twi->EVENTS_ERROR != 0) 00163 { 00164 twi->EVENTS_ERROR = 0; 00165 twi->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; 00166 twi->POWER = 0; 00167 TWI_DELAY(5); 00168 twi->POWER = 1; 00169 twi->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos; 00170 00171 twi_master_init(); 00172 return 1; 00173 } 00174 twi->EVENTS_TXDSENT = 0; 00175 if( --data_length == 0) 00176 { 00177 break; 00178 } 00179 00180 twi->TXD = *data++; 00181 } 00182 if(issue_stop_condition) 00183 { 00184 twi->EVENTS_STOPPED = 0; 00185 twi->TASKS_STOP = 1; 00186 while(twi->EVENTS_STOPPED == 0) 00187 { 00188 //do nothing, wait for stop sequence is sent 00189 } 00190 } 00191 return 0; 00192 } 00193 /********************************************************************** 00194 name : 00195 function : return: 0--SUCCESS, 1--FAIL 00196 **********************************************************************/ 00197 uint8_t TwoWire::twi_master_read(uint8_t *data, uint8_t data_length, uint8_t issue_stop_condition) 00198 { 00199 uint8_t softdevice_enabled; 00200 uint32_t timeout = MAX_TIMEOUT_LOOPS;// err_code = NRF_SUCCESS; 00201 00202 sd_softdevice_is_enabled(&softdevice_enabled); 00203 //APP_ERROR_CHECK(err_code); 00204 if( 0 == data_length ) 00205 { 00206 return 1; 00207 } 00208 else if( 1== data_length )//&& issue_stop_condition == 1) 00209 { 00210 if (softdevice_enabled == 0) 00211 { 00212 NRF_PPI->CH[7].EEP = (uint32_t)&twi->EVENTS_BB; 00213 NRF_PPI->CH[7].TEP = (uint32_t)&twi->TASKS_STOP; 00214 NRF_PPI->CHEN |= (1 << 7); 00215 } 00216 else 00217 { 00218 sd_ppi_channel_assign(7, &twi->EVENTS_BB, &twi->TASKS_STOP); 00219 //APP_ERROR_CHECK(err_code); 00220 sd_ppi_channel_enable_set(1 << 7); 00221 //APP_ERROR_CHECK(err_code); 00222 } 00223 } 00224 else 00225 { 00226 if (softdevice_enabled == 0) 00227 { 00228 NRF_PPI->CH[7].EEP = (uint32_t)&twi->EVENTS_BB; 00229 NRF_PPI->CH[7].TEP = (uint32_t)&twi->TASKS_SUSPEND; 00230 NRF_PPI->CHEN |= (1 << 7); 00231 } 00232 else 00233 { 00234 sd_ppi_channel_assign(7, &twi->EVENTS_BB, &twi->TASKS_SUSPEND); 00235 //APP_ERROR_CHECK(err_code); 00236 sd_ppi_channel_enable_set(1 << 7); 00237 //APP_ERROR_CHECK(err_code); 00238 } 00239 } 00240 00241 twi->EVENTS_RXDREADY = 0; 00242 twi->TASKS_STARTRX = 1; 00243 00244 while(1) 00245 { 00246 while( twi->EVENTS_RXDREADY == 0 && (--timeout) ) 00247 { 00248 //do nothing, just wait 00249 } 00250 00251 if( timeout == 0 ) 00252 { 00253 twi->EVENTS_ERROR = 0; 00254 twi->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; 00255 twi->POWER = 0; 00256 TWI_DELAY(5); 00257 twi->POWER = 1; 00258 twi->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos; 00259 00260 twi_master_init(); 00261 00262 return 1; 00263 } 00264 00265 twi->EVENTS_RXDREADY = 0; 00266 *data++ = twi->RXD; 00267 00268 if( --data_length == 1 ) 00269 { 00270 if (softdevice_enabled == 0) 00271 { 00272 //NRF_PPI->CH[7].EEP = (uint32_t)&twi->EVENTS_BB; 00273 NRF_PPI->CH[7].TEP = (uint32_t)&twi->TASKS_STOP; 00274 } 00275 else 00276 { 00277 sd_ppi_channel_assign(7, &twi->EVENTS_BB, &twi->TASKS_STOP); 00278 //APP_ERROR_CHECK(err_code); 00279 } 00280 } 00281 00282 if( data_length == 0 ) 00283 { 00284 twi->TASKS_STOP = 1; 00285 break; 00286 } 00287 TWI_DELAY(20); 00288 twi->TASKS_RESUME = 1; 00289 } 00290 while( twi->EVENTS_STOPPED == 0 ) 00291 { 00292 //do nothing 00293 } 00294 00295 twi->EVENTS_STOPPED = 0; 00296 00297 if (softdevice_enabled == 0) 00298 { 00299 NRF_PPI->CHEN &= ~(1 << 7); 00300 } 00301 else 00302 { 00303 sd_ppi_channel_enable_clr( 1 << 7 ); 00304 //APP_ERROR_CHECK(err_code); 00305 } 00306 return 0; 00307 } 00308 00309 /********************************************************************** 00310 name : 00311 function : 00312 **********************************************************************/ 00313 TwoWire::TwoWire(NRF_TWI_Type *twi_use) 00314 { 00315 twi = twi_use; 00316 00317 RX_BufferIndex = 0; 00318 RX_BufferLength = 0; 00319 TX_BufferIndex = 0; 00320 TX_BufferLength = 0; 00321 00322 Transform_Addr = 0; 00323 00324 twi_status = UNINITIALIZED; 00325 } 00326 /********************************************************************** 00327 name : 00328 function : 00329 **********************************************************************/ 00330 void TwoWire::begin(uint32_t scl, uint32_t sda, uint8_t speed) 00331 { 00332 if( speed == 2 ) 00333 { 00334 twi_frequency = TWI_FREQUENCY_FREQUENCY_K400; 00335 } 00336 else if( speed == 1 ) 00337 { 00338 twi_frequency = TWI_FREQUENCY_FREQUENCY_K250; 00339 } 00340 else 00341 { 00342 twi_frequency = TWI_FREQUENCY_FREQUENCY_K100; 00343 } 00344 00345 SCL_Pin = scl; 00346 SDA_Pin = sda; 00347 twi_master_init(); 00348 00349 twi_status = MASTER_IDLE; 00350 } 00351 /********************************************************************** 00352 name : 00353 function : 00354 **********************************************************************/ 00355 void TwoWire::begin() 00356 { 00357 begin(TWI_SCL, TWI_SDA, 0); 00358 } 00359 /********************************************************************** 00360 name : 00361 function : 00362 **********************************************************************/ 00363 void TwoWire::beginTransmission( uint8_t address ) 00364 { 00365 Transform_Addr = address; 00366 TX_BufferIndex = 0; 00367 twi_status = MASTER_SEND; 00368 } 00369 /********************************************************************** 00370 name : 00371 function : 00372 **********************************************************************/ 00373 void TwoWire::beginTransmission( int address ) 00374 { 00375 beginTransmission( (uint8_t)address ); 00376 } 00377 /********************************************************************** 00378 name : 00379 function : return: 0--SUCCESS, 1--FAIL 00380 **********************************************************************/ 00381 uint8_t TwoWire::endTransmission( uint8_t stop) 00382 { 00383 uint8_t twi_flag = 1; 00384 00385 if(TX_BufferLength > 0 && !(twi_master_clear_bus()) ) 00386 { 00387 twi->ADDRESS = ( Transform_Addr >> 1); 00388 twi_flag = twi_master_write(TX_Buffer, TX_BufferLength, stop); 00389 } 00390 00391 TX_BufferLength = 0; 00392 twi_status = MASTER_IDLE; 00393 00394 return twi_flag; 00395 } 00396 /********************************************************************** 00397 name : 00398 function : return: 0--SUCCESS, 1--FAIL 00399 **********************************************************************/ 00400 uint8_t TwoWire::endTransmission(void) 00401 { 00402 uint8_t twi_flag; 00403 00404 twi_flag = endTransmission(1); 00405 00406 return twi_flag; 00407 } 00408 /********************************************************************** 00409 name : 00410 function : return: 0--SUCCESS, -1--FAIL, 00411 **********************************************************************/ 00412 int TwoWire::write(uint8_t data) 00413 { 00414 if(twi_status == MASTER_SEND) 00415 { 00416 if(TX_BufferLength >= BUFF_MAX_LENGTH) 00417 { 00418 return -1; 00419 } 00420 TX_Buffer[TX_BufferLength++] = data; 00421 return 0; 00422 } 00423 else 00424 { 00425 return -1; 00426 } 00427 } 00428 /********************************************************************** 00429 name : 00430 function : return: -1--FAIL, else--the length of data stored 00431 **********************************************************************/ 00432 int TwoWire::write(const uint8_t *data, size_t quantity ) 00433 { 00434 if( twi_status == MASTER_SEND ) 00435 { 00436 for( size_t i=0; i<quantity; ++i ) 00437 { 00438 if(TX_BufferLength >= BUFF_MAX_LENGTH) 00439 { 00440 return i; 00441 } 00442 TX_Buffer[TX_BufferLength++] = data[i]; 00443 } 00444 } 00445 else 00446 { 00447 return -1; 00448 } 00449 00450 return quantity; 00451 } 00452 /********************************************************************** 00453 name : 00454 function : return: 0--SUCCESS, 1--FAIL 00455 **********************************************************************/ 00456 uint8_t TwoWire::requestFrom(uint8_t addr, uint8_t quantity, uint8_t stop) 00457 { 00458 uint8_t twi_flag = 1; 00459 00460 if(quantity > BUFF_MAX_LENGTH) 00461 { 00462 quantity = BUFF_MAX_LENGTH; 00463 } 00464 if(quantity > 0 && !(twi_master_clear_bus()) ) 00465 { 00466 twi->ADDRESS = ( addr >> 1 ); 00467 twi_flag = twi_master_read(RX_Buffer, quantity, stop); 00468 } 00469 RX_BufferIndex = 0; 00470 RX_BufferLength = quantity; 00471 00472 return twi_flag; 00473 } 00474 /********************************************************************** 00475 name : 00476 function : 00477 **********************************************************************/ 00478 uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) 00479 { 00480 return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true); 00481 } 00482 /********************************************************************** 00483 name : 00484 function : 00485 **********************************************************************/ 00486 uint8_t TwoWire::requestFrom(int address, int quantity) 00487 { 00488 return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true); 00489 } 00490 /********************************************************************** 00491 name : 00492 function : 00493 **********************************************************************/ 00494 uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) 00495 { 00496 return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) sendStop); 00497 } 00498 /********************************************************************** 00499 name : 00500 function : return:-1--FAIL, else:the length of data that could be read 00501 **********************************************************************/ 00502 int TwoWire::available(void) 00503 { 00504 if(RX_BufferIndex <= RX_BufferLength) 00505 { 00506 return (RX_BufferLength - RX_BufferIndex); 00507 } 00508 else 00509 { 00510 return -1; 00511 } 00512 } 00513 /********************************************************************** 00514 name : 00515 function : 00516 **********************************************************************/ 00517 int TwoWire::read(void) 00518 { 00519 if(RX_BufferIndex < RX_BufferLength) 00520 { 00521 return RX_Buffer[RX_BufferIndex++]; 00522 } 00523 else 00524 { 00525 return -1; 00526 } 00527 } 00528
Generated on Wed Jul 13 2022 05:37:38 by 1.7.2