Browse Source

run a reasonable LCD message on boot asap, support the second serial port (enabled only in farm mode)

Andre Sklenar 7 years ago
parent
commit
7d2d6c6fdc
4 changed files with 136 additions and 21 deletions
  1. 2 1
      Firmware/Marlin.h
  2. 41 2
      Firmware/MarlinSerial.cpp
  3. 42 17
      Firmware/MarlinSerial.h
  4. 51 1
      Firmware/Marlin_main.cpp

+ 2 - 1
Firmware/Marlin.h

@@ -96,6 +96,7 @@ void serial_echopair_P(const char *s_P, float v);
 void serial_echopair_P(const char *s_P, double v);
 void serial_echopair_P(const char *s_P, unsigned long v);
 
+extern int selectedSerialPort;
 
 //Things to write to serial from Program memory. Saves 400 to 2k of RAM.
 FORCE_INLINE void serialprintPGM(const char *str)
@@ -348,4 +349,4 @@ float temp_comp_interpolation(float temperature);
 void temp_compensation_apply();
 void temp_compensation_start();
 void wait_for_heater(long codenum);
-void serialecho_temperatures();
+void serialecho_temperatures();

+ 41 - 2
Firmware/MarlinSerial.cpp

@@ -64,6 +64,23 @@ FORCE_INLINE void store_char(unsigned char c)
           store_char(c);
       }
   }
+  
+  SIGNAL(USART2_RX_vect)
+  {
+      if (selectedSerialPort == 1) {
+        // Test for a framing error.
+        if (UCSR2A & (1<<FE2)) {
+            // Characters received with the framing errors will be ignored.
+            // The temporary variable "c" was made volatile, so the compiler does not optimize this out.
+            volatile unsigned char c = UDR2;
+        } else {
+            // Read the input register.
+            unsigned char c = UDR2;
+            store_char(c);
+            
+        }
+      }
+  }
 #endif
 
 // Constructors ////////////////////////////////////////////////////////////////
@@ -88,7 +105,7 @@ void MarlinSerial::begin(long baud)
     useU2X = false;
   }
 #endif
-  
+// set up the first (original serial port)
   if (useU2X) {
     M_UCSRxA = 1 << M_U2Xx;
     baud_setting = (F_CPU / 4 / baud - 1) / 2;
@@ -104,13 +121,35 @@ void MarlinSerial::begin(long baud)
   sbi(M_UCSRxB, M_RXENx);
   sbi(M_UCSRxB, M_TXENx);
   sbi(M_UCSRxB, M_RXCIEx);
+  
+  
+// set up the second serial port
+  if (useU2X) {
+        UCSR2A = 1 << U2X2;
+        baud_setting = (F_CPU / 4 / baud - 1) / 2;
+    } else {
+        UCSR2A = 0;
+        baud_setting = (F_CPU / 8 / baud - 1) / 2;
+    }
+
+    // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
+    UBRR2H = baud_setting >> 8;
+    UBRR2L = baud_setting;
+
+    sbi(UCSR2B, RXEN2);
+    sbi(UCSR2B, TXEN2);
+    sbi(UCSR2B, RXCIE2);
 }
 
 void MarlinSerial::end()
 {
   cbi(M_UCSRxB, M_RXENx);
   cbi(M_UCSRxB, M_TXENx);
-  cbi(M_UCSRxB, M_RXCIEx);  
+  cbi(M_UCSRxB, M_RXCIEx);
+  
+  cbi(UCSR2B, RXEN2);
+  cbi(UCSR2B, TXEN2);
+  cbi(UCSR2B, RXCIE2); 
 }
 
 

+ 42 - 17
Firmware/MarlinSerial.h

@@ -73,6 +73,7 @@
 // is the index of the location from which to read.
 #define RX_BUFFER_SIZE 128
 
+extern int selectedSerialPort;
 
 struct ring_buffer
 {
@@ -110,24 +111,48 @@ class MarlinSerial //: public Stream
     }
     
     
-    FORCE_INLINE void checkRx(void)
+    void checkRx(void)
     {
-        if((M_UCSRxA & (1<<M_RXCx)) != 0) {
-            // Test for a framing error.
-            if (M_UCSRxA & (1<<M_FEx)) {
-                // Characters received with the framing errors will be ignored.
-                // The temporary variable "c" was made volatile, so the compiler does not optimize this out.
-                volatile unsigned char c = M_UDRx;
-            } else {
-                unsigned char c  =  M_UDRx;
-                int i = (unsigned int)(rx_buffer.head + 1) % RX_BUFFER_SIZE;
-                // if we should be storing the received character into the location
-                // just before the tail (meaning that the head would advance to the
-                // current location of the tail), we're about to overflow the buffer
-                // and so we don't write the character or advance the head.
-                if (i != rx_buffer.tail) {
-                    rx_buffer.buffer[rx_buffer.head] = c;
-                    rx_buffer.head = i;
+        if (selectedSerialPort == 0) {
+            if((M_UCSRxA & (1<<M_RXCx)) != 0) {
+                // Test for a framing error.
+                if (M_UCSRxA & (1<<M_FEx)) {
+                    // Characters received with the framing errors will be ignored.
+                    // The temporary variable "c" was made volatile, so the compiler does not optimize this out.
+                    volatile unsigned char c = M_UDRx;
+                } else {
+                    unsigned char c  =  M_UDRx;
+                    int i = (unsigned int)(rx_buffer.head + 1) % RX_BUFFER_SIZE;
+                    // if we should be storing the received character into the location
+                    // just before the tail (meaning that the head would advance to the
+                    // current location of the tail), we're about to overflow the buffer
+                    // and so we don't write the character or advance the head.
+                    if (i != rx_buffer.tail) {
+                        rx_buffer.buffer[rx_buffer.head] = c;
+                        rx_buffer.head = i;
+                    }
+                    selectedSerialPort = 0;
+                }
+            }
+        } else if(selectedSerialPort == 1) {
+            if((UCSR2A & (1<<RXC2)) != 0) {
+                // Test for a framing error.
+                if (UCSR2A & (1<<FE2)) {
+                    // Characters received with the framing errors will be ignored.
+                    // The temporary variable "c" was made volatile, so the compiler does not optimize this out.
+                    volatile unsigned char c = UDR2;
+                } else {
+                    unsigned char c  =  UDR2;
+                    int i = (unsigned int)(rx_buffer.head + 1) % RX_BUFFER_SIZE;
+                    // if we should be storing the received character into the location
+                    // just before the tail (meaning that the head would advance to the
+                    // current location of the tail), we're about to overflow the buffer
+                    // and so we don't write the character or advance the head.
+                    if (i != rx_buffer.tail) {
+                        rx_buffer.buffer[rx_buffer.head] = c;
+                        rx_buffer.head = i;
+                    }
+                    selectedSerialPort = 1;
                 }
             }
         }

+ 51 - 1
Firmware/Marlin_main.cpp

@@ -289,6 +289,8 @@ unsigned int custom_message_type;
 unsigned int custom_message_state;
 char snmm_filaments_used = 0;
 
+int selectedSerialPort;
+
 float distance_from_min[3];
 float angleDiff;
 
@@ -996,8 +998,22 @@ void factory_reset(char level, bool quiet)
 // are initialized by the main() routine provided by the Arduino framework.
 void setup()
 {
+	lcd_init();
+    lcd_print_at_PGM(0, 1, PSTR("   Original Prusa   "));
+    lcd_print_at_PGM(0, 2, PSTR("    3D  Printers    "));
 	setup_killpin();
 	setup_powerhold();
+    farm_mode = eeprom_read_byte((uint8_t*)EEPROM_FARM_MODE);
+	EEPROM_read_B(EEPROM_FARM_NUMBER, &farm_no);
+	//if ((farm_mode == 0xFF && farm_no == 0) || (farm_no == 0xFFFF)) farm_mode = false; //if farm_mode has not been stored to eeprom yet and farm number is set to zero or EEPROM is fresh, deactivate farm mode 
+	if (farm_no == 0xFFFF) farm_no = 0;
+	if (farm_mode)
+	{
+		prusa_statistics(8);
+        selectedSerialPort = 1;
+	} else {
+        selectedSerialPort = 0;
+    }
 	MYSERIAL.begin(BAUDRATE);
 	SERIAL_PROTOCOLLNPGM("start");
 	SERIAL_ECHO_START;
@@ -1052,6 +1068,8 @@ void setup()
 	tp_init();    // Initialize temperature loop
 	plan_init();  // Initialize planner;
 	watchdog_init();
+    lcd_print_at_PGM(0, 1, PSTR("   Original Prusa   ")); // we need to do this again for some reason, no time to research
+    lcd_print_at_PGM(0, 2, PSTR("    3D  Printers    "));
 	st_init();    // Initialize stepper, this enables interrupts!
 	setup_photpin();
 	servo_init();
@@ -1125,7 +1143,7 @@ void setup()
 	}
 	else
 	{
-		_delay_ms(1000);  // wait 1sec to display the splash screen
+		//_delay_ms(1000);  // wait 1sec to display the splash screen // what's this and why do we need it?? - andre
 	}
 
 
@@ -1378,6 +1396,11 @@ void get_command()
 		  rx_buffer_full = true;				//sets flag that buffer was full	
 	  }
     char serial_char = MYSERIAL.read();
+    if (selectedSerialPort == 1) {
+        selectedSerialPort = 0;
+        MYSERIAL.write(serial_char);
+        selectedSerialPort = 1;
+    }
       TimeSent = millis();
       TimeNow = millis();
 
@@ -2101,6 +2124,33 @@ void process_commands()
         trace();
         prusa_sd_card_upload = true;
         card.openFile(strchr_pointer+4,false);
+    } else if (code_seen("SN")) {
+        if (farm_mode) {
+            selectedSerialPort = 0;
+            MSerial.write(";S");
+            // S/N is:CZPX0917X003XC13518
+            int numbersRead = 0;
+
+            while (numbersRead < 19) {
+                while (MSerial.available() > 0) {
+                    uint8_t serial_char = MSerial.read();
+                    selectedSerialPort = 1;
+                    MSerial.write(serial_char);
+                    numbersRead++;
+                    selectedSerialPort = 0;
+                }
+            }
+            selectedSerialPort = 1;
+            MSerial.write('\n');
+            /*for (int b = 0; b < 3; b++) {
+                tone(BEEPER, 110);
+                delay(50);
+                noTone(BEEPER);
+                delay(50);
+            }*/
+        } else {
+            MYSERIAL.println("Not in farm mode.");
+        }
     } else if(code_seen("Fir")){
 
       SERIAL_PROTOCOLLN(FW_version);