Handle I2C multiplexer channel selection

This commit is contained in:
2024-09-02 03:07:44 +02:00
parent 19983fb613
commit 3f336798c3
7 changed files with 155 additions and 14 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -1,5 +1,6 @@
#include "common.h"
#include "bus/usart.h"
#include <avr/io.h>
#include <avr/interrupt.h>
//#include <util/atomic.h>