void i2c_transmit(uint8_t slave_addr, uint8_t len, volatile bool_t* finished) { i2c_len = len; i2c_slave_addr = slave_addr & ~I2C_RECEIVE; i2c_finished = finished; i2c_status = I2C_BUSY; I2cSendStart(); }
bool_t i2c_submit(struct i2c_periph* p, struct i2c_transaction* t) { uint8_t idx; idx = p->trans_insert_idx + 1; if (idx >= I2C_TRANSACTION_QUEUE_LEN) idx = 0; if (idx == p->trans_extract_idx) { /* queue full */ p->errors->queue_full_cnt++; t->status = I2CTransFailed; return FALSE; } t->status = I2CTransPending; /* disable I2C interrupt */ //uint8_t* vic = (uint8_t*)(p->init_struct); //VICIntEnClear = VIC_BIT(*vic); disableIRQ(); p->trans[p->trans_insert_idx] = t; p->trans_insert_idx = idx; /* if peripheral is idle, start the transaction */ if (p->status == I2CIdle) I2cSendStart(p); /* else it will be started by the interrupt handler */ /* when the previous transactions completes */ /* enable I2C interrupt again */ //VICIntEnable = VIC_BIT(*vic); enableIRQ(); return TRUE; }
bool_t i2c_submit(struct i2c_periph* p, struct i2c_transaction* t) { unsigned cpsr; uint8_t idx; idx = p->trans_insert_idx + 1; if (idx >= I2C_TRANSACTION_QUEUE_LEN) idx = 0; if (idx == p->trans_extract_idx) { t->status = I2CTransFailed; return FALSE; /* queue full */ } t->status = I2CTransPending; uint8_t* vic = (uint8_t*)(p->init_struct); cpsr = disableIRQ(); // disable global interrupts VICIntEnClear = VIC_BIT(*vic); restoreIRQ(cpsr); // restore global interrupts p->trans[p->trans_insert_idx] = t; p->trans_insert_idx = idx; /* if peripheral is idle, start the transaction */ if (p->status == I2CIdle) I2cSendStart(p); /* else it will be started by the interrupt handler */ /* when the previous transactions completes */ //int_enable(); cpsr = disableIRQ(); // disable global interrupts VICIntEnable = VIC_BIT(*vic); restoreIRQ(cpsr); // restore global interrupts return TRUE; }
__attribute__ ((always_inline)) static inline void I2cEndOfTransaction(struct i2c_periph* p) { // handle fifo here p->trans_extract_idx++; if (p->trans_extract_idx >= I2C_TRANSACTION_QUEUE_LEN) p->trans_extract_idx = 0; // if no more transaction to process, stop here, else start next transaction if (p->trans_extract_idx == p->trans_insert_idx) { p->status = I2CIdle; } else { I2cSendStart(p); } }
static inline void i2c_automaton(uint32_t state) { switch (state) { case I2C_START: case I2C_RESTART: I2cSendByte(i2c_slave_addr); I2cClearStart(); i2c_index = 0; break; case I2C_MR_DATA_ACK: if (i2c_index < i2c_len) { i2c_buf[i2c_index] = I2C_DATA_REG; i2c_index++; I2cReceive(i2c_index < i2c_len - 1); } else { /* error , we should have got NACK */ I2cSendStop(); } break; case I2C_MR_SLA_ACK: /* At least one char */ /* Wait and reply with ACK or NACK */ I2cReceive(i2c_index < i2c_len - 1); break; case I2C_MR_SLA_NACK: case I2C_MT_SLA_NACK: I2cSendStart(); break; case I2C_MT_SLA_ACK: case I2C_MT_DATA_ACK: if (i2c_index < i2c_len) { I2cSendByte(i2c_buf[i2c_index]); i2c_index++; } else { I2cSendStop(); } break; case I2C_MR_DATA_NACK: if (i2c_index < i2c_len) { i2c_buf[i2c_index] = I2C_DATA_REG; } I2cSendStop(); break; default: I2cSendStop(); /* LED_ON(2); FIXME log error */ } }
static SiiResultCodes_t CraWriteBlockI2c ( int_t busIndex, uint8_t deviceId, uint8_t regAddr, const uint8_t *pBuffer, uint16_t count ) { SiiResultCodes_t status = SII_ERR_FAIL; do { // Send the register address but don't send stop if ( I2cSendStart( busIndex, deviceId, ®Addr, 1, FALSE ) != PLATFORM_SUCCESS ) { break; } // Send the remainder of the data, if necessary if ( I2cSendContinue( busIndex, pBuffer, count, TRUE ) != PLATFORM_SUCCESS ) { break; } status = SII_SUCCESS; } while (0); return( status ); }
static SiiResultCodes_t CraReadBlockI2c (int_t busIndex, uint8_t deviceId, uint8_t regAddr, uint8_t *pBuffer, uint16_t count ) { SiiResultCodes_t status = SII_ERR_FAIL; do { // Send the register address and stop bit if ( I2cSendStart( busIndex, deviceId, ®Addr, 1, FALSE ) != PLATFORM_SUCCESS ) { break; } // Receive the requested number of data bytes if ( I2cReceiveStart( busIndex, deviceId, pBuffer, count, TRUE ) != PLATFORM_SUCCESS ) { break; } status = SII_SUCCESS; } while (0); return( status ); }
bool_t i2c_submit(struct i2c_periph* p, struct i2c_transaction* t) { uint8_t idx; idx = p->trans_insert_idx + 1; if (idx >= I2C_TRANSACTION_QUEUE_LEN) idx = 0; if (idx == p->trans_extract_idx) { t->status = I2CTransFailed; return FALSE; /* queue full */ } t->status = I2CTransPending; int_disable(); p->trans[p->trans_insert_idx] = t; p->trans_insert_idx = idx; /* if peripheral is idle, start the transaction */ if (p->status == I2CIdle) I2cSendStart(p); /* else it will be started by the interrupt handler */ /* when the previous transactions completes */ int_enable(); return TRUE; }
__attribute__ ((always_inline)) static inline void I2cAutomaton(int32_t state, struct i2c_periph* p) { struct i2c_transaction* trans = p->trans[p->trans_extract_idx]; switch (state) { case I2C_START: case I2C_RESTART: // Set R/W flag switch (trans->type) { case I2CTransRx : SetBit(trans->slave_addr,0); break; case I2CTransTx: case I2CTransTxRx: ClearBit(trans->slave_addr,0); break; default: break; } I2cSendByte(p->reg_addr,trans->slave_addr); I2cClearStart(p->reg_addr); p->idx_buf = 0; break; case I2C_MR_DATA_ACK: if (p->idx_buf < trans->len_r) { trans->buf[p->idx_buf] = ((i2cRegs_t *)(p->reg_addr))->dat; p->idx_buf++; I2cReceive(p->reg_addr,p->idx_buf < trans->len_r - 1); } else { /* error , we should have got NACK */ I2cFail(p,trans); } break; case I2C_MR_DATA_NACK: if (p->idx_buf < trans->len_r) { trans->buf[p->idx_buf] = ((i2cRegs_t *)(p->reg_addr))->dat; } I2cSendStop(p,trans); break; case I2C_MR_SLA_ACK: /* At least one char */ /* Wait and reply with ACK or NACK */ I2cReceive(p->reg_addr,p->idx_buf < trans->len_r - 1); break; case I2C_MR_SLA_NACK: case I2C_MT_SLA_NACK: /* Slave is not responding, transaction is failed */ I2cFail(p,trans); break; case I2C_MT_SLA_ACK: case I2C_MT_DATA_ACK: if (p->idx_buf < trans->len_w) { I2cSendByte(p->reg_addr,trans->buf[p->idx_buf]); p->idx_buf++; } else { if (trans->type == I2CTransTxRx) { trans->type = I2CTransRx; /* FIXME should not change type */ p->idx_buf = 0; trans->slave_addr |= 1; I2cSendStart(p); } else { I2cSendStop(p,trans); } } break; default: I2cFail(p,trans); /* FIXME log error */ break; } }