Handle I2C multiplexer channel selection
This commit is contained in:
@@ -1,12 +1,104 @@
|
||||
#include "common.h"
|
||||
#include "bus/twi.h"
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define TW_START 0x08
|
||||
#define TW_REP_START 0x10
|
||||
#define TW_MT_SLA_ACK 0x18
|
||||
#define TW_MT_SLA_NACK 0x20
|
||||
#define TW_MT_DATA_ACK 0x28
|
||||
#define TW_MR_SLA_ACK 0x40
|
||||
#define TW_MR_SLA_NACK 0x48
|
||||
#define TW_MR_DATA_ACK 0x50
|
||||
|
||||
int TWI_Init(void)
|
||||
{
|
||||
// Set SCL bit rate to 400kHz
|
||||
|
||||
TWSR = 0x00; // TWI status register
|
||||
TWBR = 0x0C; // TWI bit rate register
|
||||
TWSR = 0x00; // TWI status register
|
||||
TWBR = 0x0C; // TWI bit rate register
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TWI_Start(char addr, char mode)
|
||||
{
|
||||
unsigned int status;
|
||||
|
||||
assert(mode == 0 || mode == 1);
|
||||
|
||||
// Send start condition
|
||||
|
||||
TWCR = (1 << TWEN) // Enable TWI
|
||||
| (1 << TWINT) // Clear interrupt flag
|
||||
| (1 << TWSTA); // Send start condition
|
||||
|
||||
// Wait until start condition sent
|
||||
|
||||
while ((TWCR & (1 << TWINT)) == 0);
|
||||
if ((TWSR & 0xf8) != TW_START)
|
||||
return -1;
|
||||
|
||||
// Send slave address
|
||||
|
||||
addr = addr << 1; // Lowest bit for mode
|
||||
TWDR = addr + mode; // Mode 0=R, 1=W
|
||||
TWCR = (1 << TWEN) // Enable TWI
|
||||
| (1 << TWINT); // Clear interrupt flag
|
||||
|
||||
// Wait until slave address sent
|
||||
|
||||
while ((TWCR & (1 << TWINT)) == 0);
|
||||
status = TWSR & 0xF8;
|
||||
|
||||
if ((mode == 0 && status != TW_MT_SLA_ACK) ||
|
||||
(mode == 1 && status != TW_MR_SLA_ACK))
|
||||
return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TWI_Write(char data)
|
||||
{
|
||||
TWDR = data;
|
||||
TWCR = (1 << TWEN) // Enable TWI
|
||||
| (1 << TWINT); // Clear interrupt flag
|
||||
|
||||
while ((TWCR & (1 << TWINT)) == 0);
|
||||
|
||||
if ((TWSR & 0xF8) != TW_MT_DATA_ACK)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TWI_Wait_ACK(void)
|
||||
{
|
||||
unsigned int status;
|
||||
|
||||
while ((TWCR & (1 << TWINT)) == 0);
|
||||
status = TWSR & 0xF8;
|
||||
|
||||
if (status != TW_MT_DATA_ACK &&
|
||||
status != TW_MR_DATA_ACK)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TWI_Stop(void)
|
||||
{
|
||||
// Send stop condition
|
||||
|
||||
TWCR = (1 << TWEN) // Enable TWI
|
||||
| (1 << TWINT) // Clear interrupt flag
|
||||
| (1 << TWSTO); // Send stop condition
|
||||
|
||||
// Wait until stop condition sent
|
||||
|
||||
while (TWCR & (1 << TWSTO));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,5 +2,9 @@
|
||||
#define MAD_CORE_BUS_TWI_H
|
||||
|
||||
int TWI_Init(void);
|
||||
int TWI_Start(char addr, char mode);
|
||||
int TWI_Write(char data);
|
||||
int TWI_Wait_ACK(void);
|
||||
int TWI_Stop(void);
|
||||
|
||||
#endif // MAD_CORE_BUS_TWI_H
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "common.h"
|
||||
#include "bus/usart.h"
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
//#include <util/atomic.h>
|
||||
|
||||
Reference in New Issue
Block a user