diff --git a/Arduino.mk b/Arduino.mk index 5b0af0f..0dfe161 100644 --- a/Arduino.mk +++ b/Arduino.mk @@ -19,7 +19,7 @@ # # Original Arduino adaptation by mellis, eighthave, oli.keller # -# Current version: 1.5.2 +# Current version: 1.6.0 # # Refer to HISTORY.md file for complete history of changes # diff --git a/HISTORY.md b/HISTORY.md index c35d3f8..d8f89e6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,14 +5,18 @@ The following is the rough list of changes that went into different versions. I tried to give credit whenever possible. If I have missed anyone, kindly add it to the list. ### In Development +- TBC + +### 1.6.0 (2017-07-11) - Fix: Allowed for SparkFun's weird usb pid/vid submenu shenanigans (issue #499). (https://github.com/sej7278) - Fix: Do not include the Arduino header when calling generate_assembly on .cpp files. (https://github.com/Batchyx) - Fix: Auto-detect F_CPU on Teensy from boards.txt (https://github.com/DaWelter) - Fix: params typo in PuTTY section (issue #487) (https://github.com/ericdand) - Fix: Fixed sed expression to properly format show_submenu (issue #488) (https://github.com/cbosdo) -- New: Add support for good old cu as monitor command (issue #492) (https://github.com/mwm) - Tweak: Removed tilde from documentation (issue #497). (https://github.com/sej7278) +- New: Add support for good old cu as monitor command (issue #492) (https://github.com/mwm) - New: Add a documentation how to setup Makefile for 3rd party boards (issue #499). (https://github.com/MilanV) +- New: Add support for Robotis OpenCM boards ### 1.5.2 (2017-01-11) diff --git a/OpenCM.mk b/OpenCM.mk new file mode 100644 index 0000000..257cf78 --- /dev/null +++ b/OpenCM.mk @@ -0,0 +1,236 @@ +######################################################################## +# +# Support for Robotis OpenCM boards +# +# http://en.robotis.com/index/product.php?cate_code=131010 +# +# You must install the OpenCM IDE for this Makefile to work: +# +# http://support.robotis.com/en/software/robotis_opencm/robotis_opencm.htm +# +# Based on work that is copyright Jeremy Shaw, Sudar, Nicholas Zambetti, +# David A. Mellis & Hernando Barragan. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of the +# License, or (at your option) any later version. +# +# Adapted from Teensy 3.x makefile which was adapted from Arduino 0011 +# Makefile by M J Oldfield +# +# Original Arduino adaptation by mellis, eighthave, oli.keller +# +######################################################################## + +ifndef ARDMK_DIR + ARDMK_DIR := $(realpath $(dir $(realpath $(lastword $(MAKEFILE_LIST))))) +endif + +# include Common.mk now we know where it is +include $(ARDMK_DIR)/Common.mk + +ARDUINO_DIR = $(OPENCMIDE_DIR) + +ifndef ARDMK_VENDOR + ARDMK_VENDOR = robotis +endif + +ifndef ARDUINO_CORE_PATH + ARDUINO_CORE_PATH = $(ARDUINO_DIR)/hardware/robotis/cores/robotis +endif + +ifndef BOARDS_TXT + BOARDS_TXT = $(ARDUINO_DIR)/hardware/$(ARDMK_VENDOR)/boards.txt +endif + +ifndef PARSE_OPENCM + # result = $(call READ_BOARD_TXT, 'boardname', 'parameter') + PARSE_OPENCM = $(shell grep -v "^\#" "$(BOARDS_TXT)" | grep $(1).$(2) | cut -d = -f 2- ) +endif + +ifndef F_CPU + F_CPU := $(call PARSE_OPENCM,$(BOARD_TAG),build.f_cpu) +endif + +# if boards.txt gets modified, look there, else hard code it +ARCHITECTURE = $(call PARSE_OPENCM,$(BOARD_TAG),build.architecture) +ifeq ($(strip $(ARCHITECTURE)),) + ARCHITECTURE = arm +endif + +AVR_TOOLS_DIR = $(call dir_if_exists,$(ARDUINO_DIR)/hardware/tools/$(ARCHITECTURE)) + +# Robotis has moved the platform lib dir to their root folder +ifndef ARDUINO_PLATFORM_LIB_PATH + ARDUINO_PLATFORM_LIB_PATH = $(ARDUINO_DIR)/libraries + $(call show_config_variable,ARDUINO_PLATFORM_LIB_PATH,[COMPUTED],(from ARDUINO_DIR)) +endif + +ifndef ARDUINO_HEADER + ARDUINO_HEADER = wirish.h +endif + +######################################################################## +# command names + +ifndef CC_NAME + CC_NAME := $(call PARSE_OPENCM,$(BOARD_TAG),build.command.gcc) + ifndef CC_NAME + CC_NAME := arm-none-eabi-gcc + else + $(call show_config_variable,CC_NAME,[COMPUTED]) + endif +endif + +ifndef CXX_NAME + CXX_NAME := $(call PARSE_OPENCM,$(BOARD_TAG),build.command.g++) + ifndef CXX_NAME + CXX_NAME := arm-none-eabi-g++ + else + $(call show_config_variable,CXX_NAME,[COMPUTED]) + endif +endif + +ifndef AS_NAME + AS_NAME := $(call PARSE_OPENCM,$(BOARD_TAG),build.command.as) + ifndef AS_NAME + AS_NAME := arm-none-eabi-as + else + $(call show_config_variable,AS_NAME,[COMPUTED]) + endif +endif + +ifndef OBJDUMP_NAME + OBJDUMP_NAME := $(call PARSE_OPENCM,$(BOARD_TAG),build.command.objdump) + ifndef OBJDUMP_NAME + OBJDUMP_NAME := arm-none-eabi-objdump + else + $(call show_config_variable,OBJDUMP_NAME,[COMPUTED]) + endif +endif + +ifndef AR_NAME + AR_NAME := $(call PARSE_OPENCM,$(BOARD_TAG),build.command.ar) + ifndef AR_NAME + AR_NAME := arm-none-eabi-ar + else + $(call show_config_variable,AR_NAME,[COMPUTED]) + endif +endif + +ifndef SIZE_NAME + SIZE_NAME := $(call PARSE_OPENCM,$(BOARD_TAG),build.command.size) + ifndef SIZE_NAME + SIZE_NAME := arm-none-eabi-size + else + $(call show_config_variable,SIZE_NAME,[COMPUTED]) + endif +endif + +ifndef NM_NAME + NM_NAME := $(call PARSE_OPENCM,$(BOARD_TAG),build.command.nm) + ifndef NM_NAME + NM_NAME := arm-none-eabi-nm + else + $(call show_config_variable,NM_NAME,[COMPUTED]) + endif +endif + +ifndef OBJCOPY_NAME + OBJCOPY_NAME := $(call PARSE_OPENCM,$(BOARD_TAG),build.command.objcopy) + ifndef OBJCOPY_NAME + OBJCOPY_NAME := arm-none-eabi-objcopy + else + $(call show_config_variable,OBJCOPY_NAME,[COMPUTED]) + endif +endif + +# processor stuff +ifndef MCU + MCU := $(call PARSE_OPENCM,$(BOARD_TAG),build.family) +endif + +ifndef MCU_FLAG_NAME + MCU_FLAG_NAME=mcpu +endif + +######################################################################## +# FLAGS +ifndef USB_TYPE + USB_TYPE = USB_SERIAL +endif + +CPPFLAGS += -DBOARD_$(call PARSE_OPENCM,$(BOARD_TAG),build.board) +CPPFLAGS += -DMCU_$(call PARSE_OPENCM,$(BOARD_TAG),build.mcu) +CPPFLAGS += -DSTM32_MEDIUM_DENSITY -DVECT_TAB_FLASH + +CPPFLAGS += $(call PARSE_OPENCM,$(BOARD_TAG),build.option) + +CXXFLAGS += -fno-rtti + +CXXFLAGS += $(call PARSE_OPENCM,$(BOARD_TAG),build.cppoption) +ifeq ("$(call PARSE_OPENCM,$(BOARD_TAG),build.gnu0x)","true") + CXXFLAGS_STD += -std=gnu++0x +endif + +ifeq ("$(call PARSE_OPENCM,$(BOARD_TAG),build.elide_constructors)", "true") + CXXFLAGS += -felide-constructors +endif + +CPPFLAGS += -mthumb -march=armv7-m -nostdlib -Wl,--gc-sections -Wall + +LDFLAGS += -T$(ARDUINO_DIR)/hardware/robotis/cores/robotis/CM900/flash.ld +LDFLAGS += -L$(ARDUINO_CORE_PATH) +LDFLAGS += -mthumb -Xlinker --gc-sections -Wall + +OTHER_LIBS += -lstdc++ + +######################################################################## +# Reset is handled by upload script +override RESET_CMD = + +######################################################################## +# Object conversion & uploading magic, modified from Arduino.mk +override TARGET_HEX = $(OBJDIR)/$(TARGET).bin + +ifndef AVRDUDE + AVRDUDE := $(shell which robotis-loader 2>/dev/null) + ifndef AVRDUDE + AVRDUDE = $(ARDMK_DIR)/bin/robotis-loader + endif +endif + +override avr_size = $(SIZE) --target=binary $(2) + +override AVRDUDE_COM_OPTS = +ifeq ($(CURRENT_OS), WINDOWS) + override AVRDUDE_ARD_OPTS = $(COM_STYLE_MONITOR_PORT) +else + override AVRDUDE_ARD_OPTS = $(call get_monitor_port) +endif + +override AVRDUDE_UPLOAD_HEX = $(TARGET_HEX) + +######################################################################## +# automatically include Arduino.mk + +include $(ARDMK_DIR)/Arduino.mk + +######################################################################## +# Object conversion & uploading magic, modified from Arduino.mk + +$(OBJDIR)/%.bin: $(OBJDIR)/%.elf $(COMMON_DEPS) + @$(MKDIR) $(dir $@) + $(OBJCOPY) -v -Obinary $< $@ + @$(ECHO) '\n' + $(call avr_size,$<,$@) +ifneq ($(strip $(HEX_MAXIMUM_SIZE)),) + @if [ `$(SIZE) --target=binary $@ | awk 'FNR == 2 {print $$2}'` -le $(HEX_MAXIMUM_SIZE) ]; then touch $@.sizeok; fi +else + @$(ECHO) "Maximum flash memory of $(BOARD_TAG) is not specified. Make sure the size of $@ is less then $(BOARD_TAG)\'s flash memory" + @touch $@.sizeok +endif + +# link fails to plug _sbrk into libc if core is a lib, seems a bug in the linker +CORE_LIB = $(CORE_OBJS) diff --git a/README.md b/README.md index 1947c6e..7ea5c0b 100644 --- a/README.md +++ b/README.md @@ -279,9 +279,17 @@ For Teensy 3.x support you must first install [Teensyduino](http://www.pjrc.com/ See examples/BlinkTeensy for example usage. +## Robotis OpenCM + +For Robotis OpenCM support you must first install [the OpenCM IDE](http://support.robotis.com/en/software/robotis_opencm/robotis_opencm.htm) + +See examples/BlinkOpenCM for example usage. + +For large Robotis projects, [libmaple](https://github.com/Rhoban/Maple) may be more appropriate, as the OpenCM IDE uses a very old compiler release. + ## Versioning -The current version of the makefile is `1.5.2`. You can find the full history in the [HISTORY.md](HISTORY.md) file +The current version of the makefile is `1.6.0`. You can find the full history in the [HISTORY.md](HISTORY.md) file This project adheres to Semantic [Versioning 2.0](http://semver.org/). diff --git a/ard-reset-arduino.1 b/ard-reset-arduino.1 index 781afa9..00677b5 100644 --- a/ard-reset-arduino.1 +++ b/ard-reset-arduino.1 @@ -1,4 +1,4 @@ -.TH ARD-RESET-ARDUINO "1" "January 2017" "ard-reset-arduino 1.5.2" "Arduino CLI Reset" +.TH ARD-RESET-ARDUINO "1" "January 2017" "ard-reset-arduino 1.6.0" "Arduino CLI Reset" .SH NAME ard-reset-arduino - Reset Arduino board diff --git a/bin/robotis-loader b/bin/robotis-loader new file mode 100755 index 0000000..95d4e71 --- /dev/null +++ b/bin/robotis-loader @@ -0,0 +1,94 @@ +#!/usr/bin/python + +# This script sends a program on a robotis board (OpenCM9.04 or CM900) +# using the robotis bootloader (used in OpenCM IDE) +# +# Usage: +# python robotis-loader.py +# +# Example: +# python robotis-loader.py /dev/ttyACM0 firmware.bin +# +# https://github.com/Gregwar/robotis-loader + +import serial, sys, os, time + +print('~~ Robotis loader ~~') +print('') + +# Reading command line +if len(sys.argv) != 3: + exit('! Usage: robotis-loader.py ') +pgm, port, binary = sys.argv + +# Helper to prints a progress bar +def progressBar(percent, precision=65): + threshold=precision*percent/100.0 + sys.stdout.write('[ ') + for x in xrange(0, precision): + if x < threshold: sys.stdout.write('#') + else: sys.stdout.write(' ') + sys.stdout.write(' ] ') + sys.stdout.flush() + +# Opening the firmware file +try: + stat = os.stat(binary) + size = stat.st_size + firmware = file(binary, 'rb') + print('* Opening %s, size=%d' % (binary, size)) +except: + exit('! Unable to open file %s' % binary) + +# Opening serial port +try: + s = serial.Serial(port, baudrate=115200) +except: + exit('! Unable to open serial port %s' % port) + +print('* Resetting the board') +s.setRTS(True) +s.setDTR(False) +time.sleep(0.1) +s.setRTS(False) +s.write('CM9X') +s.close() +time.sleep(1.0); + +print('* Connecting...') +s = serial.Serial(port, baudrate=115200) +s.write('AT&LD') +print('* Download signal transmitted, waiting...') + +# Entering bootloader sequence +while True: + line = s.readline().strip() + if line.endswith('Ready..'): + print('* Board ready, sending data') + cs = 0 + pos = 0 + while True: + c = firmware.read(2048) + if len(c): + pos += len(c) + sys.stdout.write("\r") + progressBar(100*float(pos)/float(size)) + s.write(c) + for k in range(0,len(c)): + cs = (cs+ord(c[k]))%256 + else: + break + print('') + s.setDTR(True) + print('* Checksum: %d' % (cs)) + s.write(chr(cs)) + print('* Firmware was sent') + else: + if line == 'Success..': + print('* Success, running the code') + print('') + s.write('AT&RST') + s.close() + exit() + else: + print('Board -> '+line) diff --git a/examples/BlinkOpenCM/Blink.ino b/examples/BlinkOpenCM/Blink.ino new file mode 100644 index 0000000..8b37aa0 --- /dev/null +++ b/examples/BlinkOpenCM/Blink.ino @@ -0,0 +1,18 @@ +/* + Blink + Turns an LED on for one second, then off for one second, repeatedly. + + This example code is in the public domain. + */ + +void setup() { + // initialize the led pin as an output. + pinMode(BOARD_LED_PIN, OUTPUT); +} + +void loop() { + digitalWrite(BOARD_LED_PIN, HIGH); // set the LED on + delay(1000); // wait for a second + digitalWrite(BOARD_LED_PIN, LOW); // set the LED off + delay(1000); // wait for a second +} diff --git a/examples/BlinkOpenCM/Makefile b/examples/BlinkOpenCM/Makefile new file mode 100644 index 0000000..0f7b285 --- /dev/null +++ b/examples/BlinkOpenCM/Makefile @@ -0,0 +1,7 @@ +BOARD_TAG = cm904 +ARDUINO_LIBS = + +#MONITOR_PORT = /dev/ttyACM0 +#OPENCMIDE_DIR = /where/you/installed/robotis_opencm + +include ../../OpenCM.mk diff --git a/packaging/fedora/arduino-mk.spec b/packaging/fedora/arduino-mk.spec index 326ea0a..61bf317 100644 --- a/packaging/fedora/arduino-mk.spec +++ b/packaging/fedora/arduino-mk.spec @@ -1,5 +1,5 @@ Name: arduino-mk -Version: 1.5.2 +Version: 1.6.0 Release: 1%{dist} Summary: Program your Arduino from the command line Packager: Simon John @@ -37,6 +37,8 @@ install -m 644 *.mk arduino-mk-vars.md %{buildroot}/%{_datadir}/arduino install -m 644 licence.txt %{buildroot}/%{_docdir}/%{name} install -m 755 bin/ard-reset-arduino %{buildroot}/%{_bindir}/ard-reset-arduino install -m 644 ard-reset-arduino.1 %{buildroot}/%{_mandir}/man1 +install -m 755 bin/robotis-loader %{buildroot}/%{_bindir}/robotis-loader +install -m 644 robotis-loader.1 %{buildroot}/%{_mandir}/man1 %clean rm -rf %{buildroot} @@ -45,6 +47,8 @@ rm -rf %{buildroot} %defattr(-,root,root,-) %{_bindir}/ard-reset-arduino %{_mandir}/man1/ard-reset-arduino.1* +%{_bindir}/robotis-loader +%{_mandir}/man1/robotis-loader.1* %{_datadir}/arduino/*.mk %{_datadir}/arduino/arduino-mk-vars.md %doc %{_docdir}/%{name}/licence.txt @@ -52,6 +56,8 @@ rm -rf %{buildroot} %{_docdir}/%{name}/examples %changelog +* Tue Jul 11 2017 Karl Semich +- Added robotis-loader binary and manpage * Sat Apr 12 2014 Simon John - Put manpage back. * Fri Apr 04 2014 Simon John diff --git a/robotis-loader.1 b/robotis-loader.1 new file mode 100644 index 0000000..debd000 --- /dev/null +++ b/robotis-loader.1 @@ -0,0 +1,27 @@ +.TH ROBOTIS-LOADER "1" "July 2017" "robotis-loader" "Robotis CLI Uploader" + +.SH NAME +robotis-loader - Flash Robotis boards + +.SH SYNOPSIS +.B robotis-loader +PORT BINARY + +.SH DESCRIPTION +Sends a program on a Robotis board (OpenCM9.04 or CM900) using the +Robotis bootloader (used in OpenCM IDE). + +.SH EXAMPLE +robotis-loader /dev/ttyACM0 firmware.bin + +.SH BUGS +Problems may reported on the github project page at: +.PP +https://github.com/Gregwar/robotis-loader + +.SH AUTHOR +Grégoire Passault, g.passault@gmail.com + +.SH LICENSE +This is under MIT license. + diff --git a/tests/script/runtests.sh b/tests/script/runtests.sh index 58b8e15..7792186 100755 --- a/tests/script/runtests.sh +++ b/tests/script/runtests.sh @@ -7,7 +7,7 @@ failures=() # These examples cannot be tested easily at the moment as they require # alternate cores. The MakefileExample doesn't actually contain any source code # to compile. -NON_TESTABLE_EXAMPLES=(ATtinyBlink MakefileExample TinySoftWareSerial BlinkTeensy BlinkNetworkRPi BlinkInAVRC) +NON_TESTABLE_EXAMPLES=(ATtinyBlink MakefileExample TinySoftWareSerial BlinkOpenCM BlinkTeensy BlinkNetworkRPi BlinkInAVRC) for dir in $TESTS_DIR/*/ do