Mercurial > d1-mini-20ch-servo
changeset 13:846c874c742c draft
Make PWM generation more robust
| author | Radomir Dopieralski <sheep-devel@sheep.art.pl> |
|---|---|
| date | Fri, 20 Jan 2017 17:47:37 +0100 |
| parents | 6894e39cec87 |
| children | 326ed6d18e6b |
| files | firmware/Makefile firmware/main.c |
| diffstat | 2 files changed, 47 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/firmware/Makefile Fri Jan 20 11:55:51 2017 +0100 +++ b/firmware/Makefile Fri Jan 20 17:47:37 2017 +0100 @@ -4,7 +4,7 @@ OBJECTS = main.o FUSES = -U lfuse:w:0xE2:m -U hfuse:w:0xDF:m -AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE) -B 500 +AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE) -B 100 COMPILE = avr-gcc -std=gnu99 -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE) all: main.hex
--- a/firmware/main.c Fri Jan 20 11:55:51 2017 +0100 +++ b/firmware/main.c Fri Jan 20 17:47:37 2017 +0100 @@ -23,6 +23,9 @@ volatile static uint8_t servo_mask_b[MAX_SERVO]; volatile static uint8_t servo_mask_c[MAX_SERVO]; volatile static uint8_t servo_mask_d[MAX_SERVO]; +volatile static uint8_t servo_enable_b; +volatile static uint8_t servo_enable_c; +volatile static uint8_t servo_enable_d; volatile static uint8_t servo_event; // Remap servo numbers to pins. @@ -35,9 +38,11 @@ ISR(TIMER1_COMPA_vect) { servo_event = 0; - PORTB = 0b11111111; - PORTC = 0b00001111; // leave out RESET, SDA, SCL, PC7 - PORTD = 0b11111111; + PORTB = 0xff; + // leave out RESET, A, SCL, PC7 + // pull up SDA and SCL + PORTC = 0xff & 0x3f; + PORTD = 0xff; TCNT1 = 0; OCR1B = servo_delay[0]; } @@ -45,7 +50,7 @@ ISR(TIMER1_COMPB_vect) { PORTB &= servo_mask_b[servo_event]; - PORTC &= servo_mask_c[servo_event]; + PORTC &= servo_mask_c[servo_event] | 0x30; PORTD &= servo_mask_d[servo_event]; servo_event += 1; OCR1B = servo_delay[servo_event]; @@ -65,19 +70,22 @@ servo_delay[event] = smallest_pulse; servo_mask_b[event] = 0xff; for (uint8_t servo = 0; servo < 8; ++servo) { - if (servo_pulse[servo] <= smallest_pulse) { + if (servo_pulse[servo] && + servo_pulse[servo] <= smallest_pulse) { servo_mask_b[event] &= ~(1 << servo); } } servo_mask_c[event] = 0xff; for (uint8_t servo = 0; servo < 4; ++servo) { - if (servo_pulse[8 + servo] <= smallest_pulse) { + if (servo_pulse[8 + servo] && + servo_pulse[8 + servo] <= smallest_pulse) { servo_mask_c[event] &= ~(1 << servo); } } servo_mask_d[event] = 0xff; for (uint8_t servo = 0; servo < 8; ++servo) { - if (servo_pulse[12 + servo] <= smallest_pulse) { + if (servo_pulse[12 + servo] && + servo_pulse[12 + servo] <= smallest_pulse) { servo_mask_d[event] &= ~(1 << servo); } } @@ -87,7 +95,7 @@ uint16_t adc(uint8_t pin) { - ADMUX = 0<<ADLAR | 0<<REFS1 | 0<<REFS0 | (0x03 & pin); + ADMUX = 0<<ADLAR | 0<<REFS1 | 0<<REFS0 | 0x03 & pin; ADCSRA |= 1<<ADSC; while (ADCSRA & (1<<ADSC)) { // Pass. @@ -97,19 +105,19 @@ int main() { + uint8_t i2c_address = I2C_ADDRESS; // Init ADC. - ADCSRA = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 0<<ADPS0; // Pre-scaler 64. - uint8_t i2c_address = I2C_ADDRESS; - if (adc(6) > 511) { - i2c_address += 1; - } - if (adc(7) > 511) { - i2c_address += 2; - } - ADCSRA = 0<<ADEN; +// ADCSRA = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 0<<ADPS0; // Pre-scaler 64. +// if (adc(6) > 511) { +// i2c_address += 1; +// } +// if (adc(7) > 511) { +// i2c_address += 2; +// } +// ADCSRA = 0<<ADEN; // setup i2c slave - PORTC |= 1<<PC4 | 1<<PC5; // enable pullups + //PORTC |= 1<<PC4 | 1<<PC5; // enable pullups TWAR = i2c_address<<1; // setup servos @@ -130,10 +138,17 @@ sei(); TCCR1C |= 1<<FOC1A; // trigger COMPA + uint8_t dirty = 0; // run i2c slave while (1) { TWCR = 1<<TWEN | 1<<TWINT | 1<<TWEA; - while (!(TWCR & (1<<TWINT))) {} + while (!(TWCR & (1<<TWINT))) { + // Only do the change if we are not in the middle of events. + if (dirty && servo_delay[servo_event] == 0xffff) { + servo_update(); + dirty = 0; + } + } switch (TWSR & 0xF8) { case 0x60: // received address for write and acked i2c_cursor = 0; @@ -145,19 +160,20 @@ } break; case 0xa0: // stop or repeated start received - if (i2c_cursor > 0) { - uint8_t i2c_servo = i2c_buffer[0]; - for (uint8_t i = 1; i < i2c_cursor - 1; i += 2) { - if (i2c_servo >= 20) { - i2c_servo = 0; - } - bytes2int.bytes[0] = i2c_buffer[i]; - bytes2int.bytes[1] = i2c_buffer[i + 1]; - servo_pulse[servo_map[i2c_servo]] = bytes2int.value; - i2c_servo += 1; + if (i2c_cursor == 0) { + break; + } + uint8_t i2c_servo = i2c_buffer[0]; + for (uint8_t i = 1; i < i2c_cursor - 1; i += 2) { + if (i2c_servo >= MAX_SERVO) { + i2c_servo = 0; } - servo_update(); + bytes2int.bytes[0] = i2c_buffer[i]; + bytes2int.bytes[1] = i2c_buffer[i + 1]; + servo_pulse[servo_map[i2c_servo]] = bytes2int.value; + i2c_servo += 1; } + dirty = 1; break; } }
