Пример #1
0
void ICACHE_FLASH_ATTR
i2c_init(void)
{
    //Disable interrupts
    ETS_GPIO_INTR_DISABLE();

    //Set pin functions
    PIN_FUNC_SELECT(I2C_SDA_MUX, I2C_SDA_FUNC);
    PIN_FUNC_SELECT(I2C_SCK_MUX, I2C_SCK_FUNC);

    //Set SDA as open drain
    GPIO_REG_WRITE(
        GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SDA_PIN)), 
        GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SDA_PIN))) | 
        GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)
    );

    GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_SDA_PIN));

    //Set SCK as open drain
    GPIO_REG_WRITE(
        GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SCK_PIN)), 
        GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SCK_PIN))) | 
        GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)
    );

    GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_SCK_PIN));

    //Turn interrupt back on
    ETS_GPIO_INTR_ENABLE();

    i2c_sda(1);
    i2c_sck(1);
    return;
}
Пример #2
0
/**
 * Receive byte from the I2C bus 
 * returns the byte 
 */
uint8 ICACHE_FLASH_ATTR
i2c_readByte(void)
{
    uint8 data = 0;
    uint8 data_bit;
    uint8 i;

    i2c_sda(1);

    for (i = 0; i < 8; i++)
    {
        os_delay_us(I2C_SLEEP_TIME);
        i2c_sck(0);
        os_delay_us(I2C_SLEEP_TIME);

        i2c_sck(1);
        os_delay_us(I2C_SLEEP_TIME);

        data_bit = i2c_read();
        os_delay_us(I2C_SLEEP_TIME);

        data_bit <<= (7 - i);
        data |= data_bit;
    }
    i2c_sck(0);
    os_delay_us(I2C_SLEEP_TIME);
    
    return data;
}
Пример #3
0
/**
 * I2C Stop signal 
 */
void ICACHE_FLASH_ATTR
i2c_stop(void)
{
    os_delay_us(I2C_SLEEP_TIME);
    i2c_sck(1);
    os_delay_us(I2C_SLEEP_TIME);
    i2c_sda(1);
    os_delay_us(I2C_SLEEP_TIME);
}
Пример #4
0
/**
 * Send I2C ACK to the bus
 * uint8 state 1 or 0
 *  1 for ACK
 *  0 for NACK
 */
void ICACHE_FLASH_ATTR
i2c_send_ack(uint8 state)
{
    i2c_sck(0);
    os_delay_us(I2C_SLEEP_TIME);
    //Set SDA 
    //  HIGH for NACK
    //  LOW  for ACK
    i2c_sda((state?0:1));

    //Pulse the SCK
    i2c_sck(0);
    os_delay_us(I2C_SLEEP_TIME);
    i2c_sck(1);
    os_delay_us(I2C_SLEEP_TIME);
    i2c_sck(0);
    os_delay_us(I2C_SLEEP_TIME);

    i2c_sda(1);
    os_delay_us(I2C_SLEEP_TIME);
}
Пример #5
0
/**
 * Receive I2C ACK from the bus
 * returns 1 or 0
 *  1 for ACK
 *  0 for NACK
 */
uint8 ICACHE_FLASH_ATTR
i2c_check_ack(void)
{
    uint8 ack;
    i2c_sda(1);
    os_delay_us(I2C_SLEEP_TIME);
    i2c_sck(0);
    os_delay_us(I2C_SLEEP_TIME);
    i2c_sck(1);
    os_delay_us(I2C_SLEEP_TIME);

    //Get SDA pin status
    ack = i2c_read(); 

    os_delay_us(I2C_SLEEP_TIME);
    i2c_sck(0);
    os_delay_us(I2C_SLEEP_TIME);
    i2c_sda(0);
    os_delay_us(I2C_SLEEP_TIME);

    return (ack?0:1);
}
Пример #6
0
// *************************************************************************************************
// @fn          as_write_register
// @brief       Write a byte to the pressure sensor
// @param       u8 device               Device address
//              u8 address              Register address
//              u8 data                 Data to write
// @return      u8
// *************************************************************************************************
u8 i2c_write_register(u8 device, u8 data)
{
    volatile u8 success;

    i2c_sda(I2C_SEND_START);               // Generate start condition

    i2c_write(device | I2C_WRITE);         // Send 7bit device address + r/w bit '0' -> write
    success = i2c_sda(I2C_CHECK_ACK);      // Check ACK from device
    if (!success) {
    	I2C_SCL_HI;
    	i2c_sda(I2C_SEND_STOP);
       return (0);
    }

    i2c_write(data);                       // Send 8bit data to register
    success = i2c_sda(I2C_CHECK_ACK);      // Check ACK from device
    // Slave does not send this ACK
    //if (!success) return (0);

    i2c_sda(I2C_SEND_STOP);                // Generate stop condition

    return (1);
}
Пример #7
0
/**
 * Write byte to I2C bus
 * uint8 data: to byte to be writen
 */
void ICACHE_FLASH_ATTR
i2c_writeByte(uint8 data)
{
    uint8 data_bit;
    sint8 i;

    os_delay_us(I2C_SLEEP_TIME);

    for (i = 7; i >= 0; i--) {
        data_bit = data >> i;
        i2c_sda(data_bit);
        os_delay_us(I2C_SLEEP_TIME);
        i2c_sck(1);
        os_delay_us(I2C_SLEEP_TIME);
        i2c_sck(0);
        os_delay_us(I2C_SLEEP_TIME);
    }
}
Пример #8
0
// Initialise the I2C communications
static void i2c_init(void)
{
	// Declare variables
	GPIO_InitTypeDef init;

	// SDA pin configuration
	init.GPIO_Pin = PIN_COMPASS_SDA;
	init.GPIO_Mode = GPIO_Mode_Out_OD;
	init.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(PORT_COMPASS_SDA, &init);
	
	// SCL pin configuration
	init.GPIO_Pin = PIN_COMPASS_SCL;
	init.GPIO_Mode = GPIO_Mode_Out_OD;
	init.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(PORT_COMPASS_SCL, &init);

	// Initialise the states of the SDA and SCL pins
	i2c_sda(1);
	i2c_scl(1);
}
Пример #9
0
// Perform one step of the I2C FSM
static void i2c_step(void)
{
	switch(g_i2c_state)
	{
		// Idle states
		case I2C_IDLE: // Idle bus with SCL and SDA high
			break;
		case I2C_READY: // Bus ready for activity with SCL and SDA low
			break;

		// Start states
		case I2C_START:
			i2c_init(); // Sets SDA and SCL to 1
			g_i2c_state = I2C_START_2;
			break;
		case I2C_START_2:
			i2c_sda(0); // SDA falling while SCL 1 => Start bit
			g_i2c_state = I2C_START_3;
			break;
		case I2C_START_3:
			i2c_scl(0); // Now SDA and SCL are both 0, ready for bus activity
			g_i2c_state = I2C_READY;
			break;
		
		// Write states
		case I2C_WRITE:
			i2c_sda(g_i2c_to_write & (1 << g_i2c_bit)); // SDA reflects data bit
			g_i2c_state = I2C_WRITE_2;
			break;
		case I2C_WRITE_2:
			i2c_scl(1); // Toggle SCL high
			g_i2c_state = I2C_WRITE_3;
			break;
		case I2C_WRITE_3:
			i2c_scl(0); // Toggle SCL low
			if(g_i2c_bit == 0)
				g_i2c_state = I2C_WRITE_ACK_1;
			else
			{
				g_i2c_bit--;
				g_i2c_state = I2C_WRITE;
			}
			break;
		case I2C_WRITE_ACK_1:
			i2c_sda(1); // Release SDA to allow the slave to ACK or NACK
			g_i2c_state = I2C_WRITE_ACK_2;
			break;
		case I2C_WRITE_ACK_2:
			i2c_scl(1); // Toggle SCL high
			g_i2c_state = I2C_WRITE_ACK_3;
			break;
		case I2C_WRITE_ACK_3:
			if(i2c_sda_read()) // Read the acknowledgement bit
				g_i2c_state = I2C_WRITE_GOT_NACK;
			else
				g_i2c_state = I2C_WRITE_GOT_ACK;
			i2c_scl(0); // Toggle SCL low
			break;
		case I2C_WRITE_GOT_ACK:
			break;
		case I2C_WRITE_GOT_NACK:
			break;
		
		// Read states
		case I2C_READ:
			i2c_sda(1); // Release SDA to allow the slave to transmit data
			g_i2c_state = I2C_READ_2;
			break;
		case I2C_READ_2:
			i2c_scl(1); // Toggle SCL high
			g_i2c_state = I2C_READ_3;
			break;
		case I2C_READ_3:
			if(i2c_sda_read())
				g_i2c_read |= (1 << g_i2c_bit);
			i2c_scl(0); // Toggle SCL low
			if(g_i2c_bit == 0)
				g_i2c_state = I2C_READ_4;
			else
			{
				g_i2c_bit--;
				g_i2c_state = I2C_READ_2;
			}
			break;
		case I2C_READ_4:
			i2c_sda(0); // Reassert control over SDA again and pull it low for an ACK
			g_i2c_state = I2C_READ_ACK_1;
			break;
		case I2C_READ_ACK_1:
			i2c_scl(1); // Toggle SCL high
			g_i2c_state = I2C_READ_ACK_2;
			break;
		case I2C_READ_ACK_2:
			i2c_scl(0); // Toggle SCL low
			g_i2c_state = I2C_READ_ENDED;
			break;
		case I2C_READ_ENDED:
			break;
		
		// Stop states
		case I2C_STOP:
			i2c_sda(0);
			g_i2c_state = I2C_STOP_2;
			break;
		case I2C_STOP_2:
			i2c_scl(1);
			g_i2c_state = I2C_STOP_3;
			break;
		case I2C_STOP_3:
			i2c_sda(1);
			g_i2c_state = I2C_IDLE;
			break;
		
		// Default state
		default:
			break;
	}
}