Last active
October 28, 2019 22:43
-
-
Save donn/30b1c63d863e836ed01c26bcf713040a to your computer and use it in GitHub Desktop.
TM4C123GH6PM Environment Mac Setup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# TM4C123GH6PM Environment Mac Setup | |
# | |
# This is what I do when I procrastinate. | |
# | |
# I recommend you have homebrew pre-installed for this, but the script | |
# will try to install it anyway. | |
# | |
# (To get STM32 working on Mac instead, try | |
# https://github.com/glegrain/STM32-with-macOS) | |
# | |
# Ruby | |
# -- | |
# ©Mohamed Gaber 2019 | |
# | |
# Permission is hereby granted, free of charge, to any person obtaining a | |
# copy of this software and associated documentation files (the "Software"), | |
# to deal in the Software without restriction, including without limitation | |
# the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
# and/or sell copies of the Software, and to permit persons to whom the | |
# Software is furnished to do so, subject to the following conditions: | |
# | |
# The above copyright notice and this permission notice shall be included in | |
# all copies or substantial portions of the Software. | |
# | |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
# DEALINGS IN THE SOFTWARE. | |
require 'tmpdir' | |
require 'fileutils' | |
macOS = Gem::Version.new(`sw_vers -productVersion`.chomp) | |
ftdi_needed = false | |
if macOS < Gem::Version.new('10.15') and macOS > Gem::Version.new('10.8') | |
ftdi_needed = true | |
end | |
puts "TM4C123 macOS Environment Setup" | |
puts "You can exit at any time by using Ctrl+C." | |
puts "" | |
puts "By installing, you agree to ALL OF:" | |
puts "" | |
counter = 0 | |
puts "#{counter}. The FT Driver License Terms\n\t(https://www.ftdichip.com/Drivers/FTDriverLicenceTerms.htm)" if ftdi_needed; counter += 1 if ftdi_needed | |
puts "#{counter}. The ARM MDK EULA\n\t(https://www.keil.com/Content/eula/mdkeula.html)"; counter += 1 | |
puts "" | |
puts "This setup script includes no implied or explicit warranty of any kind." | |
puts "The author is not liable for any damages incurred to your computer or device." | |
puts "" | |
puts "Checking for SW-TM4C-*.exe in local folder…" | |
files = Dir["SW-TM4C-*.exe"] | |
if files.count == 0 | |
puts "Cannot find the Tivaware for Windows installer. You will need to download this yourself.\n\t(http://software-dl.ti.com/tiva-c/SW-TM4C/latest/index_FDS.html)" | |
exit 66 | |
else | |
puts "Found." | |
end | |
puts "" | |
tivaware_installer = files[0] | |
keil_tm4c_pack = 'https://keilpack.azureedge.net/pack/Keil.TM4C_DFP.1.1.0.pack' | |
print "Where would you like to install your files? [Default: ~/Embedded]> " | |
install_dir = gets("\n").chomp | |
install_dir = "#{ENV["HOME"]}/Embedded" if install_dir.empty? | |
FileUtils.mkdir_p install_dir | |
puts "Starting." | |
puts "" | |
if ftdi_needed | |
puts "[SETUP] macOS version is > 10.8 and < 10.15, FTDI driver needed…" | |
Dir.mktmpdir("D2xx") { |dir| | |
`curl -sL https://www.ftdichip.com/Drivers/D2XX/MacOSX/D2xxHelper_v2.0.0.pkg > '#{dir}/package.pkg'` | |
`tar -C '#{dir}' -xf '#{dir}/package.pkg'` | |
`tar -C '#{dir}' -xf '#{dir}/dst.pkg/Payload'` | |
puts "[SETUP] The program may ask you for sudo permission to install the driver." | |
`sudo cp -r '#{dir}/Library/Extensions/D2xxHelper.kext' /System/Library/Extensions/` | |
`sudo kextload /System/Library/Extensions/D2xxHelper.kext` | |
} | |
end | |
brew_result = `which brew` | |
if $?.exitstatus != 0 | |
puts "[SETUP] Homebrew not found, installing… (brew setup script may ask you for superuser permission)" | |
system("/usr/bin/ruby -e \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\"") | |
end | |
puts "[SETUP] Installing dependencies. This may take a while." | |
system("brew install donn/lm4tools/lm4tools open-ocd") | |
puts "" | |
puts "[SETUP] Placing middleware…" | |
# CMSIS | |
puts "[SETUP] Checking out CMSIS Core…" | |
cmsis_core_dir = "#{install_dir}/CMSISCore" | |
FileUtils.mkdir_p cmsis_core_dir | |
`svn checkout --force https://github.com/ARM-software/CMSIS_5/trunk/CMSIS/Core/Include '#{cmsis_core_dir}'` | |
# Tivaware | |
puts "[SETUP] Unzipping Tivaware…" | |
tivaware_dir = "#{install_dir}/Tivaware" | |
FileUtils.mkdir_p tivaware_dir | |
`unzip '#{tivaware_installer}' -d '#{tivaware_dir}'` | |
# Pack | |
puts "[SETUP] Getting TM4C Device Family Pack…" | |
dfp_dir = "#{install_dir}/DFP" | |
FileUtils.mkdir_p dfp_dir | |
`curl -L '#{keil_tm4c_pack}' > '#{dfp_dir}/tm4c.pack'` | |
`tar -C '#{dfp_dir}' -xf '#{dfp_dir}/tm4c.pack'` | |
new_proj_script = <<NEWPROJSCRIPT | |
#!/usr/bin/env ruby | |
require 'fileutils' | |
if ARGV.count != 1 | |
puts "Usage: \#{$0} <name of new project>" | |
exit 64 | |
end | |
name = ARGV[0] | |
FileUtils.mkdir_p name | |
# TI | |
ti_dir = "\#{name}/TI" | |
FileUtils.mkdir_p ti_dir | |
`cp '#{tivaware_dir}/examples/boards/dk-tm4c123g/blinky/blinky.ld' '\#{ti_dir}/link.ld'` | |
`cp '#{tivaware_dir}/examples/boards/dk-tm4c123g/blinky/startup_gcc.c' '\#{ti_dir}/startup.c'` | |
# Main | |
src_dir = "\#{name}/Sources" | |
FileUtils.mkdir_p src_dir | |
File.open("\#{src_dir}/main.c", "w") { |file| | |
file << <<-MAIN_C | |
#include "TM4C123GH6PM.h" | |
int main(void) { | |
// Enable clocks | |
SYSCTL->RCGCGPIO |= 0b00100000; // GPIO F | |
// GPIO F | |
GPIOF->DEN = 0b00001110; // Set LEDs to output | |
GPIOF->DIR = 0b00001110; // Set LEDs to output | |
GPIOF->DATA = 0b00001110; // Set LEDs to white | |
while(1) {} | |
} | |
MAIN_C | |
} | |
# Header Directory | |
hdr_dir = "\#{name}/Includes" | |
FileUtils.mkdir_p hdr_dir | |
# Makefile | |
File.open("\#{name}/Makefile", "w") { |file| | |
file << <<-MAKEFILE | |
# Adapted from Tiva Makefile from uCtools project | |
# (uctools.github.com) | |
MCU = TM4C123GH6PM | |
SOURCES = TI/startup.c $(shell find Sources | grep '\\\\.c') | |
OBJECTS = $(addprefix $(BUILD_DIR)/, $(patsubst %.c,%.o,$(SOURCES))) | |
LD_SCRIPT = TI/link.ld | |
BUILD_DIR = build | |
OUT_FILE = flashable.bin | |
TIVAWARE_PATH = #{tivaware_dir} | |
CMSIS_PATH = #{cmsis_core_dir} | |
TM4C123_PATH = #{dfp_dir}/Device/Include/TM4C123 | |
CFLAGS = -g -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp | |
CFLAGS += -Os -ffunction-sections -fdata-sections -MD -std=c11 -Wall | |
CFLAGS += -Wno-unused-variable -DPART_$(MCU) -c | |
CFLAGS += -I$(TIVAWARE_PATH) -I$(CMSIS_PATH) -I$(TM4C123_PATH) -IIncludes | |
CFLAGS += -DTARGET_IS_BLIZZARD_RA1 | |
LDFLAGS = -T $(LD_SCRIPT) --entry ResetISR --gc-sections | |
####################################### | |
CC = arm-none-eabi-gcc | |
LD = arm-none-eabi-ld | |
OBJCOPY = arm-none-eabi-objcopy | |
####################################### | |
# default: build bin | |
all: $(OUT_FILE) | |
$(OBJECTS): $(BUILD_DIR)/%.o: %.c | |
mkdir -p $(@D) | |
$(CC) $(CFLAGS) -o $@ $^ | |
$(BUILD_DIR)/a.out: $(OBJECTS) | |
$(LD) -o $@ $^ $(LDFLAGS) | |
$(OUT_FILE): $(BUILD_DIR)/a.out | |
$(OBJCOPY) -O binary $< $@ | |
.PHONY: clean | |
clean: | |
rm -rf $(BUILD_DIR) | |
MAKEFILE | |
} | |
# Readme | |
File.open("\#{name}/Readme.md", "w") { |file| | |
file << <<-README | |
# \#{name} | |
This is an automatically generated README file. | |
# Usage | |
Invoke `make` to build. | |
Invoke `lm4flash flashable.bin` to flash the compiled file to memory. | |
Invoke `screen /dev/cu.usbmodem<something>` for serial terminals. (You'll need to try a couple.) | |
To use the Open On-chip debugger: | |
``` | |
arm-none-eabi-gdb -ex 'target extended-remote | openocd -f board/ek-tm4c1294xl.cfg -c "gdb_port pipe; log_output openocd.log"; monitor reset; monitor halt' | |
``` | |
# Programming differences from Keil | |
The most notable differences are: | |
* You need to add the interrupts manually to the IVT in TI/startup.c | |
* You must perform your clock configuration manually. | |
This is because we're not using Keil startup files, we're using TI's. | |
# Acknowledgements | |
* The Makefile is based on [uctools/tiva-template](https://github.com/uctools/tiva-template). | |
* Guide used: http://chrisrm.com/howto-develop-on-the-ti-tiva-launchpad-using-linux/ | |
README | |
} | |
NEWPROJSCRIPT | |
new_proj_path = "#{install_dir}/new_tivac_project" | |
File.open(new_proj_path, "w") { |file| | |
file << new_proj_script | |
} | |
File.chmod(0o755, new_proj_path) | |
puts "[SETUP] Done." | |
puts "" | |
puts "To create a new project, write this in the terminal:" | |
puts "\t#{new_proj_path} <name of your project>" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment