mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-10-31 05:12:33 +01:00 
			
		
		
		
	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
	 yiancar
						yiancar