#include #include "ql_gpio.h" #include "ql_rtos.h" #include "ql_uart.h" #include "ql_application.h" #include "ql_type.h" //#include "global_types.h" #include "ql_func.h" #define NO_ERROR 0 #define STATUS_FAIL -1 #define SW_I2C_CLOCK_PERIOD_USEC 10 #define DELAY_USEC (SW_I2C_CLOCK_PERIOD_USEC / 2) /** * Initialize all hard- and software components that are needed to set the * SDA and SCL pins. */ void sw_i2c_init_pins(void) { // IMPLEMENT /*SDA*/ ql_gpio_init(GPIO_PIN_NO_50,PIN_DIRECTION_OUT,PIN_PULL_PU,PIN_LEVEL_HIGH); /*SCL*/ ql_gpio_init(GPIO_PIN_NO_49,PIN_DIRECTION_OUT,PIN_PULL_PU,PIN_LEVEL_HIGH); } /** * Release all resources initialized by sensirion_init_pins() */ void sw_i2c_release_pins(void) { // IMPLEMENT or leave empty if no resources need to be freed ql_gpio_deinit(GPIO_PIN_NO_49); ql_gpio_deinit(GPIO_PIN_NO_50); } /** * Configure the SDA pin as an input. With an external pull-up resistor the line * should be left floating, without external pull-up resistor, the input must be * configured to use the internal pull-up resistor. */ void sw_i2c_SDA_in(void) { // IMPLEMENT ql_gpio_deinit(GPIO_PIN_NO_50); ql_gpio_init(GPIO_PIN_NO_50,PIN_DIRECTION_IN,PIN_PULL_DISABLE,PIN_LEVEL_HIGH); } /** * Configure the SDA pin as an output and drive it low or set to logical false. */ void sw_i2c_SDA_out(void) { // IMPLEMENT ql_gpio_deinit(GPIO_PIN_NO_50); ql_gpio_init(GPIO_PIN_NO_50,PIN_DIRECTION_OUT,PIN_PULL_DISABLE,PIN_LEVEL_LOW); ql_gpio_set_level(GPIO_PIN_NO_50,PIN_LEVEL_LOW); } /** * Read the value of the SDA pin. * @returns 0 if the pin is low and 1 otherwise. */ uint8_t sw_i2c_SDA_read(void) { // IMPLEMENT PIN_LEVEL_E vv ; ql_gpio_get_level(GPIO_PIN_NO_50,&vv); return vv; } /** * Configure the SCL pin as an input. With an external pull-up resistor the line * should be left floating, without external pull-up resistor, the input must be * configured to use the internal pull-up resistor. */ void sw_i2c_SCL_in(void) { ql_gpio_deinit(GPIO_PIN_NO_49); ql_gpio_init(GPIO_PIN_NO_49,PIN_DIRECTION_IN,PIN_PULL_DISABLE,PIN_LEVEL_HIGH); } /** * Configure the SCL pin as an output and drive it low or set to logical false. */ void sw_i2c_SCL_out(void) { // IMPLEMENT ql_gpio_deinit(GPIO_PIN_NO_49); ql_gpio_init(GPIO_PIN_NO_49,PIN_DIRECTION_OUT,PIN_PULL_DISABLE,PIN_LEVEL_LOW); ql_gpio_set_level(GPIO_PIN_NO_49,PIN_LEVEL_LOW); } /** * Read the value of the SCL pin. * @returns 0 if the pin is low and 1 otherwise. */ uint8_t sw_i2c_SCL_read(void) { PIN_LEVEL_E vv ; ql_gpio_get_level(GPIO_PIN_NO_49,&vv); return vv; } /** * Sleep for a given number of microseconds. The function should delay the * execution approximately, but no less than, the given time. * * The precision needed depends on the desired i2c frequency, i.e. should be * exact to about half a clock cycle (defined in * `SENSIRION_I2C_CLOCK_PERIOD_USEC` in `sensirion_arch_config.h`). * * Example with 400kHz requires a precision of 1 / (2 * 400kHz) == 1.25usec. * * @param useconds the sleep time in microseconds */ void sw_i2c_sleep_usec(u32 useconds) { volatile uint_32 i; for(i=0;i= 0; i--) { sw_i2c_SCL_out(); if ((data >> i) & 0x01) sw_i2c_SDA_in(); else sw_i2c_SDA_out(); sw_i2c_sleep_usec(DELAY_USEC); sw_i2c_SCL_in(); sw_i2c_sleep_usec(DELAY_USEC); if (sw_i2c_wait_while_clock_stretching()) return STATUS_FAIL; } sw_i2c_SCL_out(); sw_i2c_SDA_in(); sw_i2c_sleep_usec(DELAY_USEC); sw_i2c_SCL_in(); if (sw_i2c_wait_while_clock_stretching()) return STATUS_FAIL; nack = (sw_i2c_SDA_read() != 0); sw_i2c_SCL_out(); return nack; } uint8_t sw_i2c_read_byte(uint8_t ack) { int8 i; uint8_t data = 0; sw_i2c_SDA_in(); for (i = 7; i >= 0; i--) { sw_i2c_sleep_usec(DELAY_USEC); sw_i2c_SCL_in(); if (sw_i2c_wait_while_clock_stretching()) return 0xFF; // return 0xFF on error data |= (sw_i2c_SDA_read() != 0) << i; sw_i2c_SCL_out(); } if (ack) sw_i2c_SDA_out(); else sw_i2c_SDA_in(); sw_i2c_sleep_usec(DELAY_USEC); sw_i2c_SCL_in(); sw_i2c_sleep_usec(DELAY_USEC); if (sw_i2c_wait_while_clock_stretching()) return 0xFF; // return 0xFF on error sw_i2c_SCL_out(); sw_i2c_SDA_in(); return data; } int8 sw_i2c_start(void) { sw_i2c_SCL_in(); if (sw_i2c_wait_while_clock_stretching()) return STATUS_FAIL; sw_i2c_SDA_out(); sw_i2c_sleep_usec(DELAY_USEC); sw_i2c_SCL_out(); sw_i2c_sleep_usec(DELAY_USEC); return NO_ERROR; } void sw_i2c_stop(void) { sw_i2c_SDA_out(); sw_i2c_sleep_usec(DELAY_USEC); sw_i2c_SCL_in(); sw_i2c_sleep_usec(DELAY_USEC); sw_i2c_SDA_in(); sw_i2c_sleep_usec(DELAY_USEC); } void sw_i2c_init(void) { sw_i2c_init_pins(); sw_i2c_SCL_in(); sw_i2c_SDA_in(); } void sw_i2c_release(void) { sw_i2c_SCL_in(); sw_i2c_SDA_in(); sw_i2c_release_pins(); }