I2C hang recover function added

Dependencies:   UniGraphic mbed vt100

In this version, check_i2c_pins function was added in edge_mgr.cpp.

プログラムの起動時、I2Cモジュールを初期化する前に、I2Cに使用するピンの電位を確認し
もし一方でも Low に張り付いていた場合、SCL を GPIO 出力に設定して 
所定回数 (I2C_UNLOCK_TRIAL_CYCLE) 反転させることにより、疑似リセットクロックを生成します。

その後は、通常の起動手順に復帰し、以降はこれまでと同様の動作をします。

Committer:
Rhyme
Date:
Tue Apr 03 08:30:29 2018 +0000
Revision:
0:d895cd1cd897
Initial I2C Pin force reset function added

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Rhyme 0:d895cd1cd897 1 /*
Rhyme 0:d895cd1cd897 2 * File description here
Rhyme 0:d895cd1cd897 3 */
Rhyme 0:d895cd1cd897 4 #include "VEML6040.h"
Rhyme 0:d895cd1cd897 5 #include "af_mgr.h"
Rhyme 0:d895cd1cd897 6
Rhyme 0:d895cd1cd897 7 /* VEML6075 SLAVE ADDRESS AND FUNCTION DESCRIPTION */
Rhyme 0:d895cd1cd897 8 #define REG_COLOR_CONF 0x00
Rhyme 0:d895cd1cd897 9 #define REG_Reserved1 0x01
Rhyme 0:d895cd1cd897 10 #define REG_Reserved2 0x02
Rhyme 0:d895cd1cd897 11 #define REG_Reserved3 0x03
Rhyme 0:d895cd1cd897 12 #define REG_Reserved4 0x04
Rhyme 0:d895cd1cd897 13 #define REG_Reserved5 0x05
Rhyme 0:d895cd1cd897 14 #define REG_Reserved6 0x06
Rhyme 0:d895cd1cd897 15 #define REG_Reserved7 0x07
Rhyme 0:d895cd1cd897 16 #define REG_R_Data 0x08
Rhyme 0:d895cd1cd897 17 #define REG_G_Data 0x09
Rhyme 0:d895cd1cd897 18 #define REG_B_Data 0x0A
Rhyme 0:d895cd1cd897 19 #define REG_W_Data 0x0B
Rhyme 0:d895cd1cd897 20
Rhyme 0:d895cd1cd897 21 // Following magic numbers are from
Rhyme 0:d895cd1cd897 22 // VISHAY VEML6040 Application Note 84331
Rhyme 0:d895cd1cd897 23 // Page 4
Rhyme 0:d895cd1cd897 24 #define LUX_RESOLUTION_0 (0.25168)
Rhyme 0:d895cd1cd897 25 #define LUX_RESOLUTION_1 (0.12584)
Rhyme 0:d895cd1cd897 26 #define LUX_RESOLUTION_2 (0.06292)
Rhyme 0:d895cd1cd897 27 #define LUX_RESOLUTION_3 (0.03146)
Rhyme 0:d895cd1cd897 28 #define LUX_RESOLUTION_4 (0.01573)
Rhyme 0:d895cd1cd897 29 #define LUX_RESOLUTION_5 (0.007865)
Rhyme 0:d895cd1cd897 30
Rhyme 0:d895cd1cd897 31 // Following magic numbers are from
Rhyme 0:d895cd1cd897 32 // VISHAY VEML6040 Application Note 84331
Rhyme 0:d895cd1cd897 33 // Page 9
Rhyme 0:d895cd1cd897 34 #define CORR_COEFF_M0 (0.048403)
Rhyme 0:d895cd1cd897 35 #define CORR_COEFF_M1 (0.183633)
Rhyme 0:d895cd1cd897 36 #define CORR_COEFF_M2 (-0.253589)
Rhyme 0:d895cd1cd897 37 #define CORR_COEFF_M3 (0.022916)
Rhyme 0:d895cd1cd897 38 #define CORR_COEFF_M4 (0.176388)
Rhyme 0:d895cd1cd897 39 #define CORR_COEFF_M5 (-0.183205)
Rhyme 0:d895cd1cd897 40 #define CORR_COEFF_M6 (-0.077436)
Rhyme 0:d895cd1cd897 41 #define CORR_COEFF_M7 (0.124541)
Rhyme 0:d895cd1cd897 42 #define CORR_COEFF_M8 (0.032081)
Rhyme 0:d895cd1cd897 43
Rhyme 0:d895cd1cd897 44 // Following magic numbers are from
Rhyme 0:d895cd1cd897 45 // VISHAY VEML6040 Application Note 84331
Rhyme 0:d895cd1cd897 46 // Page 10
Rhyme 0:d895cd1cd897 47 #define CCT_CONST (4278.6)
Rhyme 0:d895cd1cd897 48 #define OFFSET_OPEN_AIR (0.5)
Rhyme 0:d895cd1cd897 49
Rhyme 0:d895cd1cd897 50 VEML6040::VEML6040(I2C *i2c, int addr) : m_addr(addr<<1) {
Rhyme 0:d895cd1cd897 51 p_i2c = i2c ;
Rhyme 0:d895cd1cd897 52 p_i2c->frequency(100000); /* 100kHz */
Rhyme 0:d895cd1cd897 53 // activate the peripheral
Rhyme 0:d895cd1cd897 54 }
Rhyme 0:d895cd1cd897 55
Rhyme 0:d895cd1cd897 56 VEML6040::~VEML6040() { }
Rhyme 0:d895cd1cd897 57
Rhyme 0:d895cd1cd897 58 /**
Rhyme 0:d895cd1cd897 59 * set COLOR Config
Rhyme 0:d895cd1cd897 60 * @param colorconf uint8_t 8bit register value
Rhyme 0:d895cd1cd897 61 * @returns 0: success non-0: failure
Rhyme 0:d895cd1cd897 62 * @note Command Code 0x00 is used to access CONF register
Rhyme 0:d895cd1cd897 63 * @note bit[7] (reserved)
Rhyme 0:d895cd1cd897 64 * @note bit[6:4] = IT[2:0] Integration Time Selector
Rhyme 0:d895cd1cd897 65 * @note bit[3] (reserved)
Rhyme 0:d895cd1cd897 66 * @note bit[2] TRIG Proceed one detcting cycle at manual force mode
Rhyme 0:d895cd1cd897 67 * @note bit[1] AF 0: Auto mode 1: manual force mode
Rhyme 0:d895cd1cd897 68 * @note bit[0] SD 0: normal 1: chip shutdown setting
Rhyme 0:d895cd1cd897 69 *
Rhyme 0:d895cd1cd897 70 * @note IT[2:0] 0=40ms, 1=80ms, 2=160ms, 3=320ms, 4=640ms, 5=1280ms
Rhyme 0:d895cd1cd897 71 * @note as our WatchDog is set to 1sec, 1280ms is invalid
Rhyme 0:d895cd1cd897 72 * @note and 640ms may not be practical
Rhyme 0:d895cd1cd897 73 */
Rhyme 0:d895cd1cd897 74 int VEML6040::setCOLORConf(uint8_t colorconf)
Rhyme 0:d895cd1cd897 75 {
Rhyme 0:d895cd1cd897 76 int result ;
Rhyme 0:d895cd1cd897 77 uint8_t data[3] ;
Rhyme 0:d895cd1cd897 78 data[0] = REG_COLOR_CONF ;
Rhyme 0:d895cd1cd897 79 data[1] = colorconf ;
Rhyme 0:d895cd1cd897 80 data[2] = 0 ;
Rhyme 0:d895cd1cd897 81 result = writeRegs(data, 3) ;
Rhyme 0:d895cd1cd897 82 return( result ) ;
Rhyme 0:d895cd1cd897 83 }
Rhyme 0:d895cd1cd897 84
Rhyme 0:d895cd1cd897 85 /**
Rhyme 0:d895cd1cd897 86 * get COLOR Config
Rhyme 0:d895cd1cd897 87 * @param *colorconf uint8_t refer to setCOLORConf for the value
Rhyme 0:d895cd1cd897 88 * @returns 0: success non-0: failure
Rhyme 0:d895cd1cd897 89 */
Rhyme 0:d895cd1cd897 90 int VEML6040::getCOLORConf(uint8_t *colorconf)
Rhyme 0:d895cd1cd897 91 {
Rhyme 0:d895cd1cd897 92 int result ;
Rhyme 0:d895cd1cd897 93 uint8_t data[2] ;
Rhyme 0:d895cd1cd897 94 result = readRegs(REG_COLOR_CONF, data, 2) ;
Rhyme 0:d895cd1cd897 95 if (result == 0) {
Rhyme 0:d895cd1cd897 96 *colorconf = data[0] ;
Rhyme 0:d895cd1cd897 97 }
Rhyme 0:d895cd1cd897 98 return( result ) ;
Rhyme 0:d895cd1cd897 99 }
Rhyme 0:d895cd1cd897 100
Rhyme 0:d895cd1cd897 101
Rhyme 0:d895cd1cd897 102
Rhyme 0:d895cd1cd897 103 int VEML6040::getRData(uint16_t *rdata)
Rhyme 0:d895cd1cd897 104 {
Rhyme 0:d895cd1cd897 105 uint8_t data[2] ;
Rhyme 0:d895cd1cd897 106 int result ;
Rhyme 0:d895cd1cd897 107 result = readRegs(REG_R_Data, data, 2) ;
Rhyme 0:d895cd1cd897 108 *rdata = (data[1]<<8) | data[0] ;
Rhyme 0:d895cd1cd897 109 return( result ) ;
Rhyme 0:d895cd1cd897 110 }
Rhyme 0:d895cd1cd897 111
Rhyme 0:d895cd1cd897 112 int VEML6040::getGData(uint16_t *gdata)
Rhyme 0:d895cd1cd897 113 {
Rhyme 0:d895cd1cd897 114 uint8_t data[2] ;
Rhyme 0:d895cd1cd897 115 int result ;
Rhyme 0:d895cd1cd897 116 result = readRegs(REG_G_Data, data, 2) ;
Rhyme 0:d895cd1cd897 117 *gdata = (data[1]<<8) | data[0] ;
Rhyme 0:d895cd1cd897 118 return( result ) ;
Rhyme 0:d895cd1cd897 119 }
Rhyme 0:d895cd1cd897 120
Rhyme 0:d895cd1cd897 121 int VEML6040::getBData(uint16_t *bdata)
Rhyme 0:d895cd1cd897 122 {
Rhyme 0:d895cd1cd897 123 uint8_t data[2] ;
Rhyme 0:d895cd1cd897 124 int result ;
Rhyme 0:d895cd1cd897 125 result = readRegs(REG_B_Data, data, 2) ;
Rhyme 0:d895cd1cd897 126 *bdata = (data[1]<<8) | data[0] ;
Rhyme 0:d895cd1cd897 127 return( result ) ;
Rhyme 0:d895cd1cd897 128 }
Rhyme 0:d895cd1cd897 129
Rhyme 0:d895cd1cd897 130 int VEML6040::getWData(uint16_t *wdata)
Rhyme 0:d895cd1cd897 131 {
Rhyme 0:d895cd1cd897 132 uint8_t data[2] ;
Rhyme 0:d895cd1cd897 133 int result ;
Rhyme 0:d895cd1cd897 134 result = readRegs(REG_W_Data, data, 2) ;
Rhyme 0:d895cd1cd897 135 *wdata = (data[1]<<8) | data[0] ;
Rhyme 0:d895cd1cd897 136 return( result ) ;
Rhyme 0:d895cd1cd897 137 }
Rhyme 0:d895cd1cd897 138
Rhyme 0:d895cd1cd897 139 // usage
Rhyme 0:d895cd1cd897 140 // fvalue = veml->getUVA() ;
Rhyme 0:d895cd1cd897 141 // printf("%f", fvalue) ;
Rhyme 0:d895cd1cd897 142 float VEML6040::getR(void)
Rhyme 0:d895cd1cd897 143 {
Rhyme 0:d895cd1cd897 144 uint16_t data ;
Rhyme 0:d895cd1cd897 145 float value ;
Rhyme 0:d895cd1cd897 146 getRData(&data) ;
Rhyme 0:d895cd1cd897 147 value = (float)LUX_RESOLUTION_0 * (float)data ;
Rhyme 0:d895cd1cd897 148 return( value ) ;
Rhyme 0:d895cd1cd897 149 }
Rhyme 0:d895cd1cd897 150
Rhyme 0:d895cd1cd897 151 float VEML6040::getG(void)
Rhyme 0:d895cd1cd897 152 {
Rhyme 0:d895cd1cd897 153 uint16_t data ;
Rhyme 0:d895cd1cd897 154 float value ;
Rhyme 0:d895cd1cd897 155 getGData(&data) ;
Rhyme 0:d895cd1cd897 156 value = (float)LUX_RESOLUTION_0 * (float)data ;
Rhyme 0:d895cd1cd897 157 return( value ) ;
Rhyme 0:d895cd1cd897 158 }
Rhyme 0:d895cd1cd897 159
Rhyme 0:d895cd1cd897 160 float VEML6040::getB(void)
Rhyme 0:d895cd1cd897 161 {
Rhyme 0:d895cd1cd897 162 uint16_t data ;
Rhyme 0:d895cd1cd897 163 float value ;
Rhyme 0:d895cd1cd897 164 getBData(&data) ;
Rhyme 0:d895cd1cd897 165 value = (float)LUX_RESOLUTION_0 * (float)data ;
Rhyme 0:d895cd1cd897 166 return( value ) ;
Rhyme 0:d895cd1cd897 167 }
Rhyme 0:d895cd1cd897 168
Rhyme 0:d895cd1cd897 169 float VEML6040::getW(void)
Rhyme 0:d895cd1cd897 170 {
Rhyme 0:d895cd1cd897 171 uint16_t data ;
Rhyme 0:d895cd1cd897 172 float value ;
Rhyme 0:d895cd1cd897 173 getWData(&data) ;
Rhyme 0:d895cd1cd897 174 value = (float)LUX_RESOLUTION_0 * (float)data ;
Rhyme 0:d895cd1cd897 175 return( value ) ;
Rhyme 0:d895cd1cd897 176 }
Rhyme 0:d895cd1cd897 177
Rhyme 0:d895cd1cd897 178 float VEML6040::getX(void)
Rhyme 0:d895cd1cd897 179 {
Rhyme 0:d895cd1cd897 180 uint16_t R ;
Rhyme 0:d895cd1cd897 181 uint16_t G ;
Rhyme 0:d895cd1cd897 182 uint16_t B ;
Rhyme 0:d895cd1cd897 183 float value ;
Rhyme 0:d895cd1cd897 184 getRData(&R) ;
Rhyme 0:d895cd1cd897 185 getGData(&G) ;
Rhyme 0:d895cd1cd897 186 getBData(&B) ;
Rhyme 0:d895cd1cd897 187 value = (float)CORR_COEFF_M0 * (float)R + (float)CORR_COEFF_M1 * (float)G + (float)CORR_COEFF_M2 * (float)B ;
Rhyme 0:d895cd1cd897 188 return( value ) ;
Rhyme 0:d895cd1cd897 189 }
Rhyme 0:d895cd1cd897 190
Rhyme 0:d895cd1cd897 191 float VEML6040::getY(void)
Rhyme 0:d895cd1cd897 192 {
Rhyme 0:d895cd1cd897 193 uint16_t R ;
Rhyme 0:d895cd1cd897 194 uint16_t G ;
Rhyme 0:d895cd1cd897 195 uint16_t B ;
Rhyme 0:d895cd1cd897 196 float value ;
Rhyme 0:d895cd1cd897 197 getRData(&R) ;
Rhyme 0:d895cd1cd897 198 getGData(&G) ;
Rhyme 0:d895cd1cd897 199 getBData(&B) ;
Rhyme 0:d895cd1cd897 200 value = (float)CORR_COEFF_M3 * (float)R + (float)CORR_COEFF_M4 * (float)G + (float)CORR_COEFF_M5 * (float)B ;
Rhyme 0:d895cd1cd897 201 return( value ) ;
Rhyme 0:d895cd1cd897 202 }
Rhyme 0:d895cd1cd897 203
Rhyme 0:d895cd1cd897 204 float VEML6040::getZ(void)
Rhyme 0:d895cd1cd897 205 {
Rhyme 0:d895cd1cd897 206 uint16_t R ;
Rhyme 0:d895cd1cd897 207 uint16_t G ;
Rhyme 0:d895cd1cd897 208 uint16_t B ;
Rhyme 0:d895cd1cd897 209 float value ;
Rhyme 0:d895cd1cd897 210 getRData(&R) ;
Rhyme 0:d895cd1cd897 211 getGData(&G) ;
Rhyme 0:d895cd1cd897 212 getBData(&B) ;
Rhyme 0:d895cd1cd897 213 value = (float)CORR_COEFF_M6 * (float)R + (float)CORR_COEFF_M7 * (float)G + (float)CORR_COEFF_M8 * (float)B ;
Rhyme 0:d895cd1cd897 214 return( value ) ;
Rhyme 0:d895cd1cd897 215 }
Rhyme 0:d895cd1cd897 216
Rhyme 0:d895cd1cd897 217 float VEML6040::getCCTiData(void)
Rhyme 0:d895cd1cd897 218 {
Rhyme 0:d895cd1cd897 219 uint16_t rdata ;
Rhyme 0:d895cd1cd897 220 uint16_t gdata ;
Rhyme 0:d895cd1cd897 221 uint16_t bdata ;
Rhyme 0:d895cd1cd897 222 float value ;
Rhyme 0:d895cd1cd897 223 getRData(&rdata) ;
Rhyme 0:d895cd1cd897 224 getGData(&gdata) ;
Rhyme 0:d895cd1cd897 225 getBData(&bdata) ;
Rhyme 0:d895cd1cd897 226 value = ((float)rdata - (float)bdata) / (float)gdata + (float)OFFSET_OPEN_AIR ;
Rhyme 0:d895cd1cd897 227 return( value ) ;
Rhyme 0:d895cd1cd897 228 }
Rhyme 0:d895cd1cd897 229
Rhyme 0:d895cd1cd897 230 float VEML6040::getCCTData(void)
Rhyme 0:d895cd1cd897 231 {
Rhyme 0:d895cd1cd897 232 // uint16_t cctidata ;
Rhyme 0:d895cd1cd897 233 float cctidata ;
Rhyme 0:d895cd1cd897 234 float value ;
Rhyme 0:d895cd1cd897 235 cctidata = getCCTiData() ;
Rhyme 0:d895cd1cd897 236 // getCCTiData(&cctidata) ;
Rhyme 0:d895cd1cd897 237 value = (float)CCT_CONST * powf( cctidata, -1.2455 ) ;
Rhyme 0:d895cd1cd897 238 return( value ) ;
Rhyme 0:d895cd1cd897 239 }
Rhyme 0:d895cd1cd897 240
Rhyme 0:d895cd1cd897 241 float VEML6040::getCIEX(void)
Rhyme 0:d895cd1cd897 242 {
Rhyme 0:d895cd1cd897 243 float X ;
Rhyme 0:d895cd1cd897 244 float Y ;
Rhyme 0:d895cd1cd897 245 float Z ;
Rhyme 0:d895cd1cd897 246 float value ;
Rhyme 0:d895cd1cd897 247 X = getX() ;
Rhyme 0:d895cd1cd897 248 Y = getY() ;
Rhyme 0:d895cd1cd897 249 Z = getZ() ;
Rhyme 0:d895cd1cd897 250 value = (float)X / ((float)X + (float)Y + (float)Z) ;
Rhyme 0:d895cd1cd897 251 return( value ) ;
Rhyme 0:d895cd1cd897 252 }
Rhyme 0:d895cd1cd897 253
Rhyme 0:d895cd1cd897 254 float VEML6040::getCIEY(void)
Rhyme 0:d895cd1cd897 255 {
Rhyme 0:d895cd1cd897 256 float X ;
Rhyme 0:d895cd1cd897 257 float Y ;
Rhyme 0:d895cd1cd897 258 float Z ;
Rhyme 0:d895cd1cd897 259 float value ;
Rhyme 0:d895cd1cd897 260 X = getX() ;
Rhyme 0:d895cd1cd897 261 Y = getY() ;
Rhyme 0:d895cd1cd897 262 Z = getZ() ;
Rhyme 0:d895cd1cd897 263 value = (float)Y / ((float)X + (float)Y + (float)Z) ;
Rhyme 0:d895cd1cd897 264 return( value ) ;
Rhyme 0:d895cd1cd897 265 }
Rhyme 0:d895cd1cd897 266
Rhyme 0:d895cd1cd897 267 int VEML6040::readRegs(int addr, uint8_t * data, int len) {
Rhyme 0:d895cd1cd897 268 char t[1] = {addr};
Rhyme 0:d895cd1cd897 269 int result ;
Rhyme 0:d895cd1cd897 270 __disable_irq() ; // Disable Interrupts
Rhyme 0:d895cd1cd897 271 result = p_i2c->write(m_addr, t, 1, true);
Rhyme 0:d895cd1cd897 272 if (result == 0) { // write success
Rhyme 0:d895cd1cd897 273 result = p_i2c->read(m_addr, (char *)data, len, false);
Rhyme 0:d895cd1cd897 274 }
Rhyme 0:d895cd1cd897 275 __enable_irq() ; // Enable Interrupts
Rhyme 0:d895cd1cd897 276 return(result) ;
Rhyme 0:d895cd1cd897 277 }
Rhyme 0:d895cd1cd897 278
Rhyme 0:d895cd1cd897 279 int VEML6040::writeRegs(uint8_t * data, int len) {
Rhyme 0:d895cd1cd897 280 int result ;
Rhyme 0:d895cd1cd897 281 __disable_irq() ; // Disable Interrupts
Rhyme 0:d895cd1cd897 282 result = p_i2c->write(m_addr, (char *)data, len);
Rhyme 0:d895cd1cd897 283 __enable_irq() ; // Enable Interrupts
Rhyme 0:d895cd1cd897 284 return(result) ;
Rhyme 0:d895cd1cd897 285 }