diff --git a/extruder/analog.c b/extruder/analog.c index e4aebbb..d3e36de 100644 --- a/extruder/analog.c +++ b/extruder/analog.c @@ -54,8 +54,8 @@ void analog_init() { adc_counter = 0; adc_running_mask = 1; - AIO0_DDR &= ANALOG_MASK; - DIDR0 = ANALOG_MASK & 0x3F; + AIO0_DDR &= ~(ANALOG_MASK); + DIDR0 = (ANALOG_MASK) & 0x3F; // now we start the first conversion and leave the rest to the interrupt ADCSRA |= MASK(ADIE) | MASK(ADSC); @@ -73,7 +73,7 @@ ISR(ADC_vect, ISR_NOBLOCK) { adc_counter = ANALOG_START; adc_running_mask = ANALOG_START_MASK; } - } while ((adc_running_mask & ANALOG_MASK) == 0); + } while ((adc_running_mask & (ANALOG_MASK)) == 0); // start next conversion ADMUX = (adc_counter) | REFERENCE; diff --git a/extruder/config.h.dist b/extruder/config.h.dist index cd6d41a..e4345b4 100644 --- a/extruder/config.h.dist +++ b/extruder/config.h.dist @@ -3,6 +3,9 @@ #include "arduino.h" +// controller index- bus is multidrop after all +#define THIS_CONTROLLER_NUM 0 + //RS485 Interface pins #define RX_ENABLE_PIN DIO4 #define TX_ENABLE_PIN AIO2 @@ -40,33 +43,13 @@ #define TEMP_HYSTERESIS 20 #define TEMP_RESIDENCY_TIME 60 -#define NUM_TEMP_SENSORS 1 -#ifdef TEMP_C -/***************************************************************************\ -* * -* Fill in the following struct according to your hardware * -* * -* If your temperature sensor has no associated heater, enter '255' as the * -* heater index. * -* * -* for GEN3 set temp_type to TT_INTERCOM, temp_pin to 0 and heater index to * -* 255 * -* * -\***************************************************************************/ +#ifdef DEFINE_TEMP_SENSOR +DEFINE_TEMP_SENSOR(extruder, TT_THERMISTOR, PINC3) +#endif -struct { - uint8_t temp_type; - uint8_t temp_pin; - - uint8_t heater_index; -} temp_sensors[NUM_TEMP_SENSORS] = -{ - { - TT_THERMISTOR, - PINC3, - 0 - } -}; +#ifdef DEFINE_HEATER +DEFINE_HEATER(extruder, PORTD, DIO6_PIN, OCR0A) +DEFINE_HEATER(bed, PORTD, DIO5_PIN, OCR0B) #endif // list of PWM-able pins and corresponding timers @@ -81,49 +64,6 @@ struct { #define TH_COUNT 8 #define PID_SCALE 1024L -#define NUM_HEATERS 2 -#ifdef HEATER_C -/***************************************************************************\ -* * -* Fill in the following struct according to your hardware * -* * -* For the atmega168/328, timer/pin mappings are as follows * -* * -* OCR0A - PD6 * -* OCR0B - PD5 * -* OCR2A - PB3 * -* OCR2B - PD3 * -* * -\***************************************************************************/ -struct { - volatile uint8_t *heater_port; - uint8_t heater_pin; - volatile uint8_t *heater_pwm; -} heaters[NUM_HEATERS] = -{ - { - &PORTD, - PIND6, - &OCR0A - }, - { - &PORTB, - PINB4, - 0 - } -}; -#endif - -// #define HEATER_PIN DIO11 -// #define HEATER_PWM OCR2A -// -// #define BED_PIN DIO12 - -/* - Intercom -*/ -#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); WRITE(RX_ENABLE_PIN,0); } while(0) -#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); WRITE(RX_ENABLE_PIN,0); } while(0) /* Motors @@ -132,16 +72,4 @@ struct { #define enable_motors() do { TCCR0A |= MASK(COM0A1) | MASK(COM0B1); } while (0) #define disable_motors() do { TCCR0A &= ~MASK(COM0A1) & ~MASK(COM0B1); } while (0) -/* - Heater -*/ - -// #ifdef HEATER_PWM -// #define enable_heater() do { TCCR2A |= MASK(COM2A1); } while (0) -// #define disable_heater() do { TCCR2A &= ~MASK(COM2A1); } while (0) -// #else -// #define enable_heater() WRITE(HEATER_PIN, 1) -// #define disable_heater() WRITE(HEATER_PIN, 0) -// #endif - #endif /* _CONFIG_H */ diff --git a/extruder/debug.h b/extruder/debug.h index e96e268..08f0321 100644 --- a/extruder/debug.h +++ b/extruder/debug.h @@ -3,18 +3,12 @@ #include -#ifdef DEBUG - #define DEBUG_PID 1 - #define DEBUG_DDA 2 - #define DEBUG_POSITION 4 -#else - // by setting these to zero, the compiler should optimise the relevant code out - #define DEBUG_PID 0 - #define DEBUG_DDA 0 - #define DEBUG_POSITION 0 -#endif +// by setting these to zero, the compiler should optimise the relevant code out +#define DEBUG_PID 0 +#define DEBUG_DDA 0 +#define DEBUG_POSITION 0 -#define DEBUG_ECHO 128 +#define DEBUG_ECHO 0 extern volatile uint8_t debug_flags; diff --git a/extruder/extruder.c b/extruder/extruder.c index cc4bbb0..e67c539 100644 --- a/extruder/extruder.c +++ b/extruder/extruder.c @@ -187,7 +187,7 @@ int main (void) temp_sensor_tick(); - update_send_cmd(temp_get(0) >> 2); - temp_set(0, get_read_cmd()); + send_temperature(0, temp_get(0)); + temp_set(0, read_temperature(0)); } } diff --git a/extruder/heater.c b/extruder/heater.c index 7d0d759..8779dc1 100644 --- a/extruder/heater.c +++ b/extruder/heater.c @@ -9,9 +9,21 @@ #ifndef EXTRUDER #include "sersendf.h" #endif +#include "temp.h" -#define HEATER_C -#include "config.h" +typedef struct { + volatile uint8_t *heater_port; + uint8_t heater_pin; + volatile uint8_t *heater_pwm; +} heater_definition_t; + +#undef DEFINE_HEATER +#define DEFINE_HEATER(name, port, pin, pwm) { &(port), (pin), &(pwm) }, +static const heater_definition_t heaters[NUM_HEATERS] = +{ + #include "config.h" +}; +#undef DEFINE_HEATER // this struct holds the heater PID factors that are stored in the EEPROM during poweroff struct { @@ -32,6 +44,8 @@ struct { uint16_t sanity_counter; uint16_t sane_temperature; #endif + + uint8_t heater_output; } heaters_runtime[NUM_HEATERS]; #define DEFAULT_P 8192 @@ -50,8 +64,7 @@ typedef struct { EE_factor EEMEM EE_factors[NUM_HEATERS]; void heater_init() { - #if NUM_HEATERS > 0 - uint8_t i; + heater_t i; // setup pins for (i = 0; i < NUM_HEATERS; i++) { *(heaters[i].heater_port) &= ~MASK(heaters[i].heater_pin); @@ -80,82 +93,96 @@ void heater_init() { // 0 is a "sane" temperature when we're trying to cool down heaters_runtime[i].sane_temperature = 0; #endif - - // read factors from eeprom - heaters_pid[i].p_factor = eeprom_read_dword((uint32_t *) &EE_factors[i].EE_p_factor); - heaters_pid[i].i_factor = eeprom_read_dword((uint32_t *) &EE_factors[i].EE_i_factor); - heaters_pid[i].d_factor = eeprom_read_dword((uint32_t *) &EE_factors[i].EE_d_factor); - heaters_pid[i].i_limit = eeprom_read_word((uint16_t *) &EE_factors[i].EE_i_limit); - - if ((heaters_pid[i].p_factor == 0) && (heaters_pid[i].i_factor == 0) && (heaters_pid[i].d_factor == 0) && (heaters_pid[i].i_limit == 0)) { - heaters_pid[i].p_factor = DEFAULT_P; - heaters_pid[i].i_factor = DEFAULT_I; - heaters_pid[i].d_factor = DEFAULT_D; - heaters_pid[i].i_limit = DEFAULT_I_LIMIT; - } + + #ifndef BANG_BANG + // read factors from eeprom + heaters_pid[i].p_factor = eeprom_read_dword((uint32_t *) &EE_factors[i].EE_p_factor); + heaters_pid[i].i_factor = eeprom_read_dword((uint32_t *) &EE_factors[i].EE_i_factor); + heaters_pid[i].d_factor = eeprom_read_dword((uint32_t *) &EE_factors[i].EE_d_factor); + heaters_pid[i].i_limit = eeprom_read_word((uint16_t *) &EE_factors[i].EE_i_limit); + + if ((heaters_pid[i].p_factor == 0) && (heaters_pid[i].i_factor == 0) && (heaters_pid[i].d_factor == 0) && (heaters_pid[i].i_limit == 0)) { + heaters_pid[i].p_factor = DEFAULT_P; + heaters_pid[i].i_factor = DEFAULT_I; + heaters_pid[i].d_factor = DEFAULT_D; + heaters_pid[i].i_limit = DEFAULT_I_LIMIT; + } + #endif /* BANG_BANG */ } - #endif } void heater_save_settings() { - uint8_t i; - for (i = 0; i < NUM_HEATERS; i++) { - eeprom_write_dword((uint32_t *) &EE_factors[i].EE_p_factor, heaters_pid[i].p_factor); - eeprom_write_dword((uint32_t *) &EE_factors[i].EE_i_factor, heaters_pid[i].i_factor); - eeprom_write_dword((uint32_t *) &EE_factors[i].EE_d_factor, heaters_pid[i].d_factor); - eeprom_write_word((uint16_t *) &EE_factors[i].EE_i_limit, heaters_pid[i].i_limit); - } + #ifndef BANG_BANG + heater_t i; + for (i = 0; i < NUM_HEATERS; i++) { + eeprom_write_dword((uint32_t *) &EE_factors[i].EE_p_factor, heaters_pid[i].p_factor); + eeprom_write_dword((uint32_t *) &EE_factors[i].EE_i_factor, heaters_pid[i].i_factor); + eeprom_write_dword((uint32_t *) &EE_factors[i].EE_d_factor, heaters_pid[i].d_factor); + eeprom_write_word((uint16_t *) &EE_factors[i].EE_i_limit, heaters_pid[i].i_limit); + } + #endif /* BANG_BANG */ } -void heater_tick(uint8_t h, uint16_t current_temp, uint16_t target_temp) { - #if NUM_HEATERS > 0 - int16_t heater_p; - int16_t heater_d; +void heater_tick(heater_t h, temp_sensor_t t, uint16_t current_temp, uint16_t target_temp) { uint8_t pid_output; - - int16_t t_error = target_temp - current_temp; - - heaters_runtime[h].temp_history[heaters_runtime[h].temp_history_pointer++] = current_temp; - heaters_runtime[h].temp_history_pointer &= (TH_COUNT - 1); - - // PID stuff - // proportional - heater_p = t_error; - - // integral - heaters_runtime[h].heater_i += t_error; - // prevent integrator wind-up - if (heaters_runtime[h].heater_i > heaters_pid[h].i_limit) - heaters_runtime[h].heater_i = heaters_pid[h].i_limit; - else if (heaters_runtime[h].heater_i < -heaters_pid[h].i_limit) - heaters_runtime[h].heater_i = -heaters_pid[h].i_limit; - - // derivative - // note: D follows temp rather than error so there's no large derivative when the target changes - heater_d = heaters_runtime[h].temp_history[heaters_runtime[h].temp_history_pointer] - current_temp; - - // combine factors - int32_t pid_output_intermed = ( - ( - (((int32_t) heater_p) * heaters_pid[h].p_factor) + - (((int32_t) heaters_runtime[h].heater_i) * heaters_pid[h].i_factor) + - (((int32_t) heater_d) * heaters_pid[h].d_factor) - ) / PID_SCALE - ); - - // rebase and limit factors - if (pid_output_intermed > 255) - pid_output = 255; - else if (pid_output_intermed < 0) - pid_output = 0; - else - pid_output = pid_output_intermed & 0xFF; - #ifdef DEBUG - if (debug_flags & DEBUG_PID) - sersendf_P(PSTR("T{E:%d, P:%d * %ld = %ld / I:%d * %ld = %ld / D:%d * %ld = %ld # O: %ld = %u}\n"), t_error, heater_p, heaters_pid[h].p_factor, (int32_t) heater_p * heaters_pid[h].p_factor / PID_SCALE, heaters_runtime[h].heater_i, heaters_pid[h].i_factor, (int32_t) heaters_runtime[h].heater_i * heaters_pid[h].i_factor / PID_SCALE, heater_d, heaters_pid[h].d_factor, (int32_t) heater_d * heaters_pid[h].d_factor / PID_SCALE, pid_output_intermed, pid_output); + #ifndef BANG_BANG + int16_t heater_p; + int16_t heater_d; + int16_t t_error = target_temp - current_temp; + #endif /* BANG_BANG */ + + if (h >= NUM_HEATERS || t >= NUM_TEMP_SENSORS) + return; + + #ifndef BANG_BANG + heaters_runtime[h].temp_history[heaters_runtime[h].temp_history_pointer++] = current_temp; + heaters_runtime[h].temp_history_pointer &= (TH_COUNT - 1); + + // PID stuff + // proportional + heater_p = t_error; + + // integral + heaters_runtime[h].heater_i += t_error; + // prevent integrator wind-up + if (heaters_runtime[h].heater_i > heaters_pid[h].i_limit) + heaters_runtime[h].heater_i = heaters_pid[h].i_limit; + else if (heaters_runtime[h].heater_i < -heaters_pid[h].i_limit) + heaters_runtime[h].heater_i = -heaters_pid[h].i_limit; + + // derivative + // note: D follows temp rather than error so there's no large derivative when the target changes + heater_d = heaters_runtime[h].temp_history[heaters_runtime[h].temp_history_pointer] - current_temp; + + // combine factors + int32_t pid_output_intermed = ( + ( + (((int32_t) heater_p) * heaters_pid[h].p_factor) + + (((int32_t) heaters_runtime[h].heater_i) * heaters_pid[h].i_factor) + + (((int32_t) heater_d) * heaters_pid[h].d_factor) + ) / PID_SCALE + ); + + // rebase and limit factors + if (pid_output_intermed > 255) + pid_output = 255; + else if (pid_output_intermed < 0) + pid_output = 0; + else + pid_output = pid_output_intermed & 0xFF; + + #ifdef DEBUG + if (debug_flags & DEBUG_PID) + sersendf_P(PSTR("T{E:%d, P:%d * %ld = %ld / I:%d * %ld = %ld / D:%d * %ld = %ld # O: %ld = %u}\n"), t_error, heater_p, heaters_pid[h].p_factor, (int32_t) heater_p * heaters_pid[h].p_factor / PID_SCALE, heaters_runtime[h].heater_i, heaters_pid[h].i_factor, (int32_t) heaters_runtime[h].heater_i * heaters_pid[h].i_factor / PID_SCALE, heater_d, heaters_pid[h].d_factor, (int32_t) heater_d * heaters_pid[h].d_factor / PID_SCALE, pid_output_intermed, pid_output); + #endif + #else + if (current_temp >= target_temp) + pid_output = BANG_BANG_ON; + else + pid_output = BANG_BANG_OFF; #endif - + #ifdef HEATER_SANITY_CHECK // check heater sanity // implementation is a moving window with some slow-down to compensate for thermal mass @@ -208,16 +235,19 @@ void heater_tick(uint8_t h, uint16_t current_temp, uint16_t target_temp) { if (labs(current_temp - heaters_runtime[h].sane_temperature) > TEMP_HYSTERESIS) { // no change, or change in wrong direction for a long time- heater is broken! pid_output = 0; - sersendf_P(PSTR("!! heater %d broken- temp is %d.%dC, target is %d.%dC, didn't reach %d.%dC in %d0 milliseconds\n"), h, current_temp >> 2, (current_temp & 3) * 25, target_temp >> 2, (target_temp & 3) * 25, heaters_runtime[h].sane_temperature >> 2, (heaters_runtime[h].sane_temperature & 3) * 25, heaters_runtime[h].sanity_counter); + sersendf_P(PSTR("!! heater %d or temp sensor %d broken- temp is %d.%dC, target is %d.%dC, didn't reach %d.%dC in %d0 milliseconds\n"), h, t, current_temp >> 2, (current_temp & 3) * 25, target_temp >> 2, (target_temp & 3) * 25, heaters_runtime[h].sane_temperature >> 2, (heaters_runtime[h].sane_temperature & 3) * 25, heaters_runtime[h].sanity_counter); } #endif /* HEATER_SANITY_CHECK */ heater_set(h, pid_output); - #endif /* if NUM_HEATERS > 0 */ } -void heater_set(uint8_t index, uint8_t value) { - #if NUM_HEATERS > 0 +void heater_set(heater_t index, uint8_t value) { + if (index >= NUM_HEATERS) + return; + + heaters_runtime[index].heater_output = value; + if (heaters[index].heater_pwm) { *(heaters[index].heater_pwm) = value; #ifdef DEBUG @@ -231,21 +261,50 @@ void heater_set(uint8_t index, uint8_t value) { else *(heaters[index].heater_port) &= ~MASK(heaters[index].heater_pin); } - #endif /* if NUM_HEATERS > 0 */ } -void pid_set_p(uint8_t index, int32_t p) { - heaters_pid[index].p_factor = p; +uint8_t heaters_all_off() { + uint8_t i; + for (i = 0; i < NUM_HEATERS; i++) { + if (heaters_runtime[i].heater_output > 0) + return 0; + } + + return 255; } -void pid_set_i(uint8_t index, int32_t i) { - heaters_pid[index].i_factor = i; +void pid_set_p(heater_t index, int32_t p) { + #ifndef BANG_BANG + if (index >= NUM_HEATERS) + return; + + heaters_pid[index].p_factor = p; + #endif /* BANG_BANG */ } -void pid_set_d(uint8_t index, int32_t d) { - heaters_pid[index].d_factor = d; +void pid_set_i(heater_t index, int32_t i) { + #ifndef BANG_BANG + if (index >= NUM_HEATERS) + return; + + heaters_pid[index].i_factor = i; + #endif /* BANG_BANG */ } -void pid_set_i_limit(uint8_t index, int32_t i_limit) { - heaters_pid[index].i_limit = i_limit; +void pid_set_d(heater_t index, int32_t d) { + #ifndef BANG_BANG + if (index >= NUM_HEATERS) + return; + + heaters_pid[index].d_factor = d; + #endif /* BANG_BANG */ +} + +void pid_set_i_limit(heater_t index, int32_t i_limit) { + #ifndef BANG_BANG + if (index >= NUM_HEATERS) + return; + + heaters_pid[index].i_limit = i_limit; + #endif /* BANG_BANG */ } diff --git a/extruder/heater.h b/extruder/heater.h index fdc9dc9..edd3d23 100644 --- a/extruder/heater.h +++ b/extruder/heater.h @@ -1,20 +1,34 @@ #ifndef _HEATER_H #define _HEATER_H +#include "config.h" #include +#include "temp.h" #define enable_heater() heater_set(0, 64) #define disable_heater() heater_set(0, 0) +#undef DEFINE_HEATER +#define DEFINE_HEATER(name, port, pin, pwm) HEATER_ ## name, +typedef enum +{ + #include "config.h" + NUM_HEATERS, + HEATER_noheater +} heater_t; +#undef DEFINE_HEATER + void heater_init(void); void heater_save_settings(void); -void heater_set(uint8_t index, uint8_t value); -void heater_tick(uint8_t h, uint16_t current_temp, uint16_t target_temp); +void heater_set(heater_t index, uint8_t value); +void heater_tick(heater_t h, temp_sensor_t t, uint16_t current_temp, uint16_t target_temp); -void pid_set_p(uint8_t index, int32_t p); -void pid_set_i(uint8_t index, int32_t i); -void pid_set_d(uint8_t index, int32_t d); -void pid_set_i_limit(uint8_t index, int32_t i_limit); +uint8_t heaters_all_off(void); + +void pid_set_p(heater_t index, int32_t p); +void pid_set_i(heater_t index, int32_t i); +void pid_set_d(heater_t index, int32_t d); +void pid_set_i_limit(heater_t index, int32_t i_limit); #endif /* _HEATER_H */ diff --git a/extruder/intercom.c b/extruder/intercom.c index 7cab163..8da6e62 100644 --- a/extruder/intercom.c +++ b/extruder/intercom.c @@ -1,47 +1,53 @@ #include "intercom.h" +#include #include #include "config.h" #include "delay.h" -#ifdef GEN3 +#if (defined TEMP_INTERCOM) || (defined EXTRUDER) #define INTERCOM_BAUD 57600 -#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); WRITE(RX_ENABLE_PIN,0); } while(0) -#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); WRITE(RX_ENABLE_PIN,0); } while(0) +#define START 0x55 -/* - Defines a super simple intercom interface using the RS485 modules +enum { + ERROR_BAD_CRC +} err_codes; - Host will say: START1 START2 PWM_CMD PWM_CHK - Extruder will reply: START1 START2 TMP_CMD TMP_CHK +typedef struct { + uint8_t start; + union { + struct { + uint8_t dio0 :1; + uint8_t dio1 :1; + uint8_t dio2 :1; + uint8_t dio3 :1; + uint8_t dio4 :1; + uint8_t dio5 :1; + uint8_t dio6 :1; + uint8_t dio7 :1; + }; + uint8_t dio; + }; + uint8_t controller_num; + uint16_t temp[3]; + uint8_t err; + uint8_t crc; +} intercom_packet_t; - CHK = 255-CMD, if they match do the work, if not, ignore this packet +typedef union { + intercom_packet_t packet; + uint8_t data[sizeof(intercom_packet_t)]; +} intercom_packet; - in a loop -*/ +intercom_packet tx; +intercom_packet rx; +uint8_t packet_pointer; +uint8_t rxcrc; -#define START1 0xAA -#define START2 0x55 - -typedef enum { - SEND_START1, - SEND_START2, - SEND_CMD, - SEND_CHK, - SEND_DONE, - - READ_START1, - READ_START2, - READ_CMD, - READ_CHK, -} intercom_state_e; - - -intercom_state_e state = READ_START1; -uint8_t cmd, chk, send_cmd, read_cmd; +volatile uint8_t intercom_flags; void intercom_init(void) { @@ -70,30 +76,60 @@ void intercom_init(void) UCSR0B |= MASK(RXCIE0) | MASK(TXCIE0); #endif + + intercom_flags = 0; } -void update_send_cmd(uint8_t new_send_cmd) { - send_cmd = new_send_cmd; +void send_temperature(uint8_t index, uint16_t temperature) { + tx.packet.temp[index] = temperature; } -uint8_t get_read_cmd(void) { - return read_cmd; +uint16_t read_temperature(uint8_t index) { + return rx.packet.temp[index]; } -static void write_byte(uint8_t val) { #ifdef HOST - UDR1 = val; +void set_dio(uint8_t index, uint8_t value) { + if (value) + tx.packet.dio |= (1 << index); + else + tx.packet.dio &= ~(1 << index); +} #else - UDR0 = val; +uint8_t get_dio(uint8_t index) { + return rx.packet.dio & (1 << index); +} #endif + +void set_err(uint8_t err) { + tx.packet.err = err; } +uint8_t get_err() { + return rx.packet.err; +} void start_send(void) { - state = SEND_START1; + uint8_t txcrc = 0, i; + + // atomically update flags + uint8_t sreg = SREG; + cli(); + intercom_flags = (intercom_flags & ~FLAG_TX_FINISHED) | FLAG_TX_IN_PROGRESS; + SREG = sreg; + + // calculate CRC for outgoing packet + for (i = 0; i < (sizeof(intercom_packet_t) - 1); i++) { + txcrc ^= tx.data[i]; + } + tx.packet.crc = txcrc; + + // enable transmit pin enable_transmit(); delay_us(15); - //Enable interrupts so we can send next characters + + // actually start sending the packet + packet_pointer = 0; #ifdef HOST UCSR1B |= MASK(UDRIE1); #else @@ -101,119 +137,100 @@ void start_send(void) { #endif } -static void finish_send(void) { - state = READ_START1; - disable_transmit(); -} - - /* Interrupts, UART 0 for mendel */ + +// receive data interrupt- stuff into rx #ifdef HOST ISR(USART1_RX_vect) #else ISR(USART_RX_vect) #endif { + // pull character static uint8_t c; -#ifdef HOST - c = UDR1; - UCSR1A &= ~MASK(FE1) & ~MASK(DOR1) & ~MASK(UPE1); -#else - c = UDR0; - UCSR0A &= ~MASK(FE0) & ~MASK(DOR0) & ~MASK(UPE0); -#endif - - if (state >= READ_START1) { - - switch(state) { - case READ_START1: - if (c == START1) state = READ_START2; - break; - case READ_START2: - if (c == START2) state = READ_CMD; - else state = READ_START1; - break; - case READ_CMD: - cmd = c; - state = READ_CHK; - break; - case READ_CHK: - chk = c; - - if (chk == 255 - cmd) { - //Values are correct, do something useful - WRITE(DEBUG_LED,1); - read_cmd = cmd; -#ifdef EXTRUDER - start_send(); -#endif - } - else - { - state = READ_START1; - } - break; - default: - break; - } + #ifdef HOST + c = UDR1; + UCSR1A &= ~MASK(FE1) & ~MASK(DOR1) & ~MASK(UPE1); + #else + c = UDR0; + UCSR0A &= ~MASK(FE0) & ~MASK(DOR0) & ~MASK(UPE0); + #endif + + // are we waiting for a start byte? is this one? + if ((packet_pointer == 0) && (c == START)) { + rxcrc = rx.packet.start = START; + packet_pointer = 1; + intercom_flags |= FLAG_RX_IN_PROGRESS; } + // we're receiving a packet + if (packet_pointer > 0) { + // calculate CRC (except CRC character!) + if (packet_pointer < (sizeof(intercom_packet_t) - 1)) + rxcrc ^= c; + // stuff byte into structure + rx.data[packet_pointer++] = c; + // last byte? + if (packet_pointer >= sizeof(intercom_packet_t)) { + // reset pointer + packet_pointer = 0; + + intercom_flags = (intercom_flags & ~FLAG_RX_IN_PROGRESS) | FLAG_NEW_RX; + #ifndef HOST + if (rx.packet.controller_num == THIS_CONTROLLER_NUM) { + if (rxcrc != rx.packet.crc) + tx.packet.err = ERROR_BAD_CRC; + start_send(); + } + #endif + } + } } +// finished transmitting interrupt- only enabled at end of packet #ifdef HOST ISR(USART1_TX_vect) #else ISR(USART_TX_vect) #endif { - if (state == SEND_DONE) { - finish_send(); - - -#ifdef HOST - UCSR1B &= ~MASK(TXCIE1); -#else - UCSR0B &= ~MASK(TXCIE0); -#endif + if (packet_pointer >= sizeof(intercom_packet_t)) { + disable_transmit(); + packet_pointer = 0; + intercom_flags = (intercom_flags & ~FLAG_TX_IN_PROGRESS) | FLAG_TX_FINISHED; + #ifdef HOST + UCSR1B &= ~MASK(TXCIE1); + #else + UCSR0B &= ~MASK(TXCIE0); + #endif } } +// tx queue empty interrupt- send next byte #ifdef HOST ISR(USART1_UDRE_vect) #else ISR(USART_UDRE_vect) #endif { - switch(state) { - case SEND_START1: - write_byte(START1); - state = SEND_START2; - break; - case SEND_START2: - write_byte(START2); - state = SEND_CMD; - break; - case SEND_CMD: - write_byte(send_cmd); - state = SEND_CHK; - break; - case SEND_CHK: - write_byte(255 - send_cmd); - state = SEND_DONE; -#ifdef HOST - UCSR1B &= ~MASK(UDRIE1); - UCSR1B |= MASK(TXCIE1); -#else - UCSR0B &= ~MASK(UDRIE0); - UCSR0B |= MASK(TXCIE0); -#endif - break; - default: - break; + #ifdef HOST + UDR1 = tx.data[packet_pointer++]; + #else + UDR0 = tx.data[packet_pointer++]; + #endif + + if (packet_pointer >= sizeof(intercom_packet_t)) { + #ifdef HOST + UCSR1B &= ~MASK(UDRIE1); + UCSR1B |= MASK(TXCIE1); + #else + UCSR0B &= ~MASK(UDRIE0); + UCSR0B |= MASK(TXCIE0); + #endif } } -#endif /* GEN3 */ +#endif /* TEMP_INTERCOM */ diff --git a/extruder/intercom.h b/extruder/intercom.h index 5a6ab8e..f8bc666 100644 --- a/extruder/intercom.h +++ b/extruder/intercom.h @@ -3,15 +3,42 @@ #include +#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); WRITE(RX_ENABLE_PIN,0); } while(0) +#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); WRITE(RX_ENABLE_PIN,0); } while(0) + // initialise serial subsystem void intercom_init(void); -//Update the message we are sending over intercom -void update_send_cmd(uint8_t new_send_cmd); +// if host, send target temperature to extruder +// if extruder, send actual temperature to host +void send_temperature(uint8_t index, uint16_t temperature); +// if host, read actual temperature from extruder +// if extruder, read target temperature from host +uint16_t read_temperature(uint8_t index); + +// if host, set DIOs on extruder controller +// if extruder, report DIO state +void set_dio(uint8_t index, uint8_t value); + +// if host, read extruder DIO inputs +// if extruder, set DIO outputs +uint8_t get_dio(uint8_t index); + +// set error code to send to other end +void set_err(uint8_t err); + +// get error code sent from other end +uint8_t get_err(void); + +// if host, send packet to extruder +// if extruder, return packet to host void start_send(void); -//Read the message we are receiving over intercom -uint8_t get_read_cmd(void); +#define FLAG_RX_IN_PROGRESS 1 +#define FLAG_TX_IN_PROGRESS 2 +#define FLAG_NEW_RX 4 +#define FLAG_TX_FINISHED 8 +extern volatile uint8_t intercom_flags; #endif /* _INTERCOM_H */ diff --git a/extruder/temp.c b/extruder/temp.c index 4809218..e1d13a5 100644 --- a/extruder/temp.c +++ b/extruder/temp.c @@ -4,22 +4,6 @@ #include #include -typedef enum { - TT_THERMISTOR, - TT_MAX6675, - TT_AD595, - TT_PT100, - TT_INTERCOM -} temp_types; - -typedef enum { - PRESENT, - TCOPEN -} temp_flags_enum; - -#define TEMP_C -#include "config.h" - #include "arduino.h" #include "delay.h" #include "debug.h" @@ -27,10 +11,38 @@ typedef enum { #include "sersendf.h" #endif #include "heater.h" -#ifdef GEN3 +#ifdef TEMP_INTERCOM #include "intercom.h" #endif +typedef enum { + TT_THERMISTOR, + TT_MAX6675, + TT_AD595, + TT_PT100, + TT_INTERCOM, + TT_DUMMY, +} temp_types; + +typedef enum { + PRESENT, + TCOPEN +} temp_flags_enum; + +typedef struct { + uint8_t temp_type; + uint8_t temp_pin; + uint8_t heater_index; +} temp_sensor_definition_t; + +#undef DEFINE_TEMP_SENSOR +#define DEFINE_TEMP_SENSOR(name, type, pin) { (type), (pin), (HEATER_ ## name) }, +static const temp_sensor_definition_t temp_sensors[NUM_TEMP_SENSORS] = +{ + #include "config.h" +}; +#undef DEFINE_TEMP_SENSOR + // this struct holds the runtime sensor data- read temperatures, targets, etc struct { temp_flags_enum temp_flags; @@ -48,30 +60,7 @@ struct { #ifdef TEMP_THERMISTOR #include "analog.h" - -#define NUMTEMPS 20 -uint16_t temptable[NUMTEMPS][2] PROGMEM = { - {1, 841}, - {54, 255}, - {107, 209}, - {160, 184}, - {213, 166}, - {266, 153}, - {319, 142}, - {372, 132}, - {425, 124}, - {478, 116}, - {531, 108}, - {584, 101}, - {637, 93}, - {690, 86}, - {743, 78}, - {796, 70}, - {849, 61}, - {902, 50}, - {955, 34}, - {1008, 3} -}; +#include "ThermistorTable.h" #endif #ifdef TEMP_AD595 @@ -79,7 +68,7 @@ uint16_t temptable[NUMTEMPS][2] PROGMEM = { #endif void temp_init() { - uint8_t i; + temp_sensor_t i; for (i = 0; i < NUM_TEMP_SENSORS; i++) { switch(temp_sensors[i].temp_type) { #ifdef TEMP_MAX6675 @@ -100,10 +89,10 @@ void temp_init() { break;*/ #endif - #ifdef GEN3 + #ifdef TEMP_INTERCOM case TT_INTERCOM: intercom_init(); - update_send_cmd(0); + send_temperature(0, 0); break; #endif } @@ -111,7 +100,7 @@ void temp_init() { } void temp_sensor_tick() { - uint8_t i = 0; + temp_sensor_t i = 0; for (; i < NUM_TEMP_SENSORS; i++) { if (temp_sensors_runtime[i].next_read_time) { temp_sensors_runtime[i].next_read_time--; @@ -179,15 +168,50 @@ void temp_sensor_tick() { //Calculate real temperature based on lookup table for (j = 1; j < NUMTEMPS; j++) { if (pgm_read_word(&(temptable[j][0])) > temp) { - // multiply by 4 because internal temp is stored as 14.2 fixed point - temp = pgm_read_word(&(temptable[j][1])) * 4 + (pgm_read_word(&(temptable[j][0])) - temp) * 4 * (pgm_read_word(&(temptable[j-1][1])) - pgm_read_word(&(temptable[j][1]))) / (pgm_read_word(&(temptable[j][0])) - pgm_read_word(&(temptable[j-1][0]))); + // Thermistor table is already in 14.2 fixed point + #ifndef EXTRUDER + if (debug_flags & DEBUG_PID) + sersendf_P(PSTR("pin:%d Raw ADC:%d table entry: %d"),temp_sensors[i].temp_pin,temp,j); + #endif + // Linear interpolating temperature value + // y = ((x - x₀)y₁ + (x₁-x)y₀ ) / (x₁ - x₀) + // y = temp + // x = ADC reading + // x₀= temptable[j-1][0] + // x₁= temptable[j][0] + // y₀= temptable[j-1][1] + // y₁= temptable[j][1] + // y = + // Wikipedia's example linear interpolation formula. + temp = ( + // ((x - x₀)y₁ + ((uint32_t)temp - pgm_read_word(&(temptable[j-1][0]))) * pgm_read_word(&(temptable[j][1])) + // + + + + // (x₁-x) + (pgm_read_word(&(temptable[j][0])) - (uint32_t)temp) + // y₀ ) + * pgm_read_word(&(temptable[j-1][1]))) + // / + / + // (x₁ - x₀) + (pgm_read_word(&(temptable[j][0])) - pgm_read_word(&(temptable[j-1][0]))); + #ifndef EXTRUDER + if (debug_flags & DEBUG_PID) + sersendf_P(PSTR(" temp:%d.%d"),temp/4,(temp%4)*25); + #endif break; } } + #ifndef EXTRUDER + if (debug_flags & DEBUG_PID) + sersendf_P(PSTR(" Sensor:%d\n"),i); + #endif + //Clamp for overflows if (j == NUMTEMPS) - temp = temptable[NUMTEMPS-1][1] * 4; + temp = temptable[NUMTEMPS-1][1]; temp_sensors_runtime[i].next_read_time = 0; } while (0); @@ -196,7 +220,7 @@ void temp_sensor_tick() { #ifdef TEMP_AD595 case TT_AD595: - temp = analog_read(temp_pin); + temp = analog_read(temp_sensors[i].temp_pin); // convert // >>8 instead of >>10 because internal temp is stored as 14.2 fixed point @@ -213,16 +237,30 @@ void temp_sensor_tick() { break #endif /* TEMP_PT100 */ - #ifdef GEN3 + #ifdef TEMP_INTERCOM case TT_INTERCOM: - temp = get_read_cmd() << 2; + temp = read_temperature(temp_sensors[i].temp_pin); start_send(); temp_sensors_runtime[i].next_read_time = 0; break; - #endif /* GEN3 */ + #endif /* TEMP_INTERCOM */ + + #ifdef TEMP_DUMMY + case TT_DUMMY: + temp = temp_sensors_runtime[i].last_read_temp; + + if (temp_sensors_runtime[i].target_temp > temp) + temp++; + else if (temp_sensors_runtime[i].target_temp < temp) + temp--; + + temp_sensors_runtime[i].next_read_time = 0; + + break; + #endif /* TEMP_DUMMY */ } temp_sensors_runtime[i].last_read_temp = temp; @@ -235,14 +273,16 @@ void temp_sensor_tick() { } if (temp_sensors[i].heater_index < NUM_HEATERS) { - heater_tick(temp_sensors[i].heater_index, temp_sensors_runtime[i].last_read_temp, temp_sensors_runtime[i].target_temp); + heater_tick(temp_sensors[i].heater_index, i, temp_sensors_runtime[i].last_read_temp, temp_sensors_runtime[i].target_temp); } } } } uint8_t temp_achieved() { - uint8_t i, all_ok = 255; + temp_sensor_t i; + uint8_t all_ok = 255; + for (i = 0; i < NUM_TEMP_SENSORS; i++) { if (temp_sensors_runtime[i].temp_residency < TEMP_RESIDENCY_TIME) all_ok = 0; @@ -250,26 +290,42 @@ uint8_t temp_achieved() { return all_ok; } -void temp_set(uint8_t index, uint16_t temperature) { +void temp_set(temp_sensor_t index, uint16_t temperature) { + if (index >= NUM_TEMP_SENSORS) + return; + temp_sensors_runtime[index].target_temp = temperature; temp_sensors_runtime[index].temp_residency = 0; -#ifdef GEN3 +#ifdef TEMP_INTERCOM if (temp_sensors[index].temp_type == TT_INTERCOM) - update_send_cmd(temperature >> 2); + send_temperature(temp_sensors[index].temp_pin, temperature); #endif } -uint16_t temp_get(uint8_t index) { +uint16_t temp_get(temp_sensor_t index) { + if (index >= NUM_TEMP_SENSORS) + return 0; + return temp_sensors_runtime[index].last_read_temp; } // extruder doesn't have sersendf_P #ifndef EXTRUDER -void temp_print(uint8_t index) { +void temp_print(temp_sensor_t index) { uint8_t c = 0; - + + if (index >= NUM_TEMP_SENSORS) + return; + c = (temp_sensors_runtime[index].last_read_temp & 3) * 25; + + sersendf_P(PSTR("T:%u.%u"), temp_sensors_runtime[index].last_read_temp >> 2, c); + #ifdef HEATER_BED + uint8_t b = 0; + b = (temp_sensors_runtime[HEATER_BED].last_read_temp & 3) * 25; - sersendf_P(PSTR("T: %u.%u\n"), temp_sensors_runtime[index].last_read_temp >> 2, c); + sersendf_P(PSTR(" B:%u.%u"), temp_sensors_runtime[HEATER_bed].last_read_temp >> 2 , b); + #endif + } #endif diff --git a/extruder/temp.h b/extruder/temp.h index b00ee95..1815c4c 100644 --- a/extruder/temp.h +++ b/extruder/temp.h @@ -1,6 +1,7 @@ #ifndef _TEMP_H #define _TEMP_H +#include "config.h" #include /* @@ -11,6 +12,15 @@ no point in specifying a port- all the different temp sensors we have must be on we still need to specify which analog pins we use in machine.h for the analog sensors however, otherwise the analog subsystem won't read them. */ +#undef DEFINE_TEMP_SENSOR +#define DEFINE_TEMP_SENSOR(name, type, pin) TEMP_SENSOR_ ## name, +typedef enum { + #include "config.h" + NUM_TEMP_SENSORS, + TEMP_SENSOR_none +} temp_sensor_t; +#undef DEFINE_TEMP_SENSOR + #define temp_tick temp_sensor_tick void temp_init(void); @@ -19,11 +29,9 @@ void temp_sensor_tick(void); uint8_t temp_achieved(void); -void temp_set(uint8_t index, uint16_t temperature); -uint16_t temp_get(uint8_t index); +void temp_set(temp_sensor_t index, uint16_t temperature); +uint16_t temp_get(temp_sensor_t index); -void temp_print(uint8_t index); - -uint16_t temp_read(uint8_t index); +void temp_print(temp_sensor_t index); #endif /* _TIMER_H */ diff --git a/intercom.c b/intercom.c index c523d6e..8da6e62 100644 --- a/intercom.c +++ b/intercom.c @@ -1,47 +1,53 @@ #include "intercom.h" +#include #include #include "config.h" #include "delay.h" -#ifdef TEMP_INTERCOM +#if (defined TEMP_INTERCOM) || (defined EXTRUDER) #define INTERCOM_BAUD 57600 -#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); WRITE(RX_ENABLE_PIN,0); } while(0) -#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); WRITE(RX_ENABLE_PIN,0); } while(0) +#define START 0x55 -/* - Defines a super simple intercom interface using the RS485 modules +enum { + ERROR_BAD_CRC +} err_codes; - Host will say: START1 START2 PWM_CMD PWM_CHK - Extruder will reply: START1 START2 TMP_CMD TMP_CHK +typedef struct { + uint8_t start; + union { + struct { + uint8_t dio0 :1; + uint8_t dio1 :1; + uint8_t dio2 :1; + uint8_t dio3 :1; + uint8_t dio4 :1; + uint8_t dio5 :1; + uint8_t dio6 :1; + uint8_t dio7 :1; + }; + uint8_t dio; + }; + uint8_t controller_num; + uint16_t temp[3]; + uint8_t err; + uint8_t crc; +} intercom_packet_t; - CHK = 255-CMD, if they match do the work, if not, ignore this packet +typedef union { + intercom_packet_t packet; + uint8_t data[sizeof(intercom_packet_t)]; +} intercom_packet; - in a loop -*/ +intercom_packet tx; +intercom_packet rx; +uint8_t packet_pointer; +uint8_t rxcrc; -#define START1 0xAA -#define START2 0x55 - -typedef enum { - SEND_START1, - SEND_START2, - SEND_CMD, - SEND_CHK, - SEND_DONE, - - READ_START1, - READ_START2, - READ_CMD, - READ_CHK, -} intercom_state_e; - - -intercom_state_e state = READ_START1; -uint8_t cmd, chk, send_cmd, read_cmd; +volatile uint8_t intercom_flags; void intercom_init(void) { @@ -70,30 +76,60 @@ void intercom_init(void) UCSR0B |= MASK(RXCIE0) | MASK(TXCIE0); #endif + + intercom_flags = 0; } -void update_send_cmd(uint8_t new_send_cmd) { - send_cmd = new_send_cmd; +void send_temperature(uint8_t index, uint16_t temperature) { + tx.packet.temp[index] = temperature; } -uint8_t get_read_cmd(void) { - return read_cmd; +uint16_t read_temperature(uint8_t index) { + return rx.packet.temp[index]; } -static void write_byte(uint8_t val) { #ifdef HOST - UDR1 = val; +void set_dio(uint8_t index, uint8_t value) { + if (value) + tx.packet.dio |= (1 << index); + else + tx.packet.dio &= ~(1 << index); +} #else - UDR0 = val; +uint8_t get_dio(uint8_t index) { + return rx.packet.dio & (1 << index); +} #endif + +void set_err(uint8_t err) { + tx.packet.err = err; } +uint8_t get_err() { + return rx.packet.err; +} void start_send(void) { - state = SEND_START1; + uint8_t txcrc = 0, i; + + // atomically update flags + uint8_t sreg = SREG; + cli(); + intercom_flags = (intercom_flags & ~FLAG_TX_FINISHED) | FLAG_TX_IN_PROGRESS; + SREG = sreg; + + // calculate CRC for outgoing packet + for (i = 0; i < (sizeof(intercom_packet_t) - 1); i++) { + txcrc ^= tx.data[i]; + } + tx.packet.crc = txcrc; + + // enable transmit pin enable_transmit(); delay_us(15); - //Enable interrupts so we can send next characters + + // actually start sending the packet + packet_pointer = 0; #ifdef HOST UCSR1B |= MASK(UDRIE1); #else @@ -101,118 +137,99 @@ void start_send(void) { #endif } -static void finish_send(void) { - state = READ_START1; - disable_transmit(); -} - - /* Interrupts, UART 0 for mendel */ + +// receive data interrupt- stuff into rx #ifdef HOST ISR(USART1_RX_vect) #else ISR(USART_RX_vect) #endif { + // pull character static uint8_t c; -#ifdef HOST - c = UDR1; - UCSR1A &= ~MASK(FE1) & ~MASK(DOR1) & ~MASK(UPE1); -#else - c = UDR0; - UCSR0A &= ~MASK(FE0) & ~MASK(DOR0) & ~MASK(UPE0); -#endif - - if (state >= READ_START1) { - - switch(state) { - case READ_START1: - if (c == START1) state = READ_START2; - break; - case READ_START2: - if (c == START2) state = READ_CMD; - else state = READ_START1; - break; - case READ_CMD: - cmd = c; - state = READ_CHK; - break; - case READ_CHK: - chk = c; - - if (chk == 255 - cmd) { - //Values are correct, do something useful - WRITE(DEBUG_LED,1); - read_cmd = cmd; -#ifdef EXTRUDER - start_send(); -#endif - } - else - { - state = READ_START1; - } - break; - default: - break; - } + #ifdef HOST + c = UDR1; + UCSR1A &= ~MASK(FE1) & ~MASK(DOR1) & ~MASK(UPE1); + #else + c = UDR0; + UCSR0A &= ~MASK(FE0) & ~MASK(DOR0) & ~MASK(UPE0); + #endif + + // are we waiting for a start byte? is this one? + if ((packet_pointer == 0) && (c == START)) { + rxcrc = rx.packet.start = START; + packet_pointer = 1; + intercom_flags |= FLAG_RX_IN_PROGRESS; } + // we're receiving a packet + if (packet_pointer > 0) { + // calculate CRC (except CRC character!) + if (packet_pointer < (sizeof(intercom_packet_t) - 1)) + rxcrc ^= c; + // stuff byte into structure + rx.data[packet_pointer++] = c; + // last byte? + if (packet_pointer >= sizeof(intercom_packet_t)) { + // reset pointer + packet_pointer = 0; + + intercom_flags = (intercom_flags & ~FLAG_RX_IN_PROGRESS) | FLAG_NEW_RX; + #ifndef HOST + if (rx.packet.controller_num == THIS_CONTROLLER_NUM) { + if (rxcrc != rx.packet.crc) + tx.packet.err = ERROR_BAD_CRC; + start_send(); + } + #endif + } + } } +// finished transmitting interrupt- only enabled at end of packet #ifdef HOST ISR(USART1_TX_vect) #else ISR(USART_TX_vect) #endif { - if (state == SEND_DONE) { - finish_send(); - - -#ifdef HOST - UCSR1B &= ~MASK(TXCIE1); -#else - UCSR0B &= ~MASK(TXCIE0); -#endif + if (packet_pointer >= sizeof(intercom_packet_t)) { + disable_transmit(); + packet_pointer = 0; + intercom_flags = (intercom_flags & ~FLAG_TX_IN_PROGRESS) | FLAG_TX_FINISHED; + #ifdef HOST + UCSR1B &= ~MASK(TXCIE1); + #else + UCSR0B &= ~MASK(TXCIE0); + #endif } } +// tx queue empty interrupt- send next byte #ifdef HOST ISR(USART1_UDRE_vect) #else ISR(USART_UDRE_vect) #endif { - switch(state) { - case SEND_START1: - write_byte(START1); - state = SEND_START2; - break; - case SEND_START2: - write_byte(START2); - state = SEND_CMD; - break; - case SEND_CMD: - write_byte(send_cmd); - state = SEND_CHK; - break; - case SEND_CHK: - write_byte(255 - send_cmd); - state = SEND_DONE; -#ifdef HOST - UCSR1B &= ~MASK(UDRIE1); - UCSR1B |= MASK(TXCIE1); -#else - UCSR0B &= ~MASK(UDRIE0); - UCSR0B |= MASK(TXCIE0); -#endif - break; - default: - break; + #ifdef HOST + UDR1 = tx.data[packet_pointer++]; + #else + UDR0 = tx.data[packet_pointer++]; + #endif + + if (packet_pointer >= sizeof(intercom_packet_t)) { + #ifdef HOST + UCSR1B &= ~MASK(UDRIE1); + UCSR1B |= MASK(TXCIE1); + #else + UCSR0B &= ~MASK(UDRIE0); + UCSR0B |= MASK(TXCIE0); + #endif } } diff --git a/intercom.h b/intercom.h index 5a6ab8e..f8bc666 100644 --- a/intercom.h +++ b/intercom.h @@ -3,15 +3,42 @@ #include +#define enable_transmit() do { WRITE(TX_ENABLE_PIN,1); WRITE(RX_ENABLE_PIN,0); } while(0) +#define disable_transmit() do { WRITE(TX_ENABLE_PIN,0); WRITE(RX_ENABLE_PIN,0); } while(0) + // initialise serial subsystem void intercom_init(void); -//Update the message we are sending over intercom -void update_send_cmd(uint8_t new_send_cmd); +// if host, send target temperature to extruder +// if extruder, send actual temperature to host +void send_temperature(uint8_t index, uint16_t temperature); +// if host, read actual temperature from extruder +// if extruder, read target temperature from host +uint16_t read_temperature(uint8_t index); + +// if host, set DIOs on extruder controller +// if extruder, report DIO state +void set_dio(uint8_t index, uint8_t value); + +// if host, read extruder DIO inputs +// if extruder, set DIO outputs +uint8_t get_dio(uint8_t index); + +// set error code to send to other end +void set_err(uint8_t err); + +// get error code sent from other end +uint8_t get_err(void); + +// if host, send packet to extruder +// if extruder, return packet to host void start_send(void); -//Read the message we are receiving over intercom -uint8_t get_read_cmd(void); +#define FLAG_RX_IN_PROGRESS 1 +#define FLAG_TX_IN_PROGRESS 2 +#define FLAG_NEW_RX 4 +#define FLAG_TX_FINISHED 8 +extern volatile uint8_t intercom_flags; #endif /* _INTERCOM_H */ diff --git a/temp.c b/temp.c index f5423b2..e1d13a5 100644 --- a/temp.c +++ b/temp.c @@ -92,7 +92,7 @@ void temp_init() { #ifdef TEMP_INTERCOM case TT_INTERCOM: intercom_init(); - update_send_cmd(0); + send_temperature(0, 0); break; #endif } @@ -169,8 +169,10 @@ void temp_sensor_tick() { for (j = 1; j < NUMTEMPS; j++) { if (pgm_read_word(&(temptable[j][0])) > temp) { // Thermistor table is already in 14.2 fixed point + #ifndef EXTRUDER if (debug_flags & DEBUG_PID) sersendf_P(PSTR("pin:%d Raw ADC:%d table entry: %d"),temp_sensors[i].temp_pin,temp,j); + #endif // Linear interpolating temperature value // y = ((x - x₀)y₁ + (x₁-x)y₀ ) / (x₁ - x₀) // y = temp @@ -194,13 +196,17 @@ void temp_sensor_tick() { / // (x₁ - x₀) (pgm_read_word(&(temptable[j][0])) - pgm_read_word(&(temptable[j-1][0]))); + #ifndef EXTRUDER if (debug_flags & DEBUG_PID) sersendf_P(PSTR(" temp:%d.%d"),temp/4,(temp%4)*25); + #endif break; } } + #ifndef EXTRUDER if (debug_flags & DEBUG_PID) sersendf_P(PSTR(" Sensor:%d\n"),i); + #endif //Clamp for overflows @@ -214,7 +220,7 @@ void temp_sensor_tick() { #ifdef TEMP_AD595 case TT_AD595: - temp = analog_read(temp_pin); + temp = analog_read(temp_sensors[i].temp_pin); // convert // >>8 instead of >>10 because internal temp is stored as 14.2 fixed point @@ -233,7 +239,7 @@ void temp_sensor_tick() { #ifdef TEMP_INTERCOM case TT_INTERCOM: - temp = get_read_cmd() << 2; + temp = read_temperature(temp_sensors[i].temp_pin); start_send(); @@ -292,7 +298,7 @@ void temp_set(temp_sensor_t index, uint16_t temperature) { temp_sensors_runtime[index].temp_residency = 0; #ifdef TEMP_INTERCOM if (temp_sensors[index].temp_type == TT_INTERCOM) - update_send_cmd(temperature >> 2); + send_temperature(temp_sensors[index].temp_pin, temperature); #endif }