⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c_sample.c

📁 oki67500系列arm工程例程源代码
💻 C
字号:
/**************************************************************************/
/*                                                                        */
/*     Copyright (C) 2003 Oki Electric Industry Co., LTD.                 */
/*                                                                        */
/*     System Name  :  ML675001 series                                    */
/*     Module Name  :  ML675001 i2c sample program                        */
/*     File   Name  :  i2c_sample.c                                       */
/*     Revision     :  01.00                                              */
/*     Date         :  2003/08/18                                         */
/*                                                                        */
/**************************************************************************/
#include   "ML675001.h"
#include   "common.h"
#include   "cache.h"

/* constants */
#define    I2C_LED_NORMAL       LED_NORMAL_END_PATTERN  /* OK pattern */
#define    I2C_END_PATTERN      0xFF  /* data-end pattern */
#define    I2C_UNIT_ID          0x01  /* I2C unit ID No.  */
#define    CONTROL_SIZE         16    /* control data size */
#define    CONTROL_ADR_HI       0x00  /* control address(HI) */
#define    CONTROL_ADR_LOW      0x80  /* control address(LOW) */
#define    BUFF_SIZE            CONTROL_SIZE+2

/* functions */
int     main(void);             /* main routine */
void    init_i2c(void);         /* initialize I2C */
void    i2c_cont(void);         /* I2C send/receive control */
void    i2c_send(UBYTE, UBYTE); /* I2C send process */
UBYTE   i2c_receive(UBYTE);     /* I2C receive process */
UBYTE   i2c_IR_chk(void);      /* I2C interrupt handler */
void    led_on(UHWORD);         /* LED on */

/* global variables */
volatile  unsigned  char  send_buff[BUFF_SIZE];  /* send buffer */
volatile  unsigned  char  receive_buff[CONTROL_SIZE];  /* receive buffer */


volatile  unsigned char sda_ctl_data = (0xA0 | (I2C_UNIT_ID << 1));

volatile  char led_pt;
volatile  char rec_size = CONTROL_SIZE;
volatile  int  I2C_unit_id = I2C_UNIT_ID;
volatile  int  last_flag;           /* =0:next data being,1:last data */
volatile  int  end_flag;            /* =0:no end,1:end */
volatile  int  send_receive_flg;    /* =0:skip,
                                       =1:data read,
                                       =2:data write */
/******************************************************************/
/*  Entry point                                                   */
/*  Function : main                                               */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  0                                           */
/******************************************************************/
int main(void)
{
    init_cache();  /* Initialize CACHE memory */
    cache_on(CACHE_BANK0);  /* Bank0 : Cache enable */

    init_i2c();                 /* initialize i2c */

    /***  initialize led  ***/
    init_led();                 /* set output mode */
    led_on(LED_START_PATTERN);  /* light led start pattern */

    while(end_flag == 0) {      /* loop1 */
        i2c_cont();             /* I2C send/receive control */
    }
    led_on(led_pt);             /* turn on lower square LED */

    return 0;
}

/******************************************************************/
/*  Initialize I2C                                                */
/*  Function : init_i2c                                           */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void init_i2c()
{
    UHWORD  i;
    UHWORD  gppo_data;
    UHWORD  set_data;

    /***********************************************************
        Setup of I2C
        I2CCLR_I2CMD	corresponds to Fast-mode(400kHz)
        I2CBC_I2CBC		corresponds to HCLK=33MHz,I2CMD=400kHz
        I2CIR_I2CIR		corresponds to interrupt clear
        I2CIMR_I2CMF	corresponds to interrupt mask off
    ***********************************************************/
    put_value(I2CCLR ,I2CCLR_CMD4);
    put_value(I2CBC ,I2CBC_400K60);
    put_value(I2CIMR ,I2CIMR_MF);

    set_hbit(GPCTL,GPCTL_I2C);    /* selection of a secondary function (I2C & PIOA)*/
    /* PIOA 5-7 bit is secondary function (A0,A1,A2) */
    gppo_data = get_hvalue(GPPMA);
    set_data = ((gppo_data & 0xFF1F) | 0x00E0);
    put_hvalue(GPPMA, set_data);
    gppo_data = get_hvalue(GPPOA);
    set_data = ((gppo_data & 0xFF1F) | (I2C_unit_id << 5));
    put_hvalue(GPPOA, set_data);

    /***********************************************************
        Clear end_flag & send_receive_flg
    ***********************************************************/
    end_flag = 0;
    send_receive_flg = 2;

    for(i=0;i<CONTROL_SIZE;i++) {
        send_buff[i+2] = i;
        receive_buff[i] = I2C_END_PATTERN;
    }

    /* data pattern setting (Random Read) */
    send_buff[0] = CONTROL_ADR_HI;   /* High Byte Address */
    send_buff[1] = CONTROL_ADR_LOW;  /* Low Byte Addoress */

    return;
}

/******************************************************************/
/*  I2C-Data send/receive control                                 */
/*  Function : i2c_cont                                           */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void     i2c_cont(void)
{
    int     i;
    UBYTE   read_data;
    UBYTE   rec_flags;

    switch(send_receive_flg) {
        case    1:          /* require data read */
            /***  adderse send  ***/
            put_value(I2CSAD,(sda_ctl_data | I2CSAD_RW_SND));
            for(i = 0;i < 2;i ++) {   /* loop2 */
                i2c_send(send_buff[i],(I2CCON_STCM | I2CCON_OC)); /* send request */
                if(led_pt != LED_NORMAL_END_PATTERN) {  /* send NG */
                    return;
                }
            }
            /***  data read  ***/
            put_value(I2CSAD,(sda_ctl_data | I2CSAD_RW_REC));
            rec_flags = I2CCON_EN;      /* send/write mode change */
            for(i=0;i<rec_size;i++) {   /* loop3 */
                if(rec_size == (i+1)) { /* next read data exists */
                    rec_flags += (I2CCON_STCM);
                }
                else {
                    rec_flags += (I2CCON_STCM | I2CCON_OC);
                }

                read_data = i2c_receive(rec_flags);     /* receive request */
                if(led_pt != LED_NORMAL_END_PATTERN) {  /* send NG */
                    return;
                }
                receive_buff[i] = read_data;    /* receive data save */
                rec_flags = 0;
            }
            break;
        case    2:          /* require data write */
            put_value(I2CSAD,(sda_ctl_data | I2CSAD_RW_SND));
            for(i = 0;i < BUFF_SIZE;i ++) {   /* loop4 */
                /* next data  */
                last_flag = (i == (BUFF_SIZE-1)) ? 1 : 0;
                if(last_flag ==0) {
                    i2c_send(send_buff[i],(I2CCON_STCM | I2CCON_OC)); /* send request */
                } else {
                    i2c_send(send_buff[i],I2CCON_STCM); /* send request */
                }
                if(led_pt != LED_NORMAL_END_PATTERN) {  /* send NG */
                    return;
                }
            }
            break;
        default:            /* others */
            break;
    }
    send_receive_flg = 0;

    return;
}

/******************************************************************/
/*  I2C data send                                                 */
/*  Function : i2c_send                                           */
/*      Parameters                                                */
/*          Input  :  send data                                   */
/*          Output :  Nothing                                     */
/******************************************************************/
void    i2c_send(UBYTE send_data, UBYTE set_data)
{

    put_value(I2CDR ,send_data);

    put_value(I2CCON, (set_data));        /* Set control register */

    if(i2c_IR_chk() != LED_NORMAL_END_PATTERN) {   /* send/receive check */
        put_value(I2CCON, I2CCON_STCM);
        send_receive_flg = 0;
    }

    return;
}

/******************************************************************/
/*  I2C data receive                                              */
/*  Function : i2c_receive                                        */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  receive data                                */
/******************************************************************/
UBYTE   i2c_receive(UBYTE oc_flag)
{
    UBYTE   read_data;

    put_value(I2CCON, oc_flag);    /* Set control register */

    if(i2c_IR_chk() != LED_NORMAL_END_PATTERN) {   /* send/receive check */
        put_value(I2CCON, I2CCON_STCM);
        send_receive_flg = 0;
    }

    /* waite receive complete */
    read_data = get_value(I2CDR);       /* Read receive data */

    return(read_data);
}

/********************************************************************/
/*  I2C Interruption check                                          */
/*  Function : i2c_IR_chk                                           */
/*        Parameters                                                */
/*            Input  :  Nothing                                     */
/*            Output :  Nothing                                     */
/********************************************************************/
UBYTE i2c_IR_chk()
{
    unsigned  char  chk_data;

    while((get_value(I2CIR) & I2CIR_IR) != I2CIR_IR)
        ;
    led_pt = LED_NORMAL_END_PATTERN;
    chk_data = get_value(I2CSR);    /* read I2CSR register */
    if((chk_data & I2CSR_AAK) == I2CSR_AAK) {   /* address ACK no receive ? */
        led_pt = LED_A;
    }
    else if((chk_data & I2CSR_DAK) == I2CSR_DAK) {  /* data ACK no receive ? */
        led_pt = LED_d;
    }
    put_value(I2CIR,I2CIR_IR);      /* Interruption clean */
    led_on(led_pt);                 /* turn on lower square LED */

    return(led_pt);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -