msg_t I2C::receive(i2caddr_t addr, uint8_t* rxbuf, size_t rxbytes, systime_t timeout){ msg_t msg; lock(); msg = i2cMasterReceiveTimeout(&driver, addr, rxbuf, rxbytes, timeout); if(msg == RDY_TIMEOUT){ i2cStop(&driver); i2cStart(&driver, &config); } unlock(); return msg; }
/* This is main function. */ void request_fake(void){ msg_t status = MSG_OK; systime_t tmo = MS2ST(4); i2cAcquireBus(&I2CD1); status = i2cMasterReceiveTimeout(&I2CD1, addr, rx_data, 2, tmo); i2cReleaseBus(&I2CD1); if (status == MSG_RESET){ errors = i2cGetErrors(&I2CD1); osalDbgCheck(I2C_ACK_FAILURE == errors); } }
msg_t I2C::receive(i2caddr_t addr, uint8_t* rxbuf, size_t rxbytes, systime_t timeout){ msg_t msg; lock(); //msg = i2cMasterReceiveTimeout(&driver, addr, rxbuf, rxbytes, timeout); clk_mgr_req_hsi(); msg = i2cMasterReceiveTimeout(&driver, addr, rxbuf, rxbytes, MS2ST(rxbytes)); if(msg == RDY_TIMEOUT){ i2cStop(&driver); clear_bus(); i2cStart(&driver, &config); } clk_mgr_noreq_hsi(); unlock(); return msg; }
/* * Application entry point. */ int main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); /* * Starting the I2C driver 2. */ i2cStart(&I2CD2, &i2cconfig); /* * Starting the blinker thread. */ chThdCreateStatic(blinker_wa, sizeof(blinker_wa), NORMALPRIO-1, blinker, NULL); /* * Normal main() thread activity, in this demo it does nothing. */ while (true) { unsigned i; msg_t msg; static const uint8_t cmd[] = {0, 0}; uint8_t data[16]; msg = i2cMasterTransmitTimeout(&I2CD2, 0x52, cmd, sizeof(cmd), data, sizeof(data), TIME_INFINITE); if (msg != MSG_OK) palTogglePad(GPIOC, GPIOC_LED3); for (i = 0; i < 256; i++) { msg = i2cMasterReceiveTimeout(&I2CD2, 0x52, data, sizeof(data), TIME_INFINITE); if (msg != MSG_OK) palTogglePad(GPIOC, GPIOC_LED3); } chThdSleepMilliseconds(500); palTogglePad(GPIOC, GPIOC_LED2); } return 0; }
/** * обертка запускатор транзакции */ msg_t i2c_receive(i2caddr_t addr, uint8_t *rxbuf, size_t rxbytes){ msg_t status = RDY_OK; i2cAcquireBus(&I2CD2); status = i2cMasterReceiveTimeout(&I2CD2, addr, rxbuf, rxbytes, MS2ST(6)); i2cReleaseBus(&I2CD2); chDbgAssert(status == RDY_OK, "i2c_transmit(), #1", "error in driver"); if (status == RDY_TIMEOUT){ /* в случае таймаута необходимо перезапустить драйвер */ i2cStop(&I2CD2); chThdSleepMilliseconds(1); i2cStart(&I2CD2, &i2cfg2); setGlobalFlag(I2C_RESTARTED_FLAG); return status; } return status; }
/* This is main function. */ void request_temperature(void){ int16_t t_int = 0, t_frac = 0; msg_t status = RDY_OK; systime_t tmo = MS2ST(4); i2cAcquireBus(&I2CD1); status = i2cMasterReceiveTimeout(&I2CD1, tmp75_addr, tmp75_rx_data, 2, tmo); i2cReleaseBus(&I2CD1); if (status != RDY_OK){ errors = i2cGetErrors(&I2CD1); } t_int = tmp75_rx_data[0] * 100; t_frac = (tmp75_rx_data[1] * 100) >> 8; temperature = t_int + t_frac; }
msg_t i2c_receive(i2caddr_t addr, uint8_t *rxbuf, size_t rxbytes){ msg_t status = RDY_OK; systime_t tmo = calc_timeout(&I2C_BUS, 0, rxbytes); i2cAcquireBus(&I2C_BUS); status = i2cMasterReceiveTimeout(&I2C_BUS, addr, rxbuf, rxbytes, tmo); i2cReleaseBus(&I2C_BUS); chDbgAssert(status == RDY_OK, "i2c_transmit(), #1", "error in driver"); if (status == RDY_TIMEOUT){ //chprintf((BaseChannel *)&SD1, "I2C Timeout, restarting...\r\n"); i2cStop(&I2C_BUS); chThdSleepMilliseconds(1); i2cStart(&I2C_BUS, &i2cfg1); setGlobalFlag(I2C_RESTARTED_FLAG); return status; } return status; }
static THD_FUNCTION(PollFakeThread, arg) { (void)arg; chRegSetThreadName("PollFake"); while (true) { msg_t status; uint8_t rx_data[2]; i2cflags_t errors; i2cAcquireBus(&I2CD1); status = i2cMasterReceiveTimeout(&I2CD1, I2C_FAKE_ADDR, rx_data, 2, MS2ST(4)); i2cReleaseBus(&I2CD1); if (status == MSG_RESET){ errors = i2cGetErrors(&I2CD1); osalDbgCheck(I2C_ACK_FAILURE == errors); } palTogglePad(IOPORT1, LED1); /* on */ osalThreadSleepMilliseconds(1000); } }
static msg_t i2cThread( void *arg ) { (void)arg; chRegSetThreadName( "i" ); // To all LOW/HIGH levels on address pins to reach their levels. chThdSleepMilliseconds( I2C_IO_TIMEOUT_MS ); while ( 1 ) { // Read ADDRESS pins. uint16_t ind = palReadPad( ADDR_PORT, ADDR_0_PIN ) | ( palReadPad( ADDR_PORT, ADDR_1_PIN ) << 1 ) | ( palReadPad( ADDR_PORT, ADDR_2_PIN ) << 2 ); ind = (~ind) & 0x0007; static uint8_t master; static msg_t status; static systime_t tmo; tmo = MS2ST( I2C_IO_TIMEOUT_MS ); master = ( ind == 0 ) ? 1 : 0; // I/O with other boards. static uint32_t dataOut = 0; static uint32_t pendDataOut = 0; static uint32_t dataIn = 0; setLeds( master ? 1 : 0 ); if ( master ) { // First the board itself. chMtxLock( &mutex ); ins[0] = valueRead(); write( pendOuts[0] ); chMtxUnlock(); // After all slave boards. static int8_t i; for ( i=0; i<I2C_SLAVES_CNT; i++ ) { // To make IO thread safe IO itself takes place in separate variables. // But storage arrays are filled within locked mutex. // Get output. chMtxLock( &mutex ); pendDataOut = pendOuts[i+1]; dataOut = outs[i+1]; chMtxUnlock(); // Write only if data to write differs from already written. if ( pendDataOut != dataOut ) { // IO itself. status = i2cMasterTransmitTimeout( &I2CD1, I2C_BASE_ADDR+i, (uint8_t *)(&pendDataOut), sizeof(pendDataOut), 0, 0, tmo ); if ( status == RDY_OK ) { chMtxLock( &mutex ); outs[i+1] = pendDataOut; chMtxUnlock(); toggleLedsImmediate( 2 ); } else { setLeds( 7 ); i2cStop( &I2CD1 ); chThdSleepMilliseconds( 10 ); i2cStart( &I2CD1, &i2cfg1 ); continue; } } status = i2cMasterReceiveTimeout( &I2CD1, I2C_BASE_ADDR+i, (uint8_t *)(&dataIn), sizeof(dataIn), tmo ); if ( status == RDY_OK ) { toggleLedsImmediate( 4 ); } else { setLeds( 7 ); i2cStop( &I2CD1 ); chThdSleepMilliseconds( 10 ); i2cStart( &I2CD1, &i2cfg1 ); continue; } // Get back input. chMtxLock( &mutex ); //ins[i+1] = (dataIn & 0x0000FFFF); ins[i+1] = dataIn; chMtxUnlock(); } // Here is generic I2C io. i2cIo(); chThdSleepMilliseconds( I2C_QUERY_PERIOD_MS ); } else { static uint8_t addr; addr = I2C_BASE_ADDR + ind - 1; //setLeds( addr ); dataIn = valueRead(); do { //dataIn = 0x12345678; status = i2cSlaveIoTimeout( &I2CD1, addr, (uint8_t *)&dataOut, sizeof( dataOut ), (uint8_t *)&dataIn, sizeof( dataIn ), i2cRxCb, i2cTxCb, tmo ); if ( status != RDY_OK ) { i2cStart( &I2CD1, &i2cfg1 ); setLeds( 7 ); } } while ( status != RDY_OK ); // Managed to initialize I2C slave IO. setLeds( 0 ); while ( 1 ) { /* status = i2cSlaveIoTimeout( &I2CD1, addr, (uint8_t *)&dataOut, sizeof( dataOut ), (uint8_t *)&dataIn, sizeof( dataIn ), i2cRxCb, i2cTxCb, tmo ); */ chThdSleepMilliseconds( I2C_QUERY_PERIOD_MS ); pendDataOut = valueRead(); chSysLock(); dataIn = pendDataOut; chSysUnlock(); write( dataOut ); } } /*if ( a == 0b00000111 ) { setLeds( 1 ); static uint32_t out = 0x12345678; status = RDY_OK; status = i2cMasterTransmitTimeout( &I2CD1, testAddr, (uint8_t *)(&out), sizeof(out), 0, 0, tmo ); } else setLeds( 2 ); */ } return 0; }
void i2cIo( void ) { static msg_t status; static uint8_t st; // Debug code. /* static uint16_t nnn = 0; if ( nnn++ > 50 ) nnn = 0; else return; g_i2cAddr = 64; g_i2cStatus = 1; g_i2cTxSz = 4; g_i2cRxSz = 0; g_i2cOutBuffer[0] = 6; g_i2cOutBuffer[1] = 1; g_i2cOutBuffer[2] = 0x0F; g_i2cOutBuffer[3] = 0x70; */ // / Debug code. chMtxLock( &mutex ); st = g_i2cStatus; chMtxUnlock(); if ( st == 1 ) { static systime_t tmo; tmo = MS2ST( 300 ); if ( g_i2cTxSz > 0 ) { status = i2cMasterTransmitTimeout( &I2CD1, g_i2cAddr, g_i2cOutBuffer, g_i2cTxSz, 0, 0, tmo ); if ( status == RDY_OK ) toggleLedsImmediate( 2 ); else setLeds( 7 ); if ( status != RDY_OK ) { chMtxLock( &mutex ); g_i2cStatus = 2; chMtxUnlock(); i2cStart( &I2CD1, &i2cfg1 ); return; } } if ( g_i2cRxSz > 0 ) { status = i2cMasterReceiveTimeout( &I2CD1, g_i2cAddr, g_i2cInBuffer, g_i2cRxSz, tmo ); if ( status == RDY_OK ) toggleLedsImmediate( 4 ); else setLeds( 7 ); if ( status != RDY_OK ) { chMtxLock( &mutex ); g_i2cStatus = 3; chMtxUnlock(); i2cStart( &I2CD1, &i2cfg1 ); return; } } chMtxLock( &mutex ); g_i2cStatus = 0; chMtxUnlock();