Skip to content

Commit

Permalink
Merge pull request #508 from fuzzyTew/robotis-opencm
Browse files Browse the repository at this point in the history
Add makefile for Robotis OpenCM
  • Loading branch information
sudar committed Jul 16, 2017
2 parents ba96840 + 5bcb64a commit d738cac
Show file tree
Hide file tree
Showing 11 changed files with 406 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Arduino.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
#
Expand Down
6 changes: 5 additions & 1 deletion HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
236 changes: 236 additions & 0 deletions OpenCM.mk
Original file line number Diff line number Diff line change
@@ -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 [email protected]; 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 [email protected]
endif

# link fails to plug _sbrk into libc if core is a lib, seems a bug in the linker
CORE_LIB = $(CORE_OBJS)
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/).

Expand Down
2 changes: 1 addition & 1 deletion ard-reset-arduino.1
Original file line number Diff line number Diff line change
@@ -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
Expand Down
94 changes: 94 additions & 0 deletions bin/robotis-loader
Original file line number Diff line number Diff line change
@@ -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 <serial port> <binary>
#
# 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 <serial-port> <binary>')
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)
Loading

0 comments on commit d738cac

Please sign in to comment.