/*
* BOOTLOADER GPIO I2C SAMPLE CODE.
*/
#include <string.h>
#include <stdlib.h>
#include <debug.h>
#include <stdarg.h>
#include <errno.h>
#include <sys/types.h>
#include "gpio.h"
#include "timer.h"
#include "typedefs.h"
#define I2C_DELAY 5
#define I2C_M_WD 0
#define I2C_M_RD 1
static uint32_t RM_GPIO_SDA;
static uint32_t RM_GPIO_SCL;
#define RM_GPIO_SDA_PIN_SET_HIGH gpio_set_pin_value(RM_GPIO_SDA,1)
#define RM_GPIO_SDA_PIN_SET_LOW gpio_set_pin_value(RM_GPIO_SDA,0)
#define RM_GPIO_SCL_PIN_SET_HIGH gpio_set_pin_value(RM_GPIO_SCL,1)
#define RM_GPIO_SCL_PIN_SET_LOW gpio_set_pin_value(RM_GPIO_SCL,0)
#define RM_GPIO_SDA_PIN_SET_INPUT gpio_set_direction(RM_GPIO_SDA,0)
#define RM_GPIO_SDA_PIN_SET_OUTPUT gpio_set_direction(RM_GPIO_SDA,1)
#define GET_RM_GPIO_SDA_PIN_STATE gpio_get_pin_value(RM_GPIO_SDA)
int rm_gpio_i2c_init(uint32_t pin_sda,uint32_t pin_scl)
{
dprintf("rm_gpio_i2c_init, pin_sda:%d, pin_scl:%d\n",pin_sda,pin_scl);
//if((pin_sda < 0) || (pin_scl < 0))
// return -1;
RM_GPIO_SDA = pin_sda;
RM_GPIO_SCL = pin_scl;
atc_gpio_mode_set(RM_GPIO_SDA, 0); //GPIO0 as gpio function
atc_gpio_mode_set(RM_GPIO_SCL, 0); //GPIO0 as gpio function
atc_gpio_set_direction(RM_GPIO_SDA, 1); //RM_GPIO_0 as output
atc_gpio_set_direction(RM_GPIO_SCL, 1); //RM_GPIO_0 as output
return 0;
}
int rm_gpio_i2c_delay(uint32_t time)
{
if(time <= 0){
return -1;
}
delay_us(time);
return 0;
}
int rm_gpio_i2c_start(void)
{
/*set sda pin to high*/
RM_GPIO_SDA_PIN_SET_HIGH;
delay_us(I2C_DELAY);
/*set scl pin to high*/
RM_GPIO_SCL_PIN_SET_HIGH;
delay_us(I2C_DELAY);
/*set sda pin to low*/
RM_GPIO_SDA_PIN_SET_LOW;
delay_us(I2C_DELAY);
/*set scl pin to low*/
RM_GPIO_SCL_PIN_SET_LOW;
delay_us(I2C_DELAY);
return 0;
}
int rm_gpio_i2c_stop(void)
{
/*set sda pin to low*/
RM_GPIO_SDA_PIN_SET_LOW;
delay_us(I2C_DELAY);
/*set scl pin to high*/
RM_GPIO_SCL_PIN_SET_HIGH;
delay_us(I2C_DELAY);
/*set sda pin to high*/
RM_GPIO_SDA_PIN_SET_HIGH;
delay_us(I2C_DELAY);
return 0;
}
int rm_gpio_i2c_write_ask(uint8_t flag)
{
if(flag){
/*set sda pin to high*/
RM_GPIO_SDA_PIN_SET_HIGH;
}else{
/*set sda pin to low*/
RM_GPIO_SDA_PIN_SET_LOW;
}
delay_us(I2C_DELAY);
/*toggle clock*/
RM_GPIO_SCL_PIN_SET_HIGH;
delay_us(I2C_DELAY);
RM_GPIO_SCL_PIN_SET_LOW;
delay_us(I2C_DELAY);
/*set sda pin to high*/
RM_GPIO_SDA_PIN_SET_HIGH;
delay_us(I2C_DELAY);
return 0;
}
uint8_t rm_gpio_i2c_read_ask(void)
{
uint8_t ret;
RM_GPIO_SDA_PIN_SET_INPUT;
delay_us(I2C_DELAY);
/*read*/
if(!GET_RM_GPIO_SDA_PIN_STATE){
ret = 1;
}else{
ret = 0;
delay_us(I2C_DELAY);
if(!GET_RM_GPIO_SDA_PIN_STATE){
ret = 1;
}else{
ret = 0;
}
}
/*set scl pin to high*/
RM_GPIO_SCL_PIN_SET_HIGH;
delay_us(I2C_DELAY);
/*set scl pin to low*/
RM_GPIO_SCL_PIN_SET_LOW;
delay_us(I2C_DELAY);
RM_GPIO_SDA_PIN_SET_OUTPUT;
RM_GPIO_SDA_PIN_SET_LOW;
return ret;
}
uint8_t rm_gpio_i2c_read_byte(void)
{
uint8_t i;
uint8_t ret = 0;
RM_GPIO_SDA_PIN_SET_INPUT;
/*loop*/
for(i = 0; i < 8; i ++){
delay_us(I2C_DELAY);
/*set scl pin to high*/
RM_GPIO_SCL_PIN_SET_HIGH;
delay_us(I2C_DELAY);
/*read SDA*/
ret = ret << 1;
if(GET_RM_GPIO_SDA_PIN_STATE){
ret |= 1;
}
delay_us(I2C_DELAY);
/*set scl pin to low*/
RM_GPIO_SCL_PIN_SET_LOW;
if(i == 7){
RM_GPIO_SDA_PIN_SET_OUTPUT;
}
delay_us(I2C_DELAY);
}
return ret;
}
uint8_t rm_gpio_i2c_write_byte(uint8_t data)
{
uint8_t i;
for(i = 0; i< 8; i++){
if(data & 0x80){
/*set sda pin to high*/
RM_GPIO_SDA_PIN_SET_HIGH;
}else{
/*set sda pin to high*/
RM_GPIO_SDA_PIN_SET_LOW;
}
delay_us(I2C_DELAY);
data <<= 1;
/*set scl pin to high*/
RM_GPIO_SCL_PIN_SET_HIGH;
delay_us(I2C_DELAY);
/*set scl pin to low*/
RM_GPIO_SCL_PIN_SET_LOW;
}
return rm_gpio_i2c_read_ask();
}
int rm_gpio_i2c_read_bytes(uint8_t addr, uint8_t *buf, uint8_t length)
{
int i;
rm_gpio_i2c_start();
rm_gpio_i2c_write_byte(addr | I2C_M_WD);
rm_gpio_i2c_write_byte(buf[0]);
rm_gpio_i2c_stop();
length --;
rm_gpio_i2c_start();
rm_gpio_i2c_write_byte(addr | I2C_M_RD);
for(i = 1; i <= (int)length; i++){
buf[i]=rm_gpio_i2c_read_byte();
if(i == ((int)length -1)){
rm_gpio_i2c_write_ask(1);
}else{
rm_gpio_i2c_write_ask(0);
}
}
rm_gpio_i2c_stop();
return 0;
}
int rm_gpio_i2c_write_bytes(uint8_t addr, uint8_t *buf, uint8_t length)
{
int i;
rm_gpio_i2c_start();
rm_gpio_i2c_write_byte(addr);
for(i=0; i < (int)length; i++){
rm_gpio_i2c_write_byte(buf[i]);
}
rm_gpio_i2c_stop();
return 0;
}
int rm_gpio_i2c_write_table(uint8_t slave_addr, uint8_t table[][3], uint8_t length)
{
int i = 0;
uint8_t buf[2] = {0,0};
dprintf("rm_gpio_i2c_write_table, slave_addr:0x%x, length:%d\n",slave_addr,length);
for(i=0; i < length; i++){
buf[0]=table[i][0];
buf[1]=table[i][1];
rm_gpio_i2c_write_bytes(slave_addr,buf,2);
if(table[i][2] > 0){
delay_us(table[i][2]);
}
}
return 0;
}