📄 i2c_sample.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 + -