jlass 发表于 2013-3-7 10:31 
SMI时序不对居多,特别是读写翻转的时候
- void rtl_smi_delay(unsigned char t)
- {
- while(t--)
- {
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- }
- }
- void rtl_smi_start()
- {
- SCK=0;
- SDA=1;
- rtl_smi_delay(5);
- /* CLK 1: 0 -> 1, 1 -> 0 */
- SCK=1;
- rtl_smi_delay(5);
- SCK=0;
- rtl_smi_delay(5);
- /* CLK 2: */
- SCK=1;
- rtl_smi_delay(5);
- SDA=0;
- rtl_smi_delay(5);
- SCK=0;
- //rtl_smi_delay(5);
- //SDA=1;
- }
- void rtl_smi_stop()
- {
- rtl_smi_delay(5);
- SDA=0;
- SCK=0;
- rtl_smi_delay(5);
- SCK=1;
- rtl_smi_delay(5);
- SDA=1;
- rtl_smi_delay(5);
- SDA=0;
- /* add a click */
- rtl_smi_delay(5);
- SDA=1;
- SCK=0;
- rtl_smi_delay(5);
- SCK=1;
- rtl_smi_delay(5);
- SCK=0;
- }
- void rtl_smi_write_bits(unsigned char wtData, unsigned char len)
- {
- for (; len > 0; len--) {
- SCK=0;
- rtl_smi_delay(3);
- /* prepare data */
- SDA=!!(wtData & ( 1 << (len - 1)));
- rtl_smi_delay(2);
- /* clocking */
- SCK=1;
- rtl_smi_delay(5);
- SCK=0;
- }
- }
- void rtl_smi_read_bits(unsigned char len, unsigned char *rddata)
- {
- //gpio_direction_input(sda); SDA pin 设置为输入模式 P3M1=0;
- P0M1=0x40;//高阻输入模式
- P0M0=0x80;
- SDA=1;
- for (*rddata = 0; len > 0; len--) {
- unsigned char u;
- SCK=0;
- rtl_smi_delay(5);
- /* clocking */
- SCK=1;
- rtl_smi_delay(6);
- u = SDA;
- SCK=0;
- *rddata |= (u << (len - 1));
- }
- //gpio_direction_input(sda); SDA pin 设置为输出模式 P3M1=1;用推挽模式
- P0M1=0x00;//推挽输出模式
- P0M0=0xC0;
- }
- unsigned char rtl_smi_wait_for_ack()
- {
- unsigned char retry_cnt;
- retry_cnt = 0;
- do {
- unsigned char ack;
- rtl_smi_read_bits(1, &ack);
- if (ack == 0)
- break;
- if (++retry_cnt >15)
- return 1;
- } while (1);
- return 0;
- }
- unsigned char rtl_smi_write_byte(unsigned char wtdata)
- {
- rtl_smi_write_bits(wtdata, 8);
- return rtl_smi_wait_for_ack();
- }
- unsigned char rtl_smi_write_byte1(unsigned char wtdata)
- {
- rtl_smi_write_bits(wtdata, 8);
- return 0;
- }
- unsigned char rtl_smi_read_byte0(unsigned char *rddata)//读之后应答结束
- {
- unsigned char t;
- /* read data */
- rtl_smi_read_bits(8, &t);
- *rddata = (t & 0xff);
- /* send an ACK */
- rtl_smi_write_bits(0x00,1);
- return 0;
- }
- unsigned char rtl_smi_read_byte1(unsigned char *rddata)//读之后非应答结束
- {
- unsigned char t;
- /* read data */
- rtl_smi_read_bits(8, &t);
- *rddata = (t & 0xff);
- /* send an ACK */
- rtl_smi_write_bits(0x01,1);
- return 0;
- }
- unsigned char rtl_smi_read_reg(unsigned int addr, unsigned int *rddata)
- {
- unsigned char lo = 0;
- unsigned char hi = 0;
- unsigned char ret;
- i2dutype retdata,addrdata;
- addrdata.intdata=addr;
- rtl_smi_start();
- /* send READ command */
- ret = rtl_smi_write_byte(0x0B << 4 | 0x04 << 1 | 0x01);
- LED1=0;
- if (ret)
- goto out;
- LED2=0;
- /* set ADDR[7:0] */
- ret = rtl_smi_write_byte(addrdata.dudata.Ldata);
- if (ret)
- goto out;
- /* set ADDR[15:8] */
- ret = rtl_smi_write_byte(addrdata.dudata.Hdata);
- if (ret)
- goto out;
- //rtl_smi_write_bits(0x00,1);
- /* read DATA[7:0] */
- rtl_smi_read_byte0(&lo);
- /* read DATA[15:8] */
- rtl_smi_read_byte1(&hi);
- retdata.dudata.Hdata=hi;
- retdata.dudata.Ldata=lo;
- *rddata=retdata.intdata;
- //*rddata = ((unsigned int ) lo) | (((unsigned int ) hi) << 8);
- ret = 0;
- out:
- rtl_smi_stop();
- return ret;
- }
- unsigned char rtl_smi_write_reg(unsigned int addr, unsigned int wtdata)
- {
- int ret;
- rtl_smi_start();
- /* send WRITE command */
- ret = rtl_smi_write_byte(0x0B << 4 | 0x04 << 1 | 0x00);
- if (ret)
- goto out;
-
- /* set ADDR[7:0] */
- ret = rtl_smi_write_byte(addr & 0xff);
- if (ret)
- goto out;
-
- /* set ADDR[15:8] */
- ret = rtl_smi_write_byte(addr >> 8);
- if (ret)
- goto out;
-
- /* write DATA[7:0] */
- ret = rtl_smi_write_byte(wtdata & 0xff);
- if (ret)
- goto out;
-
- /* write DATA[15:8] */
- ret = rtl_smi_write_byte(wtdata >> 8);
- if (ret)
- goto out;
- LED5=0;
- ret = 0;
- out:
- rtl_smi_stop();
- return ret;
- }
|