gpio-based i2c for eCos
来源:互联网 发布:mysql数据库同步 日志 编辑:程序博客网 时间:2024/05/22 10:52
#include <cyg/io/io.h>
#include <cyg/infra/diag.h>
#include "cyg/kernel/kapi.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ADDR(x) (*((volatile unsigned long *)x))
#define API
#define SCL 11
#define SDA 12
#define XIP_FUNC
#define SCL_0 gpio_set_value(SCL, 0)
#define SCL_1 gpio_set_value(SCL, 1)
#define SDA_0 gpio_set_value(SDA, 0)
#define SDA_1 gpio_set_value(SDA, 1)
static void i2c_start(void);
static void i2c_stop(void);
static void wait_ack(void);
static void i2c_writebyte(unsigned char a);
static unsigned char i2c_readbyte(void);
static void SDAIN(void);
static void SDAOUT(void);
static void sendack(void);
static void sendnack(void);
static void i2c_writebit(unsigned char a);
void i2c_init(void);
void i2c_byte_write(unsigned char sadd, unsigned char reg, unsigned char val);
unsigned char i2c_byte_read(unsigned char sadd, unsigned char reg);
static int gpio_get_value(int gpio)
{
int reg_val;
if (gpio <= 31) {
// GPIO_DATA_0
reg_val = ADDR(0x10000620);
return ((reg_val >> gpio) & 0x1);
} else if (gpio >= 32 && gpio <= 63) {
// GPIO_DATA_1
reg_val = ADDR(0x10000624);
return ((reg_val >> (gpio - 32)) & 0x1);
} else {
// 64 ... 95
// GPIO_DATA_2
reg_val = ADDR(0x10000628);
return ((reg_val >> (gpio - 64)) & 0x1);
}
return 0;
}
static void gpio_set_value(int gpio, int value)
{
if (gpio <= 31) {
if (value > 0) {
// GPIO_DSET_0
ADDR(0x10000630) |= 1 << gpio;
} else {
// GPIO_DCLR_0
ADDR(0x10000640) |= 1 << gpio;
}
} else if (gpio >= 32 && gpio <= 63) {
if (value > 0) {
// GPIO_DSET_1
ADDR(0x10000634) |= 1 << (gpio - 32);
} else {
// GPIO_DCLR_1
ADDR(0x10000644) |= 1 << (gpio - 32);
}
} else {
// 64 ... 95
if (value > 0) {
// GPIO_DSET_2
ADDR(0x10000638) |= 1 << (gpio - 64);
} else {
// GPIO_DCLR_2
ADDR(0x10000648) |= 1 << (gpio - 64);
}
}
}
/**
* @brief realese the SDA
*/
static void SDAIN(void)
{
int gpio = SDA;
if (gpio <= 31) {
// GPIO_CTRL_0
ADDR(0x10000600) &= ~(1 << gpio);
} else if (gpio >= 32 && gpio <= 63) {
// GPIO_CTRL_1
ADDR(0x10000604) &= ~(1 << (gpio - 32));
} else {
// 64 ... 95
// GPIO_CTRL_2
ADDR(0x10000608) &= ~(1 << (gpio - 64));
}
}
/**
* @brief get the control of SDA
*/
static void SDAOUT(void)
{
int gpio = SDA;
if (gpio <= 31) {
// GPIO_CTRL_0
ADDR(0x10000600) |= 1 << gpio;
} else if (gpio >= 32 && gpio <= 63) {
// GPIO_CTRL_1
ADDR(0x10000604) |= 1 << (gpio - 32);
} else {
// 64 ... 95
// GPIO_CTRL_2
ADDR(0x10000608) |= 1 << (gpio - 64);
}
}
/*
* MT7628K CPU freq = 580/575 MHz, about 1.72 ns, 1 us = 581 clock
* ESP8266 CPU freq = 80 MHz, about 12.5 ns, 1 us = 80 clock
*
* 100 kHz = 100,000, about 10 us
* 400 kHz = 400,000, about 2.5 us
*
*/
static void delay5us(void)
{
unsigned short i;
i=50;
while(i--);
}
/**
* @brief send ack signal at i2c bus
*/
static void sendack(void)
{
i2c_writebit(0);
}
/**
* @brief send nack signal at i2c bus
*/
static void sendnack(void)
{
i2c_writebit(1);
}
/**
* @brief realese the SDA
*/
/**
* @brief send start signal at i2c bus
*/
static void i2c_start(void)
{
SDAOUT();
SDA_1;
delay5us();
SCL_1;
delay5us();
SDA_0;
delay5us();
SCL_0;
delay5us();
}
/**
* @brief send stop signal at i2c bus
*/
static void i2c_stop(void)
{
SDAOUT();
SDA_0;
delay5us();
SCL_1;
delay5us();
SDA_1;
delay5us();
SCL_0;
delay5us();
}
/**
* @brief recieve ack signal at i2c bus
*/
static void wait_ack(void)
{
int i;
SCL_0;
delay5us;
SDAIN();
delay5us;
SCL_1;
delay5us();
while(gpio_get_value(SDA)&&(i<0x2b0)) {
i++;
}
SCL_0;
delay5us();
}
/**
* @brief write a byte at i2c bus
*
* @param the data to write
*/
static void i2c_writebyte(unsigned char a)
{
unsigned short i;
SDAOUT();
for (i=0; i<8; i++) {
SCL_0;
delay5us();
if (a&0x80) {
SDA_1;
} else {
SDA_0;
}
a = a<<1;
delay5us();
SCL_1;
delay5us();
}
}
/**
* @brief write a bit at i2c bus
*
* @param the data to write
*/
static void i2c_writebit(unsigned char a)
{
SDAOUT();
SCL_0;
delay5us();
if (a==0) {
SDA_0;
} else {
SDA_1;
}
delay5us();
SCL_1;
delay5us();
SCL_0;
delay5us();
}
/**
* @brief read a byte at i2c bus
*
* @retval the data read
*/
static unsigned char i2c_readbyte()
{
unsigned char i, temp;
temp=0;
SDAIN();
SCL_0;
delay5us();
for (i=0; i<8; i++) {
SCL_1;
delay5us();
temp=(temp<<1)|gpio_get_value(SDA);
delay5us();
SCL_0;
delay5us();
}
return temp;
}
/**
* @brief initial the i2c related gpios
*/
API void i2c_init(void)
{
// pin mux
// Reference to "MT7628 PROGRAMMING GUIDE", p15 of System Control
// GPIO1_MODE 0x10000060
// GPIO2_MODE 0x10000064
gpio_set_value(SDA, 1);
gpio_set_value(SCL, 1);
}
/**
* @brief write data at certain address on MPU6050
*
* @param add the in-chip address of the data
* @param Achar the data to write
*/
API void i2c_byte_write(unsigned char sadd, unsigned char reg, unsigned char val)
{
i2c_start();
i2c_writebyte(sadd);
wait_ack();
i2c_writebyte(reg);
wait_ack();
i2c_writebyte(val);
wait_ack();
i2c_stop();
}
/**
* @brief read data from certain address of MPU6050
*
* @param add the in-chip address of the data
* @retval the data read
*/
API unsigned char i2c_byte_read(unsigned char sadd, unsigned char reg)
{
unsigned char temp;
i2c_start();
i2c_writebyte(sadd);
wait_ack();
delay5us();
i2c_writebyte(reg);
wait_ack();
i2c_start();
i2c_writebyte(sadd+1);
wait_ack();
temp=i2c_readbyte();
sendnack();
i2c_stop();
return temp;
}
#include <cyg/infra/diag.h>
#include "cyg/kernel/kapi.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ADDR(x) (*((volatile unsigned long *)x))
#define API
#define SCL 11
#define SDA 12
#define XIP_FUNC
#define SCL_0 gpio_set_value(SCL, 0)
#define SCL_1 gpio_set_value(SCL, 1)
#define SDA_0 gpio_set_value(SDA, 0)
#define SDA_1 gpio_set_value(SDA, 1)
static void i2c_start(void);
static void i2c_stop(void);
static void wait_ack(void);
static void i2c_writebyte(unsigned char a);
static unsigned char i2c_readbyte(void);
static void SDAIN(void);
static void SDAOUT(void);
static void sendack(void);
static void sendnack(void);
static void i2c_writebit(unsigned char a);
void i2c_init(void);
void i2c_byte_write(unsigned char sadd, unsigned char reg, unsigned char val);
unsigned char i2c_byte_read(unsigned char sadd, unsigned char reg);
static int gpio_get_value(int gpio)
{
int reg_val;
if (gpio <= 31) {
// GPIO_DATA_0
reg_val = ADDR(0x10000620);
return ((reg_val >> gpio) & 0x1);
} else if (gpio >= 32 && gpio <= 63) {
// GPIO_DATA_1
reg_val = ADDR(0x10000624);
return ((reg_val >> (gpio - 32)) & 0x1);
} else {
// 64 ... 95
// GPIO_DATA_2
reg_val = ADDR(0x10000628);
return ((reg_val >> (gpio - 64)) & 0x1);
}
return 0;
}
static void gpio_set_value(int gpio, int value)
{
if (gpio <= 31) {
if (value > 0) {
// GPIO_DSET_0
ADDR(0x10000630) |= 1 << gpio;
} else {
// GPIO_DCLR_0
ADDR(0x10000640) |= 1 << gpio;
}
} else if (gpio >= 32 && gpio <= 63) {
if (value > 0) {
// GPIO_DSET_1
ADDR(0x10000634) |= 1 << (gpio - 32);
} else {
// GPIO_DCLR_1
ADDR(0x10000644) |= 1 << (gpio - 32);
}
} else {
// 64 ... 95
if (value > 0) {
// GPIO_DSET_2
ADDR(0x10000638) |= 1 << (gpio - 64);
} else {
// GPIO_DCLR_2
ADDR(0x10000648) |= 1 << (gpio - 64);
}
}
}
/**
* @brief realese the SDA
*/
static void SDAIN(void)
{
int gpio = SDA;
if (gpio <= 31) {
// GPIO_CTRL_0
ADDR(0x10000600) &= ~(1 << gpio);
} else if (gpio >= 32 && gpio <= 63) {
// GPIO_CTRL_1
ADDR(0x10000604) &= ~(1 << (gpio - 32));
} else {
// 64 ... 95
// GPIO_CTRL_2
ADDR(0x10000608) &= ~(1 << (gpio - 64));
}
}
/**
* @brief get the control of SDA
*/
static void SDAOUT(void)
{
int gpio = SDA;
if (gpio <= 31) {
// GPIO_CTRL_0
ADDR(0x10000600) |= 1 << gpio;
} else if (gpio >= 32 && gpio <= 63) {
// GPIO_CTRL_1
ADDR(0x10000604) |= 1 << (gpio - 32);
} else {
// 64 ... 95
// GPIO_CTRL_2
ADDR(0x10000608) |= 1 << (gpio - 64);
}
}
/*
* MT7628K CPU freq = 580/575 MHz, about 1.72 ns, 1 us = 581 clock
* ESP8266 CPU freq = 80 MHz, about 12.5 ns, 1 us = 80 clock
*
* 100 kHz = 100,000, about 10 us
* 400 kHz = 400,000, about 2.5 us
*
*/
static void delay5us(void)
{
unsigned short i;
i=50;
while(i--);
}
/**
* @brief send ack signal at i2c bus
*/
static void sendack(void)
{
i2c_writebit(0);
}
/**
* @brief send nack signal at i2c bus
*/
static void sendnack(void)
{
i2c_writebit(1);
}
/**
* @brief realese the SDA
*/
/**
* @brief send start signal at i2c bus
*/
static void i2c_start(void)
{
SDAOUT();
SDA_1;
delay5us();
SCL_1;
delay5us();
SDA_0;
delay5us();
SCL_0;
delay5us();
}
/**
* @brief send stop signal at i2c bus
*/
static void i2c_stop(void)
{
SDAOUT();
SDA_0;
delay5us();
SCL_1;
delay5us();
SDA_1;
delay5us();
SCL_0;
delay5us();
}
/**
* @brief recieve ack signal at i2c bus
*/
static void wait_ack(void)
{
int i;
SCL_0;
delay5us;
SDAIN();
delay5us;
SCL_1;
delay5us();
while(gpio_get_value(SDA)&&(i<0x2b0)) {
i++;
}
SCL_0;
delay5us();
}
/**
* @brief write a byte at i2c bus
*
* @param the data to write
*/
static void i2c_writebyte(unsigned char a)
{
unsigned short i;
SDAOUT();
for (i=0; i<8; i++) {
SCL_0;
delay5us();
if (a&0x80) {
SDA_1;
} else {
SDA_0;
}
a = a<<1;
delay5us();
SCL_1;
delay5us();
}
}
/**
* @brief write a bit at i2c bus
*
* @param the data to write
*/
static void i2c_writebit(unsigned char a)
{
SDAOUT();
SCL_0;
delay5us();
if (a==0) {
SDA_0;
} else {
SDA_1;
}
delay5us();
SCL_1;
delay5us();
SCL_0;
delay5us();
}
/**
* @brief read a byte at i2c bus
*
* @retval the data read
*/
static unsigned char i2c_readbyte()
{
unsigned char i, temp;
temp=0;
SDAIN();
SCL_0;
delay5us();
for (i=0; i<8; i++) {
SCL_1;
delay5us();
temp=(temp<<1)|gpio_get_value(SDA);
delay5us();
SCL_0;
delay5us();
}
return temp;
}
/**
* @brief initial the i2c related gpios
*/
API void i2c_init(void)
{
// pin mux
// Reference to "MT7628 PROGRAMMING GUIDE", p15 of System Control
// GPIO1_MODE 0x10000060
// GPIO2_MODE 0x10000064
gpio_set_value(SDA, 1);
gpio_set_value(SCL, 1);
}
/**
* @brief write data at certain address on MPU6050
*
* @param add the in-chip address of the data
* @param Achar the data to write
*/
API void i2c_byte_write(unsigned char sadd, unsigned char reg, unsigned char val)
{
i2c_start();
i2c_writebyte(sadd);
wait_ack();
i2c_writebyte(reg);
wait_ack();
i2c_writebyte(val);
wait_ack();
i2c_stop();
}
/**
* @brief read data from certain address of MPU6050
*
* @param add the in-chip address of the data
* @retval the data read
*/
API unsigned char i2c_byte_read(unsigned char sadd, unsigned char reg)
{
unsigned char temp;
i2c_start();
i2c_writebyte(sadd);
wait_ack();
delay5us();
i2c_writebyte(reg);
wait_ack();
i2c_start();
i2c_writebyte(sadd+1);
wait_ack();
temp=i2c_readbyte();
sendnack();
i2c_stop();
return temp;
}
阅读全文
0 0
- gpio-based i2c for eCos
- gpio-based I2C
- stm32 gpio-based i2c
- eCos读写GPIO
- i2c - gpio
- i2c - gpio
- i2c, i2c-gpio
- GPIO模拟I2C / I2C注意事项
- CCI(gpio I2c) 与I2C
- i2c 驱动gpio模拟i2c
- GPIO软件模拟I2C
- linux gpio模拟i2c
- linux gpio模拟i2c
- GPIO模拟I2C-1
- GPIO软件模拟I2C
- GPIO模拟I2C操作
- GPIO模拟I2C操作
- gpio模拟I2C
- [Mybatis] TypeHandler的简单应用及源码分析
- 最全面的常用正则表达式大全
- 数仓相关文章索引(1)
- 中国的振兴之路·《看懂世界格局的第一本书·2》
- SpringBoot中logback日志保存到mongoDB
- gpio-based i2c for eCos
- SpringBoot-01SpringBoot配置FastJson
- redis的基本操作
- git回退版本
- 微信本地开发准备
- 链表(链式存储)的基本操作
- SublimeText在Mac系统上的安装方法
- OrmLite数据库
- MYBATIS 的parameter