📄 i2c.c.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 + -