Add I2C slave library
- Add I2C slave library for general use.
This commit is contained in:
		
							parent
							
								
									3d9fda3629
								
							
						
					
					
						commit
						60797c8439
					
				
							
								
								
									
										100
									
								
								drivers/avr/i2c_slave.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										100
									
								
								drivers/avr/i2c_slave.c
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,100 @@
 | 
			
		||||
/* Library made by: g4lvanix
 | 
			
		||||
 * Github repository: https://github.com/g4lvanix/I2C-slave-lib
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <avr/io.h>
 | 
			
		||||
#include <util/twi.h>
 | 
			
		||||
#include <avr/interrupt.h>
 | 
			
		||||
 | 
			
		||||
#include "i2c_slave.h"
 | 
			
		||||
 | 
			
		||||
void i2c_init(uint8_t address){
 | 
			
		||||
	// load address into TWI address register
 | 
			
		||||
	TWAR = (address << 1);
 | 
			
		||||
	// set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt
 | 
			
		||||
	TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void i2c_stop(void){
 | 
			
		||||
	// clear acknowledge and enable bits
 | 
			
		||||
	TWCR &= ~( (1<<TWEA) | (1<<TWEN) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ISR(TWI_vect){
 | 
			
		||||
	
 | 
			
		||||
	// temporary stores the received data
 | 
			
		||||
	uint8_t data;
 | 
			
		||||
	
 | 
			
		||||
	// own address has been acknowledged
 | 
			
		||||
	if( (TWSR & 0xF8) == TW_SR_SLA_ACK ){  
 | 
			
		||||
		buffer_address = 0xFF;
 | 
			
		||||
		// clear TWI interrupt flag, prepare to receive next byte and acknowledge
 | 
			
		||||
		TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN); 
 | 
			
		||||
	}
 | 
			
		||||
	else if( (TWSR & 0xF8) == TW_SR_DATA_ACK ){ // data has been received in slave receiver mode
 | 
			
		||||
		
 | 
			
		||||
		// save the received byte inside data 
 | 
			
		||||
		data = TWDR;
 | 
			
		||||
		
 | 
			
		||||
		// check wether an address has already been transmitted or not
 | 
			
		||||
		if(buffer_address == 0xFF){
 | 
			
		||||
			
 | 
			
		||||
			buffer_address = data; 
 | 
			
		||||
			
 | 
			
		||||
			// clear TWI interrupt flag, prepare to receive next byte and acknowledge
 | 
			
		||||
			TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN); 
 | 
			
		||||
		}
 | 
			
		||||
		else{ // if a databyte has already been received
 | 
			
		||||
			
 | 
			
		||||
			// store the data at the current address
 | 
			
		||||
			rxbuffer[buffer_address] = data;
 | 
			
		||||
			
 | 
			
		||||
			// increment the buffer address
 | 
			
		||||
			buffer_address++;
 | 
			
		||||
			
 | 
			
		||||
			// if there is still enough space inside the buffer
 | 
			
		||||
			if(buffer_address < 0xFF){
 | 
			
		||||
				// clear TWI interrupt flag, prepare to receive next byte and acknowledge
 | 
			
		||||
				TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN); 
 | 
			
		||||
			}
 | 
			
		||||
			else{
 | 
			
		||||
				// Don't acknowledge
 | 
			
		||||
				TWCR &= ~(1<<TWEA); 
 | 
			
		||||
				// clear TWI interrupt flag, prepare to receive last byte.
 | 
			
		||||
				TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEN); 
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else if( (TWSR & 0xF8) == TW_ST_DATA_ACK ){ // device has been addressed to be a transmitter
 | 
			
		||||
		
 | 
			
		||||
		// copy data from TWDR to the temporary memory
 | 
			
		||||
		data = TWDR;
 | 
			
		||||
		
 | 
			
		||||
		// if no buffer read address has been sent yet
 | 
			
		||||
		if( buffer_address == 0xFF ){
 | 
			
		||||
			buffer_address = data;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// copy the specified buffer address into the TWDR register for transmission
 | 
			
		||||
		TWDR = txbuffer[buffer_address];
 | 
			
		||||
		// increment buffer read address
 | 
			
		||||
		buffer_address++;
 | 
			
		||||
		
 | 
			
		||||
		// if there is another buffer address that can be sent
 | 
			
		||||
		if(buffer_address < 0xFF){
 | 
			
		||||
			// clear TWI interrupt flag, prepare to send next byte and receive acknowledge
 | 
			
		||||
			TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN); 
 | 
			
		||||
		}
 | 
			
		||||
		else{
 | 
			
		||||
			// Don't acknowledge
 | 
			
		||||
			TWCR &= ~(1<<TWEA); 
 | 
			
		||||
			// clear TWI interrupt flag, prepare to receive last byte.
 | 
			
		||||
			TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEN); 
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	else{
 | 
			
		||||
		// if none of the above apply prepare TWI to be addressed again
 | 
			
		||||
		TWCR |= (1<<TWIE) | (1<<TWEA) | (1<<TWEN);
 | 
			
		||||
	} 
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								drivers/avr/i2c_slave.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								drivers/avr/i2c_slave.h
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
/* Library made by: g4lvanix
 | 
			
		||||
 * Github repository: https://github.com/g4lvanix/I2C-slave-lib
 | 
			
		||||
 | 
			
		||||
 Info: Inititate the library by giving the required address.
 | 
			
		||||
       Read or write to the necessary buffer according to the opperation.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef I2C_SLAVE_H
 | 
			
		||||
#define I2C_SLAVE_H
 | 
			
		||||
 | 
			
		||||
volatile uint8_t buffer_address;
 | 
			
		||||
volatile uint8_t txbuffer[0xFF];
 | 
			
		||||
volatile uint8_t rxbuffer[0xFF];
 | 
			
		||||
 | 
			
		||||
void i2c_init(uint8_t address);
 | 
			
		||||
void i2c_stop(void);
 | 
			
		||||
ISR(TWI_vect);
 | 
			
		||||
 | 
			
		||||
#endif // I2C_SLAVE_H
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user