Example #1
0
int i2c_master_wr(unsigned int addr, const void * buf, int len)
{
	struct stm32f_i2c * i2c = STM32F_I2C1;
	int ret;

	xfer.ptr = (uint8_t *)buf;
	xfer.rem = len;
	xfer.cnt = len;
	/* – To enter Transmitter mode, a master sends the slave 
	   address with LSB reset. */
	xfer.addr = addr << 1;
	xfer.ret = -2;

	DCC_LOG2(LOG_INFO, "addr=0x%02x len=%d", addr, len);

//	tracef("addr=0x%02x len=%d", addr, len);

	__thinkos_flag_clr(xfer.flag);

	i2c->cr1 = I2C_START | I2C_ACK | I2C_PE; /* generate a Start condition */

	if (thinkos_flag_timedwait(xfer.flag, 100) == THINKOS_ETIMEDOUT) {
	//	tracef("thinkos_flag_timedwait() tmo %d %d ", xfer.cnt, xfer.flag);
		DCC_LOG(LOG_TRACE, "Timeout...");
		i2c_master_reset();
		ret = -1;
	} else
		ret = xfer.ret;

	DCC_LOG1(LOG_INFO, "ret=%d", ret);

	return ret;

}
Example #2
0
void i2c_reset(void)
{
	thinkos_mutex_lock(i2c_mutex);

	i2c_master_reset();

	thinkos_mutex_unlock(i2c_mutex);
}
Example #3
0
int i2c_cb(int i2c_id, unsigned char ** data, void * user, bool nack) {
	switch(i2c_status) {
	case I2C_IDLE:
		i2c_data = RF_ADDRESS << 1;
		*data = &i2c_data;
		i2c_status++;
		return I2C_MASTER_WRITE;
		
	case I2C_ADDRESS:
		if(nack) {
			i2c_status = I2C_STOP2;
			return I2C_MASTER_STOP;
		}
		i2c_status = I2C_REG_L;
		i2c_data = REG_FIFO_LEN;
		*data = &i2c_data;
		return I2C_MASTER_WRITE;
		
	case I2C_REG_L:
		if(nack) {
			i2c_status = I2C_STOP2;
			return I2C_MASTER_STOP;
		}
		i2c_status = I2C_RESTART;
		return I2C_MASTER_RESTART;
		
	case I2C_RESTART:
		i2c_data = RF_ADDRESS << 1 | 0x1;
		*data = &i2c_data;
		i2c_status = I2C_ADDRESS2;
		return I2C_MASTER_WRITE;
		
	case I2C_ADDRESS2:
		if(nack){
			i2c_status = I2C_STOP2;
			return I2C_MASTER_STOP;
		}
		i2c_status = I2C_READ_L1;
		*data = &i2c_data;
		return I2C_MASTER_READ;
		
	case I2C_READ_L1:
		i2c_status = I2C_READ_L1_ACK;
		fifo_read_len = i2c_data;
		return I2C_MASTER_ACK;
		
	case I2C_READ_L2:
		fifo_read_len |= i2c_data << 8;
		
		if(fifo_read_len && !AsebaFifoRxFull()) {
			i2c_status = I2C_READ_L2_ACK;
			return I2C_MASTER_ACK;
		} else {
			i2c_status = I2C_READ_FIFO_NACK;
			return I2C_MASTER_NACK;
		}		
	case I2C_READ_L1_ACK:
		i2c_status = I2C_READ_L2;
		*data = &i2c_data;
		return I2C_MASTER_READ;
		
	case I2C_READ_FIFO_ACK:
	case I2C_READ_L2_ACK:
		i2c_status = I2C_READ_FIFO;
		*data = &i2c_data;
		return I2C_MASTER_READ;
		
	case I2C_READ_FIFO:
		AsebaFifoPushToRx(i2c_data);
		status |= RF_DATA_RX;
		fifo_read_len--;
		if(fifo_read_len && !AsebaFifoRxFull()) {
			i2c_status = I2C_READ_FIFO_ACK;
			return I2C_MASTER_ACK;
		} else {
			i2c_status = I2C_READ_FIFO_NACK;
			return I2C_MASTER_NACK;
		}
	case I2C_READ_FIFO_NACK:
		// Check if we should write something.
		if(!AsebaFifoTxEmpty()) {
			i2c_status = I2C_RESTART2;
			return I2C_MASTER_RESTART;
			
		} else {
			// Nothing to send. End of communication.
			i2c_status = I2C_STOP2;
			return I2C_MASTER_STOP;
		}	
	case I2C_RESTART2:
		i2c_data = RF_ADDRESS << 1;
		*data = &i2c_data;
		i2c_status = I2C_ADDRESS3;
		return I2C_MASTER_WRITE;
	case I2C_ADDRESS3:
		if(nack) {
			i2c_status = I2C_STOP2;
			return I2C_MASTER_STOP;
		}
		*data = &i2c_data;
		i2c_data = REG_FIFO;
		i2c_status = I2C_REG_F;
		return I2C_MASTER_WRITE;
	case I2C_REG_F:
		if(nack || AsebaFifoTxEmpty()) {
			i2c_status = I2C_STOP2;
			return I2C_MASTER_STOP;
		} 
		i2c_status = I2C_WRITE_FIFO;
		i2c_data = AsebaFifoTxPeek();
		*data = &i2c_data;
		return I2C_MASTER_WRITE;
			
	case I2C_WRITE_FIFO:
		if(!nack) // The device accepted our write.
			AsebaFifoTxPop();

		if(nack || AsebaFifoTxEmpty()) {
			// RF fifo full ... or our fifo is empty.
			// In both case we have to stop writing.
			i2c_status = I2C_STOP2;
			return I2C_MASTER_STOP;
		} 
		// try a next write
		i2c_status = I2C_WRITE_FIFO;
		i2c_data = AsebaFifoTxPeek();
		*data = &i2c_data;
		return I2C_MASTER_WRITE;
		
	case I2C_STOP2:
		i2c_status = I2C_IDLE;
		if(read_acc) {
			read_acc = 0;
			// Read async will immediatly start a transfert.
			// We must reset the state machine first.
			i2c_master_reset(i2c_id);
			mma7660_read_async();
			return I2C_MASTER_QUIT;
		} else
			return I2C_MASTER_DONE;
	}
	// Never reached
	return I2C_MASTER_QUIT;	
}