pdk7105的I2C配置

pdk7105的I2C配置
stm23-0047版本中增加了I2C的配置
<<include/configs/pdk7105.h>>
已知:
PIO3[4]  SCL
PIO3[5]  SDA
根据board/st/pdk7105.c代码中
static void configI2c(void)
{
 /*
  * The I2C busses are routed as follows:
  *
  * Bus   SCL    SDA
  * ---   ---    ---
  *  A PIO2[2]  PIO2[3]
  *  B PIO2[5]  PIO2[6]  Used only for SPI
  *  C PIO3[4]  PIO3[5]
  *  D PIO3[6]  PIO3[7]
  */
#if defined(CONFIG_I2C_BUS_A)   /* Use I2C Bus "A" */
 SET_PIO_PIN(PIO_PORT(2),2,STPIO_BIDIR); /* I2C_SCLA */
 SET_PIO_PIN(PIO_PORT(2),3,STPIO_BIDIR); /* I2C_SDAA */
#elif defined(CONFIG_I2C_BUS_C)   /* Use I2C Bus "C" */
 SET_PIO_PIN(PIO_PORT(3),4,STPIO_BIDIR); /* I2C_SCLC */
 SET_PIO_PIN(PIO_PORT(3),5,STPIO_BIDIR); /* I2C_SDAC */
#elif defined(CONFIG_I2C_BUS_D)   /* Use I2C Bus "D" */
 SET_PIO_PIN(PIO_PORT(3),6,STPIO_BIDIR); /* I2C_SCLD */
 SET_PIO_PIN(PIO_PORT(3),7,STPIO_BIDIR); /* I2C_SDAD */
#else
#error Unknown I2C Bus!
#endif
}
选用C总线,故定义CONFIG_I2C_BUS_C
SET_PIO_PIN(PIO_PORT(3),4,STPIO_BIDIR); /* I2C_SCLC */
SET_PIO_PIN(PIO_PORT(3),5,STPIO_BIDIR); /* I2C_SDAC */

#define SET_PIO_PIN(PIO_ADDR, PIN, DIR)     /
do {         /
 writel( PIN_C0((PIN),(DIR)),     /
  (PIO_ADDR)+STPIO_PC0_OFFSET+STPIO_SET_OFFSET);  /
 writel( PIN_C1((PIN),(DIR)),     /
  (PIO_ADDR)+STPIO_PC1_OFFSET+STPIO_SET_OFFSET);  /
 writel( PIN_C2((PIN),(DIR)),     /
  (PIO_ADDR)+STPIO_PC2_OFFSET+STPIO_SET_OFFSET);  /
 writel( CLEAR_PIN_C0((PIN),(DIR)),    /
  (PIO_ADDR)+STPIO_PC0_OFFSET+STPIO_CLEAR_OFFSET); /
 writel( CLEAR_PIN_C1((PIN),(DIR)),    /
  (PIO_ADDR)+STPIO_PC1_OFFSET+STPIO_CLEAR_OFFSET); /
 writel( CLEAR_PIN_C2((PIN),(DIR)),    /
  (PIO_ADDR)+STPIO_PC2_OFFSET+STPIO_CLEAR_OFFSET); /
} while (0)

#define PIN_C0(PIN, DIR) PIN_CX((PIN), (DIR), 0x01)
#define PIN_C1(PIN, DIR) PIN_CX((PIN), (DIR), 0x02)
#define PIN_C2(PIN, DIR) PIN_CX((PIN), (DIR), 0x04)
#define PIN_CX(PIN, DIR, X) (((PIN)==STPIO_NO_PIN) ? 0 : (((DIR) & (X))!=0) << (PIN))//将PIN口的位0,1,2置1
#define writel(b,addr) ((*(volatile u32 *) (addr)) = (b))//将b写入地址addr(long:32位)

SET_PIO_PIN(PIO_PORT(3),4,STPIO_BIDIR); /* I2C_SCLC */将ST40_PIO3_REGS_BASE(0xfd023000)的第4位置1
SET_PIO_PIN(PIO_PORT(3),5,STPIO_BIDIR); /* I2C_SDAC */将ST40_PIO3_REGS_BASE(0xfd023000)的第5位置1

SET_PIO_PIN(PIO_PORT(3),4,STPIO_BIDIR);//等价于*(0xfd023000)|=(1<<4)

 

extern void stx7105_i2c_scl(const int val)
{
#if defined(CONFIG_I2C_BUS_A)   /* Use I2C Bus "A" */
 STPIO_SET_PIN(PIO_PORT(2), 2, (val) ? 1 : 0);
#elif defined(CONFIG_I2C_BUS_C)   /* Use I2C Bus "C" */
 STPIO_SET_PIN(PIO_PORT(3), 4, (val) ? 1 : 0);
#elif defined(CONFIG_I2C_BUS_D)   /* Use I2C Bus "D" */
 STPIO_SET_PIN(PIO_PORT(3), 6, (val) ? 1 : 0);
#endif
}
stx7105_i2c_scl(const int val)设置PIO3[4]的值为val[0:1]

extern void stx7105_i2c_sda(const int val)
{
#if defined(CONFIG_I2C_BUS_A)   /* Use I2C Bus "A" */
 STPIO_SET_PIN(PIO_PORT(2), 3, (val) ? 1 : 0);
#elif defined(CONFIG_I2C_BUS_C)   /* Use I2C Bus "C" */
 STPIO_SET_PIN(PIO_PORT(3), 5, (val) ? 1 : 0);
#elif defined(CONFIG_I2C_BUS_D)   /* Use I2C Bus "D" */
 STPIO_SET_PIN(PIO_PORT(3), 7, (val) ? 1 : 0);
#endif
}
stx7105_i2c_sda(const int val)设置PIO3[5]值为val

extern int stx7105_i2c_read(void)
{
#if defined(CONFIG_I2C_BUS_A)   /* Use I2C Bus "A" */
 return STPIO_GET_PIN(PIO_PORT(2), 3);
#elif defined(CONFIG_I2C_BUS_C)   /* Use I2C Bus "C" */
 return STPIO_GET_PIN(PIO_PORT(3), 5);
#elif defined(CONFIG_I2C_BUS_D)   /* Use I2C Bus "D" */
 return STPIO_GET_PIN(PIO_PORT(3), 7);
#endif
}
stx7105_i2c_read(void)获取PIO3[5]的值STPIO_GET_PIN(PIO_PORT(3),5)


/*----------------------------------------------------------------------
 * I2C configuration
 */

#define CONFIG_CMD_I2C    /* do we want I2C support ? */

#if defined(CONFIG_CMD_I2C)
# define CONFIG_I2C_BUS_C   /* Use I2C Bus "C" */
# define CONFIG_I2C_CMD_TREE  /* use a "i2c" root command */
# define CFG_I2C_SLAVE  0x7F /* I2C slave address */ /* QQQ - TO CHECK */
# define CONFIG_SOFT_I2C   /* I2C with S/W bit-banging */
# undef  CONFIG_HARD_I2C   /* I2C withOUT hardware support */
# define I2C_ACTIVE   /* open-drain, nothing to do */
# define I2C_TRISTATE   /* open-drain, nothing to do */
# define I2C_SCL(val)  do { stx7105_i2c_scl((val)); } while (0)
# define I2C_SDA(val)  do { stx7105_i2c_sda((val)); } while (0)
# define I2C_READ   stx7105_i2c_read()

 /*
  * The "BOGOS" for NDELAY() may be calibrated using the
  * following code fragment, and measuring (using an oscilloscope)
  * the frequency of the I2C SCL pin, and adjusting
  * NDELAY_BOGOS, until the SCL is approximately 100 kHz.
  * (100kHz has a period of 5us + 5us).
  *
  * printf("just toggling I2C SCL (100kHz frequency) .../n");
  * while (1)
  * {
  *  I2C_SCL(1); NDELAY(5000);
  *  I2C_SCL(0); NDELAY(5000);
  * }
  */
# define NDELAY_BOGOS  22 /* Empirical measurement for 1ns */
# define NDELAY(ns)      /
  do {       /
   const unsigned n_bogo = NDELAY_BOGOS;  /
   const unsigned n_ticks =    /
    ((ns)<n_bogo) ? 1u : (ns)/n_bogo; /
   volatile unsigned n_count;   /
   for(n_count=0; n_count<n_ticks; n_count++) /
    ; /* do nothing */  /
  } while(0)

 /*
  * Note there are 4 * I2C_DELAY per I2C clock cycle
  * So, 400 kHz requires an I2C delay of 625 ns.
  * However, this calculation only works if the S/W
  * overhead in I2C bit-banging is negligible - which it is not!
  * So, in practice, either I2C_DELAY or CFG_I2C_SPEED will be lower.
  * The higher the clock frequency, the greater the difference.
  * Empirical measurement/adjustment is recommended.
  */
# define CFG_I2C_SPEED 400000    /* I2C speed (Hz) */
# define I2C_DELAY do { NDELAY(625); } while (0) /* 625 ns */
#endif /* CONFIG_CMD_I2C */


#endif /* __CONFIG_H */

I2C_SCL(1)   SCL置高
I2C_SDA(val)  SDA
NDELAY(ns)
# define I2C_READ   stx7105_i2c_read() STPIO_GET_PIN(PIO_PORT(3), 5);


 I2C总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。
  开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
  结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
  应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。
CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。
若未收到应答信号,由判断为受控单元出现故障。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值