This commit is contained in:
2025-04-30 15:47:19 +02:00
parent a9cd9b33a7
commit b41ea791a8
64 changed files with 86 additions and 4723 deletions

69
main.c
View File

@@ -1,7 +1,9 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdbool.h>
#include <avr/iom32.h>
// Motor A
#define MOTOR_A_POT 2
@@ -17,6 +19,13 @@
#define MOTOR_B_PIN_A_OCR OCR0
#define MOTOR_B_PIN_B_OCR OCR1B
// I2C Slave Register Map
#define REGISTER_COUNT 16
volatile uint8_t registers[REGISTER_COUNT];
// I2C State
volatile uint8_t reg_address = 0;
volatile bool reg_address_received = false;
typedef struct {
uint8_t pot_channel;
@@ -165,9 +174,69 @@ void update_motor(ServoMotor *motor) {
uint8_t i = 127;
ISR(TWI_vect) {
switch (TWSR & 0xF8) {
case 0x60: // Own SLA+W received, ACK returned
case 0x68: // Arbitration lost, own SLA+W received, ACK returned
reg_address_received = false; // Reset for new transfer
TWCR |= (1 << TWINT) | (1 << TWEA); // ACK next byte
break;
case 0x80: // Data received, ACK returned
case 0x90: // Data received (General Call), ACK returned
if (!reg_address_received) {
reg_address = TWDR; // First received byte = register address
reg_address_received = true;
} else {
if (reg_address < REGISTER_COUNT) {
registers[reg_address++] = TWDR; // Store received data, then auto-increment address
}
}
TWCR |= (1 << TWINT) | (1 << TWEA); // ACK next byte
break;
case 0xA8: // Own SLA+R received, ACK returned
case 0xB0: // Arbitration lost, own SLA+R received, ACK returned
if (reg_address < REGISTER_COUNT) {
TWDR = registers[reg_address++]; // Load data to send
} else {
TWDR = 0xFF; // Out of range, send dummy
}
TWCR |= (1 << TWINT) | (1 << TWEA); // ACK next byte
break;
case 0xB8: // Data transmitted, ACK received
if (reg_address < REGISTER_COUNT) {
TWDR = registers[reg_address++];
} else {
TWDR = 0xFF;
}
TWCR |= (1 << TWINT) | (1 << TWEA); // ACK next byte
break;
case 0xC0: // Data transmitted, NACK received (done)
case 0xC8: // Last byte transmitted, ACK received
case 0x88: // Data received, NACK returned
TWCR |= (1 << TWINT) | (1 << TWEA); // Done
break;
case 0x00: // Bus error
TWCR |= (1 << TWSTO) | (1 << TWINT) | (1 << TWEA); // Recover
break;
default:
TWCR |= (1 << TWINT) | (1 << TWEA); // Default ACK
break;
}
}
int main(void) {
ADCSRA |= (1 << ADEN);
DDRA = (1 << 7); //LED
TWAR = (0x69 << 1) | (1 << 0);
TWCR = (1 << 6) | (1 << 2) | (1 << 0);
*(motor_a.pin_a_ddr) |= (1 << motor_a.pin_a_bit); // Direction pin output
*(motor_a.pin_b_ddr) |= (1 << motor_a.pin_b_bit); // Direction pin output
*(motor_b.pin_a_ddr) |= (1 << motor_b.pin_a_bit); // Direction pin output