Add support for Printrboard RevF
The PrintrBoard Rev F utilizes a mcp4728 DAC to set motor current. Printrbot's implementation utilizes 2 new M-codes to set and write the DAC settings to the DAC EEPROM: `M909` (Read DAC) and `M910` (Write DAC). `M907` is re-used to set value, `M908` for direct control. The Pins file for the RevF board is included.
This commit is contained in:
		
				
					committed by
					
						 Scott Lahteine
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							7f2375ab46
						
					
				
				
					commit
					6843b78f99
				
			| @@ -163,6 +163,9 @@ MCU              ?= at90usb1286 | ||||
| else ifeq  ($(HARDWARE_MOTHERBOARD),81) | ||||
| HARDWARE_VARIANT ?= Teensy | ||||
| MCU              ?= at90usb1286 | ||||
| else ifeq  ($(HARDWARE_MOTHERBOARD),811) | ||||
| HARDWARE_VARIANT ?= Teensy | ||||
| MCU              ?= at90usb1286 | ||||
| else ifeq  ($(HARDWARE_MOTHERBOARD),82) | ||||
| HARDWARE_VARIANT ?= Teensy | ||||
| MCU              ?= at90usb646 | ||||
| @@ -287,7 +290,7 @@ CXXSRC = WMath.cpp WString.cpp Print.cpp Marlin_main.cpp	\ | ||||
| 	SdFile.cpp SdVolume.cpp planner.cpp stepper.cpp \ | ||||
| 	temperature.cpp cardreader.cpp configuration_store.cpp \ | ||||
| 	watchdog.cpp SPI.cpp servo.cpp Tone.cpp ultralcd.cpp digipot_mcp4451.cpp \ | ||||
| 	vector_3.cpp qr_solve.cpp buzzer.cpp | ||||
| 	dac_mcp4728.cpp vector_3.cpp qr_solve.cpp buzzer.cpp | ||||
| ifeq ($(LIQUID_TWI2), 0) | ||||
| CXXSRC += LiquidCrystal.cpp | ||||
| else | ||||
|   | ||||
| @@ -40,6 +40,7 @@ | ||||
| #define BOARD_TEENSYLU          8    // Teensylu | ||||
| #define BOARD_RUMBA             80   // Rumba | ||||
| #define BOARD_PRINTRBOARD       81   // Printrboard (AT90USB1286) | ||||
| #define BOARD_PRINTRBOARD_REVF  811  // Printrboard Revision F (AT90USB1286) | ||||
| #define BOARD_BRAINWAVE         82   // Brainwave (AT90USB646) | ||||
| #define BOARD_SAV_MKI           83   // SAV Mk-I (AT90USB1286) | ||||
| #define BOARD_TEENSY2           84   // Teensy++2.0 (AT90USB1286) - CLI compile: DEFINES=AT90USBxx_TEENSYPP_ASSIGNMENTS HARDWARE_MOTHERBOARD=84  make | ||||
|   | ||||
							
								
								
									
										115
									
								
								Marlin/dac_mcp4728.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								Marlin/dac_mcp4728.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| /* | ||||
|  | ||||
|   mcp4728.cpp - Arduino library for MicroChip MCP4728 I2C D/A converter | ||||
|   For implementation details, please take a look at the datasheet http://ww1.microchip.com/downloads/en/DeviceDoc/22187a.pdf | ||||
|   For discussion and feedback, please go to http://arduino.cc/forum/index.php/topic,51842.0.html | ||||
| */ | ||||
|  | ||||
|  | ||||
| /* _____PROJECT INCLUDES_____________________________________________________ */ | ||||
| #include "dac_mcp4728.h" | ||||
|  | ||||
| #if ENABLED(DAC_STEPPER_CURRENT) | ||||
|  | ||||
| // Used Global variables | ||||
| uint16_t     mcp4728_values[4]; | ||||
|  | ||||
| /* | ||||
| Begin I2C, get current values (input register and eeprom) of mcp4728 | ||||
| */ | ||||
| void mcp4728_init() { | ||||
|   Wire.begin(); | ||||
|   Wire.requestFrom(int(DAC_DEV_ADDRESS), 24); | ||||
|   while(Wire.available()) { | ||||
|     int deviceID = Wire.receive(); | ||||
|     int hiByte = Wire.receive(); | ||||
|     int loByte = Wire.receive(); | ||||
|  | ||||
|     int isEEPROM = (deviceID & 0B00001000) >> 3; | ||||
|     int channel = (deviceID & 0B00110000) >> 4; | ||||
|     if (isEEPROM != 1) { | ||||
|       mcp4728_values[channel] = word((hiByte & 0B00001111), loByte); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| /* | ||||
| Write input resister value to specified channel using fastwrite method. | ||||
| Channel : 0-3, Values : 0-4095 | ||||
| */ | ||||
| uint8_t mcp4728_analogWrite(uint8_t channel, uint16_t value) { | ||||
|   mcp4728_values[channel] = value; | ||||
|   return mcp4728_fastWrite(); | ||||
| } | ||||
| /* | ||||
| Write all input resistor values to EEPROM using SequencialWrite method. | ||||
| This will update both input register and EEPROM value | ||||
| This will also write current Vref, PowerDown, Gain settings to EEPROM | ||||
| */ | ||||
| uint8_t mcp4728_eepromWrite() { | ||||
|   Wire.beginTransmission(DAC_DEV_ADDRESS); | ||||
|   Wire.send(SEQWRITE); | ||||
|   for (uint8_t channel=0; channel <= 3; channel++) { | ||||
|     Wire.send(DAC_STEPPER_VREF << 7 | 0 << 5 | DAC_STEPPER_GAIN << 4 | highByte(mcp4728_values[channel])); | ||||
|     Wire.send(lowByte(mcp4728_values[channel])); | ||||
|   } | ||||
|   return Wire.endTransmission(); | ||||
| } | ||||
|  | ||||
| /* | ||||
|   Write Voltage reference setting to all input regiters | ||||
| */ | ||||
| uint8_t mcp4728_setVref_all(uint8_t value) { | ||||
|   Wire.beginTransmission(DAC_DEV_ADDRESS); | ||||
|   Wire.send(VREFWRITE | value << 3 | value << 2 | value << 1 | value); | ||||
|   return Wire.endTransmission(); | ||||
| } | ||||
| /* | ||||
|   Write Gain setting to all input regiters | ||||
| */ | ||||
| uint8_t mcp4728_setGain_all(uint8_t value) { | ||||
|   Wire.beginTransmission(DAC_DEV_ADDRESS); | ||||
|   Wire.send(GAINWRITE | value << 3 | value << 2 | value << 1 | value); | ||||
|   return Wire.endTransmission(); | ||||
| } | ||||
|  | ||||
| /* | ||||
|   Return Input Regiter value | ||||
| */ | ||||
| uint16_t mcp4728_getValue(uint8_t channel) { return mcp4728_values[channel]; } | ||||
|  | ||||
| /* | ||||
| // Steph: Might be useful in the future | ||||
| // Return Vout | ||||
| uint16_t mcp4728_getVout(uint8_t channel) { | ||||
|   uint32_t vref = 2048; | ||||
|   uint32_t vOut = (vref * mcp4728_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096; | ||||
|   if (vOut > defaultVDD) vOut = defaultVDD; | ||||
|   return vOut; | ||||
| } | ||||
| */ | ||||
|  | ||||
| /* | ||||
| FastWrite input register values - All DAC ouput update. refer to DATASHEET 5.6.1 | ||||
| DAC Input and PowerDown bits update. | ||||
| No EEPROM update | ||||
| */ | ||||
| uint8_t mcp4728_fastWrite() { | ||||
|   Wire.beginTransmission(DAC_DEV_ADDRESS); | ||||
|   for (uint8_t channel=0; channel <= 3; channel++) { | ||||
|     Wire.send(highByte(mcp4728_values[channel])); | ||||
|     Wire.send(lowByte(mcp4728_values[channel])); | ||||
|   } | ||||
|   return Wire.endTransmission(); | ||||
| } | ||||
|  | ||||
| /* | ||||
| Common function for simple general commands | ||||
| */ | ||||
| uint8_t mcp4728_simpleCommand(byte simpleCommand) { | ||||
|   Wire.beginTransmission(GENERALCALL); | ||||
|   Wire.send(simpleCommand); | ||||
|   return Wire.endTransmission(); | ||||
| } | ||||
|  | ||||
| #endif // DAC_STEPPER_CURRENT | ||||
							
								
								
									
										44
									
								
								Marlin/dac_mcp4728.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								Marlin/dac_mcp4728.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| /** | ||||
| Arduino library for MicroChip MCP4728 I2C D/A converter. | ||||
| */ | ||||
|  | ||||
| #ifndef mcp4728_h | ||||
| #define mcp4728_h | ||||
|  | ||||
| #include "Configuration.h" | ||||
| #include "Configuration_adv.h" | ||||
|  | ||||
| #if ENABLED(DAC_STEPPER_CURRENT) | ||||
| #include "WProgram.h" | ||||
| #include "Wire.h" | ||||
| //#include <Wire.h> | ||||
|  | ||||
| #define defaultVDD 5000 | ||||
| #define BASE_ADDR 0x60 | ||||
| #define RESET 0B00000110 | ||||
| #define WAKE 0B00001001 | ||||
| #define UPDATE 0B00001000 | ||||
| #define MULTIWRITE 0B01000000 | ||||
| #define SINGLEWRITE 0B01011000 | ||||
| #define SEQWRITE 0B01010000 | ||||
| #define VREFWRITE 0B10000000 | ||||
| #define GAINWRITE 0B11000000 | ||||
| #define POWERDOWNWRITE 0B10100000 | ||||
| #define GENERALCALL 0B0000000 | ||||
| #define GAINWRITE 0B11000000 | ||||
|  | ||||
| // This is taken from the original lib, makes it easy to edit if needed | ||||
| #define DAC_DEV_ADDRESS (BASE_ADDR | 0x00) | ||||
|  | ||||
| void mcp4728_init(); | ||||
| uint8_t mcp4728_analogWrite(uint8_t channel, uint16_t value); | ||||
| uint8_t mcp4728_eepromWrite(); | ||||
| uint8_t mcp4728_setVref_all(uint8_t value); | ||||
| uint8_t mcp4728_setGain_all(uint8_t value); | ||||
| uint16_t mcp4728_getValue(uint8_t channel); | ||||
| uint8_t mcp4728_fastWrite(); | ||||
| uint8_t mcp4728_simpleCommand(byte simpleCommand); | ||||
|  | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| @@ -77,6 +77,8 @@ | ||||
|   #include "pins_RUMBA.h" | ||||
| #elif MB(PRINTRBOARD) | ||||
|   #include "pins_PRINTRBOARD.h" | ||||
| #elif MB(PRINTRBOARD_REVF) | ||||
|   #include "pins_PRINTRBOARD_REVF.h" | ||||
| #elif MB(BRAINWAVE) | ||||
|   #include "pins_BRAINWAVE.h" | ||||
| #elif MB(BRAINWAVE_PRO) | ||||
|   | ||||
							
								
								
									
										134
									
								
								Marlin/pins_PRINTRBOARD_REVF.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								Marlin/pins_PRINTRBOARD_REVF.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | ||||
| /** | ||||
|  * Printrboard pin assignments (AT90USB1286) | ||||
|  * Requires the Teensyduino software with Teensy++ 2.0 selected in Arduino IDE! | ||||
|  * http://www.pjrc.com/teensy/teensyduino.html | ||||
|  * See http://reprap.org/wiki/Printrboard for more info | ||||
|  */ | ||||
|  | ||||
| #ifndef __AVR_AT90USB1286__ | ||||
|   #error Oops!  Make sure you have 'Teensy++ 2.0' selected from the 'Tools -> Boards' menu. | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(AT90USBxx_TEENSYPP_ASSIGNMENTS)  // use Teensyduino Teensy++2.0 pin assignments instead of Marlin traditional. | ||||
|   #error These Printrboard assignments depend on traditional Marlin assignments, not AT90USBxx_TEENSYPP_ASSIGNMENTS in fastio.h | ||||
| #endif | ||||
|  | ||||
| #define LARGE_FLASH        true | ||||
|  | ||||
| #define X_STEP_PIN          0 | ||||
| #define X_DIR_PIN           1 | ||||
| #define X_ENABLE_PIN       39 | ||||
|  | ||||
| #define Y_STEP_PIN          2 | ||||
| #define Y_DIR_PIN           3 | ||||
| #define Y_ENABLE_PIN       38 | ||||
|  | ||||
| #define Z_STEP_PIN          4 | ||||
| #define Z_DIR_PIN           5 | ||||
| #define Z_ENABLE_PIN       23 | ||||
|  | ||||
| #define E0_STEP_PIN         6 | ||||
| #define E0_DIR_PIN          7 | ||||
| #define E0_ENABLE_PIN      19 | ||||
|  | ||||
| #define HEATER_0_PIN       21  // Extruder | ||||
| #define HEATER_1_PIN       46 | ||||
| #define HEATER_2_PIN       47 | ||||
| #define HEATER_BED_PIN     20 | ||||
|  | ||||
| // If soft or fast PWM is off then use Teensyduino pin numbering, Marlin | ||||
| // fastio pin numbering otherwise | ||||
| #if ENABLED(FAN_SOFT_PWM) || ENABLED(FAST_PWM_FAN) | ||||
|   #define FAN_PIN          22 | ||||
| #else | ||||
|   #define FAN_PIN          16 | ||||
| #endif | ||||
|  | ||||
| #define X_STOP_PIN         35 | ||||
| #define Y_STOP_PIN         12 | ||||
| #define Z_STOP_PIN         36 | ||||
|  | ||||
| #define TEMP_0_PIN          1  // Extruder / Analog pin numbering | ||||
| #define TEMP_BED_PIN        0  // Bed / Analog pin numbering | ||||
|  | ||||
| #if ENABLED(FILAMENT_SENSOR) | ||||
|   #define FILWIDTH_PIN      2 | ||||
| #endif | ||||
|  | ||||
| #define TEMP_1_PIN         -1 | ||||
| #define TEMP_2_PIN         -1 | ||||
|  | ||||
| ////LCD Pin Setup//// | ||||
|  | ||||
| #define SDPOWER            -1 | ||||
| #define SDSS               20 // Teensylu pin mapping | ||||
| #define LED_PIN            -1 | ||||
| #define PS_ON_PIN          -1 | ||||
| #define KILL_PIN           -1 | ||||
| #define ALARM_PIN          -1 | ||||
|  | ||||
| // uncomment to enable an I2C based DAC like on the Printrboard REVF | ||||
| #define DAC_STEPPER_CURRENT | ||||
| // Number of channels available for DAC, For Printrboar REVF there are 4 | ||||
| #define DAC_STEPPER_ORDER 	{3,2,1,0} | ||||
|  | ||||
| #define DAC_STEPPER_SENSE 0.11 | ||||
| #define DAC_STEPPER_ADDRESS	0 | ||||
| #define DAC_STEPPER_MAX 	3520 | ||||
| #define DAC_STEPPER_VREF 	1 //internal Vref, gain 1x = 2.048V | ||||
| #define DAC_STEPPER_GAIN	0 | ||||
|  | ||||
| #if DISABLED(SDSUPPORT) | ||||
|   // these pins are defined in the SD library if building with SD support | ||||
|   #define SCK_PIN           9 | ||||
|   #define MISO_PIN         11 | ||||
|   #define MOSI_PIN         10 | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(ULTRA_LCD) | ||||
|   #define BEEPER_PIN -1 | ||||
|  | ||||
|   #define LCD_PINS_RS 9 | ||||
|   #define LCD_PINS_ENABLE 8 | ||||
|   #define LCD_PINS_D4 7 | ||||
|   #define LCD_PINS_D5 6 | ||||
|   #define LCD_PINS_D6 5 | ||||
|   #define LCD_PINS_D7 4 | ||||
|  | ||||
|   #define BTN_EN1   16 | ||||
|   #define BTN_EN2   17 | ||||
|   #define BTN_ENC   18//the click | ||||
|  | ||||
|   #define BLEN_C 2 | ||||
|   #define BLEN_B 1 | ||||
|   #define BLEN_A 0 | ||||
|  | ||||
|   #define SD_DETECT_PIN -1 | ||||
|  | ||||
|   //encoder rotation values | ||||
|   #define encrot0 0 | ||||
|   #define encrot1 2 | ||||
|   #define encrot2 3 | ||||
|   #define encrot3 1 | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(VIKI2) || ENABLED(miniVIKI) | ||||
|   #define BEEPER_PIN 32 //FastIO | ||||
|   // Pins for DOGM SPI LCD Support | ||||
|   #define DOGLCD_A0  42 //Non-FastIO | ||||
|   #define DOGLCD_CS  43 //Non-FastIO | ||||
|   #define LCD_SCREEN_ROT_180 | ||||
|  | ||||
|   //The encoder and click button (FastIO Pins) | ||||
|   #define BTN_EN1 26 | ||||
|   #define BTN_EN2 27 | ||||
|   #define BTN_ENC 47  //the click switch | ||||
|  | ||||
|   #define SDSS 45 | ||||
|   #define SD_DETECT_PIN -1 // FastIO (Manual says 72 I'm not certain cause I can't test) | ||||
|  | ||||
|   #if ENABLED(TEMP_STAT_LEDS) | ||||
|     #define STAT_LED_RED      12 //Non-FastIO | ||||
|     #define STAT_LED_BLUE     10 //Non-FastIO | ||||
|   #endif | ||||
| #endif | ||||
| @@ -30,6 +30,7 @@ | ||||
| #include "language.h" | ||||
| #include "cardreader.h" | ||||
| #include "speed_lookuptable.h" | ||||
| #include "dac_mcp4728.h" | ||||
| #if HAS_DIGIPOTSS | ||||
|   #include <SPI.h> | ||||
| #endif | ||||
| @@ -1224,9 +1225,72 @@ void digipot_current(uint8_t driver, int current) { | ||||
|   #else | ||||
|     UNUSED(driver); | ||||
|     UNUSED(current); | ||||
| #endif | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| #if ENABLED(DAC_STEPPER_CURRENT) | ||||
|  | ||||
|   bool dac_present = false; | ||||
|   const uint8_t dac_order[NUM_AXIS] = DAC_STEPPER_ORDER; | ||||
|  | ||||
|   int dac_init() { | ||||
|     mcp4728_init(); | ||||
|  | ||||
|     if (mcp4728_simpleCommand(RESET)) return -1; | ||||
|  | ||||
|     dac_present = true; | ||||
|  | ||||
|     mcp4728_setVref_all(DAC_STEPPER_VREF); | ||||
|     mcp4728_setGain_all(DAC_STEPPER_GAIN); | ||||
|  | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   void dac_current_percent(uint8_t channel, float val) { | ||||
|     if (!dac_present) return; | ||||
|  | ||||
|     NOMORE(val, 100); | ||||
|  | ||||
|     mcp4728_analogWrite(dac_order[channel], val * DAC_STEPPER_MAX / 100); | ||||
|     mcp4728_simpleCommand(UPDATE); | ||||
|   } | ||||
|  | ||||
|   void dac_current_raw(uint8_t channel, uint16_t val) { | ||||
|     if (!dac_present) return; | ||||
|  | ||||
|     NOMORE(val, DAC_STEPPER_MAX); | ||||
|  | ||||
|     mcp4728_analogWrite(dac_order[channel], val); | ||||
|     mcp4728_simpleCommand(UPDATE); | ||||
|   } | ||||
|  | ||||
|   static float dac_perc(int8_t n) { return 100.0 * mcp4728_getValue(dac_order[n]) / DAC_STEPPER_MAX; } | ||||
|   static float dac_amps(int8_t n) { return ((2.048 * mcp4728_getValue(dac_order[n])) / 4096.0) / (8.0 * DAC_STEPPER_SENSE); } | ||||
|  | ||||
|   void dac_print_values() { | ||||
|     if (!dac_present) return; | ||||
|  | ||||
|     SERIAL_ECHO_START; | ||||
|     SERIAL_ECHOLNPGM("Stepper current values in % (Amps):"); | ||||
|     SERIAL_ECHO_START; | ||||
|     SERIAL_ECHOPAIR(" X:",  dac_perc(0)); | ||||
|     SERIAL_ECHOPAIR(" (",   dac_amps(0)); | ||||
|     SERIAL_ECHOPAIR(") Y:", dac_perc(1)); | ||||
|     SERIAL_ECHOPAIR(" (",   dac_amps(1)); | ||||
|     SERIAL_ECHOPAIR(") Z:", dac_perc(2)); | ||||
|     SERIAL_ECHOPAIR(" (",   dac_amps(2)); | ||||
|     SERIAL_ECHOPAIR(") E:", dac_perc(3)); | ||||
|     SERIAL_ECHOPAIR(" (",   dac_amps(3)); | ||||
|     SERIAL_ECHOLN(")"); | ||||
|   } | ||||
|  | ||||
|   void dac_commit_eeprom() { | ||||
|     if (!dac_present) return; | ||||
|     mcp4728_eepromWrite(); | ||||
|   } | ||||
|  | ||||
| #endif // DAC_STEPPER_CURRENT | ||||
|  | ||||
| void microstep_init() { | ||||
|   #if HAS_MICROSTEPS_E1 | ||||
|     pinMode(E1_MS1_PIN, OUTPUT); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user