├── hardware └── openplc │ └── avr │ ├── firmwares │ ├── inputBoard │ │ ├── inputBoard.cpp.elf │ │ ├── inputBoard.ino │ │ └── OPLC_Protocol.h │ └── outputBoard │ │ ├── outputBoard.cpp.elf │ │ ├── outputBoard.ino │ │ └── OPLC_Protocol.h │ ├── libraries │ ├── EEPROM │ │ ├── library.properties │ │ ├── examples │ │ │ ├── eeprom_clear │ │ │ │ └── eeprom_clear.ino │ │ │ ├── eeprom_write │ │ │ │ └── eeprom_write.ino │ │ │ └── eeprom_read │ │ │ │ └── eeprom_read.ino │ │ ├── keywords.txt │ │ ├── EEPROM.h │ │ └── EEPROM.cpp │ ├── SoftwareSerial │ │ ├── library.properties │ │ ├── keywords.txt │ │ ├── examples │ │ │ ├── SoftwareSerialExample │ │ │ │ └── SoftwareSerialExample.ino │ │ │ └── TwoPortReceive │ │ │ │ └── TwoPortReceive.ino │ │ └── SoftwareSerial.h │ ├── SPI │ │ ├── library.properties │ │ ├── keywords.txt │ │ ├── examples │ │ │ ├── DigitalPotControl │ │ │ │ └── DigitalPotControl.ino │ │ │ └── BarometricPressureSensor │ │ │ │ └── BarometricPressureSensor.ino │ │ └── SPI.cpp │ ├── Wire │ │ ├── library.properties │ │ ├── examples │ │ │ ├── master_writer │ │ │ │ └── master_writer.ino │ │ │ ├── slave_sender │ │ │ │ └── slave_sender.ino │ │ │ ├── master_reader │ │ │ │ └── master_reader.ino │ │ │ ├── digital_potentiometer │ │ │ │ └── digital_potentiometer.ino │ │ │ ├── slave_receiver │ │ │ │ └── slave_receiver.ino │ │ │ └── SFRRanger_reader │ │ │ │ └── SFRRanger_reader.ino │ │ ├── keywords.txt │ │ ├── utility │ │ │ └── twi.h │ │ └── Wire.h │ ├── OpenPLC │ │ ├── Special_functions.h │ │ ├── Globals.h │ │ ├── Prototypes.h │ │ ├── OpenPLC.h │ │ ├── Cards_Comm.h │ │ └── OPLC_Protocol.h │ └── Mudbus │ │ ├── Mudbus.h │ │ └── Mudbus.cpp │ ├── cores │ └── arduino │ │ ├── Arduino.h │ │ ├── Server.h │ │ ├── new.h │ │ ├── new.cpp │ │ ├── hooks.c │ │ ├── abi.cpp │ │ ├── Printable.h │ │ ├── main.cpp │ │ ├── Client.h │ │ ├── wiring_shift.c │ │ ├── WMath.cpp │ │ ├── USBDesc.h │ │ ├── HardwareSerial2.cpp │ │ ├── HardwareSerial3.cpp │ │ ├── IPAddress.cpp │ │ ├── wiring_private.h │ │ ├── HardwareSerial1.cpp │ │ ├── wiring_pulse.c │ │ ├── HardwareSerial0.cpp │ │ ├── Print.h │ │ ├── IPAddress.h │ │ ├── Udp.h │ │ ├── HardwareSerial_private.h │ │ ├── Stream.h │ │ ├── WCharacter.h │ │ ├── HardwareSerial.h │ │ ├── wiring_digital.c │ │ ├── Print.cpp │ │ ├── CDC.cpp │ │ ├── USBAPI.h │ │ ├── Arduino-core.h │ │ └── Stream.cpp │ ├── boards.txt │ ├── platform.txt │ └── variants │ └── iocard │ └── pins_arduino.h └── README.md /hardware/openplc/avr/firmwares/inputBoard/inputBoard.cpp.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPLC/OpenPLC-libs/HEAD/hardware/openplc/avr/firmwares/inputBoard/inputBoard.cpp.elf -------------------------------------------------------------------------------- /hardware/openplc/avr/firmwares/outputBoard/outputBoard.cpp.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPLC/OpenPLC-libs/HEAD/hardware/openplc/avr/firmwares/outputBoard/outputBoard.cpp.elf -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/EEPROM/library.properties: -------------------------------------------------------------------------------- 1 | name=EEPROM 2 | version=1.0 3 | author=Arduino 4 | maintainer=Arduino 5 | sentence=Enables reading and writing to the permanent board storage. For all Arduino boards BUT Arduino DUE. 6 | paragraph= 7 | url=http://arduino.cc/en/Reference/EEPROM 8 | architectures=avr 9 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/SoftwareSerial/library.properties: -------------------------------------------------------------------------------- 1 | name=SoftwareSerial 2 | version=1.0 3 | author=Arduino 4 | maintainer=Arduino 5 | sentence=Enables serial communication on digital pins. For all Arduino boards, BUT Arduino DUE. 6 | paragraph= 7 | url=http://arduino.cc/en/Reference/SoftwareSerial 8 | architectures=avr 9 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/SPI/library.properties: -------------------------------------------------------------------------------- 1 | name=SPI 2 | version=1.0 3 | author=Arduino 4 | maintainer=Arduino 5 | sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. For all Arduino boards, BUT Arduino DUE. 6 | paragraph= 7 | url=http://arduino.cc/en/Reference/SPI 8 | architectures=avr 9 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/Wire/library.properties: -------------------------------------------------------------------------------- 1 | name=Wire 2 | version=1.0 3 | author=Arduino 4 | maintainer=Arduino 5 | sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus. For all Arduino boards, BUT Arduino DUE. 6 | paragraph= 7 | url=http://arduino.cc/en/Reference/Wire 8 | architectures=avr 9 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * EEPROM Clear 3 | * 4 | * Sets all of the bytes of the EEPROM to 0. 5 | * This example code is in the public domain. 6 | 7 | */ 8 | 9 | #include 10 | 11 | void setup() 12 | { 13 | // write a 0 to all 512 bytes of the EEPROM 14 | for (int i = 0; i < 512; i++) 15 | EEPROM.write(i, 0); 16 | 17 | // turn the LED on when we're done 18 | digitalWrite(13, HIGH); 19 | } 20 | 21 | void loop() 22 | { 23 | } 24 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/EEPROM/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Ultrasound 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | EEPROM KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | ####################################### 16 | # Constants (LITERAL1) 17 | ####################################### 18 | 19 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/Arduino.h: -------------------------------------------------------------------------------- 1 | /* 2 | A wrapper library for OpenPLC. 3 | This includes OpenPLCWrapper.h and Arduino-core.h 4 | 5 | OpenPLCWrapper takes care of all OpenPLC side of things, 6 | making it smooth to transition from the main board to 7 | mini/micro OpenPLC boards without changing the included files. 8 | The variant system of Arduino IDE takes care of that. 9 | 10 | The Arduino-core.h is renamed from the original Arduino.h file 11 | and takes care of all the arduino stuff that needs to be there 12 | from the beginning. 13 | 14 | */ 15 | 16 | #ifndef OpenPLCWrapper_h 17 | #define OpenPLCWrapper_h 18 | 19 | #include 20 | //#include 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/SoftwareSerial/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map for SoftwareSerial 3 | # (formerly NewSoftSerial) 4 | ####################################### 5 | 6 | ####################################### 7 | # Datatypes (KEYWORD1) 8 | ####################################### 9 | 10 | SoftwareSerial KEYWORD1 11 | 12 | ####################################### 13 | # Methods and Functions (KEYWORD2) 14 | ####################################### 15 | 16 | begin KEYWORD2 17 | end KEYWORD2 18 | read KEYWORD2 19 | write KEYWORD2 20 | available KEYWORD2 21 | isListening KEYWORD2 22 | overflow KEYWORD2 23 | flush KEYWORD2 24 | listen KEYWORD2 25 | peek KEYWORD2 26 | 27 | ####################################### 28 | # Constants (LITERAL1) 29 | ####################################### 30 | 31 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/Wire/examples/master_writer/master_writer.ino: -------------------------------------------------------------------------------- 1 | // Wire Master Writer 2 | // by Nicholas Zambetti 3 | 4 | // Demonstrates use of the Wire library 5 | // Writes data to an I2C/TWI slave device 6 | // Refer to the "Wire Slave Receiver" example for use with this 7 | 8 | // Created 29 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() 16 | { 17 | Wire.begin(); // join i2c bus (address optional for master) 18 | } 19 | 20 | byte x = 0; 21 | 22 | void loop() 23 | { 24 | Wire.beginTransmission(4); // transmit to device #4 25 | Wire.write("x is "); // sends five bytes 26 | Wire.write(x); // sends one byte 27 | Wire.endTransmission(); // stop transmitting 28 | 29 | x++; 30 | delay(500); 31 | } 32 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/Wire/examples/slave_sender/slave_sender.ino: -------------------------------------------------------------------------------- 1 | // Wire Slave Sender 2 | // by Nicholas Zambetti 3 | 4 | // Demonstrates use of the Wire library 5 | // Sends data as an I2C/TWI slave device 6 | // Refer to the "Wire Master Reader" example for use with this 7 | 8 | // Created 29 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() 16 | { 17 | Wire.begin(2); // join i2c bus with address #2 18 | Wire.onRequest(requestEvent); // register event 19 | } 20 | 21 | void loop() 22 | { 23 | delay(100); 24 | } 25 | 26 | // function that executes whenever data is requested by master 27 | // this function is registered as an event, see setup() 28 | void requestEvent() 29 | { 30 | Wire.write("hello "); // respond with message of 6 bytes 31 | // as expected by master 32 | } 33 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/Wire/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Wire 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ####################################### 10 | # Methods and Functions (KEYWORD2) 11 | ####################################### 12 | 13 | begin KEYWORD2 14 | setClock KEYWORD2 15 | beginTransmission KEYWORD2 16 | endTransmission KEYWORD2 17 | requestFrom KEYWORD2 18 | send KEYWORD2 19 | receive KEYWORD2 20 | onReceive KEYWORD2 21 | onRequest KEYWORD2 22 | 23 | ####################################### 24 | # Instances (KEYWORD2) 25 | ####################################### 26 | 27 | Wire KEYWORD2 28 | 29 | ####################################### 30 | # Constants (LITERAL1) 31 | ####################################### 32 | 33 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/Wire/examples/master_reader/master_reader.ino: -------------------------------------------------------------------------------- 1 | // Wire Master Reader 2 | // by Nicholas Zambetti 3 | 4 | // Demonstrates use of the Wire library 5 | // Reads data from an I2C/TWI slave device 6 | // Refer to the "Wire Slave Sender" example for use with this 7 | 8 | // Created 29 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() 16 | { 17 | Wire.begin(); // join i2c bus (address optional for master) 18 | Serial.begin(9600); // start serial for output 19 | } 20 | 21 | void loop() 22 | { 23 | Wire.requestFrom(2, 6); // request 6 bytes from slave device #2 24 | 25 | while (Wire.available()) // slave may send less than requested 26 | { 27 | char c = Wire.read(); // receive a byte as character 28 | Serial.print(c); // print the character 29 | } 30 | 31 | delay(500); 32 | } 33 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/SPI/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map SPI 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | SPI KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | begin KEYWORD2 15 | end KEYWORD2 16 | transfer KEYWORD2 17 | setBitOrder KEYWORD2 18 | setDataMode KEYWORD2 19 | setClockDivider KEYWORD2 20 | 21 | 22 | ####################################### 23 | # Constants (LITERAL1) 24 | ####################################### 25 | SPI_CLOCK_DIV4 LITERAL1 26 | SPI_CLOCK_DIV16 LITERAL1 27 | SPI_CLOCK_DIV64 LITERAL1 28 | SPI_CLOCK_DIV128 LITERAL1 29 | SPI_CLOCK_DIV2 LITERAL1 30 | SPI_CLOCK_DIV8 LITERAL1 31 | SPI_CLOCK_DIV32 LITERAL1 32 | SPI_CLOCK_DIV64 LITERAL1 33 | SPI_MODE0 LITERAL1 34 | SPI_MODE1 LITERAL1 35 | SPI_MODE2 LITERAL1 36 | SPI_MODE3 LITERAL1 -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/Server.h: -------------------------------------------------------------------------------- 1 | /* 2 | Server.h - Base class that provides Server 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef server_h 21 | #define server_h 22 | 23 | class Server : public Print { 24 | public: 25 | virtual void begin() =0; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * EEPROM Write 3 | * 4 | * Stores values read from analog input 0 into the EEPROM. 5 | * These values will stay in the EEPROM when the board is 6 | * turned off and may be retrieved later by another sketch. 7 | */ 8 | 9 | #include 10 | 11 | // the current address in the EEPROM (i.e. which byte 12 | // we're going to write to next) 13 | int addr = 0; 14 | 15 | void setup() 16 | { 17 | } 18 | 19 | void loop() 20 | { 21 | // need to divide by 4 because analog inputs range from 22 | // 0 to 1023 and each byte of the EEPROM can only hold a 23 | // value from 0 to 255. 24 | int val = analogRead(0) / 4; 25 | 26 | // write the value to the appropriate byte of the EEPROM. 27 | // these values will remain there when the board is 28 | // turned off. 29 | EEPROM.write(addr, val); 30 | 31 | // advance to the next address. there are 512 bytes in 32 | // the EEPROM, so go back to 0 when we hit 512. 33 | addr = addr + 1; 34 | if (addr == 512) 35 | addr = 0; 36 | 37 | delay(100); 38 | } 39 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/OpenPLC/Special_functions.h: -------------------------------------------------------------------------------- 1 | //LADDER SPECIAL FUNCTIONS 2 | 3 | //allways on 4 | boolean SF_01() 5 | { 6 | return (1); 7 | } 8 | 9 | //allways off 10 | boolean SF_02() 11 | { 12 | return (0); 13 | } 14 | 15 | //first cicle on 16 | boolean SF_03() 17 | { 18 | return first_cycle; 19 | } 20 | 21 | //30s off - 30s on 22 | boolean SF_04() 23 | { 24 | return toggle_30s; 25 | } 26 | 27 | //500ms off - 500ms on 28 | boolean SF_05() 29 | { 30 | return toggle_500ms; 31 | } 32 | 33 | //cycle off - cycle on 34 | boolean SF_06() 35 | { 36 | return toggle_50ms; 37 | } 38 | 39 | void countTimers() 40 | { 41 | system_timer++; //increment system timer each cycle 42 | 43 | //SPECIAL FUNCTION VARIABLES 44 | first_cycle = false; //after the first cycle this boolean remains off 45 | toggle_50ms = !toggle_50ms; //toggle each cycle 46 | if (!(system_timer % 10)) 47 | { 48 | toggle_500ms = !toggle_500ms; //toggle each 500ms 49 | } 50 | if (system_timer == 600) 51 | { 52 | system_timer = 0; //reset timer 53 | toggle_30s = !toggle_30s; //toggle each 30s 54 | } 55 | } -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/new.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef NEW_H 20 | #define NEW_H 21 | 22 | #include 23 | 24 | void * operator new(size_t size); 25 | void * operator new[](size_t size); 26 | void operator delete(void * ptr); 27 | void operator delete[](void * ptr); 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * EEPROM Read 3 | * 4 | * Reads the value of each byte of the EEPROM and prints it 5 | * to the computer. 6 | * This example code is in the public domain. 7 | */ 8 | 9 | #include 10 | 11 | // start reading from the first byte (address 0) of the EEPROM 12 | int address = 0; 13 | byte value; 14 | 15 | void setup() 16 | { 17 | // initialize serial and wait for port to open: 18 | Serial.begin(9600); 19 | while (!Serial) { 20 | ; // wait for serial port to connect. Needed for Leonardo only 21 | } 22 | } 23 | 24 | void loop() 25 | { 26 | // read a byte from the current address of the EEPROM 27 | value = EEPROM.read(address); 28 | 29 | Serial.print(address); 30 | Serial.print("\t"); 31 | Serial.print(value, DEC); 32 | Serial.println(); 33 | 34 | // advance to the next address of the EEPROM 35 | address = address + 1; 36 | 37 | // there are only 512 bytes of EEPROM, from 0 to 511, so if we're 38 | // on address 512, wrap around to address 0 39 | if (address == 512) 40 | address = 0; 41 | 42 | delay(500); 43 | } 44 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/EEPROM/EEPROM.h: -------------------------------------------------------------------------------- 1 | /* 2 | EEPROM.h - EEPROM library 3 | Copyright (c) 2006 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef EEPROM_h 21 | #define EEPROM_h 22 | 23 | #include 24 | 25 | class EEPROMClass 26 | { 27 | public: 28 | uint8_t read(int); 29 | void write(int, uint8_t); 30 | }; 31 | 32 | extern EEPROMClass EEPROM; 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino: -------------------------------------------------------------------------------- 1 | // I2C Digital Potentiometer 2 | // by Nicholas Zambetti 3 | // and Shawn Bonkowski 4 | 5 | // Demonstrates use of the Wire library 6 | // Controls AD5171 digital potentiometer via I2C/TWI 7 | 8 | // Created 31 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | // This example code is in the public domain. 13 | 14 | 15 | #include 16 | 17 | void setup() 18 | { 19 | Wire.begin(); // join i2c bus (address optional for master) 20 | } 21 | 22 | byte val = 0; 23 | 24 | void loop() 25 | { 26 | Wire.beginTransmission(44); // transmit to device #44 (0x2c) 27 | // device address is specified in datasheet 28 | Wire.write(byte(0x00)); // sends instruction byte 29 | Wire.write(val); // sends potentiometer value byte 30 | Wire.endTransmission(); // stop transmitting 31 | 32 | val++; // increment value 33 | if (val == 64) // if reached 64th position (max) 34 | { 35 | val = 0; // start over from lowest value 36 | } 37 | delay(500); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/Wire/examples/slave_receiver/slave_receiver.ino: -------------------------------------------------------------------------------- 1 | // Wire Slave Receiver 2 | // by Nicholas Zambetti 3 | 4 | // Demonstrates use of the Wire library 5 | // Receives data as an I2C/TWI slave device 6 | // Refer to the "Wire Master Writer" example for use with this 7 | 8 | // Created 29 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() 16 | { 17 | Wire.begin(4); // join i2c bus with address #4 18 | Wire.onReceive(receiveEvent); // register event 19 | Serial.begin(9600); // start serial for output 20 | } 21 | 22 | void loop() 23 | { 24 | delay(100); 25 | } 26 | 27 | // function that executes whenever data is received from master 28 | // this function is registered as an event, see setup() 29 | void receiveEvent(int howMany) 30 | { 31 | while (1 < Wire.available()) // loop through all but the last 32 | { 33 | char c = Wire.read(); // receive byte as a character 34 | Serial.print(c); // print the character 35 | } 36 | int x = Wire.read(); // receive byte as an integer 37 | Serial.println(x); // print the integer 38 | } 39 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/new.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include 20 | 21 | void *operator new(size_t size) { 22 | return malloc(size); 23 | } 24 | 25 | void *operator new[](size_t size) { 26 | return malloc(size); 27 | } 28 | 29 | void operator delete(void * ptr) { 30 | free(ptr); 31 | } 32 | 33 | void operator delete[](void * ptr) { 34 | free(ptr); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OpenPLC 2 | ======== 3 | 4 | * OpenPLC is an effort to implement a robust and industry standard PLC 5 | (Programmable Logic Controller) keeping in the spirit of Open Source 6 | Hardware (OSHW) and Free and Open Source Software (FOSS). OpenPLC builds 7 | upon the Arduino platform. 8 | 9 | * For more details on OpenPLC visit the website http://openplcproject.com 10 | 11 | * Arduino is an open-source physical computing platform based on a simple i/o 12 | board and a development environment that implements the Processing/Wiring 13 | language. Arduino can be used to develop stand-alone interactive objects or 14 | can be connected to software on your computer (e.g. Flash, Processing, MaxMSP). 15 | The boards can be assembled by hand or purchased preassembled; the open-source 16 | IDE can be downloaded for free. 17 | 18 | * For more information, see the website at: http://www.arduino.cc/ 19 | or the forums at: http://arduino.cc/forum/ 20 | 21 | Usage 22 | ------------ 23 | You can copy this hardware folder to your sketchbook to add support for OpenPLC boards. 24 | As of now (Sept, 2014), there is basic support for writing sketches for OpenPLC main boards. 25 | In future OpenPLC Mini boards shall be added too. 26 | 27 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/hooks.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | /** 20 | * Empty yield() hook. 21 | * 22 | * This function is intended to be used by library writers to build 23 | * libraries or sketches that supports cooperative threads. 24 | * 25 | * Its defined as a weak symbol and it can be redefined to implement a 26 | * real cooperative scheduler. 27 | */ 28 | static void __empty() { 29 | // Empty 30 | } 31 | void yield(void) __attribute__ ((weak, alias("__empty"))); 32 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/abi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include 20 | 21 | extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); 22 | extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); 23 | 24 | void __cxa_pure_virtual(void) { 25 | // We might want to write some diagnostics to uart in this case 26 | //std::terminate(); 27 | abort(); 28 | } 29 | 30 | void __cxa_deleted_virtual(void) { 31 | // We might want to write some diagnostics to uart in this case 32 | //std::terminate(); 33 | abort(); 34 | } 35 | 36 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/Printable.h: -------------------------------------------------------------------------------- 1 | /* 2 | Printable.h - Interface class that allows printing of complex types 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Printable_h 21 | #define Printable_h 22 | 23 | #include 24 | 25 | class Print; 26 | 27 | /** The Printable class provides a way for new classes to allow themselves to be printed. 28 | By deriving from Printable and implementing the printTo method, it will then be possible 29 | for users to print out instances of this class by passing them into the usual 30 | Print::print and Print::println methods. 31 | */ 32 | 33 | class Printable 34 | { 35 | public: 36 | virtual size_t printTo(Print& p) const = 0; 37 | }; 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | main.cpp - Main loop for Arduino sketches 3 | Copyright (c) 2005-2013 Arduino Team. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | 22 | //Declared weak in Arduino.h to allow user redefinitions. 23 | int atexit(void (*func)()) { return 0; } 24 | 25 | // Weak empty variant initialization function. 26 | // May be redefined by variant files. 27 | void initVariant() __attribute__((weak)); 28 | void initVariant() { } 29 | 30 | int main(void) 31 | { 32 | init(); 33 | 34 | initVariant(); 35 | 36 | #if defined(USBCON) 37 | USBDevice.attach(); 38 | #endif 39 | 40 | setup(); 41 | 42 | for (;;) { 43 | loop(); 44 | if (serialEventRun) serialEventRun(); 45 | } 46 | 47 | return 0; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Software serial multple serial test 3 | 4 | Receives from the hardware serial, sends to software serial. 5 | Receives from software serial, sends to hardware serial. 6 | 7 | The circuit: 8 | * RX is digital pin 10 (connect to TX of other device) 9 | * TX is digital pin 11 (connect to RX of other device) 10 | 11 | Note: 12 | Not all pins on the Mega and Mega 2560 support change interrupts, 13 | so only the following can be used for RX: 14 | 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 15 | 16 | Not all pins on the Leonardo support change interrupts, 17 | so only the following can be used for RX: 18 | 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI). 19 | 20 | created back in the mists of time 21 | modified 25 May 2012 22 | by Tom Igoe 23 | based on Mikal Hart's example 24 | 25 | This example code is in the public domain. 26 | 27 | */ 28 | #include 29 | 30 | SoftwareSerial mySerial(10, 11); // RX, TX 31 | 32 | void setup() 33 | { 34 | // Open serial communications and wait for port to open: 35 | Serial.begin(57600); 36 | while (!Serial) { 37 | ; // wait for serial port to connect. Needed for Leonardo only 38 | } 39 | 40 | 41 | Serial.println("Goodnight moon!"); 42 | 43 | // set the data rate for the SoftwareSerial port 44 | mySerial.begin(4800); 45 | mySerial.println("Hello, world?"); 46 | } 47 | 48 | void loop() // run over and over 49 | { 50 | if (mySerial.available()) 51 | Serial.write(mySerial.read()); 52 | if (Serial.available()) 53 | mySerial.write(Serial.read()); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/Client.h: -------------------------------------------------------------------------------- 1 | /* 2 | Client.h - Base class that provides Client 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef client_h 21 | #define client_h 22 | #include "Print.h" 23 | #include "Stream.h" 24 | #include "IPAddress.h" 25 | 26 | class Client : public Stream { 27 | 28 | public: 29 | virtual int connect(IPAddress ip, uint16_t port) =0; 30 | virtual int connect(const char *host, uint16_t port) =0; 31 | virtual size_t write(uint8_t) =0; 32 | virtual size_t write(const uint8_t *buf, size_t size) =0; 33 | virtual int available() = 0; 34 | virtual int read() = 0; 35 | virtual int read(uint8_t *buf, size_t size) = 0; 36 | virtual int peek() = 0; 37 | virtual void flush() = 0; 38 | virtual void stop() = 0; 39 | virtual uint8_t connected() = 0; 40 | virtual operator bool() = 0; 41 | protected: 42 | uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/Wire/utility/twi.h: -------------------------------------------------------------------------------- 1 | /* 2 | twi.h - TWI/I2C library for Wiring & Arduino 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef twi_h 21 | #define twi_h 22 | 23 | #include 24 | 25 | //#define ATMEGA8 26 | 27 | #ifndef TWI_FREQ 28 | #define TWI_FREQ 100000L 29 | #endif 30 | 31 | #ifndef TWI_BUFFER_LENGTH 32 | #define TWI_BUFFER_LENGTH 32 33 | #endif 34 | 35 | #define TWI_READY 0 36 | #define TWI_MRX 1 37 | #define TWI_MTX 2 38 | #define TWI_SRX 3 39 | #define TWI_STX 4 40 | 41 | void twi_init(void); 42 | void twi_setAddress(uint8_t); 43 | uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t); 44 | uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); 45 | uint8_t twi_transmit(const uint8_t*, uint8_t); 46 | void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); 47 | void twi_attachSlaveTxEvent( void (*)(void) ); 48 | void twi_reply(uint8_t); 49 | void twi_stop(void); 50 | void twi_releaseBus(void); 51 | 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/wiring_shift.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_shift.c - shiftOut() function 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | 22 | $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ 23 | */ 24 | 25 | #include "wiring_private.h" 26 | 27 | uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) { 28 | uint8_t value = 0; 29 | uint8_t i; 30 | 31 | for (i = 0; i < 8; ++i) { 32 | digitalWrite(clockPin, HIGH); 33 | if (bitOrder == LSBFIRST) 34 | value |= digitalRead(dataPin) << i; 35 | else 36 | value |= digitalRead(dataPin) << (7 - i); 37 | digitalWrite(clockPin, LOW); 38 | } 39 | return value; 40 | } 41 | 42 | void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) 43 | { 44 | uint8_t i; 45 | 46 | for (i = 0; i < 8; i++) { 47 | if (bitOrder == LSBFIRST) 48 | digitalWrite(dataPin, !!(val & (1 << i))); 49 | else 50 | digitalWrite(dataPin, !!(val & (1 << (7 - i)))); 51 | 52 | digitalWrite(clockPin, HIGH); 53 | digitalWrite(clockPin, LOW); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/WMath.cpp: -------------------------------------------------------------------------------- 1 | /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 | 3 | /* 4 | Part of the Wiring project - http://wiring.org.co 5 | Copyright (c) 2004-06 Hernando Barragan 6 | Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/ 7 | 8 | This library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU Lesser General Public 10 | License as published by the Free Software Foundation; either 11 | version 2.1 of the License, or (at your option) any later version. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General 19 | Public License along with this library; if not, write to the 20 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 21 | Boston, MA 02111-1307 USA 22 | 23 | $Id$ 24 | */ 25 | 26 | extern "C" { 27 | #include "stdlib.h" 28 | } 29 | 30 | void randomSeed(unsigned int seed) 31 | { 32 | if (seed != 0) { 33 | srandom(seed); 34 | } 35 | } 36 | 37 | long random(long howbig) 38 | { 39 | if (howbig == 0) { 40 | return 0; 41 | } 42 | return random() % howbig; 43 | } 44 | 45 | long random(long howsmall, long howbig) 46 | { 47 | if (howsmall >= howbig) { 48 | return howsmall; 49 | } 50 | long diff = howbig - howsmall; 51 | return random(diff) + howsmall; 52 | } 53 | 54 | long map(long x, long in_min, long in_max, long out_min, long out_max) 55 | { 56 | return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 57 | } 58 | 59 | unsigned int makeWord(unsigned int w) { return w; } 60 | unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; } -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/EEPROM/EEPROM.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | EEPROM.cpp - EEPROM library 3 | Copyright (c) 2006 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | /****************************************************************************** 21 | * Includes 22 | ******************************************************************************/ 23 | 24 | #include 25 | #include "Arduino.h" 26 | #include "EEPROM.h" 27 | 28 | /****************************************************************************** 29 | * Definitions 30 | ******************************************************************************/ 31 | 32 | /****************************************************************************** 33 | * Constructors 34 | ******************************************************************************/ 35 | 36 | /****************************************************************************** 37 | * User API 38 | ******************************************************************************/ 39 | 40 | uint8_t EEPROMClass::read(int address) 41 | { 42 | return eeprom_read_byte((unsigned char *) address); 43 | } 44 | 45 | void EEPROMClass::write(int address, uint8_t value) 46 | { 47 | eeprom_write_byte((unsigned char *) address, value); 48 | } 49 | 50 | EEPROMClass EEPROM; 51 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/OpenPLC/Globals.h: -------------------------------------------------------------------------------- 1 | //global variables 2 | boolean newMessage = false; //new message flag 3 | char message[100]; //serial message buffer 4 | int messageIndex = 0; //serial message buffer index 5 | 6 | //system variables 7 | boolean input_card_address[8] = {false, false, false, false, false, false, false, false}; //address of each input card connected. false means no card connected 8 | boolean output_card_address[8] = {false, false, false, false, false, false, false, false}; //address of each output card connected. false means no card connected 9 | //special function variables 10 | boolean first_cycle = true; 11 | boolean toggle_30s = false; 12 | boolean toggle_500ms = false; 13 | boolean toggle_50ms = false; 14 | int system_timer = 0; 15 | char PLCstatus; //status of the actual state of the OpenPLC 16 | int errorCount = 0; 17 | long lastError = 0; 18 | 19 | Mudbus modbus; //create the modbus object 20 | 21 | /************************************************* 22 | * LOCAL INPUT/OUTPUT BUFFERS * 23 | * * 24 | * These buffers store the value of the input and * 25 | * output read from the cards. During the PLC * 26 | * cycle, all input cards' values are read and * 27 | * stored inside inputVector. After that, the * 28 | * Ladder programm is processed and then the * 29 | * result is stored inside the outputVector. At * 30 | * the end of the PLC cycle, the values stored in * 31 | * the outputVector are sent to the output cards. * 32 | ************************************************** 33 | */ 34 | boolean inputVector[64] = { 35 | 0, 0, 0, 0, 0, 0, 0, 0, 36 | 0, 0, 0, 0, 0, 0, 0, 0, 37 | 0, 0, 0, 0, 0, 0, 0, 0, 38 | 0, 0, 0, 0, 0, 0, 0, 0, 39 | 0, 0, 0, 0, 0, 0, 0, 0, 40 | 0, 0, 0, 0, 0, 0, 0, 0, 41 | 0, 0, 0, 0, 0, 0, 0, 0, 42 | 0, 0, 0, 0, 0, 0, 0, 0 43 | }; 44 | boolean outputVector[64] = { 45 | 0, 0, 0, 0, 0, 0, 0, 0, 46 | 0, 0, 0, 0, 0, 0, 0, 0, 47 | 0, 0, 0, 0, 0, 0, 0, 0, 48 | 0, 0, 0, 0, 0, 0, 0, 0, 49 | 0, 0, 0, 0, 0, 0, 0, 0, 50 | 0, 0, 0, 0, 0, 0, 0, 0, 51 | 0, 0, 0, 0, 0, 0, 0, 0, 52 | 0, 0, 0, 0, 0, 0, 0, 0 53 | }; -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/USBDesc.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* Copyright (c) 2011, Peter Barrett 4 | ** 5 | ** Permission to use, copy, modify, and/or distribute this software for 6 | ** any purpose with or without fee is hereby granted, provided that the 7 | ** above copyright notice and this permission notice appear in all copies. 8 | ** 9 | ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 12 | ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES 13 | ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 14 | ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 15 | ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 16 | ** SOFTWARE. 17 | */ 18 | 19 | #define CDC_ENABLED 20 | #define HID_ENABLED 21 | 22 | 23 | #ifdef CDC_ENABLED 24 | #define CDC_INTERFACE_COUNT 2 25 | #define CDC_ENPOINT_COUNT 3 26 | #else 27 | #define CDC_INTERFACE_COUNT 0 28 | #define CDC_ENPOINT_COUNT 0 29 | #endif 30 | 31 | #ifdef HID_ENABLED 32 | #define HID_INTERFACE_COUNT 1 33 | #define HID_ENPOINT_COUNT 1 34 | #else 35 | #define HID_INTERFACE_COUNT 0 36 | #define HID_ENPOINT_COUNT 0 37 | #endif 38 | 39 | #define CDC_ACM_INTERFACE 0 // CDC ACM 40 | #define CDC_DATA_INTERFACE 1 // CDC Data 41 | #define CDC_FIRST_ENDPOINT 1 42 | #define CDC_ENDPOINT_ACM (CDC_FIRST_ENDPOINT) // CDC First 43 | #define CDC_ENDPOINT_OUT (CDC_FIRST_ENDPOINT+1) 44 | #define CDC_ENDPOINT_IN (CDC_FIRST_ENDPOINT+2) 45 | 46 | #define HID_INTERFACE (CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT) // HID Interface 47 | #define HID_FIRST_ENDPOINT (CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT) 48 | #define HID_ENDPOINT_INT (HID_FIRST_ENDPOINT) 49 | 50 | #define INTERFACE_COUNT (MSC_INTERFACE + MSC_INTERFACE_COUNT) 51 | 52 | #ifdef CDC_ENABLED 53 | #define CDC_RX CDC_ENDPOINT_OUT 54 | #define CDC_TX CDC_ENDPOINT_IN 55 | #endif 56 | 57 | #ifdef HID_ENABLED 58 | #define HID_TX HID_ENDPOINT_INT 59 | #endif 60 | 61 | #define IMANUFACTURER 1 62 | #define IPRODUCT 2 63 | 64 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/HardwareSerial2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial2.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "HardwareSerial.h" 27 | #include "HardwareSerial_private.h" 28 | 29 | // Each HardwareSerial is defined in its own file, sine the linker pulls 30 | // in the entire file when any element inside is used. --gc-sections can 31 | // additionally cause unused symbols to be dropped, but ISRs have the 32 | // "used" attribute so are never dropped and they keep the 33 | // HardwareSerial instance in as well. Putting each instance in its own 34 | // file prevents the linker from pulling in any unused instances in the 35 | // first place. 36 | 37 | #if defined(HAVE_HWSERIAL2) 38 | 39 | ISR(USART2_RX_vect) 40 | { 41 | Serial2._rx_complete_irq(); 42 | } 43 | 44 | ISR(USART2_UDRE_vect) 45 | { 46 | Serial2._tx_udr_empty_irq(); 47 | } 48 | 49 | HardwareSerial Serial2(&UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UCSR2C, &UDR2); 50 | 51 | // Function that can be weakly referenced by serialEventRun to prevent 52 | // pulling in this file if it's not otherwise used. 53 | bool Serial2_available() { 54 | return Serial2.available(); 55 | } 56 | 57 | #endif // HAVE_HWSERIAL2 58 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/HardwareSerial3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial3.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "HardwareSerial.h" 27 | #include "HardwareSerial_private.h" 28 | 29 | // Each HardwareSerial is defined in its own file, sine the linker pulls 30 | // in the entire file when any element inside is used. --gc-sections can 31 | // additionally cause unused symbols to be dropped, but ISRs have the 32 | // "used" attribute so are never dropped and they keep the 33 | // HardwareSerial instance in as well. Putting each instance in its own 34 | // file prevents the linker from pulling in any unused instances in the 35 | // first place. 36 | 37 | #if defined(HAVE_HWSERIAL3) 38 | 39 | ISR(USART3_RX_vect) 40 | { 41 | Serial3._rx_complete_irq(); 42 | } 43 | 44 | ISR(USART3_UDRE_vect) 45 | { 46 | Serial3._tx_udr_empty_irq(); 47 | } 48 | 49 | HardwareSerial Serial3(&UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UCSR3C, &UDR3); 50 | 51 | // Function that can be weakly referenced by serialEventRun to prevent 52 | // pulling in this file if it's not otherwise used. 53 | bool Serial3_available() { 54 | return Serial3.available(); 55 | } 56 | 57 | #endif // HAVE_HWSERIAL3 58 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Digital Pot Control 3 | 4 | This example controls an Analog Devices AD5206 digital potentiometer. 5 | The AD5206 has 6 potentiometer channels. Each channel's pins are labeled 6 | A - connect this to voltage 7 | W - this is the pot's wiper, which changes when you set it 8 | B - connect this to ground. 9 | 10 | The AD5206 is SPI-compatible,and to command it, you send two bytes, 11 | one with the channel number (0 - 5) and one with the resistance value for the 12 | channel (0 - 255). 13 | 14 | The circuit: 15 | * All A pins of AD5206 connected to +5V 16 | * All B pins of AD5206 connected to ground 17 | * An LED and a 220-ohm resisor in series connected from each W pin to ground 18 | * CS - to digital pin 10 (SS pin) 19 | * SDI - to digital pin 11 (MOSI pin) 20 | * CLK - to digital pin 13 (SCK pin) 21 | 22 | created 10 Aug 2010 23 | by Tom Igoe 24 | 25 | Thanks to Heather Dewey-Hagborg for the original tutorial, 2005 26 | 27 | */ 28 | 29 | 30 | // inslude the SPI library: 31 | #include 32 | 33 | 34 | // set pin 10 as the slave select for the digital pot: 35 | const int slaveSelectPin = 10; 36 | 37 | void setup() { 38 | // set the slaveSelectPin as an output: 39 | pinMode (slaveSelectPin, OUTPUT); 40 | // initialize SPI: 41 | SPI.begin(); 42 | } 43 | 44 | void loop() { 45 | // go through the six channels of the digital pot: 46 | for (int channel = 0; channel < 6; channel++) { 47 | // change the resistance on this channel from min to max: 48 | for (int level = 0; level < 255; level++) { 49 | digitalPotWrite(channel, level); 50 | delay(10); 51 | } 52 | // wait a second at the top: 53 | delay(100); 54 | // change the resistance on this channel from max to min: 55 | for (int level = 0; level < 255; level++) { 56 | digitalPotWrite(channel, 255 - level); 57 | delay(10); 58 | } 59 | } 60 | 61 | } 62 | 63 | void digitalPotWrite(int address, int value) { 64 | // take the SS pin low to select the chip: 65 | digitalWrite(slaveSelectPin, LOW); 66 | // send in the address and value via SPI: 67 | SPI.transfer(address); 68 | SPI.transfer(value); 69 | // take the SS pin high to de-select the chip: 70 | digitalWrite(slaveSelectPin, HIGH); 71 | } 72 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/IPAddress.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | IPAddress.cpp - Base class that provides IPAddress 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | IPAddress::IPAddress() 24 | { 25 | _address.dword = 0; 26 | } 27 | 28 | IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) 29 | { 30 | _address.bytes[0] = first_octet; 31 | _address.bytes[1] = second_octet; 32 | _address.bytes[2] = third_octet; 33 | _address.bytes[3] = fourth_octet; 34 | } 35 | 36 | IPAddress::IPAddress(uint32_t address) 37 | { 38 | _address.dword = address; 39 | } 40 | 41 | IPAddress::IPAddress(const uint8_t *address) 42 | { 43 | memcpy(_address.bytes, address, sizeof(_address.bytes)); 44 | } 45 | 46 | IPAddress& IPAddress::operator=(const uint8_t *address) 47 | { 48 | memcpy(_address.bytes, address, sizeof(_address.bytes)); 49 | return *this; 50 | } 51 | 52 | IPAddress& IPAddress::operator=(uint32_t address) 53 | { 54 | _address.dword = address; 55 | return *this; 56 | } 57 | 58 | bool IPAddress::operator==(const uint8_t* addr) const 59 | { 60 | return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0; 61 | } 62 | 63 | size_t IPAddress::printTo(Print& p) const 64 | { 65 | size_t n = 0; 66 | for (int i =0; i < 3; i++) 67 | { 68 | n += p.print(_address.bytes[i], DEC); 69 | n += p.print('.'); 70 | } 71 | n += p.print(_address.bytes[3], DEC); 72 | return n; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/wiring_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_private.h - Internal header file. 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | 22 | $Id: wiring.h 239 2007-01-12 17:58:39Z mellis $ 23 | */ 24 | 25 | #ifndef WiringPrivate_h 26 | #define WiringPrivate_h 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "Arduino.h" 34 | 35 | #ifdef __cplusplus 36 | extern "C"{ 37 | #endif 38 | 39 | #ifndef cbi 40 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 41 | #endif 42 | #ifndef sbi 43 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 44 | #endif 45 | 46 | #define EXTERNAL_INT_0 0 47 | #define EXTERNAL_INT_1 1 48 | #define EXTERNAL_INT_2 2 49 | #define EXTERNAL_INT_3 3 50 | #define EXTERNAL_INT_4 4 51 | #define EXTERNAL_INT_5 5 52 | #define EXTERNAL_INT_6 6 53 | #define EXTERNAL_INT_7 7 54 | 55 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__) 56 | #define EXTERNAL_NUM_INTERRUPTS 8 57 | #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) 58 | #define EXTERNAL_NUM_INTERRUPTS 3 59 | #elif defined(__AVR_ATmega32U4__) 60 | #define EXTERNAL_NUM_INTERRUPTS 5 61 | #else 62 | #define EXTERNAL_NUM_INTERRUPTS 2 63 | #endif 64 | 65 | typedef void (*voidFuncPtr)(void); 66 | 67 | #ifdef __cplusplus 68 | } // extern "C" 69 | #endif 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/HardwareSerial1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial1.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "HardwareSerial.h" 27 | #include "HardwareSerial_private.h" 28 | 29 | // Each HardwareSerial is defined in its own file, sine the linker pulls 30 | // in the entire file when any element inside is used. --gc-sections can 31 | // additionally cause unused symbols to be dropped, but ISRs have the 32 | // "used" attribute so are never dropped and they keep the 33 | // HardwareSerial instance in as well. Putting each instance in its own 34 | // file prevents the linker from pulling in any unused instances in the 35 | // first place. 36 | 37 | #if defined(HAVE_HWSERIAL1) 38 | 39 | #if defined(UART1_RX_vect) 40 | ISR(UART1_RX_vect) 41 | #elif defined(USART1_RX_vect) 42 | ISR(USART1_RX_vect) 43 | #else 44 | #error "Don't know what the Data Register Empty vector is called for Serial1" 45 | #endif 46 | { 47 | Serial1._rx_complete_irq(); 48 | } 49 | 50 | #if defined(UART1_UDRE_vect) 51 | ISR(UART1_UDRE_vect) 52 | #elif defined(USART1_UDRE_vect) 53 | ISR(USART1_UDRE_vect) 54 | #else 55 | #error "Don't know what the Data Register Empty vector is called for Serial1" 56 | #endif 57 | { 58 | Serial1._tx_udr_empty_irq(); 59 | } 60 | 61 | HardwareSerial Serial1(&UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1); 62 | 63 | // Function that can be weakly referenced by serialEventRun to prevent 64 | // pulling in this file if it's not otherwise used. 65 | bool Serial1_available() { 66 | return Serial1.available(); 67 | } 68 | 69 | #endif // HAVE_HWSERIAL1 70 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/OpenPLC/Prototypes.h: -------------------------------------------------------------------------------- 1 | /***************************************************** 2 | * PROTOTYPE DEFINITIONS * 3 | * * 4 | * This file defines the function prototypes used * 5 | * on the OpenPLC library * 6 | * * 7 | ***************************************************** 8 | */ 9 | 10 | //Cards_Comm.h 11 | void clearOutputs(void); //certify that all outputs are turned off 12 | void updateInput(void); //read inputs of each input card connected and update the local input buffer 13 | void updateOutput(void); //set outputs of each output card connected according to the local output buffer 14 | void checkSlots(void); //search for cards connected on each slot 15 | void checkCard(void); //check to see how many boards are connected to the system 16 | 17 | //OpenPLC.cpp 18 | void ModbusInit(void); //initialize the modbus functions 19 | void ModbusCycle(void); //check to see if new modbus messages are received and process them 20 | void OpenPLCcycle(void); //read inputs, process them according to the ladder software and set outputs 21 | void readPLCSwitch(void); //read the switch to determine the PLC status 22 | void setStatusLeds(void); //set the leds according to PLC status 23 | int readInput(int input); //return the value of the specified input according to the local input buffer 24 | int readOutput(int output); //return the value of the specified output according to the local output buffer 25 | int setOutput(int output, boolean state); //set or clear the value of the specified output in the local output buffer 26 | void PLCInit(void); //initialize plc functions 27 | 28 | //OPLC_Protocol.h 29 | void OPLC_send(byte dataSize, byte function, byte address, byte * data); //send a message over the OPLC Protocol 30 | boolean OPLC_receive(byte * dataSize, byte * function, byte * data); //receive a message over the OPLC Protocol 31 | 32 | //PC_Comm.h 33 | void showInfo(void); //show information about the PLC over Serial Port when requested 34 | void newValue(int startAddress); //change the value of the IP Addres, Subnet Mask or Gateway 35 | void newMAC(void); //change the MAC address 36 | void newAddress(void); //change one of the cards address 37 | void restoreOriginal(void); //restore all information to factory-default 38 | void CheckSerial(void); //check to see if any message was received over Serial Port 39 | void ProcessMessage(void); //process any received message 40 | 41 | //Special_functions.h 42 | boolean SF_01(void); 43 | boolean SF_02(void); 44 | boolean SF_03(void); 45 | boolean SF_04(void); 46 | boolean SF_05(void); 47 | boolean SF_06(void); 48 | void countTimers(void); -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/Wire/Wire.h: -------------------------------------------------------------------------------- 1 | /* 2 | TwoWire.h - TWI/I2C library for Arduino & Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 20 | */ 21 | 22 | #ifndef TwoWire_h 23 | #define TwoWire_h 24 | 25 | #include 26 | #include "Stream.h" 27 | 28 | #define BUFFER_LENGTH 32 29 | 30 | class TwoWire : public Stream 31 | { 32 | private: 33 | static uint8_t rxBuffer[]; 34 | static uint8_t rxBufferIndex; 35 | static uint8_t rxBufferLength; 36 | 37 | static uint8_t txAddress; 38 | static uint8_t txBuffer[]; 39 | static uint8_t txBufferIndex; 40 | static uint8_t txBufferLength; 41 | 42 | static uint8_t transmitting; 43 | static void (*user_onRequest)(void); 44 | static void (*user_onReceive)(int); 45 | static void onRequestService(void); 46 | static void onReceiveService(uint8_t*, int); 47 | public: 48 | TwoWire(); 49 | void begin(); 50 | void begin(uint8_t); 51 | void begin(int); 52 | void setClock(uint32_t); 53 | void beginTransmission(uint8_t); 54 | void beginTransmission(int); 55 | uint8_t endTransmission(void); 56 | uint8_t endTransmission(uint8_t); 57 | uint8_t requestFrom(uint8_t, uint8_t); 58 | uint8_t requestFrom(uint8_t, uint8_t, uint8_t); 59 | uint8_t requestFrom(int, int); 60 | uint8_t requestFrom(int, int, int); 61 | virtual size_t write(uint8_t); 62 | virtual size_t write(const uint8_t *, size_t); 63 | virtual int available(void); 64 | virtual int read(void); 65 | virtual int peek(void); 66 | virtual void flush(void); 67 | void onReceive( void (*)(int) ); 68 | void onRequest( void (*)(void) ); 69 | 70 | inline size_t write(unsigned long n) { return write((uint8_t)n); } 71 | inline size_t write(long n) { return write((uint8_t)n); } 72 | inline size_t write(unsigned int n) { return write((uint8_t)n); } 73 | inline size_t write(int n) { return write((uint8_t)n); } 74 | using Print::write; 75 | }; 76 | 77 | extern TwoWire Wire; 78 | 79 | #endif 80 | 81 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/wiring_pulse.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_pulse.c - pulseIn() function 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | 22 | $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ 23 | */ 24 | 25 | #include "wiring_private.h" 26 | #include "pins_arduino.h" 27 | 28 | /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH 29 | * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds 30 | * to 3 minutes in length, but must be called at least a few dozen microseconds 31 | * before the start of the pulse. */ 32 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) 33 | { 34 | // cache the port and bit of the pin in order to speed up the 35 | // pulse width measuring loop and achieve finer resolution. calling 36 | // digitalRead() instead yields much coarser resolution. 37 | uint8_t bit = digitalPinToBitMask(pin); 38 | uint8_t port = digitalPinToPort(pin); 39 | uint8_t stateMask = (state ? bit : 0); 40 | unsigned long width = 0; // keep initialization out of time critical area 41 | 42 | // convert the timeout from microseconds to a number of times through 43 | // the initial loop; it takes 16 clock cycles per iteration. 44 | unsigned long numloops = 0; 45 | unsigned long maxloops = microsecondsToClockCycles(timeout) / 16; 46 | 47 | // wait for any previous pulse to end 48 | while ((*portInputRegister(port) & bit) == stateMask) 49 | if (numloops++ == maxloops) 50 | return 0; 51 | 52 | // wait for the pulse to start 53 | while ((*portInputRegister(port) & bit) != stateMask) 54 | if (numloops++ == maxloops) 55 | return 0; 56 | 57 | // wait for the pulse to stop 58 | while ((*portInputRegister(port) & bit) == stateMask) { 59 | if (numloops++ == maxloops) 60 | return 0; 61 | width++; 62 | } 63 | 64 | // convert the reading to microseconds. The loop has been determined 65 | // to be 20 clock cycles long and have about 16 clocks between the edge 66 | // and the start of the loop. There will be some error introduced by 67 | // the interrupt handlers. 68 | return clockCyclesToMicroseconds(width * 21 + 16); 69 | } 70 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/HardwareSerial0.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial0.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "HardwareSerial.h" 27 | #include "HardwareSerial_private.h" 28 | 29 | // Each HardwareSerial is defined in its own file, sine the linker pulls 30 | // in the entire file when any element inside is used. --gc-sections can 31 | // additionally cause unused symbols to be dropped, but ISRs have the 32 | // "used" attribute so are never dropped and they keep the 33 | // HardwareSerial instance in as well. Putting each instance in its own 34 | // file prevents the linker from pulling in any unused instances in the 35 | // first place. 36 | 37 | #if defined(HAVE_HWSERIAL0) 38 | 39 | #if defined(USART_RX_vect) 40 | ISR(USART_RX_vect) 41 | #elif defined(USART0_RX_vect) 42 | ISR(USART0_RX_vect) 43 | #elif defined(USART_RXC_vect) 44 | ISR(USART_RXC_vect) // ATmega8 45 | #else 46 | #error "Don't know what the Data Received vector is called for Serial" 47 | #endif 48 | { 49 | Serial._rx_complete_irq(); 50 | } 51 | 52 | #if defined(UART0_UDRE_vect) 53 | ISR(UART0_UDRE_vect) 54 | #elif defined(UART_UDRE_vect) 55 | ISR(UART_UDRE_vect) 56 | #elif defined(USART0_UDRE_vect) 57 | ISR(USART0_UDRE_vect) 58 | #elif defined(USART_UDRE_vect) 59 | ISR(USART_UDRE_vect) 60 | #else 61 | #error "Don't know what the Data Register Empty vector is called for Serial" 62 | #endif 63 | { 64 | Serial._tx_udr_empty_irq(); 65 | } 66 | 67 | #if defined(UBRRH) && defined(UBRRL) 68 | HardwareSerial Serial(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR); 69 | #else 70 | HardwareSerial Serial(&UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0); 71 | #endif 72 | 73 | // Function that can be weakly referenced by serialEventRun to prevent 74 | // pulling in this file if it's not otherwise used. 75 | bool Serial0_available() { 76 | return Serial.available(); 77 | } 78 | 79 | #endif // HAVE_HWSERIAL0 80 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/Print.h: -------------------------------------------------------------------------------- 1 | /* 2 | Print.h - Base class that provides print() and println() 3 | Copyright (c) 2008 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Print_h 21 | #define Print_h 22 | 23 | #include 24 | #include // for size_t 25 | 26 | #include "WString.h" 27 | #include "Printable.h" 28 | 29 | #define DEC 10 30 | #define HEX 16 31 | #define OCT 8 32 | #define BIN 2 33 | 34 | class Print 35 | { 36 | private: 37 | int write_error; 38 | size_t printNumber(unsigned long, uint8_t); 39 | size_t printFloat(double, uint8_t); 40 | protected: 41 | void setWriteError(int err = 1) { write_error = err; } 42 | public: 43 | Print() : write_error(0) {} 44 | 45 | int getWriteError() { return write_error; } 46 | void clearWriteError() { setWriteError(0); } 47 | 48 | virtual size_t write(uint8_t) = 0; 49 | size_t write(const char *str) { 50 | if (str == NULL) return 0; 51 | return write((const uint8_t *)str, strlen(str)); 52 | } 53 | virtual size_t write(const uint8_t *buffer, size_t size); 54 | size_t write(const char *buffer, size_t size) { 55 | return write((const uint8_t *)buffer, size); 56 | } 57 | 58 | size_t print(const __FlashStringHelper *); 59 | size_t print(const String &); 60 | size_t print(const char[]); 61 | size_t print(char); 62 | size_t print(unsigned char, int = DEC); 63 | size_t print(int, int = DEC); 64 | size_t print(unsigned int, int = DEC); 65 | size_t print(long, int = DEC); 66 | size_t print(unsigned long, int = DEC); 67 | size_t print(double, int = 2); 68 | size_t print(const Printable&); 69 | 70 | size_t println(const __FlashStringHelper *); 71 | size_t println(const String &s); 72 | size_t println(const char[]); 73 | size_t println(char); 74 | size_t println(unsigned char, int = DEC); 75 | size_t println(int, int = DEC); 76 | size_t println(unsigned int, int = DEC); 77 | size_t println(long, int = DEC); 78 | size_t println(unsigned long, int = DEC); 79 | size_t println(double, int = 2); 80 | size_t println(const Printable&); 81 | size_t println(void); 82 | }; 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Software serial multple serial test 3 | 4 | Receives from the two software serial ports, 5 | sends to the hardware serial port. 6 | 7 | In order to listen on a software port, you call port.listen(). 8 | When using two software serial ports, you have to switch ports 9 | by listen()ing on each one in turn. Pick a logical time to switch 10 | ports, like the end of an expected transmission, or when the 11 | buffer is empty. This example switches ports when there is nothing 12 | more to read from a port 13 | 14 | The circuit: 15 | Two devices which communicate serially are needed. 16 | * First serial device's TX attached to digital pin 2, RX to pin 3 17 | * Second serial device's TX attached to digital pin 4, RX to pin 5 18 | 19 | Note: 20 | Not all pins on the Mega and Mega 2560 support change interrupts, 21 | so only the following can be used for RX: 22 | 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 23 | 24 | Not all pins on the Leonardo support change interrupts, 25 | so only the following can be used for RX: 26 | 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI). 27 | 28 | created 18 Apr. 2011 29 | modified 25 May 2012 30 | by Tom Igoe 31 | based on Mikal Hart's twoPortRXExample 32 | 33 | This example code is in the public domain. 34 | 35 | */ 36 | 37 | #include 38 | // software serial #1: TX = digital pin 10, RX = digital pin 11 39 | SoftwareSerial portOne(10, 11); 40 | 41 | // software serial #2: TX = digital pin 8, RX = digital pin 9 42 | // on the Mega, use other pins instead, since 8 and 9 don't work on the Mega 43 | SoftwareSerial portTwo(8, 9); 44 | 45 | void setup() 46 | { 47 | // Open serial communications and wait for port to open: 48 | Serial.begin(9600); 49 | while (!Serial) { 50 | ; // wait for serial port to connect. Needed for Leonardo only 51 | } 52 | 53 | 54 | // Start each software serial port 55 | portOne.begin(9600); 56 | portTwo.begin(9600); 57 | } 58 | 59 | void loop() 60 | { 61 | // By default, the last intialized port is listening. 62 | // when you want to listen on a port, explicitly select it: 63 | portOne.listen(); 64 | Serial.println("Data from port one:"); 65 | // while there is data coming in, read it 66 | // and send to the hardware serial port: 67 | while (portOne.available() > 0) { 68 | char inByte = portOne.read(); 69 | Serial.write(inByte); 70 | } 71 | 72 | // blank line to separate data from the two ports: 73 | Serial.println(); 74 | 75 | // Now listen on the second port 76 | portTwo.listen(); 77 | // while there is data coming in, read it 78 | // and send to the hardware serial port: 79 | Serial.println("Data from port two:"); 80 | while (portTwo.available() > 0) { 81 | char inByte = portTwo.read(); 82 | Serial.write(inByte); 83 | } 84 | 85 | // blank line to separate data from the two ports: 86 | Serial.println(); 87 | } 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/IPAddress.h: -------------------------------------------------------------------------------- 1 | /* 2 | IPAddress.h - Base class that provides IPAddress 3 | Copyright (c) 2011 Adrian McEwen. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef IPAddress_h 21 | #define IPAddress_h 22 | 23 | #include 24 | #include 25 | 26 | // A class to make it easier to handle and pass around IP addresses 27 | 28 | class IPAddress : public Printable { 29 | private: 30 | union { 31 | uint8_t bytes[4]; // IPv4 address 32 | uint32_t dword; 33 | } _address; 34 | 35 | // Access the raw byte array containing the address. Because this returns a pointer 36 | // to the internal structure rather than a copy of the address this function should only 37 | // be used when you know that the usage of the returned uint8_t* will be transient and not 38 | // stored. 39 | uint8_t* raw_address() { return _address.bytes; }; 40 | 41 | public: 42 | // Constructors 43 | IPAddress(); 44 | IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); 45 | IPAddress(uint32_t address); 46 | IPAddress(const uint8_t *address); 47 | 48 | // Overloaded cast operator to allow IPAddress objects to be used where a pointer 49 | // to a four-byte uint8_t array is expected 50 | operator uint32_t() const { return _address.dword; }; 51 | bool operator==(const IPAddress& addr) const { return _address.dword == addr._address.dword; }; 52 | bool operator==(const uint8_t* addr) const; 53 | 54 | // Overloaded index operator to allow getting and setting individual octets of the address 55 | uint8_t operator[](int index) const { return _address.bytes[index]; }; 56 | uint8_t& operator[](int index) { return _address.bytes[index]; }; 57 | 58 | // Overloaded copy operators to allow initialisation of IPAddress objects from other types 59 | IPAddress& operator=(const uint8_t *address); 60 | IPAddress& operator=(uint32_t address); 61 | 62 | virtual size_t printTo(Print& p) const; 63 | 64 | friend class EthernetClass; 65 | friend class UDP; 66 | friend class Client; 67 | friend class Server; 68 | friend class DhcpClass; 69 | friend class DNSClient; 70 | }; 71 | 72 | const IPAddress INADDR_NONE(0,0,0,0); 73 | 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino: -------------------------------------------------------------------------------- 1 | // I2C SRF10 or SRF08 Devantech Ultrasonic Ranger Finder 2 | // by Nicholas Zambetti 3 | // and James Tichenor 4 | 5 | // Demonstrates use of the Wire library reading data from the 6 | // Devantech Utrasonic Rangers SFR08 and SFR10 7 | 8 | // Created 29 April 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() 16 | { 17 | Wire.begin(); // join i2c bus (address optional for master) 18 | Serial.begin(9600); // start serial communication at 9600bps 19 | } 20 | 21 | int reading = 0; 22 | 23 | void loop() 24 | { 25 | // step 1: instruct sensor to read echoes 26 | Wire.beginTransmission(112); // transmit to device #112 (0x70) 27 | // the address specified in the datasheet is 224 (0xE0) 28 | // but i2c adressing uses the high 7 bits so it's 112 29 | Wire.write(byte(0x00)); // sets register pointer to the command register (0x00) 30 | Wire.write(byte(0x50)); // command sensor to measure in "inches" (0x50) 31 | // use 0x51 for centimeters 32 | // use 0x52 for ping microseconds 33 | Wire.endTransmission(); // stop transmitting 34 | 35 | // step 2: wait for readings to happen 36 | delay(70); // datasheet suggests at least 65 milliseconds 37 | 38 | // step 3: instruct sensor to return a particular echo reading 39 | Wire.beginTransmission(112); // transmit to device #112 40 | Wire.write(byte(0x02)); // sets register pointer to echo #1 register (0x02) 41 | Wire.endTransmission(); // stop transmitting 42 | 43 | // step 4: request reading from sensor 44 | Wire.requestFrom(112, 2); // request 2 bytes from slave device #112 45 | 46 | // step 5: receive reading from sensor 47 | if (2 <= Wire.available()) // if two bytes were received 48 | { 49 | reading = Wire.read(); // receive high byte (overwrites previous reading) 50 | reading = reading << 8; // shift high byte to be high 8 bits 51 | reading |= Wire.read(); // receive low byte as lower 8 bits 52 | Serial.println(reading); // print the reading 53 | } 54 | 55 | delay(250); // wait a bit since people have to read the output :) 56 | } 57 | 58 | 59 | /* 60 | 61 | // The following code changes the address of a Devantech Ultrasonic Range Finder (SRF10 or SRF08) 62 | // usage: changeAddress(0x70, 0xE6); 63 | 64 | void changeAddress(byte oldAddress, byte newAddress) 65 | { 66 | Wire.beginTransmission(oldAddress); 67 | Wire.write(byte(0x00)); 68 | Wire.write(byte(0xA0)); 69 | Wire.endTransmission(); 70 | 71 | Wire.beginTransmission(oldAddress); 72 | Wire.write(byte(0x00)); 73 | Wire.write(byte(0xAA)); 74 | Wire.endTransmission(); 75 | 76 | Wire.beginTransmission(oldAddress); 77 | Wire.write(byte(0x00)); 78 | Wire.write(byte(0xA5)); 79 | Wire.endTransmission(); 80 | 81 | Wire.beginTransmission(oldAddress); 82 | Wire.write(byte(0x00)); 83 | Wire.write(newAddress); 84 | Wire.endTransmission(); 85 | } 86 | 87 | */ 88 | -------------------------------------------------------------------------------- /hardware/openplc/avr/boards.txt: -------------------------------------------------------------------------------- 1 | # See: http://code.google.com/p/arduino/wiki/Platforms 2 | 3 | menu.cpu=Processor 4 | 5 | ############################################################## 6 | 7 | opinput.name=OpenPLC Input Card 8 | 9 | opinput.vid.0=0x2341 10 | opinput.pid.0=0x0043 11 | opinput.vid.1=0x2341 12 | opinput.pid.1=0x0001 13 | 14 | opinput.upload.tool=avrdude 15 | opinput.upload.protocol=arduino 16 | opinput.upload.maximum_size=32256 17 | opinput.upload.maximum_data_size=2048 18 | opinput.upload.speed=115200 19 | 20 | opinput.bootloader.tool=avrdude 21 | opinput.bootloader.low_fuses=0xFF 22 | opinput.bootloader.high_fuses=0xDE 23 | opinput.bootloader.extended_fuses=0x05 24 | opinput.bootloader.unlock_bits=0x3F 25 | opinput.bootloader.lock_bits=0x0F 26 | opinput.bootloader.file=optiboot/optiboot_atmega328.hex 27 | 28 | opinput.openplc.firmware=inputBoard/inputBoard.cpp.hex 29 | 30 | opinput.build.mcu=atmega328p 31 | opinput.build.f_cpu=16000000L 32 | opinput.build.board=AVR_UNO 33 | opinput.build.core=arduino 34 | opinput.build.variant=iocard 35 | 36 | ############################################################## 37 | 38 | 39 | opoutput.name=OpenPLC Output Card 40 | 41 | opoutput.vid.0=0x2341 42 | opoutput.pid.0=0x0043 43 | opoutput.vid.1=0x2341 44 | opoutput.pid.1=0x0001 45 | 46 | opoutput.upload.tool=avrdude 47 | opoutput.upload.protocol=arduino 48 | opoutput.upload.maximum_size=32256 49 | opoutput.upload.maximum_data_size=2048 50 | opoutput.upload.speed=115200 51 | 52 | opoutput.bootloader.tool=avrdude 53 | opoutput.bootloader.low_fuses=0xFF 54 | opoutput.bootloader.high_fuses=0xDE 55 | opoutput.bootloader.extended_fuses=0x05 56 | opoutput.bootloader.unlock_bits=0x3F 57 | opoutput.bootloader.lock_bits=0x0F 58 | opoutput.bootloader.file=optiboot/optiboot_atmega328.hex 59 | 60 | opinput.openplc.firmware=outputBoard/outputBoard.cpp.hex 61 | 62 | opoutput.build.mcu=atmega328p 63 | opoutput.build.f_cpu=16000000L 64 | opoutput.build.board=AVR_UNO 65 | opoutput.build.core=arduino 66 | opoutput.build.variant=iocard 67 | 68 | ############################################################## 69 | 70 | 71 | opmain.name=OpenPLC Main Card 72 | 73 | opmain.vid.0=0x2341 74 | opmain.pid.0=0x0010 75 | opmain.vid.1=0x2341 76 | opmain.pid.1=0x0042 77 | 78 | opmain.upload.tool=avrdude 79 | opmain.upload.maximum_data_size=8192 80 | 81 | opmain.bootloader.tool=avrdude 82 | opmain.bootloader.low_fuses=0xFF 83 | opmain.bootloader.unlock_bits=0x3F 84 | opmain.bootloader.lock_bits=0x0F 85 | 86 | opmain.build.f_cpu=16000000L 87 | opmain.build.core=arduino 88 | opmain.build.variant=cpucard 89 | # default board may be overridden by the cpu menu 90 | opmain.build.board=AVR_MEGA2560 91 | 92 | ## Arduino Mega w/ ATmega2560 93 | ## ------------------------- 94 | opmain.menu.cpu.atmega2560=ATMega 2560 95 | 96 | opmain.menu.cpu.atmega2560.upload.protocol=wiring 97 | opmain.menu.cpu.atmega2560.upload.maximum_size=253952 98 | opmain.menu.cpu.atmega2560.upload.speed=115200 99 | 100 | opmain.menu.cpu.atmega2560.bootloader.high_fuses=0xD8 101 | opmain.menu.cpu.atmega2560.bootloader.extended_fuses=0xFD 102 | opmain.menu.cpu.atmega2560.bootloader.file=stk500v2/stk500boot_v2_mega2560.hex 103 | 104 | opmain.menu.cpu.atmega2560.build.mcu=atmega2560 105 | opmain.menu.cpu.atmega2560.build.board=AVR_MEGA2560 106 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/Mudbus/Mudbus.h: -------------------------------------------------------------------------------- 1 | /* 2 | Mudbus.h - an Arduino library for a Modbus TCP slave. 3 | Copyright (C) 2011 Dee Wykoff 4 | Adaptations for the OpenPLC by Thiago Alves - OpenPLC Team 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | //#include "WProgram.h" 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #ifndef Mudbus_h 27 | #define Mudbus_h 28 | 29 | #define MB_N_R 125 //Max number of 16 bit registers for Modbus is 125 30 | #define MB_N_C 64 //Max number of coils for Modbus is 2000 - max number of coils for OpenPLC is 64 31 | #define MB_N_I 64 //Max number of discrete inputs 32 | #define MB_PORT 502 //definition of the Ethernet port for Modbus communication 33 | 34 | //Declaration of the supported modbus functions and the respective function code 35 | enum MB_FC { 36 | MB_FC_NONE = 0, 37 | MB_FC_READ_COILS = 1, 38 | MB_FC_READ_INPUTS = 2, //created by Thiago Alves for the OpenPLC Project 39 | MB_FC_READ_REGISTERS = 3, 40 | MB_FC_WRITE_COIL = 5, 41 | MB_FC_WRITE_REGISTER = 6, 42 | //Function codes 15 & 16 by Martin Pettersson http://siamect.com 43 | MB_FC_WRITE_MULTIPLE_COILS = 15, 44 | MB_FC_WRITE_MULTIPLE_REGISTERS = 16 45 | }; 46 | 47 | //definition of the Mudbus class 48 | class Mudbus 49 | { 50 | public: 51 | Mudbus(); //constructor 52 | void Run(); //this method must run in a loop 53 | int R[MB_N_R]; //array holding 16-bit registers values 54 | bool C[MB_N_C]; //array holding Coils state 55 | bool I[MB_N_I]; //array holding Inputs state 56 | //Controls for debug 57 | bool Active; 58 | unsigned long PreviousActivityTime; 59 | int Runs, Reads, Writes; 60 | private: 61 | uint8_t ByteArray[260]; //message received / sent 62 | MB_FC FC; //Function code received / sent 63 | void SetFC(int fc); //method to identify the function code received 64 | }; 65 | 66 | #endif 67 | 68 | /* Speculations on Modbus message structure: 69 | ********************************************** 70 | **********Master(PC) request frames*********** 71 | 00 ID high 0 72 | 01 ID low 1 73 | 02 Protocol high 0 74 | 03 Protocol low 0 75 | 04 Message length high 0 76 | 05 Message length low 6 (6 bytes after this) 77 | 06 Slave number 1 78 | 07 Function code 79 | 08 Start address high maybe 0 80 | 09 Start address low maybe 0 81 | 10 Length high maybe 125 or Data high if write 82 | 11 Length low maybe 125 or Data low if write 83 | ********************************************** 84 | **********Slave(Arduino) response frames****** 85 | 00 ID high echo / 0 86 | 01 ID low echo / slave ID 1 87 | 02 Protocol high echo 88 | 03 Protocol low echo 89 | 04 Message length high echo 90 | 05 Message length low num bytes after this 91 | 06 Slave number echo 92 | 07 Function code echo 93 | 08 Start address high num bytes of data 94 | 09 Data high 95 | 10 Data low 96 | ********************************************** 97 | */ 98 | -------------------------------------------------------------------------------- /hardware/openplc/avr/firmwares/inputBoard/inputBoard.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | //EEPROM data 4 | #define PROGRAMMED 0 5 | #define CARD_ADDRESS 1 6 | #define PROGRAMMED_VALUE 128 7 | 8 | //definition of slot id pins 9 | #define D0 A2 10 | #define D1 A0 11 | #define D2 A1 12 | 13 | //input pins definition 14 | #define X0 2 15 | #define X1 3 16 | #define X2 4 17 | #define X3 5 18 | #define X4 6 19 | #define X5 7 20 | #define X6 8 21 | #define X7 9 22 | 23 | //definition of the BUS Enable pin 24 | #define DE_PIN A5 25 | 26 | #include "OPLC_Protocol.h" 27 | 28 | byte dataSize, function, address, data[MAX_DATA_SIZE]; 29 | byte myAddress = 0x01; //default address 30 | 31 | int slotNumber = 0; 32 | 33 | void setup() 34 | { 35 | // initialize serial: 36 | Serial.begin(57600); 37 | //Serial.begin(115200); 38 | 39 | pinMode(DE_PIN, OUTPUT); 40 | 41 | // make the slot pins inputs: 42 | pinMode(D0, INPUT); 43 | pinMode(D1, INPUT); 44 | pinMode(D2, INPUT); 45 | //calculate slot number 46 | slotNumber = (4 * digitalRead(D2)) + (2 * digitalRead(D1)) + (1 * digitalRead(D0)); //get the slot number 47 | 48 | //setup inputs 49 | pinMode(X0, INPUT); 50 | pinMode(X1, INPUT); 51 | pinMode(X2, INPUT); 52 | pinMode(X3, INPUT); 53 | pinMode(X4, INPUT); 54 | pinMode(X5, INPUT); 55 | pinMode(X6, INPUT); 56 | pinMode(X7, INPUT); 57 | 58 | //verify if the address is already programmed 59 | if (EEPROM.read(PROGRAMMED) != PROGRAMMED_VALUE) //Blank EEPROM, must programm address on it for the first use 60 | { 61 | EEPROM.write(PROGRAMMED, PROGRAMMED_VALUE); //Sinalize that the EEPROM is now programmed 62 | EEPROM.write(CARD_ADDRESS, 0x01); //default card address 63 | } 64 | 65 | //read address 66 | myAddress = EEPROM.read(CARD_ADDRESS); 67 | } 68 | 69 | void loop() 70 | { 71 | if (OPLC_receive(&dataSize, &function, &address, data)) //if received something 72 | { 73 | switch (function) 74 | { 75 | case CARD_TYPE: 76 | sendCardType(); 77 | break; 78 | case CHANGE_ADDRESS: 79 | changeCardAddress(); 80 | break; 81 | case READ_INPUT: 82 | sendInput(); 83 | break; 84 | case MSG_ERROR: 85 | sendLastMsg(); 86 | break; 87 | default: 88 | //sendErrorMsg(); 89 | break; 90 | } 91 | } 92 | } 93 | 94 | void sendCardType() 95 | { 96 | if (address == slotNumber) //the message is for me 97 | { 98 | byte dataResponse[2] = { 99 | 0x01, //discrete input card 100 | myAddress //actual card address 101 | }; 102 | OPLC_send(2, CARD_TYPE, address, dataResponse); //dataSize, function, address, data 103 | } 104 | } 105 | 106 | void changeCardAddress() 107 | { 108 | if (address == slotNumber) 109 | { 110 | if (data[0] > 0 && data[0] < 9) //new address validation 111 | { 112 | EEPROM.write(CARD_ADDRESS, data[0]); //update eeprom 113 | myAddress = data[0]; //update local variable 114 | 115 | //return a confirmation message 116 | OPLC_send(1, CHANGE_ADDRESS, address, data); //dataSize, function, address, data 117 | } 118 | else 119 | { 120 | OPLC_send(0, MSG_ERROR, address, 0); //dataSize, function, address, data 121 | } 122 | } 123 | } 124 | 125 | void sendInput() 126 | { 127 | if (address == myAddress) 128 | { 129 | int a = 0, b = X0; //indexers 130 | byte dataResponse[1]; 131 | while (b <= X7) 132 | { 133 | bitWrite(dataResponse[0], a, digitalRead(b)); //writes 0 or 1 to a specific bit inside dataResponse[0] 134 | a++; 135 | b++; 136 | } 137 | OPLC_send(1, READ_INPUT, address, dataResponse); //dataSize, function, address, data 138 | } 139 | } 140 | 141 | void sendErrorMsg() 142 | { 143 | if (address == myAddress) 144 | { 145 | OPLC_send(0, MSG_ERROR, address, 0x00); //dataSize, function, address, data 146 | } 147 | } 148 | 149 | void sendLastMsg() 150 | { 151 | } 152 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/SoftwareSerial/SoftwareSerial.h: -------------------------------------------------------------------------------- 1 | /* 2 | SoftwareSerial.h (formerly NewSoftSerial.h) - 3 | Multi-instance software serial library for Arduino/Wiring 4 | -- Interrupt-driven receive and other improvements by ladyada 5 | (http://ladyada.net) 6 | -- Tuning, circular buffer, derivation from class Print/Stream, 7 | multi-instance support, porting to 8MHz processors, 8 | various optimizations, PROGMEM delay tables, inverse logic and 9 | direct port writing by Mikal Hart (http://www.arduiniana.org) 10 | -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) 11 | -- 20MHz processor support by Garrett Mace (http://www.macetech.com) 12 | -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/) 13 | 14 | This library is free software; you can redistribute it and/or 15 | modify it under the terms of the GNU Lesser General Public 16 | License as published by the Free Software Foundation; either 17 | version 2.1 of the License, or (at your option) any later version. 18 | 19 | This library is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 | Lesser General Public License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public 25 | License along with this library; if not, write to the Free Software 26 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 27 | 28 | The latest version of this library can always be found at 29 | http://arduiniana.org. 30 | */ 31 | 32 | #ifndef SoftwareSerial_h 33 | #define SoftwareSerial_h 34 | 35 | #include 36 | #include 37 | 38 | /****************************************************************************** 39 | * Definitions 40 | ******************************************************************************/ 41 | 42 | #define _SS_MAX_RX_BUFF 64 // RX buffer size 43 | #ifndef GCC_VERSION 44 | #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 45 | #endif 46 | 47 | class SoftwareSerial : public Stream 48 | { 49 | private: 50 | // per object data 51 | uint8_t _receivePin; 52 | uint8_t _receiveBitMask; 53 | volatile uint8_t *_receivePortRegister; 54 | uint8_t _transmitBitMask; 55 | volatile uint8_t *_transmitPortRegister; 56 | 57 | uint16_t _rx_delay_centering; 58 | uint16_t _rx_delay_intrabit; 59 | uint16_t _rx_delay_stopbit; 60 | uint16_t _tx_delay; 61 | 62 | uint16_t _buffer_overflow:1; 63 | uint16_t _inverse_logic:1; 64 | 65 | // static data 66 | static char _receive_buffer[_SS_MAX_RX_BUFF]; 67 | static volatile uint8_t _receive_buffer_tail; 68 | static volatile uint8_t _receive_buffer_head; 69 | static SoftwareSerial *active_object; 70 | 71 | // private methods 72 | void recv(); 73 | uint8_t rx_pin_read(); 74 | void tx_pin_write(uint8_t pin_state); 75 | void setTX(uint8_t transmitPin); 76 | void setRX(uint8_t receivePin); 77 | 78 | // private static method for timing 79 | static inline void tunedDelay(uint16_t delay); 80 | 81 | public: 82 | // public methods 83 | SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false); 84 | ~SoftwareSerial(); 85 | void begin(long speed); 86 | bool listen(); 87 | void end(); 88 | bool isListening() { return this == active_object; } 89 | bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; } 90 | int peek(); 91 | 92 | virtual size_t write(uint8_t byte); 93 | virtual int read(); 94 | virtual int available(); 95 | virtual void flush(); 96 | 97 | using Print::write; 98 | 99 | // public only for easy access by interrupt handlers 100 | static inline void handle_interrupt(); 101 | }; 102 | 103 | // Arduino 0012 workaround 104 | #undef int 105 | #undef char 106 | #undef long 107 | #undef byte 108 | #undef float 109 | #undef abs 110 | #undef round 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /hardware/openplc/avr/firmwares/outputBoard/outputBoard.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | //EEPROM data 4 | #define PROGRAMMED 0 5 | #define CARD_ADDRESS 1 6 | #define PROGRAMMED_VALUE 128 7 | 8 | //definition of slot id pins 9 | #define D0 A2 10 | #define D1 A0 11 | #define D2 A1 12 | 13 | //output pins definition 14 | #define Y0 2 15 | #define Y1 3 16 | #define Y2 4 17 | #define Y3 5 18 | #define Y4 6 19 | #define Y5 7 20 | #define Y6 8 21 | #define Y7 9 22 | 23 | //definition of the BUS Enable pin 24 | #define DE_PIN A5 25 | 26 | #include "OPLC_Protocol.h" 27 | 28 | byte dataSize, function, address, data[MAX_DATA_SIZE]; 29 | byte myAddress = 0x01; //default address 30 | 31 | int slotNumber = 0; 32 | 33 | void setup() 34 | { 35 | // initialize serial: 36 | Serial.begin(57600); 37 | //Serial.begin(115200); 38 | 39 | pinMode(DE_PIN, OUTPUT); 40 | 41 | // make the slot pins inputs: 42 | pinMode(D0, INPUT); 43 | pinMode(D1, INPUT); 44 | pinMode(D2, INPUT); 45 | //calculate slot number 46 | slotNumber = (4 * digitalRead(D2)) + (2 * digitalRead(D1)) + (1 * digitalRead(D0)); //get the slot number 47 | 48 | //setup outputs 49 | pinMode(Y0, OUTPUT); 50 | pinMode(Y1, OUTPUT); 51 | pinMode(Y2, OUTPUT); 52 | pinMode(Y3, OUTPUT); 53 | pinMode(Y4, OUTPUT); 54 | pinMode(Y5, OUTPUT); 55 | pinMode(Y6, OUTPUT); 56 | pinMode(Y7, OUTPUT); 57 | 58 | //set outputs for the first time 59 | digitalWrite(Y0, HIGH); 60 | digitalWrite(Y1, HIGH); 61 | digitalWrite(Y2, HIGH); 62 | digitalWrite(Y3, HIGH); 63 | digitalWrite(Y4, HIGH); 64 | digitalWrite(Y5, HIGH); 65 | digitalWrite(Y6, HIGH); 66 | digitalWrite(Y7, HIGH); 67 | 68 | //verify if the address is already programmed 69 | if (EEPROM.read(PROGRAMMED) != PROGRAMMED_VALUE) //Blank EEPROM, must programm address on it for the first use 70 | { 71 | EEPROM.write(PROGRAMMED, PROGRAMMED_VALUE); //Sinalize that the EEPROM is now programmed 72 | EEPROM.write(CARD_ADDRESS, 0x01); //default card address 73 | } 74 | 75 | //read address 76 | myAddress = EEPROM.read(CARD_ADDRESS); 77 | } 78 | 79 | void loop() 80 | { 81 | if (OPLC_receive(&dataSize, &function, &address, data)) //if received something 82 | { 83 | switch (function) 84 | { 85 | case CARD_TYPE: 86 | sendCardType(); 87 | break; 88 | case CHANGE_ADDRESS: 89 | changeCardAddress(); 90 | break; 91 | case SET_OUTPUT: 92 | setOutput(); 93 | break; 94 | case MSG_ERROR: 95 | sendLastMsg(); 96 | break; 97 | default: 98 | //sendErrorMsg(); 99 | break; 100 | } 101 | } 102 | } 103 | 104 | void sendCardType() 105 | { 106 | if (address == slotNumber) //the message is for me 107 | { 108 | byte dataResponse[2] = { 109 | 0x02, //discrete output card 110 | myAddress //actual card address 111 | }; 112 | OPLC_send(2, CARD_TYPE, address, dataResponse); //dataSize, function, address, data 113 | } 114 | } 115 | 116 | void changeCardAddress() 117 | { 118 | if (address == slotNumber) 119 | { 120 | if (data[0] > 0 && data[0] < 9) //new address validation 121 | { 122 | EEPROM.write(CARD_ADDRESS, data[0]); //update eeprom 123 | myAddress = data[0]; //update local variable 124 | 125 | //return a confirmation message 126 | OPLC_send(1, CHANGE_ADDRESS, address, data); //dataSize, function, address, data 127 | } 128 | else 129 | { 130 | OPLC_send(0, MSG_ERROR, address, 0); //dataSize, function, address, data 131 | } 132 | } 133 | } 134 | 135 | void setOutput() 136 | { 137 | if (address == myAddress) 138 | { 139 | int a = 0, b = Y0; //indexers 140 | //set each output according to data received 141 | while (b <= Y7) 142 | { 143 | digitalWrite(b, !bitRead(data[0], a)); 144 | a++; 145 | b++; 146 | } 147 | OPLC_send(1, SET_OUTPUT, address, data); //dataSize, function, address, data 148 | } 149 | } 150 | 151 | void sendErrorMsg() 152 | { 153 | if (address == myAddress) 154 | { 155 | OPLC_send(0, MSG_ERROR, address, 0x00); //dataSize, function, address, data 156 | } 157 | } 158 | 159 | void sendLastMsg() 160 | { 161 | } 162 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/SPI/SPI.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 by Cristian Maglie 3 | * Copyright (c) 2014 by Paul Stoffregen (Transaction API) 4 | * SPI Master library for arduino. 5 | * 6 | * This file is free software; you can redistribute it and/or modify 7 | * it under the terms of either the GNU General Public License version 2 8 | * or the GNU Lesser General Public License version 2.1, both as 9 | * published by the Free Software Foundation. 10 | */ 11 | 12 | #include "SPI.h" 13 | #include "pins_arduino.h" 14 | 15 | SPIClass SPI; 16 | 17 | uint8_t SPIClass::interruptMode = 0; 18 | uint8_t SPIClass::interruptMask = 0; 19 | uint8_t SPIClass::interruptSave = 0; 20 | #ifdef SPI_TRANSACTION_MISMATCH_LED 21 | uint8_t SPIClass::inTransactionFlag = 0; 22 | #endif 23 | 24 | void SPIClass::begin() 25 | { 26 | // Set SS to high so a connected chip will be "deselected" by default 27 | digitalWrite(SS, HIGH); 28 | 29 | // When the SS pin is set as OUTPUT, it can be used as 30 | // a general purpose output port (it doesn't influence 31 | // SPI operations). 32 | pinMode(SS, OUTPUT); 33 | 34 | // Warning: if the SS pin ever becomes a LOW INPUT then SPI 35 | // automatically switches to Slave, so the data direction of 36 | // the SS pin MUST be kept as OUTPUT. 37 | SPCR |= _BV(MSTR); 38 | SPCR |= _BV(SPE); 39 | 40 | // Set direction register for SCK and MOSI pin. 41 | // MISO pin automatically overrides to INPUT. 42 | // By doing this AFTER enabling SPI, we avoid accidentally 43 | // clocking in a single bit since the lines go directly 44 | // from "input" to SPI control. 45 | // http://code.google.com/p/arduino/issues/detail?id=888 46 | pinMode(SCK, OUTPUT); 47 | pinMode(MOSI, OUTPUT); 48 | } 49 | 50 | void SPIClass::end() { 51 | SPCR &= ~_BV(SPE); 52 | } 53 | 54 | // mapping of interrupt numbers to bits within SPI_AVR_EIMSK 55 | #if defined(__AVR_ATmega32U4__) 56 | #define SPI_INT0_MASK (1< 1) return; 96 | 97 | noInterrupts(); 98 | switch (interruptNumber) { 99 | #ifdef SPI_INT0_MASK 100 | case 0: mask = SPI_INT0_MASK; break; 101 | #endif 102 | #ifdef SPI_INT1_MASK 103 | case 1: mask = SPI_INT1_MASK; break; 104 | #endif 105 | #ifdef SPI_INT2_MASK 106 | case 2: mask = SPI_INT2_MASK; break; 107 | #endif 108 | #ifdef SPI_INT3_MASK 109 | case 3: mask = SPI_INT3_MASK; break; 110 | #endif 111 | #ifdef SPI_INT4_MASK 112 | case 4: mask = SPI_INT4_MASK; break; 113 | #endif 114 | #ifdef SPI_INT5_MASK 115 | case 5: mask = SPI_INT5_MASK; break; 116 | #endif 117 | #ifdef SPI_INT6_MASK 118 | case 6: mask = SPI_INT6_MASK; break; 119 | #endif 120 | #ifdef SPI_INT7_MASK 121 | case 7: mask = SPI_INT7_MASK; break; 122 | #endif 123 | default: 124 | interruptMode = 2; 125 | interrupts(); 126 | return; 127 | } 128 | interruptMode = 1; 129 | interruptMask |= mask; 130 | interrupts(); 131 | } 132 | 133 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/Udp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Udp.cpp: Library to send/receive UDP packets. 3 | * 4 | * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) 5 | * 1) UDP does not guarantee the order in which assembled UDP packets are received. This 6 | * might not happen often in practice, but in larger network topologies, a UDP 7 | * packet can be received out of sequence. 8 | * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being 9 | * aware of it. Again, this may not be a concern in practice on small local networks. 10 | * For more information, see http://www.cafeaulait.org/course/week12/35.html 11 | * 12 | * MIT License: 13 | * Copyright (c) 2008 Bjoern Hartmann 14 | * Permission is hereby granted, free of charge, to any person obtaining a copy 15 | * of this software and associated documentation files (the "Software"), to deal 16 | * in the Software without restriction, including without limitation the rights 17 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | * copies of the Software, and to permit persons to whom the Software is 19 | * furnished to do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be included in 22 | * all copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30 | * THE SOFTWARE. 31 | * 32 | * bjoern@cs.stanford.edu 12/30/2008 33 | */ 34 | 35 | #ifndef udp_h 36 | #define udp_h 37 | 38 | #include 39 | #include 40 | 41 | class UDP : public Stream { 42 | 43 | public: 44 | virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use 45 | virtual void stop() =0; // Finish with the UDP socket 46 | 47 | // Sending UDP packets 48 | 49 | // Start building up a packet to send to the remote host specific in ip and port 50 | // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port 51 | virtual int beginPacket(IPAddress ip, uint16_t port) =0; 52 | // Start building up a packet to send to the remote host specific in host and port 53 | // Returns 1 if successful, 0 if there was a problem resolving the hostname or port 54 | virtual int beginPacket(const char *host, uint16_t port) =0; 55 | // Finish off this packet and send it 56 | // Returns 1 if the packet was sent successfully, 0 if there was an error 57 | virtual int endPacket() =0; 58 | // Write a single byte into the packet 59 | virtual size_t write(uint8_t) =0; 60 | // Write size bytes from buffer into the packet 61 | virtual size_t write(const uint8_t *buffer, size_t size) =0; 62 | 63 | // Start processing the next available incoming packet 64 | // Returns the size of the packet in bytes, or 0 if no packets are available 65 | virtual int parsePacket() =0; 66 | // Number of bytes remaining in the current packet 67 | virtual int available() =0; 68 | // Read a single byte from the current packet 69 | virtual int read() =0; 70 | // Read up to len bytes from the current packet and place them into buffer 71 | // Returns the number of bytes read, or 0 if none are available 72 | virtual int read(unsigned char* buffer, size_t len) =0; 73 | // Read up to len characters from the current packet and place them into buffer 74 | // Returns the number of characters read, or 0 if none are available 75 | virtual int read(char* buffer, size_t len) =0; 76 | // Return the next byte from the current packet without moving on to the next byte 77 | virtual int peek() =0; 78 | virtual void flush() =0; // Finish reading the current packet 79 | 80 | // Return the IP address of the host who sent the current incoming packet 81 | virtual IPAddress remoteIP() =0; 82 | // Return the port of the host who sent the current incoming packet 83 | virtual uint16_t remotePort() =0; 84 | protected: 85 | uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; 86 | }; 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /hardware/openplc/avr/firmwares/inputBoard/OPLC_Protocol.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /************************************************************* 4 | * OPLC PROTOCOL * 5 | * * 6 | * The OpenPLC protocol stablishes the way that * 7 | * messages are sent from one board to another. * 8 | * These messages must obey the following format: * 9 | * * 10 | * MESSAGE STRUCTURE * 11 | * START | SIZE | FUNCTION | ADDRESS | DATA * 12 | * * 13 | * START = 0x7E * 14 | * SIZE = size of the DATA field (in bytes) * 15 | * FUNCTION = function to be executed * 16 | * ADDRESS = address of the target * 17 | * DATA = data sent or received * 18 | * * 19 | * FUNCTIONS | ARGUMENTS * 20 | * 0x01 = ask for the card's type * 21 | * 0x02 = change card address * 22 | * 0x03 = read discrete inputs * 23 | * 0x04 = set discrete outputs * 24 | * 0x05 = error message * 25 | * * 26 | ************************************************************** 27 | */ 28 | 29 | #define OPLC_TIMEOUT 5 30 | #define MAX_FUNCTION_NUMBER 0x05 31 | #define MAX_DATA_SIZE 10 32 | 33 | //OPLC functions 34 | #define CARD_TYPE 0x01 35 | #define CHANGE_ADDRESS 0x02 36 | #define READ_INPUT 0x03 37 | #define SET_OUTPUT 0x04 38 | #define MSG_ERROR 0x05 39 | 40 | void OPLC_send(byte dataSize, byte function, byte address, byte * data) 41 | { 42 | byte header[4]; 43 | header[0] = 0x7E; //start message 44 | header[1] = dataSize; //message size 45 | header[2] = function; //function code 46 | header[3] = address; //address 47 | 48 | //enable sending data through the bus 49 | digitalWrite(DE_PIN, HIGH); 50 | delayMicroseconds(500); 51 | //Serial.write('a'); //send an invalid character to clear transmission 52 | //Serial.flush(); 53 | 54 | //send the header first 55 | int i; 56 | for (i = 0; i < 4; i++) 57 | { 58 | Serial.write(header[i]); 59 | } 60 | //send the data 61 | for (i = 0; i < dataSize; i++) 62 | { 63 | Serial.write(data[i]); 64 | } 65 | 66 | //wait until all data is sent 67 | Serial.flush(); 68 | //disable sending data through the bus 69 | digitalWrite(DE_PIN, LOW); 70 | } 71 | 72 | boolean OPLC_receive(byte * dataSize, byte * function, byte * address, byte * data) 73 | { 74 | long timeout; 75 | byte byteIndex = 0; 76 | byte message[MAX_DATA_SIZE]; 77 | 78 | //waiting for the start bit 79 | while (true) 80 | { 81 | if (Serial.available()) 82 | { 83 | if (Serial.read() == 0x7E) 84 | { 85 | break; //the start bit was received. Get out of the loop. 86 | } 87 | } 88 | } 89 | 90 | //getting message size 91 | timeout = millis(); 92 | while (true) 93 | { 94 | if ((millis() - timeout) > OPLC_TIMEOUT) 95 | { 96 | return (0); //no message received 97 | } 98 | if (Serial.available()) 99 | { 100 | *dataSize = Serial.read(); 101 | if (*dataSize > MAX_DATA_SIZE) //maximum data size is 10 bytes 102 | { 103 | *function = 0x05; //error function 104 | return (1); //received a message but with errors 105 | } 106 | break; //get out of the loop 107 | } 108 | } 109 | 110 | //getting message function 111 | while (true) 112 | { 113 | if ((millis() - timeout) > OPLC_TIMEOUT) 114 | { 115 | return (0); //no message received 116 | } 117 | if (Serial.available()) 118 | { 119 | *function = Serial.read(); 120 | if (*function > MAX_FUNCTION_NUMBER) //wrong function 121 | { 122 | *function = 0x05; //error function 123 | return (1); //received a message but with errors 124 | } 125 | break; //get out of the loop 126 | } 127 | } 128 | 129 | //getting address byte 130 | while (true) 131 | { 132 | if (Serial.available()) //if received the address byte 133 | { 134 | *address = Serial.read(); //read address 135 | break; //finish loop 136 | } 137 | } 138 | 139 | //getting data 140 | byteIndex = 0; 141 | while (byteIndex < *dataSize) 142 | { 143 | if ((millis() - timeout) > OPLC_TIMEOUT) 144 | { 145 | return (0); //no message received 146 | } 147 | if (Serial.available()) 148 | { 149 | data[byteIndex] = Serial.read(); 150 | byteIndex++; 151 | } 152 | } 153 | return (1); //message received with no errors 154 | } 155 | -------------------------------------------------------------------------------- /hardware/openplc/avr/firmwares/outputBoard/OPLC_Protocol.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /************************************************************* 4 | * OPLC PROTOCOL * 5 | * * 6 | * The OpenPLC protocol stablishes the way that * 7 | * messages are sent from one board to another. * 8 | * These messages must obey the following format: * 9 | * * 10 | * MESSAGE STRUCTURE * 11 | * START | SIZE | FUNCTION | ADDRESS | DATA * 12 | * * 13 | * START = 0x7E * 14 | * SIZE = size of the DATA field (in bytes) * 15 | * FUNCTION = function to be executed * 16 | * ADDRESS = address of the target * 17 | * DATA = data sent or received * 18 | * * 19 | * FUNCTIONS | ARGUMENTS * 20 | * 0x01 = ask for the card's type * 21 | * 0x02 = change card address * 22 | * 0x03 = read discrete inputs * 23 | * 0x04 = set discrete outputs * 24 | * 0x05 = error message * 25 | * * 26 | ************************************************************** 27 | */ 28 | 29 | #define OPLC_TIMEOUT 5 30 | #define MAX_FUNCTION_NUMBER 0x05 31 | #define MAX_DATA_SIZE 10 32 | 33 | //OPLC functions 34 | #define CARD_TYPE 0x01 35 | #define CHANGE_ADDRESS 0x02 36 | #define READ_INPUT 0x03 37 | #define SET_OUTPUT 0x04 38 | #define MSG_ERROR 0x05 39 | 40 | void OPLC_send(byte dataSize, byte function, byte address, byte * data) 41 | { 42 | byte header[4]; 43 | header[0] = 0x7E; //start message 44 | header[1] = dataSize; //message size 45 | header[2] = function; //function code 46 | header[3] = address; //address 47 | 48 | //enable sending data through the bus 49 | digitalWrite(DE_PIN, HIGH); 50 | delayMicroseconds(500); 51 | //Serial.write('a'); //send an invalid character to clear transmission 52 | //Serial.flush(); 53 | 54 | //send the header first 55 | int i; 56 | for (i = 0; i < 4; i++) 57 | { 58 | Serial.write(header[i]); 59 | } 60 | //send the data 61 | for (i = 0; i < dataSize; i++) 62 | { 63 | Serial.write(data[i]); 64 | } 65 | 66 | //wait until all data is sent 67 | Serial.flush(); 68 | //disable sending data through the bus 69 | digitalWrite(DE_PIN, LOW); 70 | } 71 | 72 | boolean OPLC_receive(byte * dataSize, byte * function, byte * address, byte * data) 73 | { 74 | long timeout; 75 | byte byteIndex = 0; 76 | byte message[MAX_DATA_SIZE]; 77 | 78 | //waiting for the start bit 79 | while (true) 80 | { 81 | if (Serial.available()) 82 | { 83 | if (Serial.read() == 0x7E) 84 | { 85 | break; //the start bit was received. Get out of the loop. 86 | } 87 | } 88 | } 89 | 90 | //getting message size 91 | timeout = millis(); 92 | while (true) 93 | { 94 | if ((millis() - timeout) > OPLC_TIMEOUT) 95 | { 96 | return (0); //no message received 97 | } 98 | if (Serial.available()) 99 | { 100 | *dataSize = Serial.read(); 101 | if (*dataSize > MAX_DATA_SIZE) //maximum data size is 10 bytes 102 | { 103 | *function = 0x05; //error function 104 | return (1); //received a message but with errors 105 | } 106 | break; //get out of the loop 107 | } 108 | } 109 | 110 | //getting message function 111 | while (true) 112 | { 113 | if ((millis() - timeout) > OPLC_TIMEOUT) 114 | { 115 | return (0); //no message received 116 | } 117 | if (Serial.available()) 118 | { 119 | *function = Serial.read(); 120 | if (*function > MAX_FUNCTION_NUMBER) //wrong function 121 | { 122 | *function = 0x05; //error function 123 | return (1); //received a message but with errors 124 | } 125 | break; //get out of the loop 126 | } 127 | } 128 | 129 | //getting address byte 130 | while (true) 131 | { 132 | if (Serial.available()) //if received the address byte 133 | { 134 | *address = Serial.read(); //read address 135 | break; //finish loop 136 | } 137 | } 138 | 139 | //getting data 140 | byteIndex = 0; 141 | while (byteIndex < *dataSize) 142 | { 143 | if ((millis() - timeout) > OPLC_TIMEOUT) 144 | { 145 | return (0); //no message received 146 | } 147 | if (Serial.available()) 148 | { 149 | data[byteIndex] = Serial.read(); 150 | byteIndex++; 151 | } 152 | } 153 | return (1); //message received with no errors 154 | } 155 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/HardwareSerial_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial_private.h - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | */ 23 | 24 | #include "wiring_private.h" 25 | 26 | // this next line disables the entire HardwareSerial.cpp, 27 | // this is so I can support Attiny series and any other chip without a uart 28 | #if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3) 29 | 30 | // Ensure that the various bit positions we use are available with a 0 31 | // postfix, so we can always use the values for UART0 for all UARTs. The 32 | // alternative, passing the various values for each UART to the 33 | // HardwareSerial constructor also works, but makes the code bigger and 34 | // slower. 35 | #if !defined(TXC0) 36 | #if defined(TXC) 37 | // Some chips like ATmega8 don't have UPE, only PE. The other bits are 38 | // named as expected. 39 | #if !defined(UPE) && defined(PE) 40 | #define UPE PE 41 | #endif 42 | // On ATmega8, the uart and its bits are not numbered, so there is no TXC0 etc. 43 | #define TXC0 TXC 44 | #define RXEN0 RXEN 45 | #define TXEN0 TXEN 46 | #define RXCIE0 RXCIE 47 | #define UDRIE0 UDRIE 48 | #define U2X0 U2X 49 | #define UPE0 UPE 50 | #define UDRE0 UDRE 51 | #elif defined(TXC1) 52 | // Some devices have uart1 but no uart0 53 | #define TXC0 TXC1 54 | #define RXEN0 RXEN1 55 | #define TXEN0 TXEN1 56 | #define RXCIE0 RXCIE1 57 | #define UDRIE0 UDRIE1 58 | #define U2X0 U2X1 59 | #define UPE0 UPE1 60 | #define UDRE0 UDRE1 61 | #else 62 | #error No UART found in HardwareSerial.cpp 63 | #endif 64 | #endif // !defined TXC0 65 | 66 | // Check at compiletime that it is really ok to use the bit positions of 67 | // UART0 for the other UARTs as well, in case these values ever get 68 | // changed for future hardware. 69 | #if defined(TXC1) && (TXC1 != TXC0 || RXEN1 != RXEN0 || RXCIE1 != RXCIE0 || \ 70 | UDRIE1 != UDRIE0 || U2X1 != U2X0 || UPE1 != UPE0 || \ 71 | UDRE1 != UDRE0) 72 | #error "Not all bit positions for UART1 are the same as for UART0" 73 | #endif 74 | #if defined(TXC2) && (TXC2 != TXC0 || RXEN2 != RXEN0 || RXCIE2 != RXCIE0 || \ 75 | UDRIE2 != UDRIE0 || U2X2 != U2X0 || UPE2 != UPE0 || \ 76 | UDRE2 != UDRE0) 77 | #error "Not all bit positions for UART2 are the same as for UART0" 78 | #endif 79 | #if defined(TXC3) && (TXC3 != TXC0 || RXEN3 != RXEN0 || RXCIE3 != RXCIE0 || \ 80 | UDRIE3 != UDRIE0 || U3X3 != U3X0 || UPE3 != UPE0 || \ 81 | UDRE3 != UDRE0) 82 | #error "Not all bit positions for UART3 are the same as for UART0" 83 | #endif 84 | 85 | // Constructors //////////////////////////////////////////////////////////////// 86 | 87 | HardwareSerial::HardwareSerial( 88 | volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, 89 | volatile uint8_t *ucsra, volatile uint8_t *ucsrb, 90 | volatile uint8_t *ucsrc, volatile uint8_t *udr) : 91 | _ubrrh(ubrrh), _ubrrl(ubrrl), 92 | _ucsra(ucsra), _ucsrb(ucsrb), _ucsrc(ucsrc), 93 | _udr(udr), 94 | _rx_buffer_head(0), _rx_buffer_tail(0), 95 | _tx_buffer_head(0), _tx_buffer_tail(0) 96 | { 97 | } 98 | 99 | // Actual interrupt handlers ////////////////////////////////////////////////////////////// 100 | 101 | void HardwareSerial::_rx_complete_irq(void) 102 | { 103 | if (bit_is_clear(*_ucsra, UPE0)) { 104 | // No Parity error, read byte and store it in the buffer if there is 105 | // room 106 | unsigned char c = *_udr; 107 | rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE; 108 | 109 | // if we should be storing the received character into the location 110 | // just before the tail (meaning that the head would advance to the 111 | // current location of the tail), we're about to overflow the buffer 112 | // and so we don't write the character or advance the head. 113 | if (i != _rx_buffer_tail) { 114 | _rx_buffer[_rx_buffer_head] = c; 115 | _rx_buffer_head = i; 116 | } 117 | } else { 118 | // Parity error, read byte but discard it 119 | *_udr; 120 | }; 121 | } 122 | 123 | #endif // whole file 124 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/Stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | Stream.h - base class for character-based streams. 3 | Copyright (c) 2010 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | parsing functions based on TextFinder library by Michael Margolis 20 | */ 21 | 22 | #ifndef Stream_h 23 | #define Stream_h 24 | 25 | #include 26 | #include "Print.h" 27 | 28 | // compatability macros for testing 29 | /* 30 | #define getInt() parseInt() 31 | #define getInt(skipChar) parseInt(skipchar) 32 | #define getFloat() parseFloat() 33 | #define getFloat(skipChar) parseFloat(skipChar) 34 | #define getString( pre_string, post_string, buffer, length) 35 | readBytesBetween( pre_string, terminator, buffer, length) 36 | */ 37 | 38 | class Stream : public Print 39 | { 40 | protected: 41 | unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read 42 | unsigned long _startMillis; // used for timeout measurement 43 | int timedRead(); // private method to read stream with timeout 44 | int timedPeek(); // private method to peek stream with timeout 45 | int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout 46 | 47 | public: 48 | virtual int available() = 0; 49 | virtual int read() = 0; 50 | virtual int peek() = 0; 51 | virtual void flush() = 0; 52 | 53 | Stream() {_timeout=1000;} 54 | 55 | // parsing methods 56 | 57 | void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second 58 | 59 | bool find(char *target); // reads data from the stream until the target string is found 60 | bool find(uint8_t *target) { return find ((char *)target); } 61 | // returns true if target string is found, false if timed out (see setTimeout) 62 | 63 | bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found 64 | bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } 65 | // returns true if target string is found, false if timed out 66 | 67 | bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found 68 | bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } 69 | 70 | bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found 71 | bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } 72 | 73 | 74 | long parseInt(); // returns the first valid (long) integer value from the current position. 75 | // initial characters that are not digits (or the minus sign) are skipped 76 | // integer is terminated by the first character that is not a digit. 77 | 78 | float parseFloat(); // float version of parseInt 79 | 80 | size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer 81 | size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } 82 | // terminates if length characters have been read or timeout (see setTimeout) 83 | // returns the number of characters placed in the buffer (0 means no valid data found) 84 | 85 | size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character 86 | size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } 87 | // terminates if length characters have been read, timeout, or if the terminator character detected 88 | // returns the number of characters placed in the buffer (0 means no valid data found) 89 | 90 | // Arduino String functions to be added here 91 | String readString(); 92 | String readStringUntil(char terminator); 93 | 94 | protected: 95 | long parseInt(char skipChar); // as above but the given skipChar is ignored 96 | // as above but the given skipChar is ignored 97 | // this allows format characters (typically commas) in values to be ignored 98 | 99 | float parseFloat(char skipChar); // as above but the given skipChar is ignored 100 | }; 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | SCP1000 Barometric Pressure Sensor Display 3 | 4 | Shows the output of a Barometric Pressure Sensor on a 5 | Uses the SPI library. For details on the sensor, see: 6 | http://www.sparkfun.com/commerce/product_info.php?products_id=8161 7 | http://www.vti.fi/en/support/obsolete_products/pressure_sensors/ 8 | 9 | This sketch adapted from Nathan Seidle's SCP1000 example for PIC: 10 | http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip 11 | 12 | Circuit: 13 | SCP1000 sensor attached to pins 6, 7, 10 - 13: 14 | DRDY: pin 6 15 | CSB: pin 7 16 | MOSI: pin 11 17 | MISO: pin 12 18 | SCK: pin 13 19 | 20 | created 31 July 2010 21 | modified 14 August 2010 22 | by Tom Igoe 23 | */ 24 | 25 | // the sensor communicates using SPI, so include the library: 26 | #include 27 | 28 | //Sensor's memory register addresses: 29 | const int PRESSURE = 0x1F; //3 most significant bits of pressure 30 | const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure 31 | const int TEMPERATURE = 0x21; //16 bit temperature reading 32 | const byte READ = 0b11111100; // SCP1000's read command 33 | const byte WRITE = 0b00000010; // SCP1000's write command 34 | 35 | // pins used for the connection with the sensor 36 | // the other you need are controlled by the SPI library): 37 | const int dataReadyPin = 6; 38 | const int chipSelectPin = 7; 39 | 40 | void setup() { 41 | Serial.begin(9600); 42 | 43 | // start the SPI library: 44 | SPI.begin(); 45 | 46 | // initalize the data ready and chip select pins: 47 | pinMode(dataReadyPin, INPUT); 48 | pinMode(chipSelectPin, OUTPUT); 49 | 50 | //Configure SCP1000 for low noise configuration: 51 | writeRegister(0x02, 0x2D); 52 | writeRegister(0x01, 0x03); 53 | writeRegister(0x03, 0x02); 54 | // give the sensor time to set up: 55 | delay(100); 56 | } 57 | 58 | void loop() { 59 | //Select High Resolution Mode 60 | writeRegister(0x03, 0x0A); 61 | 62 | // don't do anything until the data ready pin is high: 63 | if (digitalRead(dataReadyPin) == HIGH) { 64 | //Read the temperature data 65 | int tempData = readRegister(0x21, 2); 66 | 67 | // convert the temperature to celsius and display it: 68 | float realTemp = (float)tempData / 20.0; 69 | Serial.print("Temp[C]="); 70 | Serial.print(realTemp); 71 | 72 | 73 | //Read the pressure data highest 3 bits: 74 | byte pressure_data_high = readRegister(0x1F, 1); 75 | pressure_data_high &= 0b00000111; //you only needs bits 2 to 0 76 | 77 | //Read the pressure data lower 16 bits: 78 | unsigned int pressure_data_low = readRegister(0x20, 2); 79 | //combine the two parts into one 19-bit number: 80 | long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4; 81 | 82 | // display the temperature: 83 | Serial.println("\tPressure [Pa]=" + String(pressure)); 84 | } 85 | } 86 | 87 | //Read from or write to register from the SCP1000: 88 | unsigned int readRegister(byte thisRegister, int bytesToRead ) { 89 | byte inByte = 0; // incoming byte from the SPI 90 | unsigned int result = 0; // result to return 91 | Serial.print(thisRegister, BIN); 92 | Serial.print("\t"); 93 | // SCP1000 expects the register name in the upper 6 bits 94 | // of the byte. So shift the bits left by two bits: 95 | thisRegister = thisRegister << 2; 96 | // now combine the address and the command into one byte 97 | byte dataToSend = thisRegister & READ; 98 | Serial.println(thisRegister, BIN); 99 | // take the chip select low to select the device: 100 | digitalWrite(chipSelectPin, LOW); 101 | // send the device the register you want to read: 102 | SPI.transfer(dataToSend); 103 | // send a value of 0 to read the first byte returned: 104 | result = SPI.transfer(0x00); 105 | // decrement the number of bytes left to read: 106 | bytesToRead--; 107 | // if you still have another byte to read: 108 | if (bytesToRead > 0) { 109 | // shift the first byte left, then get the second byte: 110 | result = result << 8; 111 | inByte = SPI.transfer(0x00); 112 | // combine the byte you just got with the previous one: 113 | result = result | inByte; 114 | // decrement the number of bytes left to read: 115 | bytesToRead--; 116 | } 117 | // take the chip select high to de-select: 118 | digitalWrite(chipSelectPin, HIGH); 119 | // return the result: 120 | return (result); 121 | } 122 | 123 | 124 | //Sends a write command to SCP1000 125 | 126 | void writeRegister(byte thisRegister, byte thisValue) { 127 | 128 | // SCP1000 expects the register address in the upper 6 bits 129 | // of the byte. So shift the bits left by two bits: 130 | thisRegister = thisRegister << 2; 131 | // now combine the register address and the command into one byte: 132 | byte dataToSend = thisRegister | WRITE; 133 | 134 | // take the chip select low to select the device: 135 | digitalWrite(chipSelectPin, LOW); 136 | 137 | SPI.transfer(dataToSend); //Send register location 138 | SPI.transfer(thisValue); //Send value to record into register 139 | 140 | // take the chip select high to de-select: 141 | digitalWrite(chipSelectPin, HIGH); 142 | } 143 | 144 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/WCharacter.h: -------------------------------------------------------------------------------- 1 | /* 2 | WCharacter.h - Character utility functions for Wiring & Arduino 3 | Copyright (c) 2010 Hernando Barragan. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Character_h 21 | #define Character_h 22 | 23 | #include 24 | 25 | // WCharacter.h prototypes 26 | inline boolean isAlphaNumeric(int c) __attribute__((always_inline)); 27 | inline boolean isAlpha(int c) __attribute__((always_inline)); 28 | inline boolean isAscii(int c) __attribute__((always_inline)); 29 | inline boolean isWhitespace(int c) __attribute__((always_inline)); 30 | inline boolean isControl(int c) __attribute__((always_inline)); 31 | inline boolean isDigit(int c) __attribute__((always_inline)); 32 | inline boolean isGraph(int c) __attribute__((always_inline)); 33 | inline boolean isLowerCase(int c) __attribute__((always_inline)); 34 | inline boolean isPrintable(int c) __attribute__((always_inline)); 35 | inline boolean isPunct(int c) __attribute__((always_inline)); 36 | inline boolean isSpace(int c) __attribute__((always_inline)); 37 | inline boolean isUpperCase(int c) __attribute__((always_inline)); 38 | inline boolean isHexadecimalDigit(int c) __attribute__((always_inline)); 39 | inline int toAscii(int c) __attribute__((always_inline)); 40 | inline int toLowerCase(int c) __attribute__((always_inline)); 41 | inline int toUpperCase(int c)__attribute__((always_inline)); 42 | 43 | 44 | // Checks for an alphanumeric character. 45 | // It is equivalent to (isalpha(c) || isdigit(c)). 46 | inline boolean isAlphaNumeric(int c) 47 | { 48 | return ( isalnum(c) == 0 ? false : true); 49 | } 50 | 51 | 52 | // Checks for an alphabetic character. 53 | // It is equivalent to (isupper(c) || islower(c)). 54 | inline boolean isAlpha(int c) 55 | { 56 | return ( isalpha(c) == 0 ? false : true); 57 | } 58 | 59 | 60 | // Checks whether c is a 7-bit unsigned char value 61 | // that fits into the ASCII character set. 62 | inline boolean isAscii(int c) 63 | { 64 | return ( isascii (c) == 0 ? false : true); 65 | } 66 | 67 | 68 | // Checks for a blank character, that is, a space or a tab. 69 | inline boolean isWhitespace(int c) 70 | { 71 | return ( isblank (c) == 0 ? false : true); 72 | } 73 | 74 | 75 | // Checks for a control character. 76 | inline boolean isControl(int c) 77 | { 78 | return ( iscntrl (c) == 0 ? false : true); 79 | } 80 | 81 | 82 | // Checks for a digit (0 through 9). 83 | inline boolean isDigit(int c) 84 | { 85 | return ( isdigit (c) == 0 ? false : true); 86 | } 87 | 88 | 89 | // Checks for any printable character except space. 90 | inline boolean isGraph(int c) 91 | { 92 | return ( isgraph (c) == 0 ? false : true); 93 | } 94 | 95 | 96 | // Checks for a lower-case character. 97 | inline boolean isLowerCase(int c) 98 | { 99 | return (islower (c) == 0 ? false : true); 100 | } 101 | 102 | 103 | // Checks for any printable character including space. 104 | inline boolean isPrintable(int c) 105 | { 106 | return ( isprint (c) == 0 ? false : true); 107 | } 108 | 109 | 110 | // Checks for any printable character which is not a space 111 | // or an alphanumeric character. 112 | inline boolean isPunct(int c) 113 | { 114 | return ( ispunct (c) == 0 ? false : true); 115 | } 116 | 117 | 118 | // Checks for white-space characters. For the avr-libc library, 119 | // these are: space, formfeed ('\f'), newline ('\n'), carriage 120 | // return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). 121 | inline boolean isSpace(int c) 122 | { 123 | return ( isspace (c) == 0 ? false : true); 124 | } 125 | 126 | 127 | // Checks for an uppercase letter. 128 | inline boolean isUpperCase(int c) 129 | { 130 | return ( isupper (c) == 0 ? false : true); 131 | } 132 | 133 | 134 | // Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 135 | // 8 9 a b c d e f A B C D E F. 136 | inline boolean isHexadecimalDigit(int c) 137 | { 138 | return ( isxdigit (c) == 0 ? false : true); 139 | } 140 | 141 | 142 | // Converts c to a 7-bit unsigned char value that fits into the 143 | // ASCII character set, by clearing the high-order bits. 144 | inline int toAscii(int c) 145 | { 146 | return toascii (c); 147 | } 148 | 149 | 150 | // Warning: 151 | // Many people will be unhappy if you use this function. 152 | // This function will convert accented letters into random 153 | // characters. 154 | 155 | // Converts the letter c to lower case, if possible. 156 | inline int toLowerCase(int c) 157 | { 158 | return tolower (c); 159 | } 160 | 161 | 162 | // Converts the letter c to upper case, if possible. 163 | inline int toUpperCase(int c) 164 | { 165 | return toupper (c); 166 | } 167 | 168 | #endif -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/HardwareSerial.h: -------------------------------------------------------------------------------- 1 | /* 2 | HardwareSerial.h - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 28 September 2010 by Mark Sproul 20 | Modified 14 August 2012 by Alarus 21 | Modified 3 December 2013 by Matthijs Kooijman 22 | */ 23 | 24 | #ifndef HardwareSerial_h 25 | #define HardwareSerial_h 26 | 27 | #include 28 | 29 | #include "Stream.h" 30 | 31 | // Define constants and variables for buffering incoming serial data. We're 32 | // using a ring buffer (I think), in which head is the index of the location 33 | // to which to write the next incoming character and tail is the index of the 34 | // location from which to read. 35 | #if !(defined(SERIAL_TX_BUFFER_SIZE) && defined(SERIAL_RX_BUFFER_SIZE)) 36 | #if (RAMEND < 1000) 37 | #define SERIAL_TX_BUFFER_SIZE 16 38 | #define SERIAL_RX_BUFFER_SIZE 16 39 | #else 40 | #define SERIAL_TX_BUFFER_SIZE 64 41 | #define SERIAL_RX_BUFFER_SIZE 64 42 | #endif 43 | #endif 44 | #if (SERIAL_TX_BUFFER_SIZE>256) 45 | typedef uint16_t tx_buffer_index_t; 46 | #else 47 | typedef uint8_t tx_buffer_index_t; 48 | #endif 49 | #if (SERIAL_RX_BUFFER_SIZE>256) 50 | typedef uint16_t rx_buffer_index_t; 51 | #else 52 | typedef uint8_t rx_buffer_index_t; 53 | #endif 54 | 55 | // Define config for Serial.begin(baud, config); 56 | #define SERIAL_5N1 0x00 57 | #define SERIAL_6N1 0x02 58 | #define SERIAL_7N1 0x04 59 | #define SERIAL_8N1 0x06 60 | #define SERIAL_5N2 0x08 61 | #define SERIAL_6N2 0x0A 62 | #define SERIAL_7N2 0x0C 63 | #define SERIAL_8N2 0x0E 64 | #define SERIAL_5E1 0x20 65 | #define SERIAL_6E1 0x22 66 | #define SERIAL_7E1 0x24 67 | #define SERIAL_8E1 0x26 68 | #define SERIAL_5E2 0x28 69 | #define SERIAL_6E2 0x2A 70 | #define SERIAL_7E2 0x2C 71 | #define SERIAL_8E2 0x2E 72 | #define SERIAL_5O1 0x30 73 | #define SERIAL_6O1 0x32 74 | #define SERIAL_7O1 0x34 75 | #define SERIAL_8O1 0x36 76 | #define SERIAL_5O2 0x38 77 | #define SERIAL_6O2 0x3A 78 | #define SERIAL_7O2 0x3C 79 | #define SERIAL_8O2 0x3E 80 | 81 | class HardwareSerial : public Stream 82 | { 83 | protected: 84 | volatile uint8_t * const _ubrrh; 85 | volatile uint8_t * const _ubrrl; 86 | volatile uint8_t * const _ucsra; 87 | volatile uint8_t * const _ucsrb; 88 | volatile uint8_t * const _ucsrc; 89 | volatile uint8_t * const _udr; 90 | // Has any byte been written to the UART since begin() 91 | bool _written; 92 | 93 | volatile rx_buffer_index_t _rx_buffer_head; 94 | volatile rx_buffer_index_t _rx_buffer_tail; 95 | volatile tx_buffer_index_t _tx_buffer_head; 96 | volatile tx_buffer_index_t _tx_buffer_tail; 97 | 98 | // Don't put any members after these buffers, since only the first 99 | // 32 bytes of this struct can be accessed quickly using the ldd 100 | // instruction. 101 | unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE]; 102 | unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE]; 103 | 104 | public: 105 | inline HardwareSerial( 106 | volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, 107 | volatile uint8_t *ucsra, volatile uint8_t *ucsrb, 108 | volatile uint8_t *ucsrc, volatile uint8_t *udr); 109 | void begin(unsigned long baud) { begin(baud, SERIAL_8N1); } 110 | void begin(unsigned long, uint8_t); 111 | void end(); 112 | virtual int available(void); 113 | virtual int peek(void); 114 | virtual int read(void); 115 | int availableForWrite(void); 116 | virtual void flush(void); 117 | virtual size_t write(uint8_t); 118 | inline size_t write(unsigned long n) { return write((uint8_t)n); } 119 | inline size_t write(long n) { return write((uint8_t)n); } 120 | inline size_t write(unsigned int n) { return write((uint8_t)n); } 121 | inline size_t write(int n) { return write((uint8_t)n); } 122 | using Print::write; // pull in write(str) and write(buf, size) from Print 123 | operator bool() { return true; } 124 | 125 | // Interrupt handlers - Not intended to be called externally 126 | inline void _rx_complete_irq(void); 127 | void _tx_udr_empty_irq(void); 128 | }; 129 | 130 | #if defined(UBRRH) || defined(UBRR0H) 131 | extern HardwareSerial Serial; 132 | #define HAVE_HWSERIAL0 133 | #endif 134 | #if defined(UBRR1H) 135 | extern HardwareSerial Serial1; 136 | #define HAVE_HWSERIAL1 137 | #endif 138 | #if defined(UBRR2H) 139 | extern HardwareSerial Serial2; 140 | #define HAVE_HWSERIAL2 141 | #endif 142 | #if defined(UBRR3H) 143 | extern HardwareSerial Serial3; 144 | #define HAVE_HWSERIAL3 145 | #endif 146 | 147 | extern void serialEventRun(void) __attribute__((weak)); 148 | 149 | #endif 150 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/OpenPLC/OpenPLC.h: -------------------------------------------------------------------------------- 1 | //#include "WProgram.h" //Arduino library 2 | #include 3 | #include //modbus library for the modbus ethernet implementation 4 | #include //library to control write/erase functions at EEPROM 5 | #include //auto-generated ladder library 6 | #include "Prototypes.h" 7 | 8 | 9 | 10 | //Basic OpenPLC Definitions 11 | #define ON 1 12 | #define OFF 0 13 | #define ERROR_MSG -1 14 | #define MAX_ERROR 10 15 | #define ERROR_TIMEOUT 10000 16 | 17 | //RS485 BUS Definitions 18 | #define DE_PIN 20 19 | #define LISTEN_PIN 21 20 | 21 | //Possible PLC Status 22 | #define RUN 1 23 | #define STOP 2 24 | #define HALTED 3 25 | 26 | //PLC Status Switch Pins 27 | #define RUN_PIN 6 28 | #define STOP_PIN 7 29 | #define AUTO_PIN 8 30 | 31 | //Status Leds Pins 32 | #define RUN_LED 5 33 | #define ERROR_LED 3 34 | 35 | //Boards 36 | #define NONE 0x00 37 | #define DISCRETE_INPUT 0x01 38 | #define DISCRETE_OUTPUT 0x02 39 | 40 | //OpenPLC EEPROM address 41 | #define PROGRAMMED 0 42 | #define PROGRAMMED_VALUE 128 43 | #define MAC 1 44 | #define IP 7 45 | #define GATEWAY 11 46 | #define SUBNET 15 47 | 48 | /***************************************************** 49 | * INPUT DEFINITIONS * 50 | * * 51 | * Here we are associating each OpenPLC input name * 52 | * with a number, so that when we call 'X1_3' in a * 53 | * program, we are actualy calling the number '3' * 54 | * that is interpreted as the 3rd input of the first * 55 | * input card. * 56 | ***************************************************** 57 | */ 58 | //1st input card 59 | #define X1_0 0 60 | #define X1_1 1 61 | #define X1_2 2 62 | #define X1_3 3 63 | #define X1_4 4 64 | #define X1_5 5 65 | #define X1_6 6 66 | #define X1_7 7 67 | //2nd input card 68 | #define X2_0 8 69 | #define X2_1 9 70 | #define X2_2 10 71 | #define X2_3 11 72 | #define X2_4 12 73 | #define X2_5 13 74 | #define X2_6 14 75 | #define X2_7 15 76 | //3rd input card 77 | #define X3_0 16 78 | #define X3_1 17 79 | #define X3_2 18 80 | #define X3_3 19 81 | #define X3_4 20 82 | #define X3_5 21 83 | #define X3_6 22 84 | #define X3_7 23 85 | //4th input card 86 | #define X4_0 24 87 | #define X4_1 25 88 | #define X4_2 26 89 | #define X4_3 27 90 | #define X4_4 28 91 | #define X4_5 29 92 | #define X4_6 30 93 | #define X4_7 31 94 | //5th input card 95 | #define X5_0 32 96 | #define X5_1 33 97 | #define X5_2 34 98 | #define X5_3 35 99 | #define X5_4 36 100 | #define X5_5 37 101 | #define X5_6 38 102 | #define X5_7 39 103 | //6th input card 104 | #define X6_0 40 105 | #define X6_1 41 106 | #define X6_2 42 107 | #define X6_3 43 108 | #define X6_4 44 109 | #define X6_5 45 110 | #define X6_6 46 111 | #define X6_7 47 112 | //7th input card 113 | #define X7_0 48 114 | #define X7_1 49 115 | #define X7_2 50 116 | #define X7_3 51 117 | #define X7_4 52 118 | #define X7_5 53 119 | #define X7_6 54 120 | #define X7_7 55 121 | //8th input card 122 | #define X8_0 56 123 | #define X8_1 57 124 | #define X8_2 58 125 | #define X8_3 59 126 | #define X8_4 60 127 | #define X8_5 61 128 | #define X8_6 62 129 | #define X8_7 63 130 | 131 | /***************************************************** 132 | * OUTPUT DEFINITIONS * 133 | * * 134 | * Here we are associating each OpenPLC output name * 135 | * with a number, so that when we call 'Y1_3' in a * 136 | * program, we are actualy calling the number '3' * 137 | * that is interpreted as the 3rd output of the * 138 | * first output card. * 139 | ***************************************************** 140 | */ 141 | //1st output card 142 | #define Y1_0 0 143 | #define Y1_1 1 144 | #define Y1_2 2 145 | #define Y1_3 3 146 | #define Y1_4 4 147 | #define Y1_5 5 148 | #define Y1_6 6 149 | #define Y1_7 7 150 | //2nd output card 151 | #define Y2_0 8 152 | #define Y2_1 9 153 | #define Y2_2 10 154 | #define Y2_3 11 155 | #define Y2_4 12 156 | #define Y2_5 13 157 | #define Y2_6 14 158 | #define Y2_7 15 159 | //3rd output card 160 | #define Y3_0 16 161 | #define Y3_1 17 162 | #define Y3_2 18 163 | #define Y3_3 19 164 | #define Y3_4 20 165 | #define Y3_5 21 166 | #define Y3_6 22 167 | #define Y3_7 23 168 | //4th output card 169 | #define Y4_0 24 170 | #define Y4_1 25 171 | #define Y4_2 26 172 | #define Y4_3 27 173 | #define Y4_4 28 174 | #define Y4_5 29 175 | #define Y4_6 30 176 | #define Y4_7 31 177 | //5th output card 178 | #define Y5_0 32 179 | #define Y5_1 33 180 | #define Y5_2 34 181 | #define Y5_3 35 182 | #define Y5_4 36 183 | #define Y5_5 37 184 | #define Y5_6 38 185 | #define Y5_7 39 186 | //6th output card 187 | #define Y6_0 40 188 | #define Y6_1 41 189 | #define Y6_2 42 190 | #define Y6_3 43 191 | #define Y6_4 44 192 | #define Y6_5 45 193 | #define Y6_6 46 194 | #define Y6_7 47 195 | //7th output card 196 | #define Y7_0 48 197 | #define Y7_1 49 198 | #define Y7_2 50 199 | #define Y7_3 51 200 | #define Y7_4 52 201 | #define Y7_5 53 202 | #define Y7_6 54 203 | #define Y7_7 55 204 | //8th output card 205 | #define Y8_0 56 206 | #define Y8_1 57 207 | #define Y8_2 58 208 | #define Y8_3 59 209 | #define Y8_4 60 210 | #define Y8_5 61 211 | #define Y8_6 62 212 | #define Y8_7 63 213 | 214 | #define MAX_INPUT 64 215 | #define MAX_OUTPUT 64 216 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/OpenPLC/Cards_Comm.h: -------------------------------------------------------------------------------- 1 | void clearOutputs() 2 | { 3 | int i; 4 | byte sendData[1] = {0x00}; 5 | for (i = 1; i <= 8; i++) 6 | { 7 | OPLC_send(0x01, SET_OUTPUT, i, sendData); //clear outputs 8 | delay(OPLC_TIMEOUT); //wait to avoid multiple messages on the bus 9 | } 10 | } 11 | 12 | void updateInput() 13 | { 14 | byte dataSize, function, cardAddress, dataReceived[1]; 15 | byte inputsReceived[8]; 16 | boolean hadError = false; 17 | int i, j, vectorIndex; 18 | for (i = 0; i < 8; i++) //reading each input card 19 | { 20 | if (input_card_address[i]) //if there is a card connected with the address 'i+1' 21 | { 22 | //ask for the inputs state 23 | OPLC_send(0x00, READ_INPUT, i + 1, 0x00); //dataSize, function, address, data 24 | if (OPLC_receive(&dataSize, &function, &cardAddress, dataReceived) && function == READ_INPUT) 25 | { 26 | inputsReceived[i] = dataReceived[0]; //save the byte read 27 | } 28 | else 29 | { 30 | Serial.print("ERROR\r"); 31 | hadError = true; 32 | errorCount++; 33 | lastError = millis(); //clear error timeout 34 | } 35 | } 36 | else 37 | { 38 | inputsReceived[i] = 0; 39 | } 40 | } 41 | //copying each bit to the input vector 42 | vectorIndex = 0; 43 | if (!hadError) //if there were no errors 44 | { 45 | for (i = 0; i < 8; i++) 46 | { 47 | for (j = 0; j < 8; j++) 48 | { 49 | inputVector[vectorIndex] = bitRead(inputsReceived[i], j); 50 | vectorIndex++; 51 | } 52 | } 53 | } 54 | 55 | //show inputs read 56 | /* 57 | Serial.print("\rInputs:\r"); 58 | for (i=0;i 0 && dataReceived[1] < 9) //validate card address (must be between 1 and 8) 128 | { 129 | input_card_address[dataReceived[1] - 1] = true; //found an input card 130 | } 131 | break; 132 | case DISCRETE_OUTPUT: 133 | if (dataReceived[1] > 0 && dataReceived[1] < 9) //validate card address (must be between 1 and 8) 134 | { 135 | output_card_address[dataReceived[1] - 1] = true; //found an output card 136 | } 137 | break; 138 | } 139 | } 140 | } 141 | } 142 | 143 | void checkCard(int slotNumber) 144 | { 145 | byte dataSize, function, address, dataReceived[2]; 146 | 147 | Serial.print("Slot"); Serial.print(slotNumber); Serial.print(":\r"); 148 | Serial.flush(); 149 | OPLC_send(0x00, CARD_TYPE, slotNumber, 0x00); 150 | if (OPLC_receive(&dataSize, &function, &address, dataReceived) && function == CARD_TYPE) 151 | { 152 | switch (dataReceived[0]) 153 | { 154 | case DISCRETE_INPUT: 155 | Serial.print("Discrete Input Card\r"); 156 | break; 157 | case DISCRETE_OUTPUT: 158 | Serial.print("Discrete Output Card\r"); 159 | break; 160 | default: 161 | Serial.print("Unrecognized Card\r"); 162 | break; 163 | } 164 | Serial.print("Address:\r"); 165 | //Serial.print("0x"); 166 | Serial.print(dataReceived[1], HEX); 167 | Serial.print('\r'); 168 | } 169 | else if (function == MSG_ERROR) 170 | { 171 | Serial.print("Error communicating with the card\r"); 172 | Serial.print("Address:\r"); 173 | Serial.print("none\r"); 174 | } 175 | else 176 | { 177 | Serial.print("No card installed\r"); 178 | Serial.print("Address:\r"); 179 | Serial.print("none\r"); 180 | } 181 | Serial.flush(); 182 | } -------------------------------------------------------------------------------- /hardware/openplc/avr/platform.txt: -------------------------------------------------------------------------------- 1 | 2 | name=Open PLC Cards (w/ AVR Chips) 3 | version=1.5.8 4 | 5 | 6 | # AVR compile variables 7 | # --------------------- 8 | 9 | # Default "compiler.path" is correct, change only if you want to overidde the initial value 10 | compiler.path={runtime.ide.path}/hardware/tools/avr/bin/ 11 | compiler.c.cmd=avr-gcc 12 | compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections -MMD 13 | # -w flag added to avoid printing a wrong warning http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59396 14 | # This is fixed in gcc 4.8.3 and will be removed as soon as we update the toolchain 15 | compiler.c.elf.flags=-w -Os -Wl,--gc-sections 16 | compiler.c.elf.cmd=avr-gcc 17 | compiler.S.flags=-c -g -x assembler-with-cpp 18 | compiler.cpp.cmd=avr-g++ 19 | compiler.cpp.flags=-c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD 20 | compiler.ar.cmd=avr-ar 21 | compiler.ar.flags=rcs 22 | compiler.objcopy.cmd=avr-objcopy 23 | compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 24 | compiler.elf2hex.flags=-O ihex -R .eeprom 25 | compiler.elf2hex.cmd=avr-objcopy 26 | compiler.ldflags= 27 | compiler.size.cmd=avr-size 28 | 29 | # This can be overriden in boards.txt 30 | build.extra_flags= 31 | 32 | # These can be overridden in platform.local.txt 33 | compiler.c.extra_flags= 34 | compiler.c.elf.extra_flags= 35 | compiler.S.extra_flags= 36 | compiler.cpp.extra_flags= 37 | compiler.ar.extra_flags= 38 | compiler.objcopy.eep.extra_flags= 39 | compiler.elf2hex.extra_flags= 40 | 41 | # AVR compile patterns 42 | # -------------------- 43 | 44 | ## Compile c files 45 | recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" 46 | 47 | ## Compile c++ files 48 | recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" 49 | 50 | ## Compile S files 51 | recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" 52 | 53 | ## Create archives 54 | recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{build.path}/{archive_file}" "{object_file}" 55 | 56 | ## Combine gc-sections, archives, and objects 57 | recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm 58 | 59 | ## Create eeprom 60 | recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} {compiler.objcopy.eep.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep" 61 | 62 | ## Create hex 63 | recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" 64 | 65 | ## Compute size 66 | recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" 67 | recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).* 68 | recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).* 69 | recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).* 70 | 71 | 72 | # AVR Uploader/Programmers tools 73 | # ------------------------------ 74 | 75 | tools.avrdude.cmd.path={runtime.ide.path}/hardware/tools/avr/bin/avrdude 76 | tools.avrdude.config.path={runtime.ide.path}/hardware/tools/avr/etc/avrdude.conf 77 | 78 | tools.avrdude.upload.params.verbose=-v -v -v -v 79 | tools.avrdude.upload.params.quiet=-q -q 80 | tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" {upload.verbose} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i" 81 | 82 | tools.avrdude.program.params.verbose=-v -v -v -v 83 | tools.avrdude.program.params.quiet=-q -q 84 | tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i" 85 | 86 | tools.avrdude.erase.params.verbose=-v -v -v -v 87 | tools.avrdude.erase.params.quiet=-q -q 88 | tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Ulock:w:{bootloader.unlock_bits}:m -Uefuse:w:{bootloader.extended_fuses}:m -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m 89 | 90 | tools.avrdude.bootloader.params.verbose=-v -v -v -v 91 | tools.avrdude.bootloader.params.quiet=-q -q 92 | tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{runtime.platform.path}/bootloaders/{bootloader.file}:i" -Ulock:w:{bootloader.lock_bits}:m 93 | 94 | 95 | # USB Default Flags 96 | # Default blank usb manufacturer will be filled it at compile time 97 | # - from numeric vendor ID, set to Unknown otherwise 98 | build.usb_manufacturer= 99 | build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' 100 | 101 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/wiring_digital.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_digital.c - digital input and output functions 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | 22 | Modified 28 September 2010 by Mark Sproul 23 | 24 | $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ 25 | */ 26 | 27 | #define ARDUINO_MAIN 28 | #include "wiring_private.h" 29 | #include "pins_arduino.h" 30 | 31 | void pinMode(uint8_t pin, uint8_t mode) 32 | { 33 | uint8_t bit = digitalPinToBitMask(pin); 34 | uint8_t port = digitalPinToPort(pin); 35 | volatile uint8_t *reg, *out; 36 | 37 | if (port == NOT_A_PIN) return; 38 | 39 | // JWS: can I let the optimizer do this? 40 | reg = portModeRegister(port); 41 | out = portOutputRegister(port); 42 | 43 | if (mode == INPUT) { 44 | uint8_t oldSREG = SREG; 45 | cli(); 46 | *reg &= ~bit; 47 | *out &= ~bit; 48 | SREG = oldSREG; 49 | } else if (mode == INPUT_PULLUP) { 50 | uint8_t oldSREG = SREG; 51 | cli(); 52 | *reg &= ~bit; 53 | *out |= bit; 54 | SREG = oldSREG; 55 | } else { 56 | uint8_t oldSREG = SREG; 57 | cli(); 58 | *reg |= bit; 59 | SREG = oldSREG; 60 | } 61 | } 62 | 63 | // Forcing this inline keeps the callers from having to push their own stuff 64 | // on the stack. It is a good performance win and only takes 1 more byte per 65 | // user than calling. (It will take more bytes on the 168.) 66 | // 67 | // But shouldn't this be moved into pinMode? Seems silly to check and do on 68 | // each digitalread or write. 69 | // 70 | // Mark Sproul: 71 | // - Removed inline. Save 170 bytes on atmega1280 72 | // - changed to a switch statment; added 32 bytes but much easier to read and maintain. 73 | // - Added more #ifdefs, now compiles for atmega645 74 | // 75 | //static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline)); 76 | //static inline void turnOffPWM(uint8_t timer) 77 | static void turnOffPWM(uint8_t timer) 78 | { 79 | switch (timer) 80 | { 81 | #if defined(TCCR1A) && defined(COM1A1) 82 | case TIMER1A: cbi(TCCR1A, COM1A1); break; 83 | #endif 84 | #if defined(TCCR1A) && defined(COM1B1) 85 | case TIMER1B: cbi(TCCR1A, COM1B1); break; 86 | #endif 87 | #if defined(TCCR1A) && defined(COM1C1) 88 | case TIMER1C: cbi(TCCR1A, COM1C1); break; 89 | #endif 90 | 91 | #if defined(TCCR2) && defined(COM21) 92 | case TIMER2: cbi(TCCR2, COM21); break; 93 | #endif 94 | 95 | #if defined(TCCR0A) && defined(COM0A1) 96 | case TIMER0A: cbi(TCCR0A, COM0A1); break; 97 | #endif 98 | 99 | #if defined(TIMER0B) && defined(COM0B1) 100 | case TIMER0B: cbi(TCCR0A, COM0B1); break; 101 | #endif 102 | #if defined(TCCR2A) && defined(COM2A1) 103 | case TIMER2A: cbi(TCCR2A, COM2A1); break; 104 | #endif 105 | #if defined(TCCR2A) && defined(COM2B1) 106 | case TIMER2B: cbi(TCCR2A, COM2B1); break; 107 | #endif 108 | 109 | #if defined(TCCR3A) && defined(COM3A1) 110 | case TIMER3A: cbi(TCCR3A, COM3A1); break; 111 | #endif 112 | #if defined(TCCR3A) && defined(COM3B1) 113 | case TIMER3B: cbi(TCCR3A, COM3B1); break; 114 | #endif 115 | #if defined(TCCR3A) && defined(COM3C1) 116 | case TIMER3C: cbi(TCCR3A, COM3C1); break; 117 | #endif 118 | 119 | #if defined(TCCR4A) && defined(COM4A1) 120 | case TIMER4A: cbi(TCCR4A, COM4A1); break; 121 | #endif 122 | #if defined(TCCR4A) && defined(COM4B1) 123 | case TIMER4B: cbi(TCCR4A, COM4B1); break; 124 | #endif 125 | #if defined(TCCR4A) && defined(COM4C1) 126 | case TIMER4C: cbi(TCCR4A, COM4C1); break; 127 | #endif 128 | #if defined(TCCR4C) && defined(COM4D1) 129 | case TIMER4D: cbi(TCCR4C, COM4D1); break; 130 | #endif 131 | 132 | #if defined(TCCR5A) 133 | case TIMER5A: cbi(TCCR5A, COM5A1); break; 134 | case TIMER5B: cbi(TCCR5A, COM5B1); break; 135 | case TIMER5C: cbi(TCCR5A, COM5C1); break; 136 | #endif 137 | } 138 | } 139 | 140 | void digitalWrite(uint8_t pin, uint8_t val) 141 | { 142 | uint8_t timer = digitalPinToTimer(pin); 143 | uint8_t bit = digitalPinToBitMask(pin); 144 | uint8_t port = digitalPinToPort(pin); 145 | volatile uint8_t *out; 146 | 147 | if (port == NOT_A_PIN) return; 148 | 149 | // If the pin that support PWM output, we need to turn it off 150 | // before doing a digital write. 151 | if (timer != NOT_ON_TIMER) turnOffPWM(timer); 152 | 153 | out = portOutputRegister(port); 154 | 155 | uint8_t oldSREG = SREG; 156 | cli(); 157 | 158 | if (val == LOW) { 159 | *out &= ~bit; 160 | } else { 161 | *out |= bit; 162 | } 163 | 164 | SREG = oldSREG; 165 | } 166 | 167 | int digitalRead(uint8_t pin) 168 | { 169 | uint8_t timer = digitalPinToTimer(pin); 170 | uint8_t bit = digitalPinToBitMask(pin); 171 | uint8_t port = digitalPinToPort(pin); 172 | 173 | if (port == NOT_A_PIN) return LOW; 174 | 175 | // If the pin that support PWM output, we need to turn it off 176 | // before getting a digital reading. 177 | if (timer != NOT_ON_TIMER) turnOffPWM(timer); 178 | 179 | if (*portInputRegister(port) & bit) return HIGH; 180 | return LOW; 181 | } 182 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/OpenPLC/OPLC_Protocol.h: -------------------------------------------------------------------------------- 1 | /************************************************************* 2 | * OPLC PROTOCOL * 3 | * * 4 | * The OpenPLC protocol stablishes the way that * 5 | * messages are sent from one board to another. * 6 | * These messages must obey the following format: * 7 | * * 8 | * MESSAGE STRUCTURE * 9 | * START | SIZE | FUNCTION | ADDRESS | DATA * 10 | * * 11 | * START = 0x7E * 12 | * SIZE = size of the DATA field (in bytes) * 13 | * FUNCTION = function to be executed * 14 | * ADDRESS = address of the target * 15 | * DATA = data sent or received * 16 | * * 17 | * FUNCTIONS | ARGUMENTS * 18 | * 0x01 = ask for the card's type * 19 | * 0x02 = change card address * 20 | * 0x03 = read discrete inputs * 21 | * 0x04 = set discrete outputs * 22 | * 0x05 = error message * 23 | * * 24 | ************************************************************** 25 | */ 26 | #define OPLC_TIMEOUT 5 27 | #define MAX_FUNCTION_NUMBER 0x05 28 | #define MAX_DATA_SIZE 10 29 | 30 | //OPLC functions 31 | #define CARD_TYPE 0x01 32 | #define CHANGE_ADDRESS 0x02 33 | #define READ_INPUT 0x03 34 | #define SET_OUTPUT 0x04 35 | #define MSG_ERROR 0x05 36 | 37 | void OPLC_send(byte dataSize, byte function, byte address, byte * data) 38 | { 39 | byte header[4]; 40 | header[0] = 0x7E; //start message 41 | header[1] = dataSize; //message size 42 | header[2] = function; //function code 43 | header[3] = address; //address 44 | 45 | //send the header first 46 | int i; 47 | for (i = 0; i < 4; i++) 48 | { 49 | Serial1.write(header[i]); 50 | } 51 | //send the data 52 | for (i = 0; i < dataSize; i++) 53 | { 54 | Serial1.write(data[i]); 55 | } 56 | 57 | //wait until all data is sent 58 | Serial1.flush(); 59 | } 60 | 61 | boolean OPLC_receive(byte * dataSize, byte * function, byte * address, byte * data) 62 | { 63 | long timeout; 64 | byte byteIndex = 0; 65 | byte message[MAX_DATA_SIZE]; 66 | 67 | //start timeout counter 68 | timeout = millis(); 69 | 70 | //enable receiving data through the bus 71 | digitalWrite(DE_PIN, LOW); 72 | 73 | //waiting for the start bit 74 | while (true) 75 | { 76 | if ((millis() - timeout) > OPLC_TIMEOUT) 77 | { 78 | //disable receiving data through the bus 79 | digitalWrite(DE_PIN, HIGH); 80 | delay(1); 81 | return (0); //no message received 82 | } 83 | if (Serial1.available()) 84 | { 85 | if (Serial1.read() == 0x7E) 86 | { 87 | break; //the start bit was received. Get out of the loop. 88 | } 89 | } 90 | } 91 | 92 | timeout = millis(); //reset counter 93 | 94 | //getting message size 95 | while (true) 96 | { 97 | if ((millis() - timeout) > OPLC_TIMEOUT) 98 | { 99 | //disable receiving data through the bus 100 | digitalWrite(DE_PIN, HIGH); 101 | delayMicroseconds(500); 102 | return (0); //no message received 103 | } 104 | if (Serial1.available()) 105 | { 106 | *dataSize = Serial1.read(); 107 | if (*dataSize > MAX_DATA_SIZE) //maximum data size is 10 bytes 108 | { 109 | *function = 0x05; //error function 110 | //disable receiving data through the bus 111 | digitalWrite(DE_PIN, HIGH); 112 | delayMicroseconds(500); 113 | return (1); //received a message but with errors 114 | } 115 | break; //get out of the loop 116 | } 117 | } 118 | 119 | //getting message function 120 | while (true) 121 | { 122 | if ((millis() - timeout) > OPLC_TIMEOUT) 123 | { 124 | //disable receiving data through the bus 125 | digitalWrite(DE_PIN, HIGH); 126 | delayMicroseconds(500); 127 | return (0); //no message received 128 | } 129 | if (Serial1.available()) 130 | { 131 | *function = Serial1.read(); 132 | if (*function > MAX_FUNCTION_NUMBER) //wrong function 133 | { 134 | *function = 0x05; //error function 135 | //disable receiving data through the bus 136 | digitalWrite(DE_PIN, HIGH); 137 | delayMicroseconds(500); 138 | return (1); //received a message but with errors 139 | } 140 | break; //get out of the loop 141 | } 142 | } 143 | 144 | //getting address byte 145 | while (true) 146 | { 147 | if ((millis() - timeout) > OPLC_TIMEOUT) 148 | { 149 | //disable receiving data through the bus 150 | digitalWrite(DE_PIN, HIGH); 151 | delayMicroseconds(500); 152 | return (0); //no message received 153 | } 154 | if (Serial1.available()) //if received the address byte 155 | { 156 | *address = Serial1.read(); //read address 157 | break; //finish loop 158 | } 159 | } 160 | 161 | //getting data 162 | byteIndex = 0; 163 | while (byteIndex < *dataSize) 164 | { 165 | if ((millis() - timeout) > OPLC_TIMEOUT) 166 | { 167 | //disable receiving data through the bus 168 | digitalWrite(DE_PIN, HIGH); 169 | delayMicroseconds(500); 170 | return (0); //no message received 171 | } 172 | if (Serial1.available()) 173 | { 174 | data[byteIndex] = Serial1.read(); 175 | byteIndex++; 176 | } 177 | } 178 | 179 | //disable receiving data through the bus 180 | digitalWrite(DE_PIN, HIGH); 181 | delayMicroseconds(500); 182 | return (1); //message received with no errors 183 | } -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/Print.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print.cpp - Base class that provides print() and println() 3 | Copyright (c) 2008 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "Arduino.h" 27 | 28 | #include "Print.h" 29 | 30 | // Public Methods ////////////////////////////////////////////////////////////// 31 | 32 | /* default implementation: may be overridden */ 33 | size_t Print::write(const uint8_t *buffer, size_t size) 34 | { 35 | size_t n = 0; 36 | while (size--) { 37 | n += write(*buffer++); 38 | } 39 | return n; 40 | } 41 | 42 | size_t Print::print(const __FlashStringHelper *ifsh) 43 | { 44 | PGM_P p = reinterpret_cast(ifsh); 45 | size_t n = 0; 46 | while (1) { 47 | unsigned char c = pgm_read_byte(p++); 48 | if (c == 0) break; 49 | n += write(c); 50 | } 51 | return n; 52 | } 53 | 54 | size_t Print::print(const String &s) 55 | { 56 | return write(s.c_str(), s.length()); 57 | } 58 | 59 | size_t Print::print(const char str[]) 60 | { 61 | return write(str); 62 | } 63 | 64 | size_t Print::print(char c) 65 | { 66 | return write(c); 67 | } 68 | 69 | size_t Print::print(unsigned char b, int base) 70 | { 71 | return print((unsigned long) b, base); 72 | } 73 | 74 | size_t Print::print(int n, int base) 75 | { 76 | return print((long) n, base); 77 | } 78 | 79 | size_t Print::print(unsigned int n, int base) 80 | { 81 | return print((unsigned long) n, base); 82 | } 83 | 84 | size_t Print::print(long n, int base) 85 | { 86 | if (base == 0) { 87 | return write(n); 88 | } else if (base == 10) { 89 | if (n < 0) { 90 | int t = print('-'); 91 | n = -n; 92 | return printNumber(n, 10) + t; 93 | } 94 | return printNumber(n, 10); 95 | } else { 96 | return printNumber(n, base); 97 | } 98 | } 99 | 100 | size_t Print::print(unsigned long n, int base) 101 | { 102 | if (base == 0) return write(n); 103 | else return printNumber(n, base); 104 | } 105 | 106 | size_t Print::print(double n, int digits) 107 | { 108 | return printFloat(n, digits); 109 | } 110 | 111 | size_t Print::println(const __FlashStringHelper *ifsh) 112 | { 113 | size_t n = print(ifsh); 114 | n += println(); 115 | return n; 116 | } 117 | 118 | size_t Print::print(const Printable& x) 119 | { 120 | return x.printTo(*this); 121 | } 122 | 123 | size_t Print::println(void) 124 | { 125 | size_t n = print('\r'); 126 | n += print('\n'); 127 | return n; 128 | } 129 | 130 | size_t Print::println(const String &s) 131 | { 132 | size_t n = print(s); 133 | n += println(); 134 | return n; 135 | } 136 | 137 | size_t Print::println(const char c[]) 138 | { 139 | size_t n = print(c); 140 | n += println(); 141 | return n; 142 | } 143 | 144 | size_t Print::println(char c) 145 | { 146 | size_t n = print(c); 147 | n += println(); 148 | return n; 149 | } 150 | 151 | size_t Print::println(unsigned char b, int base) 152 | { 153 | size_t n = print(b, base); 154 | n += println(); 155 | return n; 156 | } 157 | 158 | size_t Print::println(int num, int base) 159 | { 160 | size_t n = print(num, base); 161 | n += println(); 162 | return n; 163 | } 164 | 165 | size_t Print::println(unsigned int num, int base) 166 | { 167 | size_t n = print(num, base); 168 | n += println(); 169 | return n; 170 | } 171 | 172 | size_t Print::println(long num, int base) 173 | { 174 | size_t n = print(num, base); 175 | n += println(); 176 | return n; 177 | } 178 | 179 | size_t Print::println(unsigned long num, int base) 180 | { 181 | size_t n = print(num, base); 182 | n += println(); 183 | return n; 184 | } 185 | 186 | size_t Print::println(double num, int digits) 187 | { 188 | size_t n = print(num, digits); 189 | n += println(); 190 | return n; 191 | } 192 | 193 | size_t Print::println(const Printable& x) 194 | { 195 | size_t n = print(x); 196 | n += println(); 197 | return n; 198 | } 199 | 200 | // Private Methods ///////////////////////////////////////////////////////////// 201 | 202 | size_t Print::printNumber(unsigned long n, uint8_t base) { 203 | char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. 204 | char *str = &buf[sizeof(buf) - 1]; 205 | 206 | *str = '\0'; 207 | 208 | // prevent crash if called with base == 1 209 | if (base < 2) base = 10; 210 | 211 | do { 212 | unsigned long m = n; 213 | n /= base; 214 | char c = m - base * n; 215 | *--str = c < 10 ? c + '0' : c + 'A' - 10; 216 | } while(n); 217 | 218 | return write(str); 219 | } 220 | 221 | size_t Print::printFloat(double number, uint8_t digits) 222 | { 223 | size_t n = 0; 224 | 225 | if (isnan(number)) return print("nan"); 226 | if (isinf(number)) return print("inf"); 227 | if (number > 4294967040.0) return print ("ovf"); // constant determined empirically 228 | if (number <-4294967040.0) return print ("ovf"); // constant determined empirically 229 | 230 | // Handle negative numbers 231 | if (number < 0.0) 232 | { 233 | n += print('-'); 234 | number = -number; 235 | } 236 | 237 | // Round correctly so that print(1.999, 2) prints as "2.00" 238 | double rounding = 0.5; 239 | for (uint8_t i=0; i 0) { 251 | n += print("."); 252 | } 253 | 254 | // Extract digits from the remainder one at a time 255 | while (digits-- > 0) 256 | { 257 | remainder *= 10.0; 258 | int toPrint = int(remainder); 259 | n += print(toPrint); 260 | remainder -= toPrint; 261 | } 262 | 263 | return n; 264 | } 265 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/CDC.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* Copyright (c) 2011, Peter Barrett 4 | ** 5 | ** Permission to use, copy, modify, and/or distribute this software for 6 | ** any purpose with or without fee is hereby granted, provided that the 7 | ** above copyright notice and this permission notice appear in all copies. 8 | ** 9 | ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 12 | ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES 13 | ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 14 | ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 15 | ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 16 | ** SOFTWARE. 17 | */ 18 | 19 | #include "USBAPI.h" 20 | #include 21 | 22 | #if defined(USBCON) 23 | #ifdef CDC_ENABLED 24 | 25 | typedef struct 26 | { 27 | u32 dwDTERate; 28 | u8 bCharFormat; 29 | u8 bParityType; 30 | u8 bDataBits; 31 | u8 lineState; 32 | } LineInfo; 33 | 34 | static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 }; 35 | 36 | #define WEAK __attribute__ ((weak)) 37 | 38 | extern const CDCDescriptor _cdcInterface PROGMEM; 39 | const CDCDescriptor _cdcInterface = 40 | { 41 | D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1), 42 | 43 | // CDC communication interface 44 | D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0), 45 | D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd) 46 | D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not) 47 | D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported 48 | D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 49 | D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40), 50 | 51 | // CDC data interface 52 | D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), 53 | D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x40,0), 54 | D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0) 55 | }; 56 | 57 | int WEAK CDC_GetInterface(u8* interfaceNum) 58 | { 59 | interfaceNum[0] += 2; // uses 2 60 | return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface)); 61 | } 62 | 63 | bool WEAK CDC_Setup(Setup& setup) 64 | { 65 | u8 r = setup.bRequest; 66 | u8 requestType = setup.bmRequestType; 67 | 68 | if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) 69 | { 70 | if (CDC_GET_LINE_CODING == r) 71 | { 72 | USB_SendControl(0,(void*)&_usbLineInfo,7); 73 | return true; 74 | } 75 | } 76 | 77 | if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) 78 | { 79 | if (CDC_SET_LINE_CODING == r) 80 | { 81 | USB_RecvControl((void*)&_usbLineInfo,7); 82 | } 83 | 84 | if (CDC_SET_CONTROL_LINE_STATE == r) 85 | { 86 | _usbLineInfo.lineState = setup.wValueL; 87 | } 88 | 89 | if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r) 90 | { 91 | // auto-reset into the bootloader is triggered when the port, already 92 | // open at 1200 bps, is closed. this is the signal to start the watchdog 93 | // with a relatively long period so it can finish housekeeping tasks 94 | // like servicing endpoints before the sketch ends 95 | 96 | // We check DTR state to determine if host port is open (bit 0 of lineState). 97 | if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) 98 | { 99 | *(uint16_t *)0x0800 = 0x7777; 100 | wdt_enable(WDTO_120MS); 101 | } 102 | else 103 | { 104 | // Most OSs do some intermediate steps when configuring ports and DTR can 105 | // twiggle more than once before stabilizing. 106 | // To avoid spurious resets we set the watchdog to 250ms and eventually 107 | // cancel if DTR goes back high. 108 | 109 | wdt_disable(); 110 | wdt_reset(); 111 | *(uint16_t *)0x0800 = 0x0; 112 | } 113 | } 114 | return true; 115 | } 116 | return false; 117 | } 118 | 119 | 120 | void Serial_::begin(unsigned long /* baud_count */) 121 | { 122 | peek_buffer = -1; 123 | } 124 | 125 | void Serial_::begin(unsigned long /* baud_count */, byte /* config */) 126 | { 127 | peek_buffer = -1; 128 | } 129 | 130 | void Serial_::end(void) 131 | { 132 | } 133 | 134 | int Serial_::available(void) 135 | { 136 | if (peek_buffer >= 0) { 137 | return 1 + USB_Available(CDC_RX); 138 | } 139 | return USB_Available(CDC_RX); 140 | } 141 | 142 | int Serial_::peek(void) 143 | { 144 | if (peek_buffer < 0) 145 | peek_buffer = USB_Recv(CDC_RX); 146 | return peek_buffer; 147 | } 148 | 149 | int Serial_::read(void) 150 | { 151 | if (peek_buffer >= 0) { 152 | int c = peek_buffer; 153 | peek_buffer = -1; 154 | return c; 155 | } 156 | return USB_Recv(CDC_RX); 157 | } 158 | 159 | void Serial_::flush(void) 160 | { 161 | USB_Flush(CDC_TX); 162 | } 163 | 164 | size_t Serial_::write(uint8_t c) 165 | { 166 | return write(&c, 1); 167 | } 168 | 169 | size_t Serial_::write(const uint8_t *buffer, size_t size) 170 | { 171 | /* only try to send bytes if the high-level CDC connection itself 172 | is open (not just the pipe) - the OS should set lineState when the port 173 | is opened and clear lineState when the port is closed. 174 | bytes sent before the user opens the connection or after 175 | the connection is closed are lost - just like with a UART. */ 176 | 177 | // TODO - ZE - check behavior on different OSes and test what happens if an 178 | // open connection isn't broken cleanly (cable is yanked out, host dies 179 | // or locks up, or host virtual serial port hangs) 180 | if (_usbLineInfo.lineState > 0) { 181 | int r = USB_Send(CDC_TX,buffer,size); 182 | if (r > 0) { 183 | return r; 184 | } else { 185 | setWriteError(); 186 | return 0; 187 | } 188 | } 189 | setWriteError(); 190 | return 0; 191 | } 192 | 193 | // This operator is a convenient way for a sketch to check whether the 194 | // port has actually been configured and opened by the host (as opposed 195 | // to just being connected to the host). It can be used, for example, in 196 | // setup() before printing to ensure that an application on the host is 197 | // actually ready to receive and display the data. 198 | // We add a short delay before returning to fix a bug observed by Federico 199 | // where the port is configured (lineState != 0) but not quite opened. 200 | Serial_::operator bool() { 201 | bool result = false; 202 | if (_usbLineInfo.lineState > 0) 203 | result = true; 204 | delay(10); 205 | return result; 206 | } 207 | 208 | Serial_ Serial; 209 | 210 | #endif 211 | #endif /* if defined(USBCON) */ 212 | -------------------------------------------------------------------------------- /hardware/openplc/avr/variants/iocard/pins_arduino.h: -------------------------------------------------------------------------------- 1 | /* 2 | pins_arduino.h - Pin definition functions for Arduino 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2007 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | 22 | $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ 23 | */ 24 | 25 | #ifndef Pins_Arduino_h 26 | #define Pins_Arduino_h 27 | 28 | #include 29 | 30 | #define NUM_DIGITAL_PINS 20 31 | #define NUM_ANALOG_INPUTS 6 32 | #define analogInputToDigitalPin(p) ((p < 6) ? (p) + 14 : -1) 33 | 34 | #if defined(__AVR_ATmega8__) 35 | #define digitalPinHasPWM(p) ((p) == 9 || (p) == 10 || (p) == 11) 36 | #else 37 | #define digitalPinHasPWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11) 38 | #endif 39 | 40 | static const uint8_t SS = 10; 41 | static const uint8_t MOSI = 11; 42 | static const uint8_t MISO = 12; 43 | static const uint8_t SCK = 13; 44 | 45 | static const uint8_t SDA = 18; 46 | static const uint8_t SCL = 19; 47 | #define LED_BUILTIN 13 48 | 49 | static const uint8_t A0 = 14; 50 | static const uint8_t A1 = 15; 51 | static const uint8_t A2 = 16; 52 | static const uint8_t A3 = 17; 53 | static const uint8_t A4 = 18; 54 | static const uint8_t A5 = 19; 55 | static const uint8_t A6 = 20; 56 | static const uint8_t A7 = 21; 57 | 58 | #define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0)) 59 | #define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1)) 60 | #define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0)))) 61 | #define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14))) 62 | 63 | #define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : NOT_AN_INTERRUPT)) 64 | 65 | #ifdef ARDUINO_MAIN 66 | 67 | // On the Arduino board, digital pins are also used 68 | // for the analog output (software PWM). Analog input 69 | // pins are a separate set. 70 | 71 | // ATMEL ATMEGA8 & 168 / ARDUINO 72 | // 73 | // +-\/-+ 74 | // PC6 1| |28 PC5 (AI 5) 75 | // (D 0) PD0 2| |27 PC4 (AI 4) 76 | // (D 1) PD1 3| |26 PC3 (AI 3) 77 | // (D 2) PD2 4| |25 PC2 (AI 2) 78 | // PWM+ (D 3) PD3 5| |24 PC1 (AI 1) 79 | // (D 4) PD4 6| |23 PC0 (AI 0) 80 | // VCC 7| |22 GND 81 | // GND 8| |21 AREF 82 | // PB6 9| |20 AVCC 83 | // PB7 10| |19 PB5 (D 13) 84 | // PWM+ (D 5) PD5 11| |18 PB4 (D 12) 85 | // PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM 86 | // (D 7) PD7 13| |16 PB2 (D 10) PWM 87 | // (D 8) PB0 14| |15 PB1 (D 9) PWM 88 | // +----+ 89 | // 90 | // (PWM+ indicates the additional PWM pins on the ATmega168.) 91 | 92 | // ATMEL ATMEGA1280 / ARDUINO 93 | // 94 | // 0-7 PE0-PE7 works 95 | // 8-13 PB0-PB5 works 96 | // 14-21 PA0-PA7 works 97 | // 22-29 PH0-PH7 works 98 | // 30-35 PG5-PG0 works 99 | // 36-43 PC7-PC0 works 100 | // 44-51 PJ7-PJ0 works 101 | // 52-59 PL7-PL0 works 102 | // 60-67 PD7-PD0 works 103 | // A0-A7 PF0-PF7 104 | // A8-A15 PK0-PK7 105 | 106 | 107 | // these arrays map port names (e.g. port B) to the 108 | // appropriate addresses for various functions (e.g. reading 109 | // and writing) 110 | const uint16_t PROGMEM port_to_mode_PGM[] = { 111 | NOT_A_PORT, 112 | NOT_A_PORT, 113 | (uint16_t) &DDRB, 114 | (uint16_t) &DDRC, 115 | (uint16_t) &DDRD, 116 | }; 117 | 118 | const uint16_t PROGMEM port_to_output_PGM[] = { 119 | NOT_A_PORT, 120 | NOT_A_PORT, 121 | (uint16_t) &PORTB, 122 | (uint16_t) &PORTC, 123 | (uint16_t) &PORTD, 124 | }; 125 | 126 | const uint16_t PROGMEM port_to_input_PGM[] = { 127 | NOT_A_PORT, 128 | NOT_A_PORT, 129 | (uint16_t) &PINB, 130 | (uint16_t) &PINC, 131 | (uint16_t) &PIND, 132 | }; 133 | 134 | const uint8_t PROGMEM digital_pin_to_port_PGM[] = { 135 | PD, /* 0 */ 136 | PD, 137 | PD, 138 | PD, 139 | PD, 140 | PD, 141 | PD, 142 | PD, 143 | PB, /* 8 */ 144 | PB, 145 | PB, 146 | PB, 147 | PB, 148 | PB, 149 | PC, /* 14 */ 150 | PC, 151 | PC, 152 | PC, 153 | PC, 154 | PC, 155 | }; 156 | 157 | const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { 158 | _BV(0), /* 0, port D */ 159 | _BV(1), 160 | _BV(2), 161 | _BV(3), 162 | _BV(4), 163 | _BV(5), 164 | _BV(6), 165 | _BV(7), 166 | _BV(0), /* 8, port B */ 167 | _BV(1), 168 | _BV(2), 169 | _BV(3), 170 | _BV(4), 171 | _BV(5), 172 | _BV(0), /* 14, port C */ 173 | _BV(1), 174 | _BV(2), 175 | _BV(3), 176 | _BV(4), 177 | _BV(5), 178 | }; 179 | 180 | const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { 181 | NOT_ON_TIMER, /* 0 - port D */ 182 | NOT_ON_TIMER, 183 | NOT_ON_TIMER, 184 | // on the ATmega168, digital pin 3 has hardware pwm 185 | #if defined(__AVR_ATmega8__) 186 | NOT_ON_TIMER, 187 | #else 188 | TIMER2B, 189 | #endif 190 | NOT_ON_TIMER, 191 | // on the ATmega168, digital pins 5 and 6 have hardware pwm 192 | #if defined(__AVR_ATmega8__) 193 | NOT_ON_TIMER, 194 | NOT_ON_TIMER, 195 | #else 196 | TIMER0B, 197 | TIMER0A, 198 | #endif 199 | NOT_ON_TIMER, 200 | NOT_ON_TIMER, /* 8 - port B */ 201 | TIMER1A, 202 | TIMER1B, 203 | #if defined(__AVR_ATmega8__) 204 | TIMER2, 205 | #else 206 | TIMER2A, 207 | #endif 208 | NOT_ON_TIMER, 209 | NOT_ON_TIMER, 210 | NOT_ON_TIMER, 211 | NOT_ON_TIMER, /* 14 - port C */ 212 | NOT_ON_TIMER, 213 | NOT_ON_TIMER, 214 | NOT_ON_TIMER, 215 | NOT_ON_TIMER, 216 | }; 217 | 218 | #endif 219 | 220 | // These serial port names are intended to allow libraries and architecture-neutral 221 | // sketches to automatically default to the correct port name for a particular type 222 | // of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, 223 | // the first hardware serial port whose RX/TX pins are not dedicated to another use. 224 | // 225 | // SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor 226 | // 227 | // SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial 228 | // 229 | // SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library 230 | // 231 | // SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. 232 | // 233 | // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX 234 | // pins are NOT connected to anything by default. 235 | #define SERIAL_PORT_MONITOR Serial 236 | #define SERIAL_PORT_HARDWARE Serial 237 | 238 | #endif 239 | -------------------------------------------------------------------------------- /hardware/openplc/avr/libraries/Mudbus/Mudbus.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Mudbus.cpp - an Arduino library for a Modbus TCP slave. 3 | Copyright (C) 2011 Dee Wykoff 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "Mudbus.h" 20 | 21 | EthernetServer MbServer(MB_PORT); 22 | 23 | Mudbus::Mudbus() 24 | { 25 | } 26 | 27 | void Mudbus::Run() 28 | { 29 | Runs = 1 + Runs * (Runs < 999); 30 | 31 | //****************** Read from socket **************** 32 | EthernetClient client = MbServer.available(); 33 | if (client.available()) 34 | { 35 | Reads = 1 + Reads * (Reads < 999); 36 | int i = 0; 37 | while (client.available()) 38 | { 39 | ByteArray[i] = client.read(); 40 | i++; 41 | } 42 | SetFC(ByteArray[7]); //Byte 7 of request is FC 43 | if (!Active) 44 | { 45 | Active = true; 46 | PreviousActivityTime = millis(); 47 | } 48 | } 49 | if (millis() > (PreviousActivityTime + 60000)) 50 | { 51 | if (Active) 52 | { 53 | Active = false; 54 | } 55 | } 56 | 57 | int Start, WordDataLength, ByteDataLength, CoilDataLength, InputDataLength, MessageLength; 58 | 59 | //****************** Read Coils ********************** 60 | if (FC == MB_FC_READ_COILS) 61 | { 62 | Start = word(ByteArray[8], ByteArray[9]); 63 | CoilDataLength = word(ByteArray[10], ByteArray[11]); 64 | //calculating the size of the message in bytes 65 | ByteDataLength = CoilDataLength / 8; 66 | if (ByteDataLength * 8 < CoilDataLength) ByteDataLength++; 67 | CoilDataLength = ByteDataLength * 8; 68 | ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one. 69 | ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data). 70 | for (int i = 0; i < ByteDataLength ; i++) 71 | { 72 | for (int j = 0; j < 8; j++) 73 | { 74 | bitWrite(ByteArray[9 + i], j, C[Start + i * 8 + j]); 75 | } 76 | } 77 | MessageLength = ByteDataLength + 9; 78 | client.write(ByteArray, MessageLength); 79 | Writes = 1 + Writes * (Writes < 999); 80 | FC = MB_FC_NONE; 81 | } 82 | //*************** Read Discrete Inputs *************** 83 | if (FC == MB_FC_READ_INPUTS) 84 | { 85 | Start = word(ByteArray[8], ByteArray[9]); 86 | InputDataLength = word(ByteArray[10], ByteArray[11]); 87 | ByteDataLength = InputDataLength / 8; 88 | if (ByteDataLength * 8 < InputDataLength) ByteDataLength++; 89 | InputDataLength = ByteDataLength * 8; 90 | ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one. 91 | ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data). 92 | for (int i = 0; i < ByteDataLength ; i++) 93 | { 94 | for (int j = 0; j < 8; j++) 95 | { 96 | bitWrite(ByteArray[9 + i], j, I[Start + i * 8 + j]); 97 | } 98 | } 99 | MessageLength = ByteDataLength + 9; 100 | client.write(ByteArray, MessageLength); 101 | Writes = 1 + Writes * (Writes < 999); 102 | FC = MB_FC_NONE; 103 | } 104 | //****************** Read Registers ****************** 105 | if (FC == MB_FC_READ_REGISTERS) 106 | { 107 | Start = word(ByteArray[8], ByteArray[9]); 108 | WordDataLength = word(ByteArray[10], ByteArray[11]); 109 | ByteDataLength = WordDataLength * 2; 110 | ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one. 111 | ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data). 112 | for (int i = 0; i < WordDataLength; i++) 113 | { 114 | ByteArray[ 9 + i * 2] = highByte(R[Start + i]); 115 | ByteArray[10 + i * 2] = lowByte(R[Start + i]); 116 | } 117 | MessageLength = ByteDataLength + 9; 118 | client.write(ByteArray, MessageLength); 119 | Writes = 1 + Writes * (Writes < 999); 120 | FC = MB_FC_NONE; 121 | } 122 | 123 | //****************** Write Coil ********************** 124 | if (FC == MB_FC_WRITE_COIL) 125 | { 126 | Start = word(ByteArray[8], ByteArray[9]); 127 | C[Start] = word(ByteArray[10], ByteArray[11]) > 0; 128 | ByteArray[5] = 2; //Number of bytes after this one. 129 | MessageLength = 8; 130 | client.write(ByteArray, MessageLength); 131 | Writes = 1 + Writes * (Writes < 999); 132 | FC = MB_FC_NONE; 133 | } 134 | 135 | //****************** Write Register ****************** 136 | if (FC == MB_FC_WRITE_REGISTER) 137 | { 138 | Start = word(ByteArray[8], ByteArray[9]); 139 | R[Start] = word(ByteArray[10], ByteArray[11]); 140 | ByteArray[5] = 6; //Number of bytes after this one. 141 | MessageLength = 12; 142 | client.write(ByteArray, MessageLength); 143 | Writes = 1 + Writes * (Writes < 999); 144 | FC = MB_FC_NONE; 145 | } 146 | 147 | 148 | //****************** Write Multiple Coils ********************** 149 | //Function codes 15 & 16 by Martin Pettersson http://siamect.com 150 | if (FC == MB_FC_WRITE_MULTIPLE_COILS) 151 | { 152 | Start = word(ByteArray[8], ByteArray[9]); 153 | CoilDataLength = word(ByteArray[10], ByteArray[11]); 154 | ByteDataLength = CoilDataLength / 8; 155 | if (ByteDataLength * 8 < CoilDataLength) ByteDataLength++; 156 | CoilDataLength = ByteDataLength * 8; 157 | ByteArray[5] = ByteDataLength + 5; //Number of bytes after this one. 158 | for (int i = 0; i < ByteDataLength ; i++) 159 | { 160 | for (int j = 0; j < 8; j++) 161 | { 162 | C[Start + i * 8 + j] = bitRead( ByteArray[13 + i], j); 163 | } 164 | } 165 | MessageLength = 12; 166 | client.write(ByteArray, MessageLength); 167 | Writes = 1 + Writes * (Writes < 999); 168 | FC = MB_FC_NONE; 169 | } 170 | 171 | 172 | //****************** Write Multiple Registers ****************** 173 | //Function codes 15 & 16 by Martin Pettersson http://siamect.com 174 | if (FC == MB_FC_WRITE_MULTIPLE_REGISTERS) 175 | { 176 | Start = word(ByteArray[8], ByteArray[9]); 177 | WordDataLength = word(ByteArray[10], ByteArray[11]); 178 | ByteDataLength = WordDataLength * 2; 179 | ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one. 180 | for (int i = 0; i < WordDataLength; i++) 181 | { 182 | R[Start + i] = word(ByteArray[ 13 + i * 2], ByteArray[14 + i * 2]); 183 | } 184 | MessageLength = 12; 185 | client.write(ByteArray, MessageLength); 186 | Writes = 1 + Writes * (Writes < 999); 187 | FC = MB_FC_NONE; 188 | } 189 | } 190 | 191 | 192 | void Mudbus::SetFC(int fc) 193 | { 194 | if (fc == 1) FC = MB_FC_READ_COILS; 195 | if (fc == 2) FC = MB_FC_READ_INPUTS; 196 | if (fc == 3) FC = MB_FC_READ_REGISTERS; 197 | if (fc == 5) FC = MB_FC_WRITE_COIL; 198 | if (fc == 6) FC = MB_FC_WRITE_REGISTER; 199 | if (fc == 15) FC = MB_FC_WRITE_MULTIPLE_COILS; 200 | if (fc == 16) FC = MB_FC_WRITE_MULTIPLE_REGISTERS; 201 | } 202 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/USBAPI.h: -------------------------------------------------------------------------------- 1 | /* 2 | USBAPI.h 3 | Copyright (c) 2005-2014 Arduino. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef __USBAPI__ 21 | #define __USBAPI__ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | typedef unsigned char u8; 30 | typedef unsigned short u16; 31 | typedef unsigned long u32; 32 | 33 | #include "Arduino.h" 34 | 35 | #if defined(USBCON) 36 | 37 | #include "USBDesc.h" 38 | #include "USBCore.h" 39 | 40 | //================================================================================ 41 | //================================================================================ 42 | // USB 43 | 44 | class USBDevice_ 45 | { 46 | public: 47 | USBDevice_(); 48 | bool configured(); 49 | 50 | void attach(); 51 | void detach(); // Serial port goes down too... 52 | void poll(); 53 | }; 54 | extern USBDevice_ USBDevice; 55 | 56 | //================================================================================ 57 | //================================================================================ 58 | // Serial over CDC (Serial1 is the physical port) 59 | 60 | struct ring_buffer; 61 | 62 | #if (RAMEND < 1000) 63 | #define SERIAL_BUFFER_SIZE 16 64 | #else 65 | #define SERIAL_BUFFER_SIZE 64 66 | #endif 67 | 68 | class Serial_ : public Stream 69 | { 70 | private: 71 | int peek_buffer; 72 | public: 73 | Serial_() { peek_buffer = -1; }; 74 | void begin(unsigned long); 75 | void begin(unsigned long, uint8_t); 76 | void end(void); 77 | 78 | virtual int available(void); 79 | virtual int peek(void); 80 | virtual int read(void); 81 | virtual void flush(void); 82 | virtual size_t write(uint8_t); 83 | virtual size_t write(const uint8_t*, size_t); 84 | using Print::write; // pull in write(str) and write(buf, size) from Print 85 | operator bool(); 86 | 87 | volatile uint8_t _rx_buffer_head; 88 | volatile uint8_t _rx_buffer_tail; 89 | unsigned char _rx_buffer[SERIAL_BUFFER_SIZE]; 90 | }; 91 | extern Serial_ Serial; 92 | 93 | #define HAVE_CDCSERIAL 94 | 95 | //================================================================================ 96 | //================================================================================ 97 | // Mouse 98 | 99 | #define MOUSE_LEFT 1 100 | #define MOUSE_RIGHT 2 101 | #define MOUSE_MIDDLE 4 102 | #define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) 103 | 104 | class Mouse_ 105 | { 106 | private: 107 | uint8_t _buttons; 108 | void buttons(uint8_t b); 109 | public: 110 | Mouse_(void); 111 | void begin(void); 112 | void end(void); 113 | void click(uint8_t b = MOUSE_LEFT); 114 | void move(signed char x, signed char y, signed char wheel = 0); 115 | void press(uint8_t b = MOUSE_LEFT); // press LEFT by default 116 | void release(uint8_t b = MOUSE_LEFT); // release LEFT by default 117 | bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default 118 | }; 119 | extern Mouse_ Mouse; 120 | 121 | //================================================================================ 122 | //================================================================================ 123 | // Keyboard 124 | 125 | #define KEY_LEFT_CTRL 0x80 126 | #define KEY_LEFT_SHIFT 0x81 127 | #define KEY_LEFT_ALT 0x82 128 | #define KEY_LEFT_GUI 0x83 129 | #define KEY_RIGHT_CTRL 0x84 130 | #define KEY_RIGHT_SHIFT 0x85 131 | #define KEY_RIGHT_ALT 0x86 132 | #define KEY_RIGHT_GUI 0x87 133 | 134 | #define KEY_UP_ARROW 0xDA 135 | #define KEY_DOWN_ARROW 0xD9 136 | #define KEY_LEFT_ARROW 0xD8 137 | #define KEY_RIGHT_ARROW 0xD7 138 | #define KEY_BACKSPACE 0xB2 139 | #define KEY_TAB 0xB3 140 | #define KEY_RETURN 0xB0 141 | #define KEY_ESC 0xB1 142 | #define KEY_INSERT 0xD1 143 | #define KEY_DELETE 0xD4 144 | #define KEY_PAGE_UP 0xD3 145 | #define KEY_PAGE_DOWN 0xD6 146 | #define KEY_HOME 0xD2 147 | #define KEY_END 0xD5 148 | #define KEY_CAPS_LOCK 0xC1 149 | #define KEY_F1 0xC2 150 | #define KEY_F2 0xC3 151 | #define KEY_F3 0xC4 152 | #define KEY_F4 0xC5 153 | #define KEY_F5 0xC6 154 | #define KEY_F6 0xC7 155 | #define KEY_F7 0xC8 156 | #define KEY_F8 0xC9 157 | #define KEY_F9 0xCA 158 | #define KEY_F10 0xCB 159 | #define KEY_F11 0xCC 160 | #define KEY_F12 0xCD 161 | 162 | // Low level key report: up to 6 keys and shift, ctrl etc at once 163 | typedef struct 164 | { 165 | uint8_t modifiers; 166 | uint8_t reserved; 167 | uint8_t keys[6]; 168 | } KeyReport; 169 | 170 | class Keyboard_ : public Print 171 | { 172 | private: 173 | KeyReport _keyReport; 174 | void sendReport(KeyReport* keys); 175 | public: 176 | Keyboard_(void); 177 | void begin(void); 178 | void end(void); 179 | virtual size_t write(uint8_t k); 180 | virtual size_t press(uint8_t k); 181 | virtual size_t release(uint8_t k); 182 | virtual void releaseAll(void); 183 | }; 184 | extern Keyboard_ Keyboard; 185 | 186 | //================================================================================ 187 | //================================================================================ 188 | // Low level API 189 | 190 | typedef struct 191 | { 192 | uint8_t bmRequestType; 193 | uint8_t bRequest; 194 | uint8_t wValueL; 195 | uint8_t wValueH; 196 | uint16_t wIndex; 197 | uint16_t wLength; 198 | } Setup; 199 | 200 | //================================================================================ 201 | //================================================================================ 202 | // HID 'Driver' 203 | 204 | int HID_GetInterface(uint8_t* interfaceNum); 205 | int HID_GetDescriptor(int i); 206 | bool HID_Setup(Setup& setup); 207 | void HID_SendReport(uint8_t id, const void* data, int len); 208 | 209 | //================================================================================ 210 | //================================================================================ 211 | // MSC 'Driver' 212 | 213 | int MSC_GetInterface(uint8_t* interfaceNum); 214 | int MSC_GetDescriptor(int i); 215 | bool MSC_Setup(Setup& setup); 216 | bool MSC_Data(uint8_t rx,uint8_t tx); 217 | 218 | //================================================================================ 219 | //================================================================================ 220 | // CSC 'Driver' 221 | 222 | int CDC_GetInterface(uint8_t* interfaceNum); 223 | int CDC_GetDescriptor(int i); 224 | bool CDC_Setup(Setup& setup); 225 | 226 | //================================================================================ 227 | //================================================================================ 228 | 229 | #define TRANSFER_PGM 0x80 230 | #define TRANSFER_RELEASE 0x40 231 | #define TRANSFER_ZERO 0x20 232 | 233 | int USB_SendControl(uint8_t flags, const void* d, int len); 234 | int USB_RecvControl(void* d, int len); 235 | 236 | uint8_t USB_Available(uint8_t ep); 237 | int USB_Send(uint8_t ep, const void* data, int len); // blocking 238 | int USB_Recv(uint8_t ep, void* data, int len); // non-blocking 239 | int USB_Recv(uint8_t ep); // non-blocking 240 | void USB_Flush(uint8_t ep); 241 | 242 | #endif 243 | 244 | #endif /* if defined(USBCON) */ 245 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/Arduino-core.h: -------------------------------------------------------------------------------- 1 | /* 2 | Arduino.h - Main include file for the Arduino SDK 3 | Copyright (c) 2005-2013 Arduino Team. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Arduino_h 21 | #define Arduino_h 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include "binary.h" 33 | 34 | #ifdef __cplusplus 35 | extern "C"{ 36 | #endif 37 | 38 | void yield(void); 39 | 40 | #define HIGH 0x1 41 | #define LOW 0x0 42 | 43 | #define INPUT 0x0 44 | #define OUTPUT 0x1 45 | #define INPUT_PULLUP 0x2 46 | 47 | #define PI 3.1415926535897932384626433832795 48 | #define HALF_PI 1.5707963267948966192313216916398 49 | #define TWO_PI 6.283185307179586476925286766559 50 | #define DEG_TO_RAD 0.017453292519943295769236907684886 51 | #define RAD_TO_DEG 57.295779513082320876798154814105 52 | #define EULER 2.718281828459045235360287471352 53 | 54 | #define SERIAL 0x0 55 | #define DISPLAY 0x1 56 | 57 | #define LSBFIRST 0 58 | #define MSBFIRST 1 59 | 60 | #define CHANGE 1 61 | #define FALLING 2 62 | #define RISING 3 63 | 64 | #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) 65 | #define DEFAULT 0 66 | #define EXTERNAL 1 67 | #define INTERNAL 2 68 | #else 69 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) 70 | #define INTERNAL1V1 2 71 | #define INTERNAL2V56 3 72 | #else 73 | #define INTERNAL 3 74 | #endif 75 | #define DEFAULT 1 76 | #define EXTERNAL 0 77 | #endif 78 | 79 | // undefine stdlib's abs if encountered 80 | #ifdef abs 81 | #undef abs 82 | #endif 83 | 84 | #define min(a,b) ((a)<(b)?(a):(b)) 85 | #define max(a,b) ((a)>(b)?(a):(b)) 86 | #define abs(x) ((x)>0?(x):-(x)) 87 | #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) 88 | #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) 89 | #define radians(deg) ((deg)*DEG_TO_RAD) 90 | #define degrees(rad) ((rad)*RAD_TO_DEG) 91 | #define sq(x) ((x)*(x)) 92 | 93 | #define interrupts() sei() 94 | #define noInterrupts() cli() 95 | 96 | #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) 97 | #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) 98 | #define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) 99 | 100 | #define lowByte(w) ((uint8_t) ((w) & 0xff)) 101 | #define highByte(w) ((uint8_t) ((w) >> 8)) 102 | 103 | #define bitRead(value, bit) (((value) >> (bit)) & 0x01) 104 | #define bitSet(value, bit) ((value) |= (1UL << (bit))) 105 | #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) 106 | #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) 107 | 108 | // avr-libc defines _NOP() since 1.6.2 109 | #ifndef _NOP 110 | #define _NOP() do { __asm__ volatile ("nop"); } while (0) 111 | #endif 112 | 113 | typedef unsigned int word; 114 | 115 | #define bit(b) (1UL << (b)) 116 | 117 | typedef uint8_t boolean; 118 | typedef uint8_t byte; 119 | 120 | void init(void); 121 | void initVariant(void); 122 | 123 | int atexit(void (*func)()) __attribute__((weak)); 124 | 125 | void pinMode(uint8_t, uint8_t); 126 | void digitalWrite(uint8_t, uint8_t); 127 | int digitalRead(uint8_t); 128 | int analogRead(uint8_t); 129 | void analogReference(uint8_t mode); 130 | void analogWrite(uint8_t, int); 131 | 132 | unsigned long millis(void); 133 | unsigned long micros(void); 134 | void delay(unsigned long); 135 | void delayMicroseconds(unsigned int us); 136 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); 137 | 138 | void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); 139 | uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); 140 | 141 | void attachInterrupt(uint8_t, void (*)(void), int mode); 142 | void detachInterrupt(uint8_t); 143 | 144 | void setup(void); 145 | void loop(void); 146 | 147 | // Get the bit location within the hardware port of the given virtual pin. 148 | // This comes from the pins_*.c file for the active board configuration. 149 | 150 | #define analogInPinToBit(P) (P) 151 | 152 | // On the ATmega1280, the addresses of some of the port registers are 153 | // greater than 255, so we can't store them in uint8_t's. 154 | extern const uint16_t PROGMEM port_to_mode_PGM[]; 155 | extern const uint16_t PROGMEM port_to_input_PGM[]; 156 | extern const uint16_t PROGMEM port_to_output_PGM[]; 157 | 158 | extern const uint8_t PROGMEM digital_pin_to_port_PGM[]; 159 | // extern const uint8_t PROGMEM digital_pin_to_bit_PGM[]; 160 | extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[]; 161 | extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; 162 | 163 | // Get the bit location within the hardware port of the given virtual pin. 164 | // This comes from the pins_*.c file for the active board configuration. 165 | // 166 | // These perform slightly better as macros compared to inline functions 167 | // 168 | #define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) 169 | #define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) ) 170 | #define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) ) 171 | #define analogInPinToBit(P) (P) 172 | #define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) ) 173 | #define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) ) 174 | #define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) ) 175 | 176 | #define NOT_A_PIN 0 177 | #define NOT_A_PORT 0 178 | 179 | #define NOT_AN_INTERRUPT -1 180 | 181 | #ifdef ARDUINO_MAIN 182 | #define PA 1 183 | #define PB 2 184 | #define PC 3 185 | #define PD 4 186 | #define PE 5 187 | #define PF 6 188 | #define PG 7 189 | #define PH 8 190 | #define PJ 10 191 | #define PK 11 192 | #define PL 12 193 | #endif 194 | 195 | #define NOT_ON_TIMER 0 196 | #define TIMER0A 1 197 | #define TIMER0B 2 198 | #define TIMER1A 3 199 | #define TIMER1B 4 200 | #define TIMER1C 5 201 | #define TIMER2 6 202 | #define TIMER2A 7 203 | #define TIMER2B 8 204 | 205 | #define TIMER3A 9 206 | #define TIMER3B 10 207 | #define TIMER3C 11 208 | #define TIMER4A 12 209 | #define TIMER4B 13 210 | #define TIMER4C 14 211 | #define TIMER4D 15 212 | #define TIMER5A 16 213 | #define TIMER5B 17 214 | #define TIMER5C 18 215 | 216 | #ifdef __cplusplus 217 | } // extern "C" 218 | #endif 219 | 220 | #ifdef __cplusplus 221 | #include "WCharacter.h" 222 | #include "WString.h" 223 | #include "HardwareSerial.h" 224 | #include "USBAPI.h" 225 | #if defined(HAVE_HWSERIAL0) && defined(HAVE_CDCSERIAL) 226 | #error "Targets with both UART0 and CDC serial not supported" 227 | #endif 228 | 229 | uint16_t makeWord(uint16_t w); 230 | uint16_t makeWord(byte h, byte l); 231 | 232 | #define word(...) makeWord(__VA_ARGS__) 233 | 234 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); 235 | 236 | void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); 237 | void noTone(uint8_t _pin); 238 | 239 | // WMath prototypes 240 | long random(long); 241 | long random(long, long); 242 | void randomSeed(unsigned int); 243 | long map(long, long, long, long, long); 244 | 245 | #endif 246 | 247 | #include "pins_arduino.h" 248 | 249 | #endif 250 | -------------------------------------------------------------------------------- /hardware/openplc/avr/cores/arduino/Stream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Stream.cpp - adds parsing methods to Stream class 3 | Copyright (c) 2008 David A. Mellis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Created July 2011 20 | parsing functions based on TextFinder library by Michael Margolis 21 | */ 22 | 23 | #include "Arduino.h" 24 | #include "Stream.h" 25 | 26 | #define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait 27 | #define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field 28 | 29 | // private method to read stream with timeout 30 | int Stream::timedRead() 31 | { 32 | int c; 33 | _startMillis = millis(); 34 | do { 35 | c = read(); 36 | if (c >= 0) return c; 37 | } while(millis() - _startMillis < _timeout); 38 | return -1; // -1 indicates timeout 39 | } 40 | 41 | // private method to peek stream with timeout 42 | int Stream::timedPeek() 43 | { 44 | int c; 45 | _startMillis = millis(); 46 | do { 47 | c = peek(); 48 | if (c >= 0) return c; 49 | } while(millis() - _startMillis < _timeout); 50 | return -1; // -1 indicates timeout 51 | } 52 | 53 | // returns peek of the next digit in the stream or -1 if timeout 54 | // discards non-numeric characters 55 | int Stream::peekNextDigit() 56 | { 57 | int c; 58 | while (1) { 59 | c = timedPeek(); 60 | if (c < 0) return c; // timeout 61 | if (c == '-') return c; 62 | if (c >= '0' && c <= '9') return c; 63 | read(); // discard non-numeric 64 | } 65 | } 66 | 67 | // Public Methods 68 | ////////////////////////////////////////////////////////////// 69 | 70 | void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait 71 | { 72 | _timeout = timeout; 73 | } 74 | 75 | // find returns true if the target string is found 76 | bool Stream::find(char *target) 77 | { 78 | return findUntil(target, (char*)""); 79 | } 80 | 81 | // reads data from the stream until the target string of given length is found 82 | // returns true if target string is found, false if timed out 83 | bool Stream::find(char *target, size_t length) 84 | { 85 | return findUntil(target, length, NULL, 0); 86 | } 87 | 88 | // as find but search ends if the terminator string is found 89 | bool Stream::findUntil(char *target, char *terminator) 90 | { 91 | return findUntil(target, strlen(target), terminator, strlen(terminator)); 92 | } 93 | 94 | // reads data from the stream until the target string of the given length is found 95 | // search terminated if the terminator string is found 96 | // returns true if target string is found, false if terminated or timed out 97 | bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) 98 | { 99 | size_t index = 0; // maximum target string length is 64k bytes! 100 | size_t termIndex = 0; 101 | int c; 102 | 103 | if( *target == 0) 104 | return true; // return true if target is a null string 105 | while( (c = timedRead()) > 0){ 106 | 107 | if(c != target[index]) 108 | index = 0; // reset index if any char does not match 109 | 110 | if( c == target[index]){ 111 | //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1); 112 | if(++index >= targetLen){ // return true if all chars in the target match 113 | return true; 114 | } 115 | } 116 | 117 | if(termLen > 0 && c == terminator[termIndex]){ 118 | if(++termIndex >= termLen) 119 | return false; // return false if terminate string found before target string 120 | } 121 | else 122 | termIndex = 0; 123 | } 124 | return false; 125 | } 126 | 127 | 128 | // returns the first valid (long) integer value from the current position. 129 | // initial characters that are not digits (or the minus sign) are skipped 130 | // function is terminated by the first character that is not a digit. 131 | long Stream::parseInt() 132 | { 133 | return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) 134 | } 135 | 136 | // as above but a given skipChar is ignored 137 | // this allows format characters (typically commas) in values to be ignored 138 | long Stream::parseInt(char skipChar) 139 | { 140 | boolean isNegative = false; 141 | long value = 0; 142 | int c; 143 | 144 | c = peekNextDigit(); 145 | // ignore non numeric leading characters 146 | if(c < 0) 147 | return 0; // zero returned if timeout 148 | 149 | do{ 150 | if(c == skipChar) 151 | ; // ignore this charactor 152 | else if(c == '-') 153 | isNegative = true; 154 | else if(c >= '0' && c <= '9') // is c a digit? 155 | value = value * 10 + c - '0'; 156 | read(); // consume the character we got with peek 157 | c = timedPeek(); 158 | } 159 | while( (c >= '0' && c <= '9') || c == skipChar ); 160 | 161 | if(isNegative) 162 | value = -value; 163 | return value; 164 | } 165 | 166 | 167 | // as parseInt but returns a floating point value 168 | float Stream::parseFloat() 169 | { 170 | return parseFloat(NO_SKIP_CHAR); 171 | } 172 | 173 | // as above but the given skipChar is ignored 174 | // this allows format characters (typically commas) in values to be ignored 175 | float Stream::parseFloat(char skipChar){ 176 | boolean isNegative = false; 177 | boolean isFraction = false; 178 | long value = 0; 179 | int c; 180 | float fraction = 1.0; 181 | 182 | c = peekNextDigit(); 183 | // ignore non numeric leading characters 184 | if(c < 0) 185 | return 0; // zero returned if timeout 186 | 187 | do{ 188 | if(c == skipChar) 189 | ; // ignore 190 | else if(c == '-') 191 | isNegative = true; 192 | else if (c == '.') 193 | isFraction = true; 194 | else if(c >= '0' && c <= '9') { // is c a digit? 195 | value = value * 10 + c - '0'; 196 | if(isFraction) 197 | fraction *= 0.1; 198 | } 199 | read(); // consume the character we got with peek 200 | c = timedPeek(); 201 | } 202 | while( (c >= '0' && c <= '9') || c == '.' || c == skipChar ); 203 | 204 | if(isNegative) 205 | value = -value; 206 | if(isFraction) 207 | return value * fraction; 208 | else 209 | return value; 210 | } 211 | 212 | // read characters from stream into buffer 213 | // terminates if length characters have been read, or timeout (see setTimeout) 214 | // returns the number of characters placed in the buffer 215 | // the buffer is NOT null terminated. 216 | // 217 | size_t Stream::readBytes(char *buffer, size_t length) 218 | { 219 | size_t count = 0; 220 | while (count < length) { 221 | int c = timedRead(); 222 | if (c < 0) break; 223 | *buffer++ = (char)c; 224 | count++; 225 | } 226 | return count; 227 | } 228 | 229 | 230 | // as readBytes with terminator character 231 | // terminates if length characters have been read, timeout, or if the terminator character detected 232 | // returns the number of characters placed in the buffer (0 means no valid data found) 233 | 234 | size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) 235 | { 236 | if (length < 1) return 0; 237 | size_t index = 0; 238 | while (index < length) { 239 | int c = timedRead(); 240 | if (c < 0 || c == terminator) break; 241 | *buffer++ = (char)c; 242 | index++; 243 | } 244 | return index; // return number of characters, not including null terminator 245 | } 246 | 247 | String Stream::readString() 248 | { 249 | String ret; 250 | int c = timedRead(); 251 | while (c >= 0) 252 | { 253 | ret += (char)c; 254 | c = timedRead(); 255 | } 256 | return ret; 257 | } 258 | 259 | String Stream::readStringUntil(char terminator) 260 | { 261 | String ret; 262 | int c = timedRead(); 263 | while (c >= 0 && c != terminator) 264 | { 265 | ret += (char)c; 266 | c = timedRead(); 267 | } 268 | return ret; 269 | } 270 | 271 | --------------------------------------------------------------------------------