123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- /*
- * I2C.c
- * k4be 2022
- * License: BSD
- */
- #include <avr/io.h>
- #include <util/delay.h>
- #include "I2C.h"
- #include "main.h"
- #define I2C_FREQ 400000
- #define PRESCALER 1 /* possible values: 1, 4, 16, 64 */
- void I2C_init(void){
- TWBR = (F_CPU/I2C_FREQ - 16.0)/2.0/PRESCALER;
- #if PRESCALER == 1
- TWSR |= 0;
- #elif PRESCALER == 4
- TWSR |= _BV(TWPS0);
- #elif PRESCALER == 16
- TWSR |= _BV(TWPS1);
- #elif PRESCALER == 64
- TWSR |= _BV(TWPS1) | _BV(TWPS0);
- #else
- #error Invalid prescaler
- #endif
- }
- /* two byte command (or command + value) */
- unsigned int I2C_SendCommand(unsigned char address, unsigned char command, unsigned char data_byte)
- {
- unsigned int error = ERROR_I2C;
- for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)
- {
- error = 0;
- TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition
- error |= I2C_WaitForTWInt();
-
- error |= I2C_SendOneCommandByte(address << 1);
- error |= I2C_SendOneCommandByte(command);
- error |= I2C_SendOneCommandByte(data_byte);
-
- TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
- }
-
- return error;
- }
- /* three byte command (or command + 2 values) */
- unsigned int I2C_SendCommand3byte(unsigned char address,unsigned char command,unsigned char data0, unsigned char data1)
- {
- unsigned int error = ERROR_I2C;
- for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)
- {
- error = 0;
- TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition
- error |= I2C_WaitForTWInt();
-
- error |= I2C_SendOneCommandByte(address << 1);
- error |= I2C_SendOneCommandByte(command);
- error |= I2C_SendOneCommandByte(data0);
- error |= I2C_SendOneCommandByte(data1);
-
- TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
- }
- return error;
- }
- /* read single byte */
- unsigned int I2C_ReceiveCommand(unsigned char address, unsigned char command, unsigned char *data_byte)
- {
- unsigned int error = ERROR_I2C;
- unsigned char _unused;
- for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)
- {
- error = 0;
- TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition
- error |= I2C_WaitForTWInt();
-
- error |= I2C_SendOneCommandByte(address << 1);
- error |= I2C_SendOneCommandByte(command);
- error |= I2C_SendOneCommandByte((address << 1) | 1);
- TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
- error |= I2C_WaitForTWInt();
- error |= I2C_ReceiveOneCommandByte(&_unused, 0);
- error |= I2C_ReceiveOneCommandByte(data_byte, 0);
- TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
- }
-
- return error;
- }
- /* send command + any byte count */
- unsigned int I2C_Send_n_bytes(unsigned char address,unsigned char command, const unsigned char *data, unsigned int length)
- {
- unsigned int error = ERROR_I2C;
- unsigned int i;
-
- for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)
- {
- error = 0;
- TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition
- error |= I2C_WaitForTWInt();
-
- error |= I2C_SendOneCommandByte(address << 1);
- error |= I2C_SendOneCommandByte(command);
- for(i=0;i<length;i++){
- error |= I2C_SendOneCommandByte(data[i]);
- }
-
- TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
- }
- return error;
- }
- /* read any byte count */
- unsigned int I2C_Receive_n_bytes(unsigned char address, unsigned char command, unsigned char *data, unsigned int length)
- {
- unsigned int i;
- unsigned int error = ERROR_I2C;
- for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)
- {
- error = 0;
- TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send START condition
- error |= I2C_WaitForTWInt();
-
- error |= I2C_SendOneCommandByte(address << 1);
- error |= I2C_SendOneCommandByte(command);
-
- TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
- _delay_us(1);
- TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
- error |= I2C_WaitForTWInt();
-
- error |= I2C_SendOneCommandByte((address << 1) | 1);
- for(i=0; i<length; i++){
- error |= I2C_ReceiveOneCommandByte(&data[i], i != length-1);
- }
- TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
- }
-
- return error;
- }
- /* read 2 bytes */
- unsigned int I2C_ReceiveCommand3byte(unsigned char address, unsigned char command, unsigned char *data0, unsigned char *data1)
- {
- unsigned int error = ERROR_I2C;
- unsigned char _unused;
- for(int index = 0 ; (index < MAX_REPEAT_I2C) && (error != ERROR_NO); index++)
- {
- error = 0;
- TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);//Send START condition
- error |= I2C_WaitForTWInt();
-
- error |= I2C_SendOneCommandByte(address << 1);
- error |= I2C_SendOneCommandByte(command);
- error |= I2C_SendOneCommandByte((address << 1) | 1);
-
- TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
- error |= I2C_WaitForTWInt();
- error |= I2C_ReceiveOneCommandByte(&_unused, 0);
- error |= I2C_ReceiveOneCommandByte(data0, 0);
- error |= I2C_ReceiveOneCommandByte(data1, 0);
-
- TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
- }
-
- return error;
- }
- unsigned int I2C_SendOneCommandByte(unsigned char command)
- {
- TWDR = command;
- TWCR = (1<<TWINT) | (1<<TWEN);
- return I2C_WaitForTWInt();
- }
- unsigned int I2C_ReceiveOneCommandByte(unsigned char *command, unsigned char ack)
- {
- TWCR = (1<<TWINT) | (1<<TWEN) | (ack?_BV(TWEA):0);
- unsigned int error = I2C_WaitForTWInt();
- *command = TWDR;
- return error;
- }
- unsigned int I2C_WaitForTWInt(void){
- unsigned char count = 10;
- while (count && !(TWCR & (1<<TWINT))){
- count--;
- _delay_us(1000000.0/I2C_FREQ*10); /* wait for 10 bit periods; the transaction never succeeds quicker */
- }
- if(count == 0) return ERROR_I2C_TIMEOUT;
- return ERROR_NO;
- }
|