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

📄 i2c.c.svn-base

📁 Spearhead2000 的 USB驱动程序
💻 SVN-BASE
字号:
/********************************************************************************                                                                           ****  Copyright (c) 1999 ST Microelectronics                                   ****  All rights reserved                                                      ****                                                                           ****      Filename  :  i2c.c                                                   ****      Author    :  Nicola Imperato                                         ****      Revision  :  1.0                                                     ****                                                                           ****                                                                           ****                                                                           *********************************************************************************/#include "i2c.h"#include "vic_pl190.h"#include "gpio.h"#include "uart.h"#include "gp_timers.h"//#include <stdlib.h>//static volatile unsigned int i2c_done = 0;//volatile unsigned int i2c_count = 0;void i2c_Start( void ){    int i;  	I2CCntl->CR |= CR_START;	while (!((I2CCntl->SR1 & SR1_SB)==SR1_SB));	for (i=0; i< 20; i++)                                /*to wider SCL low after Start Bit */	{		if (!((I2CCntl->SR1 & SR1_BTF)==SR1_BTF)) ;	}	}void i2c_Stop( void ){        int i;        for (i=0; i< 50; i++)                                 /*to wider SCL low after ACK was inserted the loop before DR write */	{	   if (!((I2CCntl->SR1 & SR1_BTF)==SR1_BTF)) ;	}	I2CCntl->CR |= CR_STOP;	}void i2c_Ack( void ){  	I2CCntl->CR |= CR_ACK;	}void i2c_nAck( void ){  	I2CCntl->CR &= ~CR_ACK;	}void i2c_SetAddr (char i2c_addr){		i2c_Start();	I2CCntl->DR = (unsigned int)i2c_addr;}void i2c_TxData (char i2c_data){	int i;	unsigned int sr2; 		do {		if (I2CCntl->SR2) {		sr2 = I2CCntl->SR2; 		 while (1);		 }		I2CCntl->CR |= CR_PE;	} while (!((I2CCntl->SR1 & SR1_BTF)==SR1_BTF)) ;	for (i=0; i< 20; i++)                                /*to wider SCL low after ACK was inserted the loop before DR write */	{		if (!((I2CCntl->SR1 & SR1_BTF)==SR1_BTF)) ;	}	  	I2CCntl->DR = (unsigned int)i2c_data;}char i2c_RxData (char last){		int i;			do {		if (I2CCntl->SR2)  while (1);		I2CCntl->CR |= CR_PE;	} while (!((I2CCntl->SR1 & SR1_BTF)==SR1_BTF)) ;        		for (i=0; i< 20; i++)                                 /*to wider SCL low after ACK was inserted the loop before DR write */	{		if (!((I2CCntl->SR1 & SR1_BTF)==SR1_BTF)) ;	}		if (last)	{	      for (i=0; i< 20; i++)                                 /*to wider SCL low after ACK was inserted the loop before DR write */	      {		if (!((I2CCntl->SR1 & SR1_BTF)==SR1_BTF)) ;	      }	      i2c_Stop();         }	 return (char)I2CCntl->DR;}void i2c_tx (char *buff_addr, char mem_addr, char nb , char slave_addr){	        i2c_SetAddr(slave_addr);    //slave selection	i2c_TxData(mem_addr);       // memory location selection	for (;nb>0; nb--)		i2c_TxData(*(buff_addr + nb -1));					i2c_Stop();}void i2c_rx (char *buff_addr, char mem_addr, char nb , char slave_addr){	i2c_SetAddr(slave_addr);    //slave selection	i2c_TxData(mem_addr);       // memory location selection	i2c_SetAddr(slave_addr | 0x01);    //slave selection in read mode  -- this sequence is set by 24cxx eeprom sequencial read protocol	do	{		nb--;		if (nb==0)		{			i2c_nAck();   //no Ack after last recepion			*(buff_addr + nb) = i2c_RxData(1); //Last data read		}		else		{			*(buff_addr + nb) = i2c_RxData(0);		  		}	} while (nb > 0);	i2c_Ack();   //peche' dopo il last reception faccio nACK e quindi il bit ACK di CR  e' resettato , e quindi per le future receprion devo risettarlo	}voidi2cInterrupt(unsigned int vector)           //ISR{   /*   if (vector & ITC_I2C_int)      {    I2CCntl->CR &= ~CR_ITE;  // disable interrupt        i2c_done = 1; 	i2c_count++;        // GPIO_1 signal        gpioWrite(1, 0);        gpioWrite(1, 1);    }*/    }voidi2cInit(void){	intctlIntRegister(ITC_I2C_int, i2cInterrupt, 0);        I2CCntl->CR  = 0x00;                            //reset CR	//I2CCntl->CCR = 0x3c;                            //clock = 400khz @ APB clk = 96 Mhz        I2CCntl->CCR = 0xff;                            //clock = 400khz @ APB clk = 96 Mhz        I2CCntl->CR &= ~CR_ITE;                         // disable interrupt	I2CCntl->CR  |= (CR_PE | CR_ACK);               //set PE and ACK        I2CCntl->CR  |= (CR_PE | CR_ACK);               //set PE and ACK     }voidi2cTest(void){  	char eeprom_wdata[16];	char eeprom_rdata[16];	char j, error;	int i;	char in_buf,data_write,address,schedule;			schedule='r';	while ((schedule == 'r') && (schedule != 's'))	{		UART_tx_vec("O -> Full Test : write and read all 2k byte 24C02W eeprom",strlen("O -> Full Test : write and read all 2k byte 24C02W eeprom"));			UART_tx_vec("1 -> Write single location",strlen("1 -> Write single location"));			UART_tx_vec("2 -> Read  single location",strlen("2 -> Read  single location"));			while (!(UART_putc(13)));	while (!(UART_putc(10)));	while (!(UART_getc(&in_buf)));        			switch (in_buf) 	{	case '0' :		   for (j=0; j< 128; j++)  		   {		       for (i=0; i< 16; i++)		   	  {		   	   eeprom_wdata[i]=(16*j)+i;		   	   }		   	   i2c_tx(eeprom_wdata,0 + (16 *j),16,0xa0);		   	   /* Wait some mSec to write in eeprom*/	                   gptSetTimer(TIMER1, GPT_ENAB | GPT_SINGLE_SHOT | GPT_FREQ_259_766Khz, 1386);		   	   while (!(gptGetTimerVal(1) == 1000));                   }		  		   		   error = 0;		   for (j=0; j< 128; j++)		   {	   		       i2c_rx(eeprom_rdata,0 + (j*16),16,0xa0);		       for (i=0; i< 16; i++)		       {   		   	  if (eeprom_rdata[i]!=(i + (j*16))%256)   //fail		   	   {		   	    UART_tx_vec("I2C  FAIL @ ",strlen("I2C FAIL @ "));		   	    UART_print_integer((int)eeprom_rdata[i]);		   	    while (!(UART_putc(13)));		   	    while (!(UART_putc(10)));                   	    error =1;		   	   }		   		   		   	 }		   	 		       		   }	 		   		   if (error == 1) 		   {		       UART_tx_vec("I2C TEST FAIL ",strlen("I2C TEST FAIL "));		   }		   else 		   {		       UART_tx_vec("I2C TEST PASS ",strlen("I2C TEST PASS "));		   }		   break;	case '1' :	           UART_tx_vec("Input a char to write ",strlen("Input a char to write "));		   while (!(UART_getc(&data_write)));                   while (!(UART_putc(data_write)));		   //data_write= data_write-'0'; // convert to integer	           while (!(UART_putc(13)));	           while (!(UART_putc(10)));	           UART_tx_vec("Input a number 0-9 for address ",strlen("Input a number 0-9 for address "));		   while (!(UART_getc(&address)));                   while (!(UART_putc(address)));	           while (!(UART_putc(13)));	           while (!(UART_putc(10)));		   i2c_tx(&data_write,address-'0',1,0xa0);		    /* Wait some mSec to write in eeprom*/                   gptSetTimer(TIMER1, GPT_ENAB | GPT_SINGLE_SHOT | GPT_FREQ_259_766Khz, 1386);		   while (!(gptGetTimerVal(1) == 1000));	           break;	case '2' :	           UART_tx_vec("Input a number 0-9 for address to read",strlen("Input a number 0-9 for address to read")); 		   while (!(UART_getc(&address))); 		   while (!(UART_putc(13))); 		   while (!(UART_putc(10))); 		   i2c_rx(&data_write,address - '0',1,0xa0); 		   UART_tx_vec("Data read ",strlen("Data read ")); 		   while (!(UART_putc(data_write))); 		   while (!(UART_putc(13))); 		   while (!(UART_putc(10))); 		   break;		   }       UART_tx_vec("press s to stop r to run again ",strlen("press s to stop r to run again"));       while (!(UART_getc(&schedule)));               while( (schedule != 's') && (schedule != 'r'))        {          while (!(UART_getc(&schedule)));       }       while (!(UART_putc(13)));       while (!(UART_putc(10)));		   	}	   		  }

⌨️ 快捷键说明

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