-#include <stdint.h>\r
-#include <string.h>\r
-\r
-#include <avr/interrupt.h>\r
-\r
-#include "intercom.h"\r
-#include "analog.h"\r
-#include "config.h"\r
-#include "watchdog.h"\r
-#include "heater.h"\r
-#include "temp.h"\r
-#include "timer.h"\r
-\r
-static uint8_t motor_pwm;\r
-static uint8_t motor_idle_counter;\r
-\r
-void io_init(void) {\r
- // setup I/O pins\r
- WRITE(DEBUG_LED, 0); SET_OUTPUT(DEBUG_LED);\r
- WRITE(H1D,0); SET_OUTPUT(H1D);\r
- WRITE(H1E,0); SET_OUTPUT(H1E);\r
- WRITE(H2D,0); SET_OUTPUT(H2D);\r
- WRITE(H2E,0); SET_OUTPUT(H2E);\r
-\r
- SET_INPUT(TRIM_POT);\r
- SET_INPUT(TEMP_PIN);\r
- SET_INPUT(TEMP_BED_PIN);\r
- SET_INPUT(E_STEP_PIN);\r
- SET_INPUT(E_DIR_PIN);\r
-\r
- // use pull up resistors to avoid noise\r
- WRITE(E_STEP_PIN, 1);\r
- WRITE(E_DIR_PIN, 1);\r
-\r
- //Enable the RS485 transceiver\r
- SET_OUTPUT(RX_ENABLE_PIN);\r
- SET_OUTPUT(TX_ENABLE_PIN);\r
- WRITE(RX_ENABLE_PIN,0);\r
- disable_transmit();\r
-\r
- #ifdef HEATER_PIN\r
- WRITE(HEATER_PIN, 0); SET_OUTPUT(HEATER_PIN);\r
- #endif\r
-\r
- #ifdef BED_PIN\r
- WRITE(BED_PIN, 0); SET_OUTPUT(BED_PIN);\r
- #endif\r
-\r
- #ifdef FAN_PIN\r
- WRITE(FAN_PIN, 0); SET_OUTPUT(FAN_PIN);\r
- #endif\r
-\r
-// #if defined(HEATER_PWM) || defined(FAN_PWM) || defined(BED_PWM)\r
- // setup PWM timer: fast PWM, no prescaler\r
- TCCR2A = MASK(WGM21) | MASK(WGM20);\r
- TCCR2B = MASK(CS22);\r
- TIMSK2 = 0;\r
- OCR2A = 0;\r
- OCR2B = 0;\r
-// #endif\r
-\r
- #if defined(H1E_PWM) && defined(H2E_PWM)\r
- TCCR0A = MASK(WGM01) | MASK(WGM00);\r
- TCCR0B = MASK(CS20);\r
- TIMSK0 = 0;\r
- OCR0A = 0;\r
- OCR0B = 0;\r
- #endif\r
-}\r
-\r
-void motor_init(void) {\r
- //Enable an interrupt to be triggered when the step pin changes\r
- //This will be PCIE0\r
- motor_idle_counter = 0;\r
- PCICR = MASK(PCIE0);\r
- PCMSK0 = MASK(PCINT2);\r
-}\r
-\r
-ISR(PCINT0_vect) {\r
- static uint8_t coil_pos, pwm;\r
-\r
- //if the step pin is high, we advance the motor\r
- if (READ(E_STEP_PIN)) {\r
-\r
- //Turn on motors only on first tick to save power I guess\r
- enable_motors();\r
-\r
- //Set motor idle counter to zero\r
- motor_idle_counter = 0;\r
-\r
- //Advance the coil position\r
- if (READ(E_DIR_PIN))\r
- coil_pos++;\r
- else\r
- coil_pos--;\r
-\r
- coil_pos &= 7;\r
-\r
- //Grab the latest motor power to use\r
- pwm = motor_pwm;\r
-\r
- switch(coil_pos) {\r
- case 0:\r
- WRITE(H1D, 0);\r
- WRITE(H2D, 0);\r
- H1E_PWM = 0;\r
- H2E_PWM = pwm;\r
- break;\r
- case 1:\r
- WRITE(H1D, 1);\r
- WRITE(H2D, 0);\r
- H1E_PWM = pwm;\r
- H2E_PWM = pwm;\r
- break;\r
- case 2:\r
- WRITE(H1D, 1);\r
- WRITE(H2D, 0);\r
- H1E_PWM = pwm;\r
- H2E_PWM = 0;\r
- break;\r
- case 3:\r
- WRITE(H1D, 1);\r
- WRITE(H2D, 1);\r
- H1E_PWM = pwm;\r
- H2E_PWM = pwm;\r
- break;\r
- case 4:\r
- WRITE(H1D, 1);\r
- WRITE(H2D, 1);\r
- H1E_PWM = 0;\r
- H2E_PWM = pwm;\r
- break;\r
- case 5:\r
- WRITE(H1D, 0);\r
- WRITE(H2D, 1);\r
- H1E_PWM = pwm;\r
- H2E_PWM = pwm;\r
- break;\r
- case 6:\r
- WRITE(H1D, 0);\r
- WRITE(H2D, 1);\r
- H1E_PWM = pwm;\r
- H2E_PWM = 0;\r
- break;\r
- case 7:\r
- WRITE(H1D, 0);\r
- WRITE(H2D, 0);\r
- H1E_PWM = pwm;\r
- H2E_PWM = pwm;\r
- break;\r
- }\r
- }\r
-}\r
-\r
-void init(void) {\r
- // set up watchdog\r
- wd_init();\r
-\r
- // setup analog reading\r
- analog_init();\r
-\r
- // set up serial\r
- intercom_init();\r
-\r
- // set up inputs and outputs\r
- io_init();\r
-\r
- // temp sensor\r
- temp_init();\r
-\r
- // heater\r
- heater_init();\r
-\r
- // set up extruder motor driver\r
- motor_init();\r
-\r
- // set up clock\r
- timer_init();\r
-\r
- // enable interrupts\r
- sei();\r
-\r
- // reset watchdog\r
- wd_reset();\r
-}\r
-\r
-uint8_t writebuff[11];\r
-int main (void)\r
-{\r
- init();\r
-\r
- enable_heater();\r
-\r
- // main loop\r
- for (;;)\r
- {\r
- wd_reset();\r
-\r
- //Read motor PWM\r
- motor_pwm = analog_read(TRIM_POT_CHANNEL) >> 2;\r
-\r
- ifclock(CLOCK_FLAG_10MS) {\r
- // check temperatures and manage heaters\r
- temp_sensor_tick();\r
- }\r
- ifclock(CLOCK_FLAG_250MS) {\r
- // this is of course bad code, since the interupt routine setting motor_idle_counter to 0 can be run at any time during this code. Worst case, it runs while disable_motors() is halfway in progress\r
- motor_idle_counter++;\r
- if (motor_idle_counter > 3)\r
- disable_motors();\r
- }\r
-\r
- // check if we've had a new intercom packet\r
- if (intercom_flags & FLAG_NEW_RX) {\r
- intercom_flags &= ~FLAG_NEW_RX;\r
-\r
- switch (rx.packet.control_word) {\r
- // M105- read temperatures\r
- case 105:\r
- send_temperature(0, temp_get(0));\r
- temp_set(0, read_temperature(0));\r
- send_temperature(1, temp_get(1));\r
- temp_set(1, read_temperature(1));\r
- start_send();\r
- break;\r
- // M130 - set PID P factor\r
- case 130:\r
- pid_set_p(rx.packet.control_index, rx.packet.control_data_int32);\r
- // M131 - set PID I factor\r
- case 131:\r
- pid_set_i(rx.packet.control_index, rx.packet.control_data_int32);\r
- // M132 - set PID D factor\r
- case 132:\r
- pid_set_d(rx.packet.control_index, rx.packet.control_data_int32);\r
- // M133 - set PID I limit\r
- case 133:\r
- pid_set_i_limit(rx.packet.control_index, rx.packet.control_data_int32);\r
- // M134 - save PID values to eeprom\r
- case 134:\r
- heater_save_settings();\r
- break;\r
- }\r
- }\r
-
- if (intercom_flags & FLAG_TX_FINISHED) {
- WRITE(TX_ENABLE_PIN,0);
- }\r
-
- }\r
-}\r