update
This commit is contained in:
69
main.c
69
main.c
@@ -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
|
||||
|
Reference in New Issue
Block a user