From 7cd9b0bc5e979fe93c71d5b6ee4682e0ada1af1c Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 16 Nov 2011 22:03:33 -0800 Subject: [PATCH 01/39] modify code to use optimized AVR code via PinTmplt --- G3Firmware.sln | 164 ++++++++++++ .../Extruder/boards/ecv22/ExtruderMotor.cc | 2 +- .../Extruder/boards/ecv34/ExtruderBoard.cc | 78 +++--- .../Extruder/boards/ecv34/ExtruderBoard.hh | 4 +- .../Extruder/boards/ecv34/ExtruderMotor.cc | 14 +- .../Extruder/boards/ecv34/SoftwareServo.cc | 2 + .../Extruder/boards/ecv34/SoftwareServo.hh | 35 ++- firmware/src/Motherboard/Host.cc | 8 +- firmware/src/Motherboard/Steppers.hh | 2 +- .../Motherboard/boards/mb24/Motherboard.cc | 83 +++++- .../Motherboard/boards/mb24/Motherboard.hh | 25 +- .../src/Motherboard/lib_sd/sd_raw_config.h | 10 +- firmware/src/shared/AvrPort.cc | 93 ------- firmware/src/shared/AvrPort.hh | 67 ----- firmware/src/shared/Display.hh | 27 ++ firmware/src/shared/Heater.hh | 2 +- firmware/src/shared/Interface.cc | 16 +- firmware/src/shared/Interface.hh | 8 +- firmware/src/shared/InterfaceBoard.cc | 24 +- firmware/src/shared/InterfaceBoard.hh | 12 +- firmware/src/shared/LiquidCrystal.cc | 239 ++++++++---------- firmware/src/shared/LiquidCrystal.hh | 81 ++---- firmware/src/shared/Menu.cc | 44 ++-- firmware/src/shared/PSU.cc | 11 +- firmware/src/shared/PSU.hh | 7 +- firmware/src/shared/Pin.cc | 2 - firmware/src/shared/Pin.hh | 22 -- firmware/src/shared/PinTmplt.hh | 111 ++++++++ firmware/src/shared/StepperAxis.cc | 6 +- firmware/src/shared/StepperAxis.hh | 10 +- firmware/src/shared/StepperInterface.cc | 2 + firmware/src/shared/StepperInterface.hh | 153 +++++++---- firmware/src/shared/Thermocouple.cc | 36 +-- firmware/src/shared/Thermocouple.hh | 14 +- firmware/src/shared/UART.cc | 14 +- 35 files changed, 825 insertions(+), 603 deletions(-) create mode 100644 G3Firmware.sln delete mode 100644 firmware/src/shared/AvrPort.cc delete mode 100644 firmware/src/shared/AvrPort.hh create mode 100644 firmware/src/shared/Display.hh delete mode 100644 firmware/src/shared/Pin.cc delete mode 100644 firmware/src/shared/Pin.hh create mode 100644 firmware/src/shared/PinTmplt.hh diff --git a/G3Firmware.sln b/G3Firmware.sln new file mode 100644 index 0000000..0068a78 --- /dev/null +++ b/G3Firmware.sln @@ -0,0 +1,164 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extruder", "Extruder", "{B8BCEC9D-EBA2-47E3-A7DF-2D668B3AC267}" + ProjectSection(SolutionItems) = preProject + firmware\src\Extruder\DebugPacketProcessor.cc = firmware\src\Extruder\DebugPacketProcessor.cc + firmware\src\Extruder\DebugPacketProcessor.hh = firmware\src\Extruder\DebugPacketProcessor.hh + firmware\src\Extruder\EepromMap.cc = firmware\src\Extruder\EepromMap.cc + firmware\src\Extruder\EepromMap.hh = firmware\src\Extruder\EepromMap.hh + firmware\src\Extruder\Host.cc = firmware\src\Extruder\Host.cc + firmware\src\Extruder\Host.hh = firmware\src\Extruder\Host.hh + firmware\src\Extruder\Main.cc = firmware\src\Extruder\Main.cc + firmware\src\Extruder\Main.hh = firmware\src\Extruder\Main.hh + firmware\src\Extruder\MotorController.cc = firmware\src\Extruder\MotorController.cc + firmware\src\Extruder\MotorController.hh = firmware\src\Extruder\MotorController.hh + firmware\src\Extruder\Version.hh = firmware\src\Extruder\Version.hh + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{AE577DDE-9F1C-404B-9AF4-5A9C8D8BF39B}" + ProjectSection(SolutionItems) = preProject + firmware\src\shared\AnalogPin.cc = firmware\src\shared\AnalogPin.cc + firmware\src\shared\AnalogPin.hh = firmware\src\shared\AnalogPin.hh + firmware\src\shared\AvrPort.cc = firmware\src\shared\AvrPort.cc + firmware\src\shared\AvrPort.hh = firmware\src\shared\AvrPort.hh + firmware\src\shared\ButtonArray.hh = firmware\src\shared\ButtonArray.hh + firmware\src\shared\CircularBuffer.hh = firmware\src\shared\CircularBuffer.hh + firmware\src\shared\Commands.hh = firmware\src\shared\Commands.hh + firmware\src\shared\CoolingFan.cc = firmware\src\shared\CoolingFan.cc + firmware\src\shared\CoolingFan.hh = firmware\src\shared\CoolingFan.hh + firmware\src\shared\Eeprom.cc = firmware\src\shared\Eeprom.cc + firmware\src\shared\Eeprom.hh = firmware\src\shared\Eeprom.hh + firmware\src\shared\Heater.cc = firmware\src\shared\Heater.cc + firmware\src\shared\Heater.hh = firmware\src\shared\Heater.hh + firmware\src\shared\HeatingElement.hh = firmware\src\shared\HeatingElement.hh + firmware\src\shared\Interface.cc = firmware\src\shared\Interface.cc + firmware\src\shared\Interface.hh = firmware\src\shared\Interface.hh + firmware\src\shared\InterfaceBoard.cc = firmware\src\shared\InterfaceBoard.cc + firmware\src\shared\InterfaceBoard.hh = firmware\src\shared\InterfaceBoard.hh + firmware\src\shared\LiquidCrystal.cc = firmware\src\shared\LiquidCrystal.cc + firmware\src\shared\LiquidCrystal.hh = firmware\src\shared\LiquidCrystal.hh + firmware\src\shared\Menu.cc = firmware\src\shared\Menu.cc + firmware\src\shared\Menu.hh = firmware\src\shared\Menu.hh + firmware\src\shared\Packet.cc = firmware\src\shared\Packet.cc + firmware\src\shared\Packet.hh = firmware\src\shared\Packet.hh + firmware\src\shared\PID.cc = firmware\src\shared\PID.cc + firmware\src\shared\PID.hh = firmware\src\shared\PID.hh + firmware\src\shared\Pin.cc = firmware\src\shared\Pin.cc + firmware\src\shared\Pin.hh = firmware\src\shared\Pin.hh + firmware\src\shared\PinTmplt.hh = firmware\src\shared\PinTmplt.hh + firmware\src\shared\ProtocolDocumentation.hh = firmware\src\shared\ProtocolDocumentation.hh + firmware\src\shared\PSU.cc = firmware\src\shared\PSU.cc + firmware\src\shared\PSU.hh = firmware\src\shared\PSU.hh + firmware\src\shared\StepperAxis.cc = firmware\src\shared\StepperAxis.cc + firmware\src\shared\StepperAxis.hh = firmware\src\shared\StepperAxis.hh + firmware\src\shared\StepperInterface.cc = firmware\src\shared\StepperInterface.cc + firmware\src\shared\StepperInterface.hh = firmware\src\shared\StepperInterface.hh + firmware\src\shared\TemperatureSensor.hh = firmware\src\shared\TemperatureSensor.hh + firmware\src\shared\Thermistor.cc = firmware\src\shared\Thermistor.cc + firmware\src\shared\Thermistor.hh = firmware\src\shared\Thermistor.hh + firmware\src\shared\ThermistorTable.cc = firmware\src\shared\ThermistorTable.cc + firmware\src\shared\ThermistorTable.hh = firmware\src\shared\ThermistorTable.hh + firmware\src\shared\Thermocouple.cc = firmware\src\shared\Thermocouple.cc + firmware\src\shared\Thermocouple.hh = firmware\src\shared\Thermocouple.hh + firmware\src\shared\Timeout.cc = firmware\src\shared\Timeout.cc + firmware\src\shared\Timeout.hh = firmware\src\shared\Timeout.hh + firmware\src\shared\Types.hh = firmware\src\shared\Types.hh + firmware\src\shared\UART.cc = firmware\src\shared\UART.cc + firmware\src\shared\UART.hh = firmware\src\shared\UART.hh + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Motherboard", "Motherboard", "{C51D0777-6F43-435A-B194-9FB6DE71E516}" + ProjectSection(SolutionItems) = preProject + firmware\src\Motherboard\Command.cc = firmware\src\Motherboard\Command.cc + firmware\src\Motherboard\Command.hh = firmware\src\Motherboard\Command.hh + firmware\src\Motherboard\DebugPacketProcessor.cc = firmware\src\Motherboard\DebugPacketProcessor.cc + firmware\src\Motherboard\DebugPacketProcessor.hh = firmware\src\Motherboard\DebugPacketProcessor.hh + firmware\src\Motherboard\EepromMap.cc = firmware\src\Motherboard\EepromMap.cc + firmware\src\Motherboard\EepromMap.hh = firmware\src\Motherboard\EepromMap.hh + firmware\src\Motherboard\Errors.hh = firmware\src\Motherboard\Errors.hh + firmware\src\Motherboard\Host.cc = firmware\src\Motherboard\Host.cc + firmware\src\Motherboard\Host.hh = firmware\src\Motherboard\Host.hh + firmware\src\Motherboard\Main.cc = firmware\src\Motherboard\Main.cc + firmware\src\Motherboard\Main.hh = firmware\src\Motherboard\Main.hh + firmware\src\Motherboard\Point.cc = firmware\src\Motherboard\Point.cc + firmware\src\Motherboard\Point.hh = firmware\src\Motherboard\Point.hh + firmware\src\Motherboard\SDCard.cc = firmware\src\Motherboard\SDCard.cc + firmware\src\Motherboard\SDCard.hh = firmware\src\Motherboard\SDCard.hh + firmware\src\Motherboard\Steppers.cc = firmware\src\Motherboard\Steppers.cc + firmware\src\Motherboard\Steppers.hh = firmware\src\Motherboard\Steppers.hh + firmware\src\Motherboard\Tool.cc = firmware\src\Motherboard\Tool.cc + firmware\src\Motherboard\Tool.hh = firmware\src\Motherboard\Tool.hh + firmware\src\Motherboard\Version.hh = firmware\src\Motherboard\Version.hh + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mb24", "mb24", "{C338C176-CD4F-4133-8B44-BA1B2EFD66B8}" + ProjectSection(SolutionItems) = preProject + firmware\src\Motherboard\boards\mb24\ButtonArray.cc = firmware\src\Motherboard\boards\mb24\ButtonArray.cc + firmware\src\Motherboard\boards\mb24\Configuration.hh = firmware\src\Motherboard\boards\mb24\Configuration.hh + firmware\src\Motherboard\boards\mb24\Motherboard.cc = firmware\src\Motherboard\boards\mb24\Motherboard.cc + firmware\src\Motherboard\boards\mb24\Motherboard.hh = firmware\src\Motherboard\boards\mb24\Motherboard.hh + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "rrmbv12", "rrmbv12", "{5B20E4BA-3A26-4273-8495-099508DE2D96}" + ProjectSection(SolutionItems) = preProject + firmware\src\Motherboard\boards\rrmbv12\Configuration.hh = firmware\src\Motherboard\boards\rrmbv12\Configuration.hh + firmware\src\Motherboard\boards\rrmbv12\Motherboard.cc = firmware\src\Motherboard\boards\rrmbv12\Motherboard.cc + firmware\src\Motherboard\boards\rrmbv12\Motherboard.hh = firmware\src\Motherboard\boards\rrmbv12\Motherboard.hh + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib_sd", "lib_sd", "{656CB7F3-AB12-4881-9A8F-22644216D524}" + ProjectSection(SolutionItems) = preProject + firmware\src\Motherboard\lib_sd\byteordering.c = firmware\src\Motherboard\lib_sd\byteordering.c + firmware\src\Motherboard\lib_sd\byteordering.h = firmware\src\Motherboard\lib_sd\byteordering.h + firmware\src\Motherboard\lib_sd\ChangeLog = firmware\src\Motherboard\lib_sd\ChangeLog + firmware\src\Motherboard\lib_sd\fat.c = firmware\src\Motherboard\lib_sd\fat.c + firmware\src\Motherboard\lib_sd\fat.h = firmware\src\Motherboard\lib_sd\fat.h + firmware\src\Motherboard\lib_sd\fat_config.h = firmware\src\Motherboard\lib_sd\fat_config.h + firmware\src\Motherboard\lib_sd\partition.c = firmware\src\Motherboard\lib_sd\partition.c + firmware\src\Motherboard\lib_sd\partition.h = firmware\src\Motherboard\lib_sd\partition.h + firmware\src\Motherboard\lib_sd\partition_config.h = firmware\src\Motherboard\lib_sd\partition_config.h + firmware\src\Motherboard\lib_sd\README.txt = firmware\src\Motherboard\lib_sd\README.txt + firmware\src\Motherboard\lib_sd\sd-reader_config.h = firmware\src\Motherboard\lib_sd\sd-reader_config.h + firmware\src\Motherboard\lib_sd\sd_raw.c = firmware\src\Motherboard\lib_sd\sd_raw.c + firmware\src\Motherboard\lib_sd\sd_raw.h = firmware\src\Motherboard\lib_sd\sd_raw.h + firmware\src\Motherboard\lib_sd\sd_raw_config.h = firmware\src\Motherboard\lib_sd\sd_raw_config.h + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "boards", "boards", "{2BF72BB7-EC26-4DFE-AE91-AA5F8996EF2A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ecv22", "ecv22", "{717E20D4-3D03-4098-BC43-782400939F44}" + ProjectSection(SolutionItems) = preProject + firmware\src\Extruder\boards\ecv22\Configuration.hh = firmware\src\Extruder\boards\ecv22\Configuration.hh + firmware\src\Extruder\boards\ecv22\ExtruderBoard.cc = firmware\src\Extruder\boards\ecv22\ExtruderBoard.cc + firmware\src\Extruder\boards\ecv22\ExtruderBoard.hh = firmware\src\Extruder\boards\ecv22\ExtruderBoard.hh + firmware\src\Extruder\boards\ecv22\ExtruderMotor.cc = firmware\src\Extruder\boards\ecv22\ExtruderMotor.cc + firmware\src\Extruder\boards\ecv22\ExtruderMotor.hh = firmware\src\Extruder\boards\ecv22\ExtruderMotor.hh + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ecv34", "ecv34", "{489403D6-ED19-4806-9E94-093A2570008C}" + ProjectSection(SolutionItems) = preProject + firmware\src\Extruder\boards\ecv34\.UART.cc.swp = firmware\src\Extruder\boards\ecv34\.UART.cc.swp + firmware\src\Extruder\boards\ecv34\Configuration.cc = firmware\src\Extruder\boards\ecv34\Configuration.cc + firmware\src\Extruder\boards\ecv34\Configuration.hh = firmware\src\Extruder\boards\ecv34\Configuration.hh + firmware\src\Extruder\boards\ecv34\ExtruderBoard.cc = firmware\src\Extruder\boards\ecv34\ExtruderBoard.cc + firmware\src\Extruder\boards\ecv34\ExtruderBoard.hh = firmware\src\Extruder\boards\ecv34\ExtruderBoard.hh + firmware\src\Extruder\boards\ecv34\ExtruderMotor.cc = firmware\src\Extruder\boards\ecv34\ExtruderMotor.cc + firmware\src\Extruder\boards\ecv34\ExtruderMotor.hh = firmware\src\Extruder\boards\ecv34\ExtruderMotor.hh + firmware\src\Extruder\boards\ecv34\SoftwareServo.cc = firmware\src\Extruder\boards\ecv34\SoftwareServo.cc + firmware\src\Extruder\boards\ecv34\SoftwareServo.hh = firmware\src\Extruder\boards\ecv34\SoftwareServo.hh + EndProjectSection +EndProject +Global + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {2BF72BB7-EC26-4DFE-AE91-AA5F8996EF2A} = {B8BCEC9D-EBA2-47E3-A7DF-2D668B3AC267} + {C338C176-CD4F-4133-8B44-BA1B2EFD66B8} = {C51D0777-6F43-435A-B194-9FB6DE71E516} + {5B20E4BA-3A26-4273-8495-099508DE2D96} = {C51D0777-6F43-435A-B194-9FB6DE71E516} + {656CB7F3-AB12-4881-9A8F-22644216D524} = {C51D0777-6F43-435A-B194-9FB6DE71E516} + {717E20D4-3D03-4098-BC43-782400939F44} = {2BF72BB7-EC26-4DFE-AE91-AA5F8996EF2A} + {489403D6-ED19-4806-9E94-093A2570008C} = {2BF72BB7-EC26-4DFE-AE91-AA5F8996EF2A} + EndGlobalSection +EndGlobal diff --git a/firmware/src/Extruder/boards/ecv22/ExtruderMotor.cc b/firmware/src/Extruder/boards/ecv22/ExtruderMotor.cc index e393c5e..476676f 100644 --- a/firmware/src/Extruder/boards/ecv22/ExtruderMotor.cc +++ b/firmware/src/Extruder/boards/ecv22/ExtruderMotor.cc @@ -22,7 +22,7 @@ #include "ExtruderMotor.hh" #include "Eeprom.hh" #include "EepromMap.hh" -#include "Pin.hh" +#include "PinTmplt.hh" using namespace eeprom; diff --git a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc index 9447029..20762f7 100644 --- a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc +++ b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc @@ -33,13 +33,13 @@ ExtruderBoard ExtruderBoard::extruder_board; ExtruderBoard::ExtruderBoard() : micros(0L), - extruder_thermocouple(THERMOCOUPLE_CS,THERMOCOUPLE_SCK,THERMOCOUPLE_SO), + extruder_thermocouple(),//THERMOCOUPLE_CS,THERMOCOUPLE_SCK,THERMOCOUPLE_SO), platform_thermistor(PLATFORM_PIN,1), extruder_heater(extruder_thermocouple,extruder_element,SAMPLE_INTERVAL_MICROS_THERMOCOUPLE,eeprom::EXTRUDER_PID_BASE), platform_heater(platform_thermistor,platform_element,SAMPLE_INTERVAL_MICROS_THERMISTOR,eeprom::HBP_PID_BASE), using_platform(true), - servoA(SERVO0), - servoB(SERVO1), + //servoA(SERVO0), + //servoB(SERVO1), coolingFan(extruder_heater, eeprom::COOLING_FAN_BASE) { } @@ -87,12 +87,12 @@ void ExtruderBoard::reset(uint8_t resetFlags) { // Set the output mode for the mosfets. All three should default // off. - CHANNEL_A.setValue(false); - CHANNEL_A.setDirection(true); - CHANNEL_B.setValue(false); - CHANNEL_B.setDirection(true); - CHANNEL_C.setValue(false); - CHANNEL_C.setDirection(true); + CHANNEL_A::setValue(false); + CHANNEL_A::setDirection(true); + CHANNEL_B::setValue(false); + CHANNEL_B::setDirection(true); + CHANNEL_C::setValue(false); + CHANNEL_C::setDirection(true); // Timer 0: // Mode: Phase-correct PWM (WGM2:0 = 001), cycle freq= 976 Hz @@ -182,25 +182,27 @@ void ExtruderBoard::setMotorSpeed(int16_t speed) { } void ExtruderBoard::setServo(uint8_t index, int value) { - SoftwareServo* servo; if (index == 0) { - servo = &servoA; + if (value == -1) { + servoA.disable(); + } + else { + if (!(servoA.isEnabled())) { + servoA.enable(); + } + servoA.setPosition(value); + } } else if (index == 1) { - servo = &servoB; - } - else { - return; - } - - if (value == -1) { - servo->disable(); - } - else { - if (!(servo->isEnabled())) { - servo->enable(); - } - servo->setPosition(value); + if (value == -1) { + servoB.disable(); + } + else { + if (!(servoB.isEnabled())) { + servoB.enable(); + } + servoB.setPosition(value); + } } } @@ -226,41 +228,41 @@ void ExtruderBoard::doInterrupt() { servo_counter = 0; if (servoA.isEnabled()) { - servoA.pin.setValue(true); + servoA.setValue(true); } if (servoB.isEnabled()) { - servoB.pin.setValue(true); + servoB.setValue(true); } } if ((servoA.isEnabled()) && (servo_counter > servoA.getCounts())) { - servoA.pin.setValue(false); + servoA.setValue(false); } if ((servoB.isEnabled()) && (servo_counter > servoB.getCounts())) { - servoB.pin.setValue(false); + servoB.setValue(false); } } //runs the AutoBuildPlatform (connected to 'Extra' screw terms on ECv3.x ) void ExtruderBoard::setAutomatedBuildPlatformRunning(bool state) { - CHANNEL_A.setValue(state); + CHANNEL_A::setValue(state); } //runs the Extruder Cooling Fan (connected to 'A1/B1' screw term on ECv3.x) void ExtruderBoard::setFanRunning(bool state) { //CHANNEL_A.setValue(on); - MOTOR_DIR_PIN.setDirection(true); - MOTOR_DIR_PIN.setValue(true); - MOTOR_ENABLE_PIN.setDirection(true); - MOTOR_ENABLE_PIN.setValue(state); + MOTOR_DIR_PIN::setDirection(true); + MOTOR_DIR_PIN::setValue(true); + MOTOR_ENABLE_PIN::setDirection(true); + MOTOR_ENABLE_PIN::setValue(state); } void ExtruderBoard::setValve(bool on) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { setUsingPlatform(false); pwmBOn(false); - CHANNEL_B.setValue(on); + CHANNEL_B::setValue(on); } } @@ -270,7 +272,7 @@ void ExtruderBoard::indicateError(int errorCode) { } void ExtruderBoard::lightIndicatorLED() { - MOTOR_DIR_PIN.setValue(true); + MOTOR_DIR_PIN::setValue(true); } void ExtruderBoard::setUsingPlatform(bool is_using) { @@ -288,7 +290,7 @@ void ExtruderHeatingElement::setHeatingElement(uint8_t value) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { if (value == 0 || value == 255) { pwmCOn(false); - CHANNEL_C.setValue(value == 255); + CHANNEL_C::setValue(value == 255); } else { OCR0A = value; pwmCOn(true); @@ -302,6 +304,6 @@ void BuildPlatformHeatingElement::setHeatingElement(uint8_t value) { // It works relatively well. ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { pwmBOn(false); - CHANNEL_B.setValue(value != 0); + CHANNEL_B::setValue(value != 0); } } diff --git a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.hh b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.hh index 244a42e..d5ac6ed 100644 --- a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.hh +++ b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.hh @@ -74,8 +74,8 @@ private: uint8_t slave_id; - SoftwareServo servoA; - SoftwareServo servoB; + SoftwareServo servoA; + SoftwareServo servoB; CoolingFan coolingFan; public: diff --git a/firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc b/firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc index f20eb01..e34b1a3 100644 --- a/firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc +++ b/firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc @@ -18,7 +18,7 @@ #include #include #include "Configuration.hh" -#include "Pin.hh" +#include "PinTmplt.hh" // Enable pin D5 is also OC0B. @@ -30,9 +30,9 @@ int16_t last_extruder_speed; // Timer0 has a duty cycle of 1/16 ms. void initExtruderMotor() { last_extruder_speed = 0; - MOTOR_ENABLE_PIN.setDirection(true); - MOTOR_ENABLE_PIN.setValue(false); - MOTOR_DIR_PIN.setDirection(true); + MOTOR_ENABLE_PIN::setDirection(true); + MOTOR_ENABLE_PIN::setValue(false); + MOTOR_DIR_PIN::setDirection(true); } @@ -48,12 +48,12 @@ void setExtruderMotor(int16_t speed) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { if (speed == 0 || speed == 255) { TCCR0A &= 0b11001111; - MOTOR_ENABLE_PIN.setValue(speed==255); + MOTOR_ENABLE_PIN::setValue(speed==255); } else { - MOTOR_ENABLE_PIN.setValue(true); + MOTOR_ENABLE_PIN::setValue(true); TCCR0A |= 0b00100000; } - MOTOR_DIR_PIN.setValue(!backwards); + MOTOR_DIR_PIN::setValue(!backwards); OCR0B = speed; } } diff --git a/firmware/src/Extruder/boards/ecv34/SoftwareServo.cc b/firmware/src/Extruder/boards/ecv34/SoftwareServo.cc index d94c313..f3c367c 100644 --- a/firmware/src/Extruder/boards/ecv34/SoftwareServo.cc +++ b/firmware/src/Extruder/boards/ecv34/SoftwareServo.cc @@ -1,3 +1,4 @@ +/* #include "SoftwareServo.hh" SoftwareServo::SoftwareServo(Pin pin) : @@ -27,3 +28,4 @@ void SoftwareServo::disable() { enabled = false; pin.setValue(false); } +*/ \ No newline at end of file diff --git a/firmware/src/Extruder/boards/ecv34/SoftwareServo.hh b/firmware/src/Extruder/boards/ecv34/SoftwareServo.hh index 6106da8..6c3515d 100644 --- a/firmware/src/Extruder/boards/ecv34/SoftwareServo.hh +++ b/firmware/src/Extruder/boards/ecv34/SoftwareServo.hh @@ -18,7 +18,7 @@ #ifndef SOFTWARE_SERVO_HH_ #define SOFTWARE_SERVO_HH_ -#include "Pin.hh" +#include "PinTmplt.hh" /// Software implementation of a hobby servo driver. Though module is implemented /// purely in software, it does require periodic servicing from a microsecond @@ -31,24 +31,46 @@ /// src\Extruder\boards\ecv34\ExtruderBoard.cc. This will have to be replicated /// (or perhaps somehow refactored) before use in another board. /// \ingroup SoftwareLibraries -class SoftwareServo { +template class SoftwareServo { public: /// Create a new sofware serial instance. /// \param [in] pin Digital output #Pin that this servo should be attached to. - SoftwareServo(Pin pin); + SoftwareServo() : enabled(false) + { + pin::setDirection(true); + pin::setValue(false); + } /// Set the servo position /// \param[in] position Servo position in degrees, from 0 - 180 - void setPosition(uint8_t position); + void setPosition(uint8_t position){ + // Program the timer match value so that we generate a pulse width per: + // http://www.servocity.com/html/hs-311_standard.html + // 600us + (value * 10) + // so 0deg = 600us, 90deg = 1500us, 180deg = 2400us + if (position > 180) { + position = 180; + } + counts = 600 + 10*position; + } /// Enable the software servo module. The servo output will not be modified /// automatically; it is dependant on the code in: /// src\Extruder\boards\ecv34\ExtruderBoard.cc - void enable(); + inline void enable() { enabled = true; } /// Disable the software servo module. The servo output will be turned off /// immediately (which may cause a glitch if the output was already on). - void disable(); + inline void disable() + { + enabled = false; + pin::setValue(false); + } + + inline void setValue(bool val) + { + pin::setValue(val); + } /// Determine if this software servo module is enabled. /// \return true if the software servo module is enabled. @@ -59,7 +81,6 @@ public: /// \return Pulse width of the servo control signal, in microseconds. uint16_t getCounts() { return counts; } - Pin pin; ///< #Pin this servo is attached to. private: bool enabled; ///< True if the servo is enabled. uint16_t counts; ///< Length of servo on-time, in microseconds. diff --git a/firmware/src/Motherboard/Host.cc b/firmware/src/Motherboard/Host.cc index 6a57fec..dadcf48 100644 --- a/firmware/src/Motherboard/Host.cc +++ b/firmware/src/Motherboard/Host.cc @@ -207,9 +207,9 @@ inline void handleGetPosition(const InPacket& from_host, OutPacket& to_host) { Motherboard& board = Motherboard::getBoard(); uint8_t endstop_status = 0; for (int i = 3; i > 0; i--) { - StepperInterface& si = board.getStepperInterface(i-1); + const StepperInterface* si = board.getStepperInterface(i-1); endstop_status <<= 2; - endstop_status |= (si.isAtMaximum()?2:0) | (si.isAtMinimum()?1:0); + endstop_status |= (si->isAtMaximum()?2:0) | (si->isAtMinimum()?1:0); } to_host.append8(endstop_status); } @@ -234,9 +234,9 @@ inline void handleGetPositionExt(const InPacket& from_host, OutPacket& to_host) Motherboard& board = Motherboard::getBoard(); uint8_t endstop_status = 0; for (int i = STEPPER_COUNT; i > 0; i--) { - StepperInterface& si = board.getStepperInterface(i-1); + const StepperInterface* si = board.getStepperInterface(i-1); endstop_status <<= 2; - endstop_status |= (si.isAtMaximum()?2:0) | (si.isAtMinimum()?1:0); + endstop_status |= (si->isAtMaximum()?2:0) | (si->isAtMinimum()?1:0); } to_host.append16(endstop_status); } diff --git a/firmware/src/Motherboard/Steppers.hh b/firmware/src/Motherboard/Steppers.hh index 6fc5ce5..45f2487 100644 --- a/firmware/src/Motherboard/Steppers.hh +++ b/firmware/src/Motherboard/Steppers.hh @@ -20,7 +20,7 @@ #include "Configuration.hh" #include -#include "Pin.hh" +#include "PinTmplt.hh" #include "Command.hh" #include "Point.hh" diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.cc b/firmware/src/Motherboard/boards/mb24/Motherboard.cc index f829190..1095a0a 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.cc +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.cc @@ -33,22 +33,29 @@ /// Instantiate static motherboard instance Motherboard Motherboard::motherboard; + /// Create motherboard object Motherboard::Motherboard() : - lcd(LCD_RS_PIN, + lcd( +/* + LCD_RS_PIN, LCD_ENABLE_PIN, LCD_D0_PIN, LCD_D1_PIN, LCD_D2_PIN, - LCD_D3_PIN), + LCD_D3_PIN +*/ + ), interfaceBoard(buttonArray, lcd, - INTERFACE_FOO_PIN, - INTERFACE_BAR_PIN, +// INTERFACE_FOO_PIN, +// INTERFACE_BAR_PIN, &mainMenu, &monitorMode) { +#if 0 +/* /// Set up the stepper pins on board creation #if STEPPER_COUNT > 0 stepper[0] = StepperInterface(X_DIR_PIN, @@ -90,8 +97,45 @@ Motherboard::Motherboard() : Pin(), eeprom::AXIS_INVERSION); #endif +*/ +#endif } +#if STEPPER_COUNT > 0 +StepperTmpltEndstops<0, X_DIR_PIN,X_STEP_PIN,X_ENABLE_PIN,X_MAX_PIN,X_MIN_PIN> Motherboard::stepperX; +#endif +#if STEPPER_COUNT > 1 +StepperTmpltEndstops<1, Y_DIR_PIN,Y_STEP_PIN,Y_ENABLE_PIN,Y_MAX_PIN,Y_MIN_PIN> Motherboard::stepperY; +#endif +#if STEPPER_COUNT > 2 +StepperTmpltEndstops<2, Z_DIR_PIN,Z_STEP_PIN,Z_ENABLE_PIN,Z_MAX_PIN,Z_MIN_PIN> Motherboard::stepperZ; +#endif +#if STEPPER_COUNT > 3 +StepperTmplt<3, B_DIR_PIN,B_STEP_PIN,B_ENABLE_PIN> Motherboard::stepperB; +#endif +#if STEPPER_COUNT > 4 +StepperTmplt<4, A_DIR_PIN,A_STEP_PIN,A_ENABLE_PIN> Motherboard::stepperA; +#endif +const StepperInterface* Motherboard::stepper[STEPPER_COUNT] = +{ + /// Set up the stepper pins on board creation +#if STEPPER_COUNT > 0 + &stepperX +#endif +#if STEPPER_COUNT > 1 + ,&stepperY +#endif +#if STEPPER_COUNT > 2 + ,&stepperZ +#endif +#if STEPPER_COUNT > 3 + ,&stepperB // swap B for extruder before of lower port usage +#endif +#if STEPPER_COUNT > 4 + ,&stepperA +#endif +}; + /// Reset the motherboard to its initial state. /// This only resets the board, and does not send a reset /// to any attached toolheads. @@ -110,10 +154,23 @@ void Motherboard::reset() { bool hold_z = (axis_invert & (1<<7)) == 0; steppers::setHoldZ(hold_z); - for (int i = 0; i < STEPPER_COUNT; i++) { - stepper[i].init(i); - } - // Initialize the host and slave UARTs +#if STEPPER_COUNT > 0 + stepperX.init(); +#endif +#if STEPPER_COUNT > 1 + stepperY.init(); +#endif +#if STEPPER_COUNT > 2 + stepperZ.init(); +#endif +#if STEPPER_COUNT > 3 + stepperB.init(); // swap B for extruder before of lower port usage +#endif +#if STEPPER_COUNT > 4 + stepperA.init(); +#endif + + // Initialize the host and slave UARTs UART::getHostUART().enable(true); UART::getHostUART().in.reset(); UART::getSlaveUART().enable(true); @@ -130,7 +187,7 @@ void Motherboard::reset() { TCCR2B = 0x07; // prescaler at 1/1024 TIMSK2 = 0x01; // OVF flag on // Configure the debug pin. - DEBUG_PIN.setDirection(true); + DEBUG_PIN::setDirection(true); // Check if the interface board is attached hasInterfaceBoard = interface::isConnected(); @@ -204,7 +261,7 @@ enum { void Motherboard::indicateError(int error_code) { if (error_code == 0) { blink_state = BLINK_NONE; - DEBUG_PIN.setValue(false); + DEBUG_PIN::setValue(false); } else if (blink_count != error_code) { blink_state = BLINK_OFF; @@ -238,7 +295,7 @@ ISR(TIMER2_OVF_vect) { blinked_so_far++; blink_state = BLINK_OFF; blink_ovfs_remaining = OVFS_OFF; - DEBUG_PIN.setValue(false); + DEBUG_PIN::setValue(false); } else if (blink_state == BLINK_OFF) { if (blinked_so_far >= blink_count) { blink_state = BLINK_PAUSE; @@ -246,13 +303,13 @@ ISR(TIMER2_OVF_vect) { } else { blink_state = BLINK_ON; blink_ovfs_remaining = OVFS_ON; - DEBUG_PIN.setValue(true); + DEBUG_PIN::setValue(true); } } else if (blink_state == BLINK_PAUSE) { blinked_so_far = 0; blink_state = BLINK_ON; blink_ovfs_remaining = OVFS_ON; - DEBUG_PIN.setValue(true); + DEBUG_PIN::setValue(true); } } } diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.hh b/firmware/src/Motherboard/boards/mb24/Motherboard.hh index 59326de..3933ab7 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.hh +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.hh @@ -21,7 +21,7 @@ #include "UART.hh" #include "StepperInterface.hh" #include "Types.hh" -#include "PSU.hh" +//#include "PSU.hh" #include "Configuration.hh" #include "Timeout.hh" #include "Menu.hh" @@ -44,8 +44,25 @@ public: static Motherboard& getBoard() { return motherboard; } private: - /// Collection of stepper controllers that are on this board - StepperInterface stepper[STEPPER_COUNT]; +#if STEPPER_COUNT > 0 + static StepperTmpltEndstops<0, X_DIR_PIN,X_STEP_PIN,X_ENABLE_PIN,X_MAX_PIN,X_MIN_PIN> stepperX; +#endif +#if STEPPER_COUNT > 1 + static StepperTmpltEndstops<1, Y_DIR_PIN,Y_STEP_PIN,Y_ENABLE_PIN,Y_MAX_PIN,Y_MIN_PIN> stepperY; +#endif +#if STEPPER_COUNT > 2 + static StepperTmpltEndstops<2, Z_DIR_PIN,Z_STEP_PIN,Z_ENABLE_PIN,Z_MAX_PIN,Z_MIN_PIN> stepperZ; +#endif +#if STEPPER_COUNT > 3 + // we're using B over A because of the assigned AVR Port which gets us a performance win using it over A + static StepperTmplt<3, B_DIR_PIN,B_STEP_PIN,B_ENABLE_PIN> stepperB; +#endif +#if STEPPER_COUNT > 4 + static StepperTmplt<4, A_DIR_PIN,A_STEP_PIN,A_ENABLE_PIN> stepperA; +#endif + + /// Collection of stepper controllers that are on this board + static const StepperInterface* stepper[STEPPER_COUNT]; /// Microseconds since board initialization volatile micros_t micros; @@ -78,7 +95,7 @@ public: /// Count the number of steppers available on this board. const int getStepperCount() const { return STEPPER_COUNT; } /// Get the stepper interface for the nth stepper. - StepperInterface& getStepperInterface(int n) + const StepperInterface* getStepperInterface(int n) { return stepper[n]; } diff --git a/firmware/src/Motherboard/lib_sd/sd_raw_config.h b/firmware/src/Motherboard/lib_sd/sd_raw_config.h index 1451cf9..799af8b 100644 --- a/firmware/src/Motherboard/lib_sd/sd_raw_config.h +++ b/firmware/src/Motherboard/lib_sd/sd_raw_config.h @@ -13,7 +13,7 @@ #include #include "Configuration.hh" -#include "Pin.hh" +#include "PinTmplt.hh" #ifdef __cplusplus extern "C" @@ -115,11 +115,11 @@ extern "C" #error "no sd/mmc pin mapping available!" #endif -#define configure_pin_available() SD_DETECT_PIN.setDirection(false) -#define configure_pin_locked() SD_WRITE_PIN.setDirection(false) +#define configure_pin_available() SD_DETECT_PIN::setDirection(false) +#define configure_pin_locked() SD_WRITE_PIN::setDirection(false) -#define get_pin_available() SD_DETECT_PIN.getValue() -#define get_pin_locked() !SD_WRITE_PIN.getValue() +#define get_pin_available() SD_DETECT_PIN::getValue() +#define get_pin_locked() !SD_WRITE_PIN::getValue() #if SD_RAW_SDHC typedef uint64_t offset_t; diff --git a/firmware/src/shared/AvrPort.cc b/firmware/src/shared/AvrPort.cc deleted file mode 100644 index 9d125b4..0000000 --- a/firmware/src/shared/AvrPort.cc +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2010 by Adam Mayer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - */ - - -#include "AvrPort.hh" - -#include - -// The AVR port and pin mapping is based on a convention that has held true for all ATMega chips -// released so far: that the ports begin in sequence from register 0x00 from A onwards, and are -// arranged: -// 0 PINx -// 1 DDRx -// 2 PORTx -// This is verified true for the 168/328/644p/1280/2560. - -// We support three platforms: Atmega168 (1 UART), Atmega644, and Atmega1280/2560 -#if defined (__AVR_ATmega168__) \ - || defined (__AVR_ATmega328__) \ - || defined (__AVR_ATmega644P__) \ - || defined (__AVR_ATmega1280__) \ - || defined (__AVR_ATmega2560__) -#else - #error UART not implemented on this processor type! -#endif - - -#define PINx _SFR_MEM8(port_base+0) -#define DDRx _SFR_MEM8(port_base+1) -#define PORTx _SFR_MEM8(port_base+2) - - -AvrPort::AvrPort() : - port_base(NULL_PORT) { -} - - -AvrPort::AvrPort(port_base_t port_base_in) : - port_base(port_base_in) { -} - -bool AvrPort::isNull() { - return port_base == NULL_PORT; -} - - -void AvrPort::setPinDirection(uint8_t pin_index, bool out) { - DDRx = (DDRx & ~_BV(pin_index)) | (out?_BV(pin_index):0); -} - - -bool AvrPort::getPin(uint8_t pin_index) { - return (PINx & _BV(pin_index)) != 0; -} - - -void AvrPort::setPin(uint8_t pin_index, bool on) { - PORTx = (PORTx & ~_BV(pin_index)) | (on?_BV(pin_index):0); -} - - - -#if defined(__AVR_ATmega644P__) || \ - defined(__AVR_ATmega1280__) || \ - defined(__AVR_ATmega2560__) -AvrPort PortA(0x20); -#endif // __AVR_ATmega644P__ -AvrPort PortB(0x23); -AvrPort PortC(0x26); -AvrPort PortD(0x29); -#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) -AvrPort PortE(0x2C); -AvrPort PortF(0x2F); -AvrPort PortG(0x32); -AvrPort PortH(0x100); -AvrPort PortJ(0x103); -AvrPort PortK(0x106); -AvrPort PortL(0x109); -#endif //__AVR_ATmega1280__ diff --git a/firmware/src/shared/AvrPort.hh b/firmware/src/shared/AvrPort.hh deleted file mode 100644 index aefc177..0000000 --- a/firmware/src/shared/AvrPort.hh +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2010 by Adam Mayer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - */ - -#ifndef SHARED_AVR_PORT_HH_ -#define SHARED_AVR_PORT_HH_ - -#include - -#if defined (__AVR_ATmega168__) \ - || defined (__AVR_ATmega328__) \ - || defined (__AVR_ATmega644P__) - - typedef uint8_t port_base_t; - #define NULL_PORT 0xff - -#elif defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) - - typedef uint16_t port_base_t; - #define NULL_PORT 0xffff - -#endif - - -/// The port module represents an eight bit, digital IO port on the -/// AVR microcontroller. This library creates static -/// -/// Porting notes: -/// Be sure to define all of the ports supported by your processor, and to -/// verify that the port registers follow the same convention as the 168. -/// \ingroup HardwareLibraries -class AvrPort { -private: - port_base_t port_base; -public: - AvrPort(); - AvrPort(port_base_t port_base_in); - bool isNull(); - void setPinDirection(uint8_t pin_index, bool out); - bool getPin(uint8_t pin_index); - void setPin(uint8_t pin_index, bool on); -}; - - -extern AvrPort PortA, PortB, PortC, PortD; - -#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) - extern AvrPort PortE, PortF, PortG, PortH; - extern AvrPort PortJ, PortK, PortL; -#endif // __AVR_ATmega1280__ - - -#endif // SHARED_AVR_PORT_HH_ - diff --git a/firmware/src/shared/Display.hh b/firmware/src/shared/Display.hh new file mode 100644 index 0000000..9164c90 --- /dev/null +++ b/firmware/src/shared/Display.hh @@ -0,0 +1,27 @@ +#ifndef DISPLAY_HH +#define DISPLAY_HH + +// TODO: Proper attribution + +#include +#include +#include "AvrPort.hh" + +class Display { +public: + Display() {}; + + virtual void init() {}; + virtual void clear() {}; + virtual void setCursor(uint8_t, uint8_t) {}; + virtual void write(uint8_t) {}; + + virtual void writeInt(uint16_t value, uint8_t digits) {} + virtual void writeString(const char message[]) {}; + virtual void writeFromPgmspace(const prog_char message[]) {}; + + // note: the base interface provides a NULL Display implementation which does nothing. + +}; + +#endif // LIQUID_CRYSTAL_HH diff --git a/firmware/src/shared/Heater.hh b/firmware/src/shared/Heater.hh index 537d4cb..e07f91d 100644 --- a/firmware/src/shared/Heater.hh +++ b/firmware/src/shared/Heater.hh @@ -20,7 +20,7 @@ #include "TemperatureSensor.hh" #include "HeatingElement.hh" -#include "Pin.hh" +#include "PinTmplt.hh" #include "PID.hh" #include "Types.hh" #include "Timeout.hh" diff --git a/firmware/src/shared/Interface.cc b/firmware/src/shared/Interface.cc index 902c9aa..8f24fb8 100644 --- a/firmware/src/shared/Interface.cc +++ b/firmware/src/shared/Interface.cc @@ -18,24 +18,24 @@ bool isConnected() { // then measure it. If low, then we probably have an interface board. // If high, we probably don't. - INTERFACE_FOO_PIN.setValue(true); - INTERFACE_FOO_PIN.setDirection(false); + INTERFACE_FOO_PIN::setValue(true); + INTERFACE_FOO_PIN::setDirection(false); // if we are pulled down, then we have an led attached?? - if (!INTERFACE_FOO_PIN.getValue()) { - INTERFACE_FOO_PIN.setDirection(true); - INTERFACE_FOO_PIN.setValue(true); + if (!INTERFACE_FOO_PIN::getValue()) { + INTERFACE_FOO_PIN::setDirection(true); + INTERFACE_FOO_PIN::setValue(true); return true; } else { - INTERFACE_FOO_PIN.setDirection(true); - INTERFACE_FOO_PIN.setValue(false); + INTERFACE_FOO_PIN::setDirection(true); + INTERFACE_FOO_PIN::setValue(false); return false; } - return (!INTERFACE_FOO_PIN.getValue()); + return (!INTERFACE_FOO_PIN::getValue()); } diff --git a/firmware/src/shared/Interface.hh b/firmware/src/shared/Interface.hh index 438e365..fb81abd 100644 --- a/firmware/src/shared/Interface.hh +++ b/firmware/src/shared/Interface.hh @@ -19,11 +19,11 @@ #ifndef INTERFACE_HH_ #define INTERFACE_HH_ - -#include "Menu.hh" +#if defined HAS_INTERFACE_BOARD #include "InterfaceBoard.hh" -#include "LiquidCrystal.hh" #include "Types.hh" +#include "Menu.hh" +#include "LiquidCrystal.hh" // TODO: This style interface is weird; find a way to replace it. namespace interface { @@ -66,3 +66,5 @@ micros_t getUpdateRate(); } #endif + +#endif diff --git a/firmware/src/shared/InterfaceBoard.cc b/firmware/src/shared/InterfaceBoard.cc index ea6cfeb..3b14ea8 100644 --- a/firmware/src/shared/InterfaceBoard.cc +++ b/firmware/src/shared/InterfaceBoard.cc @@ -1,20 +1,20 @@ #include "InterfaceBoard.hh" #include "Configuration.hh" -#include "LiquidCrystal.hh" #include "Host.hh" #if defined HAS_INTERFACE_BOARD +#include "LiquidCrystal.hh" + +#define foo_pin INTERFACE_FOO_PIN +#define bar_pin INTERFACE_BAR_PIN + InterfaceBoard::InterfaceBoard(ButtonArray& buttons_in, LiquidCrystal& lcd_in, - const Pin& foo_pin_in, - const Pin& bar_pin_in, Screen* mainScreen_in, Screen* buildScreen_in) : lcd(lcd_in), - buttons(buttons_in), - foo_pin(foo_pin_in), - bar_pin(bar_pin_in) + buttons(buttons_in) { buildScreen = buildScreen_in; mainScreen = mainScreen_in; @@ -23,14 +23,12 @@ InterfaceBoard::InterfaceBoard(ButtonArray& buttons_in, void InterfaceBoard::init() { buttons.init(); - lcd.begin(LCD_SCREEN_WIDTH, LCD_SCREEN_HEIGHT); - lcd.clear(); - lcd.home(); + lcd.init(); - foo_pin.setValue(false); - foo_pin.setDirection(true); - bar_pin.setValue(false); - bar_pin.setDirection(true); + foo_pin::setValue(false); + foo_pin::setDirection(true); + bar_pin::setValue(false); + bar_pin::setDirection(true); building = false; diff --git a/firmware/src/shared/InterfaceBoard.hh b/firmware/src/shared/InterfaceBoard.hh index d8f6a8d..1355eaf 100644 --- a/firmware/src/shared/InterfaceBoard.hh +++ b/firmware/src/shared/InterfaceBoard.hh @@ -20,7 +20,8 @@ #define INTERFACE_BOARD_HH_ #include "Configuration.hh" -#include "Pin.hh" +#if defined HAS_INTERFACE_BOARD +#include "PinTmplt.hh" #include "ButtonArray.hh" #include "Menu.hh" @@ -30,8 +31,6 @@ /// Character LCD screen geometry /// /// Porting Note: Screens may need to be rewritten to support different sizes. -#define LCD_SCREEN_WIDTH 16 -#define LCD_SCREEN_HEIGHT 4 /// The InterfaceBoard module provides support for the MakerBot Industries @@ -56,9 +55,6 @@ private: Screen* screenStack[SCREEN_STACK_DEPTH]; int8_t screenIndex; ///< Stack index of the current screen. - Pin foo_pin; ///< Pin connected to the 'foo' LED - Pin bar_pin; ///< Pin connected to the 'bar' LED - /// TODO: Delete this. bool building; ///< True if the bot is building @@ -72,8 +68,6 @@ public: /// \param[in] Screen to display while building InterfaceBoard(ButtonArray& buttons_in, LiquidCrystal& lcd_in, - const Pin& foo_pin_in, - const Pin& bar_pin_in, Screen* mainScreen_in, Screen* buildScreen_in); @@ -102,5 +96,5 @@ public: void showMonitorMode(); }; - +#endif #endif diff --git a/firmware/src/shared/LiquidCrystal.cc b/firmware/src/shared/LiquidCrystal.cc index f46f716..1f14e78 100755 --- a/firmware/src/shared/LiquidCrystal.cc +++ b/firmware/src/shared/LiquidCrystal.cc @@ -1,8 +1,49 @@ -#include "LiquidCrystal.hh" #include #include #include +#include "configuration.hh" + +#if defined(LCD_ENABLE_PIN) +#include "LiquidCrystal.hh" + +#define _rs_pin LCD_RS_PIN +#define _enable_pin LCD_ENABLE_PIN +#define _d0_pin LCD_D0_PIN +#define _d1_pin LCD_D1_PIN +#define _d2_pin LCD_D2_PIN +#define _d3_pin LCD_D3_PIN + +// commands +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags for display entry mode +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags for display on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags for display/cursor shift +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + // When the display powers up, it is configured as follows: // @@ -23,62 +64,75 @@ // can't assume that its in that state when a sketch starts (and the // LiquidCrystal constructor is called). -LiquidCrystal::LiquidCrystal(Pin rs, Pin rw, Pin enable, - Pin d0, Pin d1, Pin d2, Pin d3, - Pin d4, Pin d5, Pin d6, Pin d7) +LiquidCrystal::LiquidCrystal() { - init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); + + _rs_pin::setDirection(true); + _enable_pin::setDirection(true); + + _rs_pin::setValue(false); + _enable_pin::setValue(false); + + _d0_pin::setDirection(true); + _d1_pin::setDirection(true); + _d2_pin::setDirection(true); + _d3_pin::setDirection(true); + + _d0_pin::setValue(false); + _d1_pin::setValue(false); + _d2_pin::setValue(false); + _d3_pin::setValue(false); + + _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; + } -LiquidCrystal::LiquidCrystal(Pin rs, Pin enable, - Pin d0, Pin d1, Pin d2, Pin d3, - Pin d4, Pin d5, Pin d6, Pin d7) +void LiquidCrystal::init() { - init(0, rs, Pin(), enable, d0, d1, d2, d3, d4, d5, d6, d7); + begin(LCD_SCREEN_WIDTH, LCD_SCREEN_HEIGHT); + clear(); + home(); } -LiquidCrystal::LiquidCrystal(Pin rs, Pin rw, Pin enable, - Pin d0, Pin d1, Pin d2, Pin d3) + +/************ low level data pushing commands **********/ +static inline void _delay_248ns(void) { - init(1, rs, rw, enable, d0, d1, d2, d3, Pin(), Pin(), Pin(), Pin()); + __asm__ __volatile__ ("nop \n\tnop \n\tnop \n\tnop \n\t"); } -LiquidCrystal::LiquidCrystal(Pin rs, Pin enable, - Pin d0, Pin d1, Pin d2, Pin d3) -{ - init(1, rs, Pin(), enable, d0, d1, d2, d3, Pin(), Pin(), Pin(), Pin()); +inline void LiquidCrystal::pulseEnable(void) { + _enable_pin::setValue(true); + _delay_248ns(); + _enable_pin::setValue(false); } -void LiquidCrystal::init(uint8_t fourbitmode, Pin rs, Pin rw, Pin enable, - Pin d0, Pin d1, Pin d2, Pin d3, - Pin d4, Pin d5, Pin d6, Pin d7) -{ - _rs_pin = rs; - _rw_pin = rw; - _enable_pin = enable; - - _data_pins[0] = d0; - _data_pins[1] = d1; - _data_pins[2] = d2; - _data_pins[3] = d3; - _data_pins[4] = d4; - _data_pins[5] = d5; - _data_pins[6] = d6; - _data_pins[7] = d7; - - _rs_pin.setDirection(true); - // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin# - if (!_rw_pin.isNull()) { _rw_pin.setDirection(true); } - _enable_pin.setDirection(true); - - if (fourbitmode) - _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; - else - _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; - - begin(16, 1); +inline void LiquidCrystal::write4bits(uint8_t value) { + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + _d0_pin::setValue(((value >> 0) & 0x01) != 0, false); + _d1_pin::setValue(((value >> 1) & 0x01) != 0, false); + _d2_pin::setValue(((value >> 2) & 0x01) != 0, false); + _d3_pin::setValue(((value >> 3) & 0x01) != 0, false); + } + + pulseEnable(); } +// write either command or data, with automatic 4/8-bit selection +void LiquidCrystal::send(uint8_t value, bool mode) { + _rs_pin::setValue(mode); + + write4bits(value>>4); + _delay_248ns(); // delay to keep enable_pin low before half a cycle time. + write4bits(value); + + _delay_us(41); // commands need > 37us to settle [citation needed] +} + + + + void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { if (lines > 1) { _displayfunction |= LCD_2LINE; @@ -93,49 +147,28 @@ void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! // according to datasheet, we need at least 40ms after power rises above 2.7V - // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 + // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50 _delay_us(50000); - // Now we pull both RS and R/W low to begin commands - _rs_pin.setValue(false); - _enable_pin.setValue(false); - if (!_rw_pin.isNull()) { - _rw_pin.setValue(false); - } + - //put the LCD into 4 bit or 8 bit mode - if (! (_displayfunction & LCD_8BITMODE)) { + //put the LCD into 4 bit o // this is according to the hitachi HD44780 datasheet // figure 24, pg 46 // we start in 8bit mode, try to set 4 bit mode write4bits(0x03); - _delay_us(4500); // wait min 4.1ms + _delay_us(4100); // wait min 4.1ms // second try write4bits(0x03); - _delay_us(4500); // wait min 4.1ms + _delay_us(4100); // wait min 4.1ms // third go! write4bits(0x03); _delay_us(150); - // finally, set to 8-bit interface + // finally, set to 8=4-bit interface write4bits(0x02); - } else { - // this is according to the hitachi HD44780 datasheet - // page 45 figure 23 - - // Send function set command sequence - command(LCD_FUNCTIONSET | _displayfunction); - _delay_us(4500); // wait more than 4.1ms - - // second try - command(LCD_FUNCTIONSET | _displayfunction); - _delay_us(150); - - // third go - command(LCD_FUNCTIONSET | _displayfunction); - } // finally, set # lines, font size, etc. command(LCD_FUNCTIONSET | _displayfunction); @@ -251,14 +284,6 @@ void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) { /*********** mid level commands, for sending data/cmds */ -inline void LiquidCrystal::command(uint8_t value) { - send(value, false); -} - -inline void LiquidCrystal::write(uint8_t value) { - send(value, true); -} - void LiquidCrystal::writeInt(uint16_t value, uint8_t digits) { @@ -275,69 +300,25 @@ void LiquidCrystal::writeInt(uint16_t value, uint8_t digits) { for (uint8_t i = 0; i < digits; i++) { nextDigit = currentDigit/10; - write((value%currentDigit)/nextDigit+'0'); + write(uint8_t((value%currentDigit)/nextDigit)+'0'); currentDigit = nextDigit; } } -void LiquidCrystal::writeString(char message[]) { - char* letter = message; +void LiquidCrystal::writeString(const char message[]) { + const char* letter = message; while (*letter != 0) { write(*letter); letter++; } } -void LiquidCrystal::writeFromPgmspace(const prog_uchar message[]) { +void LiquidCrystal::writeFromPgmspace(const prog_char message[]) { char letter; - while (letter = pgm_read_byte(message++)) { + while ((letter = pgm_read_byte(message++))) { write(letter); } } -/************ low level data pushing commands **********/ - -// write either command or data, with automatic 4/8-bit selection -void LiquidCrystal::send(uint8_t value, bool mode) { - _rs_pin.setValue(mode); - - // if there is a RW pin indicated, set it low to Write - if (!_rw_pin.isNull()) { - _rw_pin.setValue(false); - } - - if (_displayfunction & LCD_8BITMODE) { - write8bits(value); - } else { - write4bits(value>>4); - write4bits(value); - } -} - -void LiquidCrystal::pulseEnable(void) { - _enable_pin.setValue(false); - _delay_us(1); - _enable_pin.setValue(true); - _delay_us(1); // enable pulse must be >450ns - _enable_pin.setValue(false); - _delay_us(1); // commands need > 37us to settle [citation needed] -} - -void LiquidCrystal::write4bits(uint8_t value) { - for (int i = 0; i < 4; i++) { - _data_pins[i].setDirection(true); - _data_pins[i].setValue(((value >> i) & 0x01) != 0); - } - - pulseEnable(); -} - -void LiquidCrystal::write8bits(uint8_t value) { - for (int i = 0; i < 8; i++) { - _data_pins[i].setDirection(true); - _data_pins[i].setValue(((value >> i) & 0x01) != 0); - } - - pulseEnable(); -} +#endif \ No newline at end of file diff --git a/firmware/src/shared/LiquidCrystal.hh b/firmware/src/shared/LiquidCrystal.hh index 7b70f0e..e3f4926 100755 --- a/firmware/src/shared/LiquidCrystal.hh +++ b/firmware/src/shared/LiquidCrystal.hh @@ -5,37 +5,11 @@ #include #include -#include "Pin.hh" - -// commands -#define LCD_CLEARDISPLAY 0x01 -#define LCD_RETURNHOME 0x02 -#define LCD_ENTRYMODESET 0x04 -#define LCD_DISPLAYCONTROL 0x08 -#define LCD_CURSORSHIFT 0x10 -#define LCD_FUNCTIONSET 0x20 -#define LCD_SETCGRAMADDR 0x40 -#define LCD_SETDDRAMADDR 0x80 - -// flags for display entry mode -#define LCD_ENTRYRIGHT 0x00 -#define LCD_ENTRYLEFT 0x02 -#define LCD_ENTRYSHIFTINCREMENT 0x01 -#define LCD_ENTRYSHIFTDECREMENT 0x00 - -// flags for display on/off control -#define LCD_DISPLAYON 0x04 -#define LCD_DISPLAYOFF 0x00 -#define LCD_CURSORON 0x02 -#define LCD_CURSOROFF 0x00 -#define LCD_BLINKON 0x01 -#define LCD_BLINKOFF 0x00 - -// flags for display/cursor shift -#define LCD_DISPLAYMOVE 0x08 -#define LCD_CURSORMOVE 0x00 -#define LCD_MOVERIGHT 0x04 -#define LCD_MOVELEFT 0x00 +#include "PinTmplt.hh" +#include"Display.hh" + +#define LCD_SCREEN_WIDTH 16 +#define LCD_SCREEN_HEIGHT 4 // flags for function set #define LCD_8BITMODE 0x10 @@ -45,26 +19,19 @@ #define LCD_5x10DOTS 0x04 #define LCD_5x8DOTS 0x00 -class LiquidCrystal { +#if defined(LCD_ENABLE_PIN) + +class LiquidCrystal : public Display { public: - LiquidCrystal(Pin rs, Pin enable, - Pin d0, Pin d1, Pin d2, Pin d3, - Pin d4, Pin d5, Pin d6, Pin d7); - LiquidCrystal(Pin rs, Pin rw, Pin enable, - Pin d0, Pin d1, Pin d2, Pin d3, - Pin d4, Pin d5, Pin d6, Pin d7); - LiquidCrystal(Pin rs, Pin rw, Pin enable, - Pin d0, Pin d1, Pin d2, Pin d3); - LiquidCrystal(Pin rs, Pin enable, - Pin d0, Pin d1, Pin d2, Pin d3); - - void init(uint8_t fourbitmode, Pin rs, Pin rw, Pin enable, - Pin d0, Pin d1, Pin d2, Pin d3, - Pin d4, Pin d5, Pin d6, Pin d7); + LiquidCrystal(); + + void init(uint8_t fourbitmode); void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); - void clear(); + virtual void init(); + + virtual void clear(); void home(); void noDisplay(); @@ -81,28 +48,25 @@ public: void noAutoscroll(); void createChar(uint8_t, uint8_t[]); - void setCursor(uint8_t, uint8_t); - virtual void write(uint8_t); + virtual void setCursor(uint8_t, uint8_t); + virtual void write(uint8_t value) { send(value, true); } /** Added by MakerBot Industries to support storing strings in flash **/ - void writeInt(uint16_t value, uint8_t digits); + virtual void writeInt(uint16_t value, uint8_t digits); + + virtual void writeString(const char message[]); + + virtual void writeFromPgmspace(const prog_char message[]); - void writeString(char message[]); + inline void command(uint8_t value) { send(value, false); } - void writeFromPgmspace(const prog_uchar message[]); - void command(uint8_t); private: void send(uint8_t, bool); void write4bits(uint8_t); - void write8bits(uint8_t); void pulseEnable(); - Pin _rs_pin; // LOW: command. HIGH: character. - Pin _rw_pin; // LOW: write to LCD. HIGH: read from LCD. - Pin _enable_pin; // activated by a HIGH pulse. - Pin _data_pins[8]; uint8_t _displayfunction; uint8_t _displaycontrol; @@ -112,5 +76,6 @@ private: uint8_t _numlines,_currline; }; +#endif #endif // LIQUID_CRYSTAL_HH diff --git a/firmware/src/shared/Menu.cc b/firmware/src/shared/Menu.cc index 397dd19..cd96b01 100644 --- a/firmware/src/shared/Menu.cc +++ b/firmware/src/shared/Menu.cc @@ -1,8 +1,8 @@ -#include "Menu.hh" #include "Configuration.hh" // TODO: Kill this, should be hanlded by build system. #ifdef HAS_INTERFACE_BOARD +#include "Menu.hh" #include "Steppers.hh" #include "Commands.hh" @@ -69,10 +69,10 @@ bool queryExtruderParameter(uint8_t parameter, OutPacket& responsePacket) { } void SplashScreen::update(LiquidCrystal& lcd, bool forceRedraw) { - static PROGMEM prog_uchar splash1[] = " "; - static PROGMEM prog_uchar splash2[] = " Thing-O-Matic "; - static PROGMEM prog_uchar splash3[] = " --------- "; - static PROGMEM prog_uchar splash4[] = " "; + static PROGMEM prog_char splash1[] = " "; + static PROGMEM prog_char splash2[] = " Thing-O-Matic "; + static PROGMEM prog_char splash3[] = " --------- "; + static PROGMEM prog_char splash4[] = " "; if (forceRedraw) { @@ -107,13 +107,13 @@ void JogMode::reset() { } void JogMode::update(LiquidCrystal& lcd, bool forceRedraw) { - static PROGMEM prog_uchar jog1[] = "Jog mode: "; - static PROGMEM prog_uchar jog2[] = " Y+ Z+"; - static PROGMEM prog_uchar jog3[] = "X- X+ (mode)"; - static PROGMEM prog_uchar jog4[] = " Y- Z-"; + static PROGMEM prog_char jog1[] = "Jog mode: "; + static PROGMEM prog_char jog2[] = " Y+ Z+"; + static PROGMEM prog_char jog3[] = "X- X+ (mode)"; + static PROGMEM prog_char jog4[] = " Y- Z-"; - static PROGMEM prog_uchar distanceShort[] = "SHORT"; - static PROGMEM prog_uchar distanceLong[] = "LONG"; + static PROGMEM prog_char distanceShort[] = "SHORT"; + static PROGMEM prog_char distanceLong[] = "LONG"; if (forceRedraw || distanceChanged) { lcd.clear(); @@ -209,7 +209,7 @@ void JogMode::notifyButtonPressed(ButtonArray::ButtonName button) { void SnakeMode::update(LiquidCrystal& lcd, bool forceRedraw) { - static PROGMEM prog_uchar gameOver[] = "GAME OVER!"; + static PROGMEM prog_char gameOver[] = "GAME OVER!"; // If we are dead, restart the game. if (!snakeAlive) { @@ -334,8 +334,8 @@ void MonitorMode::reset() { } void MonitorMode::update(LiquidCrystal& lcd, bool forceRedraw) { - static PROGMEM prog_uchar extruder_temp[] = "Tool: ---/---C"; - static PROGMEM prog_uchar platform_temp[] = "Bed: ---/---C"; + static PROGMEM prog_char extruder_temp[] = "Tool: ---/---C"; + static PROGMEM prog_char platform_temp[] = "Bed: ---/---C"; if (forceRedraw) { lcd.clear(); @@ -431,7 +431,7 @@ void MonitorMode::notifyButtonPressed(ButtonArray::ButtonName button) { void Menu::update(LiquidCrystal& lcd, bool forceRedraw) { - static PROGMEM prog_uchar blankLine[] = " "; + static PROGMEM prog_char blankLine[] = " "; // Do we need to redraw the whole menu? if ((itemIndex/LCD_SCREEN_HEIGHT) != (lastDrawIndex/LCD_SCREEN_HEIGHT) @@ -524,9 +524,9 @@ void CancelBuildMenu::resetState() { } void CancelBuildMenu::drawItem(uint8_t index, LiquidCrystal& lcd) { - static PROGMEM prog_uchar cancel[] = "Cancel Build?"; - static PROGMEM prog_uchar yes[] = "Yes"; - static PROGMEM prog_uchar no[] = "No"; + static PROGMEM prog_char cancel[] = "Cancel Build?"; + static PROGMEM prog_char yes[] = "Yes"; + static PROGMEM prog_char no[] = "No"; switch (index) { case 0: @@ -565,10 +565,10 @@ MainMenu::MainMenu() { } void MainMenu::drawItem(uint8_t index, LiquidCrystal& lcd) { - static PROGMEM prog_uchar monitor[] = "Monitor Mode"; - static PROGMEM prog_uchar build[] = "Build from SD"; - static PROGMEM prog_uchar jog[] = "Jog Mode"; - static PROGMEM prog_uchar snake[] = "Snake Game"; + static PROGMEM prog_char monitor[] = "Monitor Mode"; + static PROGMEM prog_char build[] = "Build from SD"; + static PROGMEM prog_char jog[] = "Jog Mode"; + static PROGMEM prog_char snake[] = "Snake Game"; switch (index) { case 0: diff --git a/firmware/src/shared/PSU.cc b/firmware/src/shared/PSU.cc index 38d94c8..5496f35 100644 --- a/firmware/src/shared/PSU.cc +++ b/firmware/src/shared/PSU.cc @@ -14,20 +14,17 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see */ - +#if defined PSU_PIN #include "PSU.hh" -PSU::PSU(const Pin& psu) : - psu_pin(psu) -{ -} void PSU::init() { - psu_pin.setDirection(true); + PSU_PIN::setDirection(true); turnOn(true); } void PSU::turnOn(bool on) { // PSU pin is pulled low to turn on power supply - psu_pin.setValue(!on); + PSU_PIN::setValue(!on); } +#endif \ No newline at end of file diff --git a/firmware/src/shared/PSU.hh b/firmware/src/shared/PSU.hh index 3ac44a2..d5742a0 100644 --- a/firmware/src/shared/PSU.hh +++ b/firmware/src/shared/PSU.hh @@ -18,15 +18,13 @@ #ifndef BOARDS_RRMBV12_PSU_HH_ #define BOARDS_RRMBV12_PSU_HH_ -#include "Pin.hh" +#if defined PSU_PIN +#include "PinTmplt.hh" /// Simple wrapper class for encapsulating the PSU functionality /// \ingroup SoftwareLibraries class PSU { -private: - Pin psu_pin; ///< Power supply enable pin public: - PSU(const Pin& psu); /// Initialize the PSU void init(); @@ -35,5 +33,6 @@ public: /// \param[in] on True to turn the PSU on, False to turn it off. void turnOn(bool on); }; +#endif #endif // BOARDS_RRMBV12_PSU_HH_ diff --git a/firmware/src/shared/Pin.cc b/firmware/src/shared/Pin.cc deleted file mode 100644 index 6010a95..0000000 --- a/firmware/src/shared/Pin.cc +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pin.hh" - diff --git a/firmware/src/shared/Pin.hh b/firmware/src/shared/Pin.hh deleted file mode 100644 index 2b39db7..0000000 --- a/firmware/src/shared/Pin.hh +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef PIN_HH -#define PIN_HH - -#include "AvrPort.hh" -#include "Pin.hh" - -/// \ingroup HardwareLibraries -class Pin { -private: - AvrPort port; - uint8_t pin_index : 4; -public: - Pin() : port(AvrPort()), pin_index(0) {} - Pin(AvrPort& port_in, uint8_t pin_index_in) : port(port_in), pin_index(pin_index_in) {} - bool isNull() { return port.isNull(); } - void setDirection(bool out) { port.setPinDirection(pin_index,out); } - bool getValue() { return port.getPin(pin_index); } - void setValue(bool on) { port.setPin(pin_index,on); } - const uint8_t getPinIndex() const { return pin_index; } -}; - -#endif // PIN_HH diff --git a/firmware/src/shared/PinTmplt.hh b/firmware/src/shared/PinTmplt.hh new file mode 100644 index 0000000..4ecf1f3 --- /dev/null +++ b/firmware/src/shared/PinTmplt.hh @@ -0,0 +1,111 @@ +/* + * Copyright 2012 by Craig Link + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +#ifndef PIN_TMPLT_HH_ +#define PIN_TMPLT_HH_ + +#include +#include + +// The AVR port and pin mapping is based on a convention that has held true for all ATMega chips +// released so far: that the ports begin in sequence from register 0x00 from A onwards, and are +// arranged: +// 0 PINx +// 1 DDRx +// 2 PORTx +// This is verified true for the 168/328/644p/1280/2560. + +// We support three platforms: Atmega168 (1 UART), Atmega644, and Atmega1280/2560 +#if defined (__AVR_ATmega168__) \ + || defined (__AVR_ATmega328__) \ + || defined (__AVR_ATmega644P__) \ + || defined (__AVR_ATmega1280__) \ + || defined (__AVR_ATmega2560__) +#else + #error UART not implemented on this processor type! +#endif + +// The AVR port and pin mapping is based on a convention that has held true for all ATMega chips +// released so far: that the ports begin in sequence from register 0x00 from A onwards, and are +// arranged: +// 0 PINx +// 1 DDRx +// 2 PORTx +// This is verified true for the 168/644p/1280. + +#define PINx _SFR_MEM8(port_base+0) +#define DDRx _SFR_MEM8(port_base+1) +#define PORTx _SFR_MEM8(port_base+2) + + +template < uint16_t port_base, uint8_t pin_index > class PinTmplt { +public: + + static inline void setDirection(bool output, bool atomic = true) + { + if( (port_base < 0x40) || !atomic) + { + output ? DDRx |= _BV(pin_index) : DDRx &= ~_BV(pin_index); + } + else + { + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + output ? DDRx |= _BV(pin_index) : DDRx &= ~_BV(pin_index); + } + } + } + static inline void setValue(bool on, bool atomic = true) + { + if((port_base < 0x40) || !atomic ) + { + on ? PORTx |= _BV(pin_index) : PORTx &= ~_BV(pin_index); + } + else + { + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + on ? PORTx |= _BV(pin_index) : PORTx &= ~_BV(pin_index); + } + } + } + + static inline bool getValue() { return !!(PINx & _BV(pin_index)); } +}; + +#define Pin(port_id,pin_id) PinTmplt + + +#if defined(__AVR_ATmega644P__) || \ + defined(__AVR_ATmega1280__) || \ + defined(__AVR_ATmega2560__) +const uint8_t PortA = 0x20; +#endif // __AVR_ATmega644P__ +const uint8_t PortB = 0x23; +const uint8_t PortC = 0x26; +const uint8_t PortD = 0x29; +#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) +const uint8_t PortE = 0x2C; +const uint8_t PortF = 0x2F; +const uint8_t PortG = 0x32; +const uint16_t PortH = 0x100; +const uint16_t PortJ = 0x103; +const uint16_t PortK = 0x106; +const uint16_t PortL = 0x109; +#endif //__AVR_ATmega1280__ +#endif // SHARED_AVR_PORT_HH_ + diff --git a/firmware/src/shared/StepperAxis.cc b/firmware/src/shared/StepperAxis.cc index c69bce1..11fdfb5 100644 --- a/firmware/src/shared/StepperAxis.cc +++ b/firmware/src/shared/StepperAxis.cc @@ -1,11 +1,12 @@ #include "StepperAxis.hh" +#if STEPPER_COUNT > 0 StepperAxis::StepperAxis() : interface(0) { } -StepperAxis::StepperAxis(StepperInterface& stepper_interface) : - interface(&stepper_interface) { +StepperAxis::StepperAxis(const StepperInterface* stepper_interface) : + interface(stepper_interface) { reset(); } @@ -138,3 +139,4 @@ bool StepperAxis::doHoming(const int32_t intervals) { } return true; } +#endif \ No newline at end of file diff --git a/firmware/src/shared/StepperAxis.hh b/firmware/src/shared/StepperAxis.hh index 6d13ef7..08e715f 100644 --- a/firmware/src/shared/StepperAxis.hh +++ b/firmware/src/shared/StepperAxis.hh @@ -1,9 +1,11 @@ #ifndef STEPPERAXIS_HH #define STEPPERAXIS_HH -#include "StepperInterface.hh" #include "Configuration.hh" +#if STEPPER_COUNT > 0 +#include "StepperInterface.hh" + /// The stepper axis module implements a driver for a single stepper axis. It is designed /// to be accessed via the Steppers namespace, and uses a StepperInterface to talk to the /// actual hardware. @@ -11,7 +13,7 @@ class StepperAxis { public: - StepperInterface* interface; ///< Interface this axis is connected to + const StepperInterface* interface; ///< Interface this axis is connected to volatile int32_t position; ///< Current position of this axis, in steps int32_t minimum; ///< Minimum position, in steps int32_t maximum; ///< Maximum position, in steps @@ -50,7 +52,7 @@ public: /// Construct a stepper axis, using the given stepper /// interface /// \param[in] Stepper interface to use - StepperAxis(StepperInterface& stepper_interface); + StepperAxis(const StepperInterface* stepper_interface); /// Set the target position for the axis to travel to. /// \param[in] target_in Postion to move to, in steps @@ -82,5 +84,5 @@ public: /// \return True if the axis is still homing. bool doHoming(const int32_t intervals); }; - +#endif #endif // STEPPERAXIS_HH diff --git a/firmware/src/shared/StepperInterface.cc b/firmware/src/shared/StepperInterface.cc index e769225..f021fae 100644 --- a/firmware/src/shared/StepperInterface.cc +++ b/firmware/src/shared/StepperInterface.cc @@ -1,3 +1,4 @@ +#if 0 /* * Copyright 2010 by Adam Mayer * @@ -88,3 +89,4 @@ void StepperInterface::init(uint8_t idx) { min_pin.setValue(invert_endstops); } } +#endif \ No newline at end of file diff --git a/firmware/src/shared/StepperInterface.hh b/firmware/src/shared/StepperInterface.hh index f22aa44..d1a44a1 100644 --- a/firmware/src/shared/StepperInterface.hh +++ b/firmware/src/shared/StepperInterface.hh @@ -1,5 +1,5 @@ /* - * Copyright 2010 by Adam Mayer + * Copyright 2011 by Craig Link craig@moonrock.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,63 +18,128 @@ #ifndef STEPPERINTERFACE_HH_ #define STEPPERINTERFACE_HH_ -#include +#include +#include "Eeprom.hh" +#include "EepromMap.hh" +#include "Configuration.hh" -/// The StepperInterface module represents a connection to a single stepper controller. -/// \ingroup SoftwareLibraries +/// StepperInterface instances encapsulate the low-level communication +/// with a stepper board. class StepperInterface { -private: - /// Default constructor - StepperInterface() {} - StepperInterface(const Pin& dir, - const Pin& step, - const Pin& enable, - const Pin& max, - const Pin& min, - uint16_t eeprom_base_in); +public: + /// Set the direction for the stepper to move + virtual void setDirection(bool forward) const = 0; + + /// Set the value of the step line + virtual void step(bool value) const = 0; + + /// Enable or disable this axis + virtual void setEnabled(bool enabled) const = 0; + + /// True if the axis has triggered its maximum endstop + virtual bool isAtMaximum() const = 0; + /// True if the axis has triggered its minimum endstop + virtual bool isAtMinimum() const = 0; + +}; + +template < uint8_t offset, class dir_pin, class step_pin, class enable_pin > class StepperTmplt : public StepperInterface { + +public: + + /// Set the direction for the stepper to move + virtual void setDirection(bool forward) const { dir_pin::setValue(invert_axis ? !forward : forward, false); } + + /// Set the value of the step line + virtual void step(bool value) const {step_pin::setValue(value, false);} - friend class Motherboard; + /// Enable or disable this axis + virtual void setEnabled(bool enabled) const + { + // The A3982 stepper driver chip has an inverted enable. + enable_pin::setValue(!enabled, false); + } -private: - /// Initialize the pins for the interface - /// \param[in] idx Stepper index that this interface refers to (used to look up - /// it's settings in the EEPROM) - void init(uint8_t idx); + /// True if the axis has triggered its maximum endstop + virtual bool isAtMaximum() const + { + return false; + } + /// True if the axis has triggered its minimum endstop + virtual bool isAtMinimum() const + { + return false; + } +protected: - Pin dir_pin; ///< Pin (output) that the direction line is connected to - Pin step_pin; ///< Pin (output) that the step line is connected to - Pin enable_pin; ///< Pin (output) that the enable line is connected to - Pin max_pin; ///< Pin (input) that the maximum endstop is connected to. - Pin min_pin; ///< Pin (input) that the minimum endstop is connected to. - bool invert_endstops; ///< True if endstops input polarity is inverted for - ///< this axis. - bool invert_axis; ///< True if motions for this axis should be inverted + friend class Motherboard; - uint16_t eeprom_base; ///< Base address to read EEPROM configuration from + bool invert_axis; + /// Default constructor + //StepperInterface() {} + StepperTmplt() : invert_axis(false) {} + + void init() + { + dir_pin::setDirection(true); + step_pin::setDirection(true); + enable_pin::setDirection(true); + + enable_pin::setValue(true); + // get inversion characteristics + uint8_t axes_invert = eeprom::getEeprom8(eeprom::AXIS_INVERSION, 1<<1); + invert_axis = (axes_invert & (1< class StepperTmpltEndstops + : public StepperTmplt< offset, dir_pin, step_pin, enable_pin > +{ public: - /// Set the direction for the stepper to move - /// \param[in] forward True to move the stepper forward, false otherwise. - void setDirection(bool forward); - /// Set the value of the step line - /// \param[in] value True to enable, false to disable. This should be toggled - /// back and fourth to effect stepping. - void step(bool value); + /// True if the axis has triggered its maximum endstop + virtual bool isAtMaximum() const + { + bool v = max_pin::getValue(); + if (invert_endstops) v = !v; + return v; + } + /// True if the axis has triggered its minimum endstop + virtual bool isAtMinimum() const + { + bool v = min_pin::getValue(); + if (invert_endstops) v = !v; + return v; + } + +protected: + + friend class Motherboard; + + bool invert_endstops; + + StepperTmpltEndstops() : invert_endstops(true) {} + + void init() + { + StepperTmplt< offset, dir_pin, step_pin, enable_pin >::init(); + uint8_t endstops_invert = eeprom::getEeprom8(eeprom::ENDSTOP_INVERSION, 0); + bool endstops_present = (endstops_invert & (1<<7)) != 0; + // If endstops are not present, then we consider them inverted, since they will + // always register as high (pulled up). + invert_endstops = !endstops_present || ((endstops_invert & (1< 0 // We'll throw in nops to get the timing right (if necessary) inline void nop() { @@ -29,18 +30,15 @@ inline void nop() { asm volatile("nop"::); } +#define cs_pin THERMOCOUPLE_CS ///< Chip select pin (output) +#define sck_pin THERMOCOUPLE_SCK ///< Clock pin (output) +#define so_pin THERMOCOUPLE_SO ///< Data pin (input) -Thermocouple::Thermocouple(const Pin& cs,const Pin& sck,const Pin& so) : - cs_pin(cs), - sck_pin(sck), - so_pin(so) -{ -} void Thermocouple::init() { - cs_pin.setDirection(true); - sck_pin.setDirection(true); - so_pin.setDirection(false); + cs_pin::setDirection(true); + sck_pin::setDirection(true); + so_pin::setDirection(false); // cs_pin.setValue(true); // Clock select is active low // sck_pin.setValue(false); // TODO: Is this a good idea? @@ -49,33 +47,35 @@ void Thermocouple::init() { Thermocouple::SensorState Thermocouple::update() { // TODO: Check timing against datasheet. - cs_pin.setValue(false); + cs_pin::setValue(false); nop(); - sck_pin.setValue(false); + sck_pin::setValue(false); nop(); int raw = 0; for (int i = 0; i < 16; i++) { - sck_pin.setValue(true); + sck_pin::setValue(true); nop(); if (i >= 1 && i < 11) { // data bit... skip LSBs raw = raw << 1; - if (so_pin.getValue()) { raw = raw | 0x01; } + if (so_pin::getValue()) { raw = raw | 0x01; } } if (i == 13) { // Safety check: Check for open thermocouple input - if (so_pin.getValue()) { + if (so_pin::getValue()) { current_temp = BAD_TEMPERATURE; // Set the temperature to 1024 as an error condition return SS_ERROR_UNPLUGGED; } } - sck_pin.setValue(false); + sck_pin::setValue(false); nop(); } - cs_pin.setValue(true); + cs_pin::setValue(true); nop(); - sck_pin.setValue(false); + sck_pin::setValue(false); current_temp = raw; return SS_OK; } + +#endif \ No newline at end of file diff --git a/firmware/src/shared/Thermocouple.hh b/firmware/src/shared/Thermocouple.hh index efc19c3..6ebd548 100644 --- a/firmware/src/shared/Thermocouple.hh +++ b/firmware/src/shared/Thermocouple.hh @@ -18,26 +18,24 @@ #ifndef THERMOCOUPLE_HH_ #define THERMOCOUPLE_HH_ + +#if HAS_THERMOCOUPLE > 0 #include "TemperatureSensor.hh" -#include "Pin.hh" +#include "PinTmplt.hh" /// The thermocouple module provides a bitbanging driver that can read the /// temperature from (chip name) sensor, and also report on any error conditions. /// \ingroup SoftwareLibraries class Thermocouple : public TemperatureSensor { -private: - Pin cs_pin; ///< Chip select pin (output) - Pin sck_pin; ///< Clock pin (output) - Pin so_pin; ///< Data pin (input) public: /// Create a new thermocouple instance, and attach it to the given pins. /// \param [in] cs Chip Select (output). /// \param [in] sck Clock Pin (output). Can be shared with other thermocouples. /// \param [in] so Data Pin (input) - Thermocouple(const Pin& cs,const Pin& sck,const Pin& so); - void init(); + virtual void init(); - SensorState update(); + virtual SensorState update(); }; +#endif #endif // THERMOCOUPLE_HH_ diff --git a/firmware/src/shared/UART.cc b/firmware/src/shared/UART.cc index a53f9c2..db3c7b3 100644 --- a/firmware/src/shared/UART.cc +++ b/firmware/src/shared/UART.cc @@ -17,7 +17,7 @@ #include "UART.hh" -#include "Pin.hh" +#include "PinTmplt.hh" #include #include #include @@ -151,13 +151,13 @@ void UART::send_byte(char data) { // Transition to a non-transmitting state. This is only used for RS485 mode. inline void listen() { -// TX_ENABLE_PIN.setValue(false); - TX_ENABLE_PIN.setValue(false); +// TX_ENABLE_PIN::setValue(false); + TX_ENABLE_PIN::setValue(false); } // Transition to a transmitting state inline void speak() { - TX_ENABLE_PIN.setValue(true); + TX_ENABLE_PIN::setValue(true); } UART::UART(uint8_t index, communication_mode mode) : @@ -197,9 +197,9 @@ void UART::enable(bool enabled) { if (mode_ == RS485) { // If this is an RS485 pin, set up the RX and TX enable control lines. - TX_ENABLE_PIN.setDirection(true); - RX_ENABLE_PIN.setDirection(true); - RX_ENABLE_PIN.setValue(false); // Active low + TX_ENABLE_PIN::setDirection(true); + RX_ENABLE_PIN::setDirection(true); + RX_ENABLE_PIN::setValue(false); // Active low listen(); loopback_bytes = 0; From acb4c13859abba4a26a9a08f3e2883f7810f17d2 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 16 Nov 2011 22:09:12 -0800 Subject: [PATCH 02/39] remove bogus const's on integral return types --- firmware/src/shared/CircularBuffer.hh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/firmware/src/shared/CircularBuffer.hh b/firmware/src/shared/CircularBuffer.hh index a27cd7b..4da9a7a 100644 --- a/firmware/src/shared/CircularBuffer.hh +++ b/firmware/src/shared/CircularBuffer.hh @@ -87,17 +87,17 @@ public: } /// Get the length of the buffer - inline const BufSizeType getLength() const { + inline BufSizeType getLength() const { return length; } /// Get the remaining capacity of this buffer - inline const BufSizeType getRemainingCapacity() const { + inline BufSizeType getRemainingCapacity() const { return size - length; } /// Check if the buffer is empty - inline const bool isEmpty() const { + inline bool isEmpty() const { return length == 0; } /// Read the buffer directly @@ -106,11 +106,11 @@ public: return data[actual_index]; } /// Check the overflow flag - inline const bool hasOverflow() const { + inline bool hasOverflow() const { return overflow; } /// Check the underflow flag - inline const bool hasUnderflow() const { + inline bool hasUnderflow() const { return underflow; } }; From 4377f1399fa45bada2e60f2cc1548c932158879b Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 16 Nov 2011 22:10:49 -0800 Subject: [PATCH 03/39] remove bogus const --- firmware/src/shared/PID.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/src/shared/PID.hh b/firmware/src/shared/PID.hh index 58049bf..f2d4d6b 100644 --- a/firmware/src/shared/PID.hh +++ b/firmware/src/shared/PID.hh @@ -70,7 +70,7 @@ public: /// Get the current PID target /// \return Current setpoint - const int getTarget() const { return sp; } + int getTarget() const { return sp; } /// Reset the PID to board-on values void reset(); From 8fa9ae3e68f6cdf7e458398845e0e0a109d52c8c Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 16 Nov 2011 22:30:36 -0800 Subject: [PATCH 04/39] clean up some atomic block code --- firmware/src/Extruder/Main.cc | 16 +++++----- .../Extruder/boards/ecv34/ExtruderBoard.cc | 4 +-- .../Extruder/boards/ecv34/ExtruderMotor.cc | 6 ++-- firmware/src/Motherboard/Main.cc | 32 ++++++++++--------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/firmware/src/Extruder/Main.cc b/firmware/src/Extruder/Main.cc index de5bb4a..f8df4ac 100644 --- a/firmware/src/Extruder/Main.cc +++ b/firmware/src/Extruder/Main.cc @@ -28,16 +28,16 @@ #include "MotorController.hh" void reset() { - cli(); + ATOMIC_BLOCK(ATOMIC_FORCEON) { - uint8_t resetFlags = MCUSR & 0x0f; - MCUSR = 0x0; + uint8_t resetFlags = MCUSR & 0x0f; + MCUSR = 0x0; - // Intialize various modules - initThermistorTables(); - eeprom::init(); - ExtruderBoard::getBoard().reset(resetFlags); - sei(); + // Intialize various modules + initThermistorTables(); + eeprom::init(); + ExtruderBoard::getBoard().reset(resetFlags); + } } int main() { diff --git a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc index 20762f7..c15de7c 100644 --- a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc +++ b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc @@ -33,13 +33,11 @@ ExtruderBoard ExtruderBoard::extruder_board; ExtruderBoard::ExtruderBoard() : micros(0L), - extruder_thermocouple(),//THERMOCOUPLE_CS,THERMOCOUPLE_SCK,THERMOCOUPLE_SO), + extruder_thermocouple(), platform_thermistor(PLATFORM_PIN,1), extruder_heater(extruder_thermocouple,extruder_element,SAMPLE_INTERVAL_MICROS_THERMOCOUPLE,eeprom::EXTRUDER_PID_BASE), platform_heater(platform_thermistor,platform_element,SAMPLE_INTERVAL_MICROS_THERMISTOR,eeprom::HBP_PID_BASE), using_platform(true), - //servoA(SERVO0), - //servoB(SERVO1), coolingFan(extruder_heater, eeprom::COOLING_FAN_BASE) { } diff --git a/firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc b/firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc index e34b1a3..ae85fca 100644 --- a/firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc +++ b/firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc @@ -48,12 +48,12 @@ void setExtruderMotor(int16_t speed) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { if (speed == 0 || speed == 255) { TCCR0A &= 0b11001111; - MOTOR_ENABLE_PIN::setValue(speed==255); + MOTOR_ENABLE_PIN::setValue(speed==255,false); } else { - MOTOR_ENABLE_PIN::setValue(true); + MOTOR_ENABLE_PIN::setValue(true,false); TCCR0A |= 0b00100000; } - MOTOR_DIR_PIN::setValue(!backwards); + MOTOR_DIR_PIN::setValue(!backwards,false); OCR0B = speed; } } diff --git a/firmware/src/Motherboard/Main.cc b/firmware/src/Motherboard/Main.cc index 147c157..6fb7001 100644 --- a/firmware/src/Motherboard/Main.cc +++ b/firmware/src/Motherboard/Main.cc @@ -37,21 +37,24 @@ void reset(bool hard_reset) { command::reset(); eeprom::init(); board.reset(); - sei(); - // If we've just come from a hard reset, wait for 2.5 seconds before - // trying to ping an extruder. This gives the extruder time to boot - // before we send it a packet. - if (hard_reset) { - Timeout t; - t.start(1000L*2500L); // wait for 2500 ms - while (!t.hasElapsed()); - tool::test(); // Run test - } - if (!tool::reset()) - { - // Fail, but let it go; toggling the PSU is dangerous. - } + } + + // If we've just come from a hard reset, wait for 2.5 seconds before + // trying to ping an extruder. This gives the extruder time to boot + // before we send it a packet. + if (hard_reset) { + Timeout t; + t.start(1000L*2500L); // wait for 2500 ms + while (!t.hasElapsed()); + tool::test(); // Run test } + + ATOMIC_BLOCK(ATOMIC_FORCEON) { + if (!tool::reset()) + { + // Fail, but let it go; toggling the PSU is dangerous. + } + } } int main() { @@ -59,7 +62,6 @@ int main() { Motherboard& board = Motherboard::getBoard(); steppers::init(Motherboard::getBoard()); reset(true); - sei(); while (1) { // Toolhead interaction thread. tool::runToolSlice(); From 244912f951082bed292cb74a8e11db22db3fe835 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 16 Nov 2011 22:30:47 -0800 Subject: [PATCH 05/39] delete softwareservo.cc --- G3Firmware.sln | 1 - .../Extruder/boards/ecv34/SoftwareServo.cc | 31 ------------------- 2 files changed, 32 deletions(-) delete mode 100644 firmware/src/Extruder/boards/ecv34/SoftwareServo.cc diff --git a/G3Firmware.sln b/G3Firmware.sln index 0068a78..ad9bb00 100644 --- a/G3Firmware.sln +++ b/G3Firmware.sln @@ -145,7 +145,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ecv34", "ecv34", "{489403D6 firmware\src\Extruder\boards\ecv34\ExtruderBoard.hh = firmware\src\Extruder\boards\ecv34\ExtruderBoard.hh firmware\src\Extruder\boards\ecv34\ExtruderMotor.cc = firmware\src\Extruder\boards\ecv34\ExtruderMotor.cc firmware\src\Extruder\boards\ecv34\ExtruderMotor.hh = firmware\src\Extruder\boards\ecv34\ExtruderMotor.hh - firmware\src\Extruder\boards\ecv34\SoftwareServo.cc = firmware\src\Extruder\boards\ecv34\SoftwareServo.cc firmware\src\Extruder\boards\ecv34\SoftwareServo.hh = firmware\src\Extruder\boards\ecv34\SoftwareServo.hh EndProjectSection EndProject diff --git a/firmware/src/Extruder/boards/ecv34/SoftwareServo.cc b/firmware/src/Extruder/boards/ecv34/SoftwareServo.cc deleted file mode 100644 index f3c367c..0000000 --- a/firmware/src/Extruder/boards/ecv34/SoftwareServo.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* -#include "SoftwareServo.hh" - -SoftwareServo::SoftwareServo(Pin pin) : - pin(pin) -{ - pin.setDirection(true); - pin.setValue(false); -} - -void SoftwareServo::setPosition(uint8_t position) { - // Program the timer match value so that we generate a pulse width per: - // http://www.servocity.com/html/hs-311_standard.html - // 600us + (value * 10) - // so 0deg = 600us, 90deg = 1500us, 180deg = 2400us - if (position > 180) { - position = 180; - } - - counts = 600 + 10*position; -} - -void SoftwareServo::enable() { - enabled = true; -} - -void SoftwareServo::disable() { - enabled = false; - pin.setValue(false); -} -*/ \ No newline at end of file From a9cbd7b4adb9e65f4aaa0dfce2257a0843c17021 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 16 Nov 2011 22:31:10 -0800 Subject: [PATCH 06/39] add class for dual displays and modtronix --- firmware/src/shared/DualDisplay.cc | 48 +++ firmware/src/shared/DualDisplay.hh | 31 ++ firmware/src/shared/ModtronixLCD2S.cc | 560 ++++++++++++++++++++++++++ firmware/src/shared/ModtronixLCD2S.hh | 99 +++++ 4 files changed, 738 insertions(+) create mode 100644 firmware/src/shared/DualDisplay.cc create mode 100644 firmware/src/shared/DualDisplay.hh create mode 100644 firmware/src/shared/ModtronixLCD2S.cc create mode 100644 firmware/src/shared/ModtronixLCD2S.hh diff --git a/firmware/src/shared/DualDisplay.cc b/firmware/src/shared/DualDisplay.cc new file mode 100644 index 0000000..46feb9b --- /dev/null +++ b/firmware/src/shared/DualDisplay.cc @@ -0,0 +1,48 @@ +#include "DualDisplay.hh" + +#include +#include +#include + +void DualDisplay::init() +{ + lcd.init(); + lcd2s.init(); + clear(); +} + +/********** high level commands, for the user! */ +void DualDisplay::clear() +{ + lcd.clear(); + lcd2s.clear(); +} + + +void DualDisplay::setCursor(uint8_t col, uint8_t row) +{ + lcd.setCursor(col,row); + lcd2s.setCursor(col,row); +} + +void DualDisplay::write(uint8_t c) { + lcd.write(c); + lcd2s.write(c); +} + + +void DualDisplay::writeInt(uint16_t value, uint8_t digits) { + lcd.writeInt(value, digits); + lcd2s.writeInt(value, digits); +} + +void DualDisplay::writeString(const char message[]) { + lcd.writeString(message); + lcd2s.writeString(message); +} + +void DualDisplay::writeFromPgmspace(const prog_char message[]) { + lcd.writeFromPgmspace(message); + lcd2s.writeFromPgmspace(message); +} + diff --git a/firmware/src/shared/DualDisplay.hh b/firmware/src/shared/DualDisplay.hh new file mode 100644 index 0000000..8a72588 --- /dev/null +++ b/firmware/src/shared/DualDisplay.hh @@ -0,0 +1,31 @@ +#ifndef DUALDISPLAY_HH +#define DUALDISPLAY_HH + +// TODO: Proper attribution + +#include +#include +#include "AvrPort.hh" +#include "Display.hh" +#include "LiquidCrystal.hh" +#include "ModtronixLCD2S.hh" + +class DualDisplay : public Display { +public: + DualDisplay() {} + virtual void init(); + virtual void clear(); + virtual void setCursor(uint8_t col, uint8_t row); + virtual void write(uint8_t); + + virtual void writeInt(uint16_t value, uint8_t digits); + virtual void writeString(const char message[]); + virtual void writeFromPgmspace(const prog_char message[]); + +private: + Display lcd; // provide a NULL display +// LiquidCrystal lcd; + ModtronixLCD2S lcd2s; +}; + +#endif // DUALDISPLAY_HH diff --git a/firmware/src/shared/ModtronixLCD2S.cc b/firmware/src/shared/ModtronixLCD2S.cc new file mode 100644 index 0000000..4673ed4 --- /dev/null +++ b/firmware/src/shared/ModtronixLCD2S.cc @@ -0,0 +1,560 @@ +#include +#include "ModtronixLCD2S.hh" +#include "twi.h" + + +static int i2c_write(uint8_t address, uint8_t cmd, uint8_t* data, uint8_t len) +{ + twi_data bufs[] = { {0, 1, &cmd}, {0, len, data} }; + return twi_writeTo_buffers(address, bufs, 2, 0 ); +} + + + +static int i2c_write_P(uint8_t address, uint8_t cmd, PGM_P data, uint8_t len) +{ + twi_data bufs[] = { {0, 1, &cmd}, {1, len, (const uint8_t*) data} }; + return twi_writeTo_buffers(address, bufs, 2, 0 ); +} + + + +static int i2c_cmd_read(uint8_t address, uint8_t cmd, uint8_t* data, uint8_t expectedlen) +{ +// return asynctwi::write_and_read_async(address, &cmd, 1, data, expectedlen, NULL); + return 0; +} + + +/* +static int i2c_cmd_read_async(uint8_t address, uint8_t cmd, uint8_t expectedlen, asynctwi::callback_t cb) +{ + return asynctwi::write_and_read_async(address, &cmd, 1, NULL, expectedlen, cb); +} + +*/ + + +ModtronixLCD2S::ModtronixLCD2S(uint8_t addr) +{ + address = addr; + charset = 255; +} + +void ModtronixLCD2S::init() +{ + twi_init(); + //write_string("\fhello\nZeus"); +} + +void ModtronixLCD2S::remember() +{ + i2c_write(address, 0x8D, NULL, 0); +} + + + +int8_t ModtronixLCD2S::read_status() +{ + uint8_t val = 0; + int8_t len = i2c_cmd_read(address, 0xD0, &val, 1); + if (len == -1) { + return -1; + } + return val; +} + + +/* +void ModtronixLCD2S::read_status_async(asynctwi::callback_t cb) +{ + i2c_cmd_read_async(address, 0xD0, 1, cb); +} +*/ + + + +char ModtronixLCD2S::read_keypad_data() +{ + uint8_t data[2]; + i2c_cmd_read(address, 0xD1, data, 1); + return (char)(data[0]); +} + + +/* +void ModtronixLCD2S::read_keypad_data_async(asynctwi::callback_t cb) +{ + i2c_cmd_read_async(address, 0xD1, 1, cb); +} +*/ + + + +uint8_t ModtronixLCD2S::read_gpio123() +{ + uint8_t val = 0; + i2c_cmd_read(address, 0xD3, &val, 1); + return val; +} + + +/* +void ModtronixLCD2S::read_gpio123_async(asynctwi::callback_t cb) +{ + i2c_cmd_read_async(address, 0xD3, 1, cb); +} +*/ + + + + + +void ModtronixLCD2S::config(uint8_t display, uint8_t contrast, uint8_t brightness, uint8_t keypadio, uint8_t keypadbuzz) +{ + uint8_t data[4]; + data[0] = display; + data[1] = ((brightness & 0x3) << 6) | (contrast & 0x3f); + data[2] = keypadio; + data[3] = keypadbuzz; + i2c_write(address, 0xD0, data, 4); +} + + + +void ModtronixLCD2S::set_base_address(uint8_t addr) { + remember(); + i2c_write(address, 0x91, &addr, 1); +} + + + +void ModtronixLCD2S::write_decimal(int16_t val, int8_t wid, uint8_t decdigits) { + char buf[10]; + char* ptr = buf; + char* ptr2; + bool force = false; + if (val < 0) { + val = -val; + *ptr++ = '-'; + } + if (decdigits == 5) { + *ptr++ = '0'; + *ptr++ = '.'; + force = true; + } + if (force || val >= 10000) { + *ptr++ = '0'+(val/10000); + val = val % 10000; + force = true; + } + if (decdigits == 4) { + if (ptr == buf) { + *ptr++ = '0'; + } + *ptr++ = '.'; + force = true; + } + if (force || val >= 1000) { + *ptr++ = '0'+(val/1000); + val = val % 1000; + force = true; + } + if (decdigits == 3) { + if (ptr == buf) { + *ptr++ = '0'; + } + *ptr++ = '.'; + force = true; + } + if (force || val >= 100) { + *ptr++ = '0'+(val/100); + val = val % 100; + force = true; + } + if (decdigits == 2) { + if (ptr == buf) { + *ptr++ = '0'; + } + *ptr++ = '.'; + force = true; + } + if (force || val >= 10) { + *ptr++ = '0'+(val/10); + val = val % 10; + } + if (decdigits == 1) { + if (ptr == buf) { + *ptr++ = '0'; + } + *ptr++ = '.'; + } + *ptr++ = '0'+val; + *ptr = '\0'; + if (ptr-buf < wid) { + ptr2 = buf+wid; + while (ptr >= buf) { + *ptr2-- = *ptr--; + } + while (ptr2 >= buf) { + *ptr2-- = ' '; + } + } + i2c_write(address, 0x80, (uint8_t*)buf, strlen(buf)); +} + +void ModtronixLCD2S::writeInt(uint16_t value, uint8_t digits) { + char buf[digits]; + + uint16_t currentDigit; + uint16_t nextDigit; + + switch (digits) { + case 1: currentDigit = 10; break; + case 2: currentDigit = 100; break; + case 3: currentDigit = 1000; break; + case 4: currentDigit = 10000; break; + default: return; + } + + uint8_t i; + for (i = 0; i < digits; i++) { + nextDigit = currentDigit/10; + buf[i] = (value%currentDigit)/nextDigit+'0'; + currentDigit = nextDigit; + } + + i2c_write(address, 0x80, (uint8_t*)buf, i); +} + + +void ModtronixLCD2S::write_string(const char* str) { + i2c_write(address, 0x80, (uint8_t*)str, strlen(str)); +} + + + +void ModtronixLCD2S::write_string_P(PGM_P pstr) { + i2c_write_P(address, 0x80, pstr, strlen_P(pstr)); +} + + + +void ModtronixLCD2S::set_startup_line(uint8_t row, const char* str) { + uint8_t buf[22]; + buf[0] = row; + strcpy((char*)buf+1,str); + i2c_write(address, 0x90, buf, strlen(str)+1); +} + + + +void ModtronixLCD2S::write_char(char ch) { + uint8_t buf[2]; + buf[0] = ch; + buf[1] = '\0'; + i2c_write(address, 0x80, buf, 1); +} + + + +void ModtronixLCD2S::backlight_on() { + i2c_write(address, 0x28, NULL, 0); +} + + + +void ModtronixLCD2S::backlight_off() { + i2c_write(address, 0x20, NULL, 0); +} + + + +void ModtronixLCD2S::backlight_brightness(uint8_t val) { + i2c_write(address, 0x81, &val, 1); +} + + + +void ModtronixLCD2S::set_contrast(uint8_t val) { + i2c_write(address, 0x82, &val, 1); +} + + + +void ModtronixLCD2S::dir_forward() { + i2c_write(address, 0x09, NULL, 0); +} + + + +void ModtronixLCD2S::dir_backwards() { + i2c_write(address, 0x01, NULL, 0); +} + + + +void ModtronixLCD2S::display_on() { + i2c_write(address, 0x1A, NULL, 0); +} + + + +void ModtronixLCD2S::display_off() { + i2c_write(address, 0x12, NULL, 0); +} + + + +void ModtronixLCD2S::cursor_underline_on() { + i2c_write(address, 0x19, NULL, 0); +} + + + +void ModtronixLCD2S::cursor_underline_off() { + i2c_write(address, 0x11, NULL, 0); +} + + + +void ModtronixLCD2S::cursor_block_on() { + i2c_write(address, 0x18, NULL, 0); +} + + + +void ModtronixLCD2S::cursor_block_off() { + i2c_write(address, 0x10, NULL, 0); +} + + + +void ModtronixLCD2S::shift_right() { + i2c_write(address, 0x85, NULL, 0); +} + + + +void ModtronixLCD2S::shift_left() { + i2c_write(address, 0x86, NULL, 0); +} + + + +void ModtronixLCD2S::shift_up() { + i2c_write(address, 0x87, NULL, 0); +} + + + +void ModtronixLCD2S::shift_down() { + i2c_write(address, 0x88, NULL, 0); +} + + + +void ModtronixLCD2S::home() { + i2c_write(address, 0x8B, NULL, 0); +} + + + +void ModtronixLCD2S::clear() { + i2c_write(address, 0x8C, NULL, 0); +} + + + +void ModtronixLCD2S::load_charset(uint8_t val) { + if (val != charset) { + i2c_write(address, 0x8E, &val, 1); + charset = val; + } +} + + + +void ModtronixLCD2S::set_position(uint8_t row, uint8_t col) { + uint8_t data[2]; + data[0] = row; + data[1] = col; + i2c_write(address, 0x8A, data, 2); +} + + +void ModtronixLCD2S::interrupt_open_collection() { + i2c_write(address, 0x2A, NULL, 0); +} + + +void ModtronixLCD2S::interrupt_push_pull() { + i2c_write(address, 0x22, NULL, 0); +} + + +void ModtronixLCD2S::out1_on() { + i2c_write(address, 0x38, NULL, 0); +} + + + +void ModtronixLCD2S::out1_off() { + i2c_write(address, 0x30, NULL, 0); +} + + + +void ModtronixLCD2S::out2_on() { + i2c_write(address, 0x39, NULL, 0); +} + + + +void ModtronixLCD2S::out2_off() { + i2c_write(address, 0x31, NULL, 0); +} + + + +void ModtronixLCD2S::gpio1_on() { + i2c_write(address, 0x48, NULL, 0); +} + + + +void ModtronixLCD2S::gpio1_off() { + i2c_write(address, 0x40, NULL, 0); +} + + + +void ModtronixLCD2S::gpio2_on() { + i2c_write(address, 0x49, NULL, 0); +} + + + +void ModtronixLCD2S::gpio2_off() { + i2c_write(address, 0x41, NULL, 0); +} + + + +void ModtronixLCD2S::config_keypad_and_io(uint8_t val) { + remember(); + i2c_write(address, 0xE0, &val, 1); +} + + + +void ModtronixLCD2S::config_gpio1(uint8_t val) { + remember(); + i2c_write(address, 0xE3, &val, 1); +} + + + +void ModtronixLCD2S::config_gpio2(uint8_t val) { + remember(); + i2c_write(address, 0xE4, &val, 1); +} + + + +void ModtronixLCD2S::config_gpio3(uint8_t val) { + remember(); + i2c_write(address, 0xE5, &val, 1); +} + + + +void ModtronixLCD2S::set_max_backlight_brightness(uint8_t val) { + remember(); + i2c_write(address, 0xA3, &val, 1); +} + + + +void ModtronixLCD2S::set_keypad_debounce_time(uint8_t val) { + remember(); + i2c_write(address, 0xE1, &val, 1); +} + + + +void ModtronixLCD2S::set_keypad_repeat_delay(uint8_t val) { + remember(); + i2c_write(address, 0xA0, &val, 1); +} + + + +void ModtronixLCD2S::set_keypad_repeat_rate(uint8_t val) { + remember(); + i2c_write(address, 0xA1, &val, 1); +} + + + +void ModtronixLCD2S::set_keypad_buzzer_period(uint8_t val) { + remember(); + i2c_write(address, 0xA2, &val, 1); +} + + + +void ModtronixLCD2S::write_large_number_string(const char* str) { + load_charset(2); + i2c_write(address, 0x8F, (uint8_t*)str, strlen(str)); +} + + + +void ModtronixLCD2S::set_cursor_addr(uint8_t val) { + i2c_write(address, 0x89, &val, 1); +} + + + +void ModtronixLCD2S::set_out12(uint8_t val1, uint8_t val2) { + uint8_t val = (val1? 0x1 : 0) | (val2? 0x2 : 0); + i2c_write(address, 0xE2, &val, 1); +} + + + +void ModtronixLCD2S::draw_vertical_bar_graph(uint8_t row, uint8_t col, uint8_t val) { + uint8_t buf[3]; + buf[0] = row; + buf[1] = col; + buf[2] = val; + load_charset(0); + i2c_write(address, 0x93, buf, 3); +} + + + +void ModtronixLCD2S::draw_tall_bar_graph(uint8_t row, uint8_t col, uint8_t val) { + uint8_t buf[3]; + buf[0] = row; + buf[1] = col; + buf[2] = val; + load_charset(1); + i2c_write(address, 0x94, buf, 3); +} + + + +void ModtronixLCD2S::define_custom_char(uint8_t adr, const uint8_t *data) { + uint8_t buf[9]; + buf[0] = adr; + memcpy(buf+1, data, 8); + i2c_write(address, 0x92, buf, 9); +} + + + +// vim: set sw=2 autoindent nowrap expandtab: settings + + diff --git a/firmware/src/shared/ModtronixLCD2S.hh b/firmware/src/shared/ModtronixLCD2S.hh new file mode 100644 index 0000000..df2cf5c --- /dev/null +++ b/firmware/src/shared/ModtronixLCD2S.hh @@ -0,0 +1,99 @@ +// LCD Controls for a Modtronix LCD2S 4x20 LCD with I2C serial controller. +// More details at http://www.modtronix.com/products/lcd2s + +#ifndef _MODTRONIXLCD2S_H +#define _MODTRONIXLCD2S_H +#include +#include "display.hh" + +class ModtronixLCD2S : public Display { + uint8_t address; + uint8_t charset; + +public: + ModtronixLCD2S(uint8_t addr = 0x50>>1); + + virtual void init(); + virtual void clear(); + virtual void setCursor(uint8_t col, uint8_t row) { return set_position(row+1,col+1); } + virtual void write(uint8_t value) { return write_char(value); } + + virtual void writeInt(uint16_t value, uint8_t digits); + virtual void writeString(const char message[]) { return write_string(message); } + virtual void writeFromPgmspace(const prog_char message[]) { return write_string_P(message ); } + + void remember(); + void config(uint8_t display, uint8_t contrast, uint8_t brightness, uint8_t keypadio, uint8_t keypadbuzz); + void set_base_address(uint8_t addr); + + int8_t read_status(); +// void read_status_async(asynctwi::callback_t cb); + char read_keypad_data(); +// void read_keypad_data_async(asynctwi::callback_t cb); + uint8_t read_gpio123(); +// void read_gpio123_async(asynctwi::callback_t cb); + + void backlight_on(); + void backlight_off(); + void backlight_brightness(uint8_t val); + void set_contrast(uint8_t val); + + void display_on(); + void display_off(); + void cursor_underline_on(); + void cursor_underline_off(); + void cursor_block_on(); + void cursor_block_off(); + void dir_forward(); + void dir_backwards(); + void load_charset(uint8_t val); + void define_custom_char(uint8_t adr, const uint8_t *data); + + void home(); +// void clear(); + void set_position(uint8_t row, uint8_t col); + void set_cursor_addr(uint8_t val); + + void write_string(const char* str); + void write_string_P(PGM_P str); + void write_char(char ch); + void write_decimal(int16_t val, int8_t wid = 0, uint8_t decdigits = 0); + void set_startup_line(uint8_t row, const char* str); + void write_large_number_string(const char* str); + void draw_vertical_bar_graph(uint8_t row, uint8_t col, uint8_t val); + void draw_tall_bar_graph(uint8_t row, uint8_t col, uint8_t val); + + void shift_right(); + void shift_left(); + void shift_up(); + void shift_down(); + + void interrupt_open_collection(); + void interrupt_push_pull(); + void config_keypad_and_io(uint8_t val); + void config_gpio1(uint8_t val); + void config_gpio2(uint8_t val); + void config_gpio3(uint8_t val); + + void set_out12(uint8_t val1, uint8_t val2); // 0xE2 VAL + void out1_on(); + void out1_off(); + void out2_on(); + void out2_off(); + + void gpio1_on(); + void gpio1_off(); + void gpio2_on(); + void gpio2_off(); + + void set_max_backlight_brightness(uint8_t val); + void set_keypad_debounce_time(uint8_t val); + void set_keypad_repeat_delay(uint8_t val); + void set_keypad_repeat_rate(uint8_t val); + void set_keypad_buzzer_period(uint8_t val); +}; + +#endif // _MODTRONIXLCD2S_H + +// vim: set sw=2 autoindent nowrap expandtab: settings + From b79f6aacc98c67a1453031a2a1e27a48ccd30a89 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 16 Nov 2011 22:36:04 -0800 Subject: [PATCH 07/39] add twi libraries for Modtronix. --- G3Firmware.sln | 7 + firmware/src/shared/Display.hh | 2 +- firmware/src/shared/DualDisplay.hh | 1 - firmware/src/shared/twi.cc | 543 +++++++++++++++++++++++++++++ firmware/src/shared/twi.h | 66 ++++ 5 files changed, 617 insertions(+), 2 deletions(-) create mode 100644 firmware/src/shared/twi.cc create mode 100644 firmware/src/shared/twi.h diff --git a/G3Firmware.sln b/G3Firmware.sln index ad9bb00..9248f44 100644 --- a/G3Firmware.sln +++ b/G3Firmware.sln @@ -27,6 +27,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{AE577D firmware\src\shared\Commands.hh = firmware\src\shared\Commands.hh firmware\src\shared\CoolingFan.cc = firmware\src\shared\CoolingFan.cc firmware\src\shared\CoolingFan.hh = firmware\src\shared\CoolingFan.hh + firmware\src\shared\Display.hh = firmware\src\shared\Display.hh + firmware\src\shared\DualDisplay.cc = firmware\src\shared\DualDisplay.cc + firmware\src\shared\DualDisplay.hh = firmware\src\shared\DualDisplay.hh firmware\src\shared\Eeprom.cc = firmware\src\shared\Eeprom.cc firmware\src\shared\Eeprom.hh = firmware\src\shared\Eeprom.hh firmware\src\shared\Heater.cc = firmware\src\shared\Heater.cc @@ -40,6 +43,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{AE577D firmware\src\shared\LiquidCrystal.hh = firmware\src\shared\LiquidCrystal.hh firmware\src\shared\Menu.cc = firmware\src\shared\Menu.cc firmware\src\shared\Menu.hh = firmware\src\shared\Menu.hh + firmware\src\shared\ModtronixLCD2S.cc = firmware\src\shared\ModtronixLCD2S.cc + firmware\src\shared\ModtronixLCD2S.hh = firmware\src\shared\ModtronixLCD2S.hh firmware\src\shared\Packet.cc = firmware\src\shared\Packet.cc firmware\src\shared\Packet.hh = firmware\src\shared\Packet.hh firmware\src\shared\PID.cc = firmware\src\shared\PID.cc @@ -63,6 +68,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{AE577D firmware\src\shared\Thermocouple.hh = firmware\src\shared\Thermocouple.hh firmware\src\shared\Timeout.cc = firmware\src\shared\Timeout.cc firmware\src\shared\Timeout.hh = firmware\src\shared\Timeout.hh + firmware\src\shared\twi.cc = firmware\src\shared\twi.cc + firmware\src\shared\twi.h = firmware\src\shared\twi.h firmware\src\shared\Types.hh = firmware\src\shared\Types.hh firmware\src\shared\UART.cc = firmware\src\shared\UART.cc firmware\src\shared\UART.hh = firmware\src\shared\UART.hh diff --git a/firmware/src/shared/Display.hh b/firmware/src/shared/Display.hh index 9164c90..d1fd286 100644 --- a/firmware/src/shared/Display.hh +++ b/firmware/src/shared/Display.hh @@ -5,7 +5,7 @@ #include #include -#include "AvrPort.hh" +#include "PinTmplt.hh" class Display { public: diff --git a/firmware/src/shared/DualDisplay.hh b/firmware/src/shared/DualDisplay.hh index 8a72588..090be26 100644 --- a/firmware/src/shared/DualDisplay.hh +++ b/firmware/src/shared/DualDisplay.hh @@ -5,7 +5,6 @@ #include #include -#include "AvrPort.hh" #include "Display.hh" #include "LiquidCrystal.hh" #include "ModtronixLCD2S.hh" diff --git a/firmware/src/shared/twi.cc b/firmware/src/shared/twi.cc new file mode 100644 index 0000000..0beeb19 --- /dev/null +++ b/firmware/src/shared/twi.cc @@ -0,0 +1,543 @@ +/* + twi.c - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif + +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +#include "twi.h" + +static volatile uint8_t twi_state; +static uint8_t twi_slarw; + +static void (*twi_onSlaveTransmit)(void); +static void (*twi_onSlaveReceive)(uint8_t*, int); + +static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_masterBufferIndex; +static uint8_t twi_masterBufferLength; + +static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_txBufferIndex; +static volatile uint8_t twi_txBufferLength; + +static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; +static volatile uint8_t twi_rxBufferIndex; + +static volatile uint8_t twi_error; + +/* + * Function twi_init + * Desc readys twi pins and sets twi bitrate + * Input none + * Output none + */ +void twi_init(void) +{ + // initialize state + twi_state = TWI_READY; + + #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__) + // activate internal pull-ups for twi + // as per note from atmega8 manual pg167 + sbi(PORTC, 4); + sbi(PORTC, 5); + #else + // activate internal pull-ups for twi + // as per note from atmega128 manual pg204 + sbi(PORTD, 0); + sbi(PORTD, 1); + #endif + + // initialize twi prescaler and bit rate + cbi(TWSR, TWPS0); + cbi(TWSR, TWPS1); + TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2; + + /* twi bit rate formula from atmega128 manual pg 204 + SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) + note: TWBR should be 10 or higher for master mode + It is 72 for a 16mhz Wiring board with 100kHz TWI */ + + // enable twi module, acks, and twi interrupt + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); +} + +/* + * Function twi_slaveInit + * Desc sets slave address and enables interrupt + * Input none + * Output none + */ +void twi_setAddress(uint8_t address) +{ + // set twi slave address (skip over TWGCE bit) + TWAR = address << 1; +} + +/* + * Function twi_readFrom + * Desc attempts to become twi bus master and read a + * series of bytes from a device on the bus + * Input address: 7bit i2c device address + * data: pointer to byte array + * length: number of bytes to read into array + * Output number of bytes read + */ +uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 0; + } + + // wait until twi is ready, become master receiver + while(TWI_READY != twi_state){ + continue; + } + twi_state = TWI_MRX; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; + + // initialize buffer iteration vars + twi_masterBufferIndex = 0; + twi_masterBufferLength = length-1; // This is not intuitive, read on... + // On receive, the previously configured ACK/NACK setting is transmitted in + // response to the received byte before the interrupt is signalled. + // Therefor we must actually set NACK when the _next_ to last byte is + // received, causing that NACK to be sent in response to receiving the last + // expected byte of data. + + // build sla+w, slave device address + w bit + twi_slarw = TW_READ; + twi_slarw |= address << 1; + + // send start condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); + + // wait for read operation to complete + while(TWI_MRX == twi_state){ + continue; + } + + if (twi_masterBufferIndex < length) + length = twi_masterBufferIndex; + + // copy twi buffer to data + for(i = 0; i < length; ++i){ + data[i] = twi_masterBuffer[i]; + } + + return length; +} + +/* + * Function twi_writeTo + * Desc attempts to become twi bus master and write a + * series of bytes to a device on the bus + * Input address: 7bit i2c device address + * data: pointer to byte array + * length: number of bytes in array + * wait: boolean indicating to wait for write or not + * Output 0 .. success + * 1 .. length to long for buffer + * 2 .. address send, NACK received + * 3 .. data send, NACK received + * 4 .. other twi error (lost bus arbitration, bus error, ..) + */ +uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 1; + } + + // wait until twi is ready, become master transmitter + while(TWI_READY != twi_state){ + continue; + } + twi_state = TWI_MTX; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; + + // initialize buffer iteration vars + twi_masterBufferIndex = 0; + twi_masterBufferLength = length; + + // copy data to twi buffer + for(i = 0; i < length; ++i){ + twi_masterBuffer[i] = data[i]; + } + + // build sla+w, slave device address + w bit + twi_slarw = TW_WRITE; + twi_slarw |= address << 1; + + // send start condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); + + // wait for write operation to complete + while(wait && (TWI_MTX == twi_state)){ + continue; + } + + if (twi_error == 0xFF) + return 0; // success + else if (twi_error == TW_MT_SLA_NACK) + return 2; // error: address send, nack received + else if (twi_error == TW_MT_DATA_NACK) + return 3; // error: data send, nack received + else + return 4; // other twi error +} + + +uint8_t twi_writeTo_buffers(uint8_t address, const twi_data data[], uint8_t data_len, uint8_t wait) +{ + uint8_t i; + uint8_t total_length = 0; + for ( i = 0; i < data_len; i++ ) + { + total_length += data[i].length; + } + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < total_length){ + return 1; + } + + // wait until twi is ready, become master transmitter + while(TWI_READY != twi_state){ + continue; + } + twi_state = TWI_MTX; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; + + // initialize buffer iteration vars + twi_masterBufferIndex = 0; + twi_masterBufferLength = total_length; + + // copy data to twi buffer + uint8_t* ptr = twi_masterBuffer; + for ( i = 0; i < data_len; i++ ) + { + if ( data[i].progmem ) + { + memcpy_P(ptr, data[i].data, data[i].length); + ptr += data[i].length; + } + else + { + memcpy(ptr, data[i].data, data[i].length); + ptr += data[i].length; + } + } + // build sla+w, slave device address + w bit + twi_slarw = TW_WRITE; + twi_slarw |= address << 1; + + // send start condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); + + // wait for write operation to complete + while(wait && (TWI_MTX == twi_state)){ + continue; + } + + if (twi_error == 0xFF) + return 0; // success + else if (twi_error == TW_MT_SLA_NACK) + return 2; // error: address send, nack received + else if (twi_error == TW_MT_DATA_NACK) + return 3; // error: data send, nack received + else + return 4; // other twi error +} + + +/* + * Function twi_transmit + * Desc fills slave tx buffer with data + * must be called in slave tx event callback + * Input data: pointer to byte array + * length: number of bytes in array + * Output 1 length too long for buffer + * 2 not slave transmitter + * 0 ok + */ +uint8_t twi_transmit(uint8_t* data, uint8_t length) +{ + uint8_t i; + + // ensure data will fit into buffer + if(TWI_BUFFER_LENGTH < length){ + return 1; + } + + // ensure we are currently a slave transmitter + if(TWI_STX != twi_state){ + return 2; + } + + // set length and copy data into tx buffer + twi_txBufferLength = length; + for(i = 0; i < length; ++i){ + twi_txBuffer[i] = data[i]; + } + + return 0; +} + +/* + * Function twi_attachSlaveRxEvent + * Desc sets function called before a slave read operation + * Input function: callback function to use + * Output none + */ +void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) +{ + twi_onSlaveReceive = function; +} + +/* + * Function twi_attachSlaveTxEvent + * Desc sets function called before a slave write operation + * Input function: callback function to use + * Output none + */ +void twi_attachSlaveTxEvent( void (*function)(void) ) +{ + twi_onSlaveTransmit = function; +} + +/* + * Function twi_reply + * Desc sends byte or readys receive line + * Input ack: byte indicating to ack or to nack + * Output none + */ +void twi_reply(uint8_t ack) +{ + // transmit master read ready signal, with or without ack + if(ack){ + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); + }else{ + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); + } +} + +/* + * Function twi_stop + * Desc relinquishes bus master status + * Input none + * Output none + */ +void twi_stop(void) +{ + // send stop condition + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); + + // wait for stop condition to be exectued on bus + // TWINT is not set after a stop condition! + while(TWCR & _BV(TWSTO)){ + continue; + } + + // update twi state + twi_state = TWI_READY; +} + +/* + * Function twi_releaseBus + * Desc releases bus control + * Input none + * Output none + */ +void twi_releaseBus(void) +{ + // release bus + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); + + // update twi state + twi_state = TWI_READY; +} + +SIGNAL(TWI_vect) +{ + switch(TW_STATUS){ + // All Master + case TW_START: // sent start condition + case TW_REP_START: // sent repeated start condition + // copy device address and r/w bit to output register and ack + TWDR = twi_slarw; + twi_reply(1); + break; + + // Master Transmitter + case TW_MT_SLA_ACK: // slave receiver acked address + case TW_MT_DATA_ACK: // slave receiver acked data + // if there is data to send, send it, otherwise stop + if(twi_masterBufferIndex < twi_masterBufferLength){ + // copy data to output register and ack + TWDR = twi_masterBuffer[twi_masterBufferIndex++]; + twi_reply(1); + }else{ + twi_stop(); + } + break; + case TW_MT_SLA_NACK: // address sent, nack received + twi_error = TW_MT_SLA_NACK; + twi_stop(); + break; + case TW_MT_DATA_NACK: // data sent, nack received + twi_error = TW_MT_DATA_NACK; + twi_stop(); + break; + case TW_MT_ARB_LOST: // lost bus arbitration + twi_error = TW_MT_ARB_LOST; + twi_releaseBus(); + break; + + // Master Receiver + case TW_MR_DATA_ACK: // data received, ack sent + // put byte into buffer + twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + case TW_MR_SLA_ACK: // address sent, ack received + // ack if more bytes are expected, otherwise nack + if(twi_masterBufferIndex < twi_masterBufferLength){ + twi_reply(1); + }else{ + twi_reply(0); + } + break; + case TW_MR_DATA_NACK: // data received, nack sent + // put final byte into buffer + twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + case TW_MR_SLA_NACK: // address sent, nack received + twi_stop(); + break; + // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case + + // Slave Receiver + case TW_SR_SLA_ACK: // addressed, returned ack + case TW_SR_GCALL_ACK: // addressed generally, returned ack + case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack + case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack + // enter slave receiver mode + twi_state = TWI_SRX; + // indicate that rx buffer can be overwritten and ack + twi_rxBufferIndex = 0; + twi_reply(1); + break; + case TW_SR_DATA_ACK: // data received, returned ack + case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack + // if there is still room in the rx buffer + if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ + // put byte in buffer and ack + twi_rxBuffer[twi_rxBufferIndex++] = TWDR; + twi_reply(1); + }else{ + // otherwise nack + twi_reply(0); + } + break; + case TW_SR_STOP: // stop or repeated start condition received + // put a null char after data if there's room + if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ + twi_rxBuffer[twi_rxBufferIndex] = '\0'; + } + // sends ack and stops interface for clock stretching + twi_stop(); + // callback to user defined callback + twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); + // since we submit rx buffer to "wire" library, we can reset it + twi_rxBufferIndex = 0; + // ack future responses and leave slave receiver state + twi_releaseBus(); + break; + case TW_SR_DATA_NACK: // data received, returned nack + case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack + // nack back at master + twi_reply(0); + break; + + // Slave Transmitter + case TW_ST_SLA_ACK: // addressed, returned ack + case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack + // enter slave transmitter mode + twi_state = TWI_STX; + // ready the tx buffer index for iteration + twi_txBufferIndex = 0; + // set tx buffer length to be zero, to verify if user changes it + twi_txBufferLength = 0; + // request for txBuffer to be filled and length to be set + // note: user must call twi_transmit(bytes, length) to do this + twi_onSlaveTransmit(); + // if they didn't change buffer & length, initialize it + if(0 == twi_txBufferLength){ + twi_txBufferLength = 1; + twi_txBuffer[0] = 0x00; + } + // transmit first byte from buffer, fall + case TW_ST_DATA_ACK: // byte sent, ack returned + // copy data to output register + TWDR = twi_txBuffer[twi_txBufferIndex++]; + // if there is more to send, ack, otherwise nack + if(twi_txBufferIndex < twi_txBufferLength){ + twi_reply(1); + }else{ + twi_reply(0); + } + break; + case TW_ST_DATA_NACK: // received nack, we are done + case TW_ST_LAST_DATA: // received ack, but we are done already! + // ack future responses + twi_reply(1); + // leave slave receiver state + twi_state = TWI_READY; + break; + + // All + case TW_NO_INFO: // no state information + break; + case TW_BUS_ERROR: // bus error, illegal stop/start + twi_error = TW_BUS_ERROR; + twi_stop(); + break; + } +} + diff --git a/firmware/src/shared/twi.h b/firmware/src/shared/twi.h new file mode 100644 index 0000000..fbbb15b --- /dev/null +++ b/firmware/src/shared/twi.h @@ -0,0 +1,66 @@ +/* + twi.h - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef twi_h +#define twi_h + + #include + + //#define ATMEGA8 + + #ifndef CPU_FREQ + #define CPU_FREQ 16000000L + #endif + + #ifndef TWI_FREQ + #define TWI_FREQ 100000L + #endif + + #ifndef TWI_BUFFER_LENGTH + #define TWI_BUFFER_LENGTH 32 + #endif + + #define TWI_READY 0 + #define TWI_MRX 1 + #define TWI_MTX 2 + #define TWI_SRX 3 + #define TWI_STX 4 + + void twi_init(void); + void twi_setAddress(uint8_t); + uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t); + uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t); + uint8_t twi_transmit(uint8_t*, uint8_t); + void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); + void twi_attachSlaveTxEvent( void (*)(void) ); + void twi_reply(uint8_t); + void twi_stop(void); + void twi_releaseBus(void); + +struct twi_data +{ + uint8_t progmem; // bit indicating if data is in PROGMEM + uint8_t length; + const uint8_t* data; +}; + +uint8_t twi_writeTo_buffers(uint8_t address, const twi_data data[], uint8_t data_len, uint8_t wait); + +#endif + From adb5b50a1ae1fc492a23e8af5a74f67ea2997abc Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sat, 19 Nov 2011 10:19:51 -0800 Subject: [PATCH 08/39] custom pin changes for my bot --- .../Motherboard/boards/mb24/Configuration.hh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/firmware/src/Motherboard/boards/mb24/Configuration.hh b/firmware/src/Motherboard/boards/mb24/Configuration.hh index f47eedb..712a68c 100644 --- a/firmware/src/Motherboard/boards/mb24/Configuration.hh +++ b/firmware/src/Motherboard/boards/mb24/Configuration.hh @@ -40,9 +40,9 @@ // Define as 1 if and SD card slot is present; 0 if not. #define HAS_SD 1 // The pin that connects to the write protect line on the SD header. -#define SD_WRITE_PIN Pin(PortD,0) +#define SD_WRITE_PIN Pin(PortB,7) // CRAIGBOT Pin(PortD,0) // The pin that connects to the card detect line on the SD header. -#define SD_DETECT_PIN Pin(PortD,1) +#define SD_DETECT_PIN Pin(PortC,4) // CRAIGBOT Pin(PortD,1) // The pin that connects to the chip select line on the SD header. #define SD_SELECT_PIN Pin(PortB,0) @@ -63,7 +63,7 @@ // --- Piezo Buzzer configuration --- // Define as 1 if the piezo buzzer is present, 0 if not. -#define HAS_BUZZER 1 +#define HAS_BUZZER 0 // CRAIGBOT 1 // The pin that drives the buzzer #define BUZZER_PIN Pin(PortC,6) @@ -150,12 +150,12 @@ /// Pin mappings for the LCD connection. -#define LCD_RS_PIN Pin(PortC,4) -#define LCD_ENABLE_PIN Pin(PortC,3) -#define LCD_D0_PIN Pin(PortD,7) -#define LCD_D1_PIN Pin(PortG,2) -#define LCD_D2_PIN Pin(PortG,1) -#define LCD_D3_PIN Pin(PortG,0) +#define LCD_RS_PIN Pin(PortC,2) // CRAIGBOT //Pin(PortC,4) +#define LCD_ENABLE_PIN Pin(PortC,0) // CRAIGBOT //Pin(PortC,3) +#define LCD_D0_PIN Pin(PortG,0) // CRAIGBOT //Pin(PortD,7) +#define LCD_D1_PIN Pin(PortL,6) // CRAIGBOT //Pin(PortG,2) +#define LCD_D2_PIN Pin(PortL,4) // CRAIGBOT //Pin(PortG,1) +#define LCD_D3_PIN Pin(PortL,2) // CRAIGBOT //Pin(PortG,0) /// This is the pin mapping for the interface board. Because of the relatively /// high cost of using the pins in a direct manner, we will instead read the From c092b0e2a02c8fd6bd74df627e805fd64448a04a Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sat, 19 Nov 2011 10:54:16 -0800 Subject: [PATCH 09/39] add condition compilation to turn off interface board, as well as just the interface buttons --- .../Motherboard/boards/mb24/ButtonArray.cc | 6 ++ .../Motherboard/boards/mb24/Configuration.hh | 14 +++- .../Motherboard/boards/mb24/Motherboard.cc | 83 +++++-------------- .../Motherboard/boards/mb24/Motherboard.hh | 24 +++--- firmware/src/shared/Interface.cc | 8 +- firmware/src/shared/Interface.hh | 4 +- firmware/src/shared/InterfaceBoard.cc | 15 ++-- firmware/src/shared/InterfaceBoard.hh | 7 +- firmware/src/shared/LiquidCrystal.cc | 4 +- firmware/src/shared/LiquidCrystal.hh | 5 +- firmware/src/shared/Menu.cc | 7 +- firmware/src/shared/Menu.hh | 4 + 12 files changed, 80 insertions(+), 101 deletions(-) diff --git a/firmware/src/Motherboard/boards/mb24/ButtonArray.cc b/firmware/src/Motherboard/boards/mb24/ButtonArray.cc index 8fda342..ff7471e 100644 --- a/firmware/src/Motherboard/boards/mb24/ButtonArray.cc +++ b/firmware/src/Motherboard/boards/mb24/ButtonArray.cc @@ -15,6 +15,7 @@ void ButtonArray::init() { } void ButtonArray::scanButtons() { +#if HAS_INTERFACE_BUTTONS > 0 // Don't bother scanning if we already have a button. if (buttonPressWaiting) { return; @@ -55,9 +56,11 @@ void ButtonArray::scanButtons() { previousL = newL; previousC = newC; +#endif // HAS_INTERFACE_BUTTONS > 0 } bool ButtonArray::getButton(ButtonName& button) { +#if HAS_INTERFACE_BUTTONS > 0 bool buttonValid; uint8_t buttonNumber; @@ -73,4 +76,7 @@ bool ButtonArray::getButton(ButtonName& button) { } return buttonValid; +#else + return false; +#endif // HAS_INTERFACE_BUTTONS > 0 } diff --git a/firmware/src/Motherboard/boards/mb24/Configuration.hh b/firmware/src/Motherboard/boards/mb24/Configuration.hh index f47eedb..cccc52c 100644 --- a/firmware/src/Motherboard/boards/mb24/Configuration.hh +++ b/firmware/src/Motherboard/boards/mb24/Configuration.hh @@ -18,6 +18,7 @@ #ifndef BOARDS_MB24_CONFIGURATION_HH_ #define BOARDS_MB24_CONFIGURATION_HH_ +#include "PinTmplt.hh" /// This file details the pin assignments and features of the /// Makerbot Motherboard v2.x @@ -146,9 +147,8 @@ // Define as 1 if debugging packets are honored; 0 if not. #define HONOR_DEBUG_PACKETS 1 -#define HAS_INTERFACE_BOARD 1 - - +#define HAS_INTERFACE_BOARD 0 +#if HAS_INTERFACE_BOARD > 0 /// Pin mappings for the LCD connection. #define LCD_RS_PIN Pin(PortC,4) #define LCD_ENABLE_PIN Pin(PortC,3) @@ -163,6 +163,8 @@ /// modified, the #scanButtons() function _must_ be updated to reflect this. /// /// TLDR: These are here for decoration only, actual pins defined in #scanButtons() +#define HAS_INTERFACE_BUTTONS 0 +#if HAS_INTERFACE_BUTTONS > 0 #define INTERFACE_X+_PIN Pin(PortL,7) #define INTERFACE_X-_PIN Pin(PortL,6) #define INTERFACE_Y+_PIN Pin(PortL,5) @@ -177,5 +179,11 @@ #define INTERFACE_FOO_PIN Pin(PortC,0) #define INTERFACE_BAR_PIN Pin(PortL,0) #define INTERFACE_DEBUG_PIN Pin(PortB,7) +#endif // HAS_INTERFACE_BUTTONS > 0 + +#else +#define HAS_INTERFACE_BUTTONS 0 +#endif // HAS_INTERFACE_BOARD > 0 + #endif // BOARDS_RRMBV12_CONFIGURATION_HH_ diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.cc b/firmware/src/Motherboard/boards/mb24/Motherboard.cc index 1095a0a..6857c80 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.cc +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.cc @@ -35,70 +35,17 @@ Motherboard Motherboard::motherboard; /// Create motherboard object -Motherboard::Motherboard() : - lcd( -/* - LCD_RS_PIN, - LCD_ENABLE_PIN, - LCD_D0_PIN, - LCD_D1_PIN, - LCD_D2_PIN, - LCD_D3_PIN -*/ - ), - interfaceBoard(buttonArray, +Motherboard::Motherboard() +#if HAS_INTERFACE_BOARD > 0 + : + interfaceBoard( + buttonArray, lcd, -// INTERFACE_FOO_PIN, -// INTERFACE_BAR_PIN, &mainMenu, &monitorMode) +#endif // HAS_INTERFACE_BOARD > 0 { -#if 0 -/* - /// Set up the stepper pins on board creation -#if STEPPER_COUNT > 0 - stepper[0] = StepperInterface(X_DIR_PIN, - X_STEP_PIN, - X_ENABLE_PIN, - X_MAX_PIN, - X_MIN_PIN, - eeprom::AXIS_INVERSION); -#endif -#if STEPPER_COUNT > 1 - stepper[1] = StepperInterface(Y_DIR_PIN, - Y_STEP_PIN, - Y_ENABLE_PIN, - Y_MAX_PIN, - Y_MIN_PIN, - eeprom::AXIS_INVERSION); -#endif -#if STEPPER_COUNT > 2 - stepper[2] = StepperInterface(Z_DIR_PIN, - Z_STEP_PIN, - Z_ENABLE_PIN, - Z_MAX_PIN, - Z_MIN_PIN, - eeprom::AXIS_INVERSION); -#endif -#if STEPPER_COUNT > 3 - stepper[3] = StepperInterface(A_DIR_PIN, - A_STEP_PIN, - A_ENABLE_PIN, - Pin(), - Pin(), - eeprom::AXIS_INVERSION); -#endif -#if STEPPER_COUNT > 4 - stepper[4] = StepperInterface(B_DIR_PIN, - B_STEP_PIN, - B_ENABLE_PIN, - Pin(), - Pin(), - eeprom::AXIS_INVERSION); -#endif -*/ -#endif } #if STEPPER_COUNT > 0 @@ -189,9 +136,9 @@ void Motherboard::reset() { // Configure the debug pin. DEBUG_PIN::setDirection(true); +#if HAS_INTERFACE_BOARD > 0 // Check if the interface board is attached - hasInterfaceBoard = interface::isConnected(); - + hasInterfaceBoard = interface::isConnected(); if (hasInterfaceBoard) { // Make sure our interface board is initialized interfaceBoard.init(); @@ -204,6 +151,7 @@ void Motherboard::reset() { interface_update_timeout.start(interfaceBoard.getUpdateRate()); } +#endif // HAS_INTERFACE_BOARD > 0 // Blindly try to reset the toolhead with index 0. // resetToolhead(); @@ -222,9 +170,13 @@ micros_t Motherboard::getCurrentMicros() { /// Run the motherboard interrupt void Motherboard::doInterrupt() { + +#if HAS_INTERFACE_BOARD > 0 if (hasInterfaceBoard) { - interfaceBoard.doInterrupt(); + interfaceBoard.doInterrupt(); } +#endif // HAS_INTERFACE_BOARD > 0 + micros += INTERVAL_IN_MICROSECONDS; // Do not move steppers if the board is in a paused state if (command::isPaused()) return; @@ -232,12 +184,15 @@ void Motherboard::doInterrupt() { } void Motherboard::runMotherboardSlice() { + +#if HAS_INTERFACE_BOARD > 0 if (hasInterfaceBoard) { if (interface_update_timeout.hasElapsed()) { - interfaceBoard.doUpdate(); - interface_update_timeout.start(interfaceBoard.getUpdateRate()); + interfaceBoard.doUpdate(); + interface_update_timeout.start(interfaceBoard.getUpdateRate()); } } +#endif } diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.hh b/firmware/src/Motherboard/boards/mb24/Motherboard.hh index 3933ab7..e6f9fbf 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.hh +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.hh @@ -35,13 +35,13 @@ /// \ingroup MBv24 class Motherboard { private: - // TODO: Declare this in main, drop the singleton. - /// Static instance of the motherboard - static Motherboard motherboard; + // TODO: Declare this in main, drop the singleton. + /// Static instance of the motherboard + static Motherboard motherboard; public: - /// Get the motherboard instance. - static Motherboard& getBoard() { return motherboard; } + /// Get the motherboard instance. + static Motherboard& getBoard() { return motherboard; } private: #if STEPPER_COUNT > 0 @@ -70,19 +70,21 @@ private: /// Private constructor; use the singleton Motherboard(); +#if HAS_INTERFACE_BOARD > 0 // TODO: Move this to an interface board slice. Timeout interface_update_timeout; /// True if we have an interface board attached bool hasInterfaceBoard; - ButtonArray buttonArray; - LiquidCrystal lcd; - InterfaceBoard interfaceBoard; + ButtonArray buttonArray; + LiquidCrystal lcd; + InterfaceBoard interfaceBoard; - MainMenu mainMenu; ///< Main system menu - SplashScreen splashScreen; ///< Displayed at startup - MonitorMode monitorMode; ///< Displayed during build + MainMenu mainMenu; ///< Main system menu + SplashScreen splashScreen; ///< Displayed at startup + MonitorMode monitorMode; ///< Displayed during build +#endif // HAS_INTERFACE_BOARD > 0 public: /// Reset the motherboard to its initial state. diff --git a/firmware/src/shared/Interface.cc b/firmware/src/shared/Interface.cc index 8f24fb8..2f0b9bb 100644 --- a/firmware/src/shared/Interface.cc +++ b/firmware/src/shared/Interface.cc @@ -1,10 +1,10 @@ #include "Interface.hh" #include "InterfaceBoard.hh" +#if HAS_INTERFACE_BOARD > 0 // TODO: Make this a proper module. -#if defined HAS_INTERFACE_BOARD namespace interface { @@ -14,6 +14,7 @@ InterfaceBoard* board; bool isConnected() { +#if HAS_INTERFACE_BUTTONS > 0 // Strategy: Set up the foo pin as an input, turn on pull up resistor, // then measure it. If low, then we probably have an interface board. // If high, we probably don't. @@ -36,6 +37,9 @@ bool isConnected() { } return (!INTERFACE_FOO_PIN::getValue()); +#else + return true; +#endif HAS_INTERFACE_BUTTONS > 0 } @@ -67,4 +71,4 @@ void doUpdate() { } -#endif +#endif // HAS_INTERFACE_BOARD > 0 diff --git a/firmware/src/shared/Interface.hh b/firmware/src/shared/Interface.hh index fb81abd..8cd055f 100644 --- a/firmware/src/shared/Interface.hh +++ b/firmware/src/shared/Interface.hh @@ -19,8 +19,8 @@ #ifndef INTERFACE_HH_ #define INTERFACE_HH_ -#if defined HAS_INTERFACE_BOARD #include "InterfaceBoard.hh" +#if HAS_INTERFACE_BOARD > 0 #include "Types.hh" #include "Menu.hh" #include "LiquidCrystal.hh" @@ -65,6 +65,6 @@ micros_t getUpdateRate(); } -#endif +#endif // HAS_INTERFACE_BOARD > 0 #endif diff --git a/firmware/src/shared/InterfaceBoard.cc b/firmware/src/shared/InterfaceBoard.cc index 3b14ea8..508aa57 100644 --- a/firmware/src/shared/InterfaceBoard.cc +++ b/firmware/src/shared/InterfaceBoard.cc @@ -1,8 +1,7 @@ #include "InterfaceBoard.hh" -#include "Configuration.hh" +#if HAS_INTERFACE_BOARD > 0 #include "Host.hh" -#if defined HAS_INTERFACE_BOARD #include "LiquidCrystal.hh" @@ -13,8 +12,8 @@ InterfaceBoard::InterfaceBoard(ButtonArray& buttons_in, LiquidCrystal& lcd_in, Screen* mainScreen_in, Screen* buildScreen_in) : - lcd(lcd_in), - buttons(buttons_in) + buttons(buttons_in), + lcd(lcd_in) { buildScreen = buildScreen_in; mainScreen = mainScreen_in; @@ -25,10 +24,12 @@ void InterfaceBoard::init() { lcd.init(); +#if HAS_INTERFACE_BUTTONS > 0 foo_pin::setValue(false); foo_pin::setDirection(true); bar_pin::setValue(false); bar_pin::setDirection(true); +#endif HAS_INTERFACE_BUTTONS > 0 building = false; @@ -53,7 +54,7 @@ void InterfaceBoard::doUpdate() { case host::HOST_STATE_BUILDING: case host::HOST_STATE_BUILDING_FROM_SD: if (!building) { - pushScreen(buildScreen); + pushScreen(buildScreen); building = true; } break; @@ -66,7 +67,7 @@ void InterfaceBoard::doUpdate() { } - static ButtonArray::ButtonName button; + static ButtonArray::ButtonName button; if (buttons.getButton(button)) { @@ -94,4 +95,4 @@ void InterfaceBoard::popScreen() { screenStack[screenIndex]->update(lcd, true); } -#endif +#endif // HAS_INTERFACE_BOARD > 0 diff --git a/firmware/src/shared/InterfaceBoard.hh b/firmware/src/shared/InterfaceBoard.hh index 1355eaf..a373dd0 100644 --- a/firmware/src/shared/InterfaceBoard.hh +++ b/firmware/src/shared/InterfaceBoard.hh @@ -20,9 +20,8 @@ #define INTERFACE_BOARD_HH_ #include "Configuration.hh" -#if defined HAS_INTERFACE_BOARD -#include "PinTmplt.hh" #include "ButtonArray.hh" +#if HAS_INTERFACE_BOARD > 0 #include "Menu.hh" /// Maximum number of screens that can be active at once. @@ -41,6 +40,7 @@ class InterfaceBoard { public: LiquidCrystal& lcd; ///< LCD to write to private: + ButtonArray& buttons; ///< Button array to read from // TODO: Drop this? @@ -66,7 +66,8 @@ public: /// \param[in] Pin connected to the bar LED /// \param[in] Main screen, shown as root display /// \param[in] Screen to display while building - InterfaceBoard(ButtonArray& buttons_in, + InterfaceBoard( + ButtonArray& buttons_in, LiquidCrystal& lcd_in, Screen* mainScreen_in, Screen* buildScreen_in); diff --git a/firmware/src/shared/LiquidCrystal.cc b/firmware/src/shared/LiquidCrystal.cc index 1f14e78..27e1ef2 100755 --- a/firmware/src/shared/LiquidCrystal.cc +++ b/firmware/src/shared/LiquidCrystal.cc @@ -4,7 +4,7 @@ #include #include "configuration.hh" -#if defined(LCD_ENABLE_PIN) +#if HAS_INTERFACE_BOARD > 0 #include "LiquidCrystal.hh" #define _rs_pin LCD_RS_PIN @@ -321,4 +321,4 @@ void LiquidCrystal::writeFromPgmspace(const prog_char message[]) { } } -#endif \ No newline at end of file +#endif // HAS_INTERFACE_BOARD > 0 diff --git a/firmware/src/shared/LiquidCrystal.hh b/firmware/src/shared/LiquidCrystal.hh index e3f4926..3503478 100755 --- a/firmware/src/shared/LiquidCrystal.hh +++ b/firmware/src/shared/LiquidCrystal.hh @@ -19,7 +19,7 @@ #define LCD_5x10DOTS 0x04 #define LCD_5x8DOTS 0x00 -#if defined(LCD_ENABLE_PIN) +#if HAS_INTERFACE_BOARD > 0 class LiquidCrystal : public Display { public: @@ -76,6 +76,7 @@ private: uint8_t _numlines,_currline; }; -#endif + +#endif //HAS_INTERFACE_BOARD > 0 #endif // LIQUID_CRYSTAL_HH diff --git a/firmware/src/shared/Menu.cc b/firmware/src/shared/Menu.cc index cd96b01..2e54fa3 100644 --- a/firmware/src/shared/Menu.cc +++ b/firmware/src/shared/Menu.cc @@ -1,7 +1,5 @@ -#include "Configuration.hh" - -// TODO: Kill this, should be hanlded by build system. -#ifdef HAS_INTERFACE_BOARD +#include "InterfaceBoard.hh" +#if HAS_INTERFACE_BOARD > 0 #include "Menu.hh" #include "Steppers.hh" @@ -10,7 +8,6 @@ #include "Tool.hh" #include "Host.hh" #include "Timeout.hh" -#include "InterfaceBoard.hh" #include "Interface.hh" #include #include diff --git a/firmware/src/shared/Menu.hh b/firmware/src/shared/Menu.hh index facc93c..ffa5c3c 100644 --- a/firmware/src/shared/Menu.hh +++ b/firmware/src/shared/Menu.hh @@ -1,6 +1,8 @@ #ifndef MENU_HH_ #define MENU_HH_ +#if HAS_INTERFACE_BOARD > 0 + #include "Types.hh" #include "ButtonArray.hh" #include "LiquidCrystal.hh" @@ -221,4 +223,6 @@ private: SnakeMode snake; }; +#endif // HAS_INTERFACE_BOARD > 0 + #endif From a9bbb087ca8cfc6ac8e5ff2674f124e4455e523c Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sat, 19 Nov 2011 11:55:47 -0800 Subject: [PATCH 10/39] abstract out the display so that it can easily be changed --- .../Motherboard/boards/mb24/Configuration.hh | 13 +- .../Motherboard/boards/mb24/Motherboard.cc | 4 +- .../Motherboard/boards/mb24/Motherboard.hh | 5 - firmware/src/shared/Display.hh | 3 +- firmware/src/shared/DualDisplay.cc | 4 + firmware/src/shared/DualDisplay.hh | 7 +- firmware/src/shared/Interface.cc | 4 +- firmware/src/shared/Interface.hh | 4 +- firmware/src/shared/InterfaceBoard.cc | 30 ++- firmware/src/shared/InterfaceBoard.hh | 14 +- firmware/src/shared/LiquidCrystal.cc | 4 +- firmware/src/shared/LiquidCrystal.hh | 9 +- firmware/src/shared/Menu.cc | 208 +++++++++--------- firmware/src/shared/Menu.hh | 23 +- firmware/src/shared/ModtronixLCD2S.hh | 4 +- 15 files changed, 174 insertions(+), 162 deletions(-) diff --git a/firmware/src/Motherboard/boards/mb24/Configuration.hh b/firmware/src/Motherboard/boards/mb24/Configuration.hh index cccc52c..e2535c0 100644 --- a/firmware/src/Motherboard/boards/mb24/Configuration.hh +++ b/firmware/src/Motherboard/boards/mb24/Configuration.hh @@ -147,9 +147,18 @@ // Define as 1 if debugging packets are honored; 0 if not. #define HONOR_DEBUG_PACKETS 1 -#define HAS_INTERFACE_BOARD 0 +#define HAS_INTERFACE_BOARD 1 #if HAS_INTERFACE_BOARD > 0 -/// Pin mappings for the LCD connection. + +#define DISPLAY_TYPE_LIQUIDCRYSTAL 1 +#define DISPLAY_TYPE_MODTRONIXLCD2S 2 +#define DISPLAY_TYPE_DUAL 3 + +#define DISPLAY_TYPE DISPLAY_TYPE_LIQUIDCRYSTAL +//#define DISPLAY_TYPE DISPLAY_TYPE_MODTRONIXLCD2S +//#define DISPLAY_TYPE DISPLAY_TYPE_DUAL + +/// Pin mappings for the LiquidCrystal class connection. #define LCD_RS_PIN Pin(PortC,4) #define LCD_ENABLE_PIN Pin(PortC,3) #define LCD_D0_PIN Pin(PortD,7) diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.cc b/firmware/src/Motherboard/boards/mb24/Motherboard.cc index 6857c80..8054366 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.cc +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.cc @@ -39,8 +39,6 @@ Motherboard::Motherboard() #if HAS_INTERFACE_BOARD > 0 : interfaceBoard( - buttonArray, - lcd, &mainMenu, &monitorMode) @@ -147,7 +145,7 @@ void Motherboard::reset() { interfaceBoard.pushScreen(&splashScreen); // Finally, set up the *** interface - interface::init(&interfaceBoard, &lcd); + interface::init(&interfaceBoard); interface_update_timeout.start(interfaceBoard.getUpdateRate()); } diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.hh b/firmware/src/Motherboard/boards/mb24/Motherboard.hh index e6f9fbf..aedcafb 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.hh +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.hh @@ -24,10 +24,7 @@ //#include "PSU.hh" #include "Configuration.hh" #include "Timeout.hh" -#include "Menu.hh" #include "InterfaceBoard.hh" -#include "LiquidCrystal.hh" -#include "ButtonArray.hh" /// Main class for Motherboard version 2.4+ (Gen4 electronics) @@ -77,8 +74,6 @@ private: /// True if we have an interface board attached bool hasInterfaceBoard; - ButtonArray buttonArray; - LiquidCrystal lcd; InterfaceBoard interfaceBoard; MainMenu mainMenu; ///< Main system menu diff --git a/firmware/src/shared/Display.hh b/firmware/src/shared/Display.hh index d1fd286..fc7c6fc 100644 --- a/firmware/src/shared/Display.hh +++ b/firmware/src/shared/Display.hh @@ -5,7 +5,6 @@ #include #include -#include "PinTmplt.hh" class Display { public: @@ -13,6 +12,8 @@ public: virtual void init() {}; virtual void clear() {}; + virtual size_t width() const { return 1; } + virtual size_t height() const { return 1; } virtual void setCursor(uint8_t, uint8_t) {}; virtual void write(uint8_t) {}; diff --git a/firmware/src/shared/DualDisplay.cc b/firmware/src/shared/DualDisplay.cc index 46feb9b..b293697 100644 --- a/firmware/src/shared/DualDisplay.cc +++ b/firmware/src/shared/DualDisplay.cc @@ -1,3 +1,6 @@ +#include "InterfaceBoard.hh" + +#if HAS_INTERFACE_BOARD > 0 #include "DualDisplay.hh" #include @@ -46,3 +49,4 @@ void DualDisplay::writeFromPgmspace(const prog_char message[]) { lcd2s.writeFromPgmspace(message); } +#endif // HAS_INTERFACE_BOARD > 0 diff --git a/firmware/src/shared/DualDisplay.hh b/firmware/src/shared/DualDisplay.hh index 090be26..fe50ea7 100644 --- a/firmware/src/shared/DualDisplay.hh +++ b/firmware/src/shared/DualDisplay.hh @@ -4,7 +4,6 @@ // TODO: Proper attribution #include -#include #include "Display.hh" #include "LiquidCrystal.hh" #include "ModtronixLCD2S.hh" @@ -14,6 +13,8 @@ public: DualDisplay() {} virtual void init(); virtual void clear(); + virtual size_t width() const { return 16; } + virtual size_t height() const { return 4; } virtual void setCursor(uint8_t col, uint8_t row); virtual void write(uint8_t); @@ -22,8 +23,8 @@ public: virtual void writeFromPgmspace(const prog_char message[]); private: - Display lcd; // provide a NULL display -// LiquidCrystal lcd; +// Display lcd; // provide a NULL display + LiquidCrystal lcd; ModtronixLCD2S lcd2s; }; diff --git a/firmware/src/shared/Interface.cc b/firmware/src/shared/Interface.cc index 2f0b9bb..b2cfd16 100644 --- a/firmware/src/shared/Interface.cc +++ b/firmware/src/shared/Interface.cc @@ -9,7 +9,6 @@ namespace interface { -LiquidCrystal* lcd; InterfaceBoard* board; bool isConnected() { @@ -43,9 +42,8 @@ bool isConnected() { } -void init(InterfaceBoard* board_in, LiquidCrystal* lcd_in) { +void init(InterfaceBoard* board_in) { board = board_in; - lcd = lcd_in; } void pushScreen(Screen* newScreen) { diff --git a/firmware/src/shared/Interface.hh b/firmware/src/shared/Interface.hh index 8cd055f..26a0e6d 100644 --- a/firmware/src/shared/Interface.hh +++ b/firmware/src/shared/Interface.hh @@ -22,15 +22,13 @@ #include "InterfaceBoard.hh" #if HAS_INTERFACE_BOARD > 0 #include "Types.hh" -#include "Menu.hh" -#include "LiquidCrystal.hh" // TODO: This style interface is weird; find a way to replace it. namespace interface { /// Set the current interface board and lcd. This *must* be called before using /// any of the functions in this interface. -void init(InterfaceBoard* board_in, LiquidCrystal* lcd_in); +void init(InterfaceBoard* board_in); /// Returns true if the interface board is connected bool isConnected(); diff --git a/firmware/src/shared/InterfaceBoard.cc b/firmware/src/shared/InterfaceBoard.cc index 508aa57..5dcdb90 100644 --- a/firmware/src/shared/InterfaceBoard.cc +++ b/firmware/src/shared/InterfaceBoard.cc @@ -2,18 +2,28 @@ #if HAS_INTERFACE_BOARD > 0 #include "Host.hh" - +#if DISPLAY_TYPE == DISPLAY_TYPE_LIQUIDCRYSTAL #include "LiquidCrystal.hh" +static LiquidCrystal globalDisplay; + +#elif DISPLAY_TYPE == DISPLAY_TYPE_MODTRONIXLCD2S +#include "ModtronixLCD2S.hh" +static ModtronixLCD2S globalDisplay; + +#elif DISPLAY_TYPE == DISPLAY_TYPE_DUAL +#include "DualDisplay.hh" +static DualDisplay globalDisplay; +#endif + #define foo_pin INTERFACE_FOO_PIN #define bar_pin INTERFACE_BAR_PIN -InterfaceBoard::InterfaceBoard(ButtonArray& buttons_in, - LiquidCrystal& lcd_in, - Screen* mainScreen_in, + + +InterfaceBoard::InterfaceBoard(Screen* mainScreen_in, Screen* buildScreen_in) : - buttons(buttons_in), - lcd(lcd_in) + display(globalDisplay) { buildScreen = buildScreen_in; mainScreen = mainScreen_in; @@ -22,7 +32,7 @@ InterfaceBoard::InterfaceBoard(ButtonArray& buttons_in, void InterfaceBoard::init() { buttons.init(); - lcd.init(); + display.init(); #if HAS_INTERFACE_BUTTONS > 0 foo_pin::setValue(false); @@ -74,7 +84,7 @@ void InterfaceBoard::doUpdate() { screenStack[screenIndex]->notifyButtonPressed(button); } - screenStack[screenIndex]->update(lcd, false); + screenStack[screenIndex]->update(display, false); } void InterfaceBoard::pushScreen(Screen* newScreen) { @@ -83,7 +93,7 @@ void InterfaceBoard::pushScreen(Screen* newScreen) { screenStack[screenIndex] = newScreen; } screenStack[screenIndex]->reset(); - screenStack[screenIndex]->update(lcd, true); + screenStack[screenIndex]->update(display, true); } void InterfaceBoard::popScreen() { @@ -92,7 +102,7 @@ void InterfaceBoard::popScreen() { screenIndex--; } - screenStack[screenIndex]->update(lcd, true); + screenStack[screenIndex]->update(display, true); } #endif // HAS_INTERFACE_BOARD > 0 diff --git a/firmware/src/shared/InterfaceBoard.hh b/firmware/src/shared/InterfaceBoard.hh index a373dd0..5993f5e 100644 --- a/firmware/src/shared/InterfaceBoard.hh +++ b/firmware/src/shared/InterfaceBoard.hh @@ -22,6 +22,7 @@ #include "Configuration.hh" #include "ButtonArray.hh" #if HAS_INTERFACE_BOARD > 0 +#include "Display.hh" #include "Menu.hh" /// Maximum number of screens that can be active at once. @@ -38,10 +39,10 @@ /// \ingroup HardwareLibraries class InterfaceBoard { public: - LiquidCrystal& lcd; ///< LCD to write to + Display& display; ///< LCD to write to private: - ButtonArray& buttons; ///< Button array to read from + ButtonArray buttons; ///< Button array to read from // TODO: Drop this? Screen* buildScreen; ///< Screen to display while building @@ -60,16 +61,9 @@ private: public: /// Construct an interface board. - /// \param[in] button array to read from - /// \param[in] LCD to display on - /// \param[in] Pin connected to the foo LED - /// \param[in] Pin connected to the bar LED /// \param[in] Main screen, shown as root display /// \param[in] Screen to display while building - InterfaceBoard( - ButtonArray& buttons_in, - LiquidCrystal& lcd_in, - Screen* mainScreen_in, + InterfaceBoard(Screen* mainScreen_in, Screen* buildScreen_in); /// Initialze the interface board. This needs to be called once diff --git a/firmware/src/shared/LiquidCrystal.cc b/firmware/src/shared/LiquidCrystal.cc index 27e1ef2..2945987 100755 --- a/firmware/src/shared/LiquidCrystal.cc +++ b/firmware/src/shared/LiquidCrystal.cc @@ -2,7 +2,7 @@ #include #include #include -#include "configuration.hh" +#include "InterfaceBoard.hh" #if HAS_INTERFACE_BOARD > 0 #include "LiquidCrystal.hh" @@ -89,7 +89,7 @@ LiquidCrystal::LiquidCrystal() void LiquidCrystal::init() { - begin(LCD_SCREEN_WIDTH, LCD_SCREEN_HEIGHT); + begin(width(), height()); clear(); home(); } diff --git a/firmware/src/shared/LiquidCrystal.hh b/firmware/src/shared/LiquidCrystal.hh index 3503478..8340e30 100755 --- a/firmware/src/shared/LiquidCrystal.hh +++ b/firmware/src/shared/LiquidCrystal.hh @@ -4,13 +4,8 @@ // TODO: Proper attribution #include -#include -#include "PinTmplt.hh" #include"Display.hh" -#define LCD_SCREEN_WIDTH 16 -#define LCD_SCREEN_HEIGHT 4 - // flags for function set #define LCD_8BITMODE 0x10 #define LCD_4BITMODE 0x00 @@ -30,8 +25,10 @@ public: void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); virtual void init(); - virtual void clear(); + virtual size_t width() const { return 16; } + virtual size_t height() const { return 4; } + void home(); void noDisplay(); diff --git a/firmware/src/shared/Menu.cc b/firmware/src/shared/Menu.cc index 2e54fa3..d1f655f 100644 --- a/firmware/src/shared/Menu.cc +++ b/firmware/src/shared/Menu.cc @@ -65,7 +65,7 @@ bool queryExtruderParameter(uint8_t parameter, OutPacket& responsePacket) { return true; } -void SplashScreen::update(LiquidCrystal& lcd, bool forceRedraw) { +void SplashScreen::update(Display& display, bool forceRedraw) { static PROGMEM prog_char splash1[] = " "; static PROGMEM prog_char splash2[] = " Thing-O-Matic "; static PROGMEM prog_char splash3[] = " --------- "; @@ -73,21 +73,21 @@ void SplashScreen::update(LiquidCrystal& lcd, bool forceRedraw) { if (forceRedraw) { - lcd.setCursor(0,0); - lcd.writeFromPgmspace(splash1); + display.setCursor(0,0); + display.writeFromPgmspace(splash1); - lcd.setCursor(0,1); - lcd.writeFromPgmspace(splash2); + display.setCursor(0,1); + display.writeFromPgmspace(splash2); - lcd.setCursor(0,2); - lcd.writeFromPgmspace(splash3); + display.setCursor(0,2); + display.writeFromPgmspace(splash3); - lcd.setCursor(0,3); - lcd.writeFromPgmspace(splash4); + display.setCursor(0,3); + display.writeFromPgmspace(splash4); } else { // The machine has started, so we're done! - interface::popScreen(); + interface::popScreen(); } } @@ -103,7 +103,7 @@ void JogMode::reset() { distanceChanged = false; } -void JogMode::update(LiquidCrystal& lcd, bool forceRedraw) { +void JogMode::update(Display& display, bool forceRedraw) { static PROGMEM prog_char jog1[] = "Jog mode: "; static PROGMEM prog_char jog2[] = " Y+ Z+"; static PROGMEM prog_char jog3[] = "X- X+ (mode)"; @@ -113,27 +113,27 @@ void JogMode::update(LiquidCrystal& lcd, bool forceRedraw) { static PROGMEM prog_char distanceLong[] = "LONG"; if (forceRedraw || distanceChanged) { - lcd.clear(); - lcd.setCursor(0,0); - lcd.writeFromPgmspace(jog1); + display.clear(); + display.setCursor(0,0); + display.writeFromPgmspace(jog1); switch (jogDistance) { case DISTANCE_SHORT: - lcd.writeFromPgmspace(distanceShort); + display.writeFromPgmspace(distanceShort); break; case DISTANCE_LONG: - lcd.writeFromPgmspace(distanceLong); + display.writeFromPgmspace(distanceLong); break; } - lcd.setCursor(0,1); - lcd.writeFromPgmspace(jog2); + display.setCursor(0,1); + display.writeFromPgmspace(jog2); - lcd.setCursor(0,2); - lcd.writeFromPgmspace(jog3); + display.setCursor(0,2); + display.writeFromPgmspace(jog3); - lcd.setCursor(0,3); - lcd.writeFromPgmspace(jog4); + display.setCursor(0,3); + display.writeFromPgmspace(jog4); distanceChanged = false; } @@ -205,7 +205,7 @@ void JogMode::notifyButtonPressed(ButtonArray::ButtonName button) { } -void SnakeMode::update(LiquidCrystal& lcd, bool forceRedraw) { +void SnakeMode::update(Display& display, bool forceRedraw) { static PROGMEM prog_char gameOver[] = "GAME OVER!"; // If we are dead, restart the game. @@ -214,22 +214,30 @@ void SnakeMode::update(LiquidCrystal& lcd, bool forceRedraw) { forceRedraw = true; } + if (appleReset) + { + // Put the apple in an initial position (this could collide with the snake!) + applePosition.x = rand()%display.width(); + applePosition.y = rand()%display.height(); + appleReset = false; + } + if (forceRedraw) { - lcd.clear(); + display.clear(); for (uint8_t i = 0; i < snakeLength; i++) { - lcd.setCursor(snakeBody[i].x, snakeBody[i].y); - lcd.write('O'); + display.setCursor(snakeBody[i].x, snakeBody[i].y); + display.write('O'); } } // Always redraw the apple, just in case. - lcd.setCursor(applePosition.x, applePosition.y); - lcd.write('*'); + display.setCursor(applePosition.x, applePosition.y); + display.write('*'); // First, undraw the snake's tail - lcd.setCursor(snakeBody[snakeLength-1].x, snakeBody[snakeLength-1].y); - lcd.write(' '); + display.setCursor(snakeBody[snakeLength-1].x, snakeBody[snakeLength-1].y); + display.write(' '); // Then, shift the snakes body parts back, deleting the tail for(int8_t i = snakeLength-1; i >= 0; i--) { @@ -240,22 +248,22 @@ void SnakeMode::update(LiquidCrystal& lcd, bool forceRedraw) { switch(snakeDirection) { case DIR_EAST: - snakeBody[0].x = (snakeBody[0].x + 1) % LCD_SCREEN_WIDTH; + snakeBody[0].x = (snakeBody[0].x + 1) % display.width(); break; case DIR_WEST: - snakeBody[0].x = (snakeBody[0].x + LCD_SCREEN_WIDTH - 1) % LCD_SCREEN_WIDTH; + snakeBody[0].x = (snakeBody[0].x + display.width() - 1) % display.width(); break; case DIR_NORTH: - snakeBody[0].y = (snakeBody[0].y + LCD_SCREEN_HEIGHT - 1) % LCD_SCREEN_HEIGHT; + snakeBody[0].y = (snakeBody[0].y + display.height() - 1) % display.height(); break; case DIR_SOUTH: - snakeBody[0].y = (snakeBody[0].y + 1) % LCD_SCREEN_HEIGHT; + snakeBody[0].y = (snakeBody[0].y + 1) % display.height(); break; } // Now, draw the snakes new head - lcd.setCursor(snakeBody[0].x, snakeBody[0].y); - lcd.write('O'); + display.setCursor(snakeBody[0].x, snakeBody[0].y); + display.write('O'); // Check if the snake has run into itself for (uint8_t i = 1; i < snakeLength; i++) { @@ -263,8 +271,8 @@ void SnakeMode::update(LiquidCrystal& lcd, bool forceRedraw) { && snakeBody[i].y == snakeBody[0].y) { snakeAlive = false; - lcd.setCursor(1,1); - lcd.writeFromPgmspace(gameOver); + display.setCursor(1,1); + display.writeFromPgmspace(gameOver); updateRate = 5000L * 1000L; } } @@ -279,11 +287,11 @@ void SnakeMode::update(LiquidCrystal& lcd, bool forceRedraw) { updateRate -= 5L * 1000L; } - applePosition.x = rand()%LCD_SCREEN_WIDTH; - applePosition.y = rand()%LCD_SCREEN_HEIGHT; + applePosition.x = rand()%display.width(); + applePosition.y = rand()%display.height(); - lcd.setCursor(applePosition.x, applePosition.y); - lcd.write('*'); + display.setCursor(applePosition.x, applePosition.y); + display.write('*'); } } @@ -299,29 +307,27 @@ void SnakeMode::reset() { snakeBody[1].x = 1; snakeBody[1].y = 1; snakeBody[2].x = 0; snakeBody[2].y = 1; - // Put the apple in an initial position (this could collide with the snake!) - applePosition.x = rand()%LCD_SCREEN_WIDTH; - applePosition.y = rand()%LCD_SCREEN_HEIGHT; + appleReset = true; } void SnakeMode::notifyButtonPressed(ButtonArray::ButtonName button) { switch (button) { case ButtonArray::YMINUS: - snakeDirection = DIR_SOUTH; - break; + snakeDirection = DIR_SOUTH; + break; case ButtonArray::YPLUS: - snakeDirection = DIR_NORTH; - break; + snakeDirection = DIR_NORTH; + break; case ButtonArray::XMINUS: - snakeDirection = DIR_WEST; - break; + snakeDirection = DIR_WEST; + break; case ButtonArray::XPLUS: - snakeDirection = DIR_EAST; - break; + snakeDirection = DIR_EAST; + break; case ButtonArray::CANCEL: - interface::popScreen(); - break; + interface::popScreen(); + break; } } @@ -330,31 +336,31 @@ void MonitorMode::reset() { updatePhase = 0; } -void MonitorMode::update(LiquidCrystal& lcd, bool forceRedraw) { +void MonitorMode::update(Display& display, bool forceRedraw) { static PROGMEM prog_char extruder_temp[] = "Tool: ---/---C"; static PROGMEM prog_char platform_temp[] = "Bed: ---/---C"; if (forceRedraw) { - lcd.clear(); - lcd.setCursor(0,0); + display.clear(); + display.setCursor(0,0); switch(host::getHostState()) { case host::HOST_STATE_READY: - lcd.writeString(host::getMachineName()); + display.writeString(host::getMachineName()); break; case host::HOST_STATE_BUILDING: case host::HOST_STATE_BUILDING_FROM_SD: - lcd.writeString(host::getBuildName()); + display.writeString(host::getBuildName()); break; case host::HOST_STATE_ERROR: - lcd.writeString("error!"); + display.writeString("error!"); break; } - lcd.setCursor(0,2); - lcd.writeFromPgmspace(extruder_temp); + display.setCursor(0,2); + display.writeFromPgmspace(extruder_temp); - lcd.setCursor(0,3); - lcd.writeFromPgmspace(platform_temp); + display.setCursor(0,3); + display.writeFromPgmspace(platform_temp); } else { } @@ -365,42 +371,42 @@ void MonitorMode::update(LiquidCrystal& lcd, bool forceRedraw) { // Redraw tool info switch (updatePhase) { case 0: - lcd.setCursor(6,2); + display.setCursor(6,2); if (queryExtruderParameter(SLAVE_CMD_GET_TEMP, responsePacket)) { uint16_t data = responsePacket.read16(1); - lcd.writeInt(data,3); + display.writeInt(data,3); } else { - lcd.writeString("XXX"); + display.writeString("XXX"); } break; case 1: - lcd.setCursor(10,2); + display.setCursor(10,2); if (queryExtruderParameter(SLAVE_CMD_GET_SP, responsePacket)) { uint16_t data = responsePacket.read16(1); - lcd.writeInt(data,3); + display.writeInt(data,3); } else { - lcd.writeString("XXX"); + display.writeString("XXX"); } break; case 2: - lcd.setCursor(6,3); + display.setCursor(6,3); if (queryExtruderParameter(SLAVE_CMD_GET_PLATFORM_TEMP, responsePacket)) { uint16_t data = responsePacket.read16(1); - lcd.writeInt(data,3); + display.writeInt(data,3); } else { - lcd.writeString("XXX"); + display.writeString("XXX"); } break; case 3: - lcd.setCursor(10,3); + display.setCursor(10,3); if (queryExtruderParameter(SLAVE_CMD_GET_PLATFORM_SP, responsePacket)) { uint16_t data = responsePacket.read16(1); - lcd.writeInt(data,3); + display.writeInt(data,3); } else { - lcd.writeString("XXX"); + display.writeString("XXX"); } break; } @@ -427,36 +433,36 @@ void MonitorMode::notifyButtonPressed(ButtonArray::ButtonName button) { } -void Menu::update(LiquidCrystal& lcd, bool forceRedraw) { +void Menu::update(Display& display, bool forceRedraw) { static PROGMEM prog_char blankLine[] = " "; // Do we need to redraw the whole menu? - if ((itemIndex/LCD_SCREEN_HEIGHT) != (lastDrawIndex/LCD_SCREEN_HEIGHT) + if ((itemIndex/display.height()) != (lastDrawIndex/display.height()) || forceRedraw ) { // Redraw the whole menu - lcd.clear(); + display.clear(); - for (uint8_t i = 0; i < LCD_SCREEN_HEIGHT; i++) { - // Instead of using lcd.clear(), clear one line at a time so there + for (uint8_t i = 0; i < display.height(); i++) { + // Instead of using display.clear(), clear one line at a time so there // is less screen flickr. - if (i+(itemIndex/LCD_SCREEN_HEIGHT)*LCD_SCREEN_HEIGHT +1 > itemCount) { + if (i+(itemIndex/display.height())*display.height() +1 > itemCount) { break; } - lcd.setCursor(1,i); + display.setCursor(1,i); // Draw one page of items at a time - drawItem(i+(itemIndex/LCD_SCREEN_HEIGHT)*LCD_SCREEN_HEIGHT, lcd); + drawItem(i+(itemIndex/display.height())*display.height(), display); } } else { // Only need to clear the previous cursor - lcd.setCursor(0,(lastDrawIndex%LCD_SCREEN_HEIGHT)); - lcd.write(' '); + display.setCursor(0,(lastDrawIndex%display.height())); + display.write(' '); } - lcd.setCursor(0,(itemIndex%LCD_SCREEN_HEIGHT)); - lcd.write('>'); + display.setCursor(0,(itemIndex%display.height())); + display.write('>'); lastDrawIndex = itemIndex; } @@ -520,22 +526,22 @@ void CancelBuildMenu::resetState() { firstItemIndex = 2; } -void CancelBuildMenu::drawItem(uint8_t index, LiquidCrystal& lcd) { +void CancelBuildMenu::drawItem(uint8_t index, Display& display) { static PROGMEM prog_char cancel[] = "Cancel Build?"; static PROGMEM prog_char yes[] = "Yes"; static PROGMEM prog_char no[] = "No"; switch (index) { case 0: - lcd.writeFromPgmspace(cancel); + display.writeFromPgmspace(cancel); break; case 1: break; case 2: - lcd.writeFromPgmspace(yes); + display.writeFromPgmspace(yes); break; case 3: - lcd.writeFromPgmspace(no); + display.writeFromPgmspace(no); break; } } @@ -561,7 +567,7 @@ MainMenu::MainMenu() { reset(); } -void MainMenu::drawItem(uint8_t index, LiquidCrystal& lcd) { +void MainMenu::drawItem(uint8_t index, Display& display) { static PROGMEM prog_char monitor[] = "Monitor Mode"; static PROGMEM prog_char build[] = "Build from SD"; static PROGMEM prog_char jog[] = "Jog Mode"; @@ -569,19 +575,19 @@ void MainMenu::drawItem(uint8_t index, LiquidCrystal& lcd) { switch (index) { case 0: - lcd.writeFromPgmspace(monitor); + display.writeFromPgmspace(monitor); break; case 1: - lcd.writeFromPgmspace(build); + display.writeFromPgmspace(build); break; case 2: - lcd.writeFromPgmspace(jog); + display.writeFromPgmspace(jog); break; case 3: // blank break; case 4: - lcd.writeFromPgmspace(snake); + display.writeFromPgmspace(snake); break; } } @@ -678,13 +684,13 @@ bool SDMenu::getFilename(uint8_t index, char buffer[], uint8_t buffer_size) { return true; } -void SDMenu::drawItem(uint8_t index, LiquidCrystal& lcd) { +void SDMenu::drawItem(uint8_t index, Display& display) { if (index > itemCount - 1) { // TODO: report error return; } - const uint8_t MAX_FILE_LEN = LCD_SCREEN_WIDTH; + const uint8_t MAX_FILE_LEN = display.width(); char fnbuf[MAX_FILE_LEN]; if ( !getFilename(index, fnbuf, MAX_FILE_LEN) ) { @@ -694,7 +700,7 @@ void SDMenu::drawItem(uint8_t index, LiquidCrystal& lcd) { uint8_t idx; for (idx = 0; (idx < MAX_FILE_LEN) && (fnbuf[idx] != 0); idx++) { - lcd.write(fnbuf[idx]); + display.write(fnbuf[idx]); } } diff --git a/firmware/src/shared/Menu.hh b/firmware/src/shared/Menu.hh index ffa5c3c..c574e3f 100644 --- a/firmware/src/shared/Menu.hh +++ b/firmware/src/shared/Menu.hh @@ -4,8 +4,6 @@ #if HAS_INTERFACE_BOARD > 0 #include "Types.hh" -#include "ButtonArray.hh" -#include "LiquidCrystal.hh" /// The screen class defines a standard interface for anything that should /// be displayed on the LCD. @@ -23,7 +21,7 @@ public: /// \param[in] lcd LCD to write to /// \param[in] forceRedraw if true, redraw the entire screen. If false, /// only updated sections need to be redrawn. - virtual void update(LiquidCrystal& lcd, bool forceRedraw); + virtual void update(Display& display, bool forceRedraw); /// Reset the screen to it's default state virtual void reset(); @@ -47,7 +45,7 @@ class Menu: public Screen { public: micros_t getUpdateRate() {return 500L * 1000L;} - void update(LiquidCrystal& lcd, bool forceRedraw); + void update(Display& display, bool forceRedraw); void reset(); @@ -67,7 +65,7 @@ protected: /// Draw an item at the current cursor position. /// \param[in] index Index of the item to draw /// \param[in] LCD screen to draw onto - virtual void drawItem(uint8_t index, LiquidCrystal& lcd); + virtual void drawItem(uint8_t index, Display& display); /// Handle selection of a menu item /// \param[in] index Index of the menu item that was selected @@ -84,7 +82,7 @@ class SplashScreen: public Screen { public: micros_t getUpdateRate() {return 50L * 1000L;} - void update(LiquidCrystal& lcd, bool forceRedraw); + void update(Display& display, bool forceRedraw); void reset(); @@ -107,7 +105,7 @@ private: public: micros_t getUpdateRate() {return 50L * 1000L;} - void update(LiquidCrystal& lcd, bool forceRedraw); + void update(Display& display, bool forceRedraw); void reset(); @@ -142,6 +140,7 @@ private: bool snakeAlive; // The state of our snake direction_t snakeDirection; // The direction the snake is heading coord_t applePosition; // Location of the apple + bool appleReset; uint8_t applesEaten; // Number of apples that have been eaten // int gameSpeed = START_SPEED; // Speed of the game (in ms per turn) @@ -150,7 +149,7 @@ public: micros_t getUpdateRate() {return updateRate;} // Refresh the display information - void update(LiquidCrystal& lcd, bool forceRedraw); + void update(Display& display, bool forceRedraw); void reset(); @@ -171,7 +170,7 @@ protected: char buffer[], uint8_t buffer_size); - void drawItem(uint8_t index, LiquidCrystal& lcd); + void drawItem(uint8_t index, Display& display); void handleSelect(uint8_t index); }; @@ -183,7 +182,7 @@ public: void resetState(); protected: - void drawItem(uint8_t index, LiquidCrystal& lcd); + void drawItem(uint8_t index, Display& display); void handleSelect(uint8_t index); }; @@ -198,7 +197,7 @@ private: public: micros_t getUpdateRate() {return 500L * 1000L;} - void update(LiquidCrystal& lcd, bool forceRedraw); + void update(Display& display, bool forceRedraw); void reset(); @@ -211,7 +210,7 @@ public: MainMenu(); protected: - void drawItem(uint8_t index, LiquidCrystal& lcd); + void drawItem(uint8_t index, Display& display); void handleSelect(uint8_t index); diff --git a/firmware/src/shared/ModtronixLCD2S.hh b/firmware/src/shared/ModtronixLCD2S.hh index df2cf5c..5357a75 100644 --- a/firmware/src/shared/ModtronixLCD2S.hh +++ b/firmware/src/shared/ModtronixLCD2S.hh @@ -3,7 +3,6 @@ #ifndef _MODTRONIXLCD2S_H #define _MODTRONIXLCD2S_H -#include #include "display.hh" class ModtronixLCD2S : public Display { @@ -15,6 +14,9 @@ public: virtual void init(); virtual void clear(); + virtual size_t width() const { return 16; } + virtual size_t height() const { return 4; } + virtual void setCursor(uint8_t col, uint8_t row) { return set_position(row+1,col+1); } virtual void write(uint8_t value) { return write_char(value); } From c193f8a48debb776a1032b4d83b9056464c2e924 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sat, 19 Nov 2011 12:11:41 -0800 Subject: [PATCH 11/39] customize CraigBot --- firmware/src/Motherboard/boards/mb24/Configuration.hh | 4 ++-- firmware/src/shared/Menu.cc | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/firmware/src/Motherboard/boards/mb24/Configuration.hh b/firmware/src/Motherboard/boards/mb24/Configuration.hh index 1bc7f20..20e7b79 100644 --- a/firmware/src/Motherboard/boards/mb24/Configuration.hh +++ b/firmware/src/Motherboard/boards/mb24/Configuration.hh @@ -78,8 +78,8 @@ // --- Axis configuration --- // Define the number of stepper axes supported by the board. The axes are -// denoted by X, Y, Z, A and B. -#define STEPPER_COUNT 5 +// denoted by X, Y, Z, B and A. +#define STEPPER_COUNT 4 // --- Stepper and endstop configuration --- diff --git a/firmware/src/shared/Menu.cc b/firmware/src/shared/Menu.cc index d1f655f..48a5193 100644 --- a/firmware/src/shared/Menu.cc +++ b/firmware/src/shared/Menu.cc @@ -66,10 +66,10 @@ bool queryExtruderParameter(uint8_t parameter, OutPacket& responsePacket) { } void SplashScreen::update(Display& display, bool forceRedraw) { - static PROGMEM prog_char splash1[] = " "; - static PROGMEM prog_char splash2[] = " Thing-O-Matic "; - static PROGMEM prog_char splash3[] = " --------- "; - static PROGMEM prog_char splash4[] = " "; + static PROGMEM prog_char splash1[] = " CraigBot "; + static PROGMEM prog_char splash2[] = " ---------- "; + static PROGMEM prog_char splash3[] = " Cupcake CNC "; + static PROGMEM prog_char splash4[] = " #545 "; if (forceRedraw) { From c3341e1e92b126a3c276a22e5601728dc492a766 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sat, 19 Nov 2011 12:13:16 -0800 Subject: [PATCH 12/39] display monitor if now interface buttons are present --- firmware/src/Motherboard/boards/mb24/Motherboard.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.cc b/firmware/src/Motherboard/boards/mb24/Motherboard.cc index 8054366..2e19bb4 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.cc +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.cc @@ -39,7 +39,11 @@ Motherboard::Motherboard() #if HAS_INTERFACE_BOARD > 0 : interfaceBoard( +#if HAS_INTERFACE_BUTTONS > 0 &mainMenu, +#else + &monitorMode, +#endif // HAS_INTERFACE_BUTTONS > 0 &monitorMode) #endif // HAS_INTERFACE_BOARD > 0 From dd184f9352a0934dcb21123f1cc4792607d1c912 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sat, 19 Nov 2011 12:14:52 -0800 Subject: [PATCH 13/39] set the display type --- firmware/src/Motherboard/boards/mb24/Configuration.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/src/Motherboard/boards/mb24/Configuration.hh b/firmware/src/Motherboard/boards/mb24/Configuration.hh index 20e7b79..9964d48 100644 --- a/firmware/src/Motherboard/boards/mb24/Configuration.hh +++ b/firmware/src/Motherboard/boards/mb24/Configuration.hh @@ -154,8 +154,8 @@ #define DISPLAY_TYPE_MODTRONIXLCD2S 2 #define DISPLAY_TYPE_DUAL 3 -#define DISPLAY_TYPE DISPLAY_TYPE_LIQUIDCRYSTAL -//#define DISPLAY_TYPE DISPLAY_TYPE_MODTRONIXLCD2S +//#define DISPLAY_TYPE DISPLAY_TYPE_LIQUIDCRYSTAL +#define DISPLAY_TYPE DISPLAY_TYPE_MODTRONIXLCD2S //#define DISPLAY_TYPE DISPLAY_TYPE_DUAL /// Pin mappings for the LiquidCrystal class connection. From 4601bfa9ea9f44364a59e9a5398bee90e1b2a10a Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sat, 19 Nov 2011 12:15:16 -0800 Subject: [PATCH 14/39] turn on interface buttons --- firmware/src/Motherboard/boards/mb24/Configuration.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/src/Motherboard/boards/mb24/Configuration.hh b/firmware/src/Motherboard/boards/mb24/Configuration.hh index e2535c0..46233e3 100644 --- a/firmware/src/Motherboard/boards/mb24/Configuration.hh +++ b/firmware/src/Motherboard/boards/mb24/Configuration.hh @@ -172,7 +172,7 @@ /// modified, the #scanButtons() function _must_ be updated to reflect this. /// /// TLDR: These are here for decoration only, actual pins defined in #scanButtons() -#define HAS_INTERFACE_BUTTONS 0 +#define HAS_INTERFACE_BUTTONS 1 #if HAS_INTERFACE_BUTTONS > 0 #define INTERFACE_X+_PIN Pin(PortL,7) #define INTERFACE_X-_PIN Pin(PortL,6) From 9283ec577c9ae5cf63262645209f824cc2ae04a3 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sat, 19 Nov 2011 12:43:51 -0800 Subject: [PATCH 15/39] turn off interface buttons --- firmware/src/Motherboard/boards/mb24/Configuration.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/src/Motherboard/boards/mb24/Configuration.hh b/firmware/src/Motherboard/boards/mb24/Configuration.hh index 9673bc8..9964d48 100644 --- a/firmware/src/Motherboard/boards/mb24/Configuration.hh +++ b/firmware/src/Motherboard/boards/mb24/Configuration.hh @@ -172,7 +172,7 @@ /// modified, the #scanButtons() function _must_ be updated to reflect this. /// /// TLDR: These are here for decoration only, actual pins defined in #scanButtons() -#define HAS_INTERFACE_BUTTONS 1 +#define HAS_INTERFACE_BUTTONS 0 #if HAS_INTERFACE_BUTTONS > 0 #define INTERFACE_X+_PIN Pin(PortL,7) #define INTERFACE_X-_PIN Pin(PortL,6) From ddb13eba98f7799ae5a88231751b0058fe1ce1b4 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sat, 19 Nov 2011 17:12:51 -0800 Subject: [PATCH 16/39] initialize the interface outside of the atomic block because we need interupts for twi. add static debug message to out text to lcd screen --- firmware/src/Motherboard/Main.cc | 16 +++++++++------- .../src/Motherboard/boards/mb24/Configuration.hh | 2 ++ .../src/Motherboard/boards/mb24/Motherboard.cc | 5 ++--- .../src/Motherboard/boards/mb24/Motherboard.hh | 2 ++ firmware/src/shared/Display.hh | 1 - firmware/src/shared/InterfaceBoard.cc | 16 ++++++++++++++-- firmware/src/shared/InterfaceBoard.hh | 2 ++ 7 files changed, 31 insertions(+), 13 deletions(-) diff --git a/firmware/src/Motherboard/Main.cc b/firmware/src/Motherboard/Main.cc index 6fb7001..738292d 100644 --- a/firmware/src/Motherboard/Main.cc +++ b/firmware/src/Motherboard/Main.cc @@ -30,8 +30,8 @@ #include "EepromMap.hh" void reset(bool hard_reset) { + Motherboard& board = Motherboard::getBoard(); ATOMIC_BLOCK(ATOMIC_FORCEON) { - Motherboard& board = Motherboard::getBoard(); sdcard::reset(); steppers::abort(); command::reset(); @@ -39,6 +39,8 @@ void reset(bool hard_reset) { board.reset(); } + board.initInterfaceBoard(); + // If we've just come from a hard reset, wait for 2.5 seconds before // trying to ping an extruder. This gives the extruder time to boot // before we send it a packet. @@ -49,12 +51,11 @@ void reset(bool hard_reset) { tool::test(); // Run test } - ATOMIC_BLOCK(ATOMIC_FORCEON) { - if (!tool::reset()) - { - // Fail, but let it go; toggling the PSU is dangerous. - } - } + if (!tool::reset()) + { + // Fail, but let it go; toggling the PSU is dangerous. + } + } int main() { @@ -71,6 +72,7 @@ int main() { command::runCommandSlice(); // Motherboard slice board.runMotherboardSlice(); + } return 0; } diff --git a/firmware/src/Motherboard/boards/mb24/Configuration.hh b/firmware/src/Motherboard/boards/mb24/Configuration.hh index 9964d48..160ad8c 100644 --- a/firmware/src/Motherboard/boards/mb24/Configuration.hh +++ b/firmware/src/Motherboard/boards/mb24/Configuration.hh @@ -150,10 +150,12 @@ #define HAS_INTERFACE_BOARD 1 #if HAS_INTERFACE_BOARD > 0 +#define DISPLAY_TYPE_NONE 0 #define DISPLAY_TYPE_LIQUIDCRYSTAL 1 #define DISPLAY_TYPE_MODTRONIXLCD2S 2 #define DISPLAY_TYPE_DUAL 3 +//#define DISPLAY_TYPE DISPLAY_TYPE_NONE //#define DISPLAY_TYPE DISPLAY_TYPE_LIQUIDCRYSTAL #define DISPLAY_TYPE DISPLAY_TYPE_MODTRONIXLCD2S //#define DISPLAY_TYPE DISPLAY_TYPE_DUAL diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.cc b/firmware/src/Motherboard/boards/mb24/Motherboard.cc index 2e19bb4..91607dd 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.cc +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.cc @@ -137,7 +137,9 @@ void Motherboard::reset() { TIMSK2 = 0x01; // OVF flag on // Configure the debug pin. DEBUG_PIN::setDirection(true); +} +void Motherboard::initInterfaceBoard() { #if HAS_INTERFACE_BOARD > 0 // Check if the interface board is attached hasInterfaceBoard = interface::isConnected(); @@ -154,9 +156,6 @@ void Motherboard::reset() { interface_update_timeout.start(interfaceBoard.getUpdateRate()); } #endif // HAS_INTERFACE_BOARD > 0 - - // Blindly try to reset the toolhead with index 0. -// resetToolhead(); } /// Get the number of microseconds that have passed since diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.hh b/firmware/src/Motherboard/boards/mb24/Motherboard.hh index aedcafb..7c8a001 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.hh +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.hh @@ -87,6 +87,8 @@ public: /// to any attached toolheads. void reset(); + void initInterfaceBoard(); + void runMotherboardSlice(); /// Count the number of steppers available on this board. diff --git a/firmware/src/shared/Display.hh b/firmware/src/shared/Display.hh index fc7c6fc..116c938 100644 --- a/firmware/src/shared/Display.hh +++ b/firmware/src/shared/Display.hh @@ -22,7 +22,6 @@ public: virtual void writeFromPgmspace(const prog_char message[]) {}; // note: the base interface provides a NULL Display implementation which does nothing. - }; #endif // LIQUID_CRYSTAL_HH diff --git a/firmware/src/shared/InterfaceBoard.cc b/firmware/src/shared/InterfaceBoard.cc index 5dcdb90..deb1b5e 100644 --- a/firmware/src/shared/InterfaceBoard.cc +++ b/firmware/src/shared/InterfaceBoard.cc @@ -2,7 +2,11 @@ #if HAS_INTERFACE_BOARD > 0 #include "Host.hh" -#if DISPLAY_TYPE == DISPLAY_TYPE_LIQUIDCRYSTAL +#if DISPLAY_TYPE == DISPLAY_TYPE_NONE +#include "Display.hh" +static Display globalDisplay; + +#elif DISPLAY_TYPE == DISPLAY_TYPE_LIQUIDCRYSTAL #include "LiquidCrystal.hh" static LiquidCrystal globalDisplay; @@ -19,7 +23,14 @@ static DualDisplay globalDisplay; #define foo_pin INTERFACE_FOO_PIN #define bar_pin INTERFACE_BAR_PIN - +void InterfaceBoard::Debug(const char message[]) +{ + static uint16_t row = 0; + globalDisplay.setCursor(0,row++%globalDisplay.height()); + globalDisplay.writeInt(row,4); + globalDisplay.write(' '); + globalDisplay.writeString(message); +} InterfaceBoard::InterfaceBoard(Screen* mainScreen_in, Screen* buildScreen_in) : @@ -29,6 +40,7 @@ InterfaceBoard::InterfaceBoard(Screen* mainScreen_in, mainScreen = mainScreen_in; } + void InterfaceBoard::init() { buttons.init(); diff --git a/firmware/src/shared/InterfaceBoard.hh b/firmware/src/shared/InterfaceBoard.hh index 5993f5e..ade1d76 100644 --- a/firmware/src/shared/InterfaceBoard.hh +++ b/firmware/src/shared/InterfaceBoard.hh @@ -90,6 +90,8 @@ public: void doUpdate(); void showMonitorMode(); + + static void Debug(const char message[]); }; #endif #endif From e412ae143819f5e1d552ce72d8670a2b83b03b6d Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sat, 19 Nov 2011 17:13:04 -0800 Subject: [PATCH 17/39] delete unused file --- firmware/src/shared/StepperInterface.cc | 92 ------------------------- 1 file changed, 92 deletions(-) delete mode 100644 firmware/src/shared/StepperInterface.cc diff --git a/firmware/src/shared/StepperInterface.cc b/firmware/src/shared/StepperInterface.cc deleted file mode 100644 index f021fae..0000000 --- a/firmware/src/shared/StepperInterface.cc +++ /dev/null @@ -1,92 +0,0 @@ -#if 0 -/* - * Copyright 2010 by Adam Mayer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - */ - -#include "StepperInterface.hh" -#include "Eeprom.hh" -#include "EepromMap.hh" -#include "Configuration.hh" - -StepperInterface::StepperInterface(const Pin& dir, - const Pin& step, - const Pin& enable, - const Pin& max, - const Pin& min, - const uint16_t eeprom_base_in) : - dir_pin(dir), - step_pin(step), - enable_pin(enable), - max_pin(max), - min_pin(min), - invert_endstops(true), - invert_axis(false), - eeprom_base(eeprom_base_in) { -} - -void StepperInterface::setDirection(bool forward) { - if (invert_axis) forward = !forward; - dir_pin.setValue(forward); -} - -void StepperInterface::step(bool value) { - step_pin.setValue(value); -} - -void StepperInterface::setEnabled(bool enabled) { - // The A3982 stepper driver chip has an inverted enable. - enable_pin.setValue(!enabled); -} - -bool StepperInterface::isAtMaximum() { - if (max_pin.isNull()) return false; - bool v = max_pin.getValue(); - if (invert_endstops) v = !v; - return v; -} - -bool StepperInterface::isAtMinimum() { - if (min_pin.isNull()) return false; - bool v = min_pin.getValue(); - if (invert_endstops) v = !v; - return v; -} - -void StepperInterface::init(uint8_t idx) { - dir_pin.setDirection(true); - step_pin.setDirection(true); - enable_pin.setValue(true); - enable_pin.setDirection(true); - // get inversion characteristics - uint8_t axes_invert = eeprom::getEeprom8(eeprom_base, 1<<1); - uint8_t endstops_invert = eeprom::getEeprom8(eeprom_base + 1, 0); - bool endstops_present = (endstops_invert & (1<<7)) != 0; - - // If endstops are not present, then we consider them inverted, since they will - // always register as high (pulled up). - invert_endstops = !endstops_present || ((endstops_invert & (1< Date: Sat, 19 Nov 2011 17:13:24 -0800 Subject: [PATCH 18/39] adjust width of modtronix screen --- firmware/src/shared/ModtronixLCD2S.cc | 3 ++- firmware/src/shared/ModtronixLCD2S.hh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/firmware/src/shared/ModtronixLCD2S.cc b/firmware/src/shared/ModtronixLCD2S.cc index 4673ed4..65bb671 100644 --- a/firmware/src/shared/ModtronixLCD2S.cc +++ b/firmware/src/shared/ModtronixLCD2S.cc @@ -44,7 +44,8 @@ ModtronixLCD2S::ModtronixLCD2S(uint8_t addr) void ModtronixLCD2S::init() { twi_init(); - //write_string("\fhello\nZeus"); +// clear(); +// home(); } void ModtronixLCD2S::remember() diff --git a/firmware/src/shared/ModtronixLCD2S.hh b/firmware/src/shared/ModtronixLCD2S.hh index 5357a75..f93f5df 100644 --- a/firmware/src/shared/ModtronixLCD2S.hh +++ b/firmware/src/shared/ModtronixLCD2S.hh @@ -14,7 +14,7 @@ public: virtual void init(); virtual void clear(); - virtual size_t width() const { return 16; } + virtual size_t width() const { return 20; } virtual size_t height() const { return 4; } virtual void setCursor(uint8_t col, uint8_t row) { return set_position(row+1,col+1); } From 6b218a951ea3ae59503eccf8d926ef172210d1c0 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sat, 19 Nov 2011 17:20:19 -0800 Subject: [PATCH 19/39] initialize the interface outside of the atomic block because we need interupts for twi. add static debug message to out text to lcd screen --- firmware/src/Motherboard/Main.cc | 16 +++++++++------- .../src/Motherboard/boards/mb24/Configuration.hh | 2 ++ .../src/Motherboard/boards/mb24/Motherboard.cc | 5 ++--- .../src/Motherboard/boards/mb24/Motherboard.hh | 2 ++ firmware/src/shared/Display.hh | 1 - firmware/src/shared/InterfaceBoard.cc | 16 ++++++++++++++-- firmware/src/shared/InterfaceBoard.hh | 2 ++ 7 files changed, 31 insertions(+), 13 deletions(-) diff --git a/firmware/src/Motherboard/Main.cc b/firmware/src/Motherboard/Main.cc index 6fb7001..738292d 100644 --- a/firmware/src/Motherboard/Main.cc +++ b/firmware/src/Motherboard/Main.cc @@ -30,8 +30,8 @@ #include "EepromMap.hh" void reset(bool hard_reset) { + Motherboard& board = Motherboard::getBoard(); ATOMIC_BLOCK(ATOMIC_FORCEON) { - Motherboard& board = Motherboard::getBoard(); sdcard::reset(); steppers::abort(); command::reset(); @@ -39,6 +39,8 @@ void reset(bool hard_reset) { board.reset(); } + board.initInterfaceBoard(); + // If we've just come from a hard reset, wait for 2.5 seconds before // trying to ping an extruder. This gives the extruder time to boot // before we send it a packet. @@ -49,12 +51,11 @@ void reset(bool hard_reset) { tool::test(); // Run test } - ATOMIC_BLOCK(ATOMIC_FORCEON) { - if (!tool::reset()) - { - // Fail, but let it go; toggling the PSU is dangerous. - } - } + if (!tool::reset()) + { + // Fail, but let it go; toggling the PSU is dangerous. + } + } int main() { @@ -71,6 +72,7 @@ int main() { command::runCommandSlice(); // Motherboard slice board.runMotherboardSlice(); + } return 0; } diff --git a/firmware/src/Motherboard/boards/mb24/Configuration.hh b/firmware/src/Motherboard/boards/mb24/Configuration.hh index 46233e3..338bb4e 100644 --- a/firmware/src/Motherboard/boards/mb24/Configuration.hh +++ b/firmware/src/Motherboard/boards/mb24/Configuration.hh @@ -150,10 +150,12 @@ #define HAS_INTERFACE_BOARD 1 #if HAS_INTERFACE_BOARD > 0 +#define DISPLAY_TYPE_NONE 0 #define DISPLAY_TYPE_LIQUIDCRYSTAL 1 #define DISPLAY_TYPE_MODTRONIXLCD2S 2 #define DISPLAY_TYPE_DUAL 3 +//#define DISPLAY_TYPE DISPLAY_TYPE_NONE #define DISPLAY_TYPE DISPLAY_TYPE_LIQUIDCRYSTAL //#define DISPLAY_TYPE DISPLAY_TYPE_MODTRONIXLCD2S //#define DISPLAY_TYPE DISPLAY_TYPE_DUAL diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.cc b/firmware/src/Motherboard/boards/mb24/Motherboard.cc index 2e19bb4..91607dd 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.cc +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.cc @@ -137,7 +137,9 @@ void Motherboard::reset() { TIMSK2 = 0x01; // OVF flag on // Configure the debug pin. DEBUG_PIN::setDirection(true); +} +void Motherboard::initInterfaceBoard() { #if HAS_INTERFACE_BOARD > 0 // Check if the interface board is attached hasInterfaceBoard = interface::isConnected(); @@ -154,9 +156,6 @@ void Motherboard::reset() { interface_update_timeout.start(interfaceBoard.getUpdateRate()); } #endif // HAS_INTERFACE_BOARD > 0 - - // Blindly try to reset the toolhead with index 0. -// resetToolhead(); } /// Get the number of microseconds that have passed since diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.hh b/firmware/src/Motherboard/boards/mb24/Motherboard.hh index aedcafb..7c8a001 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.hh +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.hh @@ -87,6 +87,8 @@ public: /// to any attached toolheads. void reset(); + void initInterfaceBoard(); + void runMotherboardSlice(); /// Count the number of steppers available on this board. diff --git a/firmware/src/shared/Display.hh b/firmware/src/shared/Display.hh index fc7c6fc..116c938 100644 --- a/firmware/src/shared/Display.hh +++ b/firmware/src/shared/Display.hh @@ -22,7 +22,6 @@ public: virtual void writeFromPgmspace(const prog_char message[]) {}; // note: the base interface provides a NULL Display implementation which does nothing. - }; #endif // LIQUID_CRYSTAL_HH diff --git a/firmware/src/shared/InterfaceBoard.cc b/firmware/src/shared/InterfaceBoard.cc index 5dcdb90..deb1b5e 100644 --- a/firmware/src/shared/InterfaceBoard.cc +++ b/firmware/src/shared/InterfaceBoard.cc @@ -2,7 +2,11 @@ #if HAS_INTERFACE_BOARD > 0 #include "Host.hh" -#if DISPLAY_TYPE == DISPLAY_TYPE_LIQUIDCRYSTAL +#if DISPLAY_TYPE == DISPLAY_TYPE_NONE +#include "Display.hh" +static Display globalDisplay; + +#elif DISPLAY_TYPE == DISPLAY_TYPE_LIQUIDCRYSTAL #include "LiquidCrystal.hh" static LiquidCrystal globalDisplay; @@ -19,7 +23,14 @@ static DualDisplay globalDisplay; #define foo_pin INTERFACE_FOO_PIN #define bar_pin INTERFACE_BAR_PIN - +void InterfaceBoard::Debug(const char message[]) +{ + static uint16_t row = 0; + globalDisplay.setCursor(0,row++%globalDisplay.height()); + globalDisplay.writeInt(row,4); + globalDisplay.write(' '); + globalDisplay.writeString(message); +} InterfaceBoard::InterfaceBoard(Screen* mainScreen_in, Screen* buildScreen_in) : @@ -29,6 +40,7 @@ InterfaceBoard::InterfaceBoard(Screen* mainScreen_in, mainScreen = mainScreen_in; } + void InterfaceBoard::init() { buttons.init(); diff --git a/firmware/src/shared/InterfaceBoard.hh b/firmware/src/shared/InterfaceBoard.hh index 5993f5e..ade1d76 100644 --- a/firmware/src/shared/InterfaceBoard.hh +++ b/firmware/src/shared/InterfaceBoard.hh @@ -90,6 +90,8 @@ public: void doUpdate(); void showMonitorMode(); + + static void Debug(const char message[]); }; #endif #endif From b0350c1be52bdeaea43d10c8903746f69f297b93 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sat, 19 Nov 2011 17:13:04 -0800 Subject: [PATCH 20/39] delete unused file --- firmware/src/shared/StepperInterface.cc | 92 ------------------------- 1 file changed, 92 deletions(-) delete mode 100644 firmware/src/shared/StepperInterface.cc diff --git a/firmware/src/shared/StepperInterface.cc b/firmware/src/shared/StepperInterface.cc deleted file mode 100644 index f021fae..0000000 --- a/firmware/src/shared/StepperInterface.cc +++ /dev/null @@ -1,92 +0,0 @@ -#if 0 -/* - * Copyright 2010 by Adam Mayer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - */ - -#include "StepperInterface.hh" -#include "Eeprom.hh" -#include "EepromMap.hh" -#include "Configuration.hh" - -StepperInterface::StepperInterface(const Pin& dir, - const Pin& step, - const Pin& enable, - const Pin& max, - const Pin& min, - const uint16_t eeprom_base_in) : - dir_pin(dir), - step_pin(step), - enable_pin(enable), - max_pin(max), - min_pin(min), - invert_endstops(true), - invert_axis(false), - eeprom_base(eeprom_base_in) { -} - -void StepperInterface::setDirection(bool forward) { - if (invert_axis) forward = !forward; - dir_pin.setValue(forward); -} - -void StepperInterface::step(bool value) { - step_pin.setValue(value); -} - -void StepperInterface::setEnabled(bool enabled) { - // The A3982 stepper driver chip has an inverted enable. - enable_pin.setValue(!enabled); -} - -bool StepperInterface::isAtMaximum() { - if (max_pin.isNull()) return false; - bool v = max_pin.getValue(); - if (invert_endstops) v = !v; - return v; -} - -bool StepperInterface::isAtMinimum() { - if (min_pin.isNull()) return false; - bool v = min_pin.getValue(); - if (invert_endstops) v = !v; - return v; -} - -void StepperInterface::init(uint8_t idx) { - dir_pin.setDirection(true); - step_pin.setDirection(true); - enable_pin.setValue(true); - enable_pin.setDirection(true); - // get inversion characteristics - uint8_t axes_invert = eeprom::getEeprom8(eeprom_base, 1<<1); - uint8_t endstops_invert = eeprom::getEeprom8(eeprom_base + 1, 0); - bool endstops_present = (endstops_invert & (1<<7)) != 0; - - // If endstops are not present, then we consider them inverted, since they will - // always register as high (pulled up). - invert_endstops = !endstops_present || ((endstops_invert & (1< Date: Sat, 19 Nov 2011 17:13:24 -0800 Subject: [PATCH 21/39] adjust width of modtronix screen --- firmware/src/shared/ModtronixLCD2S.cc | 3 ++- firmware/src/shared/ModtronixLCD2S.hh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/firmware/src/shared/ModtronixLCD2S.cc b/firmware/src/shared/ModtronixLCD2S.cc index 4673ed4..65bb671 100644 --- a/firmware/src/shared/ModtronixLCD2S.cc +++ b/firmware/src/shared/ModtronixLCD2S.cc @@ -44,7 +44,8 @@ ModtronixLCD2S::ModtronixLCD2S(uint8_t addr) void ModtronixLCD2S::init() { twi_init(); - //write_string("\fhello\nZeus"); +// clear(); +// home(); } void ModtronixLCD2S::remember() diff --git a/firmware/src/shared/ModtronixLCD2S.hh b/firmware/src/shared/ModtronixLCD2S.hh index 5357a75..f93f5df 100644 --- a/firmware/src/shared/ModtronixLCD2S.hh +++ b/firmware/src/shared/ModtronixLCD2S.hh @@ -14,7 +14,7 @@ public: virtual void init(); virtual void clear(); - virtual size_t width() const { return 16; } + virtual size_t width() const { return 20; } virtual size_t height() const { return 4; } virtual void setCursor(uint8_t col, uint8_t row) { return set_position(row+1,col+1); } From 0c8a6a08cf8e107948c72a0f097548fc6890010b Mon Sep 17 00:00:00 2001 From: Craig Link Date: Mon, 21 Nov 2011 21:45:52 -0800 Subject: [PATCH 22/39] fix liquid crystal display and make the second argument to setValue and setDirection more explict to its behavior --- firmware/src/Motherboard/Main.cc | 10 ++- .../Motherboard/boards/mb24/ButtonArray.cc | 3 +- .../Motherboard/boards/mb24/Configuration.hh | 4 +- .../Motherboard/boards/mb24/Motherboard.cc | 12 ++-- firmware/src/shared/InterfaceBoard.cc | 2 + firmware/src/shared/LiquidCrystal.cc | 68 +++++++++---------- firmware/src/shared/LiquidCrystal.hh | 6 +- firmware/src/shared/PinTmplt.hh | 15 ++-- firmware/src/shared/StepperInterface.hh | 8 ++- 9 files changed, 71 insertions(+), 57 deletions(-) diff --git a/firmware/src/Motherboard/Main.cc b/firmware/src/Motherboard/Main.cc index 738292d..97daf9d 100644 --- a/firmware/src/Motherboard/Main.cc +++ b/firmware/src/Motherboard/Main.cc @@ -28,6 +28,7 @@ #include "SDCard.hh" #include "Eeprom.hh" #include "EepromMap.hh" +#include void reset(bool hard_reset) { Motherboard& board = Motherboard::getBoard(); @@ -61,9 +62,11 @@ void reset(bool hard_reset) { int main() { Motherboard& board = Motherboard::getBoard(); - steppers::init(Motherboard::getBoard()); + steppers::init(board); reset(true); + while (1) { + // Toolhead interaction thread. tool::runToolSlice(); // Host interaction thread. @@ -73,6 +76,11 @@ int main() { // Motherboard slice board.runMotherboardSlice(); +#ifdef TRACE_MAIN_LOOP_CYCLES + static bool debug = false; + debug = !debug; + DEBUG_PIN::setValue(debug); +#endif } return 0; } diff --git a/firmware/src/Motherboard/boards/mb24/ButtonArray.cc b/firmware/src/Motherboard/boards/mb24/ButtonArray.cc index ff7471e..8072be7 100644 --- a/firmware/src/Motherboard/boards/mb24/ButtonArray.cc +++ b/firmware/src/Motherboard/boards/mb24/ButtonArray.cc @@ -6,12 +6,13 @@ static uint8_t previousC; void ButtonArray::init() { previousL = 0; previousC = 0; - +#if HAS_INTERFACE_BUTTONS > 0 // Set all of the known buttons to inputs (see above note) DDRL = DDRL & 0x1; DDRC = DDRC & 0xF9; PORTL = PORTL & 0x1; PORTC = PORTC & 0xF9; +#endif // HAS_INTERFACE_BUTTONS > 0 } void ButtonArray::scanButtons() { diff --git a/firmware/src/Motherboard/boards/mb24/Configuration.hh b/firmware/src/Motherboard/boards/mb24/Configuration.hh index 160ad8c..6e31910 100644 --- a/firmware/src/Motherboard/boards/mb24/Configuration.hh +++ b/firmware/src/Motherboard/boards/mb24/Configuration.hh @@ -156,8 +156,8 @@ #define DISPLAY_TYPE_DUAL 3 //#define DISPLAY_TYPE DISPLAY_TYPE_NONE -//#define DISPLAY_TYPE DISPLAY_TYPE_LIQUIDCRYSTAL -#define DISPLAY_TYPE DISPLAY_TYPE_MODTRONIXLCD2S +#define DISPLAY_TYPE DISPLAY_TYPE_LIQUIDCRYSTAL +//#define DISPLAY_TYPE DISPLAY_TYPE_MODTRONIXLCD2S //#define DISPLAY_TYPE DISPLAY_TYPE_DUAL /// Pin mappings for the LiquidCrystal class connection. diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.cc b/firmware/src/Motherboard/boards/mb24/Motherboard.cc index 91607dd..44dd9a3 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.cc +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.cc @@ -145,15 +145,15 @@ void Motherboard::initInterfaceBoard() { hasInterfaceBoard = interface::isConnected(); if (hasInterfaceBoard) { // Make sure our interface board is initialized - interfaceBoard.init(); + interfaceBoard.init(); - // Then add the splash screen to it. - interfaceBoard.pushScreen(&splashScreen); + // Then add the splash screen to it. + interfaceBoard.pushScreen(&splashScreen); - // Finally, set up the *** interface - interface::init(&interfaceBoard); + // Finally, set up the *** interface + interface::init(&interfaceBoard); - interface_update_timeout.start(interfaceBoard.getUpdateRate()); + interface_update_timeout.start(interfaceBoard.getUpdateRate()); } #endif // HAS_INTERFACE_BOARD > 0 } diff --git a/firmware/src/shared/InterfaceBoard.cc b/firmware/src/shared/InterfaceBoard.cc index deb1b5e..5b25b2d 100644 --- a/firmware/src/shared/InterfaceBoard.cc +++ b/firmware/src/shared/InterfaceBoard.cc @@ -25,6 +25,8 @@ static DualDisplay globalDisplay; void InterfaceBoard::Debug(const char message[]) { + static bool init = false; + if ( !init ) { globalDisplay.init(); init = true; } static uint16_t row = 0; globalDisplay.setCursor(0,row++%globalDisplay.height()); globalDisplay.writeInt(row,4); diff --git a/firmware/src/shared/LiquidCrystal.cc b/firmware/src/shared/LiquidCrystal.cc index 2945987..8e0299f 100755 --- a/firmware/src/shared/LiquidCrystal.cc +++ b/firmware/src/shared/LiquidCrystal.cc @@ -64,34 +64,32 @@ // can't assume that its in that state when a sketch starts (and the // LiquidCrystal constructor is called). -LiquidCrystal::LiquidCrystal() -{ - _rs_pin::setDirection(true); - _enable_pin::setDirection(true); +void LiquidCrystal::init() +{ + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + _rs_pin::setDirection(true, true); + _enable_pin::setDirection(true, true); - _rs_pin::setValue(false); - _enable_pin::setValue(false); + _rs_pin::setValue(false, true); + _enable_pin::setValue(false, true); - _d0_pin::setDirection(true); - _d1_pin::setDirection(true); - _d2_pin::setDirection(true); - _d3_pin::setDirection(true); + _d0_pin::setDirection(true, true); + _d1_pin::setDirection(true, true); + _d2_pin::setDirection(true, true); + _d3_pin::setDirection(true, true); - _d0_pin::setValue(false); - _d1_pin::setValue(false); - _d2_pin::setValue(false); - _d3_pin::setValue(false); + _d0_pin::setValue(false, true); + _d1_pin::setValue(false, true); + _d2_pin::setValue(false, true); + _d3_pin::setValue(false, true); + } _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; -} -void LiquidCrystal::init() -{ begin(width(), height()); - clear(); - home(); } @@ -101,33 +99,33 @@ static inline void _delay_248ns(void) __asm__ __volatile__ ("nop \n\tnop \n\tnop \n\tnop \n\t"); } -inline void LiquidCrystal::pulseEnable(void) { - _enable_pin::setValue(true); - _delay_248ns(); - _enable_pin::setValue(false); -} - inline void LiquidCrystal::write4bits(uint8_t value) { + // set the 4 bits and then pulse the enable line + // we do everything in atomic block to save from entering and + // leaving the atomic block when setting pins on ports ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - _d0_pin::setValue(((value >> 0) & 0x01) != 0, false); - _d1_pin::setValue(((value >> 1) & 0x01) != 0, false); - _d2_pin::setValue(((value >> 2) & 0x01) != 0, false); - _d3_pin::setValue(((value >> 3) & 0x01) != 0, false); + _d0_pin::setValue((value & 0x01) != 0, true); + _d1_pin::setValue((value & 0x02) != 0, true); + _d2_pin::setValue((value & 0x04) != 0, true); + _d3_pin::setValue((value & 0x08) != 0, true); + _enable_pin::setValue(true, true); } - pulseEnable(); + _delay_248ns(); + _enable_pin::setValue(false); + } // write either command or data, with automatic 4/8-bit selection void LiquidCrystal::send(uint8_t value, bool mode) { - _rs_pin::setValue(mode); + _rs_pin::setValue(mode); write4bits(value>>4); _delay_248ns(); // delay to keep enable_pin low before half a cycle time. write4bits(value); - _delay_us(41); // commands need > 37us to settle [citation needed] + _delay_us(37); // commands need > 37us to settle [citation needed] } @@ -157,17 +155,17 @@ void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { // we start in 8bit mode, try to set 4 bit mode write4bits(0x03); - _delay_us(4100); // wait min 4.1ms + _delay_us(4500); // wait min 4.1ms // second try write4bits(0x03); - _delay_us(4100); // wait min 4.1ms + _delay_us(4500); // wait min 4.1ms // third go! write4bits(0x03); _delay_us(150); - // finally, set to 8=4-bit interface + // finally, set to 4-bit interface write4bits(0x02); // finally, set # lines, font size, etc. diff --git a/firmware/src/shared/LiquidCrystal.hh b/firmware/src/shared/LiquidCrystal.hh index 8340e30..de833bc 100755 --- a/firmware/src/shared/LiquidCrystal.hh +++ b/firmware/src/shared/LiquidCrystal.hh @@ -18,10 +18,7 @@ class LiquidCrystal : public Display { public: - LiquidCrystal(); - void init(uint8_t fourbitmode); - void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); virtual void init(); @@ -62,8 +59,7 @@ public: private: void send(uint8_t, bool); void write4bits(uint8_t); - void pulseEnable(); - + uint8_t _displayfunction; uint8_t _displaycontrol; diff --git a/firmware/src/shared/PinTmplt.hh b/firmware/src/shared/PinTmplt.hh index 4ecf1f3..c89f950 100644 --- a/firmware/src/shared/PinTmplt.hh +++ b/firmware/src/shared/PinTmplt.hh @@ -55,9 +55,15 @@ template < uint16_t port_base, uint8_t pin_index > class PinTmplt { public: - static inline void setDirection(bool output, bool atomic = true) + // ports with 2 byte base address need to be wrapped in an atomic + // block. We provide the option for the caller to wrap several calls in a single + // atomic block for code optimizing. + // see http://code.google.com/p/arduino/issues/detail?id=146 + // and http://code.google.com/p/digitalwritefast/ + + static inline void setDirection(bool output, bool externalAtomicBlock = false) { - if( (port_base < 0x40) || !atomic) + if( (port_base < 0x40) || externalAtomicBlock ) { output ? DDRx |= _BV(pin_index) : DDRx &= ~_BV(pin_index); } @@ -69,9 +75,9 @@ public: } } } - static inline void setValue(bool on, bool atomic = true) + static inline void setValue(bool on, bool externalAtomicBlock = false) { - if((port_base < 0x40) || !atomic ) + if( (port_base < 0x40) || externalAtomicBlock ) { on ? PORTx |= _BV(pin_index) : PORTx &= ~_BV(pin_index); } @@ -85,6 +91,7 @@ public: } static inline bool getValue() { return !!(PINx & _BV(pin_index)); } + }; #define Pin(port_id,pin_id) PinTmplt diff --git a/firmware/src/shared/StepperInterface.hh b/firmware/src/shared/StepperInterface.hh index d1a44a1..e9827a3 100644 --- a/firmware/src/shared/StepperInterface.hh +++ b/firmware/src/shared/StepperInterface.hh @@ -48,16 +48,18 @@ template < uint8_t offset, class dir_pin, class step_pin, class enable_pin > cla public: /// Set the direction for the stepper to move - virtual void setDirection(bool forward) const { dir_pin::setValue(invert_axis ? !forward : forward, false); } + // only called from within the StepperAxis interupt routine, so we can assume we're in an atomic block + virtual void setDirection(bool forward) const { dir_pin::setValue(invert_axis ? !forward : forward, true); } /// Set the value of the step line - virtual void step(bool value) const {step_pin::setValue(value, false);} + // only called from within the StepperAxis interupt routine, so we can assume we're in an atomic block + virtual void step(bool value) const {step_pin::setValue(value, true);} /// Enable or disable this axis virtual void setEnabled(bool enabled) const { // The A3982 stepper driver chip has an inverted enable. - enable_pin::setValue(!enabled, false); + enable_pin::setValue(!enabled); } From 95296e1c2e4821e7ce1ca39d2f771fc0e746a5a2 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Mon, 21 Nov 2011 21:46:04 -0800 Subject: [PATCH 23/39] remove deleted files from solution --- G3Firmware.sln | 5 ----- 1 file changed, 5 deletions(-) diff --git a/G3Firmware.sln b/G3Firmware.sln index 9248f44..91bbc0d 100644 --- a/G3Firmware.sln +++ b/G3Firmware.sln @@ -20,8 +20,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{AE577D ProjectSection(SolutionItems) = preProject firmware\src\shared\AnalogPin.cc = firmware\src\shared\AnalogPin.cc firmware\src\shared\AnalogPin.hh = firmware\src\shared\AnalogPin.hh - firmware\src\shared\AvrPort.cc = firmware\src\shared\AvrPort.cc - firmware\src\shared\AvrPort.hh = firmware\src\shared\AvrPort.hh firmware\src\shared\ButtonArray.hh = firmware\src\shared\ButtonArray.hh firmware\src\shared\CircularBuffer.hh = firmware\src\shared\CircularBuffer.hh firmware\src\shared\Commands.hh = firmware\src\shared\Commands.hh @@ -49,15 +47,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{AE577D firmware\src\shared\Packet.hh = firmware\src\shared\Packet.hh firmware\src\shared\PID.cc = firmware\src\shared\PID.cc firmware\src\shared\PID.hh = firmware\src\shared\PID.hh - firmware\src\shared\Pin.cc = firmware\src\shared\Pin.cc - firmware\src\shared\Pin.hh = firmware\src\shared\Pin.hh firmware\src\shared\PinTmplt.hh = firmware\src\shared\PinTmplt.hh firmware\src\shared\ProtocolDocumentation.hh = firmware\src\shared\ProtocolDocumentation.hh firmware\src\shared\PSU.cc = firmware\src\shared\PSU.cc firmware\src\shared\PSU.hh = firmware\src\shared\PSU.hh firmware\src\shared\StepperAxis.cc = firmware\src\shared\StepperAxis.cc firmware\src\shared\StepperAxis.hh = firmware\src\shared\StepperAxis.hh - firmware\src\shared\StepperInterface.cc = firmware\src\shared\StepperInterface.cc firmware\src\shared\StepperInterface.hh = firmware\src\shared\StepperInterface.hh firmware\src\shared\TemperatureSensor.hh = firmware\src\shared\TemperatureSensor.hh firmware\src\shared\Thermistor.cc = firmware\src\shared\Thermistor.cc From 156fec597b42ce6f49ed0f4903478a3fcc90c9dd Mon Sep 17 00:00:00 2001 From: Craig Link Date: Mon, 21 Nov 2011 21:51:49 -0800 Subject: [PATCH 24/39] delete unused file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0143c08..77d4698 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ #added by jmil on 2010-04-20 .sconsign.dblite +G3Firmware.suo build html *.o From de31fc8c6d554ba5a4c8ad4e0c767af210bbe426 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Mon, 21 Nov 2011 22:26:05 -0800 Subject: [PATCH 25/39] revert the ordering of steppers A and B to what users expect, even though it isn't optimal --- firmware/src/Motherboard/boards/mb24/Motherboard.cc | 12 ++++++------ firmware/src/Motherboard/boards/mb24/Motherboard.hh | 5 ++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.cc b/firmware/src/Motherboard/boards/mb24/Motherboard.cc index 44dd9a3..2395ea8 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.cc +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.cc @@ -60,10 +60,10 @@ StepperTmpltEndstops<1, Y_DIR_PIN,Y_STEP_PIN,Y_ENABLE_PIN,Y_MAX_PIN,Y_MIN_PIN> M StepperTmpltEndstops<2, Z_DIR_PIN,Z_STEP_PIN,Z_ENABLE_PIN,Z_MAX_PIN,Z_MIN_PIN> Motherboard::stepperZ; #endif #if STEPPER_COUNT > 3 -StepperTmplt<3, B_DIR_PIN,B_STEP_PIN,B_ENABLE_PIN> Motherboard::stepperB; +StepperTmplt<3, A_DIR_PIN,A_STEP_PIN,A_ENABLE_PIN> Motherboard::stepperA; #endif #if STEPPER_COUNT > 4 -StepperTmplt<4, A_DIR_PIN,A_STEP_PIN,A_ENABLE_PIN> Motherboard::stepperA; +StepperTmplt<4, B_DIR_PIN,B_STEP_PIN,B_ENABLE_PIN> Motherboard::stepperB; #endif const StepperInterface* Motherboard::stepper[STEPPER_COUNT] = { @@ -78,10 +78,10 @@ const StepperInterface* Motherboard::stepper[STEPPER_COUNT] = ,&stepperZ #endif #if STEPPER_COUNT > 3 - ,&stepperB // swap B for extruder before of lower port usage + ,&stepperA #endif #if STEPPER_COUNT > 4 - ,&stepperA + ,&stepperB // swap B for extruder before of lower port usage #endif }; @@ -113,10 +113,10 @@ void Motherboard::reset() { stepperZ.init(); #endif #if STEPPER_COUNT > 3 - stepperB.init(); // swap B for extruder before of lower port usage + stepperA.init(); #endif #if STEPPER_COUNT > 4 - stepperA.init(); + stepperB.init(); // swap B for extruder before of lower port usage #endif // Initialize the host and slave UARTs diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.hh b/firmware/src/Motherboard/boards/mb24/Motherboard.hh index 7c8a001..72844c6 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.hh +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.hh @@ -51,11 +51,10 @@ private: static StepperTmpltEndstops<2, Z_DIR_PIN,Z_STEP_PIN,Z_ENABLE_PIN,Z_MAX_PIN,Z_MIN_PIN> stepperZ; #endif #if STEPPER_COUNT > 3 - // we're using B over A because of the assigned AVR Port which gets us a performance win using it over A - static StepperTmplt<3, B_DIR_PIN,B_STEP_PIN,B_ENABLE_PIN> stepperB; + static StepperTmplt<3, A_DIR_PIN,A_STEP_PIN,A_ENABLE_PIN> stepperA; #endif #if STEPPER_COUNT > 4 - static StepperTmplt<4, A_DIR_PIN,A_STEP_PIN,A_ENABLE_PIN> stepperA; + static StepperTmplt<4, B_DIR_PIN,B_STEP_PIN,B_ENABLE_PIN> stepperB; #endif /// Collection of stepper controllers that are on this board From 0de55c5ca66c2762b4e093a308a3d8aef81a0107 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Tue, 22 Nov 2011 09:13:45 -0800 Subject: [PATCH 26/39] missed change for 2nd parameters for the because I inverted the parameter of setValue in PinTmplt --- firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc b/firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc index ae85fca..21c1485 100644 --- a/firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc +++ b/firmware/src/Extruder/boards/ecv34/ExtruderMotor.cc @@ -48,12 +48,12 @@ void setExtruderMotor(int16_t speed) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { if (speed == 0 || speed == 255) { TCCR0A &= 0b11001111; - MOTOR_ENABLE_PIN::setValue(speed==255,false); + MOTOR_ENABLE_PIN::setValue(speed==255,true); } else { - MOTOR_ENABLE_PIN::setValue(true,false); + MOTOR_ENABLE_PIN::setValue(true,true); TCCR0A |= 0b00100000; } - MOTOR_DIR_PIN::setValue(!backwards,false); + MOTOR_DIR_PIN::setValue(!backwards,true); OCR0B = speed; } } From f8f91ba847985151993febb4333677077b1cdd3e Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 30 Nov 2011 20:07:10 -0800 Subject: [PATCH 27/39] use inline statements where appropriate to reduce function call stack. clean up use of atomic_blocks and use them where they were needed and not where they weren't optimize the point setting and getting code to be significantly more efficient. --- .../Extruder/boards/ecv22/ExtruderBoard.cc | 8 - .../Extruder/boards/ecv22/ExtruderBoard.hh | 2 +- .../Extruder/boards/ecv34/ExtruderBoard.cc | 15 +- .../Extruder/boards/ecv34/ExtruderBoard.hh | 2 +- firmware/src/Motherboard/Point.cc | 33 --- firmware/src/Motherboard/Point.hh | 34 +-- firmware/src/Motherboard/Steppers.cc | 200 +++++++++++------- firmware/src/Motherboard/Steppers.hh | 5 +- .../Motherboard/boards/mb24/Motherboard.cc | 29 ++- .../Motherboard/boards/mb24/Motherboard.hh | 5 +- .../Motherboard/boards/rrmbv12/Motherboard.cc | 32 ++- .../Motherboard/boards/rrmbv12/Motherboard.hh | 4 +- firmware/src/shared/Heater.cc | 35 --- firmware/src/shared/Heater.hh | 16 +- firmware/src/shared/Interface.cc | 21 -- firmware/src/shared/Interface.hh | 13 +- firmware/src/shared/InterfaceBoard.cc | 11 +- firmware/src/shared/InterfaceBoard.hh | 4 +- firmware/src/shared/PinTmplt.hh | 24 ++- firmware/src/shared/StepperAxis.cc | 23 +- firmware/src/shared/StepperAxis.hh | 22 +- firmware/src/shared/Timeout.cc | 6 +- firmware/src/shared/Timeout.hh | 5 +- 23 files changed, 250 insertions(+), 299 deletions(-) delete mode 100644 firmware/src/Motherboard/Point.cc diff --git a/firmware/src/Extruder/boards/ecv22/ExtruderBoard.cc b/firmware/src/Extruder/boards/ecv22/ExtruderBoard.cc index 0448031..1391799 100644 --- a/firmware/src/Extruder/boards/ecv22/ExtruderBoard.cc +++ b/firmware/src/Extruder/boards/ecv22/ExtruderBoard.cc @@ -209,14 +209,6 @@ void ExtruderBoard::setMotorSpeedRPM(uint32_t speed, bool direction) { setExtruderMotorRPM(speed, direction); } -micros_t ExtruderBoard::getCurrentMicros() { - micros_t micros_snapshot; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - micros_snapshot = micros; - } - return micros_snapshot; -} - // ms between servo updates; conservative to avoid 7805 overheating #define SERVO_CYCLE_LENGTH 8 volatile uint8_t servo_cycle = 0; diff --git a/firmware/src/Extruder/boards/ecv22/ExtruderBoard.hh b/firmware/src/Extruder/boards/ecv22/ExtruderBoard.hh index 685aa7b..d0f72f2 100644 --- a/firmware/src/Extruder/boards/ecv22/ExtruderBoard.hh +++ b/firmware/src/Extruder/boards/ecv22/ExtruderBoard.hh @@ -108,7 +108,7 @@ public: /// Get the number of microseconds that have passed since /// the board was initialized. This value will wrap after /// 2**16 microseconds; callers should compensate for this. - micros_t getCurrentMicros(); + inline micros_t getCurrentMicros() { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {return micros;} } /// Perform the timer interrupt routine. void doInterrupt(); /// Indicate an error by manipulating the debug LED. diff --git a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc index c15de7c..ed1d6ce 100644 --- a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc +++ b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc @@ -139,6 +139,10 @@ void ExtruderBoard::reset(uint8_t resetFlags) { getHostUART().enable(true); getHostUART().in.reset(); + MOTOR_DIR_PIN::setDirection(true); + MOTOR_DIR_PIN::setValue(true); + MOTOR_ENABLE_PIN::setDirection(true); + coolingFan.reset(); // flashIndicatorLED(); @@ -204,14 +208,6 @@ void ExtruderBoard::setServo(uint8_t index, int value) { } } -micros_t ExtruderBoard::getCurrentMicros() { - micros_t micros_snapshot; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - micros_snapshot = micros; - } - return micros_snapshot; -} - /// Run the extruder board interrupt void ExtruderBoard::doInterrupt() { static micros_t servo_counter = 0; @@ -250,9 +246,6 @@ void ExtruderBoard::setAutomatedBuildPlatformRunning(bool state) //runs the Extruder Cooling Fan (connected to 'A1/B1' screw term on ECv3.x) void ExtruderBoard::setFanRunning(bool state) { //CHANNEL_A.setValue(on); - MOTOR_DIR_PIN::setDirection(true); - MOTOR_DIR_PIN::setValue(true); - MOTOR_ENABLE_PIN::setDirection(true); MOTOR_ENABLE_PIN::setValue(state); } diff --git a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.hh b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.hh index d5ac6ed..08da401 100644 --- a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.hh +++ b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.hh @@ -112,7 +112,7 @@ public: /// Get the number of microseconds that have passed since /// the board was initialized. This value will wrap after /// 2**16 microseconds; callers should compensate for this. - micros_t getCurrentMicros(); + inline micros_t getCurrentMicros() { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {return micros;} } /// Perform the timer interrupt routine. void doInterrupt(); /// Indicate an error by manipulating the debug LED. diff --git a/firmware/src/Motherboard/Point.cc b/firmware/src/Motherboard/Point.cc deleted file mode 100644 index 2184103..0000000 --- a/firmware/src/Motherboard/Point.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include "Point.hh" - -Point::Point() -{ -} - -Point::Point(int32_t x, int32_t y, int32_t z, int32_t a, int32_t b) { - coordinates[0] = x; - coordinates[1] = y; - coordinates[2] = z; -#if AXIS_COUNT > 3 - coordinates[3] = a; - coordinates[4] = b; -#endif -} - -Point::Point(int32_t x, int32_t y, int32_t z) { - coordinates[0] = x; - coordinates[1] = y; - coordinates[2] = z; -#if AXIS_COUNT > 3 - coordinates[3] = 0; - coordinates[4] = 0; -#endif -} - -const int32_t& Point::operator[](unsigned int index) const { - return coordinates[index]; -} - -int32_t& Point::operator[](unsigned int index) { - return coordinates[index]; -} diff --git a/firmware/src/Motherboard/Point.hh b/firmware/src/Motherboard/Point.hh index f20a679..32d836e 100644 --- a/firmware/src/Motherboard/Point.hh +++ b/firmware/src/Motherboard/Point.hh @@ -14,7 +14,7 @@ private: int32_t coordinates[AXIS_COUNT]; ///< n-dimensional coordinate public: /// Default point constructor - Point(); + Point() {} /// Construct a point with the given cooridnates. Coordinates are in /// stepper steps. @@ -23,31 +23,33 @@ public: /// \param[in] z Z axis position /// \param[in] a (if supported) A axis position /// \param[in] b (if supported) B axis position - Point(int32_t x, int32_t y, int32_t z, int32_t a, int32_t b); - - - // TODO: Can this be removed by giving the 5-dimensional function - // some initial values? - /// Construct a point with the given cooridnates. Coordinates are in - /// stepper steps. If used on a 5-dimesional system, the A and B - /// axes are set to zero. - /// \param[in] x X axis position - /// \param[in] y Y axis position - /// \param[in] z Z axis position - Point(int32_t x, int32_t y, int32_t z); +#if AXIS_COUNT > 3 + Point(int32_t x, int32_t y, int32_t z, int32_t a = 0, int32_t b = 0) +#else + Point(int32_t x, int32_t y, int32_t z) +#endif + { + coordinates[0] = x; + coordinates[1] = y; + coordinates[2] = z; +#if AXIS_COUNT > 3 + coordinates[3] = a; + coordinates[4] = b; +#endif + } /// Constant array accessor. /// \param[in] index Axis to look up /// \return Axis position, in steps - const int32_t& operator[](unsigned int index) const; + inline const int32_t& operator[](unsigned int index) const { return coordinates[index]; } /// Array accessor. /// \param[in] index Axis to look up /// \return Reference to the variable containing the axis' position. - int32_t& operator[](unsigned int index); - + inline int32_t& operator[](unsigned int index) { return coordinates[index];} + } __attribute__ ((__packed__)); diff --git a/firmware/src/Motherboard/Steppers.cc b/firmware/src/Motherboard/Steppers.cc index 23707a8..e1c3bdd 100644 --- a/firmware/src/Motherboard/Steppers.cc +++ b/firmware/src/Motherboard/Steppers.cc @@ -24,10 +24,10 @@ namespace steppers { volatile bool is_running; -int32_t intervals; +volatile bool is_homing; volatile int32_t intervals_remaining; +int32_t intervals; StepperAxis axes[STEPPER_COUNT]; -volatile bool is_homing; bool holdZ = false; @@ -39,29 +39,43 @@ bool isRunning() { void init(Motherboard& motherboard) { is_running = false; for (int i = 0; i < STEPPER_COUNT; i++) { - axes[i] = StepperAxis(motherboard.getStepperInterface(i)); + axes[i] = StepperAxis(motherboard.getStepperInterface(i)); } } void abort() { - is_running = false; - is_homing = false; + ATOMIC_BLOCK(ATOMIC_FORCEON) + { + is_running = false; + is_homing = false; + } } /// Define current position as given point void definePosition(const Point& position) { - for (int i = 0; i < STEPPER_COUNT; i++) { - axes[i].definePosition(position[i]); - } + ATOMIC_BLOCK(ATOMIC_FORCEON) + { + axes[0].position = position[0]; + axes[1].position = position[1]; + axes[2].position = position[2]; +#if STEPPER_COUNT > 3 + axes[3].position = position[3]; + axes[4].position = position[4]; +#endif + } } -/// Get current position -const Point getPosition() { +const void getPosition(Point* pt) { + ATOMIC_BLOCK(ATOMIC_FORCEON) + { + (*pt)[0] = axes[0].position; + (*pt)[1] = axes[1].position; + (*pt)[2] = axes[2].position; #if STEPPER_COUNT > 3 - return Point(axes[0].position,axes[1].position,axes[2].position,axes[3].position,axes[4].position); -#else - return Point(axes[0].position,axes[1].position,axes[2].position); + (*pt)[3] = axes[3].position; + (*pt)[4] = axes[4].position; #endif + } } void setHoldZ(bool holdZ_in) { @@ -69,68 +83,86 @@ void setHoldZ(bool holdZ_in) { } void setTarget(const Point& target, int32_t dda_interval) { - int32_t max_delta = 0; - for (int i = 0; i < AXIS_COUNT; i++) { - axes[i].setTarget(target[i], false); - const int32_t delta = axes[i].delta; - // Only shut z axis on inactivity - if (i == 2 && !holdZ) axes[i].enableStepper(delta != 0); - else if (delta != 0) axes[i].enableStepper(true); - if (delta > max_delta) { - max_delta = delta; - } - } - // compute number of intervals for this move - intervals = ((max_delta * dda_interval) / INTERVAL_IN_MICROSECONDS); - intervals_remaining = intervals; - const int32_t negative_half_interval = -intervals / 2; - for (int i = 0; i < AXIS_COUNT; i++) { - axes[i].counter = negative_half_interval; - } - is_running = true; + int32_t max_delta = 0; + for (int i = 0; i < STEPPER_COUNT; i++) { + StepperAxis& axis = axes[i]; + const int32_t delta = axis.setTarget(target[i], false); + // Only shut z axis on inactivity + if (i == 2 && !holdZ) { + axis.enableStepper(delta != 0); + } + else if (delta != 0) { + axis.enableStepper(true); + } + if (delta > max_delta) { + max_delta = delta; + } + } + ATOMIC_BLOCK(ATOMIC_FORCEON){ + // compute number of intervals for this move + intervals = ((max_delta * dda_interval) / INTERVAL_IN_MICROSECONDS); + intervals_remaining = intervals; + const int32_t negative_half_interval = -intervals / 2; + axes[0].counter = negative_half_interval; + axes[1].counter = negative_half_interval; + axes[2].counter = negative_half_interval; +#if STEPPER_COUNT > 3 + axes[3].counter = negative_half_interval; + axes[4].counter = negative_half_interval; +#endif + is_running = true; + } } void setTargetNew(const Point& target, int32_t us, uint8_t relative) { - for (int i = 0; i < AXIS_COUNT; i++) { - axes[i].setTarget(target[i], (relative & (1 << i)) != 0); - // Only shut z axis on inactivity - const int32_t delta = axes[i].delta; - if (i == 2 && !holdZ) { - axes[i].enableStepper(delta != 0); - } else if (delta != 0) { - axes[i].enableStepper(true); - } - } - // compute number of intervals for this move - intervals = us / INTERVAL_IN_MICROSECONDS; - intervals_remaining = intervals; - const int32_t negative_half_interval = -intervals / 2; - for (int i = 0; i < AXIS_COUNT; i++) { - axes[i].counter = negative_half_interval; - } - is_running = true; + for (int i = 0; i < STEPPER_COUNT; i++) { + StepperAxis& axis = axes[i]; + const int32_t delta = axis.setTarget(target[i], (relative & (1 << i)) != 0); + // Only shut z axis on inactivity + if (i == 2 && !holdZ) { + axes[i].enableStepper(delta != 0); + } else if (delta != 0) { + axes[i].enableStepper(true); + } + } + ATOMIC_BLOCK(ATOMIC_FORCEON){ + // compute number of intervals for this move + intervals = us / INTERVAL_IN_MICROSECONDS; + intervals_remaining = intervals; + const int32_t negative_half_interval = -intervals / 2; + axes[0].counter = negative_half_interval; + axes[1].counter = negative_half_interval; + axes[2].counter = negative_half_interval; +#if STEPPER_COUNT > 3 + axes[3].counter = negative_half_interval; + axes[4].counter = negative_half_interval; +#endif + is_running = true; + } } /// Start homing void startHoming(const bool maximums, const uint8_t axes_enabled, const uint32_t us_per_step) { - intervals_remaining = INT32_MAX; - intervals = us_per_step / INTERVAL_IN_MICROSECONDS; - const int32_t negative_half_interval = -intervals / 2; - for (int i = 0; i < AXIS_COUNT; i++) { - axes[i].counter = negative_half_interval; - if ((axes_enabled & (1< 0 + axes[0].doInterrupt(intervals); +#endif +#if STEPPER_COUNT > 1 + axes[1].doInterrupt(intervals); +#endif +#if STEPPER_COUNT > 2 + axes[2].doInterrupt(intervals); +#endif +#if STEPPER_COUNT > 3 + axes[3].doInterrupt(intervals); +#endif +#if STEPPER_COUNT > 4 + axes[4].doInterrupt(intervals); +#endif } return is_running; } else if (is_homing) { - is_homing = false; - for (int i = 0; i < STEPPER_COUNT; i++) { - bool still_homing = axes[i].doHoming(intervals); - is_homing = still_homing || is_homing; - } + is_homing = +#if STEPPER_COUNT > 0 + axes[0].doHoming(intervals) || +#endif +#if STEPPER_COUNT > 1 + axes[1].doHoming(intervals) || +#endif +#if STEPPER_COUNT > 2 + axes[2].doHoming(intervals) || +#endif +#if STEPPER_COUNT > 3 + axes[3].doHoming(intervals) || +#endif +#if STEPPER_COUNT > 4 + axes[4].doHoming(intervals) || +#endif + false; return is_homing; } return false; diff --git a/firmware/src/Motherboard/Steppers.hh b/firmware/src/Motherboard/Steppers.hh index 45f2487..118dceb 100644 --- a/firmware/src/Motherboard/Steppers.hh +++ b/firmware/src/Motherboard/Steppers.hh @@ -83,7 +83,8 @@ namespace steppers { /// Get the current system position /// \return The current machine position. - const Point getPosition(); +// const Point getPosition(); + const void getPosition(Point* point); /// Control whether the Z axis should stay enabled during the entire /// build (defaults to off). This is useful for machines that have @@ -92,6 +93,8 @@ namespace steppers { /// through the entire build. If false, it will be /// disabled when not moving. void setHoldZ(bool holdZ); + + }; #endif // STEPPERS_HH_ diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.cc b/firmware/src/Motherboard/boards/mb24/Motherboard.cc index 2395ea8..bad8b67 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.cc +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.cc @@ -89,6 +89,12 @@ const StepperInterface* Motherboard::stepper[STEPPER_COUNT] = /// This only resets the board, and does not send a reset /// to any attached toolheads. void Motherboard::reset() { + // Configure the debug pin. + DEBUG_PIN::setDirection(true); + + DEBUG_MOTHERBOARD_SLICE_PIN::setDirection(true); + DEBUG_MOTHERBOARD_SLICE_PIN::setValue(false); + indicateError(0); // turn off blinker // Init steppers @@ -135,8 +141,6 @@ void Motherboard::reset() { TCCR2A = 0x00; TCCR2B = 0x07; // prescaler at 1/1024 TIMSK2 = 0x01; // OVF flag on - // Configure the debug pin. - DEBUG_PIN::setDirection(true); } void Motherboard::initInterfaceBoard() { @@ -158,33 +162,26 @@ void Motherboard::initInterfaceBoard() { #endif // HAS_INTERFACE_BOARD > 0 } -/// Get the number of microseconds that have passed since -/// the board was booted. -micros_t Motherboard::getCurrentMicros() { - micros_t micros_snapshot; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - micros_snapshot = micros; - } - return micros_snapshot; -} - /// Run the motherboard interrupt void Motherboard::doInterrupt() { + micros += INTERVAL_IN_MICROSECONDS; + #if HAS_INTERFACE_BOARD > 0 if (hasInterfaceBoard) { interfaceBoard.doInterrupt(); } #endif // HAS_INTERFACE_BOARD > 0 - micros += INTERVAL_IN_MICROSECONDS; - // Do not move steppers if the board is in a paused state + // Do not move steppers if the board is in a paused state if (command::isPaused()) return; - steppers::doInterrupt(); + steppers::doInterrupt(); + } void Motherboard::runMotherboardSlice() { + DEBUG_MOTHERBOARD_SLICE_PIN::setValue(true); #if HAS_INTERFACE_BOARD > 0 if (hasInterfaceBoard) { @@ -194,6 +191,8 @@ void Motherboard::runMotherboardSlice() { } } #endif + + DEBUG_MOTHERBOARD_SLICE_PIN::setValue(false); } diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.hh b/firmware/src/Motherboard/boards/mb24/Motherboard.hh index 72844c6..9477bfc 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.hh +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.hh @@ -42,6 +42,7 @@ public: private: #if STEPPER_COUNT > 0 + static StepperTmpltEndstops<0, X_DIR_PIN,X_STEP_PIN,X_ENABLE_PIN,X_MAX_PIN,X_MIN_PIN> stepperX; #endif #if STEPPER_COUNT > 1 @@ -93,7 +94,7 @@ public: /// Count the number of steppers available on this board. const int getStepperCount() const { return STEPPER_COUNT; } /// Get the stepper interface for the nth stepper. - const StepperInterface* getStepperInterface(int n) + inline const StepperInterface* getStepperInterface(int n) { return stepper[n]; } @@ -101,7 +102,7 @@ public: /// Get the number of microseconds that have passed since /// the board was initialized. This value will wrap after /// 2**32 microseconds (ca. 70 minutes); callers should compensate for this. - micros_t getCurrentMicros(); + inline micros_t getCurrentMicros() { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {return micros;} } /// Write an error code to the debug pin. void indicateError(int errorCode); diff --git a/firmware/src/Motherboard/boards/rrmbv12/Motherboard.cc b/firmware/src/Motherboard/boards/rrmbv12/Motherboard.cc index 98fe3bb..e760eda 100644 --- a/firmware/src/Motherboard/boards/rrmbv12/Motherboard.cc +++ b/firmware/src/Motherboard/boards/rrmbv12/Motherboard.cc @@ -80,6 +80,7 @@ Motherboard::Motherboard(const Pin& psu_pin) : /// This only resets the board, and does not send a reset /// to any attached toolheads. void Motherboard::reset() { + indicateError(0); // turn off blinker // Init and turn on power supply @@ -101,21 +102,22 @@ void Motherboard::reset() { for (int i = 0; i < STEPPER_COUNT; i++) { stepper[i].init(i); } + // Initialize the host and slave UARTs - UART::getHostUART().enable(true); - UART::getHostUART().in.reset(); + UART::getHostUART().enable(true); + UART::getHostUART().in.reset(); - // TODO: These aren't done on other platforms, are they necessary? - UART::getHostUART().reset(); - UART::getHostUART().out.reset(); + // TODO: These aren't done on other platforms, are they necessary? + UART::getHostUART().reset(); + UART::getHostUART().out.reset(); - UART::getSlaveUART().enable(true); - UART::getSlaveUART().in.reset(); + UART::getSlaveUART().enable(true); + UART::getSlaveUART().in.reset(); - // TODO: These aren't done on other platforms, are they necessary? - UART::getSlaveUART().reset(); - UART::getSlaveUART().out.reset(); + // TODO: These aren't done on other platforms, are they necessary? + UART::getSlaveUART().reset(); + UART::getSlaveUART().out.reset(); // Reset and configure timer 1, the microsecond and stepper @@ -133,16 +135,6 @@ void Motherboard::reset() { DEBUG_PIN.setDirection(true); } -/// Get the number of microseconds that have passed since -/// the board was booted. -micros_t Motherboard::getCurrentMicros() { - micros_t micros_snapshot; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - micros_snapshot = micros; - } - return micros_snapshot; -} - void Motherboard::runMotherboardSlice() { } diff --git a/firmware/src/Motherboard/boards/rrmbv12/Motherboard.hh b/firmware/src/Motherboard/boards/rrmbv12/Motherboard.hh index a151486..0850e90 100644 --- a/firmware/src/Motherboard/boards/rrmbv12/Motherboard.hh +++ b/firmware/src/Motherboard/boards/rrmbv12/Motherboard.hh @@ -55,7 +55,7 @@ public: const int getStepperCount() const { return STEPPERS; } /// Get the stepper interface for the nth stepper. - StepperInterface& getStepperInterface(int n) + inline const StepperInterface* getStepperInterface(int n) { return stepper[n]; } @@ -63,7 +63,7 @@ public: /// Get the number of microseconds that have passed since /// the board was initialized. This value will wrap after /// 2**16 microseconds; callers should compensate for this. - micros_t getCurrentMicros(); + inline micros_t getCurrentMicros() { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {return micros;} } /// Write an error code to the debug pin. void indicateError(int errorCode); diff --git a/firmware/src/shared/Heater.cc b/firmware/src/shared/Heater.cc index 37fba5a..2b3c073 100644 --- a/firmware/src/shared/Heater.cc +++ b/firmware/src/shared/Heater.cc @@ -83,11 +83,6 @@ void Heater::reset() { next_sense_timeout.start(sample_interval_micros); } -void Heater::set_target_temperature(int temp) -{ - pid.setTarget(temp); -} - // We now define target hysteresis in absolute degrees. The original // implementation (+/-5%) was giving us swings of 10% in either direction // *before* any artifacts of process instability came in. @@ -99,27 +94,6 @@ bool Heater::has_reached_target_temperature() (current_temperature <= (pid.getTarget() + TARGET_HYSTERESIS)); } -int Heater::get_set_temperature() { - return pid.getTarget(); -} - -int Heater::get_current_temperature() -{ - return sensor.getTemperature(); -} - -int Heater::getPIDErrorTerm() { - return pid.getErrorTerm(); -} - -int Heater::getPIDDeltaTerm() { - return pid.getDeltaTerm(); -} - -int Heater::getPIDLastOutput() { - return pid.getLastOutput(); -} - void Heater::manage_temperature() { if (fail_state) { @@ -190,18 +164,9 @@ void Heater::manage_temperature() } } -void Heater::set_output(uint8_t value) -{ - element.setHeatingElement(value); -} - void Heater::fail() { fail_state = true; set_output(0); } -bool Heater::has_failed() -{ - return fail_state; -} diff --git a/firmware/src/shared/Heater.hh b/firmware/src/shared/Heater.hh index e07f91d..491708e 100644 --- a/firmware/src/shared/Heater.hh +++ b/firmware/src/shared/Heater.hh @@ -79,15 +79,15 @@ class Heater /// Get the current sensor temperature /// \return Current sensor temperature, in degrees Celcius - int get_current_temperature(); + inline int get_current_temperature() { return sensor.getTemperature(); } /// Get the setpoint temperature /// \return Setpoint temperature, in degrees Celcius - int get_set_temperature(); + inline int get_set_temperature() { return pid.getTarget(); } /// Set the target output temperature /// \param temp New target temperature, in degrees Celcius. - void set_target_temperature(int temp); + inline void set_target_temperature(int temp) { pid.setTarget(temp); } /// Check if the heater is within the specified band /// \return True if the heater temperature is within #TARGET_HYSTERESIS degrees @@ -96,7 +96,7 @@ class Heater /// Check if the heater is in a failure state /// \return true if the heater has failed. - bool has_failed(); + inline bool has_failed() { return fail_state; } /// Run the heater management loop. This must be called periodically, /// at a higher frequency than #sample_interval_micros. @@ -104,22 +104,22 @@ class Heater /// Change the setpoint temperature /// \param value New setpoint temperature, in degrees Celcius. - void set_output(uint8_t value); + void set_output(uint8_t value) { element.setHeatingElement(value); } /// Reset the heater to a to board-on state void reset(); /// Get the current PID error term /// \return E term from the PID controller - int getPIDErrorTerm(); + inline int getPIDErrorTerm() { return pid.getErrorTerm(); } /// Get the current PID delta term /// \return D term from the PID controller - int getPIDDeltaTerm(); + inline int getPIDDeltaTerm() { return pid.getDeltaTerm(); } /// Get the last PID output /// \return last output from the PID controller - int getPIDLastOutput(); + inline int getPIDLastOutput() { return pid.getLastOutput(); } }; #endif // HEATER_H diff --git a/firmware/src/shared/Interface.cc b/firmware/src/shared/Interface.cc index b2cfd16..daa7867 100644 --- a/firmware/src/shared/Interface.cc +++ b/firmware/src/shared/Interface.cc @@ -46,27 +46,6 @@ void init(InterfaceBoard* board_in) { board = board_in; } -void pushScreen(Screen* newScreen) { - board->pushScreen(newScreen); -} - -void popScreen() { - board->popScreen(); -} - -void doInterrupt() { - board->doInterrupt(); -} - -micros_t getUpdateRate() { - return board->getUpdateRate(); -} - -void doUpdate() { - board->doUpdate(); -} - - } #endif // HAS_INTERFACE_BOARD > 0 diff --git a/firmware/src/shared/Interface.hh b/firmware/src/shared/Interface.hh index 26a0e6d..8452db7 100644 --- a/firmware/src/shared/Interface.hh +++ b/firmware/src/shared/Interface.hh @@ -26,6 +26,8 @@ // TODO: This style interface is weird; find a way to replace it. namespace interface { +extern InterfaceBoard* board; + /// Set the current interface board and lcd. This *must* be called before using /// any of the functions in this interface. void init(InterfaceBoard* board_in); @@ -35,23 +37,23 @@ bool isConnected(); /// Display a new screen by pushing it to the screen stack. /// \param[in] newScreen Screen to be added to the stack. -void pushScreen(Screen* newScreen); +inline void pushScreen(Screen* newScreen) { board->pushScreen(newScreen); } /// Remove the top screen from the screen stack. If there is only one screen left, /// it will not be removed. -void popScreen(); +inline void popScreen() { board->popScreen(); } /// Screen update interrupt. This scans the keypad to look for any changes. To /// ensure a consistant user response, it should be called from a medium frequency /// interrupt. -void doInterrupt(); +inline void doInterrupt() { board->doInterrupt(); } /// Update the display. This function is where the current display screen /// should handle button presses, redraw it's screen, etc. It is run from the /// motherboard slice, not an interrupt, because it may take a relatively long /// time to run. -void doUpdate(); +inline void doUpdate() { board->doUpdate();} /// Returns the minimum amount of time that should elapse before the current /// display screen is updated again. This is customizable to allow for both @@ -59,7 +61,8 @@ void doUpdate(); /// the machine is not printing, as well as slow-updating screens (monitor /// mode) that can be displayed while the machine is running, without causing /// much impact. -micros_t getUpdateRate(); +inline micros_t getUpdateRate() { return board->getUpdateRate();} + } diff --git a/firmware/src/shared/InterfaceBoard.cc b/firmware/src/shared/InterfaceBoard.cc index 5b25b2d..a67e5ca 100644 --- a/firmware/src/shared/InterfaceBoard.cc +++ b/firmware/src/shared/InterfaceBoard.cc @@ -62,14 +62,6 @@ void InterfaceBoard::init() { pushScreen(mainScreen); } -void InterfaceBoard::doInterrupt() { - buttons.scanButtons(); -} - -micros_t InterfaceBoard::getUpdateRate() { - return screenStack[screenIndex]->getUpdateRate(); -} - void InterfaceBoard::doUpdate() { // If we are building, make sure we show a build menu; otherwise, @@ -91,13 +83,14 @@ void InterfaceBoard::doUpdate() { } +#if HAS_INTERFACE_BUTTONS > 0 static ButtonArray::ButtonName button; if (buttons.getButton(button)) { screenStack[screenIndex]->notifyButtonPressed(button); } - +#endif screenStack[screenIndex]->update(display, false); } diff --git a/firmware/src/shared/InterfaceBoard.hh b/firmware/src/shared/InterfaceBoard.hh index ade1d76..73e43ae 100644 --- a/firmware/src/shared/InterfaceBoard.hh +++ b/firmware/src/shared/InterfaceBoard.hh @@ -72,7 +72,7 @@ public: /// This should be called periodically by a high-speed interrupt to /// service the button input pad. - void doInterrupt(); + inline void doInterrupt() { buttons.scanButtons(); } /// Add a new screen to the stack. This automatically calls reset() /// and then update() on the screen, to ensure that it displays @@ -85,7 +85,7 @@ public: /// being displayed, then this function does nothing. void popScreen(); - micros_t getUpdateRate(); + inline micros_t getUpdateRate() const { return screenStack[screenIndex]->getUpdateRate(); } void doUpdate(); diff --git a/firmware/src/shared/PinTmplt.hh b/firmware/src/shared/PinTmplt.hh index c89f950..4dc0a9b 100644 --- a/firmware/src/shared/PinTmplt.hh +++ b/firmware/src/shared/PinTmplt.hh @@ -62,7 +62,9 @@ public: // and http://code.google.com/p/digitalwritefast/ static inline void setDirection(bool output, bool externalAtomicBlock = false) - { + { + if (port_base != 0) + { if( (port_base < 0x40) || externalAtomicBlock ) { output ? DDRx |= _BV(pin_index) : DDRx &= ~_BV(pin_index); @@ -75,8 +77,12 @@ public: } } } + } + static inline void setValue(bool on, bool externalAtomicBlock = false) - { + { + if (port_base != 0) + { if( (port_base < 0x40) || externalAtomicBlock ) { on ? PORTx |= _BV(pin_index) : PORTx &= ~_BV(pin_index); @@ -89,13 +95,25 @@ public: } } } + } - static inline bool getValue() { return !!(PINx & _BV(pin_index)); } + static inline bool getValue() + { + if (port_base != 0) + { + return !!(PINx & _BV(pin_index)); + } + else + { + return 0; + } + } }; #define Pin(port_id,pin_id) PinTmplt +#define NULL_PIN PinTmplt<0,0> #if defined(__AVR_ATmega644P__) || \ defined(__AVR_ATmega1280__) || \ diff --git a/firmware/src/shared/StepperAxis.cc b/firmware/src/shared/StepperAxis.cc index 11fdfb5..8cf89d5 100644 --- a/firmware/src/shared/StepperAxis.cc +++ b/firmware/src/shared/StepperAxis.cc @@ -10,9 +10,9 @@ StepperAxis::StepperAxis(const StepperInterface* stepper_interface) : reset(); } -void StepperAxis::setTarget(const int32_t target_in, +int32_t StepperAxis::setTarget(const int32_t target, bool relative) { - target = target_in; + ATOMIC_BLOCK(ATOMIC_FORCEON){ if (relative) { delta = target; } else { @@ -26,27 +26,18 @@ void StepperAxis::setTarget(const int32_t target_in, delta = -delta; direction = false; } + return delta; + } } void StepperAxis::setHoming(const bool direction_in) { - direction = direction_in; - interface->setEnabled(true); - delta = 1; -} - -void StepperAxis::definePosition(const int32_t position_in) { - position = position_in; -} - -void StepperAxis::enableStepper(bool enable) { - interface->setEnabled(enable); + direction = direction_in; + interface->setEnabled(true); + delta = 1; } void StepperAxis::reset() { position = 0; - minimum = 0; - maximum = 0; - target = 0; counter = 0; delta = 0; #if defined(SINGLE_SWITCH_ENDSTOPS) && (SINGLE_SWITCH_ENDSTOPS == 1) diff --git a/firmware/src/shared/StepperAxis.hh b/firmware/src/shared/StepperAxis.hh index 08e715f..b9b1e4e 100644 --- a/firmware/src/shared/StepperAxis.hh +++ b/firmware/src/shared/StepperAxis.hh @@ -12,17 +12,18 @@ /// \ingroup SoftwareLibraries class StepperAxis { -public: +protected: const StepperInterface* interface; ///< Interface this axis is connected to + +public: + bool direction; ///< True for positive, false for negative + int32_t delta; ///< Amount to increment counter per tick volatile int32_t position; ///< Current position of this axis, in steps - int32_t minimum; ///< Minimum position, in steps - int32_t maximum; ///< Maximum position, in steps - volatile int32_t target; ///< Target position, in steps volatile int32_t counter; ///< Step counter; represents the proportion of ///< a step so far passed. When the counter hits ///< zero, a step is taken. - volatile int32_t delta; ///< Amount to increment counter per tick - volatile bool direction; ///< True for positive, false for negative + +protected: #if defined(SINGLE_SWITCH_ENDSTOPS) && (SINGLE_SWITCH_ENDSTOPS == 1) volatile bool prev_direction; ///< Record the previous direction for endstop detection volatile int32_t endstop_play; ///< Amount to move while endstop triggered, to see which way to move @@ -58,19 +59,16 @@ public: /// \param[in] target_in Postion to move to, in steps /// \param[in] relative If true, consider the target position /// to be relative to the current position. - void setTarget(const int32_t target_in, bool relative); + // Returns the amount of movement required + int32_t setTarget(const int32_t target_in, bool relative); /// Start a homing procedure /// \param[in] direction_in If true, home in the positive direction. void setHoming(const bool direction_in); - /// Reset the axis position to the given position. - /// \param[in] position_in New axis position - void definePosition(const int32_t position_in); - /// Set whether the stepper motor driver on the given axis should be enabled /// \param[in] enable If true, enable the axis; otherwise, disable it. - void enableStepper(bool enable); + inline void enableStepper(bool enable) { interface->setEnabled(enable); } /// Reset to initial state void reset(); diff --git a/firmware/src/shared/Timeout.cc b/firmware/src/shared/Timeout.cc index 6ebe45d..32789f5 100644 --- a/firmware/src/shared/Timeout.cc +++ b/firmware/src/shared/Timeout.cc @@ -28,18 +28,16 @@ inline micros_t getMicros() { return Motherboard::getBoard().getCurrentMicros(); } #endif -Timeout::Timeout() : active(false), elapsed(false) {} - void Timeout::start(micros_t duration_micros_in) { active = true; elapsed = false; - start_stamp_micros = getMicros(); + start_stamp_micros = getMicros(); duration_micros = duration_micros_in; } bool Timeout::hasElapsed() { if (active && !elapsed) { - micros_t delta = getMicros() - start_stamp_micros; + micros_t delta = getMicros() - start_stamp_micros; if (delta >= duration_micros) { active = false; elapsed = true; diff --git a/firmware/src/shared/Timeout.hh b/firmware/src/shared/Timeout.hh index 2b98e67..c9368d3 100644 --- a/firmware/src/shared/Timeout.hh +++ b/firmware/src/shared/Timeout.hh @@ -36,12 +36,13 @@ private: bool active; ///< True if the timeout object is actively counting down. bool elapsed; ///< True if the timeout object has elapsed. - //TODO: Instead of storing start and duration, precompute and store the elapse time. + //TODO: Instead of storing start and duration, precompute and store the elapse time. micros_t start_stamp_micros; micros_t duration_micros; public: /// Instantiate a new timeout object. - Timeout(); + Timeout() : active(false), elapsed(false) {} + /// Start a new timeout cycle that will elapse after the given amount of time. /// \param [in] duration_micros Microseconds until the timeout cycle should elapse. From 65760e8dcbd1ca35bf1e61b9f5336e3ac936d0a4 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 30 Nov 2011 20:35:29 -0800 Subject: [PATCH 28/39] change code to use a more efficient switch statement. remove an unnecessary atomic block --- firmware/src/Motherboard/Command.cc | 546 +++++++++++++++------------- 1 file changed, 300 insertions(+), 246 deletions(-) diff --git a/firmware/src/Motherboard/Command.cc b/firmware/src/Motherboard/Command.cc index 91a6865..53d082e 100644 --- a/firmware/src/Motherboard/Command.cc +++ b/firmware/src/Motherboard/Command.cc @@ -38,11 +38,10 @@ bool outstanding_tool_command = false; bool paused = false; uint16_t getRemainingCapacity() { - uint16_t sz; - ATOMIC_BLOCK(ATOMIC_FORCEON) { - sz = command_buffer.getRemainingCapacity(); + //ATOMIC_BLOCK(ATOMIC_FORCEON) + { + return command_buffer.getRemainingCapacity(); } - return sz; } void pause(bool pause) { @@ -61,11 +60,11 @@ void push(uint8_t byte) { command_buffer.push(byte); } -uint8_t pop8() { +inline uint8_t pop8() { return command_buffer.pop(); } -int16_t pop16() { +inline int16_t pop16() { union { // AVR is little-endian int16_t a; @@ -78,7 +77,7 @@ int16_t pop16() { return shared.a; } -int32_t pop32() { +inline int32_t pop32() { union { // AVR is little-endian int32_t a; @@ -107,263 +106,318 @@ Timeout homing_timeout; Timeout tool_wait_timeout; void reset() { + DEBUG_CMD_SLICE_PIN::setDirection(true); + DEBUG_CMD_SLICE_PIN::setValue(false); command_buffer.reset(); mode = READY; } // A fast slice for processing commands and refilling the stepper queue, etc. void runCommandSlice() { + DEBUG_CMD_SLICE_PIN::setValue(true); if (sdcard::isPlaying()) { while (command_buffer.getRemainingCapacity() > 0 && sdcard::playbackHasNext()) { command_buffer.push(sdcard::playbackNext()); } } - if (paused) { return; } - if (mode == HOMING) { - if (!steppers::isRunning()) { - mode = READY; - } else if (homing_timeout.hasElapsed()) { - steppers::abort(); - mode = READY; - } - } - if (mode == MOVING) { - if (!steppers::isRunning()) { mode = READY; } - } - if (mode == DELAY) { - // check timers - if (delay_timeout.hasElapsed()) { - mode = READY; - } - } - if (mode == WAIT_ON_TOOL) { - if (tool_wait_timeout.hasElapsed()) { - mode = READY; - } else if (tool::getLock()) { - OutPacket& out = tool::getOutPacket(); - InPacket& in = tool::getInPacket(); - out.reset(); - out.append8(tool::getCurrentToolheadIndex()); - out.append8(SLAVE_CMD_GET_TOOL_STATUS); - tool::startTransaction(); - // WHILE: bounded by timeout in runToolSlice - while (!tool::isTransactionDone()) { - tool::runToolSlice(); - } - if (!in.hasError()) { - if (in.read8(1) & 0x01) { - mode = READY; - } - } - tool::releaseLock(); - } - } - if (mode == WAIT_ON_PLATFORM) { - // FIXME: Duplicates most code from WAIT_ON_TOOL - if (tool_wait_timeout.hasElapsed()) { - mode = READY; - } else if (tool::getLock()) { - OutPacket& out = tool::getOutPacket(); - InPacket& in = tool::getInPacket(); - out.reset(); - out.append8(tool::getCurrentToolheadIndex()); - out.append8(SLAVE_CMD_IS_PLATFORM_READY); - tool::startTransaction(); - // WHILE: bounded by timeout in runToolSlice - while (!tool::isTransactionDone()) { - tool::runToolSlice(); - } - if (!in.hasError()) { - if (in.read8(1) != 0) { - mode = READY; - } - } - tool::releaseLock(); - } - } - if (mode == READY) { - // process next command on the queue. - if (command_buffer.getLength() > 0) { - uint8_t command = command_buffer[0]; - if (command == HOST_CMD_QUEUE_POINT_ABS) { - // check for completion - if (command_buffer.getLength() >= 17) { - command_buffer.pop(); // remove the command code - mode = MOVING; - int32_t x = pop32(); - int32_t y = pop32(); - int32_t z = pop32(); - int32_t dda = pop32(); - steppers::setTarget(Point(x,y,z),dda); - } - } else if (command == HOST_CMD_QUEUE_POINT_EXT) { - // check for completion - if (command_buffer.getLength() >= 25) { - command_buffer.pop(); // remove the command code - mode = MOVING; - int32_t x = pop32(); - int32_t y = pop32(); - int32_t z = pop32(); - int32_t a = pop32(); - int32_t b = pop32(); - int32_t dda = pop32(); - steppers::setTarget(Point(x,y,z,a,b),dda); - } - } else if (command == HOST_CMD_QUEUE_POINT_NEW) { - // check for completion - if (command_buffer.getLength() >= 26) { - command_buffer.pop(); // remove the command code - mode = MOVING; - int32_t x = pop32(); - int32_t y = pop32(); - int32_t z = pop32(); - int32_t a = pop32(); - int32_t b = pop32(); - int32_t us = pop32(); - uint8_t relative = pop8(); - steppers::setTargetNew(Point(x,y,z,a,b),us,relative); - } - } else if (command == HOST_CMD_CHANGE_TOOL) { - if (command_buffer.getLength() >= 2) { - command_buffer.pop(); // remove the command code - tool::setCurrentToolheadIndex(command_buffer.pop()); - } - } else if (command == HOST_CMD_ENABLE_AXES) { - if (command_buffer.getLength() >= 2) { - command_buffer.pop(); // remove the command code - uint8_t axes = command_buffer.pop(); - bool enable = (axes & 0x80) != 0; - for (int i = 0; i < STEPPER_COUNT; i++) { - if ((axes & _BV(i)) != 0) { - steppers::enableAxis(i, enable); - } - } - } - } else if (command == HOST_CMD_SET_POSITION) { - // check for completion - if (command_buffer.getLength() >= 13) { - command_buffer.pop(); // remove the command code - int32_t x = pop32(); - int32_t y = pop32(); - int32_t z = pop32(); - steppers::definePosition(Point(x,y,z)); - } - } else if (command == HOST_CMD_SET_POSITION_EXT) { - // check for completion - if (command_buffer.getLength() >= 21) { - command_buffer.pop(); // remove the command code - int32_t x = pop32(); - int32_t y = pop32(); - int32_t z = pop32(); - int32_t a = pop32(); - int32_t b = pop32(); - steppers::definePosition(Point(x,y,z,a,b)); - } - } else if (command == HOST_CMD_DELAY) { - if (command_buffer.getLength() >= 5) { - mode = DELAY; - command_buffer.pop(); // remove the command code - // parameter is in milliseconds; timeouts need microseconds - uint32_t microseconds = pop32() * 1000; - delay_timeout.start(microseconds); - } - } else if (command == HOST_CMD_FIND_AXES_MINIMUM || - command == HOST_CMD_FIND_AXES_MAXIMUM) { - if (command_buffer.getLength() >= 8) { - command_buffer.pop(); // remove the command - uint8_t flags = pop8(); - uint32_t feedrate = pop32(); // feedrate in us per step - uint16_t timeout_s = pop16(); - bool direction = command == HOST_CMD_FIND_AXES_MAXIMUM; - mode = HOMING; - homing_timeout.start(timeout_s * 1000L * 1000L); - steppers::startHoming(command==HOST_CMD_FIND_AXES_MAXIMUM, - flags, - feedrate); - } - } else if (command == HOST_CMD_WAIT_FOR_TOOL) { - if (command_buffer.getLength() >= 6) { - mode = WAIT_ON_TOOL; - command_buffer.pop(); - uint8_t currentToolIndex = command_buffer.pop(); - uint16_t toolPingDelay = (uint16_t)pop16(); - uint16_t toolTimeout = (uint16_t)pop16(); - tool_wait_timeout.start(toolTimeout*1000000L); - } - } else if (command == HOST_CMD_WAIT_FOR_PLATFORM) { - // FIXME: Almost equivalent to WAIT_FOR_TOOL - if (command_buffer.getLength() >= 6) { - mode = WAIT_ON_PLATFORM; - command_buffer.pop(); - uint8_t currentToolIndex = command_buffer.pop(); - uint16_t toolPingDelay = (uint16_t)pop16(); - uint16_t toolTimeout = (uint16_t)pop16(); - tool_wait_timeout.start(toolTimeout*1000000L); - } - } else if (command == HOST_CMD_STORE_HOME_POSITION) { + if (!paused) + { + switch(mode) + { + case HOMING: { + if (!steppers::isRunning()) { + mode = READY; + } else if (homing_timeout.hasElapsed()) { + steppers::abort(); + mode = READY; + } + break; + } + case MOVING: { + if (!steppers::isRunning()) { mode = READY; } + break; + } + case DELAY: { + // check timers + if (delay_timeout.hasElapsed()) { + mode = READY; + } + break; + } + case WAIT_ON_TOOL: { + if (tool_wait_timeout.hasElapsed()) { + mode = READY; + } else if (tool::getLock()) { + OutPacket& out = tool::getOutPacket(); + InPacket& in = tool::getInPacket(); + out.reset(); + out.append8(tool::getCurrentToolheadIndex()); + out.append8(SLAVE_CMD_GET_TOOL_STATUS); + tool::startTransaction(); + tool::waitForTransaction(); + if (!in.hasError()) { + if (in.read8(1) & 0x01) { + mode = READY; + } + } + tool::releaseLock(); + } + break; + } + case WAIT_ON_PLATFORM: { + // FIXME: Duplicates most code from WAIT_ON_TOOL + if (tool_wait_timeout.hasElapsed()) { + mode = READY; + } else if (tool::getLock()) { + OutPacket& out = tool::getOutPacket(); + InPacket& in = tool::getInPacket(); + out.reset(); + out.append8(tool::getCurrentToolheadIndex()); + out.append8(SLAVE_CMD_IS_PLATFORM_READY); + tool::startTransaction(); + tool::waitForTransaction(); + if (!in.hasError()) { + if (in.read8(1) != 0) { + mode = READY; + } + } + tool::releaseLock(); + } + break; + } + } + + if (mode == READY) { + // process next command on the queue. + if (command_buffer.getLength() > 0) { + uint8_t command = command_buffer[0]; + switch(command) + { + case HOST_CMD_QUEUE_POINT_ABS:{ + // check for completion + if (command_buffer.getLength() >= 17) { + command_buffer.pop(); // remove the command code + mode = MOVING; + Point pt(pop32(), pop32(), pop32() ); + int32_t dda = pop32(); + steppers::setTarget(pt,dda); + } + break; + } + case HOST_CMD_QUEUE_POINT_ABS_16: { + // check for completion + if (command_buffer.getLength() >= 15) { + command_buffer.pop(); // remove the command code + mode = MOVING; + Point pt(pop16(), pop16(), pop16(), pop16(), pop16() ); + int32_t dda = pop32(); + steppers::setTarget(pt,dda); + } + break; + } + case HOST_CMD_QUEUE_POINT_NEW_16: { + // check for completion + if (command_buffer.getLength() >= 16) { + command_buffer.pop(); // remove the command code + mode = MOVING; + Point pt(pop16(), pop16(), pop16(), pop16(), pop16() ); + int32_t us = pop32(); + uint8_t relative = pop8(); + steppers::setTargetNew(pt,us,relative); + } + break; + } + case HOST_CMD_QUEUE_POINT_EXT: { + // check for completion + if (command_buffer.getLength() >= 25) { + command_buffer.pop(); // remove the command code + mode = MOVING; + Point pt(pop32(), pop32(), pop32(), pop32(), pop32() ); + int32_t dda = pop32(); + steppers::setTarget(pt,dda); + } + break; + } + case HOST_CMD_QUEUE_POINT_NEW: { + // check for completion + if (command_buffer.getLength() >= 26) { + command_buffer.pop(); // remove the command code + mode = MOVING; + Point pt(pop32(), pop32(), pop32(), pop32(), pop32() ); + int32_t us = pop32(); + uint8_t relative = pop8(); + steppers::setTargetNew(pt,us,relative); + } + break; + } + case HOST_CMD_CHANGE_TOOL: { + if (command_buffer.getLength() >= 2) { + command_buffer.pop(); // remove the command code + tool::setCurrentToolheadIndex(command_buffer.pop()); + } + break; + } + case HOST_CMD_ENABLE_AXES: { + if (command_buffer.getLength() >= 2) { + command_buffer.pop(); // remove the command code + uint8_t axes = command_buffer.pop(); + bool enable = (axes & 0x80) != 0; + for (int i = 0; i < STEPPER_COUNT; i++) { + if ((axes & _BV(i)) != 0) { + steppers::enableAxis(i, enable); + } + } + } + break; + } + case HOST_CMD_SET_POSITION: { + // check for completion + if (command_buffer.getLength() >= 13) { + command_buffer.pop(); // remove the command code + Point pt(pop32(), pop32(), pop32()); + steppers::definePosition(pt); + } + break; + } + case HOST_CMD_SET_POSITION_EXT: { + // check for completion + if (command_buffer.getLength() >= 21) { + command_buffer.pop(); // remove the command code + Point pt(pop32(), pop32(), pop32(), pop32(), pop32() ); + steppers::definePosition(pt); + } + break; + } + case HOST_CMD_SET_POSITION_16: { + // check for completion + if (command_buffer.getLength() >= 11) { + command_buffer.pop(); // remove the command code + Point pt(pop16(), pop16(), pop16(), pop16(), pop16() ); + steppers::definePosition(pt); + } + break; + } + case HOST_CMD_DELAY: { + if (command_buffer.getLength() >= 5) { + mode = DELAY; + command_buffer.pop(); // remove the command code + // parameter is in milliseconds; timeouts need microseconds + uint32_t microseconds = pop32() * 1000; + delay_timeout.start(microseconds); + } + break; + } + case HOST_CMD_FIND_AXES_MINIMUM: + case HOST_CMD_FIND_AXES_MAXIMUM: { + if (command_buffer.getLength() >= 8) { + command_buffer.pop(); // remove the command + uint8_t flags = pop8(); + uint32_t feedrate = pop32(); // feedrate in us per step + uint16_t timeout_s = pop16(); + bool direction = command == HOST_CMD_FIND_AXES_MAXIMUM; + mode = HOMING; + homing_timeout.start(timeout_s * 1000L * 1000L); + steppers::startHoming(command==HOST_CMD_FIND_AXES_MAXIMUM, + flags, + feedrate); + } + break; + } + case HOST_CMD_WAIT_FOR_TOOL: { + if (command_buffer.getLength() >= 6) { + mode = WAIT_ON_TOOL; + command_buffer.pop(); + uint8_t currentToolIndex = command_buffer.pop(); + uint16_t toolPingDelay = (uint16_t)pop16(); + uint16_t toolTimeout = (uint16_t)pop16(); + tool_wait_timeout.start(toolTimeout*1000000L); + } + break; + } + case HOST_CMD_WAIT_FOR_PLATFORM: { + // FIXME: Almost equivalent to WAIT_FOR_TOOL + if (command_buffer.getLength() >= 6) { + mode = WAIT_ON_PLATFORM; + command_buffer.pop(); + uint8_t currentToolIndex = command_buffer.pop(); + uint16_t toolPingDelay = (uint16_t)pop16(); + uint16_t toolTimeout = (uint16_t)pop16(); + tool_wait_timeout.start(toolTimeout*1000000L); + } + break; + } + case HOST_CMD_STORE_HOME_POSITION: { - // check for completion - if (command_buffer.getLength() >= 2) { - command_buffer.pop(); - uint8_t axes = pop8(); + // check for completion + if (command_buffer.getLength() >= 2) { + command_buffer.pop(); + uint8_t axes = pop8(); - // Go through each axis, and if that axis is specified, read it's value, - // then record it to the eeprom. - for (uint8_t i = 0; i < STEPPER_COUNT; i++) { - if ( axes & (1 << i) ) { - uint16_t offset = eeprom::AXIS_HOME_POSITIONS + 4*i; - uint32_t position = steppers::getPosition()[i]; - cli(); - eeprom_write_block(&position, (void*) offset, 4); - sei(); - } - } - } - } else if (command == HOST_CMD_RECALL_HOME_POSITION) { - // check for completion - if (command_buffer.getLength() >= 2) { - command_buffer.pop(); - uint8_t axes = pop8(); + // Go through each axis, and if that axis is specified, read it's value, + // then record it to the eeprom. + Point point; + steppers::getPosition(&point); + uint16_t offset = eeprom::AXIS_HOME_POSITIONS; + for (uint8_t i = 0; i < STEPPER_COUNT; i++) { + if ( axes & (1 << i) ) { + uint32_t position = point[i]; + eeprom_write_block(&position, (void*) offset, 4); + } + offset += 4; + } + } + break; + } + case HOST_CMD_RECALL_HOME_POSITION: { + // check for completion + if (command_buffer.getLength() >= 2) { + command_buffer.pop(); + uint8_t axes = pop8(); - Point newPoint = steppers::getPosition(); + Point newPoint; + steppers::getPosition(&newPoint); // load existing position first - for (uint8_t i = 0; i < STEPPER_COUNT; i++) { - if ( axes & (1 << i) ) { - uint16_t offset = eeprom::AXIS_HOME_POSITIONS + 4*i; - cli(); - eeprom_read_block(&(newPoint[i]), (void*) offset, 4); - sei(); - } - } + uint16_t offset = eeprom::AXIS_HOME_POSITIONS; + for (uint8_t i = 0; i < STEPPER_COUNT; i++) { + if ( axes & (1 << i) ) { + eeprom_read_block(&(newPoint[i]), (void*) offset, 4); + } + offset += 4; + } - steppers::definePosition(newPoint); - } + steppers::definePosition(newPoint); + } - } else if (command == HOST_CMD_TOOL_COMMAND) { - if (command_buffer.getLength() >= 4) { // needs a payload - uint8_t payload_length = command_buffer[3]; - if (command_buffer.getLength() >= 4+payload_length) { - // command is ready - if (tool::getLock()) { - OutPacket& out = tool::getOutPacket(); - out.reset(); - command_buffer.pop(); // remove the command code - out.append8(command_buffer.pop()); // copy tool index - out.append8(command_buffer.pop()); // copy command code - int len = pop8(); // get payload length - for (int i = 0; i < len; i++) { - out.append8(command_buffer.pop()); - } - // we don't care about the response, so we can release - // the lock after we initiate the transfer - tool::startTransaction(); - tool::releaseLock(); - } - } - } - } else { - } + break; + } + case HOST_CMD_TOOL_COMMAND: { + if (command_buffer.getLength() >= 4) { // needs a payload + uint8_t payload_length = command_buffer[3]; + if (command_buffer.getLength() >= 4+payload_length) { + // command is ready + if (tool::getLock()) { + OutPacket& out = tool::getOutPacket(); + out.reset(); + command_buffer.pop(); // remove the command code + out.append8(command_buffer.pop()); // copy tool index + out.append8(command_buffer.pop()); // copy command code + int len = pop8(); // get payload length + for (int i = 0; i < len; i++) { + out.append8(command_buffer.pop()); + } + // we don't care about the response, so we can release + // the lock after we initiate the transfer + tool::startTransaction(); + tool::releaseLock(); + } + } + } + break; + } + } + } } } + DEBUG_CMD_SLICE_PIN::setValue(false); } } From e2028e35b7f1c7e6de6769e58966c250c93c796c Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 30 Nov 2011 20:42:07 -0800 Subject: [PATCH 29/39] optimize position code for retrieving and appending position data. add initial support for 16bit position values and commands modifiy runHostSlice to not return out of the middle of itself so that it could easily be wrapped by debug logic --- firmware/src/Motherboard/Host.cc | 196 ++++++++++++++++++------------- firmware/src/Motherboard/Host.hh | 5 +- firmware/src/shared/Commands.hh | 5 + 3 files changed, 125 insertions(+), 81 deletions(-) diff --git a/firmware/src/Motherboard/Host.cc b/firmware/src/Motherboard/Host.cc index dadcf48..47283e3 100644 --- a/firmware/src/Motherboard/Host.cc +++ b/firmware/src/Motherboard/Host.cc @@ -59,63 +59,71 @@ HostState currentState; bool do_host_reset = true; -void runHostSlice() { - InPacket& in = UART::getHostUART().in; - OutPacket& out = UART::getHostUART().out; - if (out.isSending()) { - // still sending; wait until send is complete before reading new host packets. - return; - } - if (do_host_reset) { - do_host_reset = false; - // Then, reset local board - reset(false); - packet_in_timeout.abort(); - - // Clear the machine and build names - machineName[0] = 0; - buildName[0] = 0; - currentState = HOST_STATE_READY; +void resetHost() { + DEBUG_HOST_SLICE_PIN::setDirection(true); + DEBUG_HOST_SLICE_PIN::setValue(false); +} - return; - } - if (in.isStarted() && !in.isFinished()) { - if (!packet_in_timeout.isActive()) { - // initiate timeout - packet_in_timeout.start(HOST_PACKET_TIMEOUT_MICROS); - } else if (packet_in_timeout.hasElapsed()) { - in.timeout(); - } - } - if (in.hasError()) { - // Reset packet quickly and start handling the next packet. - // Report error code. - if (in.getErrorCode() == PacketError::PACKET_TIMEOUT) { - Motherboard::getBoard().indicateError(ERR_HOST_PACKET_TIMEOUT); - } else { - Motherboard::getBoard().indicateError(ERR_HOST_PACKET_MISC); - } - in.reset(); - } - if (in.isFinished()) { - packet_in_timeout.abort(); - out.reset(); -#if defined(HONOR_DEBUG_PACKETS) && (HONOR_DEBUG_PACKETS == 1) - if (processDebugPacket(in, out)) { - // okay, processed - } else -#endif - if (processCommandPacket(in, out)) { - // okay, processed - } else if (processQueryPacket(in, out)) { - // okay, processed - } else { - // Unrecognized command - out.append8(RC_CMD_UNSUPPORTED); - } - in.reset(); +void runHostSlice() { + DEBUG_HOST_SLICE_PIN::setValue(true); + + // still sending; wait until send is complete before reading new host packets. + OutPacket& out = UART::getHostUART().out; + if (!out.isSending()) { + if (do_host_reset) { + do_host_reset = false; + // Then, reset local board + reset(false); + packet_in_timeout.abort(); + + // Clear the machine and build names + machineName[0] = 0; + buildName[0] = 0; + currentState = HOST_STATE_READY; + } + else + { + InPacket& in = UART::getHostUART().in; + if (in.isStarted() && !in.isFinished()) { + if (!packet_in_timeout.isActive()) { + // initiate timeout + packet_in_timeout.start(HOST_PACKET_TIMEOUT_MICROS); + } else if (packet_in_timeout.hasElapsed()) { + in.timeout(); + } + } + if (in.hasError()) { + // Reset packet quickly and start handling the next packet. + // Report error code. + if (in.getErrorCode() == PacketError::PACKET_TIMEOUT) { + Motherboard::getBoard().indicateError(ERR_HOST_PACKET_TIMEOUT); + } else { + Motherboard::getBoard().indicateError(ERR_HOST_PACKET_MISC); + } + in.reset(); + } + if (in.isFinished()) { + packet_in_timeout.abort(); + out.reset(); + #if defined(HONOR_DEBUG_PACKETS) && (HONOR_DEBUG_PACKETS == 1) + if (processDebugPacket(in, out)) { + // okay, processed + } else + #endif + if (processCommandPacket(in, out)) { + // okay, processed + } else if (processQueryPacket(in, out)) { + // okay, processed + } else { + // Unrecognized command + out.append8(RC_CMD_UNSUPPORTED); + } + in.reset(); UART::getHostUART().beginSend(); - } + } + } + } + DEBUG_HOST_SLICE_PIN::setValue(false); } /// Identify a command packet, and process it. If the packet is a command @@ -196,28 +204,41 @@ inline void handleGetBufferSize(const InPacket& from_host, OutPacket& to_host) { } inline void handleGetPosition(const InPacket& from_host, OutPacket& to_host) { - ATOMIC_BLOCK(ATOMIC_FORCEON) { - const Point p = steppers::getPosition(); - to_host.append8(RC_OK); - to_host.append32(p[0]); - to_host.append32(p[1]); - to_host.append32(p[2]); + //ATOMIC_BLOCK(ATOMIC_FORCEON) + { + Motherboard& board = Motherboard::getBoard(); // From spec: // endstop status bits: (7-0) : | N/A | N/A | z max | z min | y max | y min | x max | x min | - Motherboard& board = Motherboard::getBoard(); uint8_t endstop_status = 0; - for (int i = 3; i > 0; i--) { - const StepperInterface* si = board.getStepperInterface(i-1); + for (int i = 2; i >= 0; i--) { + const StepperInterface* si = board.getStepperInterface(i); endstop_status <<= 2; endstop_status |= (si->isAtMaximum()?2:0) | (si->isAtMinimum()?1:0); } + Point p; + steppers::getPosition(&p); + to_host.append8(RC_OK); + to_host.append32(p[0]); + to_host.append32(p[1]); + to_host.append32(p[2]); to_host.append8(endstop_status); } } inline void handleGetPositionExt(const InPacket& from_host, OutPacket& to_host) { - ATOMIC_BLOCK(ATOMIC_FORCEON) { - const Point p = steppers::getPosition(); + //ATOMIC_BLOCK(ATOMIC_FORCEON) + { + // From spec: + // endstop status bits: (15-0) : | b max | b min | a max | a min | z max | z min | y max | y min | x max | x min | + Motherboard& board = Motherboard::getBoard(); + uint8_t endstop_status = 0; + for (int i = STEPPER_COUNT-1; i >= 0; i--) { + const StepperInterface* si = board.getStepperInterface(i); + endstop_status <<= 2; + endstop_status |= (si->isAtMaximum()?2:0) | (si->isAtMinimum()?1:0); + } + Point p; + steppers::getPosition(&p); to_host.append8(RC_OK); to_host.append32(p[0]); to_host.append32(p[1]); @@ -229,15 +250,35 @@ inline void handleGetPositionExt(const InPacket& from_host, OutPacket& to_host) to_host.append32(0); to_host.append32(0); #endif + to_host.append16(endstop_status); + } +} + +inline void handleGetPosition16(const InPacket& from_host, OutPacket& to_host) { + //ATOMIC_BLOCK(ATOMIC_FORCEON) + { // From spec: // endstop status bits: (15-0) : | b max | b min | a max | a min | z max | z min | y max | y min | x max | x min | Motherboard& board = Motherboard::getBoard(); uint8_t endstop_status = 0; - for (int i = STEPPER_COUNT; i > 0; i--) { - const StepperInterface* si = board.getStepperInterface(i-1); + for (int i = STEPPER_COUNT-1; i >= 0; i--) { + const StepperInterface* si = board.getStepperInterface(i); endstop_status <<= 2; endstop_status |= (si->isAtMaximum()?2:0) | (si->isAtMinimum()?1:0); } + Point p; + steppers::getPosition(&p); + to_host.append8(RC_OK); + to_host.append16(p[0]); + to_host.append16(p[1]); + to_host.append16(p[2]); +#if STEPPER_COUNT > 3 + to_host.append16(p[3]); + to_host.append16(p[4]); +#else + to_host.append16(0); + to_host.append16(0); +#endif to_host.append16(endstop_status); } } @@ -310,10 +351,7 @@ void doToolPause(OutPacket& to_host) { // to check for timeouts on this loop. tool::startTransaction(); tool::releaseLock(); - // WHILE: bounded by tool timeout in runToolSlice - while (!tool::isTransactionDone()) { - tool::runToolSlice(); - } + tool::waitForTransaction(); if (in.getErrorCode() == PacketError::PACKET_TIMEOUT) { to_host.append8(RC_DOWNSTREAM_TIMEOUT); } else { @@ -351,10 +389,7 @@ inline void handleToolQuery(const InPacket& from_host, OutPacket& to_host) { // to check for timeouts on this loop. tool::startTransaction(); tool::releaseLock(); - // WHILE: bounded by tool timeout in runToolSlice - while (!tool::isTransactionDone()) { - tool::runToolSlice(); - } + tool::waitForTransaction(); if (in.getErrorCode() == PacketError::PACKET_TIMEOUT) { to_host.append8(RC_DOWNSTREAM_TIMEOUT); } else { @@ -477,12 +512,17 @@ bool processQueryPacket(const InPacket& from_host, OutPacket& to_host) { case HOST_CMD_GET_BUFFER_SIZE: handleGetBufferSize(from_host,to_host); return true; +/* case HOST_CMD_GET_POSITION: handleGetPosition(from_host,to_host); return true; case HOST_CMD_GET_POSITION_EXT: handleGetPositionExt(from_host,to_host); return true; +*/ + case HOST_CMD_GET_POSITION_16: + handleGetPosition16(from_host,to_host); + return true; case HOST_CMD_CAPTURE_TO_FILE: handleCaptureToFile(from_host,to_host); return true; @@ -555,10 +595,6 @@ char* getBuildName() { return buildName; } -HostState getHostState() { - return currentState; -} - sdcard::SdErrorCode startBuildFromSD() { sdcard::SdErrorCode e; diff --git a/firmware/src/Motherboard/Host.hh b/firmware/src/Motherboard/Host.hh index 1d13327..8cf02c6 100644 --- a/firmware/src/Motherboard/Host.hh +++ b/firmware/src/Motherboard/Host.hh @@ -38,6 +38,8 @@ enum HostState { HOST_STATE_ERROR = 3 }; +void resetHost(); + /// Run the host slice. This function handles incoming packets and host resets. void runHostSlice(); @@ -53,7 +55,8 @@ char* getBuildName(); /// state machine, which is used to determine what information should be /// displayed on the interface board. /// \return Current host state. -HostState getHostState(); +extern HostState currentState; +inline HostState getHostState() { return currentState; } /// Start a build from SD card. The build name should be set by overwriting /// the value of buildName, provided by #getBuildName(). diff --git a/firmware/src/shared/Commands.hh b/firmware/src/shared/Commands.hh index 5d8f6ce..e3fd35c 100644 --- a/firmware/src/shared/Commands.hh +++ b/firmware/src/shared/Commands.hh @@ -105,6 +105,11 @@ #define HOST_CMD_STORE_HOME_POSITION 143 #define HOST_CMD_RECALL_HOME_POSITION 144 +#define HOST_CMD_QUEUE_POINT_ABS_16 160 +#define HOST_CMD_QUEUE_POINT_NEW_16 161 +#define HOST_CMD_SET_POSITION_16 162 +#define HOST_CMD_GET_POSITION_16 163 + #define HOST_CMD_DEBUG_ECHO 0x70 // These are our query commands from the host From f7ad61570568cefd619ab355566cf97c4e438fdd Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 30 Nov 2011 20:59:23 -0800 Subject: [PATCH 30/39] optimized monitoring the tool during building --- firmware/src/shared/Menu.cc | 73 +++++++++++++++---------------------- 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/firmware/src/shared/Menu.cc b/firmware/src/shared/Menu.cc index d1f655f..54907b1 100644 --- a/firmware/src/shared/Menu.cc +++ b/firmware/src/shared/Menu.cc @@ -21,8 +21,7 @@ #define HOST_TOOL_RESPONSE_TIMEOUT_MICROS (1000L*HOST_TOOL_RESPONSE_TIMEOUT_MS) /// Send a query packet to the extruder -bool queryExtruderParameter(uint8_t parameter, OutPacket& responsePacket) { - +bool queryExtruderParameter(uint8_t parameter, uint16_t& value ) { Timeout acquire_lock_timeout; acquire_lock_timeout.start(HOST_TOOL_RESPONSE_TIMEOUT_MS); while (!tool::getLock()) { @@ -30,10 +29,9 @@ bool queryExtruderParameter(uint8_t parameter, OutPacket& responsePacket) { return false; } } + OutPacket& out = tool::getOutPacket(); - InPacket& in = tool::getInPacket(); out.reset(); - responsePacket.reset(); // Fill the query packet. The first byte is the toolhead index, and the // second is the @@ -44,25 +42,22 @@ bool queryExtruderParameter(uint8_t parameter, OutPacket& responsePacket) { // to check for timeouts on this loop. tool::startTransaction(); tool::releaseLock(); - // WHILE: bounded by tool timeout in runToolSlice - while (!tool::isTransactionDone()) { - tool::runToolSlice(); - } + + // do this busy work after the transaction has started + InPacket& in = tool::getInPacket(); + + DEBUG_QUERY_TOOL_PIN::setValue(true); + tool::waitForTransaction(); + DEBUG_QUERY_TOOL_PIN::setValue(false); if (in.getErrorCode() == PacketError::PACKET_TIMEOUT) { return false; } else { - // Copy payload back. Start from 0-- we need the response code. - for (uint8_t i = 0; i < in.getLength(); i++) { - responsePacket.append8(in.read8(i)); - } - } + value = in.read16(1); - // Check that the extruder was able to process the request - if (!rcCompare(responsePacket.read8(0),RC_OK)) { - return false; + // Check that the extruder was able to process the request + return rcCompare(in.read8(0),RC_OK); } - return true; } void SplashScreen::update(Display& display, bool forceRedraw) { @@ -140,7 +135,9 @@ void JogMode::update(Display& display, bool forceRedraw) { } void JogMode::jog(ButtonArray::ButtonName direction) { - Point position = steppers::getPosition(); + + Point position; + steppers::getPosition(&position); int32_t interval = 2000; uint8_t steps; @@ -366,51 +363,39 @@ void MonitorMode::update(Display& display, bool forceRedraw) { } - OutPacket responsePacket; - + bool success = false; + uint16_t data = 0; // Redraw tool info switch (updatePhase) { case 0: display.setCursor(6,2); - if (queryExtruderParameter(SLAVE_CMD_GET_TEMP, responsePacket)) { - uint16_t data = responsePacket.read16(1); - display.writeInt(data,3); - } else { - display.writeString("XXX"); - } + success = queryExtruderParameter(SLAVE_CMD_GET_TEMP, data); break; case 1: display.setCursor(10,2); - if (queryExtruderParameter(SLAVE_CMD_GET_SP, responsePacket)) { - uint16_t data = responsePacket.read16(1); - display.writeInt(data,3); - } else { - display.writeString("XXX"); - } + success = queryExtruderParameter(SLAVE_CMD_GET_SP, data); break; case 2: display.setCursor(6,3); - if (queryExtruderParameter(SLAVE_CMD_GET_PLATFORM_TEMP, responsePacket)) { - uint16_t data = responsePacket.read16(1); - display.writeInt(data,3); - } else { - display.writeString("XXX"); - } + success = queryExtruderParameter(SLAVE_CMD_GET_PLATFORM_TEMP, data); break; case 3: display.setCursor(10,3); - if (queryExtruderParameter(SLAVE_CMD_GET_PLATFORM_SP, responsePacket)) { - uint16_t data = responsePacket.read16(1); - display.writeInt(data,3); - } else { - display.writeString("XXX"); - } + success = queryExtruderParameter(SLAVE_CMD_GET_PLATFORM_SP, data); break; } + if ( success ) + { + display.writeInt(data,3); + } else { + display.writeString("XXX"); + } + + updatePhase++; if (updatePhase > 3) { updatePhase = 0; From 0b4a9595054e0dcaa2f41c6621ce8471a70185c3 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 30 Nov 2011 21:01:36 -0800 Subject: [PATCH 31/39] pre-template --- firmware/src/shared/UART.cc | 20 +++++++++++--------- firmware/src/shared/UART.hh | 4 ++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/firmware/src/shared/UART.cc b/firmware/src/shared/UART.cc index db3c7b3..204d3c6 100644 --- a/firmware/src/shared/UART.cc +++ b/firmware/src/shared/UART.cc @@ -31,6 +31,7 @@ #include "ExtruderBoard.hh" #endif +#define RS485_TRANSMISSION_LINE_DELAY_US 1 // We have to track the number of bytes that have been sent, so that we can filter // them from our receive buffer later.This is only used for RS485 mode. volatile uint8_t loopback_bytes = 0; @@ -45,9 +46,11 @@ volatile uint8_t loopback_bytes = 0; #error UART not implemented on this processor type! #endif +#define UCSRA_VALUE(uart_) _BV(U2X##uart_) // baud rate doubling + #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega328__) - #define UBRR_VALUE 25 + #define UBRR_VALUE 16 #define UCSR0A_VALUE 0 #define INIT_SERIAL(uart_) \ @@ -56,14 +59,14 @@ volatile uint8_t loopback_bytes = 0; UBRR0L = UBRR_VALUE & 0xff; \ \ /* set config for uart, explicitly clear TX interrupt flag */ \ - UCSR0A = UCSR0A_VALUE | _BV(TXC0); \ + UCSR0A = UCSRA_VALUE(uart_) | _BV(TXC0); \ UCSR0B = _BV(RXEN0) | _BV(TXEN0); \ UCSR0C = _BV(UCSZ01)|_BV(UCSZ00); \ } #elif defined (__AVR_ATmega644P__) - #define UBRR_VALUE 25 + #define UBRR_VALUE 16 #define UBRRA_VALUE 0 // Adapted from ancient arduino/wiring rabbit hole @@ -73,7 +76,7 @@ volatile uint8_t loopback_bytes = 0; UBRR##uart_##L = UBRR_VALUE & 0xff; \ \ /* set config for uart_ */ \ - UCSR##uart_##A = UBRRA_VALUE; \ + UCSR##uart_##A = UCSRA_VALUE(uart_); \ UCSR##uart_##B = _BV(RXEN##uart_) | _BV(TXEN##uart_); \ UCSR##uart_##C = _BV(UCSZ##uart_##1)|_BV(UCSZ##uart_##0); \ } @@ -82,8 +85,7 @@ volatile uint8_t loopback_bytes = 0; // Use double-speed mode for more accurate baud rate? #define UBRR0_VALUE 16 // 115200 baud - #define UBRR1_VALUE 51 // 38400 baud - #define UCSRA_VALUE(uart_) _BV(U2X##uart_) + #define UBRR1_VALUE 16 // 115200 baud // Adapted from ancient arduino/wiring rabbit hole #define INIT_SERIAL(uart_) \ @@ -138,7 +140,7 @@ void UART::init_serial() { #endif } -void UART::send_byte(char data) { +inline void UART::send_byte(char data) { if(index_ == 0) { UDR0 = data; } @@ -175,7 +177,7 @@ void UART::beginSend() { if (mode_ == RS485) { speak(); - _delay_us(10); + _delay_us(RS485_TRANSMISSION_LINE_DELAY_US); loopback_bytes = 1; } @@ -283,7 +285,7 @@ void UART::reset() { loopback_bytes++; UDR1 = UART::getSlaveUART().out.getNextByteToSend(); } else { - _delay_us(10); + //_delay_us(RS485_TRANSMISSION_LINE_DELAY_US); listen(); } } diff --git a/firmware/src/shared/UART.hh b/firmware/src/shared/UART.hh index e373660..e719b30 100644 --- a/firmware/src/shared/UART.hh +++ b/firmware/src/shared/UART.hh @@ -73,7 +73,7 @@ private: /// Send a byte of data over the serial line. /// \param[in] data Data byte to send - inline void send_byte(char data); + void send_byte(char data); const communication_mode mode_; ///< Communication mode we are speaking const uint8_t index_; ///< Hardware UART index @@ -88,7 +88,7 @@ public: /// Enable or disable the serial port. /// \param[in] true to enable the serial port, false to disable it. - void enable(bool enabled); + void enable(bool enabled); /// Reset the UART to a listening state. This is important for /// RS485-based comms. From 6ae5671a28fbdbe77b78172f5672cac8ea6012fd Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 30 Nov 2011 22:28:58 -0800 Subject: [PATCH 32/39] comment out unused code --- firmware/src/Extruder/DebugPacketProcessor.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/src/Extruder/DebugPacketProcessor.cc b/firmware/src/Extruder/DebugPacketProcessor.cc index 5d7c752..8006cf2 100644 --- a/firmware/src/Extruder/DebugPacketProcessor.cc +++ b/firmware/src/Extruder/DebugPacketProcessor.cc @@ -67,10 +67,12 @@ bool processDebugPacket(const InPacket& from_host, OutPacket& to_host) { to_host.append8(from_host.read8(i)); } return true; +/* } else if (command == CommandCode::DEBUG_GENERATE_BAD_PACKET) { // TODO } else if (command == CommandCode::DEBUG_SIMULATE_BAD_PACKET) { // TODO +*/ } else if (command == CommandCode::DEBUG_SLAVE_PASSTHRU) { return true; } From f393127a4d93cc095500f1d6e66bd411f2e8a7b5 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 30 Nov 2011 22:30:57 -0800 Subject: [PATCH 33/39] optimized packet handling. CRC of incoming packets are calculated after the entire packet is built so that it can be done outside of an interrupt. --- firmware/src/Motherboard/Tool.cc | 107 ++++++++++---------- firmware/src/Motherboard/Tool.hh | 4 + firmware/src/shared/Packet.cc | 164 ++++++++++++++++++------------- firmware/src/shared/Packet.hh | 61 +++++++----- firmware/src/shared/UART.cc | 43 ++------ firmware/src/shared/UART.hh | 3 - 6 files changed, 196 insertions(+), 186 deletions(-) diff --git a/firmware/src/Motherboard/Tool.cc b/firmware/src/Motherboard/Tool.cc index 26aedfb..3451cee 100644 --- a/firmware/src/Motherboard/Tool.cc +++ b/firmware/src/Motherboard/Tool.cc @@ -26,8 +26,6 @@ #define TOOL_PACKET_TIMEOUT_MS 50L #define TOOL_PACKET_TIMEOUT_MICROS (1000L*TOOL_PACKET_TIMEOUT_MS) -#define DELAY_BETWEEN_TRANSMISSIONS_MICROS (500L) - namespace tool { // TODO: Don't bother initializing these here. @@ -101,10 +99,7 @@ bool getToolVersion() { // override standard timeout timeout.start(TOOL_PACKET_TIMEOUT_MICROS*2); releaseLock(); - // WHILE: bounded by tool timeout - while (!isTransactionDone()) { - runToolSlice(); // This will most likely time out if there's multiple toolheads. - } + waitForTransaction(); if (in.getErrorCode() == PacketError::PACKET_TIMEOUT) { return false; @@ -143,13 +138,13 @@ void setToolIndicatorLED() { // override standard timeout timeout.start(TOOL_PACKET_TIMEOUT_MICROS*2); releaseLock(); - // WHILE: bounded by tool timeout - while (!isTransactionDone()) { - runToolSlice(); // This will most likely time out if there's multiple toolheads. - } + waitForTransaction(); } bool reset() { + DEBUG_TOOL_SLICE_PIN::setDirection(true); + DEBUG_TOOL_SLICE_PIN::setValue(false); + // This code is very lightly modified from handleToolQuery in Host.cc. // We don't give up if we fail to get a lock; we force it instead. Timeout acquire_lock_timeout; @@ -158,7 +153,7 @@ bool reset() { if (acquire_lock_timeout.hasElapsed()) { locked = true; // grant ourselves the lock transaction_active = false; // abort transaction! - Motherboard::getBoard().indicateError(ERR_SLAVE_LOCK_TIMEOUT); + Motherboard::getBoard().indicateError(ERR_SLAVE_LOCK_TIMEOUT); break; } } @@ -171,10 +166,7 @@ bool reset() { // override standard timeout timeout.start(TOOL_PACKET_TIMEOUT_MICROS*2); releaseLock(); - // WHILE: bounded by tool timeout - while (!isTransactionDone()) { - runToolSlice(); // This will most likely time out if there's multiple toolheads. - } + waitForTransaction(); return UART::getSlaveUART().in.isFinished(); } @@ -215,68 +207,71 @@ void releaseLock() { locked = false; } +static Timeout lastTransaction; void startTransaction() { - sent_packet_count++; - - // Enforce a minimum off-time between transactions - // TODO: Base this on the time from the last transaction. - Timeout t; - t.start(DELAY_BETWEEN_TRANSMISSIONS_MICROS); // wait for xxx us - while (!t.hasElapsed()); - transaction_active = true; + sent_packet_count++; + timeout.start(TOOL_PACKET_TIMEOUT_MICROS); // 50 ms timeout retries = RETRIES; - UART::getSlaveUART().in.reset(); - UART::getSlaveUART().beginSend(); + UART::getSlaveUART().in.reset(); + UART::getSlaveUART().beginSend(); } bool isTransactionDone() { return !transaction_active; } -void runToolSlice() { +void waitForTransaction() +{ + while (transaction_active) { + tool::runToolSlice(); + } +} + +static bool retryCommunication(){ + if (retries) { + packet_retry_count++; + retries--; + timeout.start(TOOL_PACKET_TIMEOUT_MICROS); // 50 ms timeout UART& uart = UART::getSlaveUART(); + uart.out.prepareForResend(); + uart.in.reset(); + uart.reset(); + uart.beginSend(); + return true; + } + return false; +} + +void runToolSlice() { + DEBUG_TOOL_SLICE_PIN::setValue(true); + UART& uart = UART::getSlaveUART(); if (transaction_active) { - if (uart.in.isFinished()) - { + if (uart.in.isFinished()) { transaction_active = false; } else if (uart.in.hasError()) { - if (uart.in.getErrorCode() == PacketError::NOISE_BYTE) { - noise_byte_count++; - uart.in.reset(); - } else - if (retries) { - packet_retry_count++; - retries--; - timeout.start(TOOL_PACKET_TIMEOUT_MICROS); // 50 ms timeout - uart.out.prepareForResend(); - uart.in.reset(); - uart.reset(); - uart.beginSend(); - } else { - packet_failure_count++; - transaction_active = false; - Motherboard::getBoard().indicateError(ERR_SLAVE_PACKET_MISC); - } + if (uart.in.getErrorCode() == PacketError::NOISE_BYTE) { + noise_byte_count++; + uart.in.reset(); + } else if ( !retryCommunication() ) { + transaction_active = false; + Motherboard::getBoard().indicateError(ERR_SLAVE_PACKET_MISC); + } } else if (timeout.hasElapsed()) { - if (retries) { - packet_retry_count++; - retries--; - timeout.start(TOOL_PACKET_TIMEOUT_MICROS); // 50 ms timeout - uart.out.prepareForResend(); - uart.in.reset(); - uart.reset(); - uart.beginSend(); - } else { - packet_failure_count++; + if ( !retryCommunication() ) { uart.in.timeout(); uart.reset(); + packet_failure_count++; transaction_active = false; - Motherboard::getBoard().indicateError(ERR_SLAVE_PACKET_TIMEOUT); + Motherboard::getBoard().indicateError(ERR_SLAVE_PACKET_TIMEOUT); } } + else + { + } } + DEBUG_TOOL_SLICE_PIN::setValue(false); } void setCurrentToolheadIndex(uint8_t tool_index_in) { diff --git a/firmware/src/Motherboard/Tool.hh b/firmware/src/Motherboard/Tool.hh index f829efd..1cf1a41 100644 --- a/firmware/src/Motherboard/Tool.hh +++ b/firmware/src/Motherboard/Tool.hh @@ -57,6 +57,10 @@ void startTransaction(); /// \return True if the transaction is complete. bool isTransactionDone(); +/// Wait for a transaction to completed. +void waitForTransaction(); + + /// Get the output packet /// \return Reference to the output packet, which the host should fill with a query /// to send to the tool. diff --git a/firmware/src/shared/Packet.cc b/firmware/src/shared/Packet.cc index 1c8726a..fc081ce 100644 --- a/firmware/src/shared/Packet.cc +++ b/firmware/src/shared/Packet.cc @@ -16,10 +16,19 @@ */ #include "Packet.hh" +#include "Configuration.hh" #include +#include +void InPacket::appendByte(uint8_t data) { + if (length < MAX_PACKET_PAYLOAD) { + crc = _crc_ibutton_update(crc, data); + payload[length] = data; + length++; + } +} /// Append a byte and update the CRC -void Packet::appendByte(uint8_t data) { +void OutPacket::appendByte(uint8_t data) { if (length < MAX_PACKET_PAYLOAD) { crc = _crc_ibutton_update(crc, data); payload[length] = data; @@ -39,51 +48,71 @@ void Packet::reset() { state = PS_START; } -InPacket::InPacket() { - reset(); +void InPacket::computeCRC() +{ + if ( state == PS_COMPUTE_CRC ) + { + state = PS_LAST; + uint8_t _crc = 0; + for( uint8_t ndx = 0; ndx < length; ndx++ ) + { + _crc = _crc_ibutton_update(_crc, payload[ndx]); + } + if (crc != _crc) { + error(PacketError::BAD_CRC); + } + } } -/// Reset the entire packet reception. -void InPacket::reset() { - Packet::reset(); -} //process a byte for our packet. void InPacket::processByte(uint8_t b) { - if (state == PS_START) { - if (b == START_BYTE) { - state = PS_LEN; - } else { - error(PacketError::NOISE_BYTE); - } - } else if (state == PS_LEN) { - if (b < MAX_PACKET_PAYLOAD) { - expected_length = b; - state = (expected_length == 0) ? PS_CRC : PS_PAYLOAD; - } else { - error(PacketError::EXCEEDED_MAX_LENGTH); - } - } else if (state == PS_PAYLOAD) { - appendByte(b); - if (length >= expected_length) { - state = PS_CRC; - } - } else if (state == PS_CRC) { - if (crc == b) { - state = PS_LAST; - } else { - error(PacketError::BAD_CRC); - } - } + switch(state){ + case PS_START: + if (b == START_BYTE) { + state = PS_LEN; + } else { + error(PacketError::NOISE_BYTE); + } + break; + case PS_LEN: + if (b < MAX_PACKET_PAYLOAD) { + expected_length = b; + state = (expected_length == 0) ? PS_CRC : PS_PAYLOAD; + } else { + error(PacketError::EXCEEDED_MAX_LENGTH); + } + break; + case PS_PAYLOAD: + appendByte(b); + if (length >= expected_length) { + state = PS_CRC; + } + break; + case PS_CRC: + crc = b; + state = PS_COMPUTE_CRC; +/* + if ( crc == b ) + { + state = PS_LAST; + } + else + { + error(PacketError::BAD_CRC); + } +*/ + break; + default: + //DEBUG_PACKET_PIN::setValue(true); + break; + } + + } // Reads an 8-bit byte from the specified index of the payload -uint8_t Packet::read8(uint8_t index) const { - return payload[index]; -} -uint16_t Packet::read16(uint8_t index) const { - return payload[index] | (payload[index + 1] << 8); -} +/* uint32_t Packet::read32(uint8_t index) const { union { // AVR is little-endian @@ -92,23 +121,15 @@ uint32_t Packet::read32(uint8_t index) const { uint8_t data[4]; } b; } shared; - shared.b.data[0] = payload[index]; + return *((uint32_t*)(payload+index)); + shared.b.data[0] = p[index]; shared.b.data[1] = payload[index+1]; shared.b.data[2] = payload[index+2]; shared.b.data[3] = payload[index+3]; return shared.a; } - -OutPacket::OutPacket() { - reset(); -} - -/// Reset the entire packet transmission. -void OutPacket::reset() { - Packet::reset(); - send_payload_index = 0; -} +*/ void OutPacket::prepareForResend() { error_code = PacketError::NO_ERROR; @@ -116,36 +137,37 @@ void OutPacket::prepareForResend() { send_payload_index = 0; } uint8_t OutPacket::getNextByteToSend() { - uint8_t next_byte = 0; - if (state == PS_START) { - next_byte = START_BYTE; - state = PS_LEN; - } else if (state == PS_LEN) { - next_byte = length; - state = (length==0)?PS_CRC:PS_PAYLOAD; - } else if (state == PS_PAYLOAD) { - next_byte= payload[send_payload_index++]; - if (send_payload_index >= length) { - state = PS_CRC; - } - } else if (state == PS_CRC) { - next_byte = crc; - state = PS_LAST; + switch(state){ + case PS_START: + state = PS_LEN; + return START_BYTE; + case PS_LEN: + state = (length==0)?PS_CRC:PS_PAYLOAD; + return length; + case PS_PAYLOAD: + { + uint8_t next_byte = payload[send_payload_index++]; + if (send_payload_index >= length) { + state = PS_CRC; + } + return next_byte; + } + case PS_CRC: + state = PS_LAST; + return crc; + default: + // we should never get here + return 0; } - return next_byte; } -// Add an 8-bit byte to the end of the payload -void OutPacket::append8(uint8_t value) { - appendByte(value); -} void OutPacket::append16(uint16_t value) { appendByte(value&0xff); - appendByte((value>>8)&0xff); + appendByte((value>>8)); // don't need to bit-wise AND the last byte } void OutPacket::append32(uint32_t value) { appendByte(value&0xff); appendByte((value>>8)&0xff); appendByte((value>>16)&0xff); - appendByte((value>>24)&0xff); + appendByte((value>>24)); // don't need to bit-wise AND the last byte } diff --git a/firmware/src/shared/Packet.hh b/firmware/src/shared/Packet.hh index 26ab069..ebfcb55 100644 --- a/firmware/src/shared/Packet.hh +++ b/firmware/src/shared/Packet.hh @@ -19,6 +19,7 @@ #define SHARED_PACKET_HH_ #include +#include #define START_BYTE 0xD5 #define MAX_PACKET_PAYLOAD 32 @@ -66,18 +67,17 @@ protected: PS_LEN, PS_PAYLOAD, PS_CRC, + PS_COMPUTE_CRC, PS_LAST } PacketState; - volatile uint8_t length; /// The current length of the payload (data[0] if raw packets) - volatile uint8_t crc; /// The CRC of the current contents of the payload (data[-1] of raw packets) - volatile uint8_t payload[MAX_PACKET_PAYLOAD]; /// Data payload (starts at data[2] of raw packet) + volatile uint8_t length; /// The current length of the payload (data[0] if raw packets) + volatile uint8_t crc; /// The CRC of the current contents of the payload (data[-1] of raw packets) volatile uint8_t error_code; // Have any errors cropped up during processing? volatile PacketState state; + uint8_t payload[MAX_PACKET_PAYLOAD]; /// Data payload (starts at data[2] of raw packet) - /// Append a byte and update the CRC - void appendByte(uint8_t data); /// Reset this packet to an empty state void reset(); @@ -86,42 +86,49 @@ protected: error_code = error_code_in; } public: - uint8_t getLength() const { return length; } + inline uint8_t getLength() const { return length; } - bool hasError() const { + inline bool hasError() const { return error_code != PacketError::NO_ERROR; } - uint8_t getErrorCode() const { return error_code; } + inline uint8_t getErrorCode() const { return error_code; } // Reads an 8-bit byte from the specified index of the payload - uint8_t read8(uint8_t idx) const; - uint16_t read16(uint8_t idx) const; - uint32_t read32(uint8_t idx) const; + inline uint8_t read8(uint8_t idx) const { return payload[idx]; } + inline uint16_t read16(uint8_t idx) const { return *((uint16_t*)(payload+idx)); } //payload[index] | (payload[index + 1] << 8); } + inline uint32_t read32(uint8_t idx) const { return *((uint32_t*)(payload+idx)); } uint8_t debugGetState() const { return state; } - const volatile uint8_t* getData() const { return payload; } + inline const uint8_t* getData() const { return payload; } }; /// Input Packet. class InPacket: public Packet { private: volatile uint8_t expected_length; + + /// Append a byte and update the CRC in a separate step + void appendByte(uint8_t data); + void computeCRC(); + public: - InPacket(); + InPacket() { Packet::reset(); } /// Reset the entire packet reception. - void reset(); + void reset() { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { Packet::reset(); } } + //process a byte for our packet. void processByte(uint8_t b); - bool isFinished() const { + inline bool isFinished() { + if ( state == PS_COMPUTE_CRC ) {computeCRC();} return state == PS_LAST; } - bool isStarted() const { + inline bool isStarted() const { return state != PS_START; } @@ -137,17 +144,25 @@ public: class OutPacket: public Packet { private: uint8_t send_payload_index; + /// Append a byte and update the CRC + void appendByte(uint8_t data); + public: - OutPacket(); + OutPacket() { Packet::reset(); send_payload_index = 0; } /// Reset the entire packet transmission. - void reset(); - - bool isFinished() const { + void reset() { + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + Packet::reset(); + send_payload_index = 0; + } + } + + inline bool isFinished() const { return state == PS_LAST; } - bool isSending() const { + inline bool isSending() const { return state != PS_START && state != PS_LAST; } @@ -157,8 +172,8 @@ public: void prepareForResend(); // Add an 8-bit byte to the end of the payload - void append8(uint8_t value); - void append16(uint16_t value); + inline void append8(uint8_t value) { appendByte(value); } + void append16(uint16_t value); void append32(uint32_t value); }; diff --git a/firmware/src/shared/UART.cc b/firmware/src/shared/UART.cc index 204d3c6..e86a940 100644 --- a/firmware/src/shared/UART.cc +++ b/firmware/src/shared/UART.cc @@ -46,12 +46,12 @@ volatile uint8_t loopback_bytes = 0; #error UART not implemented on this processor type! #endif +// Use double-speed mode for more accurate baud rate? #define UCSRA_VALUE(uart_) _BV(U2X##uart_) // baud rate doubling #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega328__) #define UBRR_VALUE 16 - #define UCSR0A_VALUE 0 #define INIT_SERIAL(uart_) \ { \ @@ -64,30 +64,11 @@ volatile uint8_t loopback_bytes = 0; UCSR0C = _BV(UCSZ01)|_BV(UCSZ00); \ } -#elif defined (__AVR_ATmega644P__) - - #define UBRR_VALUE 16 - #define UBRRA_VALUE 0 - - // Adapted from ancient arduino/wiring rabbit hole - #define INIT_SERIAL(uart_) \ - { \ - UBRR##uart_##H = UBRR_VALUE >> 8; \ - UBRR##uart_##L = UBRR_VALUE & 0xff; \ - \ - /* set config for uart_ */ \ - UCSR##uart_##A = UCSRA_VALUE(uart_); \ - UCSR##uart_##B = _BV(RXEN##uart_) | _BV(TXEN##uart_); \ - UCSR##uart_##C = _BV(UCSZ##uart_##1)|_BV(UCSZ##uart_##0); \ - } - -#elif defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) +#elif defined (__AVR_ATmega644P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) - // Use double-speed mode for more accurate baud rate? #define UBRR0_VALUE 16 // 115200 baud #define UBRR1_VALUE 16 // 115200 baud - // Adapted from ancient arduino/wiring rabbit hole #define INIT_SERIAL(uart_) \ { \ UBRR##uart_##H = UBRR##uart_##_VALUE >> 8; \ @@ -140,17 +121,6 @@ void UART::init_serial() { #endif } -inline void UART::send_byte(char data) { - if(index_ == 0) { - UDR0 = data; - } -#if HAS_SLAVE_UART - else { - UDR1 = data; - } -#endif -} - // Transition to a non-transmitting state. This is only used for RS485 mode. inline void listen() { // TX_ENABLE_PIN::setValue(false); @@ -181,7 +151,14 @@ void UART::beginSend() { loopback_bytes = 1; } - send_byte(out.getNextByteToSend()); + if(index_ == 0) { + UDR0 = out.getNextByteToSend(); + } +#if HAS_SLAVE_UART + else { + UDR1 = out.getNextByteToSend(); + } +#endif } void UART::enable(bool enabled) { diff --git a/firmware/src/shared/UART.hh b/firmware/src/shared/UART.hh index e719b30..3865d20 100644 --- a/firmware/src/shared/UART.hh +++ b/firmware/src/shared/UART.hh @@ -71,9 +71,6 @@ private: /// Initialize the serial configuration. Must be called once at boot. void init_serial(); - /// Send a byte of data over the serial line. - /// \param[in] data Data byte to send - void send_byte(char data); const communication_mode mode_; ///< Communication mode we are speaking const uint8_t index_; ///< Hardware UART index From 7ca069ce4c573fca52046ae1f9e6bdbd67c50ae9 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 30 Nov 2011 22:40:40 -0800 Subject: [PATCH 34/39] optimized and use and int16_t for PID controller --- firmware/src/shared/CoolingFan.cc | 12 ------------ firmware/src/shared/CoolingFan.hh | 12 ++++++------ firmware/src/shared/Heater.cc | 2 +- firmware/src/shared/Heater.hh | 16 ++++++++-------- firmware/src/shared/PID.cc | 21 +++++---------------- firmware/src/shared/PID.hh | 18 +++++++++--------- 6 files changed, 29 insertions(+), 52 deletions(-) diff --git a/firmware/src/shared/CoolingFan.cc b/firmware/src/shared/CoolingFan.cc index 2ee5520..e4d6e2b 100644 --- a/firmware/src/shared/CoolingFan.cc +++ b/firmware/src/shared/CoolingFan.cc @@ -40,18 +40,6 @@ void CoolingFan::reset() { } } -void CoolingFan::setSetpoint(int temperature) { - setPoint = temperature; -} - -void CoolingFan::enable() { - enabled = true; -} - -void CoolingFan::disable() { - enabled = false; - setFanRunning(false); -} void CoolingFan::manageCoolingFan() { // TODO: only change the state if necessary diff --git a/firmware/src/shared/CoolingFan.hh b/firmware/src/shared/CoolingFan.hh index b333764..9eef87e 100644 --- a/firmware/src/shared/CoolingFan.hh +++ b/firmware/src/shared/CoolingFan.hh @@ -41,7 +41,7 @@ private: Heater& heater; ///< Heater module to read the current temperature from. bool enabled; ///< If true, the control circuit actively controls the fan. - int setPoint; ///< Setpoint temperature, in degrees Celcius. + int16_t setPoint; ///< Setpoint temperature, in degrees Celcius. uint16_t eeprom_base; ///< Base address to read EEPROM configuration from @@ -55,26 +55,26 @@ public: /// Temporarily override the setpoint temperature with a new one. /// The saved valued will be restored when the fan is reset. /// \param[in] temperature Setpoint temperature, in degrees Celcius - void setSetpoint(int temperature); + inline void setSetpoint(int16_t temperature) { setPoint = temperature; } /// Enable the cooling fan module, The fan state will not be modified /// until the next call to #manageCoolingFan(). - void enable(); + inline void enable(){ enabled = true; } /// Disable the cooling fan module. The fan will be disabled /// immediately, and further calls to #manageCoolingFan() will have no /// effect. - void disable(); + inline void disable() { enabled = false; setFanRunning(false); } /// Determine if the cooling fan module is enabled. Note that this just /// means that temperature regulation is enabled, and does not necesicarily /// mean that the fan is turned on. /// \return true if the cooling fan module is managing temperature. - bool isEnabled() { return enabled; } + inline bool isEnabled() { return enabled; } /// Get the setpoint temperature /// \return the current setpoint temperature, in degrees Celcius. - int getSetpoint() { return setPoint; } + inline int16_t getSetpoint() { return setPoint; } /// Reset the cooling fan module, reloading it's default state (tempertaure /// and enabled status) from the EEPROM. diff --git a/firmware/src/shared/Heater.cc b/firmware/src/shared/Heater.cc index 2b3c073..3b701cf 100644 --- a/firmware/src/shared/Heater.cc +++ b/firmware/src/shared/Heater.cc @@ -150,7 +150,7 @@ void Heater::manage_temperature() set_output(255); } else { - int mv = pid.calculate(current_temperature); + int16_t mv = pid.calculate(current_temperature); // offset value to compensate for heat bleed-off. // There are probably more elegant ways to do this, // but this works pretty well. diff --git a/firmware/src/shared/Heater.hh b/firmware/src/shared/Heater.hh index 491708e..7d0c11b 100644 --- a/firmware/src/shared/Heater.hh +++ b/firmware/src/shared/Heater.hh @@ -43,7 +43,7 @@ class Heater ///< be updated at. // TODO: Delete this. - int current_temperature; ///< Last known temperature reading + int16_t current_temperature; ///< Last known temperature reading uint16_t eeprom_base; ///< Base address to read EEPROM configuration from PID pid; ///< PID controller instance @@ -79,15 +79,15 @@ class Heater /// Get the current sensor temperature /// \return Current sensor temperature, in degrees Celcius - inline int get_current_temperature() { return sensor.getTemperature(); } + inline int16_t get_current_temperature() { return sensor.getTemperature(); } /// Get the setpoint temperature /// \return Setpoint temperature, in degrees Celcius - inline int get_set_temperature() { return pid.getTarget(); } + inline int16_t get_set_temperature() { return pid.getTarget(); } /// Set the target output temperature /// \param temp New target temperature, in degrees Celcius. - inline void set_target_temperature(int temp) { pid.setTarget(temp); } + inline void set_target_temperature(int16_t temp) { pid.setTarget(temp); } /// Check if the heater is within the specified band /// \return True if the heater temperature is within #TARGET_HYSTERESIS degrees @@ -104,22 +104,22 @@ class Heater /// Change the setpoint temperature /// \param value New setpoint temperature, in degrees Celcius. - void set_output(uint8_t value) { element.setHeatingElement(value); } + inline void set_output(uint8_t value) { element.setHeatingElement(value); } /// Reset the heater to a to board-on state void reset(); /// Get the current PID error term /// \return E term from the PID controller - inline int getPIDErrorTerm() { return pid.getErrorTerm(); } + inline int16_t getPIDErrorTerm() { return pid.getErrorTerm(); } /// Get the current PID delta term /// \return D term from the PID controller - inline int getPIDDeltaTerm() { return pid.getDeltaTerm(); } + inline int16_t getPIDDeltaTerm() { return pid.getDeltaTerm(); } /// Get the last PID output /// \return last output from the PID controller - inline int getPIDLastOutput() { return pid.getLastOutput(); } + inline int16_t getPIDLastOutput() { return pid.getLastOutput(); } }; #endif // HEATER_H diff --git a/firmware/src/shared/PID.cc b/firmware/src/shared/PID.cc index 1eb53db..d93a327 100644 --- a/firmware/src/shared/PID.cc +++ b/firmware/src/shared/PID.cc @@ -61,8 +61,8 @@ void PID::reset_state() { // which will give us a delta impulse for that one calculation round and then // the D term will immediately disappear. By averaging the last N deltas, we // allow changes to be registered rather than get subsumed in the sampling noise. -int PID::calculate(const int pv) { - int e = sp - pv; +int16_t PID::calculate(const int16_t pv) { + int16_t e = sp - pv; error_acc += e; // Clamp the error accumulator at accepted values. // This will help control overcorrection for accumulated error during the run-up @@ -76,7 +76,7 @@ int PID::calculate(const int pv) { } float p_term = (float)e * p_gain; float i_term = (float)error_acc * i_gain; - int delta = e - prev_error; + int16_t delta = e - prev_error; // Add to delta history delta_summation -= delta_history[delta_idx]; delta_history[delta_idx] = delta; @@ -87,26 +87,15 @@ int PID::calculate(const int pv) { prev_error = e; - last_output = ((int)(p_term + i_term + d_term))*OUTPUT_SCALE; + last_output = (int16_t)((p_term + i_term + d_term)*OUTPUT_SCALE); return last_output; } -void PID::setTarget(const int target) { +void PID::setTarget(const int16_t target) { if (sp != target) { reset_state(); sp = target; } } -int PID::getErrorTerm() { - return error_acc; -} - -int PID::getDeltaTerm() { - return (int)delta_summation; -} - -int PID::getLastOutput() { - return (int)last_output; -} diff --git a/firmware/src/shared/PID.hh b/firmware/src/shared/PID.hh index f2d4d6b..45e3a7f 100644 --- a/firmware/src/shared/PID.hh +++ b/firmware/src/shared/PID.hh @@ -42,11 +42,11 @@ private: int16_t delta_history[DELTA_SAMPLES]; float delta_summation; ///< ? uint8_t delta_idx; ///< Current index in the delta history buffer - int prev_error; ///< Previous input for calculating next delta - int error_acc; ///< Accumulated error, for calculating integral + int16_t prev_error; ///< Previous input for calculating next delta + int16_t error_acc; ///< Accumulated error, for calculating integral - int sp; ///< Process set point - int last_output; ///< Last output of the PID controller + int16_t sp; ///< Process set point + int16_t last_output; ///< Last output of the PID controller public: /// Initialize the PID module @@ -70,7 +70,7 @@ public: /// Get the current PID target /// \return Current setpoint - int getTarget() const { return sp; } + int16_t getTarget() const { return sp; } /// Reset the PID to board-on values void reset(); @@ -81,19 +81,19 @@ public: /// Calculate the next cycle of the PID loop. /// \param[in] pv Process value (measured value from the sensor) /// \return output value (used to control the output) - int calculate(int pv); + int16_t calculate(int16_t pv); /// Get the current value of the error term /// \return Error term - int getErrorTerm(); + inline int16_t getErrorTerm() { return error_acc; } /// Get the current value of the delta term /// \return Delta term - int getDeltaTerm(); + inline int16_t getDeltaTerm() { return (int16_t)delta_summation; } /// Get the last process output value /// \return Last process output value - int getLastOutput(); + inline int16_t getLastOutput() { return last_output; } }; #endif /* PID_HH_ */ From 83b925f0778819329c1e69fc019d5f047af11214 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 30 Nov 2011 22:40:52 -0800 Subject: [PATCH 35/39] remove debugging --- firmware/src/shared/Menu.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/firmware/src/shared/Menu.cc b/firmware/src/shared/Menu.cc index 54907b1..b38260a 100644 --- a/firmware/src/shared/Menu.cc +++ b/firmware/src/shared/Menu.cc @@ -46,9 +46,8 @@ bool queryExtruderParameter(uint8_t parameter, uint16_t& value ) { // do this busy work after the transaction has started InPacket& in = tool::getInPacket(); - DEBUG_QUERY_TOOL_PIN::setValue(true); tool::waitForTransaction(); - DEBUG_QUERY_TOOL_PIN::setValue(false); + if (in.getErrorCode() == PacketError::PACKET_TIMEOUT) { return false; } else { From b4bd8826387c7bf2c35078e78dbd3512b11d1fae Mon Sep 17 00:00:00 2001 From: Craig Link Date: Wed, 30 Nov 2011 22:43:10 -0800 Subject: [PATCH 36/39] inline a bunch of stuff and slice the temperature control across multiple slices --- .../Extruder/boards/ecv34/ExtruderBoard.cc | 54 +++++++------------ .../Extruder/boards/ecv34/ExtruderBoard.hh | 23 ++++---- 2 files changed, 32 insertions(+), 45 deletions(-) diff --git a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc index ed1d6ce..8945062 100644 --- a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc +++ b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.cc @@ -153,28 +153,26 @@ void ExtruderBoard::reset(uint8_t resetFlags) { } void ExtruderBoard::runExtruderSlice() { - motor_controller.update(); - - extruder_heater.manage_temperature(); - - if(isUsingPlatform()) { - platform_heater.manage_temperature(); - } - - coolingFan.manageCoolingFan(); -} - -int ExtruderBoard::get_current_temperature() -{ - return extruder_heater.get_current_temperature(); -} - -void ExtruderBoard::set_target_temperature(int temp ) -{ - return extruder_heater.set_target_temperature(temp); + motor_controller.update(); + + static uint8_t manage = 0; + manage++; + switch(manage%3) + { + case 0: + extruder_heater.manage_temperature(); + break; + case 1: + if(isUsingPlatform()) { + platform_heater.manage_temperature(); + } + break; + case 2: + coolingFan.manageCoolingFan(); + break; + } } - void ExtruderBoard::setMotorSpeed(int16_t speed) { // Since the motor and regulated cooling fan share an output, only one can be enabled at a time. // Therefore, we should override the motor speed command if the cooling fan is activated. @@ -237,17 +235,8 @@ void ExtruderBoard::doInterrupt() { } } -//runs the AutoBuildPlatform (connected to 'Extra' screw terms on ECv3.x ) -void ExtruderBoard::setAutomatedBuildPlatformRunning(bool state) -{ - CHANNEL_A::setValue(state); -} //runs the Extruder Cooling Fan (connected to 'A1/B1' screw term on ECv3.x) -void ExtruderBoard::setFanRunning(bool state) { - //CHANNEL_A.setValue(on); - MOTOR_ENABLE_PIN::setValue(state); -} void ExtruderBoard::setValve(bool on) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { @@ -262,13 +251,6 @@ void ExtruderBoard::indicateError(int errorCode) { //DEBUG_LED.setValue(errorCode != 0); } -void ExtruderBoard::lightIndicatorLED() { - MOTOR_DIR_PIN::setValue(true); -} - -void ExtruderBoard::setUsingPlatform(bool is_using) { - using_platform = is_using; -} /// Timer two comparator A match interrupt ISR(TIMER2_COMPA_vect) { diff --git a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.hh b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.hh index 08da401..3a9c038 100644 --- a/firmware/src/Extruder/boards/ecv34/ExtruderBoard.hh +++ b/firmware/src/Extruder/boards/ecv34/ExtruderBoard.hh @@ -88,11 +88,11 @@ public: // reset. uint8_t getResetFlags(); - int get_current_temperature(); - void set_target_temperature(int); + inline int get_current_temperature() { return extruder_heater.get_current_temperature(); } + inline void set_target_temperature(int temp) { return extruder_heater.set_target_temperature(temp); } - Heater& getExtruderHeater() { return extruder_heater; } - Heater& getPlatformHeater() { return platform_heater; } + inline Heater& getExtruderHeater() { return extruder_heater; } + inline Heater& getPlatformHeater() { return platform_heater; } MotorController& getMotorController() { return motor_controller; } @@ -100,14 +100,19 @@ public: void setMotorSpeedRPM(uint32_t speed, bool direction) {} // Unsupported on 3.4 /// Enable/Disable the extruder cooling fan - void setFanRunning(bool state); + //runs the Extruder Cooling Fan (connected to 'A1/B1' screw term on ECv3.x) + inline void setFanRunning(bool state) { + //CHANNEL_A.setValue(on); + MOTOR_ENABLE_PIN::setValue(state); + } /// Enable/Disable the automatic build platform motor - void setAutomatedBuildPlatformRunning(bool state); + //runs the AutoBuildPlatform (connected to 'Extra' screw terms on ECv3.x ) + inline void setAutomatedBuildPlatformRunning(bool state) { CHANNEL_A::setValue(state); } void setValve(bool on); - UART& getHostUART() { return UART::getHostUART(); } + inline UART& getHostUART() { return UART::getHostUART(); } /// Get the number of microseconds that have passed since /// the board was initialized. This value will wrap after @@ -118,10 +123,10 @@ public: /// Indicate an error by manipulating the debug LED. void indicateError(int errorCode); - void lightIndicatorLED(); + inline void lightIndicatorLED() { MOTOR_DIR_PIN::setValue(true); } bool isUsingPlatform() { return using_platform; } - void setUsingPlatform(bool is_using); + inline void setUsingPlatform(bool is_using) { using_platform = is_using; } // Index 0 = ServoA, Index 1 = ServoB. Value = -1 to turn off, 0-180 to set position. void setServo(uint8_t index, int value); From b7e6f0aa04e825b0797961052f3f6ad0d8e1ff4b Mon Sep 17 00:00:00 2001 From: Craig Link Date: Thu, 1 Dec 2011 09:14:27 -0800 Subject: [PATCH 37/39] remove debugging code --- firmware/src/Motherboard/Command.cc | 4 ---- firmware/src/Motherboard/DebugPacketProcessor.cc | 2 ++ firmware/src/Motherboard/Host.cc | 4 ---- firmware/src/Motherboard/Tool.cc | 6 +----- firmware/src/Motherboard/boards/mb24/Motherboard.cc | 5 ----- firmware/src/shared/Packet.cc | 1 - 6 files changed, 3 insertions(+), 19 deletions(-) diff --git a/firmware/src/Motherboard/Command.cc b/firmware/src/Motherboard/Command.cc index 53d082e..91b6765 100644 --- a/firmware/src/Motherboard/Command.cc +++ b/firmware/src/Motherboard/Command.cc @@ -106,15 +106,12 @@ Timeout homing_timeout; Timeout tool_wait_timeout; void reset() { - DEBUG_CMD_SLICE_PIN::setDirection(true); - DEBUG_CMD_SLICE_PIN::setValue(false); command_buffer.reset(); mode = READY; } // A fast slice for processing commands and refilling the stepper queue, etc. void runCommandSlice() { - DEBUG_CMD_SLICE_PIN::setValue(true); if (sdcard::isPlaying()) { while (command_buffer.getRemainingCapacity() > 0 && sdcard::playbackHasNext()) { command_buffer.push(sdcard::playbackNext()); @@ -418,6 +415,5 @@ void runCommandSlice() { } } } - DEBUG_CMD_SLICE_PIN::setValue(false); } } diff --git a/firmware/src/Motherboard/DebugPacketProcessor.cc b/firmware/src/Motherboard/DebugPacketProcessor.cc index c849dce..120d9ac 100644 --- a/firmware/src/Motherboard/DebugPacketProcessor.cc +++ b/firmware/src/Motherboard/DebugPacketProcessor.cc @@ -79,10 +79,12 @@ bool processDebugPacket(const InPacket& from_host, OutPacket& to_host) { to_host.append8(from_host.read8(i)); } return true; +/* } else if (command == CommandCode::DEBUG_GENERATE_BAD_PACKET) { // TODO } else if (command == CommandCode::DEBUG_SIMULATE_BAD_PACKET) { // TODO +*/ } else if (command == CommandCode::DEBUG_SLAVE_PASSTHRU) { // BLOCK: wait until sent { diff --git a/firmware/src/Motherboard/Host.cc b/firmware/src/Motherboard/Host.cc index 47283e3..4c89cef 100644 --- a/firmware/src/Motherboard/Host.cc +++ b/firmware/src/Motherboard/Host.cc @@ -60,12 +60,9 @@ HostState currentState; bool do_host_reset = true; void resetHost() { - DEBUG_HOST_SLICE_PIN::setDirection(true); - DEBUG_HOST_SLICE_PIN::setValue(false); } void runHostSlice() { - DEBUG_HOST_SLICE_PIN::setValue(true); // still sending; wait until send is complete before reading new host packets. OutPacket& out = UART::getHostUART().out; @@ -123,7 +120,6 @@ void runHostSlice() { } } } - DEBUG_HOST_SLICE_PIN::setValue(false); } /// Identify a command packet, and process it. If the packet is a command diff --git a/firmware/src/Motherboard/Tool.cc b/firmware/src/Motherboard/Tool.cc index 3451cee..e111bd6 100644 --- a/firmware/src/Motherboard/Tool.cc +++ b/firmware/src/Motherboard/Tool.cc @@ -142,9 +142,7 @@ void setToolIndicatorLED() { } bool reset() { - DEBUG_TOOL_SLICE_PIN::setDirection(true); - DEBUG_TOOL_SLICE_PIN::setValue(false); - + // This code is very lightly modified from handleToolQuery in Host.cc. // We don't give up if we fail to get a lock; we force it instead. Timeout acquire_lock_timeout; @@ -245,7 +243,6 @@ static bool retryCommunication(){ } void runToolSlice() { - DEBUG_TOOL_SLICE_PIN::setValue(true); UART& uart = UART::getSlaveUART(); if (transaction_active) { if (uart.in.isFinished()) { @@ -271,7 +268,6 @@ void runToolSlice() { { } } - DEBUG_TOOL_SLICE_PIN::setValue(false); } void setCurrentToolheadIndex(uint8_t tool_index_in) { diff --git a/firmware/src/Motherboard/boards/mb24/Motherboard.cc b/firmware/src/Motherboard/boards/mb24/Motherboard.cc index bad8b67..7c453cf 100644 --- a/firmware/src/Motherboard/boards/mb24/Motherboard.cc +++ b/firmware/src/Motherboard/boards/mb24/Motherboard.cc @@ -92,9 +92,6 @@ void Motherboard::reset() { // Configure the debug pin. DEBUG_PIN::setDirection(true); - DEBUG_MOTHERBOARD_SLICE_PIN::setDirection(true); - DEBUG_MOTHERBOARD_SLICE_PIN::setValue(false); - indicateError(0); // turn off blinker // Init steppers @@ -181,7 +178,6 @@ void Motherboard::doInterrupt() { } void Motherboard::runMotherboardSlice() { - DEBUG_MOTHERBOARD_SLICE_PIN::setValue(true); #if HAS_INTERFACE_BOARD > 0 if (hasInterfaceBoard) { @@ -192,7 +188,6 @@ void Motherboard::runMotherboardSlice() { } #endif - DEBUG_MOTHERBOARD_SLICE_PIN::setValue(false); } diff --git a/firmware/src/shared/Packet.cc b/firmware/src/shared/Packet.cc index fc081ce..ae92376 100644 --- a/firmware/src/shared/Packet.cc +++ b/firmware/src/shared/Packet.cc @@ -104,7 +104,6 @@ void InPacket::processByte(uint8_t b) { */ break; default: - //DEBUG_PACKET_PIN::setValue(true); break; } From 7c6cd5e0c44f3f15edec9441fed27ec1fe875b4c Mon Sep 17 00:00:00 2001 From: Craig Link Date: Thu, 1 Dec 2011 09:15:08 -0800 Subject: [PATCH 38/39] remove non-standard MakerBot code - ie support for Modtronix --- G3Firmware.sln | 7 - .../Motherboard/boards/mb24/Configuration.hh | 4 - firmware/src/shared/DualDisplay.cc | 52 -- firmware/src/shared/DualDisplay.hh | 31 - firmware/src/shared/ModtronixLCD2S.cc | 561 ------------------ firmware/src/shared/ModtronixLCD2S.hh | 101 ---- firmware/src/shared/twi.cc | 543 ----------------- firmware/src/shared/twi.h | 66 --- 8 files changed, 1365 deletions(-) delete mode 100644 firmware/src/shared/DualDisplay.cc delete mode 100644 firmware/src/shared/DualDisplay.hh delete mode 100644 firmware/src/shared/ModtronixLCD2S.cc delete mode 100644 firmware/src/shared/ModtronixLCD2S.hh delete mode 100644 firmware/src/shared/twi.cc delete mode 100644 firmware/src/shared/twi.h diff --git a/G3Firmware.sln b/G3Firmware.sln index 91bbc0d..125f112 100644 --- a/G3Firmware.sln +++ b/G3Firmware.sln @@ -26,8 +26,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{AE577D firmware\src\shared\CoolingFan.cc = firmware\src\shared\CoolingFan.cc firmware\src\shared\CoolingFan.hh = firmware\src\shared\CoolingFan.hh firmware\src\shared\Display.hh = firmware\src\shared\Display.hh - firmware\src\shared\DualDisplay.cc = firmware\src\shared\DualDisplay.cc - firmware\src\shared\DualDisplay.hh = firmware\src\shared\DualDisplay.hh firmware\src\shared\Eeprom.cc = firmware\src\shared\Eeprom.cc firmware\src\shared\Eeprom.hh = firmware\src\shared\Eeprom.hh firmware\src\shared\Heater.cc = firmware\src\shared\Heater.cc @@ -41,8 +39,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{AE577D firmware\src\shared\LiquidCrystal.hh = firmware\src\shared\LiquidCrystal.hh firmware\src\shared\Menu.cc = firmware\src\shared\Menu.cc firmware\src\shared\Menu.hh = firmware\src\shared\Menu.hh - firmware\src\shared\ModtronixLCD2S.cc = firmware\src\shared\ModtronixLCD2S.cc - firmware\src\shared\ModtronixLCD2S.hh = firmware\src\shared\ModtronixLCD2S.hh firmware\src\shared\Packet.cc = firmware\src\shared\Packet.cc firmware\src\shared\Packet.hh = firmware\src\shared\Packet.hh firmware\src\shared\PID.cc = firmware\src\shared\PID.cc @@ -63,8 +59,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{AE577D firmware\src\shared\Thermocouple.hh = firmware\src\shared\Thermocouple.hh firmware\src\shared\Timeout.cc = firmware\src\shared\Timeout.cc firmware\src\shared\Timeout.hh = firmware\src\shared\Timeout.hh - firmware\src\shared\twi.cc = firmware\src\shared\twi.cc - firmware\src\shared\twi.h = firmware\src\shared\twi.h firmware\src\shared\Types.hh = firmware\src\shared\Types.hh firmware\src\shared\UART.cc = firmware\src\shared\UART.cc firmware\src\shared\UART.hh = firmware\src\shared\UART.hh @@ -83,7 +77,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Motherboard", "Motherboard" firmware\src\Motherboard\Host.hh = firmware\src\Motherboard\Host.hh firmware\src\Motherboard\Main.cc = firmware\src\Motherboard\Main.cc firmware\src\Motherboard\Main.hh = firmware\src\Motherboard\Main.hh - firmware\src\Motherboard\Point.cc = firmware\src\Motherboard\Point.cc firmware\src\Motherboard\Point.hh = firmware\src\Motherboard\Point.hh firmware\src\Motherboard\SDCard.cc = firmware\src\Motherboard\SDCard.cc firmware\src\Motherboard\SDCard.hh = firmware\src\Motherboard\SDCard.hh diff --git a/firmware/src/Motherboard/boards/mb24/Configuration.hh b/firmware/src/Motherboard/boards/mb24/Configuration.hh index 338bb4e..f7bde44 100644 --- a/firmware/src/Motherboard/boards/mb24/Configuration.hh +++ b/firmware/src/Motherboard/boards/mb24/Configuration.hh @@ -152,13 +152,9 @@ #define DISPLAY_TYPE_NONE 0 #define DISPLAY_TYPE_LIQUIDCRYSTAL 1 -#define DISPLAY_TYPE_MODTRONIXLCD2S 2 -#define DISPLAY_TYPE_DUAL 3 //#define DISPLAY_TYPE DISPLAY_TYPE_NONE #define DISPLAY_TYPE DISPLAY_TYPE_LIQUIDCRYSTAL -//#define DISPLAY_TYPE DISPLAY_TYPE_MODTRONIXLCD2S -//#define DISPLAY_TYPE DISPLAY_TYPE_DUAL /// Pin mappings for the LiquidCrystal class connection. #define LCD_RS_PIN Pin(PortC,4) diff --git a/firmware/src/shared/DualDisplay.cc b/firmware/src/shared/DualDisplay.cc deleted file mode 100644 index b293697..0000000 --- a/firmware/src/shared/DualDisplay.cc +++ /dev/null @@ -1,52 +0,0 @@ -#include "InterfaceBoard.hh" - -#if HAS_INTERFACE_BOARD > 0 -#include "DualDisplay.hh" - -#include -#include -#include - -void DualDisplay::init() -{ - lcd.init(); - lcd2s.init(); - clear(); -} - -/********** high level commands, for the user! */ -void DualDisplay::clear() -{ - lcd.clear(); - lcd2s.clear(); -} - - -void DualDisplay::setCursor(uint8_t col, uint8_t row) -{ - lcd.setCursor(col,row); - lcd2s.setCursor(col,row); -} - -void DualDisplay::write(uint8_t c) { - lcd.write(c); - lcd2s.write(c); -} - - -void DualDisplay::writeInt(uint16_t value, uint8_t digits) { - lcd.writeInt(value, digits); - lcd2s.writeInt(value, digits); -} - -void DualDisplay::writeString(const char message[]) { - lcd.writeString(message); - lcd2s.writeString(message); -} - -void DualDisplay::writeFromPgmspace(const prog_char message[]) { - lcd.writeFromPgmspace(message); - lcd2s.writeFromPgmspace(message); -} - -#endif // HAS_INTERFACE_BOARD > 0 diff --git a/firmware/src/shared/DualDisplay.hh b/firmware/src/shared/DualDisplay.hh deleted file mode 100644 index fe50ea7..0000000 --- a/firmware/src/shared/DualDisplay.hh +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef DUALDISPLAY_HH -#define DUALDISPLAY_HH - -// TODO: Proper attribution - -#include -#include "Display.hh" -#include "LiquidCrystal.hh" -#include "ModtronixLCD2S.hh" - -class DualDisplay : public Display { -public: - DualDisplay() {} - virtual void init(); - virtual void clear(); - virtual size_t width() const { return 16; } - virtual size_t height() const { return 4; } - virtual void setCursor(uint8_t col, uint8_t row); - virtual void write(uint8_t); - - virtual void writeInt(uint16_t value, uint8_t digits); - virtual void writeString(const char message[]); - virtual void writeFromPgmspace(const prog_char message[]); - -private: -// Display lcd; // provide a NULL display - LiquidCrystal lcd; - ModtronixLCD2S lcd2s; -}; - -#endif // DUALDISPLAY_HH diff --git a/firmware/src/shared/ModtronixLCD2S.cc b/firmware/src/shared/ModtronixLCD2S.cc deleted file mode 100644 index 65bb671..0000000 --- a/firmware/src/shared/ModtronixLCD2S.cc +++ /dev/null @@ -1,561 +0,0 @@ -#include -#include "ModtronixLCD2S.hh" -#include "twi.h" - - -static int i2c_write(uint8_t address, uint8_t cmd, uint8_t* data, uint8_t len) -{ - twi_data bufs[] = { {0, 1, &cmd}, {0, len, data} }; - return twi_writeTo_buffers(address, bufs, 2, 0 ); -} - - - -static int i2c_write_P(uint8_t address, uint8_t cmd, PGM_P data, uint8_t len) -{ - twi_data bufs[] = { {0, 1, &cmd}, {1, len, (const uint8_t*) data} }; - return twi_writeTo_buffers(address, bufs, 2, 0 ); -} - - - -static int i2c_cmd_read(uint8_t address, uint8_t cmd, uint8_t* data, uint8_t expectedlen) -{ -// return asynctwi::write_and_read_async(address, &cmd, 1, data, expectedlen, NULL); - return 0; -} - - -/* -static int i2c_cmd_read_async(uint8_t address, uint8_t cmd, uint8_t expectedlen, asynctwi::callback_t cb) -{ - return asynctwi::write_and_read_async(address, &cmd, 1, NULL, expectedlen, cb); -} - -*/ - - -ModtronixLCD2S::ModtronixLCD2S(uint8_t addr) -{ - address = addr; - charset = 255; -} - -void ModtronixLCD2S::init() -{ - twi_init(); -// clear(); -// home(); -} - -void ModtronixLCD2S::remember() -{ - i2c_write(address, 0x8D, NULL, 0); -} - - - -int8_t ModtronixLCD2S::read_status() -{ - uint8_t val = 0; - int8_t len = i2c_cmd_read(address, 0xD0, &val, 1); - if (len == -1) { - return -1; - } - return val; -} - - -/* -void ModtronixLCD2S::read_status_async(asynctwi::callback_t cb) -{ - i2c_cmd_read_async(address, 0xD0, 1, cb); -} -*/ - - - -char ModtronixLCD2S::read_keypad_data() -{ - uint8_t data[2]; - i2c_cmd_read(address, 0xD1, data, 1); - return (char)(data[0]); -} - - -/* -void ModtronixLCD2S::read_keypad_data_async(asynctwi::callback_t cb) -{ - i2c_cmd_read_async(address, 0xD1, 1, cb); -} -*/ - - - -uint8_t ModtronixLCD2S::read_gpio123() -{ - uint8_t val = 0; - i2c_cmd_read(address, 0xD3, &val, 1); - return val; -} - - -/* -void ModtronixLCD2S::read_gpio123_async(asynctwi::callback_t cb) -{ - i2c_cmd_read_async(address, 0xD3, 1, cb); -} -*/ - - - - - -void ModtronixLCD2S::config(uint8_t display, uint8_t contrast, uint8_t brightness, uint8_t keypadio, uint8_t keypadbuzz) -{ - uint8_t data[4]; - data[0] = display; - data[1] = ((brightness & 0x3) << 6) | (contrast & 0x3f); - data[2] = keypadio; - data[3] = keypadbuzz; - i2c_write(address, 0xD0, data, 4); -} - - - -void ModtronixLCD2S::set_base_address(uint8_t addr) { - remember(); - i2c_write(address, 0x91, &addr, 1); -} - - - -void ModtronixLCD2S::write_decimal(int16_t val, int8_t wid, uint8_t decdigits) { - char buf[10]; - char* ptr = buf; - char* ptr2; - bool force = false; - if (val < 0) { - val = -val; - *ptr++ = '-'; - } - if (decdigits == 5) { - *ptr++ = '0'; - *ptr++ = '.'; - force = true; - } - if (force || val >= 10000) { - *ptr++ = '0'+(val/10000); - val = val % 10000; - force = true; - } - if (decdigits == 4) { - if (ptr == buf) { - *ptr++ = '0'; - } - *ptr++ = '.'; - force = true; - } - if (force || val >= 1000) { - *ptr++ = '0'+(val/1000); - val = val % 1000; - force = true; - } - if (decdigits == 3) { - if (ptr == buf) { - *ptr++ = '0'; - } - *ptr++ = '.'; - force = true; - } - if (force || val >= 100) { - *ptr++ = '0'+(val/100); - val = val % 100; - force = true; - } - if (decdigits == 2) { - if (ptr == buf) { - *ptr++ = '0'; - } - *ptr++ = '.'; - force = true; - } - if (force || val >= 10) { - *ptr++ = '0'+(val/10); - val = val % 10; - } - if (decdigits == 1) { - if (ptr == buf) { - *ptr++ = '0'; - } - *ptr++ = '.'; - } - *ptr++ = '0'+val; - *ptr = '\0'; - if (ptr-buf < wid) { - ptr2 = buf+wid; - while (ptr >= buf) { - *ptr2-- = *ptr--; - } - while (ptr2 >= buf) { - *ptr2-- = ' '; - } - } - i2c_write(address, 0x80, (uint8_t*)buf, strlen(buf)); -} - -void ModtronixLCD2S::writeInt(uint16_t value, uint8_t digits) { - char buf[digits]; - - uint16_t currentDigit; - uint16_t nextDigit; - - switch (digits) { - case 1: currentDigit = 10; break; - case 2: currentDigit = 100; break; - case 3: currentDigit = 1000; break; - case 4: currentDigit = 10000; break; - default: return; - } - - uint8_t i; - for (i = 0; i < digits; i++) { - nextDigit = currentDigit/10; - buf[i] = (value%currentDigit)/nextDigit+'0'; - currentDigit = nextDigit; - } - - i2c_write(address, 0x80, (uint8_t*)buf, i); -} - - -void ModtronixLCD2S::write_string(const char* str) { - i2c_write(address, 0x80, (uint8_t*)str, strlen(str)); -} - - - -void ModtronixLCD2S::write_string_P(PGM_P pstr) { - i2c_write_P(address, 0x80, pstr, strlen_P(pstr)); -} - - - -void ModtronixLCD2S::set_startup_line(uint8_t row, const char* str) { - uint8_t buf[22]; - buf[0] = row; - strcpy((char*)buf+1,str); - i2c_write(address, 0x90, buf, strlen(str)+1); -} - - - -void ModtronixLCD2S::write_char(char ch) { - uint8_t buf[2]; - buf[0] = ch; - buf[1] = '\0'; - i2c_write(address, 0x80, buf, 1); -} - - - -void ModtronixLCD2S::backlight_on() { - i2c_write(address, 0x28, NULL, 0); -} - - - -void ModtronixLCD2S::backlight_off() { - i2c_write(address, 0x20, NULL, 0); -} - - - -void ModtronixLCD2S::backlight_brightness(uint8_t val) { - i2c_write(address, 0x81, &val, 1); -} - - - -void ModtronixLCD2S::set_contrast(uint8_t val) { - i2c_write(address, 0x82, &val, 1); -} - - - -void ModtronixLCD2S::dir_forward() { - i2c_write(address, 0x09, NULL, 0); -} - - - -void ModtronixLCD2S::dir_backwards() { - i2c_write(address, 0x01, NULL, 0); -} - - - -void ModtronixLCD2S::display_on() { - i2c_write(address, 0x1A, NULL, 0); -} - - - -void ModtronixLCD2S::display_off() { - i2c_write(address, 0x12, NULL, 0); -} - - - -void ModtronixLCD2S::cursor_underline_on() { - i2c_write(address, 0x19, NULL, 0); -} - - - -void ModtronixLCD2S::cursor_underline_off() { - i2c_write(address, 0x11, NULL, 0); -} - - - -void ModtronixLCD2S::cursor_block_on() { - i2c_write(address, 0x18, NULL, 0); -} - - - -void ModtronixLCD2S::cursor_block_off() { - i2c_write(address, 0x10, NULL, 0); -} - - - -void ModtronixLCD2S::shift_right() { - i2c_write(address, 0x85, NULL, 0); -} - - - -void ModtronixLCD2S::shift_left() { - i2c_write(address, 0x86, NULL, 0); -} - - - -void ModtronixLCD2S::shift_up() { - i2c_write(address, 0x87, NULL, 0); -} - - - -void ModtronixLCD2S::shift_down() { - i2c_write(address, 0x88, NULL, 0); -} - - - -void ModtronixLCD2S::home() { - i2c_write(address, 0x8B, NULL, 0); -} - - - -void ModtronixLCD2S::clear() { - i2c_write(address, 0x8C, NULL, 0); -} - - - -void ModtronixLCD2S::load_charset(uint8_t val) { - if (val != charset) { - i2c_write(address, 0x8E, &val, 1); - charset = val; - } -} - - - -void ModtronixLCD2S::set_position(uint8_t row, uint8_t col) { - uint8_t data[2]; - data[0] = row; - data[1] = col; - i2c_write(address, 0x8A, data, 2); -} - - -void ModtronixLCD2S::interrupt_open_collection() { - i2c_write(address, 0x2A, NULL, 0); -} - - -void ModtronixLCD2S::interrupt_push_pull() { - i2c_write(address, 0x22, NULL, 0); -} - - -void ModtronixLCD2S::out1_on() { - i2c_write(address, 0x38, NULL, 0); -} - - - -void ModtronixLCD2S::out1_off() { - i2c_write(address, 0x30, NULL, 0); -} - - - -void ModtronixLCD2S::out2_on() { - i2c_write(address, 0x39, NULL, 0); -} - - - -void ModtronixLCD2S::out2_off() { - i2c_write(address, 0x31, NULL, 0); -} - - - -void ModtronixLCD2S::gpio1_on() { - i2c_write(address, 0x48, NULL, 0); -} - - - -void ModtronixLCD2S::gpio1_off() { - i2c_write(address, 0x40, NULL, 0); -} - - - -void ModtronixLCD2S::gpio2_on() { - i2c_write(address, 0x49, NULL, 0); -} - - - -void ModtronixLCD2S::gpio2_off() { - i2c_write(address, 0x41, NULL, 0); -} - - - -void ModtronixLCD2S::config_keypad_and_io(uint8_t val) { - remember(); - i2c_write(address, 0xE0, &val, 1); -} - - - -void ModtronixLCD2S::config_gpio1(uint8_t val) { - remember(); - i2c_write(address, 0xE3, &val, 1); -} - - - -void ModtronixLCD2S::config_gpio2(uint8_t val) { - remember(); - i2c_write(address, 0xE4, &val, 1); -} - - - -void ModtronixLCD2S::config_gpio3(uint8_t val) { - remember(); - i2c_write(address, 0xE5, &val, 1); -} - - - -void ModtronixLCD2S::set_max_backlight_brightness(uint8_t val) { - remember(); - i2c_write(address, 0xA3, &val, 1); -} - - - -void ModtronixLCD2S::set_keypad_debounce_time(uint8_t val) { - remember(); - i2c_write(address, 0xE1, &val, 1); -} - - - -void ModtronixLCD2S::set_keypad_repeat_delay(uint8_t val) { - remember(); - i2c_write(address, 0xA0, &val, 1); -} - - - -void ModtronixLCD2S::set_keypad_repeat_rate(uint8_t val) { - remember(); - i2c_write(address, 0xA1, &val, 1); -} - - - -void ModtronixLCD2S::set_keypad_buzzer_period(uint8_t val) { - remember(); - i2c_write(address, 0xA2, &val, 1); -} - - - -void ModtronixLCD2S::write_large_number_string(const char* str) { - load_charset(2); - i2c_write(address, 0x8F, (uint8_t*)str, strlen(str)); -} - - - -void ModtronixLCD2S::set_cursor_addr(uint8_t val) { - i2c_write(address, 0x89, &val, 1); -} - - - -void ModtronixLCD2S::set_out12(uint8_t val1, uint8_t val2) { - uint8_t val = (val1? 0x1 : 0) | (val2? 0x2 : 0); - i2c_write(address, 0xE2, &val, 1); -} - - - -void ModtronixLCD2S::draw_vertical_bar_graph(uint8_t row, uint8_t col, uint8_t val) { - uint8_t buf[3]; - buf[0] = row; - buf[1] = col; - buf[2] = val; - load_charset(0); - i2c_write(address, 0x93, buf, 3); -} - - - -void ModtronixLCD2S::draw_tall_bar_graph(uint8_t row, uint8_t col, uint8_t val) { - uint8_t buf[3]; - buf[0] = row; - buf[1] = col; - buf[2] = val; - load_charset(1); - i2c_write(address, 0x94, buf, 3); -} - - - -void ModtronixLCD2S::define_custom_char(uint8_t adr, const uint8_t *data) { - uint8_t buf[9]; - buf[0] = adr; - memcpy(buf+1, data, 8); - i2c_write(address, 0x92, buf, 9); -} - - - -// vim: set sw=2 autoindent nowrap expandtab: settings - - diff --git a/firmware/src/shared/ModtronixLCD2S.hh b/firmware/src/shared/ModtronixLCD2S.hh deleted file mode 100644 index f93f5df..0000000 --- a/firmware/src/shared/ModtronixLCD2S.hh +++ /dev/null @@ -1,101 +0,0 @@ -// LCD Controls for a Modtronix LCD2S 4x20 LCD with I2C serial controller. -// More details at http://www.modtronix.com/products/lcd2s - -#ifndef _MODTRONIXLCD2S_H -#define _MODTRONIXLCD2S_H -#include "display.hh" - -class ModtronixLCD2S : public Display { - uint8_t address; - uint8_t charset; - -public: - ModtronixLCD2S(uint8_t addr = 0x50>>1); - - virtual void init(); - virtual void clear(); - virtual size_t width() const { return 20; } - virtual size_t height() const { return 4; } - - virtual void setCursor(uint8_t col, uint8_t row) { return set_position(row+1,col+1); } - virtual void write(uint8_t value) { return write_char(value); } - - virtual void writeInt(uint16_t value, uint8_t digits); - virtual void writeString(const char message[]) { return write_string(message); } - virtual void writeFromPgmspace(const prog_char message[]) { return write_string_P(message ); } - - void remember(); - void config(uint8_t display, uint8_t contrast, uint8_t brightness, uint8_t keypadio, uint8_t keypadbuzz); - void set_base_address(uint8_t addr); - - int8_t read_status(); -// void read_status_async(asynctwi::callback_t cb); - char read_keypad_data(); -// void read_keypad_data_async(asynctwi::callback_t cb); - uint8_t read_gpio123(); -// void read_gpio123_async(asynctwi::callback_t cb); - - void backlight_on(); - void backlight_off(); - void backlight_brightness(uint8_t val); - void set_contrast(uint8_t val); - - void display_on(); - void display_off(); - void cursor_underline_on(); - void cursor_underline_off(); - void cursor_block_on(); - void cursor_block_off(); - void dir_forward(); - void dir_backwards(); - void load_charset(uint8_t val); - void define_custom_char(uint8_t adr, const uint8_t *data); - - void home(); -// void clear(); - void set_position(uint8_t row, uint8_t col); - void set_cursor_addr(uint8_t val); - - void write_string(const char* str); - void write_string_P(PGM_P str); - void write_char(char ch); - void write_decimal(int16_t val, int8_t wid = 0, uint8_t decdigits = 0); - void set_startup_line(uint8_t row, const char* str); - void write_large_number_string(const char* str); - void draw_vertical_bar_graph(uint8_t row, uint8_t col, uint8_t val); - void draw_tall_bar_graph(uint8_t row, uint8_t col, uint8_t val); - - void shift_right(); - void shift_left(); - void shift_up(); - void shift_down(); - - void interrupt_open_collection(); - void interrupt_push_pull(); - void config_keypad_and_io(uint8_t val); - void config_gpio1(uint8_t val); - void config_gpio2(uint8_t val); - void config_gpio3(uint8_t val); - - void set_out12(uint8_t val1, uint8_t val2); // 0xE2 VAL - void out1_on(); - void out1_off(); - void out2_on(); - void out2_off(); - - void gpio1_on(); - void gpio1_off(); - void gpio2_on(); - void gpio2_off(); - - void set_max_backlight_brightness(uint8_t val); - void set_keypad_debounce_time(uint8_t val); - void set_keypad_repeat_delay(uint8_t val); - void set_keypad_repeat_rate(uint8_t val); - void set_keypad_buzzer_period(uint8_t val); -}; - -#endif // _MODTRONIXLCD2S_H - -// vim: set sw=2 autoindent nowrap expandtab: settings - diff --git a/firmware/src/shared/twi.cc b/firmware/src/shared/twi.cc deleted file mode 100644 index 0beeb19..0000000 --- a/firmware/src/shared/twi.cc +++ /dev/null @@ -1,543 +0,0 @@ -/* - twi.c - TWI/I2C library for Wiring & Arduino - Copyright (c) 2006 Nicholas Zambetti. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef cbi -#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) -#endif - -#ifndef sbi -#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) -#endif - -#include "twi.h" - -static volatile uint8_t twi_state; -static uint8_t twi_slarw; - -static void (*twi_onSlaveTransmit)(void); -static void (*twi_onSlaveReceive)(uint8_t*, int); - -static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_masterBufferIndex; -static uint8_t twi_masterBufferLength; - -static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_txBufferIndex; -static volatile uint8_t twi_txBufferLength; - -static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; -static volatile uint8_t twi_rxBufferIndex; - -static volatile uint8_t twi_error; - -/* - * Function twi_init - * Desc readys twi pins and sets twi bitrate - * Input none - * Output none - */ -void twi_init(void) -{ - // initialize state - twi_state = TWI_READY; - - #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__) - // activate internal pull-ups for twi - // as per note from atmega8 manual pg167 - sbi(PORTC, 4); - sbi(PORTC, 5); - #else - // activate internal pull-ups for twi - // as per note from atmega128 manual pg204 - sbi(PORTD, 0); - sbi(PORTD, 1); - #endif - - // initialize twi prescaler and bit rate - cbi(TWSR, TWPS0); - cbi(TWSR, TWPS1); - TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2; - - /* twi bit rate formula from atmega128 manual pg 204 - SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) - note: TWBR should be 10 or higher for master mode - It is 72 for a 16mhz Wiring board with 100kHz TWI */ - - // enable twi module, acks, and twi interrupt - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); -} - -/* - * Function twi_slaveInit - * Desc sets slave address and enables interrupt - * Input none - * Output none - */ -void twi_setAddress(uint8_t address) -{ - // set twi slave address (skip over TWGCE bit) - TWAR = address << 1; -} - -/* - * Function twi_readFrom - * Desc attempts to become twi bus master and read a - * series of bytes from a device on the bus - * Input address: 7bit i2c device address - * data: pointer to byte array - * length: number of bytes to read into array - * Output number of bytes read - */ -uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) -{ - uint8_t i; - - // ensure data will fit into buffer - if(TWI_BUFFER_LENGTH < length){ - return 0; - } - - // wait until twi is ready, become master receiver - while(TWI_READY != twi_state){ - continue; - } - twi_state = TWI_MRX; - // reset error state (0xFF.. no error occured) - twi_error = 0xFF; - - // initialize buffer iteration vars - twi_masterBufferIndex = 0; - twi_masterBufferLength = length-1; // This is not intuitive, read on... - // On receive, the previously configured ACK/NACK setting is transmitted in - // response to the received byte before the interrupt is signalled. - // Therefor we must actually set NACK when the _next_ to last byte is - // received, causing that NACK to be sent in response to receiving the last - // expected byte of data. - - // build sla+w, slave device address + w bit - twi_slarw = TW_READ; - twi_slarw |= address << 1; - - // send start condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); - - // wait for read operation to complete - while(TWI_MRX == twi_state){ - continue; - } - - if (twi_masterBufferIndex < length) - length = twi_masterBufferIndex; - - // copy twi buffer to data - for(i = 0; i < length; ++i){ - data[i] = twi_masterBuffer[i]; - } - - return length; -} - -/* - * Function twi_writeTo - * Desc attempts to become twi bus master and write a - * series of bytes to a device on the bus - * Input address: 7bit i2c device address - * data: pointer to byte array - * length: number of bytes in array - * wait: boolean indicating to wait for write or not - * Output 0 .. success - * 1 .. length to long for buffer - * 2 .. address send, NACK received - * 3 .. data send, NACK received - * 4 .. other twi error (lost bus arbitration, bus error, ..) - */ -uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait) -{ - uint8_t i; - - // ensure data will fit into buffer - if(TWI_BUFFER_LENGTH < length){ - return 1; - } - - // wait until twi is ready, become master transmitter - while(TWI_READY != twi_state){ - continue; - } - twi_state = TWI_MTX; - // reset error state (0xFF.. no error occured) - twi_error = 0xFF; - - // initialize buffer iteration vars - twi_masterBufferIndex = 0; - twi_masterBufferLength = length; - - // copy data to twi buffer - for(i = 0; i < length; ++i){ - twi_masterBuffer[i] = data[i]; - } - - // build sla+w, slave device address + w bit - twi_slarw = TW_WRITE; - twi_slarw |= address << 1; - - // send start condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); - - // wait for write operation to complete - while(wait && (TWI_MTX == twi_state)){ - continue; - } - - if (twi_error == 0xFF) - return 0; // success - else if (twi_error == TW_MT_SLA_NACK) - return 2; // error: address send, nack received - else if (twi_error == TW_MT_DATA_NACK) - return 3; // error: data send, nack received - else - return 4; // other twi error -} - - -uint8_t twi_writeTo_buffers(uint8_t address, const twi_data data[], uint8_t data_len, uint8_t wait) -{ - uint8_t i; - uint8_t total_length = 0; - for ( i = 0; i < data_len; i++ ) - { - total_length += data[i].length; - } - - // ensure data will fit into buffer - if(TWI_BUFFER_LENGTH < total_length){ - return 1; - } - - // wait until twi is ready, become master transmitter - while(TWI_READY != twi_state){ - continue; - } - twi_state = TWI_MTX; - // reset error state (0xFF.. no error occured) - twi_error = 0xFF; - - // initialize buffer iteration vars - twi_masterBufferIndex = 0; - twi_masterBufferLength = total_length; - - // copy data to twi buffer - uint8_t* ptr = twi_masterBuffer; - for ( i = 0; i < data_len; i++ ) - { - if ( data[i].progmem ) - { - memcpy_P(ptr, data[i].data, data[i].length); - ptr += data[i].length; - } - else - { - memcpy(ptr, data[i].data, data[i].length); - ptr += data[i].length; - } - } - // build sla+w, slave device address + w bit - twi_slarw = TW_WRITE; - twi_slarw |= address << 1; - - // send start condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); - - // wait for write operation to complete - while(wait && (TWI_MTX == twi_state)){ - continue; - } - - if (twi_error == 0xFF) - return 0; // success - else if (twi_error == TW_MT_SLA_NACK) - return 2; // error: address send, nack received - else if (twi_error == TW_MT_DATA_NACK) - return 3; // error: data send, nack received - else - return 4; // other twi error -} - - -/* - * Function twi_transmit - * Desc fills slave tx buffer with data - * must be called in slave tx event callback - * Input data: pointer to byte array - * length: number of bytes in array - * Output 1 length too long for buffer - * 2 not slave transmitter - * 0 ok - */ -uint8_t twi_transmit(uint8_t* data, uint8_t length) -{ - uint8_t i; - - // ensure data will fit into buffer - if(TWI_BUFFER_LENGTH < length){ - return 1; - } - - // ensure we are currently a slave transmitter - if(TWI_STX != twi_state){ - return 2; - } - - // set length and copy data into tx buffer - twi_txBufferLength = length; - for(i = 0; i < length; ++i){ - twi_txBuffer[i] = data[i]; - } - - return 0; -} - -/* - * Function twi_attachSlaveRxEvent - * Desc sets function called before a slave read operation - * Input function: callback function to use - * Output none - */ -void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) -{ - twi_onSlaveReceive = function; -} - -/* - * Function twi_attachSlaveTxEvent - * Desc sets function called before a slave write operation - * Input function: callback function to use - * Output none - */ -void twi_attachSlaveTxEvent( void (*function)(void) ) -{ - twi_onSlaveTransmit = function; -} - -/* - * Function twi_reply - * Desc sends byte or readys receive line - * Input ack: byte indicating to ack or to nack - * Output none - */ -void twi_reply(uint8_t ack) -{ - // transmit master read ready signal, with or without ack - if(ack){ - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); - }else{ - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); - } -} - -/* - * Function twi_stop - * Desc relinquishes bus master status - * Input none - * Output none - */ -void twi_stop(void) -{ - // send stop condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); - - // wait for stop condition to be exectued on bus - // TWINT is not set after a stop condition! - while(TWCR & _BV(TWSTO)){ - continue; - } - - // update twi state - twi_state = TWI_READY; -} - -/* - * Function twi_releaseBus - * Desc releases bus control - * Input none - * Output none - */ -void twi_releaseBus(void) -{ - // release bus - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); - - // update twi state - twi_state = TWI_READY; -} - -SIGNAL(TWI_vect) -{ - switch(TW_STATUS){ - // All Master - case TW_START: // sent start condition - case TW_REP_START: // sent repeated start condition - // copy device address and r/w bit to output register and ack - TWDR = twi_slarw; - twi_reply(1); - break; - - // Master Transmitter - case TW_MT_SLA_ACK: // slave receiver acked address - case TW_MT_DATA_ACK: // slave receiver acked data - // if there is data to send, send it, otherwise stop - if(twi_masterBufferIndex < twi_masterBufferLength){ - // copy data to output register and ack - TWDR = twi_masterBuffer[twi_masterBufferIndex++]; - twi_reply(1); - }else{ - twi_stop(); - } - break; - case TW_MT_SLA_NACK: // address sent, nack received - twi_error = TW_MT_SLA_NACK; - twi_stop(); - break; - case TW_MT_DATA_NACK: // data sent, nack received - twi_error = TW_MT_DATA_NACK; - twi_stop(); - break; - case TW_MT_ARB_LOST: // lost bus arbitration - twi_error = TW_MT_ARB_LOST; - twi_releaseBus(); - break; - - // Master Receiver - case TW_MR_DATA_ACK: // data received, ack sent - // put byte into buffer - twi_masterBuffer[twi_masterBufferIndex++] = TWDR; - case TW_MR_SLA_ACK: // address sent, ack received - // ack if more bytes are expected, otherwise nack - if(twi_masterBufferIndex < twi_masterBufferLength){ - twi_reply(1); - }else{ - twi_reply(0); - } - break; - case TW_MR_DATA_NACK: // data received, nack sent - // put final byte into buffer - twi_masterBuffer[twi_masterBufferIndex++] = TWDR; - case TW_MR_SLA_NACK: // address sent, nack received - twi_stop(); - break; - // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case - - // Slave Receiver - case TW_SR_SLA_ACK: // addressed, returned ack - case TW_SR_GCALL_ACK: // addressed generally, returned ack - case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack - case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack - // enter slave receiver mode - twi_state = TWI_SRX; - // indicate that rx buffer can be overwritten and ack - twi_rxBufferIndex = 0; - twi_reply(1); - break; - case TW_SR_DATA_ACK: // data received, returned ack - case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack - // if there is still room in the rx buffer - if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ - // put byte in buffer and ack - twi_rxBuffer[twi_rxBufferIndex++] = TWDR; - twi_reply(1); - }else{ - // otherwise nack - twi_reply(0); - } - break; - case TW_SR_STOP: // stop or repeated start condition received - // put a null char after data if there's room - if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ - twi_rxBuffer[twi_rxBufferIndex] = '\0'; - } - // sends ack and stops interface for clock stretching - twi_stop(); - // callback to user defined callback - twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); - // since we submit rx buffer to "wire" library, we can reset it - twi_rxBufferIndex = 0; - // ack future responses and leave slave receiver state - twi_releaseBus(); - break; - case TW_SR_DATA_NACK: // data received, returned nack - case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack - // nack back at master - twi_reply(0); - break; - - // Slave Transmitter - case TW_ST_SLA_ACK: // addressed, returned ack - case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack - // enter slave transmitter mode - twi_state = TWI_STX; - // ready the tx buffer index for iteration - twi_txBufferIndex = 0; - // set tx buffer length to be zero, to verify if user changes it - twi_txBufferLength = 0; - // request for txBuffer to be filled and length to be set - // note: user must call twi_transmit(bytes, length) to do this - twi_onSlaveTransmit(); - // if they didn't change buffer & length, initialize it - if(0 == twi_txBufferLength){ - twi_txBufferLength = 1; - twi_txBuffer[0] = 0x00; - } - // transmit first byte from buffer, fall - case TW_ST_DATA_ACK: // byte sent, ack returned - // copy data to output register - TWDR = twi_txBuffer[twi_txBufferIndex++]; - // if there is more to send, ack, otherwise nack - if(twi_txBufferIndex < twi_txBufferLength){ - twi_reply(1); - }else{ - twi_reply(0); - } - break; - case TW_ST_DATA_NACK: // received nack, we are done - case TW_ST_LAST_DATA: // received ack, but we are done already! - // ack future responses - twi_reply(1); - // leave slave receiver state - twi_state = TWI_READY; - break; - - // All - case TW_NO_INFO: // no state information - break; - case TW_BUS_ERROR: // bus error, illegal stop/start - twi_error = TW_BUS_ERROR; - twi_stop(); - break; - } -} - diff --git a/firmware/src/shared/twi.h b/firmware/src/shared/twi.h deleted file mode 100644 index fbbb15b..0000000 --- a/firmware/src/shared/twi.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - twi.h - TWI/I2C library for Wiring & Arduino - Copyright (c) 2006 Nicholas Zambetti. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef twi_h -#define twi_h - - #include - - //#define ATMEGA8 - - #ifndef CPU_FREQ - #define CPU_FREQ 16000000L - #endif - - #ifndef TWI_FREQ - #define TWI_FREQ 100000L - #endif - - #ifndef TWI_BUFFER_LENGTH - #define TWI_BUFFER_LENGTH 32 - #endif - - #define TWI_READY 0 - #define TWI_MRX 1 - #define TWI_MTX 2 - #define TWI_SRX 3 - #define TWI_STX 4 - - void twi_init(void); - void twi_setAddress(uint8_t); - uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t); - uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t); - uint8_t twi_transmit(uint8_t*, uint8_t); - void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); - void twi_attachSlaveTxEvent( void (*)(void) ); - void twi_reply(uint8_t); - void twi_stop(void); - void twi_releaseBus(void); - -struct twi_data -{ - uint8_t progmem; // bit indicating if data is in PROGMEM - uint8_t length; - const uint8_t* data; -}; - -uint8_t twi_writeTo_buffers(uint8_t address, const twi_data data[], uint8_t data_len, uint8_t wait); - -#endif - From ad38c1230661a546dcc67f8a55819da116ebb691 Mon Sep 17 00:00:00 2001 From: Craig Link Date: Thu, 1 Dec 2011 09:15:27 -0800 Subject: [PATCH 39/39] fix compilation of ecv22 --- .../Extruder/boards/ecv22/Configuration.hh | 2 + .../Extruder/boards/ecv22/ExtruderBoard.cc | 30 +++---- .../Extruder/boards/ecv22/ExtruderMotor.cc | 78 ++++++++++--------- .../Extruder/boards/ecv34/Configuration.hh | 2 + 4 files changed, 62 insertions(+), 50 deletions(-) diff --git a/firmware/src/Extruder/boards/ecv22/Configuration.hh b/firmware/src/Extruder/boards/ecv22/Configuration.hh index 89a500e..ae56a9b 100644 --- a/firmware/src/Extruder/boards/ecv22/Configuration.hh +++ b/firmware/src/Extruder/boards/ecv22/Configuration.hh @@ -18,6 +18,8 @@ #ifndef BOARDS_ECV22_CONFIGURATION_HH_ #define BOARDS_ECV22_CONFIGURATION_HH_ +#include "PinTmplt.hh" + // Board configuration files define pin configurations // for different motherboards, as well as available // features. diff --git a/firmware/src/Extruder/boards/ecv22/ExtruderBoard.cc b/firmware/src/Extruder/boards/ecv22/ExtruderBoard.cc index 1391799..71a8e4c 100644 --- a/firmware/src/Extruder/boards/ecv22/ExtruderBoard.cc +++ b/firmware/src/Extruder/boards/ecv22/ExtruderBoard.cc @@ -107,13 +107,13 @@ void ExtruderBoard::reset(uint8_t resetFlags) { TIMSK2 = 0x00; // turn off channel A PWM by default // TIMER2 is used to PWM mosfet channel B on OC2A, and channel A on // PC1 (using the OC2B register). - DEBUG_LED.setDirection(true); - CHANNEL_A.setValue(false); - CHANNEL_A.setDirection(true); // set channel A as output - CHANNEL_B.setValue(false); - CHANNEL_B.setDirection(true); // set channel B as output - CHANNEL_C.setValue(false); - CHANNEL_C.setDirection(true); // set channel C as output + DEBUG_LED::setDirection(true); + CHANNEL_A::setValue(false); + CHANNEL_A::setDirection(true); // set channel A as output + CHANNEL_B::setValue(false); + CHANNEL_B::setDirection(true); // set channel B as output + CHANNEL_C::setValue(false); + CHANNEL_C::setDirection(true); // set channel C as output TCCR2A = 0b10000011; TCCR2B = 0b00000110; // prescaler 1/256 OCR2A = 0; @@ -235,10 +235,10 @@ void setChannel(ChannelChoice c, uint8_t value, bool binary) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { if (binary) { pwmAOn(false); - CHANNEL_A.setValue(value != 0); + CHANNEL_A::setValue(value != 0); } else if (value == 0 || value == 255) { pwmAOn(false); - CHANNEL_A.setValue(value == 255); + CHANNEL_A::setValue(value == 255); } else { OCR2B = value; pwmAOn(true); @@ -248,10 +248,10 @@ void setChannel(ChannelChoice c, uint8_t value, bool binary) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { if (binary) { pwmBOn(false); - CHANNEL_B.setValue(value != 0); + CHANNEL_B::setValue(value != 0); } else if (value == 0 || value == 255) { pwmBOn(false); - CHANNEL_B.setValue(value == 255); + CHANNEL_B::setValue(value == 255); } else { OCR2A = value; pwmBOn(true); @@ -259,7 +259,7 @@ void setChannel(ChannelChoice c, uint8_t value, bool binary) { } } else { // channel C -- no pwm - CHANNEL_C.setValue(value == 0?false:true); + CHANNEL_C::setValue(value == 0?false:true); } } @@ -280,7 +280,7 @@ void ExtruderBoard::setValve(bool on) { } void ExtruderBoard::indicateError(int errorCode) { - DEBUG_LED.setValue(errorCode != 0); + DEBUG_LED::setValue(errorCode != 0); } void ExtruderBoard::setUsingPlatform(bool is_using) { @@ -314,12 +314,12 @@ void BuildPlatformHeatingElement::setHeatingElement(uint8_t value) { ISR(TIMER2_OVF_vect) { if (OCR2B != 0) { - CHANNEL_A.setValue(true); + CHANNEL_A::setValue(true); } } ISR(TIMER2_COMPB_vect) { - CHANNEL_A.setValue(false); + CHANNEL_A::setValue(false); } #ifdef DEFAULT_EXTERNAL_STEPPER diff --git a/firmware/src/Extruder/boards/ecv22/ExtruderMotor.cc b/firmware/src/Extruder/boards/ecv22/ExtruderMotor.cc index 476676f..04db52b 100644 --- a/firmware/src/Extruder/boards/ecv22/ExtruderMotor.cc +++ b/firmware/src/Extruder/boards/ecv22/ExtruderMotor.cc @@ -35,12 +35,14 @@ int16_t stepper_accumulator; uint8_t stepper_phase; bool swap_motor = false; -Pin motor_enable_pin = HB1_ENABLE_PIN; -Pin motor_dir_pin = HB1_DIR_PIN; +#define motor1_enable_pin HB1_ENABLE_PIN +#define motor1_dir_pin HB1_DIR_PIN +#define motor2_enable_pin HB2_ENABLE_PIN +#define motor2_dir_pin HB2_DIR_PIN -Pin external_enable_pin = ES_ENABLE_PIN; -Pin external_dir_pin = ES_DIR_PIN; -Pin external_step_pin = ES_STEP_PIN; +#define external_enable_pin ES_ENABLE_PIN +#define external_dir_pin ES_DIR_PIN +#define external_step_pin ES_STEP_PIN // FIXME: Hardcoded steps per revolution. Eventually, this needs to be configurable // Set to 200 for standard Makerbot Stepper Motor Driver V2.3 @@ -54,12 +56,12 @@ volatile int32_t ext_stepper_counter = 0; // TIMER0 is used to PWM motor driver A enable on OC0B. void initExtruderMotor() { last_extruder_speed = 0; - HB1_ENABLE_PIN.setDirection(true); - HB1_ENABLE_PIN.setValue(false); - HB1_DIR_PIN.setDirection(true); - HB2_ENABLE_PIN.setDirection(true); - HB2_ENABLE_PIN.setValue(false); - HB2_DIR_PIN.setDirection(true); + HB1_ENABLE_PIN::setDirection(true); + HB1_ENABLE_PIN::setValue(false); + HB1_DIR_PIN::setDirection(true); + HB2_ENABLE_PIN::setDirection(true); + HB2_ENABLE_PIN::setValue(false); + HB2_DIR_PIN::setDirection(true); stepper_motor_mode = false; stepper_accumulator = 0; stepper_phase = 1; @@ -67,8 +69,6 @@ void initExtruderMotor() { uint16_t ef = getEeprom16(EXTRA_FEATURES,EF_DEFAULT); if ((ef & EF_SWAP_MOTOR_CONTROLLERS) != 0) { swap_motor = true; - motor_enable_pin = HB2_ENABLE_PIN; - motor_dir_pin = HB2_DIR_PIN; } } @@ -82,14 +82,14 @@ void setStepperMode(bool mode, bool external/* = false*/) { TIMSK0 = _BV(TOIE0); } else if (external_stepper_motor_mode) { // Setup pins - external_enable_pin.setDirection(true); - external_enable_pin.setValue(true); // true = disabled + external_enable_pin::setDirection(true); + external_enable_pin::setValue(true); // true = disabled - external_dir_pin.setDirection(true); - external_dir_pin.setValue(true); // true = forward + external_dir_pin::setDirection(true); + external_dir_pin::setValue(true); // true = forward - external_step_pin.setDirection(true); - external_step_pin.setValue(false); + external_step_pin::setDirection(true); + external_step_pin::setValue(false); // CTC Mode TCCR0A = _BV(WGM01); @@ -116,25 +116,33 @@ void setExtruderMotor(int16_t speed) { TIMSK0 = 0; if (speed == 0) { TCCR0A = _BV(WGM01) | _BV(WGM00); - motor_enable_pin.setValue(false); + if ( swap_motor ) + motor2_enable_pin::setValue(false); + else + motor1_enable_pin::setValue(false); } else if (speed == 255) { TCCR0A = _BV(WGM01) | _BV(WGM00); - motor_enable_pin.setValue(true); + if ( swap_motor ) + motor2_enable_pin::setValue(true); + else + motor1_enable_pin::setValue(true); } else { - motor_enable_pin.setValue(true); if (swap_motor) { + motor2_enable_pin::setValue(true); TCCR0A = _BV(COM0A1) | _BV(WGM01) | _BV(WGM00); } else { + motor1_enable_pin::setValue(true); TCCR0A = _BV(COM0B1) | _BV(WGM01) | _BV(WGM00); } } bool backwards = speed < 0; if (backwards) { speed = -speed; } if (speed > 255) { speed = 255; } - motor_dir_pin.setValue(!backwards); if (swap_motor) { + motor2_dir_pin::setValue(!backwards); OCR0A = speed; } else { + motor1_dir_pin::setValue(!backwards); OCR0B = speed; } } @@ -157,16 +165,16 @@ void setExtruderMotorRPM(uint32_t micros, bool direction) { // This is now done in setExtruderMotorOn() // TIMSK0 = _BV(OCIE1A); - external_dir_pin.setValue(direction); // true = forward - external_enable_pin.setValue(false); // true = disabled - external_step_pin.setValue(false); - // DEBUG_LED.setValue(true); + external_dir_pin::setValue(direction); // true = forward + external_enable_pin::setValue(false); // true = disabled + external_step_pin::setValue(false); + // DEBUG_LED::setValue(true); } else { // Timer/Counter 0 Output Compare A Match Interrupt Off TIMSK0 = 0; - external_enable_pin.setValue(true); // true = disabled + external_enable_pin::setValue(true); // true = disabled ext_stepper_ticks_per_step = 0; - // DEBUG_LED.setValue(false); + // DEBUG_LED::setValue(false); } } @@ -200,10 +208,10 @@ volatile uint8_t stepper_pwm = 0; inline void setStep() { const bool enable = (last_extruder_speed != 0) && (((stepper_pwm++) & 0x01) == 0); const uint8_t mask = 1 << stepper_phase; - HB1_DIR_PIN.setValue((hb1_dir_pattern & mask) != 0); - HB1_ENABLE_PIN.setValue( enable && ((hb1_en_pattern & mask) != 0) ); - HB2_DIR_PIN.setValue((hb2_dir_pattern & mask) != 0); - HB2_ENABLE_PIN.setValue( enable && ((hb2_en_pattern & mask) != 0) ); + HB1_DIR_PIN::setValue((hb1_dir_pattern & mask) != 0); + HB1_ENABLE_PIN::setValue( enable && ((hb1_en_pattern & mask) != 0) ); + HB2_DIR_PIN::setValue((hb2_dir_pattern & mask) != 0); + HB2_ENABLE_PIN::setValue( enable && ((hb2_en_pattern & mask) != 0) ); } ISR(TIMER0_OVF_vect) { @@ -224,9 +232,9 @@ ISR(TIMER0_COMPA_vect) { if (ext_stepper_ticks_per_step > 0) { ++ext_stepper_counter; if (ext_stepper_counter >= ext_stepper_ticks_per_step) { - external_step_pin.setValue(true); + external_step_pin::setValue(true); ext_stepper_counter -= ext_stepper_ticks_per_step; - external_step_pin.setValue(false); + external_step_pin::setValue(false); } } } diff --git a/firmware/src/Extruder/boards/ecv34/Configuration.hh b/firmware/src/Extruder/boards/ecv34/Configuration.hh index 73089a1..44f7e48 100644 --- a/firmware/src/Extruder/boards/ecv34/Configuration.hh +++ b/firmware/src/Extruder/boards/ecv34/Configuration.hh @@ -18,6 +18,8 @@ #ifndef BOARDS_ECV34_CONFIGURATION_HH_ #define BOARDS_ECV34_CONFIGURATION_HH_ +#include "PinTmplt.hh" + // Board configuration files define pin configurations // for different motherboards, as well as available // features.