mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-07-13 02:07:53 +00:00
Merge remote-tracking branch 'refs/remotes/pascallanger/master'
# Conflicts: all resolved by taking the master's code since all changes were already taken into master # Multiprotocol/CABELL_nrf224l01.ino # Multiprotocol/Multiprotocol.h # Multiprotocol/Multiprotocol.ino # Multiprotocol/NRF24l01_SPI.ino # Multiprotocol/Validate.h # Multiprotocol/_Config.h
This commit is contained in:
commit
8b8812a194
@ -1,99 +0,0 @@
|
|||||||
{
|
|
||||||
"packages": [
|
|
||||||
{
|
|
||||||
"name": "MULTI",
|
|
||||||
"maintainer": "Pascal",
|
|
||||||
"help": {
|
|
||||||
"online": "https://www.rcgroups.com/forums/showthread.php?2165676-DIY-Multiprotocol-TX-Module/page555"
|
|
||||||
},
|
|
||||||
"websiteURL": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module",
|
|
||||||
"platforms": [
|
|
||||||
{
|
|
||||||
"name": "Multi 4in1 Atmega328p",
|
|
||||||
"architecture": "avr",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"category": "Multi",
|
|
||||||
"help": {
|
|
||||||
"online": "https://www.rcgroups.com/forums/showthread.php?2165676-DIY-Multiprotocol-TX-Module/page555"
|
|
||||||
},
|
|
||||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module",
|
|
||||||
"archiveFileName": "multi_avr-1.0.0.zip",
|
|
||||||
"checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1",
|
|
||||||
"size": "15005",
|
|
||||||
"boards": [
|
|
||||||
{"name": "Multi 4in1 Atmega328p"}
|
|
||||||
],
|
|
||||||
"toolsDependencies": [
|
|
||||||
{
|
|
||||||
"packager": "arduino",
|
|
||||||
"name": "avr-gcc",
|
|
||||||
"version": "4.8.1-arduino5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"packager": "arduino",
|
|
||||||
"name": "avrdude",
|
|
||||||
"version": "6.0.1-arduino5"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Multi 4in1 STM32",
|
|
||||||
"architecture": "stm32",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"category": "Multi",
|
|
||||||
"help": {
|
|
||||||
"online": "https://www.rcgroups.com/forums/showthread.php?2165676-DIY-Multiprotocol-TX-Module/page555"
|
|
||||||
},
|
|
||||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module",
|
|
||||||
"archiveFileName": "multi_stm32-1.0.0.zip",
|
|
||||||
"checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1",
|
|
||||||
"size": "15005",
|
|
||||||
"boards": [
|
|
||||||
{"name": "Multi 4in1 STM32"}
|
|
||||||
],
|
|
||||||
"toolsDependencies": [
|
|
||||||
{
|
|
||||||
"packager": "arduino",
|
|
||||||
"name": "avr-gcc",
|
|
||||||
"version": "4.8.1-arduino5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"packager": "arduino",
|
|
||||||
"name": "avrdude",
|
|
||||||
"version": "6.0.1-arduino5"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Multi 4in1 OrangeTX",
|
|
||||||
"architecture": "xmega",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"category": "Multi",
|
|
||||||
"help": {
|
|
||||||
"online": "https://www.rcgroups.com/forums/showthread.php?2165676-DIY-Multiprotocol-TX-Module/page555"
|
|
||||||
},
|
|
||||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module",
|
|
||||||
"archiveFileName": "multi_xmega-1.0.0.zip",
|
|
||||||
"checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1",
|
|
||||||
"size": "15005",
|
|
||||||
"boards": [
|
|
||||||
{"name": "Multi 4in1 OrangeTX"}
|
|
||||||
],
|
|
||||||
"toolsDependencies": [
|
|
||||||
{
|
|
||||||
"packager": "arduino",
|
|
||||||
"name": "avr-gcc",
|
|
||||||
"version": "4.8.1-arduino5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"packager": "arduino",
|
|
||||||
"name": "avrdude",
|
|
||||||
"version": "6.0.1-arduino5"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tools":[]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
2
BootLoaders/AtmegaEmptyBoot/AtmegaMultiEmpty.hex
Normal file
2
BootLoaders/AtmegaEmptyBoot/AtmegaMultiEmpty.hex
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
:02000000FFFF00
|
||||||
|
:00000001FF
|
34
BootLoaders/AtmegaMultiBoot/AtmegaMultiBoot.hex
Normal file
34
BootLoaders/AtmegaMultiBoot/AtmegaMultiBoot.hex
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
:107E0000112484B714BE9FEF9BB99CE395B991E010
|
||||||
|
:107E100098B98370A9F08AEF80938500109284004E
|
||||||
|
:107E200085E08093810096BBB09BFECF10928100CD
|
||||||
|
:107E300093B186B181709C73892B8D3109F0B3D0D9
|
||||||
|
:107E400082E08093C00088E18093C10086E0809347
|
||||||
|
:107E5000C20081E28093C400259AC0E0D0E093E0A4
|
||||||
|
:107E6000F92EEE24E39425E0D22E31E1C32EA9D0E1
|
||||||
|
:107E7000813481F4A6D08EBBABD08EB3823811F49E
|
||||||
|
:107E800085E006C08EB3813811F484E001C083E040
|
||||||
|
:107E900091D086C0823411F484E103C0853419F492
|
||||||
|
:107EA00085E09DD07DC0853541F48BD0C82F89D029
|
||||||
|
:107EB000D0E0D82BCC0FDD1F72C0863521F484E0D2
|
||||||
|
:107EC0008ED080E0E5CF843609F03DC07AD079D0FD
|
||||||
|
:107ED000B82E77D0C11520E7D20718F000E011E0E6
|
||||||
|
:107EE00004C0FE01F7BEE895F9CF6BD0F80181938D
|
||||||
|
:107EF0008F01BE12FACFCE01905781159E4018F423
|
||||||
|
:107F0000FE01F7BEE89564D0C115FEE7DF0708F073
|
||||||
|
:107F100047C007B600FCFDCFFE01A0E0B1E08D91A7
|
||||||
|
:107F20009D910C01E7BEE89511243296A03821E01E
|
||||||
|
:107F3000B207A9F7FE01D7BEE89507B600FCFDCF52
|
||||||
|
:107F4000C7BEE8952DC08437B1F43BD03AD0B82EE7
|
||||||
|
:107F500038D03ED0FE01AC2EAB0C8F010F5F1F4F0F
|
||||||
|
:107F6000849128D0A01205C02196BA94CB0DD11DC2
|
||||||
|
:107F700017C0F801F2CF853739F42AD08EE11AD034
|
||||||
|
:107F800085E918D08FE084CF813549F421D080E194
|
||||||
|
:107F900011D08091C00086FFFCCF05D001C018D061
|
||||||
|
:107FA00080E108D064CFE0E0F0E084918F3F09F0F9
|
||||||
|
:107FB000099408959091C00095FFFCCF8093C6006E
|
||||||
|
:107FC00008958091C00087FFFCCF8091C60008957E
|
||||||
|
:107FD000F8DF803211F085E1EDDF84E1EBCFCF9364
|
||||||
|
:107FE000C82FEFDFC150E9F7CF91F2CFA8950895E0
|
||||||
|
:0C7FF000E0E6F0E098E1908380830895C3
|
||||||
|
:0400000300007E007B
|
||||||
|
:00000001FF
|
504
BootLoaders/AtmegaMultiBoot/Source/Makefile
Normal file
504
BootLoaders/AtmegaMultiBoot/Source/Makefile
Normal file
@ -0,0 +1,504 @@
|
|||||||
|
# Makefile for ATmegaBOOT
|
||||||
|
# E.Lins, 18.7.2005
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
# Instructions
|
||||||
|
#
|
||||||
|
# To make bootloader .hex file:
|
||||||
|
# make diecimila
|
||||||
|
# make lilypad
|
||||||
|
# make ng
|
||||||
|
# etc...
|
||||||
|
#
|
||||||
|
# To burn bootloader .hex file:
|
||||||
|
# make diecimila_isp
|
||||||
|
# make lilypad_isp
|
||||||
|
# make ng_isp
|
||||||
|
# etc...
|
||||||
|
|
||||||
|
# program name should not be changed...
|
||||||
|
PROGRAM = optiboot
|
||||||
|
|
||||||
|
# The default behavior is to build using tools that are in the users
|
||||||
|
# current path variables, but we can also build using an installed
|
||||||
|
# Arduino user IDE setup, or the Arduino source tree.
|
||||||
|
# Uncomment this next lines to build within the arduino environment,
|
||||||
|
# using the arduino-included avrgcc toolset (mac and pc)
|
||||||
|
# ENV ?= arduino
|
||||||
|
# ENV ?= arduinodev
|
||||||
|
# OS ?= macosx
|
||||||
|
# OS ?= windows
|
||||||
|
|
||||||
|
|
||||||
|
# enter the parameters for the avrdude isp tool -b19200
|
||||||
|
#
|
||||||
|
# These are the parameters for a usb-based STK500v2 programmer.
|
||||||
|
# Exact type unknown. (historical Makefile values.)
|
||||||
|
ISPTOOL = stk500v2
|
||||||
|
ISPPORT = usb
|
||||||
|
ISPSPEED = -b 57600
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# These are parameters for using an Arduino with the ArduinoISP sketch
|
||||||
|
# as the programmer. On a mac, for a particular Uno as programmer.
|
||||||
|
#ISPTOOL = stk500v1 -C /Applications/arduino/arduino-0022/hardware/tools/avr/etc/avrdude.conf
|
||||||
|
#ISPPORT = /dev/tty.usbmodemfd3141
|
||||||
|
#ISPSPEED = -b19200
|
||||||
|
|
||||||
|
MCU_TARGET = atmega168
|
||||||
|
LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
|
||||||
|
|
||||||
|
# Build environments
|
||||||
|
# Start of some ugly makefile-isms to allow optiboot to be built
|
||||||
|
# in several different environments. See the README.TXT file for
|
||||||
|
# details.
|
||||||
|
|
||||||
|
# default
|
||||||
|
fixpath = $(1)
|
||||||
|
|
||||||
|
ifeq ($(ENV), arduino)
|
||||||
|
# For Arduino, we assume that we're connected to the optiboot directory
|
||||||
|
# included with the arduino distribution, which means that the full set
|
||||||
|
# of avr-tools are "right up there" in standard places.
|
||||||
|
TOOLROOT = ../../../tools
|
||||||
|
GCCROOT = $(TOOLROOT)/avr/bin/
|
||||||
|
AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
|
||||||
|
|
||||||
|
ifeq ($(OS), windows)
|
||||||
|
# On windows, SOME of the tool paths will need to have backslashes instead
|
||||||
|
# of forward slashes (because they use windows cmd.exe for execution instead
|
||||||
|
# of a unix/mingw shell?) We also have to ensure that a consistent shell
|
||||||
|
# is used even if a unix shell is installed (ie as part of WINAVR)
|
||||||
|
fixpath = $(subst /,\,$1)
|
||||||
|
SHELL = cmd.exe
|
||||||
|
endif
|
||||||
|
|
||||||
|
else ifeq ($(ENV), arduinodev)
|
||||||
|
# Arduino IDE source code environment. Use the unpacked compilers created
|
||||||
|
# by the build (you'll need to do "ant build" first.)
|
||||||
|
ifeq ($(OS), macosx)
|
||||||
|
TOOLROOT = ../../../../build/macosx/work/Arduino.app/Contents/Resources/Java/hardware/tools
|
||||||
|
endif
|
||||||
|
ifeq ($(OS), windows)
|
||||||
|
TOOLROOT = ../../../../build/windows/work/hardware/tools
|
||||||
|
endif
|
||||||
|
|
||||||
|
GCCROOT = $(TOOLROOT)/avr/bin/
|
||||||
|
AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
|
||||||
|
|
||||||
|
else
|
||||||
|
GCCROOT =
|
||||||
|
AVRDUDE_CONF =
|
||||||
|
endif
|
||||||
|
#
|
||||||
|
# End of build environment code.
|
||||||
|
|
||||||
|
|
||||||
|
# the efuse should really be 0xf8; since, however, only the lower
|
||||||
|
# three bits of that byte are used on the atmega168, avrdude gets
|
||||||
|
# confused if you specify 1's for the higher bits, see:
|
||||||
|
# http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/
|
||||||
|
#
|
||||||
|
# similarly, the lock bits should be 0xff instead of 0x3f (to
|
||||||
|
# unlock the bootloader section) and 0xcf instead of 0x2f (to
|
||||||
|
# lock it), but since the high two bits of the lock byte are
|
||||||
|
# unused, avrdude would get confused.
|
||||||
|
|
||||||
|
ISPFUSES = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
|
||||||
|
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
|
||||||
|
-e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m \
|
||||||
|
-U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
|
||||||
|
ISPFLASH = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
|
||||||
|
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
|
||||||
|
-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
|
||||||
|
|
||||||
|
STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe"
|
||||||
|
STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \
|
||||||
|
-lFF -LFF -f$(HFUSE)$(LFUSE) -EF8 -ms -q -cUSB -I200kHz -s -wt
|
||||||
|
STK500-2 = $(STK500) -d$(MCU_TARGET) -ms -q -lCF -LCF -cUSB -I200kHz -s -wt
|
||||||
|
|
||||||
|
OBJ = $(PROGRAM).o
|
||||||
|
OPTIMIZE = -Os -fno-inline-small-functions -fno-split-wide-types
|
||||||
|
# -mshort-calls
|
||||||
|
|
||||||
|
DEFS =
|
||||||
|
LIBS =
|
||||||
|
|
||||||
|
CC = $(GCCROOT)avr-gcc
|
||||||
|
|
||||||
|
# Override is only needed by avr-lib build system.
|
||||||
|
|
||||||
|
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
|
||||||
|
override LDFLAGS = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib
|
||||||
|
|
||||||
|
OBJCOPY = $(GCCROOT)avr-objcopy
|
||||||
|
OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump)
|
||||||
|
|
||||||
|
SIZE = $(GCCROOT)avr-size
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Voice board test
|
||||||
|
# ATmega328
|
||||||
|
#
|
||||||
|
#atmega328: TARGET = atmega328p
|
||||||
|
#atmega328: MCU_TARGET = atmega328p
|
||||||
|
#atmega328: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=38400'
|
||||||
|
#atmega328: AVR_FREQ = 12000000L
|
||||||
|
#atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
|
||||||
|
#atmega328: $(PROGRAM)_atmega328.hex
|
||||||
|
#atmega328: $(PROGRAM)_atmega328.lst
|
||||||
|
|
||||||
|
atmega328: TARGET = atmega328
|
||||||
|
atmega328: MCU_TARGET = atmega328p
|
||||||
|
atmega328: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=57600'
|
||||||
|
atmega328: AVR_FREQ = 16000000L
|
||||||
|
atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
|
||||||
|
atmega328: $(PROGRAM)_atmega328_16.hex
|
||||||
|
atmega328: $(PROGRAM)_atmega328_16.lst
|
||||||
|
|
||||||
|
|
||||||
|
xmega32D4: TARGET = atxmega32d4
|
||||||
|
xmega32D4: MCU_TARGET = atxmega32d4
|
||||||
|
xmega32D4: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=57600'
|
||||||
|
xmega32D4: AVR_FREQ = 32000000L
|
||||||
|
xmega32D4: LDSECTIONS = -Wl,--section-start=.text=0x8000
|
||||||
|
xmega32D4: $(PROGRAM)_xmega32d4.hex
|
||||||
|
xmega32D4: $(PROGRAM)_xmega32d4.lst
|
||||||
|
|
||||||
|
|
||||||
|
# Test platforms
|
||||||
|
# Virtual boot block test
|
||||||
|
virboot328: TARGET = atmega328
|
||||||
|
virboot328: MCU_TARGET = atmega328p
|
||||||
|
virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DVIRTUAL_BOOT'
|
||||||
|
virboot328: AVR_FREQ = 16000000L
|
||||||
|
virboot328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
|
||||||
|
virboot328: $(PROGRAM)_atmega328.hex
|
||||||
|
virboot328: $(PROGRAM)_atmega328.lst
|
||||||
|
|
||||||
|
# 20MHz clocked platforms
|
||||||
|
#
|
||||||
|
# These are capable of 230400 baud, or 38400 baud on PC (Arduino Avrdude issue)
|
||||||
|
#
|
||||||
|
|
||||||
|
pro20: TARGET = pro_20mhz
|
||||||
|
pro20: MCU_TARGET = atmega168
|
||||||
|
pro20: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
pro20: AVR_FREQ = 20000000L
|
||||||
|
pro20: $(PROGRAM)_pro_20mhz.hex
|
||||||
|
pro20: $(PROGRAM)_pro_20mhz.lst
|
||||||
|
|
||||||
|
pro20_isp: pro20
|
||||||
|
pro20_isp: TARGET = pro_20mhz
|
||||||
|
# 2.7V brownout
|
||||||
|
pro20_isp: HFUSE = DD
|
||||||
|
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
|
||||||
|
pro20_isp: LFUSE = C6
|
||||||
|
# 512 byte boot
|
||||||
|
pro20_isp: EFUSE = 04
|
||||||
|
pro20_isp: isp
|
||||||
|
|
||||||
|
# 16MHz clocked platforms
|
||||||
|
#
|
||||||
|
# These are capable of 230400 baud, or 38400 baud on PC (Arduino Avrdude issue)
|
||||||
|
#
|
||||||
|
|
||||||
|
pro16: TARGET = pro_16MHz
|
||||||
|
pro16: MCU_TARGET = atmega168
|
||||||
|
pro16: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
pro16: AVR_FREQ = 16000000L
|
||||||
|
pro16: $(PROGRAM)_pro_16MHz.hex
|
||||||
|
pro16: $(PROGRAM)_pro_16MHz.lst
|
||||||
|
|
||||||
|
pro16_isp: pro16
|
||||||
|
pro16_isp: TARGET = pro_16MHz
|
||||||
|
# 2.7V brownout
|
||||||
|
pro16_isp: HFUSE = DD
|
||||||
|
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
|
||||||
|
pro16_isp: LFUSE = C6
|
||||||
|
# 512 byte boot
|
||||||
|
pro16_isp: EFUSE = 04
|
||||||
|
pro16_isp: isp
|
||||||
|
|
||||||
|
# Diecimila, Duemilanove with m168, and NG use identical bootloaders
|
||||||
|
# Call it "atmega168" for generality and clarity, keep "diecimila" for
|
||||||
|
# backward compatibility of makefile
|
||||||
|
#
|
||||||
|
atmega168: TARGET = atmega168
|
||||||
|
atmega168: MCU_TARGET = atmega168
|
||||||
|
atmega168: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=38400'
|
||||||
|
atmega168: AVR_FREQ = 12000000L
|
||||||
|
atmega168: $(PROGRAM)_atmega168.hex
|
||||||
|
atmega168: $(PROGRAM)_atmega168.lst
|
||||||
|
|
||||||
|
atmega168_isp: atmega168
|
||||||
|
atmega168_isp: TARGET = atmega168
|
||||||
|
# 2.7V brownout
|
||||||
|
atmega168_isp: HFUSE = DD
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
atmega168_isp: LFUSE = FF
|
||||||
|
# 512 byte boot
|
||||||
|
atmega168_isp: EFUSE = 04
|
||||||
|
atmega168_isp: isp
|
||||||
|
|
||||||
|
diecimila: TARGET = diecimila
|
||||||
|
diecimila: MCU_TARGET = atmega168
|
||||||
|
diecimila: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
diecimila: AVR_FREQ = 16000000L
|
||||||
|
diecimila: $(PROGRAM)_diecimila.hex
|
||||||
|
diecimila: $(PROGRAM)_diecimila.lst
|
||||||
|
|
||||||
|
diecimila_isp: diecimila
|
||||||
|
diecimila_isp: TARGET = diecimila
|
||||||
|
# 2.7V brownout
|
||||||
|
diecimila_isp: HFUSE = DD
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
diecimila_isp: LFUSE = FF
|
||||||
|
# 512 byte boot
|
||||||
|
diecimila_isp: EFUSE = 04
|
||||||
|
diecimila_isp: isp
|
||||||
|
|
||||||
|
atmega328_isp: atmega328
|
||||||
|
atmega328_isp: TARGET = atmega328
|
||||||
|
atmega328_isp: MCU_TARGET = atmega328p
|
||||||
|
# 512 byte boot, SPIEN
|
||||||
|
atmega328_isp: HFUSE = DE
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
atmega328_isp: LFUSE = FF
|
||||||
|
# 2.7V brownout
|
||||||
|
atmega328_isp: EFUSE = FD
|
||||||
|
atmega328_isp: isp
|
||||||
|
|
||||||
|
atmega1284: TARGET = atmega1284p
|
||||||
|
atmega1284: MCU_TARGET = atmega1284p
|
||||||
|
atmega1284: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DBIGBOOT'
|
||||||
|
atmega1284: AVR_FREQ = 16000000L
|
||||||
|
atmega1284: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe
|
||||||
|
atmega1284: $(PROGRAM)_atmega1284p.hex
|
||||||
|
atmega1284: $(PROGRAM)_atmega1284p.lst
|
||||||
|
|
||||||
|
atmega1284_isp: atmega1284
|
||||||
|
atmega1284_isp: TARGET = atmega1284p
|
||||||
|
atmega1284_isp: MCU_TARGET = atmega1284p
|
||||||
|
# 1024 byte boot
|
||||||
|
atmega1284_isp: HFUSE = DE
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
atmega1284_isp: LFUSE = FF
|
||||||
|
# 2.7V brownout
|
||||||
|
atmega1284_isp: EFUSE = FD
|
||||||
|
atmega1284_isp: isp
|
||||||
|
|
||||||
|
# Sanguino has a minimum boot size of 1024 bytes, so enable extra functions
|
||||||
|
#
|
||||||
|
sanguino: TARGET = atmega644p
|
||||||
|
sanguino: MCU_TARGET = atmega644p
|
||||||
|
sanguino: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DBIGBOOT'
|
||||||
|
sanguino: AVR_FREQ = 16000000L
|
||||||
|
sanguino: LDSECTIONS = -Wl,--section-start=.text=0xfc00 -Wl,--section-start=.version=0xfffe
|
||||||
|
sanguino: $(PROGRAM)_atmega644p.hex
|
||||||
|
sanguino: $(PROGRAM)_atmega644p.lst
|
||||||
|
|
||||||
|
sanguino_isp: sanguino
|
||||||
|
sanguino_isp: TARGET = atmega644p
|
||||||
|
sanguino_isp: MCU_TARGET = atmega644p
|
||||||
|
# 1024 byte boot
|
||||||
|
sanguino_isp: HFUSE = DE
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
sanguino_isp: LFUSE = FF
|
||||||
|
# 2.7V brownout
|
||||||
|
sanguino_isp: EFUSE = FD
|
||||||
|
sanguino_isp: isp
|
||||||
|
|
||||||
|
# Mega has a minimum boot size of 1024 bytes, so enable extra functions
|
||||||
|
#mega: TARGET = atmega1280
|
||||||
|
mega1280: MCU_TARGET = atmega1280
|
||||||
|
mega1280: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DBIGBOOT'
|
||||||
|
mega1280: AVR_FREQ = 16000000L
|
||||||
|
mega1280: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe
|
||||||
|
mega1280: $(PROGRAM)_atmega1280.hex
|
||||||
|
mega1280: $(PROGRAM)_atmega1280.lst
|
||||||
|
|
||||||
|
mega1280_isp: mega
|
||||||
|
mega1280_isp: TARGET = atmega1280
|
||||||
|
mega1280_isp: MCU_TARGET = atmega1280
|
||||||
|
# 1024 byte boot
|
||||||
|
mega1280_isp: HFUSE = DE
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
mega1280_isp: LFUSE = FF
|
||||||
|
# 2.7V brownout
|
||||||
|
mega1280_isp: EFUSE = FD
|
||||||
|
mega1280_isp: isp
|
||||||
|
|
||||||
|
# ATmega8
|
||||||
|
#
|
||||||
|
atmega8: TARGET = atmega8
|
||||||
|
atmega8: MCU_TARGET = atmega8
|
||||||
|
atmega8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
atmega8: AVR_FREQ = 16000000L
|
||||||
|
atmega8: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
|
||||||
|
atmega8: $(PROGRAM)_atmega8.hex
|
||||||
|
atmega8: $(PROGRAM)_atmega8.lst
|
||||||
|
|
||||||
|
atmega8_isp: atmega8
|
||||||
|
atmega8_isp: TARGET = atmega8
|
||||||
|
atmega8_isp: MCU_TARGET = atmega8
|
||||||
|
# SPIEN, CKOPT, Bootsize=512B
|
||||||
|
atmega8_isp: HFUSE = CC
|
||||||
|
# 2.7V brownout, Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
atmega8_isp: LFUSE = BF
|
||||||
|
atmega8_isp: isp
|
||||||
|
|
||||||
|
# ATmega88
|
||||||
|
#
|
||||||
|
atmega88: TARGET = atmega88
|
||||||
|
atmega88: MCU_TARGET = atmega88
|
||||||
|
atmega88: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=38400'
|
||||||
|
atmega88: AVR_FREQ = 12000000L
|
||||||
|
atmega88: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
|
||||||
|
atmega88: $(PROGRAM)_atmega88.hex
|
||||||
|
atmega88: $(PROGRAM)_atmega88.lst
|
||||||
|
|
||||||
|
atmega88_isp: atmega88
|
||||||
|
atmega88_isp: TARGET = atmega88
|
||||||
|
atmega88_isp: MCU_TARGET = atmega88
|
||||||
|
# 2.7V brownout
|
||||||
|
atmega88_isp: HFUSE = DD
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
atemga88_isp: LFUSE = FF
|
||||||
|
# 512 byte boot
|
||||||
|
atmega88_isp: EFUSE = 04
|
||||||
|
atmega88_isp: isp
|
||||||
|
|
||||||
|
|
||||||
|
# 8MHz clocked platforms
|
||||||
|
#
|
||||||
|
# These are capable of 38400 baud
|
||||||
|
#
|
||||||
|
|
||||||
|
lilypad: TARGET = lilypad
|
||||||
|
lilypad: MCU_TARGET = atmega168
|
||||||
|
lilypad: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
lilypad: AVR_FREQ = 8000000L
|
||||||
|
lilypad: $(PROGRAM)_lilypad.hex
|
||||||
|
lilypad: $(PROGRAM)_lilypad.lst
|
||||||
|
|
||||||
|
lilypad_isp: lilypad
|
||||||
|
lilypad_isp: TARGET = lilypad
|
||||||
|
# 2.7V brownout
|
||||||
|
lilypad_isp: HFUSE = DD
|
||||||
|
# Internal 8MHz osc (8MHz) Slow rising power
|
||||||
|
lilypad_isp: LFUSE = E2
|
||||||
|
# 512 byte boot
|
||||||
|
lilypad_isp: EFUSE = 04
|
||||||
|
lilypad_isp: isp
|
||||||
|
|
||||||
|
lilypad_resonator: TARGET = lilypad_resonator
|
||||||
|
lilypad_resonator: MCU_TARGET = atmega168
|
||||||
|
lilypad_resonator: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
lilypad_resonator: AVR_FREQ = 8000000L
|
||||||
|
lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex
|
||||||
|
lilypad_resonator: $(PROGRAM)_lilypad_resonator.lst
|
||||||
|
|
||||||
|
lilypad_resonator_isp: lilypad_resonator
|
||||||
|
lilypad_resonator_isp: TARGET = lilypad_resonator
|
||||||
|
# 2.7V brownout
|
||||||
|
lilypad_resonator_isp: HFUSE = DD
|
||||||
|
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
|
||||||
|
lilypad_resonator_isp: LFUSE = C6
|
||||||
|
# 512 byte boot
|
||||||
|
lilypad_resonator_isp: EFUSE = 04
|
||||||
|
lilypad_resonator_isp: isp
|
||||||
|
|
||||||
|
pro8: TARGET = pro_8MHz
|
||||||
|
pro8: MCU_TARGET = atmega168
|
||||||
|
pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
pro8: AVR_FREQ = 8000000L
|
||||||
|
pro8: $(PROGRAM)_pro_8MHz.hex
|
||||||
|
pro8: $(PROGRAM)_pro_8MHz.lst
|
||||||
|
|
||||||
|
pro8_isp: pro8
|
||||||
|
pro8_isp: TARGET = pro_8MHz
|
||||||
|
# 2.7V brownout
|
||||||
|
pro8_isp: HFUSE = DD
|
||||||
|
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
|
||||||
|
pro8_isp: LFUSE = C6
|
||||||
|
# 512 byte boot
|
||||||
|
pro8_isp: EFUSE = 04
|
||||||
|
pro8_isp: isp
|
||||||
|
|
||||||
|
atmega328_pro8: TARGET = atmega328_pro_8MHz
|
||||||
|
atmega328_pro8: MCU_TARGET = atmega328p
|
||||||
|
atmega328_pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
atmega328_pro8: AVR_FREQ = 8000000L
|
||||||
|
atmega328_pro8: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
|
||||||
|
atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex
|
||||||
|
atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.lst
|
||||||
|
|
||||||
|
atmega328_pro8_isp: atmega328_pro8
|
||||||
|
atmega328_pro8_isp: TARGET = atmega328_pro_8MHz
|
||||||
|
atmega328_pro8_isp: MCU_TARGET = atmega328p
|
||||||
|
# 512 byte boot, SPIEN
|
||||||
|
atmega328_pro8_isp: HFUSE = DE
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
atmega328_pro8_isp: LFUSE = FF
|
||||||
|
# 2.7V brownout
|
||||||
|
atmega328_pro8_isp: EFUSE = DE
|
||||||
|
atmega328_pro8_isp: isp
|
||||||
|
|
||||||
|
# 1MHz clocked platforms
|
||||||
|
#
|
||||||
|
# These are capable of 9600 baud
|
||||||
|
#
|
||||||
|
|
||||||
|
luminet: TARGET = luminet
|
||||||
|
luminet: MCU_TARGET = attiny84
|
||||||
|
luminet: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600'
|
||||||
|
luminet: CFLAGS += '-DVIRTUAL_BOOT_PARTITION'
|
||||||
|
luminet: AVR_FREQ = 1000000L
|
||||||
|
luminet: LDSECTIONS = -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1efe
|
||||||
|
luminet: $(PROGRAM)_luminet.hex
|
||||||
|
luminet: $(PROGRAM)_luminet.lst
|
||||||
|
|
||||||
|
luminet_isp: luminet
|
||||||
|
luminet_isp: TARGET = luminet
|
||||||
|
luminet_isp: MCU_TARGET = attiny84
|
||||||
|
# Brownout disabled
|
||||||
|
luminet_isp: HFUSE = DF
|
||||||
|
# 1MHz internal oscillator, slowly rising power
|
||||||
|
luminet_isp: LFUSE = 62
|
||||||
|
# Self-programming enable
|
||||||
|
luminet_isp: EFUSE = FE
|
||||||
|
luminet_isp: isp
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generic build instructions
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
isp: $(TARGET)
|
||||||
|
$(ISPFUSES)
|
||||||
|
$(ISPFLASH)
|
||||||
|
|
||||||
|
isp-stk500: $(PROGRAM)_$(TARGET).hex
|
||||||
|
$(STK500-1)
|
||||||
|
$(STK500-2)
|
||||||
|
|
||||||
|
%.elf: $(OBJ)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
$(SIZE) $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
|
||||||
|
|
||||||
|
%.lst: %.elf
|
||||||
|
$(OBJDUMP) -h -S $< > $@
|
||||||
|
|
||||||
|
%.hex: %.elf
|
||||||
|
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@
|
||||||
|
|
||||||
|
%.srec: %.elf
|
||||||
|
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@
|
||||||
|
|
||||||
|
%.bin: %.elf
|
||||||
|
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@
|
848
BootLoaders/AtmegaMultiBoot/Source/boot.h
Normal file
848
BootLoaders/AtmegaMultiBoot/Source/boot.h
Normal file
@ -0,0 +1,848 @@
|
|||||||
|
/* Modified to use out for SPM access
|
||||||
|
** Peter Knight, Optiboot project http://optiboot.googlecode.com
|
||||||
|
**
|
||||||
|
** Todo: Tidy up
|
||||||
|
**
|
||||||
|
** "_short" routines execute 1 cycle faster and use 1 less word of flash
|
||||||
|
** by using "out" instruction instead of "sts".
|
||||||
|
**
|
||||||
|
** Additional elpm variants that trust the value of RAMPZ
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 Eric B. Weddington
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of the copyright holders nor the names of
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
/* $Id: boot.h,v 1.27.2.3 2008/09/30 13:58:48 arcanum Exp $ */
|
||||||
|
|
||||||
|
#ifndef _AVR_BOOT_H_
|
||||||
|
#define _AVR_BOOT_H_ 1
|
||||||
|
|
||||||
|
/** \file */
|
||||||
|
/** \defgroup avr_boot <avr/boot.h>: Bootloader Support Utilities
|
||||||
|
\code
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/boot.h>
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
The macros in this module provide a C language interface to the
|
||||||
|
bootloader support functionality of certain AVR processors. These
|
||||||
|
macros are designed to work with all sizes of flash memory.
|
||||||
|
|
||||||
|
Global interrupts are not automatically disabled for these macros. It
|
||||||
|
is left up to the programmer to do this. See the code example below.
|
||||||
|
Also see the processor datasheet for caveats on having global interrupts
|
||||||
|
enabled during writing of the Flash.
|
||||||
|
|
||||||
|
\note Not all AVR processors provide bootloader support. See your
|
||||||
|
processor datasheet to see if it provides bootloader support.
|
||||||
|
|
||||||
|
\todo From email with Marek: On smaller devices (all except ATmega64/128),
|
||||||
|
__SPM_REG is in the I/O space, accessible with the shorter "in" and "out"
|
||||||
|
instructions - since the boot loader has a limited size, this could be an
|
||||||
|
important optimization.
|
||||||
|
|
||||||
|
\par API Usage Example
|
||||||
|
The following code shows typical usage of the boot API.
|
||||||
|
|
||||||
|
\code
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
|
void boot_program_page (uint32_t page, uint8_t *buf)
|
||||||
|
{
|
||||||
|
uint16_t i;
|
||||||
|
uint8_t sreg;
|
||||||
|
|
||||||
|
// Disable interrupts.
|
||||||
|
|
||||||
|
sreg = SREG;
|
||||||
|
cli();
|
||||||
|
|
||||||
|
eeprom_busy_wait ();
|
||||||
|
|
||||||
|
boot_page_erase (page);
|
||||||
|
boot_spm_busy_wait (); // Wait until the memory is erased.
|
||||||
|
|
||||||
|
for (i=0; i<SPM_PAGESIZE; i+=2)
|
||||||
|
{
|
||||||
|
// Set up little-endian word.
|
||||||
|
|
||||||
|
uint16_t w = *buf++;
|
||||||
|
w += (*buf++) << 8;
|
||||||
|
|
||||||
|
boot_page_fill (page + i, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
boot_page_write (page); // Store buffer in flash page.
|
||||||
|
boot_spm_busy_wait(); // Wait until the memory is written.
|
||||||
|
|
||||||
|
// Reenable RWW-section again. We need this if we want to jump back
|
||||||
|
// to the application after bootloading.
|
||||||
|
|
||||||
|
boot_rww_enable ();
|
||||||
|
|
||||||
|
// Re-enable interrupts (if they were ever enabled).
|
||||||
|
|
||||||
|
SREG = sreg;
|
||||||
|
}\endcode */
|
||||||
|
|
||||||
|
#include <avr/eeprom.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* Check for SPM Control Register in processor. */
|
||||||
|
#if defined (SPMCSR)
|
||||||
|
# define __SPM_REG SPMCSR
|
||||||
|
#elif defined (SPMCR)
|
||||||
|
# define __SPM_REG SPMCR
|
||||||
|
#else
|
||||||
|
# error AVR processor does not provide bootloader support!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Check for SPM Enable bit. */
|
||||||
|
#if defined(SPMEN)
|
||||||
|
# define __SPM_ENABLE SPMEN
|
||||||
|
#elif defined(SELFPRGEN)
|
||||||
|
# define __SPM_ENABLE SELFPRGEN
|
||||||
|
#else
|
||||||
|
# error Cannot find SPM Enable bit definition!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def BOOTLOADER_SECTION
|
||||||
|
|
||||||
|
Used to declare a function or variable to be placed into a
|
||||||
|
new section called .bootloader. This section and its contents
|
||||||
|
can then be relocated to any address (such as the bootloader
|
||||||
|
NRWW area) at link-time. */
|
||||||
|
|
||||||
|
#define BOOTLOADER_SECTION __attribute__ ((section (".bootloader")))
|
||||||
|
|
||||||
|
/* Create common bit definitions. */
|
||||||
|
#ifdef ASB
|
||||||
|
#define __COMMON_ASB ASB
|
||||||
|
#else
|
||||||
|
#define __COMMON_ASB RWWSB
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ASRE
|
||||||
|
#define __COMMON_ASRE ASRE
|
||||||
|
#else
|
||||||
|
#define __COMMON_ASRE RWWSRE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define the bit positions of the Boot Lock Bits. */
|
||||||
|
|
||||||
|
#define BLB12 5
|
||||||
|
#define BLB11 4
|
||||||
|
#define BLB02 3
|
||||||
|
#define BLB01 2
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_spm_interrupt_enable()
|
||||||
|
Enable the SPM interrupt. */
|
||||||
|
|
||||||
|
#define boot_spm_interrupt_enable() (__SPM_REG |= (uint8_t)_BV(SPMIE))
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_spm_interrupt_disable()
|
||||||
|
Disable the SPM interrupt. */
|
||||||
|
|
||||||
|
#define boot_spm_interrupt_disable() (__SPM_REG &= (uint8_t)~_BV(SPMIE))
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_is_spm_interrupt()
|
||||||
|
Check if the SPM interrupt is enabled. */
|
||||||
|
|
||||||
|
#define boot_is_spm_interrupt() (__SPM_REG & (uint8_t)_BV(SPMIE))
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_rww_busy()
|
||||||
|
Check if the RWW section is busy. */
|
||||||
|
|
||||||
|
#define boot_rww_busy() (__SPM_REG & (uint8_t)_BV(__COMMON_ASB))
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_spm_busy()
|
||||||
|
Check if the SPM instruction is busy. */
|
||||||
|
|
||||||
|
#define boot_spm_busy() (__SPM_REG & (uint8_t)_BV(__SPM_ENABLE))
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_spm_busy_wait()
|
||||||
|
Wait while the SPM instruction is busy. */
|
||||||
|
|
||||||
|
#define boot_spm_busy_wait() do{}while(boot_spm_busy())
|
||||||
|
|
||||||
|
#define __BOOT_PAGE_ERASE (_BV(__SPM_ENABLE) | _BV(PGERS))
|
||||||
|
#define __BOOT_PAGE_WRITE (_BV(__SPM_ENABLE) | _BV(PGWRT))
|
||||||
|
#define __BOOT_PAGE_FILL _BV(__SPM_ENABLE)
|
||||||
|
#define __BOOT_RWW_ENABLE (_BV(__SPM_ENABLE) | _BV(__COMMON_ASRE))
|
||||||
|
#define __BOOT_LOCK_BITS_SET (_BV(__SPM_ENABLE) | _BV(BLBSET))
|
||||||
|
|
||||||
|
#define __boot_page_fill_short(address, data) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"movw r0, %3\n\t" \
|
||||||
|
"out %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
"clr r1\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_FILL), \
|
||||||
|
"z" ((uint16_t)address), \
|
||||||
|
"r" ((uint16_t)data) \
|
||||||
|
: "r0" \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_page_fill_normal(address, data) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"movw r0, %3\n\t" \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
"clr r1\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_FILL), \
|
||||||
|
"z" ((uint16_t)address), \
|
||||||
|
"r" ((uint16_t)data) \
|
||||||
|
: "r0" \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_page_fill_alternate(address, data)\
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"movw r0, %3\n\t" \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
".word 0xffff\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
"clr r1\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_FILL), \
|
||||||
|
"z" ((uint16_t)address), \
|
||||||
|
"r" ((uint16_t)data) \
|
||||||
|
: "r0" \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_page_fill_extended(address, data) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"movw r0, %4\n\t" \
|
||||||
|
"movw r30, %A3\n\t" \
|
||||||
|
"sts %1, %C3\n\t" \
|
||||||
|
"sts %0, %2\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
"clr r1\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"i" (_SFR_MEM_ADDR(RAMPZ)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_FILL), \
|
||||||
|
"r" ((uint32_t)address), \
|
||||||
|
"r" ((uint16_t)data) \
|
||||||
|
: "r0", "r30", "r31" \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_page_fill_extended_short(address, data) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"movw r0, %4\n\t" \
|
||||||
|
"movw r30, %A3\n\t" \
|
||||||
|
"out %1, %C3\n\t" \
|
||||||
|
"out %0, %2\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
"clr r1\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
|
||||||
|
"i" (_SFR_IO_ADDR(RAMPZ)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_FILL), \
|
||||||
|
"r" ((uint32_t)address), \
|
||||||
|
"r" ((uint16_t)data) \
|
||||||
|
: "r0", "r30", "r31" \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_page_erase_short(address) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"out %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_ERASE), \
|
||||||
|
"z" ((uint16_t)address) \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
|
||||||
|
#define __boot_page_erase_normal(address) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_ERASE), \
|
||||||
|
"z" ((uint16_t)address) \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_page_erase_alternate(address) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
".word 0xffff\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_ERASE), \
|
||||||
|
"z" ((uint16_t)address) \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_page_erase_extended(address) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"movw r30, %A3\n\t" \
|
||||||
|
"sts %1, %C3\n\t" \
|
||||||
|
"sts %0, %2\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"i" (_SFR_MEM_ADDR(RAMPZ)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_ERASE), \
|
||||||
|
"r" ((uint32_t)address) \
|
||||||
|
: "r30", "r31" \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
#define __boot_page_erase_extended_short(address) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"movw r30, %A3\n\t" \
|
||||||
|
"out %1, %C3\n\t" \
|
||||||
|
"out %0, %2\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
|
||||||
|
"i" (_SFR_IO_ADDR(RAMPZ)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_ERASE), \
|
||||||
|
"r" ((uint32_t)address) \
|
||||||
|
: "r30", "r31" \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_page_write_short(address) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"out %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_WRITE), \
|
||||||
|
"z" ((uint16_t)address) \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_page_write_normal(address) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_WRITE), \
|
||||||
|
"z" ((uint16_t)address) \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_page_write_alternate(address) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
".word 0xffff\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_WRITE), \
|
||||||
|
"z" ((uint16_t)address) \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_page_write_extended(address) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"movw r30, %A3\n\t" \
|
||||||
|
"sts %1, %C3\n\t" \
|
||||||
|
"sts %0, %2\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"i" (_SFR_MEM_ADDR(RAMPZ)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_WRITE), \
|
||||||
|
"r" ((uint32_t)address) \
|
||||||
|
: "r30", "r31" \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
#define __boot_page_write_extended_short(address) \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"movw r30, %A3\n\t" \
|
||||||
|
"out %1, %C3\n\t" \
|
||||||
|
"out %0, %2\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
|
||||||
|
"i" (_SFR_IO_ADDR(RAMPZ)), \
|
||||||
|
"r" ((uint8_t)__BOOT_PAGE_WRITE), \
|
||||||
|
"r" ((uint32_t)address) \
|
||||||
|
: "r30", "r31" \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_rww_enable_short() \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"out %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_RWW_ENABLE) \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_rww_enable() \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_RWW_ENABLE) \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_rww_enable_alternate() \
|
||||||
|
(__extension__({ \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
".word 0xffff\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_RWW_ENABLE) \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
/* From the mega16/mega128 data sheets (maybe others):
|
||||||
|
|
||||||
|
Bits by SPM To set the Boot Loader Lock bits, write the desired data to
|
||||||
|
R0, write "X0001001" to SPMCR and execute SPM within four clock cycles
|
||||||
|
after writing SPMCR. The only accessible Lock bits are the Boot Lock bits
|
||||||
|
that may prevent the Application and Boot Loader section from any
|
||||||
|
software update by the MCU.
|
||||||
|
|
||||||
|
If bits 5..2 in R0 are cleared (zero), the corresponding Boot Lock bit
|
||||||
|
will be programmed if an SPM instruction is executed within four cycles
|
||||||
|
after BLBSET and SPMEN (or SELFPRGEN) are set in SPMCR. The Z-pointer is
|
||||||
|
don't care during this operation, but for future compatibility it is
|
||||||
|
recommended to load the Z-pointer with $0001 (same as used for reading the
|
||||||
|
Lock bits). For future compatibility It is also recommended to set bits 7,
|
||||||
|
6, 1, and 0 in R0 to 1 when writing the Lock bits. When programming the
|
||||||
|
Lock bits the entire Flash can be read during the operation. */
|
||||||
|
|
||||||
|
#define __boot_lock_bits_set_short(lock_bits) \
|
||||||
|
(__extension__({ \
|
||||||
|
uint8_t value = (uint8_t)(~(lock_bits)); \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"ldi r30, 1\n\t" \
|
||||||
|
"ldi r31, 0\n\t" \
|
||||||
|
"mov r0, %2\n\t" \
|
||||||
|
"out %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_LOCK_BITS_SET), \
|
||||||
|
"r" (value) \
|
||||||
|
: "r0", "r30", "r31" \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_lock_bits_set(lock_bits) \
|
||||||
|
(__extension__({ \
|
||||||
|
uint8_t value = (uint8_t)(~(lock_bits)); \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"ldi r30, 1\n\t" \
|
||||||
|
"ldi r31, 0\n\t" \
|
||||||
|
"mov r0, %2\n\t" \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_LOCK_BITS_SET), \
|
||||||
|
"r" (value) \
|
||||||
|
: "r0", "r30", "r31" \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define __boot_lock_bits_set_alternate(lock_bits) \
|
||||||
|
(__extension__({ \
|
||||||
|
uint8_t value = (uint8_t)(~(lock_bits)); \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"ldi r30, 1\n\t" \
|
||||||
|
"ldi r31, 0\n\t" \
|
||||||
|
"mov r0, %2\n\t" \
|
||||||
|
"sts %0, %1\n\t" \
|
||||||
|
"spm\n\t" \
|
||||||
|
".word 0xffff\n\t" \
|
||||||
|
"nop\n\t" \
|
||||||
|
: \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_LOCK_BITS_SET), \
|
||||||
|
"r" (value) \
|
||||||
|
: "r0", "r30", "r31" \
|
||||||
|
); \
|
||||||
|
}))
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reading lock and fuse bits:
|
||||||
|
|
||||||
|
Similarly to writing the lock bits above, set BLBSET and SPMEN (or
|
||||||
|
SELFPRGEN) bits in __SPMREG, and then (within four clock cycles) issue an
|
||||||
|
LPM instruction.
|
||||||
|
|
||||||
|
Z address: contents:
|
||||||
|
0x0000 low fuse bits
|
||||||
|
0x0001 lock bits
|
||||||
|
0x0002 extended fuse bits
|
||||||
|
0x0003 high fuse bits
|
||||||
|
|
||||||
|
Sounds confusing, doesn't it?
|
||||||
|
|
||||||
|
Unlike the macros in pgmspace.h, no need to care for non-enhanced
|
||||||
|
cores here as these old cores do not provide SPM support anyway.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def GET_LOW_FUSE_BITS
|
||||||
|
address to read the low fuse bits, using boot_lock_fuse_bits_get
|
||||||
|
*/
|
||||||
|
#define GET_LOW_FUSE_BITS (0x0000)
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def GET_LOCK_BITS
|
||||||
|
address to read the lock bits, using boot_lock_fuse_bits_get
|
||||||
|
*/
|
||||||
|
#define GET_LOCK_BITS (0x0001)
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def GET_EXTENDED_FUSE_BITS
|
||||||
|
address to read the extended fuse bits, using boot_lock_fuse_bits_get
|
||||||
|
*/
|
||||||
|
#define GET_EXTENDED_FUSE_BITS (0x0002)
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def GET_HIGH_FUSE_BITS
|
||||||
|
address to read the high fuse bits, using boot_lock_fuse_bits_get
|
||||||
|
*/
|
||||||
|
#define GET_HIGH_FUSE_BITS (0x0003)
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_lock_fuse_bits_get(address)
|
||||||
|
|
||||||
|
Read the lock or fuse bits at \c address.
|
||||||
|
|
||||||
|
Parameter \c address can be any of GET_LOW_FUSE_BITS,
|
||||||
|
GET_LOCK_BITS, GET_EXTENDED_FUSE_BITS, or GET_HIGH_FUSE_BITS.
|
||||||
|
|
||||||
|
\note The lock and fuse bits returned are the physical values,
|
||||||
|
i.e. a bit returned as 0 means the corresponding fuse or lock bit
|
||||||
|
is programmed.
|
||||||
|
*/
|
||||||
|
#define boot_lock_fuse_bits_get_short(address) \
|
||||||
|
(__extension__({ \
|
||||||
|
uint8_t __result; \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"ldi r30, %3\n\t" \
|
||||||
|
"ldi r31, 0\n\t" \
|
||||||
|
"out %1, %2\n\t" \
|
||||||
|
"lpm %0, Z\n\t" \
|
||||||
|
: "=r" (__result) \
|
||||||
|
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_LOCK_BITS_SET), \
|
||||||
|
"M" (address) \
|
||||||
|
: "r0", "r30", "r31" \
|
||||||
|
); \
|
||||||
|
__result; \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define boot_lock_fuse_bits_get(address) \
|
||||||
|
(__extension__({ \
|
||||||
|
uint8_t __result; \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"ldi r30, %3\n\t" \
|
||||||
|
"ldi r31, 0\n\t" \
|
||||||
|
"sts %1, %2\n\t" \
|
||||||
|
"lpm %0, Z\n\t" \
|
||||||
|
: "=r" (__result) \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t)__BOOT_LOCK_BITS_SET), \
|
||||||
|
"M" (address) \
|
||||||
|
: "r0", "r30", "r31" \
|
||||||
|
); \
|
||||||
|
__result; \
|
||||||
|
}))
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_signature_byte_get(address)
|
||||||
|
|
||||||
|
Read the Signature Row byte at \c address. For some MCU types,
|
||||||
|
this function can also retrieve the factory-stored oscillator
|
||||||
|
calibration bytes.
|
||||||
|
|
||||||
|
Parameter \c address can be 0-0x1f as documented by the datasheet.
|
||||||
|
\note The values are MCU type dependent.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE) | _BV(SIGRD))
|
||||||
|
|
||||||
|
#define boot_signature_byte_get_short(addr) \
|
||||||
|
(__extension__({ \
|
||||||
|
uint16_t __addr16 = (uint16_t)(addr); \
|
||||||
|
uint8_t __result; \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"out %1, %2\n\t" \
|
||||||
|
"lpm %0, Z" "\n\t" \
|
||||||
|
: "=r" (__result) \
|
||||||
|
: "i" (_SFR_IO_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t) __BOOT_SIGROW_READ), \
|
||||||
|
"z" (__addr16) \
|
||||||
|
); \
|
||||||
|
__result; \
|
||||||
|
}))
|
||||||
|
|
||||||
|
#define boot_signature_byte_get(addr) \
|
||||||
|
(__extension__({ \
|
||||||
|
uint16_t __addr16 = (uint16_t)(addr); \
|
||||||
|
uint8_t __result; \
|
||||||
|
__asm__ __volatile__ \
|
||||||
|
( \
|
||||||
|
"sts %1, %2\n\t" \
|
||||||
|
"lpm %0, Z" "\n\t" \
|
||||||
|
: "=r" (__result) \
|
||||||
|
: "i" (_SFR_MEM_ADDR(__SPM_REG)), \
|
||||||
|
"r" ((uint8_t) __BOOT_SIGROW_READ), \
|
||||||
|
"z" (__addr16) \
|
||||||
|
); \
|
||||||
|
__result; \
|
||||||
|
}))
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_page_fill(address, data)
|
||||||
|
|
||||||
|
Fill the bootloader temporary page buffer for flash
|
||||||
|
address with data word.
|
||||||
|
|
||||||
|
\note The address is a byte address. The data is a word. The AVR
|
||||||
|
writes data to the buffer a word at a time, but addresses the buffer
|
||||||
|
per byte! So, increment your address by 2 between calls, and send 2
|
||||||
|
data bytes in a word format! The LSB of the data is written to the lower
|
||||||
|
address; the MSB of the data is written to the higher address.*/
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_page_erase(address)
|
||||||
|
|
||||||
|
Erase the flash page that contains address.
|
||||||
|
|
||||||
|
\note address is a byte address in flash, not a word address. */
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_page_write(address)
|
||||||
|
|
||||||
|
Write the bootloader temporary page buffer
|
||||||
|
to flash page that contains address.
|
||||||
|
|
||||||
|
\note address is a byte address in flash, not a word address. */
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_rww_enable()
|
||||||
|
|
||||||
|
Enable the Read-While-Write memory section. */
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
\def boot_lock_bits_set(lock_bits)
|
||||||
|
|
||||||
|
Set the bootloader lock bits.
|
||||||
|
|
||||||
|
\param lock_bits A mask of which Boot Loader Lock Bits to set.
|
||||||
|
|
||||||
|
\note In this context, a 'set bit' will be written to a zero value.
|
||||||
|
Note also that only BLBxx bits can be programmed by this command.
|
||||||
|
|
||||||
|
For example, to disallow the SPM instruction from writing to the Boot
|
||||||
|
Loader memory section of flash, you would use this macro as such:
|
||||||
|
|
||||||
|
\code
|
||||||
|
boot_lock_bits_set (_BV (BLB11));
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
\note Like any lock bits, the Boot Loader Lock Bits, once set,
|
||||||
|
cannot be cleared again except by a chip erase which will in turn
|
||||||
|
also erase the boot loader itself. */
|
||||||
|
|
||||||
|
/* Normal versions of the macros use 16-bit addresses.
|
||||||
|
Extended versions of the macros use 32-bit addresses.
|
||||||
|
Alternate versions of the macros use 16-bit addresses and require special
|
||||||
|
instruction sequences after LPM.
|
||||||
|
|
||||||
|
FLASHEND is defined in the ioXXXX.h file.
|
||||||
|
USHRT_MAX is defined in <limits.h>. */
|
||||||
|
|
||||||
|
#if defined(__AVR_ATmega161__) || defined(__AVR_ATmega163__) \
|
||||||
|
|| defined(__AVR_ATmega323__)
|
||||||
|
|
||||||
|
/* Alternate: ATmega161/163/323 and 16 bit address */
|
||||||
|
#define boot_page_fill(address, data) __boot_page_fill_alternate(address, data)
|
||||||
|
#define boot_page_erase(address) __boot_page_erase_alternate(address)
|
||||||
|
#define boot_page_write(address) __boot_page_write_alternate(address)
|
||||||
|
#define boot_rww_enable() __boot_rww_enable_alternate()
|
||||||
|
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_alternate(lock_bits)
|
||||||
|
|
||||||
|
#elif (FLASHEND > USHRT_MAX)
|
||||||
|
|
||||||
|
/* Extended: >16 bit address */
|
||||||
|
#define boot_page_fill(address, data) __boot_page_fill_extended_short(address, data)
|
||||||
|
#define boot_page_erase(address) __boot_page_erase_extended_short(address)
|
||||||
|
#define boot_page_write(address) __boot_page_write_extended_short(address)
|
||||||
|
#define boot_rww_enable() __boot_rww_enable_short()
|
||||||
|
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_short(lock_bits)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Normal: 16 bit address */
|
||||||
|
#define boot_page_fill(address, data) __boot_page_fill_short(address, data)
|
||||||
|
#define boot_page_erase(address) __boot_page_erase_short(address)
|
||||||
|
#define boot_page_write(address) __boot_page_write_short(address)
|
||||||
|
#define boot_rww_enable() __boot_rww_enable_short()
|
||||||
|
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_short(lock_bits)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
|
||||||
|
Same as boot_page_fill() except it waits for eeprom and spm operations to
|
||||||
|
complete before filling the page. */
|
||||||
|
|
||||||
|
#define boot_page_fill_safe(address, data) \
|
||||||
|
do { \
|
||||||
|
boot_spm_busy_wait(); \
|
||||||
|
eeprom_busy_wait(); \
|
||||||
|
boot_page_fill(address, data); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
|
||||||
|
Same as boot_page_erase() except it waits for eeprom and spm operations to
|
||||||
|
complete before erasing the page. */
|
||||||
|
|
||||||
|
#define boot_page_erase_safe(address) \
|
||||||
|
do { \
|
||||||
|
boot_spm_busy_wait(); \
|
||||||
|
eeprom_busy_wait(); \
|
||||||
|
boot_page_erase (address); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
|
||||||
|
Same as boot_page_write() except it waits for eeprom and spm operations to
|
||||||
|
complete before writing the page. */
|
||||||
|
|
||||||
|
#define boot_page_write_safe(address) \
|
||||||
|
do { \
|
||||||
|
boot_spm_busy_wait(); \
|
||||||
|
eeprom_busy_wait(); \
|
||||||
|
boot_page_write (address); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
|
||||||
|
Same as boot_rww_enable() except waits for eeprom and spm operations to
|
||||||
|
complete before enabling the RWW mameory. */
|
||||||
|
|
||||||
|
#define boot_rww_enable_safe() \
|
||||||
|
do { \
|
||||||
|
boot_spm_busy_wait(); \
|
||||||
|
eeprom_busy_wait(); \
|
||||||
|
boot_rww_enable(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/** \ingroup avr_boot
|
||||||
|
|
||||||
|
Same as boot_lock_bits_set() except waits for eeprom and spm operations to
|
||||||
|
complete before setting the lock bits. */
|
||||||
|
|
||||||
|
#define boot_lock_bits_set_safe(lock_bits) \
|
||||||
|
do { \
|
||||||
|
boot_spm_busy_wait(); \
|
||||||
|
eeprom_busy_wait(); \
|
||||||
|
boot_lock_bits_set (lock_bits); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif /* _AVR_BOOT_H_ */
|
891
BootLoaders/AtmegaMultiBoot/Source/optiboot.c
Normal file
891
BootLoaders/AtmegaMultiBoot/Source/optiboot.c
Normal file
@ -0,0 +1,891 @@
|
|||||||
|
/**********************************************************/
|
||||||
|
/* Optiboot bootloader for Arduino */
|
||||||
|
/* */
|
||||||
|
/* http://optiboot.googlecode.com */
|
||||||
|
/* */
|
||||||
|
/* Arduino-maintained version : See README.TXT */
|
||||||
|
/* http://code.google.com/p/arduino/ */
|
||||||
|
/* It is the intent that changes not relevant to the */
|
||||||
|
/* Arduino production envionment get moved from the */
|
||||||
|
/* optiboot project to the arduino project in "lumps." */
|
||||||
|
/* */
|
||||||
|
/* Heavily optimised bootloader that is faster and */
|
||||||
|
/* smaller than the Arduino standard bootloader */
|
||||||
|
/* */
|
||||||
|
/* Enhancements: */
|
||||||
|
/* Fits in 512 bytes, saving 1.5K of code space */
|
||||||
|
/* Background page erasing speeds up programming */
|
||||||
|
/* Higher baud rate speeds up programming */
|
||||||
|
/* Written almost entirely in C */
|
||||||
|
/* Customisable timeout with accurate timeconstant */
|
||||||
|
/* Optional virtual UART. No hardware UART required. */
|
||||||
|
/* Optional virtual boot partition for devices without. */
|
||||||
|
/* */
|
||||||
|
/* What you lose: */
|
||||||
|
/* Implements a skeleton STK500 protocol which is */
|
||||||
|
/* missing several features including EEPROM */
|
||||||
|
/* programming and non-page-aligned writes */
|
||||||
|
/* High baud rate breaks compatibility with standard */
|
||||||
|
/* Arduino flash settings */
|
||||||
|
/* */
|
||||||
|
/* Fully supported: */
|
||||||
|
/* ATmega168 based devices (Diecimila etc) */
|
||||||
|
/* ATmega328P based devices (Duemilanove etc) */
|
||||||
|
/* */
|
||||||
|
/* Beta test (believed working.) */
|
||||||
|
/* ATmega8 based devices (Arduino legacy) */
|
||||||
|
/* ATmega328 non-picopower devices */
|
||||||
|
/* ATmega644P based devices (Sanguino) */
|
||||||
|
/* ATmega1284P based devices */
|
||||||
|
/* */
|
||||||
|
/* Alpha test */
|
||||||
|
/* ATmega1280 based devices (Arduino Mega) */
|
||||||
|
/* */
|
||||||
|
/* Work in progress: */
|
||||||
|
/* ATtiny84 based devices (Luminet) */
|
||||||
|
/* */
|
||||||
|
/* Does not support: */
|
||||||
|
/* USB based devices (eg. Teensy) */
|
||||||
|
/* */
|
||||||
|
/* Assumptions: */
|
||||||
|
/* The code makes several assumptions that reduce the */
|
||||||
|
/* code size. They are all true after a hardware reset, */
|
||||||
|
/* but may not be true if the bootloader is called by */
|
||||||
|
/* other means or on other hardware. */
|
||||||
|
/* No interrupts can occur */
|
||||||
|
/* UART and Timer 1 are set to their reset state */
|
||||||
|
/* SP points to RAMEND */
|
||||||
|
/* */
|
||||||
|
/* Code builds on code, libraries and optimisations from: */
|
||||||
|
/* stk500boot.c by Jason P. Kyle */
|
||||||
|
/* Arduino bootloader http://arduino.cc */
|
||||||
|
/* Spiff's 1K bootloader http://spiffie.org/know/arduino_1k_bootloader/bootloader.shtml */
|
||||||
|
/* avr-libc project http://nongnu.org/avr-libc */
|
||||||
|
/* Adaboot http://www.ladyada.net/library/arduino/bootloader.html */
|
||||||
|
/* AVR305 Atmel Application Note */
|
||||||
|
/* */
|
||||||
|
/* This program is free software; you can redistribute it */
|
||||||
|
/* and/or modify it under the terms of the GNU General */
|
||||||
|
/* Public License as published by the Free Software */
|
||||||
|
/* Foundation; either version 2 of the License, or */
|
||||||
|
/* (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* This program is distributed in the hope that it will */
|
||||||
|
/* be useful, but WITHOUT ANY WARRANTY; without even the */
|
||||||
|
/* implied warranty of MERCHANTABILITY or FITNESS FOR A */
|
||||||
|
/* PARTICULAR PURPOSE. See the GNU General Public */
|
||||||
|
/* License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General */
|
||||||
|
/* Public License along with this program; if not, write */
|
||||||
|
/* to the Free Software Foundation, Inc., */
|
||||||
|
/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
/* */
|
||||||
|
/* Licence can be viewed at */
|
||||||
|
/* http://www.fsf.org/licenses/gpl.txt */
|
||||||
|
/* */
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* */
|
||||||
|
/* Optional defines: */
|
||||||
|
/* */
|
||||||
|
/**********************************************************/
|
||||||
|
/* */
|
||||||
|
/* BIG_BOOT: */
|
||||||
|
/* Build a 1k bootloader, not 512 bytes. This turns on */
|
||||||
|
/* extra functionality. */
|
||||||
|
/* */
|
||||||
|
/* BAUD_RATE: */
|
||||||
|
/* Set bootloader baud rate. */
|
||||||
|
/* */
|
||||||
|
/* LUDICROUS_SPEED: */
|
||||||
|
/* 230400 baud :-) */
|
||||||
|
/* */
|
||||||
|
/* SOFT_UART: */
|
||||||
|
/* Use AVR305 soft-UART instead of hardware UART. */
|
||||||
|
/* */
|
||||||
|
/* LED_START_FLASHES: */
|
||||||
|
/* Number of LED flashes on bootup. */
|
||||||
|
/* */
|
||||||
|
/* LED_DATA_FLASH: */
|
||||||
|
/* Flash LED when transferring data. For boards without */
|
||||||
|
/* TX or RX LEDs, or for people who like blinky lights. */
|
||||||
|
/* */
|
||||||
|
/* SUPPORT_EEPROM: */
|
||||||
|
/* Support reading and writing from EEPROM. This is not */
|
||||||
|
/* used by Arduino, so off by default. */
|
||||||
|
/* */
|
||||||
|
/* TIMEOUT_MS: */
|
||||||
|
/* Bootloader timeout period, in milliseconds. */
|
||||||
|
/* 500,1000,2000,4000,8000 supported. */
|
||||||
|
/* */
|
||||||
|
/* UART: */
|
||||||
|
/* UART number (0..n) for devices with more than */
|
||||||
|
/* one hardware uart (644P, 1284P, etc) */
|
||||||
|
/* */
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* Version Numbers! */
|
||||||
|
/* */
|
||||||
|
/* Arduino Optiboot now includes this Version number in */
|
||||||
|
/* the source and object code. */
|
||||||
|
/* */
|
||||||
|
/* Version 3 was released as zip from the optiboot */
|
||||||
|
/* repository and was distributed with Arduino 0022. */
|
||||||
|
/* Version 4 starts with the arduino repository commit */
|
||||||
|
/* that brought the arduino repository up-to-date with */
|
||||||
|
/* the optiboot source tree changes since v3. */
|
||||||
|
/* */
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* Edit History: */
|
||||||
|
/* */
|
||||||
|
/* Nov 2012 */
|
||||||
|
/* Specific version for 9x voice module */
|
||||||
|
/* by Mike Blandford */
|
||||||
|
/* Mar 2012 */
|
||||||
|
/* 4.5 WestfW: add infrastructure for non-zero UARTS. */
|
||||||
|
/* 4.5 WestfW: fix SIGNATURE_2 for m644 (bad in avr-libc) */
|
||||||
|
/* Jan 2012: */
|
||||||
|
/* 4.5 WestfW: fix NRWW value for m1284. */
|
||||||
|
/* 4.4 WestfW: use attribute OS_main instead of naked for */
|
||||||
|
/* main(). This allows optimizations that we */
|
||||||
|
/* count on, which are prohibited in naked */
|
||||||
|
/* functions due to PR42240. (keeps us less */
|
||||||
|
/* than 512 bytes when compiler is gcc4.5 */
|
||||||
|
/* (code from 4.3.2 remains the same.) */
|
||||||
|
/* 4.4 WestfW and Maniacbug: Add m1284 support. This */
|
||||||
|
/* does not change the 328 binary, so the */
|
||||||
|
/* version number didn't change either. (?) */
|
||||||
|
/* June 2011: */
|
||||||
|
/* 4.4 WestfW: remove automatic soft_uart detect (didn't */
|
||||||
|
/* know what it was doing or why.) Added a */
|
||||||
|
/* check of the calculated BRG value instead. */
|
||||||
|
/* Version stays 4.4; existing binaries are */
|
||||||
|
/* not changed. */
|
||||||
|
/* 4.4 WestfW: add initialization of address to keep */
|
||||||
|
/* the compiler happy. Change SC'ed targets. */
|
||||||
|
/* Return the SW version via READ PARAM */
|
||||||
|
/* 4.3 WestfW: catch framing errors in getch(), so that */
|
||||||
|
/* AVRISP works without HW kludges. */
|
||||||
|
/* http://code.google.com/p/arduino/issues/detail?id=368n*/
|
||||||
|
/* 4.2 WestfW: reduce code size, fix timeouts, change */
|
||||||
|
/* verifySpace to use WDT instead of appstart */
|
||||||
|
/* 4.1 WestfW: put version number in binary. */
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
#define OPTIBOOT_MAJVER 4
|
||||||
|
#define OPTIBOOT_MINVER 5
|
||||||
|
|
||||||
|
#define MULTI_CALLED 1
|
||||||
|
|
||||||
|
#define MAKESTR(a) #a
|
||||||
|
#define MAKEVER(a, b) MAKESTR(a*256+b)
|
||||||
|
|
||||||
|
//asm(" .section .version\n"
|
||||||
|
// "optiboot_version: .word " MAKEVER(OPTIBOOT_MAJVER, OPTIBOOT_MINVER) "\n"
|
||||||
|
// " .section .text\n");
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
|
// <avr/boot.h> uses sts instructions, but this version uses out instructions
|
||||||
|
// This saves cycles and program memory.
|
||||||
|
#include "boot.h"
|
||||||
|
|
||||||
|
|
||||||
|
// We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need.
|
||||||
|
|
||||||
|
#include "pin_defs.h"
|
||||||
|
#include "stk500.h"
|
||||||
|
|
||||||
|
#ifndef LED_START_FLASHES
|
||||||
|
#define LED_START_FLASHES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LUDICROUS_SPEED
|
||||||
|
#define BAUD_RATE 230400L
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* set the UART baud rate defaults */
|
||||||
|
#ifndef BAUD_RATE
|
||||||
|
#if F_CPU >= 8000000L
|
||||||
|
#define BAUD_RATE 38400L // Highest rate Avrdude win32 will support
|
||||||
|
#elsif F_CPU >= 1000000L
|
||||||
|
#define BAUD_RATE 9600L // 19200 also supported, but with significant error
|
||||||
|
#elsif F_CPU >= 128000L
|
||||||
|
#define BAUD_RATE 4800L // Good for 128kHz internal RC
|
||||||
|
#else
|
||||||
|
#define BAUD_RATE 1200L // Good even at 32768Hz
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UART
|
||||||
|
#define UART 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Switch in soft UART for hard baud rates */
|
||||||
|
/*
|
||||||
|
* I don't understand what this was supposed to accomplish, where the
|
||||||
|
* constant "280" came from, or why automatically (and perhaps unexpectedly)
|
||||||
|
* switching to a soft uart is a good thing, so I'm undoing this in favor
|
||||||
|
* of a range check using the same calc used to config the BRG...
|
||||||
|
*/
|
||||||
|
#if (F_CPU/BAUD_RATE) > 280 // > 57600 for 16MHz
|
||||||
|
#ifndef SOFT_UART
|
||||||
|
#define SOFT_UART
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else // 0
|
||||||
|
#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 > 250
|
||||||
|
#error Unachievable baud rate (too slow) BAUD_RATE
|
||||||
|
#endif // baud rate slow check
|
||||||
|
#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 < 3
|
||||||
|
#error Unachievable baud rate (too fast) BAUD_RATE
|
||||||
|
#endif // baud rate fastn check
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Watchdog settings */
|
||||||
|
#define WATCHDOG_OFF (0)
|
||||||
|
#define WATCHDOG_16MS (_BV(WDE))
|
||||||
|
#define WATCHDOG_32MS (_BV(WDP0) | _BV(WDE))
|
||||||
|
#define WATCHDOG_64MS (_BV(WDP1) | _BV(WDE))
|
||||||
|
#define WATCHDOG_125MS (_BV(WDP1) | _BV(WDP0) | _BV(WDE))
|
||||||
|
#define WATCHDOG_250MS (_BV(WDP2) | _BV(WDE))
|
||||||
|
#define WATCHDOG_500MS (_BV(WDP2) | _BV(WDP0) | _BV(WDE))
|
||||||
|
#define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
|
||||||
|
#define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
|
||||||
|
#ifndef __AVR_ATmega8__
|
||||||
|
#define WATCHDOG_4S (_BV(WDP3) | _BV(WDE))
|
||||||
|
#define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Function Prototypes */
|
||||||
|
/* The main function is in init9, which removes the interrupt vector table */
|
||||||
|
/* we don't need. It is also 'naked', which means the compiler does not */
|
||||||
|
/* generate any entry or exit code itself. */
|
||||||
|
int main(void) __attribute__ ((OS_main)) __attribute__ ((noreturn)) __attribute__ ((section (".init9")));
|
||||||
|
void putch(char);
|
||||||
|
uint8_t getch(void);
|
||||||
|
static inline void getNch(uint8_t); /* "static inline" is a compiler hint to reduce code size */
|
||||||
|
void verifySpace();
|
||||||
|
#if LED_START_FLASHES > 0
|
||||||
|
static inline void flash_led(uint8_t);
|
||||||
|
#endif
|
||||||
|
uint8_t getLen();
|
||||||
|
//static inline void watchdogReset();
|
||||||
|
void watchdogConfig(uint8_t x);
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
void uartDelay() __attribute__ ((naked));
|
||||||
|
#endif
|
||||||
|
static void appStart() ; // __attribute__ ((naked));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NRWW memory
|
||||||
|
* Addresses below NRWW (Non-Read-While-Write) can be programmed while
|
||||||
|
* continuing to run code from flash, slightly speeding up programming
|
||||||
|
* time. Beware that Atmel data sheets specify this as a WORD address,
|
||||||
|
* while optiboot will be comparing against a 16-bit byte address. This
|
||||||
|
* means that on a part with 128kB of memory, the upper part of the lower
|
||||||
|
* 64k will get NRWW processing as well, even though it doesn't need it.
|
||||||
|
* That's OK. In fact, you can disable the overlapping processing for
|
||||||
|
* a part entirely by setting NRWWSTART to zero. This reduces code
|
||||||
|
* space a bit, at the expense of being slightly slower, overall.
|
||||||
|
*
|
||||||
|
* RAMSTART should be self-explanatory. It's bigger on parts with a
|
||||||
|
* lot of peripheral registers.
|
||||||
|
*/
|
||||||
|
#if defined(__AVR_ATmega168__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0x3800)
|
||||||
|
#elif defined(__AVR_ATmega328P__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0x7000)
|
||||||
|
#elif defined(__AVR_ATmega328__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0x7000)
|
||||||
|
#elif defined (__AVR_ATmega644P__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0xE000)
|
||||||
|
// correct for a bug in avr-libc
|
||||||
|
#undef SIGNATURE_2
|
||||||
|
#define SIGNATURE_2 0x0A
|
||||||
|
#elif defined (__AVR_ATmega1284P__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0xE000)
|
||||||
|
#elif defined(__AVR_ATtiny84__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0x0000)
|
||||||
|
#elif defined(__AVR_ATmega1280__)
|
||||||
|
#define RAMSTART (0x200)
|
||||||
|
#define NRWWSTART (0xE000)
|
||||||
|
#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0x1800)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* C zero initialises all global variables. However, that requires */
|
||||||
|
/* These definitions are NOT zero initialised, but that doesn't matter */
|
||||||
|
/* This allows us to drop the zero init code, saving us memory */
|
||||||
|
#define buff ((uint8_t*)(RAMSTART))
|
||||||
|
#ifdef VIRTUAL_BOOT_PARTITION
|
||||||
|
#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
|
||||||
|
#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle devices with up to 4 uarts (eg m1280.) Rather inelegantly.
|
||||||
|
* Note that mega8 still needs special handling, because ubrr is handled
|
||||||
|
* differently.
|
||||||
|
*/
|
||||||
|
#if UART == 0
|
||||||
|
# define UART_SRA UCSR0A
|
||||||
|
# define UART_SRB UCSR0B
|
||||||
|
# define UART_SRC UCSR0C
|
||||||
|
# define UART_SRL UBRR0L
|
||||||
|
# define UART_UDR UDR0
|
||||||
|
#elif UART == 1
|
||||||
|
# define UART_SRA UCSR1A
|
||||||
|
# define UART_SRB UCSR1B
|
||||||
|
# define UART_SRC UCSR1C
|
||||||
|
# define UART_SRL UBRR1L
|
||||||
|
# define UART_UDR UDR1
|
||||||
|
#elif UART == 2
|
||||||
|
# define UART_SRA UCSR2A
|
||||||
|
# define UART_SRB UCSR2B
|
||||||
|
# define UART_SRC UCSR2C
|
||||||
|
# define UART_SRL UBRR2L
|
||||||
|
# define UART_UDR UDR2
|
||||||
|
#elif UART == 3
|
||||||
|
# define UART_SRA UCSR3A
|
||||||
|
# define UART_SRB UCSR3B
|
||||||
|
# define UART_SRC UCSR3C
|
||||||
|
# define UART_SRL UBRR3L
|
||||||
|
# define UART_UDR UDR3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* main program starts here */
|
||||||
|
int main(void) {
|
||||||
|
uint8_t ch;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Making these local and in registers prevents the need for initializing
|
||||||
|
* them, and also saves space because code no longer stores to memory.
|
||||||
|
* (initializing address keeps the compiler happy, but isn't really
|
||||||
|
* necessary, and uses 4 bytes of flash.)
|
||||||
|
*/
|
||||||
|
register uint16_t address = 0;
|
||||||
|
|
||||||
|
// After the zero init loop, this is the first code to run.
|
||||||
|
//
|
||||||
|
// This code makes the following assumptions:
|
||||||
|
// No interrupts will execute
|
||||||
|
// SP points to RAMEND
|
||||||
|
// r1 contains zero
|
||||||
|
//
|
||||||
|
// If not, uncomment the following instructions:
|
||||||
|
// cli();
|
||||||
|
asm volatile ("clr __zero_reg__");
|
||||||
|
#ifdef __AVR_ATmega8__
|
||||||
|
SP=RAMEND; // This is done by hardware reset
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Adaboot no-wait mod
|
||||||
|
ch = MCUSR;
|
||||||
|
MCUSR = 0;
|
||||||
|
|
||||||
|
// Here, if power on, wait 0.5 secs, then check for
|
||||||
|
// serial Rx signal low, if so, stay in bootloader
|
||||||
|
// else go to application
|
||||||
|
|
||||||
|
PORTD = 0xFF ;
|
||||||
|
PORTB = 0x3C ;
|
||||||
|
PORTC = 1 ;
|
||||||
|
|
||||||
|
if (ch & (_BV(PORF) | (_BV(EXTRF)) ) )
|
||||||
|
{
|
||||||
|
#ifdef MULTI_CALLED
|
||||||
|
#if F_CPU == 12000000L
|
||||||
|
TCNT1H = 256 - 8 ;
|
||||||
|
#else
|
||||||
|
#if F_CPU == 16000000L
|
||||||
|
TCNT1H = 256 - 6 ;
|
||||||
|
#else
|
||||||
|
TCNT1H = 256 - 127 ;
|
||||||
|
#endif
|
||||||
|
TCNT1L = 0 ;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if F_CPU == 12000000L
|
||||||
|
TCNT1 = 65535-5859 ;
|
||||||
|
#else
|
||||||
|
#if F_CPU == 16000000L
|
||||||
|
TCNT1 = 65535-7813 ;
|
||||||
|
#else
|
||||||
|
TCNT1 = 65535-32767 ;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
|
||||||
|
TIFR1 = _BV(TOV1);
|
||||||
|
while(!(TIFR1 & _BV(TOV1)))
|
||||||
|
;
|
||||||
|
TCCR1B = 0 ; // Stop timer
|
||||||
|
uint8_t x ;
|
||||||
|
x = PINB & 0x3C ;
|
||||||
|
x |= PINC & 1 ;
|
||||||
|
if ( x != 0x1D )
|
||||||
|
{
|
||||||
|
appStart() ; // Power on, go to voice application
|
||||||
|
// if loaded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LED_START_FLASHES > 0
|
||||||
|
// Set up Timer 1 for timeout counter
|
||||||
|
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SOFT_UART
|
||||||
|
UART_SRA = _BV(U2X0); //Double speed mode USART0
|
||||||
|
UART_SRB = _BV(RXEN0) | _BV(TXEN0);
|
||||||
|
UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
|
||||||
|
// UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
|
||||||
|
// Baudrate of 57600
|
||||||
|
#if F_CPU == 12000000L
|
||||||
|
UART_SRL = 25 ;
|
||||||
|
#else
|
||||||
|
#if F_CPU == 16000000L
|
||||||
|
UART_SRL = 33 ;
|
||||||
|
#else
|
||||||
|
#ERROR Baud rate not available
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set up watchdog to trigger after 500ms
|
||||||
|
|
||||||
|
|
||||||
|
// watchdogConfig(WATCHDOG_1S);
|
||||||
|
|
||||||
|
/* Set LED pin as output */
|
||||||
|
LED_DDR |= _BV(LED);
|
||||||
|
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
/* Set TX pin as output */
|
||||||
|
UART_DDR |= _BV(UART_TX_BIT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LED_START_FLASHES > 0
|
||||||
|
/* Flash onboard LED to signal entering of bootloader */
|
||||||
|
flash_led(LED_START_FLASHES * 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Forever loop */
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
/* get character from UART */
|
||||||
|
ch = getch();
|
||||||
|
|
||||||
|
if(ch == STK_GET_PARAMETER)
|
||||||
|
{
|
||||||
|
GPIOR0 = getch();
|
||||||
|
verifySpace();
|
||||||
|
if (GPIOR0 == 0x82)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Send optiboot version as "minor SW version"
|
||||||
|
*/
|
||||||
|
putch(OPTIBOOT_MINVER);
|
||||||
|
}
|
||||||
|
else if (GPIOR0 == 0x81)
|
||||||
|
{
|
||||||
|
putch(OPTIBOOT_MAJVER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* GET PARAMETER returns a generic 0x03 reply for
|
||||||
|
* other parameters - enough to keep Avrdude happy
|
||||||
|
*/
|
||||||
|
putch(0x03);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(ch == STK_SET_DEVICE) {
|
||||||
|
// SET DEVICE is ignored
|
||||||
|
getNch(20);
|
||||||
|
}
|
||||||
|
else if(ch == STK_SET_DEVICE_EXT)
|
||||||
|
{
|
||||||
|
// SET DEVICE EXT is ignored
|
||||||
|
getNch(5);
|
||||||
|
}
|
||||||
|
else if(ch == STK_LOAD_ADDRESS)
|
||||||
|
{
|
||||||
|
// LOAD ADDRESS
|
||||||
|
uint16_t newAddress;
|
||||||
|
newAddress = getch() ;
|
||||||
|
newAddress = (newAddress & 0xff) | (getch() << 8);
|
||||||
|
#ifdef RAMPZ
|
||||||
|
// Transfer top bit to RAMPZ
|
||||||
|
RAMPZ = (newAddress & 0x8000) ? 1 : 0;
|
||||||
|
#endif
|
||||||
|
newAddress += newAddress; // Convert from word address to byte address
|
||||||
|
address = newAddress;
|
||||||
|
verifySpace();
|
||||||
|
}
|
||||||
|
else if(ch == STK_UNIVERSAL)
|
||||||
|
{
|
||||||
|
// UNIVERSAL command is ignored
|
||||||
|
getNch(4);
|
||||||
|
putch(0x00);
|
||||||
|
}
|
||||||
|
/* Write memory, length is big endian and is in bytes */
|
||||||
|
else if(ch == STK_PROG_PAGE)
|
||||||
|
{
|
||||||
|
// PROGRAM PAGE - we support flash programming only, not EEPROM
|
||||||
|
uint8_t *bufPtr;
|
||||||
|
uint16_t addrPtr;
|
||||||
|
register uint8_t length;
|
||||||
|
|
||||||
|
getch(); /* getlen() */
|
||||||
|
length = getch();
|
||||||
|
getch();
|
||||||
|
|
||||||
|
// If we are in RWW section, immediately start page erase
|
||||||
|
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
|
||||||
|
|
||||||
|
// While that is going on, read in page contents
|
||||||
|
bufPtr = buff;
|
||||||
|
do *bufPtr++ = getch();
|
||||||
|
while (--length);
|
||||||
|
|
||||||
|
// If we are in NRWW section, page erase has to be delayed until now.
|
||||||
|
// Todo: Take RAMPZ into account
|
||||||
|
#ifdef MULTI_CALLED
|
||||||
|
if (address < 0x7E00)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
|
||||||
|
}
|
||||||
|
// Read command terminator, start reply
|
||||||
|
verifySpace();
|
||||||
|
|
||||||
|
// If only a partial page is to be programmed, the erase might not be complete.
|
||||||
|
// So check that here
|
||||||
|
#ifdef MULTI_CALLED
|
||||||
|
if (address < 0x7E00)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
boot_spm_busy_wait();
|
||||||
|
|
||||||
|
#ifdef VIRTUAL_BOOT_PARTITION
|
||||||
|
if ((uint16_t)(void*)address == 0) {
|
||||||
|
// This is the reset vector page. We need to live-patch the code so the
|
||||||
|
// bootloader runs.
|
||||||
|
//
|
||||||
|
// Move RESET vector to WDT vector
|
||||||
|
uint16_t vect = buff[0] | (buff[1]<<8);
|
||||||
|
rstVect = vect;
|
||||||
|
wdtVect = buff[8] | (buff[9]<<8);
|
||||||
|
vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
|
||||||
|
buff[8] = vect & 0xff;
|
||||||
|
buff[9] = vect >> 8;
|
||||||
|
|
||||||
|
// Add jump to bootloader at RESET vector
|
||||||
|
buff[0] = 0x7f;
|
||||||
|
buff[1] = 0xce; // rjmp 0x1d00 instruction
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Copy buffer into programming buffer
|
||||||
|
bufPtr = buff;
|
||||||
|
addrPtr = (uint16_t)(void*)address;
|
||||||
|
ch = SPM_PAGESIZE / 2;
|
||||||
|
do {
|
||||||
|
uint16_t a;
|
||||||
|
// a = *bufPtr++;
|
||||||
|
// a |= (*bufPtr++) << 8;
|
||||||
|
|
||||||
|
a = *((uint16_t *)bufPtr) ;
|
||||||
|
bufPtr += 2 ;
|
||||||
|
|
||||||
|
__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
|
||||||
|
addrPtr += 2;
|
||||||
|
} while (--ch);
|
||||||
|
|
||||||
|
// Write from programming buffer
|
||||||
|
__boot_page_write_short((uint16_t)(void*)address);
|
||||||
|
boot_spm_busy_wait();
|
||||||
|
|
||||||
|
#if defined(RWWSRE)
|
||||||
|
// Reenable read access to flash
|
||||||
|
boot_rww_enable();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Read memory block mode, length is big endian. */
|
||||||
|
else if(ch == STK_READ_PAGE)
|
||||||
|
{
|
||||||
|
register uint8_t length;
|
||||||
|
// READ PAGE - we only read flash
|
||||||
|
getch(); /* getlen() */
|
||||||
|
length = getch();
|
||||||
|
getch();
|
||||||
|
|
||||||
|
verifySpace();
|
||||||
|
#ifdef VIRTUAL_BOOT_PARTITION
|
||||||
|
do {
|
||||||
|
// Undo vector patch in bottom page so verify passes
|
||||||
|
if (address == 0) ch=rstVect & 0xff;
|
||||||
|
else if (address == 1) ch=rstVect >> 8;
|
||||||
|
else if (address == 8) ch=wdtVect & 0xff;
|
||||||
|
else if (address == 9) ch=wdtVect >> 8;
|
||||||
|
else ch = pgm_read_byte_near(address);
|
||||||
|
address++;
|
||||||
|
putch(ch);
|
||||||
|
} while (--length);
|
||||||
|
#else
|
||||||
|
#ifdef RAMPZ
|
||||||
|
// Since RAMPZ should already be set, we need to use EPLM directly.
|
||||||
|
// do putch(pgm_read_byte_near(address++));
|
||||||
|
// while (--length);
|
||||||
|
do {
|
||||||
|
uint8_t result;
|
||||||
|
__asm__ ("elpm %0,Z\n":"=r"(result):"z"(address));
|
||||||
|
putch(result);
|
||||||
|
address++;
|
||||||
|
}
|
||||||
|
while (--length);
|
||||||
|
#else
|
||||||
|
do putch(pgm_read_byte_near(address++));
|
||||||
|
while (--length);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get device signature bytes */
|
||||||
|
else if(ch == STK_READ_SIGN)
|
||||||
|
{
|
||||||
|
// READ SIGN - return what Avrdude wants to hear
|
||||||
|
verifySpace();
|
||||||
|
putch(SIGNATURE_0);
|
||||||
|
putch(SIGNATURE_1);
|
||||||
|
putch(SIGNATURE_2);
|
||||||
|
}
|
||||||
|
else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
|
||||||
|
// Adaboot no-wait mod
|
||||||
|
|
||||||
|
// watchdogConfig(WATCHDOG_16MS);
|
||||||
|
|
||||||
|
verifySpace();
|
||||||
|
#ifdef MULTI_CALLED
|
||||||
|
putch(STK_OK);
|
||||||
|
while (!(UART_SRA & _BV(TXC0)));
|
||||||
|
appStart() ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This covers the response to commands like STK_ENTER_PROGMODE
|
||||||
|
verifySpace();
|
||||||
|
}
|
||||||
|
putch(STK_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void putch(char ch) {
|
||||||
|
#ifndef SOFT_UART
|
||||||
|
while (!(UART_SRA & _BV(UDRE0)));
|
||||||
|
UART_UDR = ch;
|
||||||
|
#else
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
" com %[ch]\n" // ones complement, carry set
|
||||||
|
" sec\n"
|
||||||
|
"1: brcc 2f\n"
|
||||||
|
" cbi %[uartPort],%[uartBit]\n"
|
||||||
|
" rjmp 3f\n"
|
||||||
|
"2: sbi %[uartPort],%[uartBit]\n"
|
||||||
|
" nop\n"
|
||||||
|
"3: rcall uartDelay\n"
|
||||||
|
" rcall uartDelay\n"
|
||||||
|
" lsr %[ch]\n"
|
||||||
|
" dec %[bitcnt]\n"
|
||||||
|
" brne 1b\n"
|
||||||
|
:
|
||||||
|
:
|
||||||
|
[bitcnt] "d" (10),
|
||||||
|
[ch] "r" (ch),
|
||||||
|
[uartPort] "I" (_SFR_IO_ADDR(UART_PORT)),
|
||||||
|
[uartBit] "I" (UART_TX_BIT)
|
||||||
|
:
|
||||||
|
"r25"
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getch(void) {
|
||||||
|
uint8_t ch;
|
||||||
|
|
||||||
|
#ifdef LED_DATA_FLASH
|
||||||
|
#ifdef __AVR_ATmega8__
|
||||||
|
LED_PORT ^= _BV(LED);
|
||||||
|
#else
|
||||||
|
LED_PIN |= _BV(LED);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"1: sbic %[uartPin],%[uartBit]\n" // Wait for start edge
|
||||||
|
" rjmp 1b\n"
|
||||||
|
" rcall uartDelay\n" // Get to middle of start bit
|
||||||
|
"2: rcall uartDelay\n" // Wait 1 bit period
|
||||||
|
" rcall uartDelay\n" // Wait 1 bit period
|
||||||
|
" clc\n"
|
||||||
|
" sbic %[uartPin],%[uartBit]\n"
|
||||||
|
" sec\n"
|
||||||
|
" dec %[bitCnt]\n"
|
||||||
|
" breq 3f\n"
|
||||||
|
" ror %[ch]\n"
|
||||||
|
" rjmp 2b\n"
|
||||||
|
"3:\n"
|
||||||
|
:
|
||||||
|
[ch] "=r" (ch)
|
||||||
|
:
|
||||||
|
[bitCnt] "d" (9),
|
||||||
|
[uartPin] "I" (_SFR_IO_ADDR(UART_PIN)),
|
||||||
|
[uartBit] "I" (UART_RX_BIT)
|
||||||
|
:
|
||||||
|
"r25"
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
while(!(UART_SRA & _BV(RXC0)))
|
||||||
|
|
||||||
|
// watchdogReset()
|
||||||
|
|
||||||
|
;
|
||||||
|
// if (!(UART_SRA & _BV(FE0))) {
|
||||||
|
/*
|
||||||
|
* A Framing Error indicates (probably) that something is talking
|
||||||
|
* to us at the wrong bit rate. Assume that this is because it
|
||||||
|
* expects to be talking to the application, and DON'T reset the
|
||||||
|
* watchdog. This should cause the bootloader to abort and run
|
||||||
|
* the application "soon", if it keeps happening. (Note that we
|
||||||
|
* don't care that an invalid char is returned...)
|
||||||
|
*/
|
||||||
|
// watchdogReset();
|
||||||
|
// }
|
||||||
|
|
||||||
|
ch = UART_UDR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LED_DATA_FLASH
|
||||||
|
#ifdef __AVR_ATmega8__
|
||||||
|
LED_PORT ^= _BV(LED);
|
||||||
|
#else
|
||||||
|
LED_PIN |= _BV(LED);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
// AVR305 equation: #define UART_B_VALUE (((F_CPU/BAUD_RATE)-23)/6)
|
||||||
|
// Adding 3 to numerator simulates nearest rounding for more accurate baud rates
|
||||||
|
#define UART_B_VALUE (((F_CPU/BAUD_RATE)-20)/6)
|
||||||
|
#if UART_B_VALUE > 255
|
||||||
|
#error Baud rate too slow for soft UART
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void uartDelay() {
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"ldi r25,%[count]\n"
|
||||||
|
"1:dec r25\n"
|
||||||
|
"brne 1b\n"
|
||||||
|
"ret\n"
|
||||||
|
::[count] "M" (UART_B_VALUE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void getNch(uint8_t count) {
|
||||||
|
do getch(); while (--count);
|
||||||
|
verifySpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
void verifySpace()
|
||||||
|
{
|
||||||
|
if ( getch() != CRC_EOP) {
|
||||||
|
|
||||||
|
putch(STK_NOSYNC);
|
||||||
|
// watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
|
||||||
|
//
|
||||||
|
// while (1) // and busy-loop so that WD causes
|
||||||
|
// ; // a reset and app start.
|
||||||
|
}
|
||||||
|
putch(STK_INSYNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LED_START_FLASHES > 0
|
||||||
|
void flash_led(uint8_t count) {
|
||||||
|
do {
|
||||||
|
TCNT1 = -(F_CPU/(1024*16));
|
||||||
|
TIFR1 = _BV(TOV1);
|
||||||
|
while(!(TIFR1 & _BV(TOV1)));
|
||||||
|
//#ifdef __AVR_ATmega8__
|
||||||
|
LED_PORT ^= _BV(LED);
|
||||||
|
//#else
|
||||||
|
// LED_PIN |= _BV(LED);
|
||||||
|
//#endif
|
||||||
|
watchdogReset();
|
||||||
|
} while (--count);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Watchdog functions. These are only safe with interrupts turned off.
|
||||||
|
void watchdogReset() {
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"wdr\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void watchdogConfig(uint8_t x) {
|
||||||
|
WDTCSR = _BV(WDCE) | _BV(WDE);
|
||||||
|
WDTCSR = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void appStart()
|
||||||
|
{
|
||||||
|
// watchdogConfig(WATCHDOG_OFF);
|
||||||
|
// __asm__ __volatile__ (
|
||||||
|
//#ifdef VIRTUAL_BOOT_PARTITION
|
||||||
|
// // Jump to WDT vector
|
||||||
|
// "ldi r30,4\n"
|
||||||
|
// "clr r31\n"
|
||||||
|
//#else
|
||||||
|
// // Jump to RST vector
|
||||||
|
// "clr r30\n"
|
||||||
|
// "clr r31\n"
|
||||||
|
//#endif
|
||||||
|
// "ijmp\n"
|
||||||
|
// );
|
||||||
|
|
||||||
|
register void (*p)() ;
|
||||||
|
p = 0 ;
|
||||||
|
|
||||||
|
if ( pgm_read_byte( (uint16_t)p ) != 0xFF )
|
||||||
|
{
|
||||||
|
(*p)() ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
80
BootLoaders/AtmegaMultiBoot/Source/pin_defs.h
Normal file
80
BootLoaders/AtmegaMultiBoot/Source/pin_defs.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
|
||||||
|
/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove */
|
||||||
|
#define LED_DDR DDRB
|
||||||
|
#define LED_PORT PORTB
|
||||||
|
#define LED_PIN PINB
|
||||||
|
#define LED PINB5
|
||||||
|
|
||||||
|
/* Ports for soft UART */
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
#define UART_PORT PORTD
|
||||||
|
#define UART_PIN PIND
|
||||||
|
#define UART_DDR DDRD
|
||||||
|
#define UART_TX_BIT 1
|
||||||
|
#define UART_RX_BIT 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__AVR_ATmega8__)
|
||||||
|
//Name conversion R.Wiersma
|
||||||
|
#define UCSR0A UCSRA
|
||||||
|
#define UDR0 UDR
|
||||||
|
#define UDRE0 UDRE
|
||||||
|
#define RXC0 RXC
|
||||||
|
#define FE0 FE
|
||||||
|
#define TIFR1 TIFR
|
||||||
|
#define WDTCSR WDTCR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Luminet support */
|
||||||
|
#if defined(__AVR_ATtiny84__)
|
||||||
|
/* Red LED is connected to pin PA4 */
|
||||||
|
#define LED_DDR DDRA
|
||||||
|
#define LED_PORT PORTA
|
||||||
|
#define LED_PIN PINA
|
||||||
|
#define LED PINA4
|
||||||
|
/* Ports for soft UART - left port only for now. TX/RX on PA2/PA3 */
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
#define UART_PORT PORTA
|
||||||
|
#define UART_PIN PINA
|
||||||
|
#define UART_DDR DDRA
|
||||||
|
#define UART_TX_BIT 2
|
||||||
|
#define UART_RX_BIT 3
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Sanguino support */
|
||||||
|
#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
|
||||||
|
/* Onboard LED is connected to pin PB0 on Sanguino */
|
||||||
|
#define LED_DDR DDRB
|
||||||
|
#define LED_PORT PORTB
|
||||||
|
#define LED_PIN PINB
|
||||||
|
#define LED PINB0
|
||||||
|
|
||||||
|
/* Ports for soft UART */
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
#define UART_PORT PORTD
|
||||||
|
#define UART_PIN PIND
|
||||||
|
#define UART_DDR DDRD
|
||||||
|
#define UART_TX_BIT 1
|
||||||
|
#define UART_RX_BIT 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Mega support */
|
||||||
|
#if defined(__AVR_ATmega1280__)
|
||||||
|
/* Onboard LED is connected to pin PB7 on Arduino Mega */
|
||||||
|
#define LED_DDR DDRB
|
||||||
|
#define LED_PORT PORTB
|
||||||
|
#define LED_PIN PINB
|
||||||
|
#define LED PINB7
|
||||||
|
|
||||||
|
/* Ports for soft UART */
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
#define UART_PORT PORTE
|
||||||
|
#define UART_PIN PINE
|
||||||
|
#define UART_DDR DDRE
|
||||||
|
#define UART_TX_BIT 1
|
||||||
|
#define UART_RX_BIT 0
|
||||||
|
#endif
|
||||||
|
#endif
|
39
BootLoaders/AtmegaMultiBoot/Source/stk500.h
Normal file
39
BootLoaders/AtmegaMultiBoot/Source/stk500.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* STK500 constants list, from AVRDUDE */
|
||||||
|
#define STK_OK 0x10
|
||||||
|
#define STK_FAILED 0x11 // Not used
|
||||||
|
#define STK_UNKNOWN 0x12 // Not used
|
||||||
|
#define STK_NODEVICE 0x13 // Not used
|
||||||
|
#define STK_INSYNC 0x14 // ' '
|
||||||
|
#define STK_NOSYNC 0x15 // Not used
|
||||||
|
#define ADC_CHANNEL_ERROR 0x16 // Not used
|
||||||
|
#define ADC_MEASURE_OK 0x17 // Not used
|
||||||
|
#define PWM_CHANNEL_ERROR 0x18 // Not used
|
||||||
|
#define PWM_ADJUST_OK 0x19 // Not used
|
||||||
|
#define CRC_EOP 0x20 // 'SPACE'
|
||||||
|
#define STK_GET_SYNC 0x30 // '0'
|
||||||
|
#define STK_GET_SIGN_ON 0x31 // '1'
|
||||||
|
#define STK_SET_PARAMETER 0x40 // '@'
|
||||||
|
#define STK_GET_PARAMETER 0x41 // 'A'
|
||||||
|
#define STK_SET_DEVICE 0x42 // 'B'
|
||||||
|
#define STK_SET_DEVICE_EXT 0x45 // 'E'
|
||||||
|
#define STK_ENTER_PROGMODE 0x50 // 'P'
|
||||||
|
#define STK_LEAVE_PROGMODE 0x51 // 'Q'
|
||||||
|
#define STK_CHIP_ERASE 0x52 // 'R'
|
||||||
|
#define STK_CHECK_AUTOINC 0x53 // 'S'
|
||||||
|
#define STK_LOAD_ADDRESS 0x55 // 'U'
|
||||||
|
#define STK_UNIVERSAL 0x56 // 'V'
|
||||||
|
#define STK_PROG_FLASH 0x60 // '`'
|
||||||
|
#define STK_PROG_DATA 0x61 // 'a'
|
||||||
|
#define STK_PROG_FUSE 0x62 // 'b'
|
||||||
|
#define STK_PROG_LOCK 0x63 // 'c'
|
||||||
|
#define STK_PROG_PAGE 0x64 // 'd'
|
||||||
|
#define STK_PROG_FUSE_EXT 0x65 // 'e'
|
||||||
|
#define STK_READ_FLASH 0x70 // 'p'
|
||||||
|
#define STK_READ_DATA 0x71 // 'q'
|
||||||
|
#define STK_READ_FUSE 0x72 // 'r'
|
||||||
|
#define STK_READ_LOCK 0x73 // 's'
|
||||||
|
#define STK_READ_PAGE 0x74 // 't'
|
||||||
|
#define STK_READ_SIGN 0x75 // 'u'
|
||||||
|
#define STK_READ_OSCCAL 0x76 // 'v'
|
||||||
|
#define STK_READ_FUSE_EXT 0x77 // 'w'
|
||||||
|
#define STK_READ_OSCCAL_EXT 0x78 // 'x'
|
45
BootLoaders/Boards/boards.txt
Normal file
45
BootLoaders/Boards/boards.txt
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# See: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
||||||
|
# See: http://code.google.com/p/arduino/wiki/Platforms
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
menu.bootloader=Bootloader
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
## Multi 4-in-1 (3.3V, 16 MHz) w/ ATmega328p
|
||||||
|
## --------------------------------------------------
|
||||||
|
multiatmega328p.name=Multi 4-in-1 (Atmega328p, 3.3V, 16MHz)
|
||||||
|
|
||||||
|
multiatmega328p.upload.tool=arduino:avrdude
|
||||||
|
multiatmega328p.upload.protocol=arduino
|
||||||
|
multiatmega328p.upload.speed=57600
|
||||||
|
multiatmega328p.upload.maximum_data_size=2048
|
||||||
|
|
||||||
|
multiatmega328p.build.mcu=atmega328p
|
||||||
|
multiatmega328p.build.f_cpu=16000000L
|
||||||
|
multiatmega328p.build.core=arduino:arduino
|
||||||
|
multiatmega328p.build.variant=arduino:eightanaloginputs
|
||||||
|
multiatmega328p.build.extra_flags=-Wl,--relax
|
||||||
|
multiatmega328p.build.board=MULTI_AVR
|
||||||
|
|
||||||
|
multiatmega328p.bootloader.tool=arduino:avrdude
|
||||||
|
multiatmega328p.bootloader.low_fuses=0xFF
|
||||||
|
multiatmega328p.bootloader.extended_fuses=0xFD
|
||||||
|
multiatmega328p.bootloader.unlock_bits=0x3F
|
||||||
|
multiatmega328p.bootloader.lock_bits=0x0F
|
||||||
|
|
||||||
|
multiatmega328p.menu.bootloader.none=No bootloader
|
||||||
|
multiatmega328p.menu.bootloader.none.build.board=MULTI_NO_BOOT
|
||||||
|
|
||||||
|
multiatmega328p.menu.bootloader.none.upload.maximum_size=32768
|
||||||
|
multiatmega328p.menu.bootloader.none.bootloader.file=Multi4in1/AtmegaMultiEmpty.hex
|
||||||
|
multiatmega328p.menu.bootloader.none.bootloader.high_fuses=0xD7
|
||||||
|
|
||||||
|
multiatmega328p.menu.bootloader.optiboot=Flash from TX
|
||||||
|
multiatmega328p.menu.bootloader.optiboot.build.board=MULTI_FLASH_FROM_TX
|
||||||
|
|
||||||
|
multiatmega328p.menu.bootloader.optiboot.upload.maximum_size=32256
|
||||||
|
multiatmega328p.menu.bootloader.optiboot.bootloader.file=Multi4in1/AtmegaMultiBoot.hex
|
||||||
|
multiatmega328p.menu.bootloader.optiboot.bootloader.high_fuses=0xD6
|
||||||
|
|
||||||
|
##############################################################
|
34
BootLoaders/Boards/bootloaders/Multi4in1/AtmegaMultiBoot.hex
Normal file
34
BootLoaders/Boards/bootloaders/Multi4in1/AtmegaMultiBoot.hex
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
:107E0000112484B714BE9FEF9BB99CE395B991E010
|
||||||
|
:107E100098B98370A9F08AEF80938500109284004E
|
||||||
|
:107E200085E08093810096BBB09BFECF10928100CD
|
||||||
|
:107E300093B186B181709C73892B8D3109F0B3D0D9
|
||||||
|
:107E400082E08093C00088E18093C10086E0809347
|
||||||
|
:107E5000C20081E28093C400259AC0E0D0E093E0A4
|
||||||
|
:107E6000F92EEE24E39425E0D22E31E1C32EA9D0E1
|
||||||
|
:107E7000813481F4A6D08EBBABD08EB3823811F49E
|
||||||
|
:107E800085E006C08EB3813811F484E001C083E040
|
||||||
|
:107E900091D086C0823411F484E103C0853419F492
|
||||||
|
:107EA00085E09DD07DC0853541F48BD0C82F89D029
|
||||||
|
:107EB000D0E0D82BCC0FDD1F72C0863521F484E0D2
|
||||||
|
:107EC0008ED080E0E5CF843609F03DC07AD079D0FD
|
||||||
|
:107ED000B82E77D0C11520E7D20718F000E011E0E6
|
||||||
|
:107EE00004C0FE01F7BEE895F9CF6BD0F80181938D
|
||||||
|
:107EF0008F01BE12FACFCE01905781159E4018F423
|
||||||
|
:107F0000FE01F7BEE89564D0C115FEE7DF0708F073
|
||||||
|
:107F100047C007B600FCFDCFFE01A0E0B1E08D91A7
|
||||||
|
:107F20009D910C01E7BEE89511243296A03821E01E
|
||||||
|
:107F3000B207A9F7FE01D7BEE89507B600FCFDCF52
|
||||||
|
:107F4000C7BEE8952DC08437B1F43BD03AD0B82EE7
|
||||||
|
:107F500038D03ED0FE01AC2EAB0C8F010F5F1F4F0F
|
||||||
|
:107F6000849128D0A01205C02196BA94CB0DD11DC2
|
||||||
|
:107F700017C0F801F2CF853739F42AD08EE11AD034
|
||||||
|
:107F800085E918D08FE084CF813549F421D080E194
|
||||||
|
:107F900011D08091C00086FFFCCF05D001C018D061
|
||||||
|
:107FA00080E108D064CFE0E0F0E084918F3F09F0F9
|
||||||
|
:107FB000099408959091C00095FFFCCF8093C6006E
|
||||||
|
:107FC00008958091C00087FFFCCF8091C60008957E
|
||||||
|
:107FD000F8DF803211F085E1EDDF84E1EBCFCF9364
|
||||||
|
:107FE000C82FEFDFC150E9F7CF91F2CFA8950895E0
|
||||||
|
:0C7FF000E0E6F0E098E1908380830895C3
|
||||||
|
:0400000300007E007B
|
||||||
|
:00000001FF
|
@ -0,0 +1,2 @@
|
|||||||
|
:02000000FFFF00
|
||||||
|
:00000001FF
|
1
BootLoaders/Boards/platform.local.txt
Normal file
1
BootLoaders/Boards/platform.local.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Empty
|
9
BootLoaders/Boards/platform.txt
Normal file
9
BootLoaders/Boards/platform.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
# Arduino AVR Core and platform.
|
||||||
|
# ------------------------------
|
||||||
|
|
||||||
|
# For more info:
|
||||||
|
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
||||||
|
|
||||||
|
name=Multi 4-in-1 Boards
|
||||||
|
version=1.0.0
|
47
BootLoaders/OrangeMultiBoot/OrangeMultiBoot.hex
Normal file
47
BootLoaders/OrangeMultiBoot/OrangeMultiBoot.hex
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
:108000001F92CDB7DEB7CFD01124809178009FEFBB
|
||||||
|
:1080100090937800837099F088EA91E680936808DD
|
||||||
|
:108020009093690880E180934C0880914C0884FF0C
|
||||||
|
:10803000FCCF109240088091680682FD8FD082E0CC
|
||||||
|
:1080400080936106C12CD12C97D0813479F494D0DF
|
||||||
|
:10805000898399D08981823811F485E005C08138FF
|
||||||
|
:1080600011F484E001C083E080D075C0823411F443
|
||||||
|
:1080700084E103C0853419F485E08CD06CC085356B
|
||||||
|
:1080800059F47AD0C82E78D0D12CD82A8D2D881FBB
|
||||||
|
:108090008827881F8BBF5EC0863521F484E07AD0A4
|
||||||
|
:1080A00080E0E2CF843641F567D066D0F82E64D008
|
||||||
|
:1080B000C601DCD000E010E25FD0F80181938F01AF
|
||||||
|
:1080C000FE12FACF60D0D7FC46C0CBD0C601DAD0C2
|
||||||
|
:1080D000760100E010E2F801619171918F01C70112
|
||||||
|
:1080E000DBD0F2E0EF0EF11C011581E2180799F7E1
|
||||||
|
:1080F000C601E0D0B6D02FC08437C1F43DD03CD00B
|
||||||
|
:10810000F82E3AD040D0F601EC2CEF0C8F010F5F27
|
||||||
|
:108110001F4F84912AD0E01207C0EFEFCE1ADE0A7B
|
||||||
|
:10812000FA94CF0CD11C17C0F801F0CF853739F481
|
||||||
|
:108130002AD08EE11AD085E918D082E495CF813516
|
||||||
|
:1081400049F421D080E111D08091A10886FFFCCFB5
|
||||||
|
:1081500005D001C018D080E108D076CFE0E0F0E093
|
||||||
|
:1081600084918F3F09F0099408959091A10895FF9B
|
||||||
|
:10817000FCCF8093A00808958091A10887FFFCCFD1
|
||||||
|
:108180008091A0080895F8DF803211F085E1EDDFDD
|
||||||
|
:1081900084E1EBCFCF93C82FEFDFC150E9F7CF9148
|
||||||
|
:1081A000F2CFA895089583EC8093520080915000FF
|
||||||
|
:1081B0008860809350008091510083FFFCCF82EC57
|
||||||
|
:1081C0008093550080915000806180935000809191
|
||||||
|
:1081D000510084FFFCCF88ED84BF1092400084BF23
|
||||||
|
:1081E00024E02093400087E08093A20087E88093FA
|
||||||
|
:1081F0008301109241081092420810924308109295
|
||||||
|
:10820000440810924608109247088FEF9FEF809322
|
||||||
|
:1082100066089093670810926008109261088BE0DE
|
||||||
|
:1082200080934008209365062093620688E180933E
|
||||||
|
:10823000720698E0909345069093410692E29093DF
|
||||||
|
:10824000A6081092A7088093A4088091A3088F7CA9
|
||||||
|
:1082500080618093A30883E08093A5088091A008A3
|
||||||
|
:1082600008958091CF0187FDFCCF08958F939F9350
|
||||||
|
:1082700082E2E0ECF1E08287FF91EF918DE984BF2B
|
||||||
|
:10828000E8950895FC0186E28093CA0188ED84BFD9
|
||||||
|
:1082900081E08093CB0108950F921F92FC01062E7E
|
||||||
|
:1082A000172E83E28093CA018DE984BFE8951F9061
|
||||||
|
:1082B0000F900895FC018EE28093CA018DE984BF7E
|
||||||
|
:0482C000E8950895A0
|
||||||
|
:040000030000800079
|
||||||
|
:00000001FF
|
503
BootLoaders/OrangeMultiBoot/Source/Makefile
Normal file
503
BootLoaders/OrangeMultiBoot/Source/Makefile
Normal file
@ -0,0 +1,503 @@
|
|||||||
|
# Makefile for ATmegaBOOT
|
||||||
|
# E.Lins, 18.7.2005
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
# Instructions
|
||||||
|
#
|
||||||
|
# To make bootloader .hex file:
|
||||||
|
# make diecimila
|
||||||
|
# make lilypad
|
||||||
|
# make ng
|
||||||
|
# etc...
|
||||||
|
#
|
||||||
|
# To burn bootloader .hex file:
|
||||||
|
# make diecimila_isp
|
||||||
|
# make lilypad_isp
|
||||||
|
# make ng_isp
|
||||||
|
# etc...
|
||||||
|
|
||||||
|
# program name should not be changed...
|
||||||
|
PROGRAM = optiboot
|
||||||
|
|
||||||
|
# The default behavior is to build using tools that are in the users
|
||||||
|
# current path variables, but we can also build using an installed
|
||||||
|
# Arduino user IDE setup, or the Arduino source tree.
|
||||||
|
# Uncomment this next lines to build within the arduino environment,
|
||||||
|
# using the arduino-included avrgcc toolset (mac and pc)
|
||||||
|
# ENV ?= arduino
|
||||||
|
# ENV ?= arduinodev
|
||||||
|
# OS ?= macosx
|
||||||
|
# OS ?= windows
|
||||||
|
|
||||||
|
|
||||||
|
# enter the parameters for the avrdude isp tool -b19200
|
||||||
|
#
|
||||||
|
# These are the parameters for a usb-based STK500v2 programmer.
|
||||||
|
# Exact type unknown. (historical Makefile values.)
|
||||||
|
ISPTOOL = stk500v2
|
||||||
|
ISPPORT = usb
|
||||||
|
ISPSPEED = -b 57600
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# These are parameters for using an Arduino with the ArduinoISP sketch
|
||||||
|
# as the programmer. On a mac, for a particular Uno as programmer.
|
||||||
|
#ISPTOOL = stk500v1 -C /Applications/arduino/arduino-0022/hardware/tools/avr/etc/avrdude.conf
|
||||||
|
#ISPPORT = /dev/tty.usbmodemfd3141
|
||||||
|
#ISPSPEED = -b19200
|
||||||
|
|
||||||
|
MCU_TARGET = atmega168
|
||||||
|
LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
|
||||||
|
|
||||||
|
# Build environments
|
||||||
|
# Start of some ugly makefile-isms to allow optiboot to be built
|
||||||
|
# in several different environments. See the README.TXT file for
|
||||||
|
# details.
|
||||||
|
|
||||||
|
# default
|
||||||
|
fixpath = $(1)
|
||||||
|
|
||||||
|
ifeq ($(ENV), arduino)
|
||||||
|
# For Arduino, we assume that we're connected to the optiboot directory
|
||||||
|
# included with the arduino distribution, which means that the full set
|
||||||
|
# of avr-tools are "right up there" in standard places.
|
||||||
|
TOOLROOT = ../../../tools
|
||||||
|
GCCROOT = $(TOOLROOT)/avr/bin/
|
||||||
|
AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
|
||||||
|
|
||||||
|
ifeq ($(OS), windows)
|
||||||
|
# On windows, SOME of the tool paths will need to have backslashes instead
|
||||||
|
# of forward slashes (because they use windows cmd.exe for execution instead
|
||||||
|
# of a unix/mingw shell?) We also have to ensure that a consistent shell
|
||||||
|
# is used even if a unix shell is installed (ie as part of WINAVR)
|
||||||
|
fixpath = $(subst /,\,$1)
|
||||||
|
SHELL = cmd.exe
|
||||||
|
endif
|
||||||
|
|
||||||
|
else ifeq ($(ENV), arduinodev)
|
||||||
|
# Arduino IDE source code environment. Use the unpacked compilers created
|
||||||
|
# by the build (you'll need to do "ant build" first.)
|
||||||
|
ifeq ($(OS), macosx)
|
||||||
|
TOOLROOT = ../../../../build/macosx/work/Arduino.app/Contents/Resources/Java/hardware/tools
|
||||||
|
endif
|
||||||
|
ifeq ($(OS), windows)
|
||||||
|
TOOLROOT = ../../../../build/windows/work/hardware/tools
|
||||||
|
endif
|
||||||
|
|
||||||
|
GCCROOT = $(TOOLROOT)/avr/bin/
|
||||||
|
AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
|
||||||
|
|
||||||
|
else
|
||||||
|
GCCROOT =
|
||||||
|
AVRDUDE_CONF =
|
||||||
|
endif
|
||||||
|
#
|
||||||
|
# End of build environment code.
|
||||||
|
|
||||||
|
|
||||||
|
# the efuse should really be 0xf8; since, however, only the lower
|
||||||
|
# three bits of that byte are used on the atmega168, avrdude gets
|
||||||
|
# confused if you specify 1's for the higher bits, see:
|
||||||
|
# http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/
|
||||||
|
#
|
||||||
|
# similarly, the lock bits should be 0xff instead of 0x3f (to
|
||||||
|
# unlock the bootloader section) and 0xcf instead of 0x2f (to
|
||||||
|
# lock it), but since the high two bits of the lock byte are
|
||||||
|
# unused, avrdude would get confused.
|
||||||
|
|
||||||
|
ISPFUSES = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
|
||||||
|
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
|
||||||
|
-e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m \
|
||||||
|
-U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
|
||||||
|
ISPFLASH = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
|
||||||
|
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
|
||||||
|
-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
|
||||||
|
|
||||||
|
STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe"
|
||||||
|
STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \
|
||||||
|
-lFF -LFF -f$(HFUSE)$(LFUSE) -EF8 -ms -q -cUSB -I200kHz -s -wt
|
||||||
|
STK500-2 = $(STK500) -d$(MCU_TARGET) -ms -q -lCF -LCF -cUSB -I200kHz -s -wt
|
||||||
|
|
||||||
|
OBJ = $(PROGRAM).o
|
||||||
|
OPTIMIZE = -Os -fno-inline-small-functions -fno-split-wide-types
|
||||||
|
# -mshort-calls
|
||||||
|
|
||||||
|
DEFS =
|
||||||
|
LIBS =
|
||||||
|
|
||||||
|
CC = $(GCCROOT)avr-gcc
|
||||||
|
|
||||||
|
# Override is only needed by avr-lib build system.
|
||||||
|
|
||||||
|
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
|
||||||
|
override LDFLAGS = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib
|
||||||
|
|
||||||
|
OBJCOPY = $(GCCROOT)avr-objcopy
|
||||||
|
OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump)
|
||||||
|
|
||||||
|
SIZE = $(GCCROOT)avr-size
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Voice board test
|
||||||
|
# ATmega328
|
||||||
|
#
|
||||||
|
#atmega328: TARGET = atmega328p
|
||||||
|
#atmega328: MCU_TARGET = atmega328p
|
||||||
|
#atmega328: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=38400'
|
||||||
|
#atmega328: AVR_FREQ = 12000000L
|
||||||
|
#atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
|
||||||
|
#atmega328: $(PROGRAM)_atmega328.hex
|
||||||
|
#atmega328: $(PROGRAM)_atmega328.lst
|
||||||
|
|
||||||
|
xmega32D4: TARGET = atxmega32d4
|
||||||
|
xmega32D4: MCU_TARGET = atxmega32d4
|
||||||
|
xmega32D4: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=57600'
|
||||||
|
xmega32D4: AVR_FREQ = 32000000L
|
||||||
|
xmega32D4: LDSECTIONS = -Wl,--section-start=.text=0x8000
|
||||||
|
xmega32D4: $(PROGRAM)_xmega32d4.hex
|
||||||
|
xmega32D4: $(PROGRAM)_xmega32d4.lst
|
||||||
|
|
||||||
|
atmega328: TARGET = atmega328
|
||||||
|
atmega328: MCU_TARGET = atmega328p
|
||||||
|
atmega328: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=57600'
|
||||||
|
atmega328: AVR_FREQ = 16000000L
|
||||||
|
atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
|
||||||
|
atmega328: $(PROGRAM)_atmega328_16.hex
|
||||||
|
atmega328: $(PROGRAM)_atmega328_16.lst
|
||||||
|
|
||||||
|
|
||||||
|
# Test platforms
|
||||||
|
# Virtual boot block test
|
||||||
|
virboot328: TARGET = atmega328
|
||||||
|
virboot328: MCU_TARGET = atmega328p
|
||||||
|
virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DVIRTUAL_BOOT'
|
||||||
|
virboot328: AVR_FREQ = 16000000L
|
||||||
|
virboot328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
|
||||||
|
virboot328: $(PROGRAM)_atmega328.hex
|
||||||
|
virboot328: $(PROGRAM)_atmega328.lst
|
||||||
|
|
||||||
|
# 20MHz clocked platforms
|
||||||
|
#
|
||||||
|
# These are capable of 230400 baud, or 38400 baud on PC (Arduino Avrdude issue)
|
||||||
|
#
|
||||||
|
|
||||||
|
pro20: TARGET = pro_20mhz
|
||||||
|
pro20: MCU_TARGET = atmega168
|
||||||
|
pro20: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
pro20: AVR_FREQ = 20000000L
|
||||||
|
pro20: $(PROGRAM)_pro_20mhz.hex
|
||||||
|
pro20: $(PROGRAM)_pro_20mhz.lst
|
||||||
|
|
||||||
|
pro20_isp: pro20
|
||||||
|
pro20_isp: TARGET = pro_20mhz
|
||||||
|
# 2.7V brownout
|
||||||
|
pro20_isp: HFUSE = DD
|
||||||
|
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
|
||||||
|
pro20_isp: LFUSE = C6
|
||||||
|
# 512 byte boot
|
||||||
|
pro20_isp: EFUSE = 04
|
||||||
|
pro20_isp: isp
|
||||||
|
|
||||||
|
# 16MHz clocked platforms
|
||||||
|
#
|
||||||
|
# These are capable of 230400 baud, or 38400 baud on PC (Arduino Avrdude issue)
|
||||||
|
#
|
||||||
|
|
||||||
|
pro16: TARGET = pro_16MHz
|
||||||
|
pro16: MCU_TARGET = atmega168
|
||||||
|
pro16: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
pro16: AVR_FREQ = 16000000L
|
||||||
|
pro16: $(PROGRAM)_pro_16MHz.hex
|
||||||
|
pro16: $(PROGRAM)_pro_16MHz.lst
|
||||||
|
|
||||||
|
pro16_isp: pro16
|
||||||
|
pro16_isp: TARGET = pro_16MHz
|
||||||
|
# 2.7V brownout
|
||||||
|
pro16_isp: HFUSE = DD
|
||||||
|
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
|
||||||
|
pro16_isp: LFUSE = C6
|
||||||
|
# 512 byte boot
|
||||||
|
pro16_isp: EFUSE = 04
|
||||||
|
pro16_isp: isp
|
||||||
|
|
||||||
|
# Diecimila, Duemilanove with m168, and NG use identical bootloaders
|
||||||
|
# Call it "atmega168" for generality and clarity, keep "diecimila" for
|
||||||
|
# backward compatibility of makefile
|
||||||
|
#
|
||||||
|
atmega168: TARGET = atmega168
|
||||||
|
atmega168: MCU_TARGET = atmega168
|
||||||
|
atmega168: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=38400'
|
||||||
|
atmega168: AVR_FREQ = 12000000L
|
||||||
|
atmega168: $(PROGRAM)_atmega168.hex
|
||||||
|
atmega168: $(PROGRAM)_atmega168.lst
|
||||||
|
|
||||||
|
atmega168_isp: atmega168
|
||||||
|
atmega168_isp: TARGET = atmega168
|
||||||
|
# 2.7V brownout
|
||||||
|
atmega168_isp: HFUSE = DD
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
atmega168_isp: LFUSE = FF
|
||||||
|
# 512 byte boot
|
||||||
|
atmega168_isp: EFUSE = 04
|
||||||
|
atmega168_isp: isp
|
||||||
|
|
||||||
|
diecimila: TARGET = diecimila
|
||||||
|
diecimila: MCU_TARGET = atmega168
|
||||||
|
diecimila: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
diecimila: AVR_FREQ = 16000000L
|
||||||
|
diecimila: $(PROGRAM)_diecimila.hex
|
||||||
|
diecimila: $(PROGRAM)_diecimila.lst
|
||||||
|
|
||||||
|
diecimila_isp: diecimila
|
||||||
|
diecimila_isp: TARGET = diecimila
|
||||||
|
# 2.7V brownout
|
||||||
|
diecimila_isp: HFUSE = DD
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
diecimila_isp: LFUSE = FF
|
||||||
|
# 512 byte boot
|
||||||
|
diecimila_isp: EFUSE = 04
|
||||||
|
diecimila_isp: isp
|
||||||
|
|
||||||
|
atmega328_isp: atmega328
|
||||||
|
atmega328_isp: TARGET = atmega328
|
||||||
|
atmega328_isp: MCU_TARGET = atmega328p
|
||||||
|
# 512 byte boot, SPIEN
|
||||||
|
atmega328_isp: HFUSE = DE
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
atmega328_isp: LFUSE = FF
|
||||||
|
# 2.7V brownout
|
||||||
|
atmega328_isp: EFUSE = FD
|
||||||
|
atmega328_isp: isp
|
||||||
|
|
||||||
|
atmega1284: TARGET = atmega1284p
|
||||||
|
atmega1284: MCU_TARGET = atmega1284p
|
||||||
|
atmega1284: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DBIGBOOT'
|
||||||
|
atmega1284: AVR_FREQ = 16000000L
|
||||||
|
atmega1284: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe
|
||||||
|
atmega1284: $(PROGRAM)_atmega1284p.hex
|
||||||
|
atmega1284: $(PROGRAM)_atmega1284p.lst
|
||||||
|
|
||||||
|
atmega1284_isp: atmega1284
|
||||||
|
atmega1284_isp: TARGET = atmega1284p
|
||||||
|
atmega1284_isp: MCU_TARGET = atmega1284p
|
||||||
|
# 1024 byte boot
|
||||||
|
atmega1284_isp: HFUSE = DE
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
atmega1284_isp: LFUSE = FF
|
||||||
|
# 2.7V brownout
|
||||||
|
atmega1284_isp: EFUSE = FD
|
||||||
|
atmega1284_isp: isp
|
||||||
|
|
||||||
|
# Sanguino has a minimum boot size of 1024 bytes, so enable extra functions
|
||||||
|
#
|
||||||
|
sanguino: TARGET = atmega644p
|
||||||
|
sanguino: MCU_TARGET = atmega644p
|
||||||
|
sanguino: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DBIGBOOT'
|
||||||
|
sanguino: AVR_FREQ = 16000000L
|
||||||
|
sanguino: LDSECTIONS = -Wl,--section-start=.text=0xfc00 -Wl,--section-start=.version=0xfffe
|
||||||
|
sanguino: $(PROGRAM)_atmega644p.hex
|
||||||
|
sanguino: $(PROGRAM)_atmega644p.lst
|
||||||
|
|
||||||
|
sanguino_isp: sanguino
|
||||||
|
sanguino_isp: TARGET = atmega644p
|
||||||
|
sanguino_isp: MCU_TARGET = atmega644p
|
||||||
|
# 1024 byte boot
|
||||||
|
sanguino_isp: HFUSE = DE
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
sanguino_isp: LFUSE = FF
|
||||||
|
# 2.7V brownout
|
||||||
|
sanguino_isp: EFUSE = FD
|
||||||
|
sanguino_isp: isp
|
||||||
|
|
||||||
|
# Mega has a minimum boot size of 1024 bytes, so enable extra functions
|
||||||
|
#mega: TARGET = atmega1280
|
||||||
|
mega1280: MCU_TARGET = atmega1280
|
||||||
|
mega1280: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400' '-DBIGBOOT'
|
||||||
|
mega1280: AVR_FREQ = 16000000L
|
||||||
|
mega1280: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe
|
||||||
|
mega1280: $(PROGRAM)_atmega1280.hex
|
||||||
|
mega1280: $(PROGRAM)_atmega1280.lst
|
||||||
|
|
||||||
|
mega1280_isp: mega
|
||||||
|
mega1280_isp: TARGET = atmega1280
|
||||||
|
mega1280_isp: MCU_TARGET = atmega1280
|
||||||
|
# 1024 byte boot
|
||||||
|
mega1280_isp: HFUSE = DE
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
mega1280_isp: LFUSE = FF
|
||||||
|
# 2.7V brownout
|
||||||
|
mega1280_isp: EFUSE = FD
|
||||||
|
mega1280_isp: isp
|
||||||
|
|
||||||
|
# ATmega8
|
||||||
|
#
|
||||||
|
atmega8: TARGET = atmega8
|
||||||
|
atmega8: MCU_TARGET = atmega8
|
||||||
|
atmega8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
atmega8: AVR_FREQ = 16000000L
|
||||||
|
atmega8: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
|
||||||
|
atmega8: $(PROGRAM)_atmega8.hex
|
||||||
|
atmega8: $(PROGRAM)_atmega8.lst
|
||||||
|
|
||||||
|
atmega8_isp: atmega8
|
||||||
|
atmega8_isp: TARGET = atmega8
|
||||||
|
atmega8_isp: MCU_TARGET = atmega8
|
||||||
|
# SPIEN, CKOPT, Bootsize=512B
|
||||||
|
atmega8_isp: HFUSE = CC
|
||||||
|
# 2.7V brownout, Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
atmega8_isp: LFUSE = BF
|
||||||
|
atmega8_isp: isp
|
||||||
|
|
||||||
|
# ATmega88
|
||||||
|
#
|
||||||
|
atmega88: TARGET = atmega88
|
||||||
|
atmega88: MCU_TARGET = atmega88
|
||||||
|
atmega88: CFLAGS += '-DLED_START_FLASHES=0' '-DBAUD_RATE=38400'
|
||||||
|
atmega88: AVR_FREQ = 12000000L
|
||||||
|
atmega88: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
|
||||||
|
atmega88: $(PROGRAM)_atmega88.hex
|
||||||
|
atmega88: $(PROGRAM)_atmega88.lst
|
||||||
|
|
||||||
|
atmega88_isp: atmega88
|
||||||
|
atmega88_isp: TARGET = atmega88
|
||||||
|
atmega88_isp: MCU_TARGET = atmega88
|
||||||
|
# 2.7V brownout
|
||||||
|
atmega88_isp: HFUSE = DD
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
atemga88_isp: LFUSE = FF
|
||||||
|
# 512 byte boot
|
||||||
|
atmega88_isp: EFUSE = 04
|
||||||
|
atmega88_isp: isp
|
||||||
|
|
||||||
|
|
||||||
|
# 8MHz clocked platforms
|
||||||
|
#
|
||||||
|
# These are capable of 38400 baud
|
||||||
|
#
|
||||||
|
|
||||||
|
lilypad: TARGET = lilypad
|
||||||
|
lilypad: MCU_TARGET = atmega168
|
||||||
|
lilypad: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
lilypad: AVR_FREQ = 8000000L
|
||||||
|
lilypad: $(PROGRAM)_lilypad.hex
|
||||||
|
lilypad: $(PROGRAM)_lilypad.lst
|
||||||
|
|
||||||
|
lilypad_isp: lilypad
|
||||||
|
lilypad_isp: TARGET = lilypad
|
||||||
|
# 2.7V brownout
|
||||||
|
lilypad_isp: HFUSE = DD
|
||||||
|
# Internal 8MHz osc (8MHz) Slow rising power
|
||||||
|
lilypad_isp: LFUSE = E2
|
||||||
|
# 512 byte boot
|
||||||
|
lilypad_isp: EFUSE = 04
|
||||||
|
lilypad_isp: isp
|
||||||
|
|
||||||
|
lilypad_resonator: TARGET = lilypad_resonator
|
||||||
|
lilypad_resonator: MCU_TARGET = atmega168
|
||||||
|
lilypad_resonator: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
lilypad_resonator: AVR_FREQ = 8000000L
|
||||||
|
lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex
|
||||||
|
lilypad_resonator: $(PROGRAM)_lilypad_resonator.lst
|
||||||
|
|
||||||
|
lilypad_resonator_isp: lilypad_resonator
|
||||||
|
lilypad_resonator_isp: TARGET = lilypad_resonator
|
||||||
|
# 2.7V brownout
|
||||||
|
lilypad_resonator_isp: HFUSE = DD
|
||||||
|
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
|
||||||
|
lilypad_resonator_isp: LFUSE = C6
|
||||||
|
# 512 byte boot
|
||||||
|
lilypad_resonator_isp: EFUSE = 04
|
||||||
|
lilypad_resonator_isp: isp
|
||||||
|
|
||||||
|
pro8: TARGET = pro_8MHz
|
||||||
|
pro8: MCU_TARGET = atmega168
|
||||||
|
pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
pro8: AVR_FREQ = 8000000L
|
||||||
|
pro8: $(PROGRAM)_pro_8MHz.hex
|
||||||
|
pro8: $(PROGRAM)_pro_8MHz.lst
|
||||||
|
|
||||||
|
pro8_isp: pro8
|
||||||
|
pro8_isp: TARGET = pro_8MHz
|
||||||
|
# 2.7V brownout
|
||||||
|
pro8_isp: HFUSE = DD
|
||||||
|
# Full swing xtal (20MHz) 258CK/14CK+4.1ms
|
||||||
|
pro8_isp: LFUSE = C6
|
||||||
|
# 512 byte boot
|
||||||
|
pro8_isp: EFUSE = 04
|
||||||
|
pro8_isp: isp
|
||||||
|
|
||||||
|
atmega328_pro8: TARGET = atmega328_pro_8MHz
|
||||||
|
atmega328_pro8: MCU_TARGET = atmega328p
|
||||||
|
atmega328_pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=38400'
|
||||||
|
atmega328_pro8: AVR_FREQ = 8000000L
|
||||||
|
atmega328_pro8: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
|
||||||
|
atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex
|
||||||
|
atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.lst
|
||||||
|
|
||||||
|
atmega328_pro8_isp: atmega328_pro8
|
||||||
|
atmega328_pro8_isp: TARGET = atmega328_pro_8MHz
|
||||||
|
atmega328_pro8_isp: MCU_TARGET = atmega328p
|
||||||
|
# 512 byte boot, SPIEN
|
||||||
|
atmega328_pro8_isp: HFUSE = DE
|
||||||
|
# Low power xtal (16MHz) 16KCK/14CK+65ms
|
||||||
|
atmega328_pro8_isp: LFUSE = FF
|
||||||
|
# 2.7V brownout
|
||||||
|
atmega328_pro8_isp: EFUSE = DE
|
||||||
|
atmega328_pro8_isp: isp
|
||||||
|
|
||||||
|
# 1MHz clocked platforms
|
||||||
|
#
|
||||||
|
# These are capable of 9600 baud
|
||||||
|
#
|
||||||
|
|
||||||
|
luminet: TARGET = luminet
|
||||||
|
luminet: MCU_TARGET = attiny84
|
||||||
|
luminet: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600'
|
||||||
|
luminet: CFLAGS += '-DVIRTUAL_BOOT_PARTITION'
|
||||||
|
luminet: AVR_FREQ = 1000000L
|
||||||
|
luminet: LDSECTIONS = -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1efe
|
||||||
|
luminet: $(PROGRAM)_luminet.hex
|
||||||
|
luminet: $(PROGRAM)_luminet.lst
|
||||||
|
|
||||||
|
luminet_isp: luminet
|
||||||
|
luminet_isp: TARGET = luminet
|
||||||
|
luminet_isp: MCU_TARGET = attiny84
|
||||||
|
# Brownout disabled
|
||||||
|
luminet_isp: HFUSE = DF
|
||||||
|
# 1MHz internal oscillator, slowly rising power
|
||||||
|
luminet_isp: LFUSE = 62
|
||||||
|
# Self-programming enable
|
||||||
|
luminet_isp: EFUSE = FE
|
||||||
|
luminet_isp: isp
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generic build instructions
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
isp: $(TARGET)
|
||||||
|
$(ISPFUSES)
|
||||||
|
$(ISPFLASH)
|
||||||
|
|
||||||
|
isp-stk500: $(PROGRAM)_$(TARGET).hex
|
||||||
|
$(STK500-1)
|
||||||
|
$(STK500-2)
|
||||||
|
|
||||||
|
%.elf: $(OBJ)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
$(SIZE) $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
|
||||||
|
|
||||||
|
%.lst: %.elf
|
||||||
|
$(OBJDUMP) -h -S $< > $@
|
||||||
|
|
||||||
|
%.hex: %.elf
|
||||||
|
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@
|
||||||
|
|
||||||
|
%.srec: %.elf
|
||||||
|
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@
|
||||||
|
|
||||||
|
%.bin: %.elf
|
||||||
|
$(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@
|
980
BootLoaders/OrangeMultiBoot/Source/optiboot.c
Normal file
980
BootLoaders/OrangeMultiBoot/Source/optiboot.c
Normal file
@ -0,0 +1,980 @@
|
|||||||
|
/**********************************************************/
|
||||||
|
/* Optiboot bootloader for Xmega */
|
||||||
|
/* */
|
||||||
|
/* http://optiboot.googlecode.com */
|
||||||
|
/* */
|
||||||
|
/* Arduino-maintained version : See README.TXT */
|
||||||
|
/* http://code.google.com/p/arduino/ */
|
||||||
|
/* It is the intent that changes not relevant to the */
|
||||||
|
/* Arduino production envionment get moved from the */
|
||||||
|
/* optiboot project to the arduino project in "lumps." */
|
||||||
|
/* */
|
||||||
|
/* Heavily optimised bootloader that is faster and */
|
||||||
|
/* smaller than the Arduino standard bootloader */
|
||||||
|
/* */
|
||||||
|
/* Enhancements: */
|
||||||
|
/* Fits in 512 bytes, saving 1.5K of code space */
|
||||||
|
/* Background page erasing speeds up programming */
|
||||||
|
/* Higher baud rate speeds up programming */
|
||||||
|
/* Written almost entirely in C */
|
||||||
|
/* Customisable timeout with accurate timeconstant */
|
||||||
|
/* Optional virtual UART. No hardware UART required. */
|
||||||
|
/* Optional virtual boot partition for devices without. */
|
||||||
|
/* */
|
||||||
|
/* What you lose: */
|
||||||
|
/* Implements a skeleton STK500 protocol which is */
|
||||||
|
/* missing several features including EEPROM */
|
||||||
|
/* programming and non-page-aligned writes */
|
||||||
|
/* High baud rate breaks compatibility with standard */
|
||||||
|
/* Arduino flash settings */
|
||||||
|
/* */
|
||||||
|
/* Fully supported: */
|
||||||
|
/* ATmega168 based devices (Diecimila etc) */
|
||||||
|
/* ATmega328P based devices (Duemilanove etc) */
|
||||||
|
/* */
|
||||||
|
/* Beta test (believed working.) */
|
||||||
|
/* ATmega8 based devices (Arduino legacy) */
|
||||||
|
/* ATmega328 non-picopower devices */
|
||||||
|
/* ATmega644P based devices (Sanguino) */
|
||||||
|
/* ATmega1284P based devices */
|
||||||
|
/* */
|
||||||
|
/* Alpha test */
|
||||||
|
/* ATmega1280 based devices (Arduino Mega) */
|
||||||
|
/* */
|
||||||
|
/* Work in progress: */
|
||||||
|
/* ATtiny84 based devices (Luminet) */
|
||||||
|
/* */
|
||||||
|
/* Does not support: */
|
||||||
|
/* USB based devices (eg. Teensy) */
|
||||||
|
/* */
|
||||||
|
/* Assumptions: */
|
||||||
|
/* The code makes several assumptions that reduce the */
|
||||||
|
/* code size. They are all true after a hardware reset, */
|
||||||
|
/* but may not be true if the bootloader is called by */
|
||||||
|
/* other means or on other hardware. */
|
||||||
|
/* No interrupts can occur */
|
||||||
|
/* UART and Timer 1 are set to their reset state */
|
||||||
|
/* SP points to RAMEND */
|
||||||
|
/* */
|
||||||
|
/* Code builds on code, libraries and optimisations from: */
|
||||||
|
/* stk500boot.c by Jason P. Kyle */
|
||||||
|
/* Arduino bootloader http://arduino.cc */
|
||||||
|
/* Spiff's 1K bootloader http://spiffie.org/know/arduino_1k_bootloader/bootloader.shtml */
|
||||||
|
/* avr-libc project http://nongnu.org/avr-libc */
|
||||||
|
/* Adaboot http://www.ladyada.net/library/arduino/bootloader.html */
|
||||||
|
/* AVR305 Atmel Application Note */
|
||||||
|
/* */
|
||||||
|
/* This program is free software; you can redistribute it */
|
||||||
|
/* and/or modify it under the terms of the GNU General */
|
||||||
|
/* Public License as published by the Free Software */
|
||||||
|
/* Foundation; either version 2 of the License, or */
|
||||||
|
/* (at your option) any later version. */
|
||||||
|
/* */
|
||||||
|
/* This program is distributed in the hope that it will */
|
||||||
|
/* be useful, but WITHOUT ANY WARRANTY; without even the */
|
||||||
|
/* implied warranty of MERCHANTABILITY or FITNESS FOR A */
|
||||||
|
/* PARTICULAR PURPOSE. See the GNU General Public */
|
||||||
|
/* License for more details. */
|
||||||
|
/* */
|
||||||
|
/* You should have received a copy of the GNU General */
|
||||||
|
/* Public License along with this program; if not, write */
|
||||||
|
/* to the Free Software Foundation, Inc., */
|
||||||
|
/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
/* */
|
||||||
|
/* Licence can be viewed at */
|
||||||
|
/* http://www.fsf.org/licenses/gpl.txt */
|
||||||
|
/* */
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* */
|
||||||
|
/* Optional defines: */
|
||||||
|
/* */
|
||||||
|
/**********************************************************/
|
||||||
|
/* */
|
||||||
|
/* BIG_BOOT: */
|
||||||
|
/* Build a 1k bootloader, not 512 bytes. This turns on */
|
||||||
|
/* extra functionality. */
|
||||||
|
/* */
|
||||||
|
/* BAUD_RATE: */
|
||||||
|
/* Set bootloader baud rate. */
|
||||||
|
/* */
|
||||||
|
/* LUDICROUS_SPEED: */
|
||||||
|
/* 230400 baud :-) */
|
||||||
|
/* */
|
||||||
|
/* SOFT_UART: */
|
||||||
|
/* Use AVR305 soft-UART instead of hardware UART. */
|
||||||
|
/* */
|
||||||
|
/* LED_START_FLASHES: */
|
||||||
|
/* Number of LED flashes on bootup. */
|
||||||
|
/* */
|
||||||
|
/* LED_DATA_FLASH: */
|
||||||
|
/* Flash LED when transferring data. For boards without */
|
||||||
|
/* TX or RX LEDs, or for people who like blinky lights. */
|
||||||
|
/* */
|
||||||
|
/* SUPPORT_EEPROM: */
|
||||||
|
/* Support reading and writing from EEPROM. This is not */
|
||||||
|
/* used by Arduino, so off by default. */
|
||||||
|
/* */
|
||||||
|
/* TIMEOUT_MS: */
|
||||||
|
/* Bootloader timeout period, in milliseconds. */
|
||||||
|
/* 500,1000,2000,4000,8000 supported. */
|
||||||
|
/* */
|
||||||
|
/* UART: */
|
||||||
|
/* UART number (0..n) for devices with more than */
|
||||||
|
/* one hardware uart (644P, 1284P, etc) */
|
||||||
|
/* */
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* Version Numbers! */
|
||||||
|
/* */
|
||||||
|
/* Arduino Optiboot now includes this Version number in */
|
||||||
|
/* the source and object code. */
|
||||||
|
/* */
|
||||||
|
/* Version 3 was released as zip from the optiboot */
|
||||||
|
/* repository and was distributed with Arduino 0022. */
|
||||||
|
/* Version 4 starts with the arduino repository commit */
|
||||||
|
/* that brought the arduino repository up-to-date with */
|
||||||
|
/* the optiboot source tree changes since v3. */
|
||||||
|
/* */
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
/**********************************************************/
|
||||||
|
/* Edit History: */
|
||||||
|
/* */
|
||||||
|
/* Nov 2012 */
|
||||||
|
/* Specific version for 9x voice module */
|
||||||
|
/* by Mike Blandford */
|
||||||
|
/* Mar 2012 */
|
||||||
|
/* 4.5 WestfW: add infrastructure for non-zero UARTS. */
|
||||||
|
/* 4.5 WestfW: fix SIGNATURE_2 for m644 (bad in avr-libc) */
|
||||||
|
/* Jan 2012: */
|
||||||
|
/* 4.5 WestfW: fix NRWW value for m1284. */
|
||||||
|
/* 4.4 WestfW: use attribute OS_main instead of naked for */
|
||||||
|
/* main(). This allows optimizations that we */
|
||||||
|
/* count on, which are prohibited in naked */
|
||||||
|
/* functions due to PR42240. (keeps us less */
|
||||||
|
/* than 512 bytes when compiler is gcc4.5 */
|
||||||
|
/* (code from 4.3.2 remains the same.) */
|
||||||
|
/* 4.4 WestfW and Maniacbug: Add m1284 support. This */
|
||||||
|
/* does not change the 328 binary, so the */
|
||||||
|
/* version number didn't change either. (?) */
|
||||||
|
/* June 2011: */
|
||||||
|
/* 4.4 WestfW: remove automatic soft_uart detect (didn't */
|
||||||
|
/* know what it was doing or why.) Added a */
|
||||||
|
/* check of the calculated BRG value instead. */
|
||||||
|
/* Version stays 4.4; existing binaries are */
|
||||||
|
/* not changed. */
|
||||||
|
/* 4.4 WestfW: add initialization of address to keep */
|
||||||
|
/* the compiler happy. Change SC'ed targets. */
|
||||||
|
/* Return the SW version via READ PARAM */
|
||||||
|
/* 4.3 WestfW: catch framing errors in getch(), so that */
|
||||||
|
/* AVRISP works without HW kludges. */
|
||||||
|
/* http://code.google.com/p/arduino/issues/detail?id=368n*/
|
||||||
|
/* 4.2 WestfW: reduce code size, fix timeouts, change */
|
||||||
|
/* verifySpace to use WDT instead of appstart */
|
||||||
|
/* 4.1 WestfW: put version number in binary. */
|
||||||
|
/**********************************************************/
|
||||||
|
|
||||||
|
#define OPTIBOOT_MAJVER 4
|
||||||
|
#define OPTIBOOT_MINVER 5
|
||||||
|
|
||||||
|
#define MULTI_CALLED 1
|
||||||
|
|
||||||
|
#define MAKESTR(a) #a
|
||||||
|
#define MAKEVER(a, b) MAKESTR(a*256+b)
|
||||||
|
|
||||||
|
// Page Size is 128 words (256 bytes)
|
||||||
|
|
||||||
|
//asm(" .section .version\n"
|
||||||
|
// "optiboot_version: .word " MAKEVER(OPTIBOOT_MAJVER, OPTIBOOT_MINVER) "\n"
|
||||||
|
// " .section .text\n");
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
|
// <avr/boot.h> uses sts instructions, but this version uses out instructions
|
||||||
|
// This saves cycles and program memory.
|
||||||
|
//#include "boot.h"
|
||||||
|
|
||||||
|
|
||||||
|
// We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need.
|
||||||
|
|
||||||
|
#include "pin_defs.h"
|
||||||
|
#include "stk500.h"
|
||||||
|
|
||||||
|
#define BIND_pin 2 //PD2
|
||||||
|
#define BIND_port PORTD
|
||||||
|
#define IS_BIND_BUTTON_on ( (BIND_port.IN & _BV(BIND_pin)) == 0x00 )
|
||||||
|
|
||||||
|
#ifndef LED_START_FLASHES
|
||||||
|
#define LED_START_FLASHES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LUDICROUS_SPEED
|
||||||
|
#define BAUD_RATE 230400L
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* set the UART baud rate defaults */
|
||||||
|
#ifndef BAUD_RATE
|
||||||
|
#if F_CPU >= 8000000L
|
||||||
|
#define BAUD_RATE 38400L // Highest rate Avrdude win32 will support
|
||||||
|
#elsif F_CPU >= 1000000L
|
||||||
|
#define BAUD_RATE 9600L // 19200 also supported, but with significant error
|
||||||
|
#elsif F_CPU >= 128000L
|
||||||
|
#define BAUD_RATE 4800L // Good for 128kHz internal RC
|
||||||
|
#else
|
||||||
|
#define BAUD_RATE 1200L // Good even at 32768Hz
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UART
|
||||||
|
#define UART 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Switch in soft UART for hard baud rates */
|
||||||
|
/*
|
||||||
|
* I don't understand what this was supposed to accomplish, where the
|
||||||
|
* constant "280" came from, or why automatically (and perhaps unexpectedly)
|
||||||
|
* switching to a soft uart is a good thing, so I'm undoing this in favor
|
||||||
|
* of a range check using the same calc used to config the BRG...
|
||||||
|
*/
|
||||||
|
#if (F_CPU/BAUD_RATE) > 280 // > 57600 for 16MHz
|
||||||
|
#ifndef SOFT_UART
|
||||||
|
#define SOFT_UART
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else // 0
|
||||||
|
#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 > 250
|
||||||
|
#error Unachievable baud rate (too slow) BAUD_RATE
|
||||||
|
#endif // baud rate slow check
|
||||||
|
#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 < 3
|
||||||
|
#error Unachievable baud rate (too fast) BAUD_RATE
|
||||||
|
#endif // baud rate fastn check
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Watchdog settings */
|
||||||
|
#define WATCHDOG_OFF (0)
|
||||||
|
#define WATCHDOG_16MS (_BV(WDE))
|
||||||
|
#define WATCHDOG_32MS (_BV(WDP0) | _BV(WDE))
|
||||||
|
#define WATCHDOG_64MS (_BV(WDP1) | _BV(WDE))
|
||||||
|
#define WATCHDOG_125MS (_BV(WDP1) | _BV(WDP0) | _BV(WDE))
|
||||||
|
#define WATCHDOG_250MS (_BV(WDP2) | _BV(WDE))
|
||||||
|
#define WATCHDOG_500MS (_BV(WDP2) | _BV(WDP0) | _BV(WDE))
|
||||||
|
#define WATCHDOG_1S (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
|
||||||
|
#define WATCHDOG_2S (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
|
||||||
|
#ifndef __AVR_ATmega8__
|
||||||
|
#define WATCHDOG_4S (_BV(WDP3) | _BV(WDE))
|
||||||
|
#define WATCHDOG_8S (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Function Prototypes */
|
||||||
|
/* The main function is in init9, which removes the interrupt vector table */
|
||||||
|
/* we don't need. It is also 'naked', which means the compiler does not */
|
||||||
|
/* generate any entry or exit code itself. */
|
||||||
|
int main(void) __attribute__ ((OS_main)) __attribute__ ((noreturn)) __attribute__ ((section (".init9")));
|
||||||
|
void putch(char);
|
||||||
|
uint8_t getch(void);
|
||||||
|
static inline void getNch(uint8_t); /* "static inline" is a compiler hint to reduce code size */
|
||||||
|
void verifySpace();
|
||||||
|
#if LED_START_FLASHES > 0
|
||||||
|
static inline void flash_led(uint8_t);
|
||||||
|
#endif
|
||||||
|
uint8_t getLen();
|
||||||
|
//static inline void watchdogReset();
|
||||||
|
void watchdogConfig(uint8_t x);
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
void uartDelay() __attribute__ ((naked));
|
||||||
|
#endif
|
||||||
|
static void appStart() ; // __attribute__ ((naked));
|
||||||
|
void boot_spm_busy_wait() ;
|
||||||
|
void __boot_page_erase_short( uint16_t address ) ;
|
||||||
|
void __boot_page_fill_short( uint16_t address, uint16_t data) ;
|
||||||
|
void __boot_page_write_short( uint16_t address) ;
|
||||||
|
void __boot_erase_flash_buffer( uint16_t address ) ;
|
||||||
|
void init() ;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NRWW memory
|
||||||
|
* Addresses below NRWW (Non-Read-While-Write) can be programmed while
|
||||||
|
* continuing to run code from flash, slightly speeding up programming
|
||||||
|
* time. Beware that Atmel data sheets specify this as a WORD address,
|
||||||
|
* while optiboot will be comparing against a 16-bit byte address. This
|
||||||
|
* means that on a part with 128kB of memory, the upper part of the lower
|
||||||
|
* 64k will get NRWW processing as well, even though it doesn't need it.
|
||||||
|
* That's OK. In fact, you can disable the overlapping processing for
|
||||||
|
* a part entirely by setting NRWWSTART to zero. This reduces code
|
||||||
|
* space a bit, at the expense of being slightly slower, overall.
|
||||||
|
*
|
||||||
|
* RAMSTART should be self-explanatory. It's bigger on parts with a
|
||||||
|
* lot of peripheral registers.
|
||||||
|
*/
|
||||||
|
#if defined(__AVR_ATmega168__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0x3800)
|
||||||
|
#elif defined(__AVR_ATmega328P__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0x7000)
|
||||||
|
#elif defined(__AVR_ATmega328__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0x7000)
|
||||||
|
#elif defined (__AVR_ATmega644P__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0xE000)
|
||||||
|
// correct for a bug in avr-libc
|
||||||
|
#undef SIGNATURE_2
|
||||||
|
#define SIGNATURE_2 0x0A
|
||||||
|
#elif defined (__AVR_ATmega1284P__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0xE000)
|
||||||
|
#elif defined(__AVR_ATtiny84__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0x0000)
|
||||||
|
#elif defined(__AVR_ATmega1280__)
|
||||||
|
#define RAMSTART (0x200)
|
||||||
|
#define NRWWSTART (0xE000)
|
||||||
|
#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
|
||||||
|
#define RAMSTART (0x100)
|
||||||
|
#define NRWWSTART (0x1800)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* C zero initialises all global variables. However, that requires */
|
||||||
|
/* These definitions are NOT zero initialised, but that doesn't matter */
|
||||||
|
/* This allows us to drop the zero init code, saving us memory */
|
||||||
|
#define buff ((uint8_t*)(RAMSTART))
|
||||||
|
#ifdef VIRTUAL_BOOT_PARTITION
|
||||||
|
#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
|
||||||
|
#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle devices with up to 4 uarts (eg m1280.) Rather inelegantly.
|
||||||
|
* Note that mega8 still needs special handling, because ubrr is handled
|
||||||
|
* differently.
|
||||||
|
*/
|
||||||
|
#if UART == 0
|
||||||
|
# define UART_SRA UCSR0A
|
||||||
|
# define UART_SRB UCSR0B
|
||||||
|
# define UART_SRC UCSR0C
|
||||||
|
# define UART_SRL UBRR0L
|
||||||
|
# define UART_UDR UDR0
|
||||||
|
#elif UART == 1
|
||||||
|
# define UART_SRA UCSR1A
|
||||||
|
# define UART_SRB UCSR1B
|
||||||
|
# define UART_SRC UCSR1C
|
||||||
|
# define UART_SRL UBRR1L
|
||||||
|
# define UART_UDR UDR1
|
||||||
|
#elif UART == 2
|
||||||
|
# define UART_SRA UCSR2A
|
||||||
|
# define UART_SRB UCSR2B
|
||||||
|
# define UART_SRC UCSR2C
|
||||||
|
# define UART_SRL UBRR2L
|
||||||
|
# define UART_UDR UDR2
|
||||||
|
#elif UART == 3
|
||||||
|
# define UART_SRA UCSR3A
|
||||||
|
# define UART_SRB UCSR3B
|
||||||
|
# define UART_SRC UCSR3C
|
||||||
|
# define UART_SRL UBRR3L
|
||||||
|
# define UART_UDR UDR3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* main program starts here */
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
uint8_t ch;
|
||||||
|
uint8_t byte ;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Making these local and in registers prevents the need for initializing
|
||||||
|
* them, and also saves space because code no longer stores to memory.
|
||||||
|
* (initializing address keeps the compiler happy, but isn't really
|
||||||
|
* necessary, and uses 4 bytes of flash.)
|
||||||
|
*/
|
||||||
|
register uint16_t address = 0;
|
||||||
|
init() ;
|
||||||
|
|
||||||
|
// After the zero init loop, this is the first code to run.
|
||||||
|
//
|
||||||
|
// This code makes the following assumptions:
|
||||||
|
// No interrupts will execute
|
||||||
|
// SP points to RAMEND
|
||||||
|
// r1 contains zero
|
||||||
|
//
|
||||||
|
// If not, uncomment the following instructions:
|
||||||
|
// cli();
|
||||||
|
asm volatile ("clr __zero_reg__");
|
||||||
|
|
||||||
|
ch = RST.STATUS ;
|
||||||
|
RST.STATUS = 0xFF ; // Clear all flags
|
||||||
|
|
||||||
|
// Here, if power on, wait 0.1 secs, then check for
|
||||||
|
// serial Rx signal low, if so, stay in bootloader
|
||||||
|
// else go to application
|
||||||
|
|
||||||
|
if (ch & (RST_EXTRF_bm | RST_PORF_bm ) )
|
||||||
|
{
|
||||||
|
TCC1.CCA = 25000 ;
|
||||||
|
TCC1.INTFLAGS = TC1_CCAIF_bm ;
|
||||||
|
|
||||||
|
while(!(TCC1.INTFLAGS & TC1_CCAIF_bm))
|
||||||
|
;
|
||||||
|
TCC1.CTRLA = 0 ; // Stop timer
|
||||||
|
|
||||||
|
uint8_t x ;
|
||||||
|
x = PORTD.IN & 0x04 ;
|
||||||
|
if ( x != 0 )
|
||||||
|
{
|
||||||
|
appStart() ; // Power on, go to app if loaded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//#ifndef SOFT_UART
|
||||||
|
// UART_SRA = _BV(U2X0); //Double speed mode USART0
|
||||||
|
// UART_SRB = _BV(RXEN0) | _BV(TXEN0);
|
||||||
|
// UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
|
||||||
|
//// UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
|
||||||
|
//// Baudrate of 57600
|
||||||
|
//#if F_CPU == 12000000L
|
||||||
|
// UART_SRL = 25 ;
|
||||||
|
//#else
|
||||||
|
//#if F_CPU == 16000000L
|
||||||
|
// UART_SRL = 33 ;
|
||||||
|
//#else
|
||||||
|
//#ERROR Baud rate not available
|
||||||
|
//#endif
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
// Set up watchdog to trigger after 500ms
|
||||||
|
|
||||||
|
|
||||||
|
// watchdogConfig(WATCHDOG_1S);
|
||||||
|
|
||||||
|
/* Set LED pin as output */
|
||||||
|
#define LED_pin 1 //PD1
|
||||||
|
#define LED_port PORTD
|
||||||
|
LED_port.DIRSET = _BV(LED_pin) ;
|
||||||
|
|
||||||
|
//#ifdef SOFT_UART
|
||||||
|
// /* Set TX pin as output */
|
||||||
|
// UART_DDR |= _BV(UART_TX_BIT);
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//#if LED_START_FLASHES > 0
|
||||||
|
// /* Flash onboard LED to signal entering of bootloader */
|
||||||
|
// flash_led(LED_START_FLASHES * 2);
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
/* Forever loop */
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
/* get character from UART */
|
||||||
|
ch = getch();
|
||||||
|
|
||||||
|
if(ch == STK_GET_PARAMETER)
|
||||||
|
{
|
||||||
|
byte = getch();
|
||||||
|
verifySpace();
|
||||||
|
if ( byte == 0x82)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Send optiboot version as "minor SW version"
|
||||||
|
*/
|
||||||
|
putch(OPTIBOOT_MINVER);
|
||||||
|
}
|
||||||
|
else if ( byte == 0x81)
|
||||||
|
{
|
||||||
|
putch(OPTIBOOT_MAJVER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* GET PARAMETER returns a generic 0x03 reply for
|
||||||
|
* other parameters - enough to keep Avrdude happy
|
||||||
|
*/
|
||||||
|
putch(0x03);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(ch == STK_SET_DEVICE) {
|
||||||
|
// SET DEVICE is ignored
|
||||||
|
getNch(20);
|
||||||
|
}
|
||||||
|
else if(ch == STK_SET_DEVICE_EXT)
|
||||||
|
{
|
||||||
|
// SET DEVICE EXT is ignored
|
||||||
|
getNch(5);
|
||||||
|
}
|
||||||
|
else if(ch == STK_LOAD_ADDRESS)
|
||||||
|
{
|
||||||
|
// LOAD ADDRESS
|
||||||
|
uint16_t newAddress;
|
||||||
|
newAddress = getch() ;
|
||||||
|
newAddress = (newAddress & 0xff) | (getch() << 8);
|
||||||
|
#ifdef RAMPZ
|
||||||
|
// Transfer top bit to RAMPZ
|
||||||
|
RAMPZ = (newAddress & 0x8000) ? 1 : 0;
|
||||||
|
#endif
|
||||||
|
// newAddress += newAddress; // Convert from word address to byte address
|
||||||
|
address = newAddress;
|
||||||
|
verifySpace();
|
||||||
|
}
|
||||||
|
else if(ch == STK_UNIVERSAL)
|
||||||
|
{
|
||||||
|
// UNIVERSAL command is ignored
|
||||||
|
getNch(4);
|
||||||
|
putch(0x00);
|
||||||
|
}
|
||||||
|
/* Write memory, length is big endian and is in bytes */
|
||||||
|
else if(ch == STK_PROG_PAGE)
|
||||||
|
{
|
||||||
|
// PROGRAM PAGE - we support flash programming only, not EEPROM
|
||||||
|
uint8_t *bufPtr;
|
||||||
|
uint16_t addrPtr;
|
||||||
|
register uint8_t length;
|
||||||
|
|
||||||
|
getch(); /* getlen() */
|
||||||
|
length = getch();
|
||||||
|
getch();
|
||||||
|
|
||||||
|
// If we are in RWW section, immediately start page erase
|
||||||
|
// if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
|
||||||
|
__boot_page_erase_short((uint16_t)(void*)address);
|
||||||
|
|
||||||
|
// While that is going on, read in page contents
|
||||||
|
bufPtr = buff;
|
||||||
|
do *bufPtr++ = getch();
|
||||||
|
while (--length);
|
||||||
|
|
||||||
|
// If we are in NRWW section, page erase has to be delayed until now.
|
||||||
|
// Todo: Take RAMPZ into account
|
||||||
|
//#ifdef MULTI_CALLED
|
||||||
|
// if (address < 0x7E00)
|
||||||
|
//#endif
|
||||||
|
// {
|
||||||
|
// if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
|
||||||
|
// }
|
||||||
|
// Read command terminator, start reply
|
||||||
|
verifySpace();
|
||||||
|
|
||||||
|
// If only a partial page is to be programmed, the erase might not be complete.
|
||||||
|
// So check that here
|
||||||
|
#ifdef MULTI_CALLED
|
||||||
|
if (address < 0x8000)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
boot_spm_busy_wait();
|
||||||
|
|
||||||
|
#ifdef VIRTUAL_BOOT_PARTITION
|
||||||
|
if ((uint16_t)(void*)address == 0) {
|
||||||
|
// This is the reset vector page. We need to live-patch the code so the
|
||||||
|
// bootloader runs.
|
||||||
|
//
|
||||||
|
// Move RESET vector to WDT vector
|
||||||
|
uint16_t vect = buff[0] | (buff[1]<<8);
|
||||||
|
rstVect = vect;
|
||||||
|
wdtVect = buff[8] | (buff[9]<<8);
|
||||||
|
vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
|
||||||
|
buff[8] = vect & 0xff;
|
||||||
|
buff[9] = vect >> 8;
|
||||||
|
|
||||||
|
// Add jump to bootloader at RESET vector
|
||||||
|
buff[0] = 0x7f;
|
||||||
|
buff[1] = 0xce; // rjmp 0x1d00 instruction
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Copy buffer into programming buffer
|
||||||
|
bufPtr = buff;
|
||||||
|
addrPtr = (uint16_t)(void*)address;
|
||||||
|
ch = SPM_PAGESIZE / 2;
|
||||||
|
__boot_erase_flash_buffer((uint16_t)(void*)addrPtr ) ;
|
||||||
|
do {
|
||||||
|
uint16_t a;
|
||||||
|
// a = *bufPtr++;
|
||||||
|
// a |= (*bufPtr++) << 8;
|
||||||
|
|
||||||
|
a = *((uint16_t *)bufPtr) ;
|
||||||
|
bufPtr += 2 ;
|
||||||
|
|
||||||
|
__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
|
||||||
|
addrPtr += 2;
|
||||||
|
} while (--ch);
|
||||||
|
|
||||||
|
// Write from programming buffer
|
||||||
|
__boot_page_write_short((uint16_t)(void*)address);
|
||||||
|
boot_spm_busy_wait();
|
||||||
|
|
||||||
|
#if defined(RWWSRE)
|
||||||
|
// Reenable read access to flash
|
||||||
|
boot_rww_enable();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Read memory block mode, length is big endian. */
|
||||||
|
else if(ch == STK_READ_PAGE)
|
||||||
|
{
|
||||||
|
register uint8_t length;
|
||||||
|
// READ PAGE - we only read flash
|
||||||
|
getch(); /* getlen() */
|
||||||
|
length = getch();
|
||||||
|
getch();
|
||||||
|
|
||||||
|
verifySpace();
|
||||||
|
//#ifdef VIRTUAL_BOOT_PARTITION
|
||||||
|
// do {
|
||||||
|
// // Undo vector patch in bottom page so verify passes
|
||||||
|
// if (address == 0) ch=rstVect & 0xff;
|
||||||
|
// else if (address == 1) ch=rstVect >> 8;
|
||||||
|
// else if (address == 8) ch=wdtVect & 0xff;
|
||||||
|
// else if (address == 9) ch=wdtVect >> 8;
|
||||||
|
// else ch = pgm_read_byte_near(address);
|
||||||
|
// address++;
|
||||||
|
// putch(ch);
|
||||||
|
// } while (--length);
|
||||||
|
//#else
|
||||||
|
//#ifdef RAMPZ
|
||||||
|
//// Since RAMPZ should already be set, we need to use EPLM directly.
|
||||||
|
//// do putch(pgm_read_byte_near(address++));
|
||||||
|
//// while (--length);
|
||||||
|
// do {
|
||||||
|
// uint8_t result;
|
||||||
|
// __asm__ ("elpm %0,Z\n":"=r"(result):"z"(address));
|
||||||
|
// putch(result);
|
||||||
|
// address++;
|
||||||
|
// }
|
||||||
|
// while (--length);
|
||||||
|
//#else
|
||||||
|
do putch(pgm_read_byte_near(address++));
|
||||||
|
while (--length);
|
||||||
|
//#endif
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get device signature bytes */
|
||||||
|
else if(ch == STK_READ_SIGN)
|
||||||
|
{
|
||||||
|
// READ SIGN - return what Avrdude wants to hear
|
||||||
|
verifySpace();
|
||||||
|
putch(SIGNATURE_0);
|
||||||
|
putch(SIGNATURE_1);
|
||||||
|
putch(SIGNATURE_2);
|
||||||
|
}
|
||||||
|
else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
|
||||||
|
// Adaboot no-wait mod
|
||||||
|
|
||||||
|
// watchdogConfig(WATCHDOG_16MS);
|
||||||
|
|
||||||
|
verifySpace();
|
||||||
|
#ifdef MULTI_CALLED
|
||||||
|
putch(STK_OK);
|
||||||
|
while(!(USARTC0.STATUS & USART_TXCIF_bm))
|
||||||
|
;
|
||||||
|
appStart() ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This covers the response to commands like STK_ENTER_PROGMODE
|
||||||
|
verifySpace();
|
||||||
|
}
|
||||||
|
putch(STK_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void putch(char ch)
|
||||||
|
{
|
||||||
|
//#ifndef SOFT_UART
|
||||||
|
while(!(USARTC0.STATUS & USART_DREIF_bm))
|
||||||
|
;
|
||||||
|
USARTC0.DATA = ch ;
|
||||||
|
//#else
|
||||||
|
// __asm__ __volatile__ (
|
||||||
|
// " com %[ch]\n" // ones complement, carry set
|
||||||
|
// " sec\n"
|
||||||
|
// "1: brcc 2f\n"
|
||||||
|
// " cbi %[uartPort],%[uartBit]\n"
|
||||||
|
// " rjmp 3f\n"
|
||||||
|
// "2: sbi %[uartPort],%[uartBit]\n"
|
||||||
|
// " nop\n"
|
||||||
|
// "3: rcall uartDelay\n"
|
||||||
|
// " rcall uartDelay\n"
|
||||||
|
// " lsr %[ch]\n"
|
||||||
|
// " dec %[bitcnt]\n"
|
||||||
|
// " brne 1b\n"
|
||||||
|
// :
|
||||||
|
// :
|
||||||
|
// [bitcnt] "d" (10),
|
||||||
|
// [ch] "r" (ch),
|
||||||
|
// [uartPort] "I" (_SFR_IO_ADDR(UART_PORT)),
|
||||||
|
// [uartBit] "I" (UART_TX_BIT)
|
||||||
|
// :
|
||||||
|
// "r25"
|
||||||
|
// );
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getch(void)
|
||||||
|
{
|
||||||
|
uint8_t ch;
|
||||||
|
|
||||||
|
//#ifdef LED_DATA_FLASH
|
||||||
|
//#ifdef __AVR_ATmega8__
|
||||||
|
// LED_PORT ^= _BV(LED);
|
||||||
|
//#else
|
||||||
|
// LED_PIN |= _BV(LED);
|
||||||
|
//#endif
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//#ifdef SOFT_UART
|
||||||
|
// __asm__ __volatile__ (
|
||||||
|
// "1: sbic %[uartPin],%[uartBit]\n" // Wait for start edge
|
||||||
|
// " rjmp 1b\n"
|
||||||
|
// " rcall uartDelay\n" // Get to middle of start bit
|
||||||
|
// "2: rcall uartDelay\n" // Wait 1 bit period
|
||||||
|
// " rcall uartDelay\n" // Wait 1 bit period
|
||||||
|
// " clc\n"
|
||||||
|
// " sbic %[uartPin],%[uartBit]\n"
|
||||||
|
// " sec\n"
|
||||||
|
// " dec %[bitCnt]\n"
|
||||||
|
// " breq 3f\n"
|
||||||
|
// " ror %[ch]\n"
|
||||||
|
// " rjmp 2b\n"
|
||||||
|
// "3:\n"
|
||||||
|
// :
|
||||||
|
// [ch] "=r" (ch)
|
||||||
|
// :
|
||||||
|
// [bitCnt] "d" (9),
|
||||||
|
// [uartPin] "I" (_SFR_IO_ADDR(UART_PIN)),
|
||||||
|
// [uartBit] "I" (UART_RX_BIT)
|
||||||
|
// :
|
||||||
|
// "r25"
|
||||||
|
//);
|
||||||
|
//#else
|
||||||
|
while(!(USARTC0.STATUS & USART_RXCIF_bm))
|
||||||
|
|
||||||
|
// watchdogReset()
|
||||||
|
|
||||||
|
;
|
||||||
|
// if (!(UART_SRA & _BV(FE0))) {
|
||||||
|
/*
|
||||||
|
* A Framing Error indicates (probably) that something is talking
|
||||||
|
* to us at the wrong bit rate. Assume that this is because it
|
||||||
|
* expects to be talking to the application, and DON'T reset the
|
||||||
|
* watchdog. This should cause the bootloader to abort and run
|
||||||
|
* the application "soon", if it keeps happening. (Note that we
|
||||||
|
* don't care that an invalid char is returned...)
|
||||||
|
*/
|
||||||
|
// watchdogReset();
|
||||||
|
// }
|
||||||
|
|
||||||
|
ch = USARTC0.DATA ;
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//#ifdef LED_DATA_FLASH
|
||||||
|
//#ifdef __AVR_ATmega8__
|
||||||
|
// LED_PORT ^= _BV(LED);
|
||||||
|
//#else
|
||||||
|
// LED_PIN |= _BV(LED);
|
||||||
|
//#endif
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
// AVR305 equation: #define UART_B_VALUE (((F_CPU/BAUD_RATE)-23)/6)
|
||||||
|
// Adding 3 to numerator simulates nearest rounding for more accurate baud rates
|
||||||
|
#define UART_B_VALUE (((F_CPU/BAUD_RATE)-20)/6)
|
||||||
|
#if UART_B_VALUE > 255
|
||||||
|
#error Baud rate too slow for soft UART
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void uartDelay() {
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"ldi r25,%[count]\n"
|
||||||
|
"1:dec r25\n"
|
||||||
|
"brne 1b\n"
|
||||||
|
"ret\n"
|
||||||
|
::[count] "M" (UART_B_VALUE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void getNch(uint8_t count) {
|
||||||
|
do getch(); while (--count);
|
||||||
|
verifySpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
void verifySpace()
|
||||||
|
{
|
||||||
|
if ( getch() != CRC_EOP) {
|
||||||
|
|
||||||
|
putch(STK_NOSYNC);
|
||||||
|
// watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
|
||||||
|
//
|
||||||
|
// while (1) // and busy-loop so that WD causes
|
||||||
|
// ; // a reset and app start.
|
||||||
|
}
|
||||||
|
putch(STK_INSYNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LED_START_FLASHES > 0
|
||||||
|
void flash_led(uint8_t count) {
|
||||||
|
do {
|
||||||
|
TCNT1 = -(F_CPU/(1024*16));
|
||||||
|
TIFR1 = _BV(TOV1);
|
||||||
|
while(!(TIFR1 & _BV(TOV1)));
|
||||||
|
//#ifdef __AVR_ATmega8__
|
||||||
|
LED_PORT ^= _BV(LED);
|
||||||
|
//#else
|
||||||
|
// LED_PIN |= _BV(LED);
|
||||||
|
//#endif
|
||||||
|
watchdogReset();
|
||||||
|
} while (--count);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Watchdog functions. These are only safe with interrupts turned off.
|
||||||
|
void watchdogReset() {
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"wdr\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void watchdogConfig(uint8_t x) {
|
||||||
|
// WDTCSR = _BV(WDCE) | _BV(WDE);
|
||||||
|
// WDTCSR = x;
|
||||||
|
//}
|
||||||
|
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
// Enable external oscillator (16MHz)
|
||||||
|
OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_256CLK_gc ;
|
||||||
|
OSC.CTRL |= OSC_XOSCEN_bm ;
|
||||||
|
while( ( OSC.STATUS & OSC_XOSCRDY_bm ) == 0 )
|
||||||
|
/* wait */ ;
|
||||||
|
// Enable PLL (*2 = 32MHz)
|
||||||
|
OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | 2 ;
|
||||||
|
OSC.CTRL |= OSC_PLLEN_bm ;
|
||||||
|
while( ( OSC.STATUS & OSC_PLLRDY_bm ) == 0 )
|
||||||
|
/* wait */ ;
|
||||||
|
// Switch to PLL clock
|
||||||
|
CPU_CCP = 0xD8 ;
|
||||||
|
CLK.CTRL = CLK_SCLKSEL_RC2M_gc ;
|
||||||
|
CPU_CCP = 0xD8 ;
|
||||||
|
CLK.CTRL = CLK_SCLKSEL_PLL_gc ;
|
||||||
|
|
||||||
|
PMIC.CTRL = 7 ; // Enable all interrupt levels
|
||||||
|
|
||||||
|
|
||||||
|
// Timer1 config
|
||||||
|
// TCC1 16-bit timer, clocked at 0.5uS
|
||||||
|
EVSYS.CH3MUX = 0x80 + 0x07 ; // Prescaler of 128
|
||||||
|
TCC1.CTRLB = 0; TCC1.CTRLC = 0; TCC1.CTRLD = 0; TCC1.CTRLE = 0;
|
||||||
|
TCC1.INTCTRLA = 0 ;
|
||||||
|
TCC1.INTCTRLB = 0 ;
|
||||||
|
TCC1.PER = 0xFFFF ;
|
||||||
|
TCC1.CNT = 0 ;
|
||||||
|
TCC1.CTRLA = 0x0B ; // Event3 (prescale of 16)
|
||||||
|
|
||||||
|
PORTD.OUTSET = 0x04 ;
|
||||||
|
PORTD.DIRCLR = 0x04 ;
|
||||||
|
PORTD.PIN2CTRL = 0x18 ; // Pullup
|
||||||
|
|
||||||
|
PORTC.OUTSET = 0x08 ;
|
||||||
|
PORTC.DIRSET = 0x08 ;
|
||||||
|
|
||||||
|
USARTC0.BAUDCTRLA = 34 ; // 57600
|
||||||
|
USARTC0.BAUDCTRLB = 0 ;
|
||||||
|
|
||||||
|
USARTC0.CTRLB = 0x18 ; // Enable Tx and Rx
|
||||||
|
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) ;
|
||||||
|
USARTC0.CTRLC = 0x03 ; // 8 bit, no parity, 1 stop
|
||||||
|
USARTC0.DATA ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void boot_spm_busy_wait()
|
||||||
|
{
|
||||||
|
while(NVM.STATUS & NVM_NVMBUSY_bm)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define A_NVM_CMD 0x1CA
|
||||||
|
|
||||||
|
void __boot_page_erase_short( uint16_t address )
|
||||||
|
{
|
||||||
|
asm( "push r24" ) ;
|
||||||
|
asm( "push r25" ) ;
|
||||||
|
NVM.CMD = NVM_CMD_ERASE_APP_PAGE_gc ;
|
||||||
|
asm( "pop r31" ) ;
|
||||||
|
asm( "pop r30" ) ;
|
||||||
|
CCP = CCP_SPM_gc ;
|
||||||
|
asm( "spm" ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __boot_erase_flash_buffer( uint16_t address )
|
||||||
|
{
|
||||||
|
asm( "movw r30,r24" ) ;
|
||||||
|
asm( "ldi r24,0x26" ) ;
|
||||||
|
asm("sts 0x1CA,r24");
|
||||||
|
CCP = CCP_IOREG_gc ;
|
||||||
|
asm( "ldi r24,1" ) ;
|
||||||
|
asm("sts 0x1CB,r24");
|
||||||
|
}
|
||||||
|
|
||||||
|
void __boot_page_fill_short( uint16_t address, uint16_t data)
|
||||||
|
{
|
||||||
|
asm( "push r0" ) ;
|
||||||
|
asm( "push r1" ) ;
|
||||||
|
asm( "movw r30,r24" ) ;
|
||||||
|
asm( "mov r0,r22" ) ;
|
||||||
|
asm( "mov r1,r23" ) ;
|
||||||
|
asm( "ldi r24,0x23" ) ;
|
||||||
|
asm("sts 0x1CA,r24");
|
||||||
|
CCP = CCP_SPM_gc ;
|
||||||
|
asm( "spm" ) ;
|
||||||
|
asm( "pop r1" ) ;
|
||||||
|
asm( "pop r0" ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __boot_page_write_short( uint16_t address)
|
||||||
|
{
|
||||||
|
asm( "movw r30,r24" ) ;
|
||||||
|
asm( "ldi r24,0x2E" ) ;
|
||||||
|
asm("sts 0x1CA,r24");
|
||||||
|
CCP = CCP_SPM_gc ;
|
||||||
|
asm( "spm" ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void appStart()
|
||||||
|
{
|
||||||
|
// watchdogConfig(WATCHDOG_OFF);
|
||||||
|
// __asm__ __volatile__ (
|
||||||
|
//#ifdef VIRTUAL_BOOT_PARTITION
|
||||||
|
// // Jump to WDT vector
|
||||||
|
// "ldi r30,4\n"
|
||||||
|
// "clr r31\n"
|
||||||
|
//#else
|
||||||
|
// // Jump to RST vector
|
||||||
|
// "clr r30\n"
|
||||||
|
// "clr r31\n"
|
||||||
|
//#endif
|
||||||
|
// "ijmp\n"
|
||||||
|
// );
|
||||||
|
|
||||||
|
register void (*p)() ;
|
||||||
|
p = 0 ;
|
||||||
|
|
||||||
|
if ( pgm_read_byte( (uint16_t)p ) != 0xFF )
|
||||||
|
{
|
||||||
|
(*p)() ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
80
BootLoaders/OrangeMultiBoot/Source/pin_defs.h
Normal file
80
BootLoaders/OrangeMultiBoot/Source/pin_defs.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
|
||||||
|
/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove */
|
||||||
|
#define LED_DDR DDRB
|
||||||
|
#define LED_PORT PORTB
|
||||||
|
#define LED_PIN PINB
|
||||||
|
#define LED PINB5
|
||||||
|
|
||||||
|
/* Ports for soft UART */
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
#define UART_PORT PORTD
|
||||||
|
#define UART_PIN PIND
|
||||||
|
#define UART_DDR DDRD
|
||||||
|
#define UART_TX_BIT 1
|
||||||
|
#define UART_RX_BIT 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__AVR_ATmega8__)
|
||||||
|
//Name conversion R.Wiersma
|
||||||
|
#define UCSR0A UCSRA
|
||||||
|
#define UDR0 UDR
|
||||||
|
#define UDRE0 UDRE
|
||||||
|
#define RXC0 RXC
|
||||||
|
#define FE0 FE
|
||||||
|
#define TIFR1 TIFR
|
||||||
|
#define WDTCSR WDTCR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Luminet support */
|
||||||
|
#if defined(__AVR_ATtiny84__)
|
||||||
|
/* Red LED is connected to pin PA4 */
|
||||||
|
#define LED_DDR DDRA
|
||||||
|
#define LED_PORT PORTA
|
||||||
|
#define LED_PIN PINA
|
||||||
|
#define LED PINA4
|
||||||
|
/* Ports for soft UART - left port only for now. TX/RX on PA2/PA3 */
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
#define UART_PORT PORTA
|
||||||
|
#define UART_PIN PINA
|
||||||
|
#define UART_DDR DDRA
|
||||||
|
#define UART_TX_BIT 2
|
||||||
|
#define UART_RX_BIT 3
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Sanguino support */
|
||||||
|
#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
|
||||||
|
/* Onboard LED is connected to pin PB0 on Sanguino */
|
||||||
|
#define LED_DDR DDRB
|
||||||
|
#define LED_PORT PORTB
|
||||||
|
#define LED_PIN PINB
|
||||||
|
#define LED PINB0
|
||||||
|
|
||||||
|
/* Ports for soft UART */
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
#define UART_PORT PORTD
|
||||||
|
#define UART_PIN PIND
|
||||||
|
#define UART_DDR DDRD
|
||||||
|
#define UART_TX_BIT 1
|
||||||
|
#define UART_RX_BIT 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Mega support */
|
||||||
|
#if defined(__AVR_ATmega1280__)
|
||||||
|
/* Onboard LED is connected to pin PB7 on Arduino Mega */
|
||||||
|
#define LED_DDR DDRB
|
||||||
|
#define LED_PORT PORTB
|
||||||
|
#define LED_PIN PINB
|
||||||
|
#define LED PINB7
|
||||||
|
|
||||||
|
/* Ports for soft UART */
|
||||||
|
#ifdef SOFT_UART
|
||||||
|
#define UART_PORT PORTE
|
||||||
|
#define UART_PIN PINE
|
||||||
|
#define UART_DDR DDRE
|
||||||
|
#define UART_TX_BIT 1
|
||||||
|
#define UART_RX_BIT 0
|
||||||
|
#endif
|
||||||
|
#endif
|
39
BootLoaders/OrangeMultiBoot/Source/stk500.h
Normal file
39
BootLoaders/OrangeMultiBoot/Source/stk500.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* STK500 constants list, from AVRDUDE */
|
||||||
|
#define STK_OK 0x10
|
||||||
|
#define STK_FAILED 0x11 // Not used
|
||||||
|
#define STK_UNKNOWN 0x12 // Not used
|
||||||
|
#define STK_NODEVICE 0x13 // Not used
|
||||||
|
#define STK_INSYNC 0x14 // ' '
|
||||||
|
#define STK_NOSYNC 0x15 // Not used
|
||||||
|
#define ADC_CHANNEL_ERROR 0x16 // Not used
|
||||||
|
#define ADC_MEASURE_OK 0x17 // Not used
|
||||||
|
#define PWM_CHANNEL_ERROR 0x18 // Not used
|
||||||
|
#define PWM_ADJUST_OK 0x19 // Not used
|
||||||
|
#define CRC_EOP 0x20 // 'SPACE'
|
||||||
|
#define STK_GET_SYNC 0x30 // '0'
|
||||||
|
#define STK_GET_SIGN_ON 0x31 // '1'
|
||||||
|
#define STK_SET_PARAMETER 0x40 // '@'
|
||||||
|
#define STK_GET_PARAMETER 0x41 // 'A'
|
||||||
|
#define STK_SET_DEVICE 0x42 // 'B'
|
||||||
|
#define STK_SET_DEVICE_EXT 0x45 // 'E'
|
||||||
|
#define STK_ENTER_PROGMODE 0x50 // 'P'
|
||||||
|
#define STK_LEAVE_PROGMODE 0x51 // 'Q'
|
||||||
|
#define STK_CHIP_ERASE 0x52 // 'R'
|
||||||
|
#define STK_CHECK_AUTOINC 0x53 // 'S'
|
||||||
|
#define STK_LOAD_ADDRESS 0x55 // 'U'
|
||||||
|
#define STK_UNIVERSAL 0x56 // 'V'
|
||||||
|
#define STK_PROG_FLASH 0x60 // '`'
|
||||||
|
#define STK_PROG_DATA 0x61 // 'a'
|
||||||
|
#define STK_PROG_FUSE 0x62 // 'b'
|
||||||
|
#define STK_PROG_LOCK 0x63 // 'c'
|
||||||
|
#define STK_PROG_PAGE 0x64 // 'd'
|
||||||
|
#define STK_PROG_FUSE_EXT 0x65 // 'e'
|
||||||
|
#define STK_READ_FLASH 0x70 // 'p'
|
||||||
|
#define STK_READ_DATA 0x71 // 'q'
|
||||||
|
#define STK_READ_FUSE 0x72 // 'r'
|
||||||
|
#define STK_READ_LOCK 0x73 // 's'
|
||||||
|
#define STK_READ_PAGE 0x74 // 't'
|
||||||
|
#define STK_READ_SIGN 0x75 // 'u'
|
||||||
|
#define STK_READ_OSCCAL 0x76 // 'v'
|
||||||
|
#define STK_READ_FUSE_EXT 0x77 // 'w'
|
||||||
|
#define STK_READ_OSCCAL_EXT 0x78 // 'x'
|
32
BootLoaders/README.md
Normal file
32
BootLoaders/README.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Arduino IDE board definition for Multi 4-in-1 transmitter module
|
||||||
|
At this point the only supported board/module is the Atmega328p-based module, the STM32-based module is not yet supported.
|
||||||
|
|
||||||
|
## Installing
|
||||||
|
The board definition is installed using the Arduino IDE Boards Manager.
|
||||||
|
|
||||||
|
1. Open the Arduino IDE
|
||||||
|
2. Go to File->Preferences (or Ctrl+Comma)
|
||||||
|
3. Locate the 'Aditional Boards Manager URLs' field and paste in this URL: https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module/master/BootLoaders/package_multi_4in1_board_index.json
|
||||||
|
4. Click OK to save the change
|
||||||
|
5. Click Tools->Board [Board Name]->Boards Manager
|
||||||
|
6. Scroll to the bottom of the list of boards and click on 'Multi 4-in-1 Boards' then click the Install button
|
||||||
|
7. Click Close to close the Boards Manager
|
||||||
|
|
||||||
|
## Selecting the board
|
||||||
|
1. Click Tools->Board [Board Name]
|
||||||
|
2. Scroll down the list to 'Multi 4-in-1 Boards' and select 'Multi 4-in-1 (Atmega328p, 3.3V, 16MHz)'
|
||||||
|
|
||||||
|
## Choosing the bootloader
|
||||||
|
There are two bootloader options. The default 'No bootloader' won't install a bootloader, allowing the maximum space for protocols. The 'Flash from TX' option installs a small Optiboot bootloader which is compatible with Ersky9x and OpenTX option to flash firmware from the transmitter's maintenance menu.
|
||||||
|
|
||||||
|
1. Click Tools->Bootloader [Bootloader Option]
|
||||||
|
2. Select the desired bootloader
|
||||||
|
|
||||||
|
**Recommended:** Click Tools->Burn Bootloader to set the fuses, even if the 'No bootloader' option was selected.
|
||||||
|
|
||||||
|
## Compiling / uploading firmware with the 'Flash from TX' bootloader
|
||||||
|
1. Follow the normal compiling method.
|
||||||
|
2. Copy the compiled .hex file (usually Multiprotocol.ino.hex) in the "/firmware" directory of the SD card.
|
||||||
|
3. Start Ersky9x in "Maintenance Mode" by holding the horizontal trims APART while powering on the transmitter.
|
||||||
|
4. Select "Update Multi", then change "File Type" to "HEX", then select "Update", choose the firmware to flash, long pressto select it and long press to flash it.
|
||||||
|
5. When finished, long press EXIT to reboot in normal mode.
|
1
BootLoaders/StmMultiBoot/README.md
Normal file
1
BootLoaders/StmMultiBoot/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
[Source for the StmMultiBooloader](https://github.com/MikeBland/StmMultiBoot)
|
BIN
BootLoaders/StmMultiBoot/StmMultiBoot.bin
Normal file
BIN
BootLoaders/StmMultiBoot/StmMultiBoot.bin
Normal file
Binary file not shown.
2
BootLoaders/StmMultiUSB/README.md
Normal file
2
BootLoaders/StmMultiUSB/README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[Source for the StmMultiUSB=STM32duino-bootloader](https://github.com/rogerclarkmelbourne/STM32duino-bootloader)
|
||||||
|
If you want the latest version, you should look for the file generic_boot20_pa1.bin.
|
BIN
BootLoaders/StmMultiUSB/StmMultiUSB.bin
Normal file
BIN
BootLoaders/StmMultiUSB/StmMultiUSB.bin
Normal file
Binary file not shown.
33
BootLoaders/package_multi_4in1_board_index.json
Normal file
33
BootLoaders/package_multi_4in1_board_index.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "Multi 4-in-1",
|
||||||
|
"maintainer": "Pascal Langer",
|
||||||
|
"websiteURL": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module",
|
||||||
|
"email": "pascal_langer@yahoo.fr",
|
||||||
|
"help": {
|
||||||
|
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"name": "Multi 4-in-1 Boards",
|
||||||
|
"architecture": "avr",
|
||||||
|
"version": "1.0",
|
||||||
|
"category": "Contributed",
|
||||||
|
"help": {
|
||||||
|
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||||
|
},
|
||||||
|
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/raw/master/BootLoaders/package_multi_4in1_board_v1.0.0.zip",
|
||||||
|
"archiveFileName": "package_multi_4in1_board_v1.0.0.zip",
|
||||||
|
"checksum": "SHA-256:61AB463B5B91BCCBF285EB4C801B37E4F46138CA8762E4C04CCB09C2FF157CB7",
|
||||||
|
"size": "3161",
|
||||||
|
"boards": [
|
||||||
|
{"name": "Multi 4-in-1 (Atmega328p, 3.3V, 16MHz)"}
|
||||||
|
],
|
||||||
|
"toolsDependencies": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tools": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
BootLoaders/package_multi_4in1_board_v1.0.0.zip
Normal file
BIN
BootLoaders/package_multi_4in1_board_v1.0.0.zip
Normal file
Binary file not shown.
@ -179,12 +179,26 @@ static void AFHDS2A_build_packet(uint8_t type)
|
|||||||
packet[0] = 0x56;
|
packet[0] = 0x56;
|
||||||
for(uint8_t ch=0; ch<14; ch++)
|
for(uint8_t ch=0; ch<14; ch++)
|
||||||
{
|
{
|
||||||
/*if((Model.limits[ch].flags & CH_FAILSAFE_EN))
|
#ifdef AFHDS2A_FAILSAFE
|
||||||
|
int8_t failsafe = AFHDS2AFailsafe[ch];
|
||||||
|
//
|
||||||
|
if(failsafe != -1)
|
||||||
{
|
{
|
||||||
packet[9 + ch*2] = Servo_data[CH_AETR[ch]] & 0xff;
|
//
|
||||||
packet[10+ ch*2] = (Servo_data[CH_AETR[ch]] >> 8) & 0xff;
|
if (failsafe > AFHDS2AFailsafeMAX)
|
||||||
|
failsafe = AFHDS2AFailsafeMAX;
|
||||||
|
//
|
||||||
|
if (failsafe < AFHDS2AFailsafeMIN)
|
||||||
|
failsafe = AFHDS2AFailsafeMIN;
|
||||||
|
//
|
||||||
|
double scale = (float)failsafe/(float)100;
|
||||||
|
int16_t failsafeMicros = 1500 + ((float)512 * scale);
|
||||||
|
//
|
||||||
|
packet[9 + ch*2] = failsafeMicros & 0xff;
|
||||||
|
packet[10+ ch*2] = ( failsafeMicros >> 8) & 0xff;
|
||||||
}
|
}
|
||||||
else*/
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
packet[9 + ch*2] = 0xff;
|
packet[9 + ch*2] = 0xff;
|
||||||
packet[10+ ch*2] = 0xff;
|
packet[10+ ch*2] = 0xff;
|
||||||
@ -260,6 +274,7 @@ uint16_t ReadAFHDS2A()
|
|||||||
while ((uint16_t)micros()-start < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
|
while ((uint16_t)micros()-start < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
|
||||||
if(!(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
if(!(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
||||||
break;
|
break;
|
||||||
|
A7105_SetPower();
|
||||||
A7105_SetTxRxMode(TXRX_OFF); // Turn LNA off since we are in near range and we want to prevent swamping
|
A7105_SetTxRxMode(TXRX_OFF); // Turn LNA off since we are in near range and we want to prevent swamping
|
||||||
A7105_Strobe(A7105_RX);
|
A7105_Strobe(A7105_RX);
|
||||||
phase &= ~AFHDS2A_WAIT_WRITE;
|
phase &= ~AFHDS2A_WAIT_WRITE;
|
||||||
@ -325,6 +340,7 @@ uint16_t ReadAFHDS2A()
|
|||||||
while ((uint16_t)micros()-start < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
|
while ((uint16_t)micros()-start < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
|
||||||
if(!(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
if(!(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
||||||
break;
|
break;
|
||||||
|
A7105_SetPower();
|
||||||
A7105_SetTxRxMode(RX_EN);
|
A7105_SetTxRxMode(RX_EN);
|
||||||
A7105_Strobe(A7105_RX);
|
A7105_Strobe(A7105_RX);
|
||||||
phase &= ~AFHDS2A_WAIT_WRITE;
|
phase &= ~AFHDS2A_WAIT_WRITE;
|
||||||
|
@ -53,7 +53,11 @@ void ASSAN_send_packet()
|
|||||||
uint16_t temp;
|
uint16_t temp;
|
||||||
for(uint8_t i=0;i<8;i++)
|
for(uint8_t i=0;i<8;i++)
|
||||||
{
|
{
|
||||||
temp=Servo_data[i]<<3;
|
if(mode_select != MODE_SERIAL) // If in PPM mode extend the output to 1000...2000µs
|
||||||
|
temp=convert_channel_16b_nolim(i,1000,2000);
|
||||||
|
else
|
||||||
|
temp=Servo_data[i];
|
||||||
|
temp<<=3;
|
||||||
packet[2*i]=temp>>8;
|
packet[2*i]=temp>>8;
|
||||||
packet[2*i+1]=temp;
|
packet[2*i+1]=temp;
|
||||||
}
|
}
|
||||||
|
@ -25,19 +25,22 @@ Multiprotocol is distributed in the hope that it will be useful,
|
|||||||
#define BAYANG_PACKET_SIZE 15
|
#define BAYANG_PACKET_SIZE 15
|
||||||
#define BAYANG_RF_NUM_CHANNELS 4
|
#define BAYANG_RF_NUM_CHANNELS 4
|
||||||
#define BAYANG_RF_BIND_CHANNEL 0
|
#define BAYANG_RF_BIND_CHANNEL 0
|
||||||
|
#define BAYANG_RF_BIND_CHANNEL_X16_AH 10
|
||||||
#define BAYANG_ADDRESS_LENGTH 5
|
#define BAYANG_ADDRESS_LENGTH 5
|
||||||
|
|
||||||
enum BAYANG_FLAGS {
|
enum BAYANG_FLAGS {
|
||||||
// flags going to packet[2]
|
// flags going to packet[2]
|
||||||
BAYANG_FLAG_RTH = 0x01,
|
BAYANG_FLAG_RTH = 0x01,
|
||||||
BAYANG_FLAG_HEADLESS = 0x02,
|
BAYANG_FLAG_HEADLESS = 0x02,
|
||||||
BAYANG_FLAG_FLIP = 0x08,
|
BAYANG_FLAG_FLIP = 0x08,
|
||||||
BAYANG_FLAG_VIDEO = 0x10,
|
BAYANG_FLAG_VIDEO = 0x10,
|
||||||
BAYANG_FLAG_PICTURE = 0x20,
|
BAYANG_FLAG_PICTURE = 0x20,
|
||||||
// flags going to packet[3]
|
// flags going to packet[3]
|
||||||
BAYANG_FLAG_INVERTED = 0x80 // inverted flight on Floureon H101
|
BAYANG_FLAG_INVERTED = 0x80, // inverted flight on Floureon H101
|
||||||
|
BAYANG_FLAG_TAKE_OFF = 0x20, // take off / landing on X16 AH
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint8_t bayang_bind_chan;
|
||||||
static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
@ -53,13 +56,29 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
|||||||
packet[i+1]=rx_tx_addr[i];
|
packet[i+1]=rx_tx_addr[i];
|
||||||
for(i=0;i<4;i++)
|
for(i=0;i<4;i++)
|
||||||
packet[i+6]=hopping_frequency[i];
|
packet[i+6]=hopping_frequency[i];
|
||||||
packet[10] = rx_tx_addr[0]; // txid[0]
|
switch (sub_protocol)
|
||||||
packet[11] = rx_tx_addr[1]; // txid[1]
|
{
|
||||||
|
case X16_AH:
|
||||||
|
packet[10] = 0x00;
|
||||||
|
packet[11] = 0x00;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
packet[10] = rx_tx_addr[0]; // txid[0]
|
||||||
|
packet[11] = rx_tx_addr[1]; // txid[1]
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint16_t val;
|
uint16_t val;
|
||||||
packet[0] = 0xA5;
|
switch (sub_protocol) {
|
||||||
|
case X16_AH:
|
||||||
|
packet[0] = 0xA6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
packet[0] = 0xA5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
packet[1] = 0xFA; // normal mode is 0xf7, expert 0xfa
|
packet[1] = 0xFA; // normal mode is 0xf7, expert 0xfa
|
||||||
|
|
||||||
//Flags packet[2]
|
//Flags packet[2]
|
||||||
@ -78,7 +97,8 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
|||||||
packet[3] = 0x00;
|
packet[3] = 0x00;
|
||||||
if(Servo_AUX6)
|
if(Servo_AUX6)
|
||||||
packet[3] = BAYANG_FLAG_INVERTED;
|
packet[3] = BAYANG_FLAG_INVERTED;
|
||||||
|
if(Servo_AUX7)
|
||||||
|
packet[3] |= BAYANG_FLAG_TAKE_OFF;
|
||||||
//Aileron
|
//Aileron
|
||||||
val = convert_channel_10b(AILERON);
|
val = convert_channel_10b(AILERON);
|
||||||
packet[4] = (val>>8) + ((val>>2) & 0xFC);
|
packet[4] = (val>>8) + ((val>>2) & 0xFC);
|
||||||
@ -96,13 +116,26 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
|||||||
packet[10] = (val>>8) + (val>>2 & 0xFC);
|
packet[10] = (val>>8) + (val>>2 & 0xFC);
|
||||||
packet[11] = val & 0xFF;
|
packet[11] = val & 0xFF;
|
||||||
}
|
}
|
||||||
packet[12] = rx_tx_addr[2]; // txid[2]
|
switch (sub_protocol)
|
||||||
packet[13] = sub_protocol==H8S3D?0x34:0x0A;
|
{
|
||||||
|
case H8S3D:
|
||||||
|
packet[12] = rx_tx_addr[2]; // txid[2]
|
||||||
|
packet[13] = 0x34;
|
||||||
|
break;
|
||||||
|
case X16_AH:
|
||||||
|
packet[12] = 0;
|
||||||
|
packet[13] = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
packet[12] = rx_tx_addr[2]; // txid[2]
|
||||||
|
packet[13] = 0x0A;
|
||||||
|
break;
|
||||||
|
}
|
||||||
packet[14] = 0;
|
packet[14] = 0;
|
||||||
for (uint8_t i=0; i < BAYANG_PACKET_SIZE-1; i++)
|
for (uint8_t i=0; i < BAYANG_PACKET_SIZE-1; i++)
|
||||||
packet[14] += packet[i];
|
packet[14] += packet[i];
|
||||||
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? BAYANG_RF_BIND_CHANNEL:hopping_frequency[hopping_frequency_no++]);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? bayang_bind_chan:hopping_frequency[hopping_frequency_no++]);
|
||||||
hopping_frequency_no%=BAYANG_RF_NUM_CHANNELS;
|
hopping_frequency_no%=BAYANG_RF_NUM_CHANNELS;
|
||||||
|
|
||||||
// clear packet status bits and TX FIFO
|
// clear packet status bits and TX FIFO
|
||||||
@ -111,17 +144,16 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
|||||||
|
|
||||||
XN297_WritePayload(packet, BAYANG_PACKET_SIZE);
|
XN297_WritePayload(packet, BAYANG_PACKET_SIZE);
|
||||||
|
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
|
|
||||||
// Power on, TX mode, 2byte CRC
|
// Power on, TX mode, 2byte CRC
|
||||||
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
||||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||||
|
|
||||||
#ifdef BAYANG_HUB_TELEMETRY
|
#ifdef BAYANG_HUB_TELEMETRY
|
||||||
if (option)
|
if (option)
|
||||||
{ // switch radio to rx as soon as packet is sent
|
{ // switch radio to rx as soon as packet is sent
|
||||||
|
|
||||||
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)));
|
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)));
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x03);
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x03);
|
||||||
}
|
}
|
||||||
@ -131,7 +163,7 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BAYANG_HUB_TELEMETRY
|
#ifdef BAYANG_HUB_TELEMETRY
|
||||||
static void __attribute__((unused)) check_rx(void)
|
static void __attribute__((unused)) BAYANG_check_rx(void)
|
||||||
{
|
{
|
||||||
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
{ // data received from model
|
{ // data received from model
|
||||||
@ -171,16 +203,16 @@ static void __attribute__((unused)) BAYANG_init()
|
|||||||
|
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
NRF24L01_FlushRx();
|
NRF24L01_FlushRx();
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, BAYANG_PACKET_SIZE);
|
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, BAYANG_PACKET_SIZE);
|
||||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||||
NRF24L01_SetPower();
|
NRF24L01_SetPower();
|
||||||
NRF24L01_Activate(0x73); // Activate feature register
|
NRF24L01_Activate(0x73); // Activate feature register
|
||||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||||
NRF24L01_Activate(0x73);
|
NRF24L01_Activate(0x73);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t BAYANG_callback()
|
uint16_t BAYANG_callback()
|
||||||
@ -204,7 +236,7 @@ uint16_t BAYANG_callback()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (packet_count > 1)
|
if (packet_count > 1)
|
||||||
check_rx();
|
BAYANG_check_rx();
|
||||||
|
|
||||||
packet_count %= 5;
|
packet_count %= 5;
|
||||||
}
|
}
|
||||||
@ -251,10 +283,18 @@ uint16_t initBAYANG(void)
|
|||||||
BAYANG_initialize_txid();
|
BAYANG_initialize_txid();
|
||||||
BAYANG_init();
|
BAYANG_init();
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
#ifdef BAYANG_HUB_TELEMETRY
|
switch (sub_protocol) {
|
||||||
init_frskyd_link_telemetry();
|
case X16_AH:
|
||||||
telemetry_lost=1; // do not send telemetry to TX right away until we have a TX_RSSI value to prevent warning message...
|
bayang_bind_chan = BAYANG_RF_BIND_CHANNEL_X16_AH;
|
||||||
#endif
|
break;
|
||||||
|
default:
|
||||||
|
bayang_bind_chan = BAYANG_RF_BIND_CHANNEL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef BAYANG_HUB_TELEMETRY
|
||||||
|
init_frskyd_link_telemetry();
|
||||||
|
telemetry_lost=1; // do not send telemetry to TX right away until we have a TX_RSSI value to prevent warning message...
|
||||||
|
#endif
|
||||||
return BAYANG_INITIAL_WAIT+BAYANG_PACKET_PERIOD;
|
return BAYANG_INITIAL_WAIT+BAYANG_PACKET_PERIOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,33 +24,34 @@ Multiprotocol is distributed in the hope that it will be useful,
|
|||||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// The Receiver for this protocol is available at: https://github.com/soligen2010/RC_RX_CABELL_V3_FHSS
|
// The Receiver for this protocol is available at: https://github.com/soligen2010/RC_RX_CABELL_V3_FHSS
|
||||||
|
|
||||||
|
|
||||||
#if defined(CABELL_NRF24L01_INO)
|
#if defined(CABELL_NRF24L01_INO)
|
||||||
|
|
||||||
#include "iface_nrf24l01.h"
|
#include "iface_nrf24l01.h"
|
||||||
|
|
||||||
#define CABELL_BIND_COUNT 2000 // At least 2000 so that if TX toggles the serial bind flag then bind mode is never exited
|
#define CABELL_BIND_COUNT 2000 // At least 2000 so that if TX toggles the serial bind flag then bind mode is never exited
|
||||||
#define CABELL_PACKET_PERIOD 3000 // Do not set too low or else next packet may not be finished transmitting before the channel is changed next time around
|
#define CABELL_PACKET_PERIOD 3000 // Do not set too low or else next packet may not be finished transmitting before the channel is changed next time around
|
||||||
|
|
||||||
#define CABELL_NUM_CHANNELS 16 // The maximum number of RC channels that can be sent in one packet
|
#define CABELL_NUM_CHANNELS 16 // The maximum number of RC channels that can be sent in one packet
|
||||||
#define CABELL_MIN_CHANNELS 4 // The minimum number of channels that must be included in a packet, the number of channels cannot be reduced any further than this
|
#define CABELL_MIN_CHANNELS 4 // The minimum number of channels that must be included in a packet, the number of channels cannot be reduced any further than this
|
||||||
#define CABELL_PAYLOAD_BYTES 24 // 12 bits per value * 16 channels
|
#define CABELL_PAYLOAD_BYTES 24 // 12 bits per value * 16 channels
|
||||||
|
|
||||||
#define CABELL_RADIO_CHANNELS 9 // This is 1/5 of the total number of radio channels used for FHSS
|
#define CABELL_RADIO_CHANNELS 9 // This is 1/5 of the total number of radio channels used for FHSS
|
||||||
#define CABELL_RADIO_MIN_CHANNEL_NUM 3 // Channel 0 is right on the boarder of allowed frequency range, so move up to avoid bleeding over
|
#define CABELL_RADIO_MIN_CHANNEL_NUM 3 // Channel 0 is right on the boarder of allowed frequency range, so move up to avoid bleeding over
|
||||||
#define CABELL_TELEMETRY_PACKET_LENGTH 4
|
#define CABELL_TELEMETRY_PACKET_LENGTH 4
|
||||||
|
|
||||||
#define CABELL_BIND_RADIO_ADDR 0xA4B7C123F7LL
|
#define CABELL_BIND_RADIO_ADDR 0xA4B7C123F7LL
|
||||||
|
|
||||||
#define CABELL_OPTION_MASK_CHANNEL_REDUCTION 0x0F
|
#define CABELL_OPTION_MASK_CHANNEL_REDUCTION 0x0F
|
||||||
#define CABELL_OPTION_MASK_RECIEVER_OUTPUT_MODE 0x30
|
#define CABELL_OPTION_MASK_RECIEVER_OUTPUT_MODE 0x30
|
||||||
#define CABELL_OPTION_SHIFT_RECIEVER_OUTPUT_MODE 4
|
#define CABELL_OPTION_SHIFT_RECIEVER_OUTPUT_MODE 4
|
||||||
#define CABELL_OPTION_MASK_MAX_POWER_OVERRIDE 0x40
|
#define CABELL_OPTION_MASK_MAX_POWER_OVERRIDE 0x40
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
enum RxMode_t : uint8_t { // Note bit 8 is used to indicate if the packet is the first of 2 on the channel. Mask out this bit before using the enum
|
{
|
||||||
|
enum RxMode_t : uint8_t
|
||||||
|
{ // Note bit 8 is used to indicate if the packet is the first of 2 on the channel. Mask out this bit before using the enum
|
||||||
normal = 0,
|
normal = 0,
|
||||||
bind = 1,
|
bind = 1,
|
||||||
setFailSafe = 2,
|
setFailSafe = 2,
|
||||||
@ -58,8 +59,8 @@ typedef struct {
|
|||||||
telemetryResponse = 4,
|
telemetryResponse = 4,
|
||||||
unBind = 127
|
unBind = 127
|
||||||
} RxMode;
|
} RxMode;
|
||||||
uint8_t reserved = 0;
|
uint8_t reserved = 0;
|
||||||
uint8_t option;
|
uint8_t option;
|
||||||
/* mask 0x0F : Channel reduction. The number of channels to not send (subtracted from the 16 max channels) at least 4 are always sent
|
/* mask 0x0F : Channel reduction. The number of channels to not send (subtracted from the 16 max channels) at least 4 are always sent
|
||||||
* mask 0x30>>4 : Receiver output mode
|
* mask 0x30>>4 : Receiver output mode
|
||||||
* 0 (00) = Single PPM on individual pins for each channel
|
* 0 (00) = Single PPM on individual pins for each channel
|
||||||
@ -69,293 +70,315 @@ typedef struct {
|
|||||||
* mask 0x40>>6 Contains max power override flag for Multi-protocol TX module. Also sent to RX
|
* mask 0x40>>6 Contains max power override flag for Multi-protocol TX module. Also sent to RX
|
||||||
* mask 0x80>>7 Unused
|
* mask 0x80>>7 Unused
|
||||||
*/
|
*/
|
||||||
uint8_t modelNum;
|
uint8_t modelNum;
|
||||||
uint8_t checkSum_LSB;
|
uint8_t checkSum_LSB;
|
||||||
uint8_t checkSum_MSB;
|
uint8_t checkSum_MSB;
|
||||||
uint8_t payloadValue [CABELL_PAYLOAD_BYTES] = {0}; //12 bits per channel value, unsigned
|
uint8_t payloadValue [CABELL_PAYLOAD_BYTES] = {0}; //12 bits per channel value, unsigned
|
||||||
} CABELL_RxTxPacket_t;
|
} CABELL_RxTxPacket_t;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
static uint8_t __attribute__((unused)) CABELL_getNextChannel (uint8_t seqArray[], uint8_t seqArraySize, uint8_t prevChannel) {
|
static uint8_t __attribute__((unused)) CABELL_getNextChannel (uint8_t seqArray[], uint8_t seqArraySize, uint8_t prevChannel)
|
||||||
/* Possible channels are in 5 bands, each band comprised of seqArraySize channels
|
{
|
||||||
* seqArray contains seqArraySize elements in the relative order in which we should progress through the band
|
/* Possible channels are in 5 bands, each band comprised of seqArraySize channels
|
||||||
*
|
* seqArray contains seqArraySize elements in the relative order in which we should progress through the band
|
||||||
* Each time the channel is changes, bands change in a way so that the next channel will be in a
|
*
|
||||||
* different non-adjacent band. Both the band changes and the index in seqArray is incremented.
|
* Each time the channel is changes, bands change in a way so that the next channel will be in a
|
||||||
*/
|
* different non-adjacent band. Both the band changes and the index in seqArray is incremented.
|
||||||
prevChannel -= CABELL_RADIO_MIN_CHANNEL_NUM; // Subtract CABELL_RADIO_MIN_CHANNEL_NUM because it was added to the return value
|
*/
|
||||||
prevChannel = constrain(prevChannel,0,(seqArraySize * 5) ); // Constrain the values just in case something bogus was sent in.
|
prevChannel -= CABELL_RADIO_MIN_CHANNEL_NUM; // Subtract CABELL_RADIO_MIN_CHANNEL_NUM because it was added to the return value
|
||||||
|
if(prevChannel>(seqArraySize * 5))
|
||||||
uint8_t currBand = prevChannel / seqArraySize;
|
prevChannel=seqArraySize * 5; // Constrain the values just in case something bogus was sent in.
|
||||||
uint8_t nextBand = (currBand + 3) % 5;
|
|
||||||
|
|
||||||
uint8_t prevChannalSeqArrayValue = prevChannel % seqArraySize;
|
uint8_t currBand = prevChannel / seqArraySize;
|
||||||
uint8_t prevChannalSeqArrayPosition = 0;
|
uint8_t nextBand = (currBand + 3) % 5;
|
||||||
for (int x = 0; x < seqArraySize; x++) { // Find the position of the previous channel in the array
|
|
||||||
if (seqArray[x] == prevChannalSeqArrayValue) {
|
|
||||||
prevChannalSeqArrayPosition = x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint8_t nextChannalSeqArrayPosition = prevChannalSeqArrayPosition + 1;
|
|
||||||
if (nextChannalSeqArrayPosition >= seqArraySize) nextChannalSeqArrayPosition = 0;
|
|
||||||
|
|
||||||
return (seqArraySize * nextBand) + seqArray[nextChannalSeqArrayPosition] + CABELL_RADIO_MIN_CHANNEL_NUM; // Add CABELL_RADIO_MIN_CHANNEL_NUM so we dont use channel 0 as it may bleed below 2.400 GHz
|
uint8_t prevChannalSeqArrayValue = prevChannel % seqArraySize;
|
||||||
|
uint8_t prevChannalSeqArrayPosition = 0;
|
||||||
|
for (int x = 0; x < seqArraySize; x++)
|
||||||
|
{ // Find the position of the previous channel in the array
|
||||||
|
if (seqArray[x] == prevChannalSeqArrayValue)
|
||||||
|
prevChannalSeqArrayPosition = x;
|
||||||
|
}
|
||||||
|
uint8_t nextChannalSeqArrayPosition = prevChannalSeqArrayPosition + 1;
|
||||||
|
if (nextChannalSeqArrayPosition >= seqArraySize)
|
||||||
|
nextChannalSeqArrayPosition = 0;
|
||||||
|
|
||||||
|
return (seqArraySize * nextBand) + seqArray[nextChannalSeqArrayPosition] + CABELL_RADIO_MIN_CHANNEL_NUM; // Add CABELL_RADIO_MIN_CHANNEL_NUM so we dont use channel 0 as it may bleed below 2.400 GHz
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
#if defined TELEMETRY
|
#if defined CABELL_HUB_TELEMETRY
|
||||||
static void __attribute__((unused)) CABELL_get_telemetry()
|
static void __attribute__((unused)) CABELL_get_telemetry()
|
||||||
{
|
{
|
||||||
// calculate TX rssi based on past 250 expected telemetry packets. Cannot use full second count because telemetry_counter is not large enough
|
// calculate TX rssi based on past 250 expected telemetry packets. Cannot use full second count because telemetry_counter is not large enough
|
||||||
state++;
|
state++;
|
||||||
if (state > 250)
|
if (state > 250)
|
||||||
{
|
{
|
||||||
TX_RSSI = telemetry_counter;
|
TX_RSSI = telemetry_counter;
|
||||||
telemetry_counter = 0;
|
telemetry_counter = 0;
|
||||||
state = 0;
|
state = 0;
|
||||||
telemetry_lost=0;
|
telemetry_lost=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process incoming telemetry packet of it was received
|
// Process incoming telemetry packet of it was received
|
||||||
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { // data received from model
|
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
NRF24L01_ReadPayload(packet, CABELL_TELEMETRY_PACKET_LENGTH);
|
{ // data received from model
|
||||||
if ((packet[0] & 0x7F) == CABELL_RxTxPacket_t::RxMode_t::telemetryResponse) // ignore high order bit in compare because it toggles with each packet
|
NRF24L01_ReadPayload(packet, CABELL_TELEMETRY_PACKET_LENGTH);
|
||||||
{
|
if ((packet[0] & 0x7F) == CABELL_RxTxPacket_t::RxMode_t::telemetryResponse) // ignore high order bit in compare because it toggles with each packet
|
||||||
RX_RSSI = packet[1]; // Packet rate 0 to 255 where 255 is 100% packet rate
|
{
|
||||||
v_lipo1 = packet[2]; // Directly from analog input of receiver, but reduced to 8-bit depth (0 to 255). Scaling depends on the input to the analog pin of the receiver.
|
RX_RSSI = packet[1]; // Packet rate 0 to 255 where 255 is 100% packet rate
|
||||||
v_lipo2 = packet[3]; // Directly from analog input of receiver, but reduced to 8-bit depth (0 to 255). Scaling depends on the input to the analog pin of the receiver.
|
v_lipo1 = packet[2]; // Directly from analog input of receiver, but reduced to 8-bit depth (0 to 255). Scaling depends on the input to the analog pin of the receiver.
|
||||||
telemetry_counter++;
|
v_lipo2 = packet[3]; // Directly from analog input of receiver, but reduced to 8-bit depth (0 to 255). Scaling depends on the input to the analog pin of the receiver.
|
||||||
if(telemetry_lost==0) telemetry_link=1;
|
telemetry_counter++;
|
||||||
}
|
if(telemetry_lost==0)
|
||||||
} else {
|
telemetry_link=1;
|
||||||
// If no telemetry packet was received then delay by the typical telemetry packet processing time
|
}
|
||||||
// This is done to try to keep the sendPacket process timing more consistent. Since the SPI payload read takes some time
|
}
|
||||||
delayMicroseconds(50);
|
else
|
||||||
}
|
{
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
// If no telemetry packet was received then delay by the typical telemetry packet processing time
|
||||||
NRF24L01_FlushRx();
|
// This is done to try to keep the sendPacket process timing more consistent. Since the SPI payload read takes some time
|
||||||
|
delayMicroseconds(50);
|
||||||
|
}
|
||||||
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
|
NRF24L01_FlushRx();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode)
|
static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode)
|
||||||
{
|
{
|
||||||
#if defined TELEMETRY
|
#if defined CABELL_HUB_TELEMETRY
|
||||||
if (!bindMode && (sub_protocol == CABELL_V3_TELEMETRY)) { // check for incoming packet and switch radio back to TX mode if we were listening for telemetry
|
if (!bindMode && (sub_protocol == CABELL_V3_TELEMETRY)) // check for incoming packet and switch radio back to TX mode if we were listening for telemetry
|
||||||
CABELL_get_telemetry();
|
CABELL_get_telemetry();
|
||||||
}
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
CABELL_RxTxPacket_t TxPacket;
|
CABELL_RxTxPacket_t TxPacket;
|
||||||
|
|
||||||
uint8_t channelReduction = constrain((option & CABELL_OPTION_MASK_CHANNEL_REDUCTION),0,CABELL_NUM_CHANNELS-CABELL_MIN_CHANNELS); // Max 12 - cannot reduce below 4 channels
|
uint8_t channelReduction = constrain((option & CABELL_OPTION_MASK_CHANNEL_REDUCTION),0,CABELL_NUM_CHANNELS-CABELL_MIN_CHANNELS); // Max 12 - cannot reduce below 4 channels
|
||||||
if (bindMode) {
|
if (bindMode)
|
||||||
channelReduction = 0; // Send full packet to bind as higher channels will contain bind info
|
channelReduction = 0; // Send full packet to bind as higher channels will contain bind info
|
||||||
}
|
|
||||||
uint8_t packetSize = sizeof(TxPacket) - ((((channelReduction - (channelReduction%2))/ 2)) * 3); // reduce 3 bytes per 2 channels, but not last channel if it is odd
|
|
||||||
uint8_t maxPayloadValueIndex = sizeof(TxPacket.payloadValue) - (sizeof(TxPacket) - packetSize);
|
|
||||||
|
|
||||||
if ((sub_protocol == CABELL_UNBIND) && !bindMode) {
|
uint8_t packetSize = sizeof(TxPacket) - ((((channelReduction - (channelReduction%2))/ 2)) * 3); // reduce 3 bytes per 2 channels, but not last channel if it is odd
|
||||||
TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::unBind;
|
uint8_t maxPayloadValueIndex = sizeof(TxPacket.payloadValue) - (sizeof(TxPacket) - packetSize);
|
||||||
TxPacket.option = option;
|
|
||||||
} else {
|
|
||||||
if (sub_protocol == CABELL_SET_FAIL_SAFE && !bindMode) {
|
|
||||||
TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::setFailSafe;
|
|
||||||
} else {
|
|
||||||
if (bindMode) {
|
|
||||||
TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::bind;
|
|
||||||
} else {
|
|
||||||
switch (sub_protocol) {
|
|
||||||
case CABELL_V3_TELEMETRY : TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::normalWithTelemetry;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default : TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::normal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TxPacket.option = (bindMode) ? (option & (~CABELL_OPTION_MASK_CHANNEL_REDUCTION)) : option; //remove channel reduction if in bind mode
|
|
||||||
}
|
|
||||||
TxPacket.reserved = 0;
|
|
||||||
TxPacket.modelNum = RX_num;
|
|
||||||
uint16_t checkSum = TxPacket.modelNum + TxPacket.option + TxPacket.RxMode + TxPacket.reserved; // Start Calculate checksum
|
|
||||||
|
|
||||||
int adjusted_x;
|
if ((sub_protocol == CABELL_UNBIND) && !bindMode)
|
||||||
int payloadIndex = 0;
|
{
|
||||||
uint16_t holdValue;
|
TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::unBind;
|
||||||
|
TxPacket.option = option;
|
||||||
for (int x = 0;(x < CABELL_NUM_CHANNELS - channelReduction); x++) {
|
}
|
||||||
switch (x) {
|
else
|
||||||
case 0 : adjusted_x = ELEVATOR; break;
|
{
|
||||||
case 1 : adjusted_x = AILERON; break;
|
if (sub_protocol == CABELL_SET_FAIL_SAFE && !bindMode)
|
||||||
case 2 : adjusted_x = RUDDER; break;
|
TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::setFailSafe;
|
||||||
case 3 : adjusted_x = THROTTLE; break;
|
else
|
||||||
default : adjusted_x = x; break;
|
{
|
||||||
}
|
if (bindMode)
|
||||||
holdValue = map(limit_channel_100(adjusted_x),servo_min_100,servo_max_100,1000,2000); // valid channel values are 1000 to 2000
|
TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::bind;
|
||||||
if (bindMode) {
|
else
|
||||||
switch (adjusted_x) {
|
{
|
||||||
case THROTTLE : holdValue = 1000; break; // always set throttle to off when binding for safety
|
switch (sub_protocol)
|
||||||
//tx address sent for bind
|
{
|
||||||
case 11 : holdValue = 1000 + rx_tx_addr[0]; break;
|
case CABELL_V3_TELEMETRY:
|
||||||
case 12 : holdValue = 1000 + rx_tx_addr[1]; break;
|
TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::normalWithTelemetry;
|
||||||
case 13 : holdValue = 1000 + rx_tx_addr[2]; break;
|
break;
|
||||||
case 14 : holdValue = 1000 + rx_tx_addr[3]; break;
|
default:
|
||||||
case 15 : holdValue = 1000 + rx_tx_addr[4]; break;
|
TxPacket.RxMode = CABELL_RxTxPacket_t::RxMode_t::normal;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TxPacket.option = (bindMode) ? (option & (~CABELL_OPTION_MASK_CHANNEL_REDUCTION)) : option; //remove channel reduction if in bind mode
|
||||||
|
}
|
||||||
|
TxPacket.reserved = 0;
|
||||||
|
TxPacket.modelNum = RX_num;
|
||||||
|
uint16_t checkSum = TxPacket.modelNum + TxPacket.option + TxPacket.RxMode + TxPacket.reserved; // Start Calculate checksum
|
||||||
|
|
||||||
// use 12 bits per value
|
int adjusted_x;
|
||||||
if (x % 2) { //output channel number is ODD
|
int payloadIndex = 0;
|
||||||
holdValue = holdValue<<4;
|
uint16_t holdValue;
|
||||||
payloadIndex--;
|
|
||||||
} else {
|
|
||||||
holdValue &= 0x0FFF;
|
|
||||||
}
|
|
||||||
TxPacket.payloadValue[payloadIndex] |= (uint8_t)(holdValue & 0x00FF);
|
|
||||||
payloadIndex++;
|
|
||||||
TxPacket.payloadValue[payloadIndex] |= (uint8_t)((holdValue>>8) & 0x00FF);
|
|
||||||
payloadIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int x = 0; x < maxPayloadValueIndex ; x++) {
|
|
||||||
checkSum += TxPacket.payloadValue[x]; // Finish Calculate checksum
|
|
||||||
}
|
|
||||||
|
|
||||||
TxPacket.checkSum_MSB = checkSum >> 8;
|
for (int x = 0;(x < CABELL_NUM_CHANNELS - channelReduction); x++)
|
||||||
TxPacket.checkSum_LSB = checkSum & 0x00FF;
|
{
|
||||||
|
switch (x)
|
||||||
|
{
|
||||||
|
case 0 : adjusted_x = ELEVATOR; break;
|
||||||
|
case 1 : adjusted_x = AILERON; break;
|
||||||
|
case 2 : adjusted_x = RUDDER; break;
|
||||||
|
case 3 : adjusted_x = THROTTLE; break;
|
||||||
|
default : adjusted_x = x; break;
|
||||||
|
}
|
||||||
|
holdValue = map(limit_channel_100(adjusted_x),servo_min_100,servo_max_100,1000,2000); // valid channel values are 1000 to 2000
|
||||||
|
if (bindMode)
|
||||||
|
{
|
||||||
|
switch (adjusted_x)
|
||||||
|
{
|
||||||
|
case THROTTLE : holdValue = 1000; break; // always set throttle to off when binding for safety
|
||||||
|
//tx address sent for bind
|
||||||
|
case 11 : holdValue = 1000 + rx_tx_addr[0]; break;
|
||||||
|
case 12 : holdValue = 1000 + rx_tx_addr[1]; break;
|
||||||
|
case 13 : holdValue = 1000 + rx_tx_addr[2]; break;
|
||||||
|
case 14 : holdValue = 1000 + rx_tx_addr[3]; break;
|
||||||
|
case 15 : holdValue = 1000 + rx_tx_addr[4]; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set channel for next transmission
|
// use 12 bits per value
|
||||||
rf_ch_num = CABELL_getNextChannel (hopping_frequency,CABELL_RADIO_CHANNELS, rf_ch_num);
|
if (x % 2)
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH,rf_ch_num);
|
{ //output channel number is ODD
|
||||||
|
holdValue = holdValue<<4;
|
||||||
|
payloadIndex--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
holdValue &= 0x0FFF;
|
||||||
|
TxPacket.payloadValue[payloadIndex] |= (uint8_t)(holdValue & 0x00FF);
|
||||||
|
payloadIndex++;
|
||||||
|
TxPacket.payloadValue[payloadIndex] |= (uint8_t)((holdValue>>8) & 0x00FF);
|
||||||
|
payloadIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
//NRF24L01_FlushTx(); //just in case things got hung up
|
for(int x = 0; x < maxPayloadValueIndex ; x++)
|
||||||
//NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
checkSum += TxPacket.payloadValue[x]; // Finish Calculate checksum
|
||||||
|
|
||||||
uint8_t* p = reinterpret_cast<uint8_t*>(&TxPacket.RxMode);
|
|
||||||
*p &= 0x7F; // Make sure 8th bit is clear
|
|
||||||
*p |= (packet_count++)<<7; // This causes the 8th bit of the first byte to toggle with each xmit so consecutive payloads are not identical.
|
|
||||||
// This is a work around for a reported bug in clone NRF24L01 chips that mis-took this case for a re-transmit of the same packet.
|
|
||||||
|
|
||||||
CABELL_SetPower();
|
TxPacket.checkSum_MSB = checkSum >> 8;
|
||||||
NRF24L01_WritePayload((uint8_t*)&TxPacket, packetSize);
|
TxPacket.checkSum_LSB = checkSum & 0x00FF;
|
||||||
|
|
||||||
#if defined TELEMETRY
|
// Set channel for next transmission
|
||||||
if (!bindMode && (sub_protocol == CABELL_V3_TELEMETRY)) { // switch radio to rx as soon as packet is sent
|
rf_ch_num = CABELL_getNextChannel (hopping_frequency,CABELL_RADIO_CHANNELS, rf_ch_num);
|
||||||
// calculate transmit time based on packet size and data rate of 1MB per sec
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH,rf_ch_num);
|
||||||
// This is done because polling the status register during xmit caused issues.
|
|
||||||
// bits = packst_size * 8 + 73 bits overhead
|
//NRF24L01_FlushTx(); //just in case things got hung up
|
||||||
// at 250 Kbs per sec, one bit is 4 uS
|
//NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||||
// then add 140 uS which is 130 uS to begin the xmit and 10 uS fudge factor
|
|
||||||
delayMicroseconds(((((unsigned long)packetSize * 8ul) + 73ul) * 4ul) + 140ul) ;
|
uint8_t* p = reinterpret_cast<uint8_t*>(&TxPacket.RxMode);
|
||||||
packet_period = CABELL_PACKET_PERIOD + (constrain(((int16_t)(CABELL_NUM_CHANNELS - channelReduction) - (int16_t)6 ),(int16_t)0 ,(int16_t)10 ) * (int16_t)100); // increase packet period by 100 us for each channel over 6
|
*p &= 0x7F; // Make sure 8th bit is clear
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0F); // RX mode with 16 bit CRC
|
*p |= (packet_count++)<<7; // This causes the 8th bit of the first byte to toggle with each xmit so consecutive payloads are not identical.
|
||||||
} else
|
// This is a work around for a reported bug in clone NRF24L01 chips that mis-took this case for a re-transmit of the same packet.
|
||||||
#endif
|
|
||||||
packet_period = CABELL_PACKET_PERIOD; // Standard packet period when not in telemetry mode.
|
CABELL_SetPower();
|
||||||
|
NRF24L01_WritePayload((uint8_t*)&TxPacket, packetSize);
|
||||||
|
|
||||||
|
#if defined CABELL_HUB_TELEMETRY
|
||||||
|
if (!bindMode && (sub_protocol == CABELL_V3_TELEMETRY))
|
||||||
|
{ // switch radio to rx as soon as packet is sent
|
||||||
|
// calculate transmit time based on packet size and data rate of 1MB per sec
|
||||||
|
// This is done because polling the status register during xmit caused issues.
|
||||||
|
// bits = packst_size * 8 + 73 bits overhead
|
||||||
|
// at 250 Kbs per sec, one bit is 4 uS
|
||||||
|
// then add 140 uS which is 130 uS to begin the xmit and 10 uS fudge factor
|
||||||
|
delayMicroseconds(((((unsigned long)packetSize * 8ul) + 73ul) * 4ul) + 140ul) ;
|
||||||
|
packet_period = CABELL_PACKET_PERIOD + (constrain(((int16_t)(CABELL_NUM_CHANNELS - channelReduction) - (int16_t)6 ),(int16_t)0 ,(int16_t)10 ) * (int16_t)100); // increase packet period by 100 us for each channel over 6
|
||||||
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0F); // RX mode with 16 bit CRC
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
packet_period = CABELL_PACKET_PERIOD; // Standard packet period when not in telemetry mode.
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
static void __attribute__((unused)) CABELL_getChannelSequence (uint8_t outArray[], uint8_t numChannels, uint64_t permutation) {
|
static void __attribute__((unused)) CABELL_getChannelSequence (uint8_t outArray[], uint8_t numChannels, uint64_t permutation)
|
||||||
/* This procedure initializes an array with the sequence progression of channels.
|
{
|
||||||
* This is not the actual channels itself, but the sequence base to be used within bands of
|
/* This procedure initializes an array with the sequence progression of channels.
|
||||||
* channels.
|
* This is not the actual channels itself, but the sequence base to be used within bands of
|
||||||
*
|
* channels.
|
||||||
* There are numChannels! permutations for arranging the channels
|
*
|
||||||
* one of these permutations will be calculated based on the permutation input
|
* There are numChannels! permutations for arranging the channels
|
||||||
* permutation should be between 1 and numChannels! but the routine will constrain it
|
* one of these permutations will be calculated based on the permutation input
|
||||||
* if these bounds are exceeded. Typically the radio's unique TX ID should be used.
|
* permutation should be between 1 and numChannels! but the routine will constrain it
|
||||||
*
|
* if these bounds are exceeded. Typically the radio's unique TX ID should be used.
|
||||||
* The maximum numChannels is 20. Anything larger than this will cause the uint64_t
|
*
|
||||||
* variables to overflow, yielding unknown results (possibly infinite loop?). Therefor
|
* The maximum numChannels is 20. Anything larger than this will cause the uint64_t
|
||||||
* this routine constrains the value.
|
* variables to overflow, yielding unknown results (possibly infinite loop?). Therefor
|
||||||
*/
|
* this routine constrains the value.
|
||||||
uint64_t i; //iterator counts numChannels
|
*/
|
||||||
uint64_t indexOfNextSequenceValue;
|
uint8_t i; //iterator counts numChannels
|
||||||
uint64_t numChannelsFactorial=1;
|
uint64_t indexOfNextSequenceValue;
|
||||||
uint8_t sequenceValue;
|
uint64_t numChannelsFactorial=1;
|
||||||
|
uint8_t sequenceValue;
|
||||||
|
|
||||||
numChannels = constrain(numChannels,1,20);
|
numChannels = constrain(numChannels,1,20);
|
||||||
|
|
||||||
for (i = 1; i <= numChannels;i++) {
|
for (i = 1; i <= numChannels;i++)
|
||||||
numChannelsFactorial *= i; // Calculate n!
|
{
|
||||||
outArray[i-1] = i-1; // Initialize array with the sequence
|
numChannelsFactorial *= i; // Calculate n!
|
||||||
}
|
outArray[i-1] = i-1; // Initialize array with the sequence
|
||||||
|
}
|
||||||
permutation = (permutation % numChannelsFactorial) + 1; // permutation must be between 1 and n! or this algorithm will infinite loop
|
|
||||||
|
|
||||||
//Rearrange the array elements based on the permutation selected
|
permutation = (permutation % numChannelsFactorial) + 1; // permutation must be between 1 and n! or this algorithm will infinite loop
|
||||||
for (i=0, permutation--; i<numChannels; i++ ) {
|
|
||||||
numChannelsFactorial /= ((uint64_t)numChannels)-i;
|
//Rearrange the array elements based on the permutation selected
|
||||||
indexOfNextSequenceValue = i+(permutation/numChannelsFactorial);
|
for (i=0, permutation--; i<numChannels; i++ )
|
||||||
permutation %= numChannelsFactorial;
|
{
|
||||||
|
numChannelsFactorial /= ((uint64_t)numChannels)-i;
|
||||||
//Copy the value in the selected array position
|
indexOfNextSequenceValue = i+(permutation/numChannelsFactorial);
|
||||||
sequenceValue = outArray[indexOfNextSequenceValue];
|
permutation %= numChannelsFactorial;
|
||||||
|
|
||||||
//Shift the unused elements in the array to make room to move in the one just selected
|
//Copy the value in the selected array position
|
||||||
for( ; indexOfNextSequenceValue > i; indexOfNextSequenceValue--) {
|
sequenceValue = outArray[indexOfNextSequenceValue];
|
||||||
outArray[indexOfNextSequenceValue] = outArray[indexOfNextSequenceValue-1];
|
|
||||||
}
|
//Shift the unused elements in the array to make room to move in the one just selected
|
||||||
// Copy the selected value into it's new array slot
|
for( ; indexOfNextSequenceValue > i; indexOfNextSequenceValue--)
|
||||||
outArray[i] = sequenceValue;
|
outArray[indexOfNextSequenceValue] = outArray[indexOfNextSequenceValue-1];
|
||||||
}
|
|
||||||
|
// Copy the selected value into it's new array slot
|
||||||
|
outArray[i] = sequenceValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
static void __attribute__((unused)) CABELL_setAddress()
|
static void __attribute__((unused)) CABELL_setAddress()
|
||||||
{
|
{
|
||||||
uint64_t CABELL_addr;
|
uint64_t CABELL_addr;
|
||||||
|
|
||||||
// Serial.print("NORM ID: ");Serial.print((uint32_t)(CABELL_normal_addr>>32)); Serial.print(" ");Serial.println((uint32_t)((CABELL_normal_addr<<32)>>32));
|
// Serial.print("NORM ID: ");Serial.print((uint32_t)(CABELL_normal_addr>>32)); Serial.print(" ");Serial.println((uint32_t)((CABELL_normal_addr<<32)>>32));
|
||||||
|
|
||||||
if (IS_BIND_DONE_on) {
|
if (IS_BIND_DONE_on)
|
||||||
CABELL_addr = (((uint64_t)rx_tx_addr[0]) << 32) +
|
{
|
||||||
(((uint64_t)rx_tx_addr[1]) << 24) +
|
CABELL_addr = (((uint64_t)rx_tx_addr[0]) << 32) +
|
||||||
(((uint64_t)rx_tx_addr[2]) << 16) +
|
(((uint64_t)rx_tx_addr[1]) << 24) +
|
||||||
(((uint64_t)rx_tx_addr[3]) << 8) +
|
(((uint64_t)rx_tx_addr[2]) << 16) +
|
||||||
(((uint64_t)rx_tx_addr[4])); // Address to use after binding
|
(((uint64_t)rx_tx_addr[3]) << 8) +
|
||||||
}
|
(((uint64_t)rx_tx_addr[4])); // Address to use after binding
|
||||||
else {
|
}
|
||||||
CABELL_addr = CABELL_BIND_RADIO_ADDR; //static addr for binding
|
else
|
||||||
}
|
CABELL_addr = CABELL_BIND_RADIO_ADDR; // Static addr for binding
|
||||||
|
|
||||||
CABELL_getChannelSequence(hopping_frequency,CABELL_RADIO_CHANNELS,CABELL_addr); // Get the sequence for hopping through channels
|
CABELL_getChannelSequence(hopping_frequency,CABELL_RADIO_CHANNELS,CABELL_addr); // Get the sequence for hopping through channels
|
||||||
rf_ch_num = CABELL_RADIO_MIN_CHANNEL_NUM; // initialize the channel sequence
|
rf_ch_num = CABELL_RADIO_MIN_CHANNEL_NUM; // Initialize the channel sequence
|
||||||
|
|
||||||
packet_count=0;
|
|
||||||
|
|
||||||
uint64_t CABELL_Telemetry_addr = ~CABELL_addr; // Invert bits for reading so that telemetry packets have a different address.
|
packet_count=0;
|
||||||
|
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, reinterpret_cast<uint8_t*>(&CABELL_Telemetry_addr), 5);
|
uint64_t CABELL_Telemetry_addr = ~CABELL_addr; // Invert bits for reading so that telemetry packets have a different address.
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, reinterpret_cast<uint8_t*>(&CABELL_Telemetry_addr), 5);
|
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, reinterpret_cast<uint8_t*>(&CABELL_addr), 5);
|
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, reinterpret_cast<uint8_t*>(&CABELL_Telemetry_addr), 5);
|
||||||
|
NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, reinterpret_cast<uint8_t*>(&CABELL_Telemetry_addr), 5);
|
||||||
|
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, reinterpret_cast<uint8_t*>(&CABELL_addr), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
static void __attribute__((unused)) CABELL_init()
|
static void __attribute__((unused)) CABELL_init()
|
||||||
{
|
{
|
||||||
NRF24L01_Initialize();
|
NRF24L01_Initialize();
|
||||||
CABELL_SetPower();
|
CABELL_SetPower();
|
||||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // slower data rate gives better range/reliability
|
NRF24L01_SetBitrate(NRF24L01_BR_250K); // slower data rate gives better range/reliability
|
||||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgment on all data pipes
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgment on all data pipes
|
||||||
NRF24L01_SetTxRxMode(TX_EN); //Power up and 16 bit CRC
|
NRF24L01_SetTxRxMode(TX_EN); //Power up and 16 bit CRC
|
||||||
|
|
||||||
CABELL_setAddress();
|
CABELL_setAddress();
|
||||||
|
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
NRF24L01_FlushRx();
|
NRF24L01_FlushRx();
|
||||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01);
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01);
|
||||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 0x20); // 32 byte packet length
|
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 0x20); // 32 byte packet length
|
||||||
NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, 0x20); // 32 byte packet length
|
NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, 0x20); // 32 byte packet length
|
||||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);
|
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);
|
||||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x5F); // no retransmits
|
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x5F); // no retransmits
|
||||||
NRF24L01_Activate(0x73); // Activate feature register
|
NRF24L01_Activate(0x73); // Activate feature register
|
||||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3F); // Enable dynamic payload length on all pipes
|
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3F); // Enable dynamic payload length on all pipes
|
||||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x04); // Enable dynamic Payload Length
|
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x04); // Enable dynamic Payload Length
|
||||||
NRF24L01_Activate(0x73);
|
NRF24L01_Activate(0x73);
|
||||||
prev_power = NRF_POWER_0;
|
prev_power = NRF_POWER_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
@ -363,63 +386,57 @@ static void CABELL_SetPower() // This over-ride the standard Set Power to all
|
|||||||
// Note that on many modules max power may actually be worse than the normal high power setting
|
// Note that on many modules max power may actually be worse than the normal high power setting
|
||||||
// test and only use max if it helps the range
|
// test and only use max if it helps the range
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE_on && !IS_RANGE_FLAG_on && ((option & CABELL_OPTION_MASK_MAX_POWER_OVERRIDE) != 0)) { // If we are not in range or bind mode and power setting override is in effect, then set max power, else standard power logic
|
if(IS_BIND_DONE_on && !IS_RANGE_FLAG_on && ((option & CABELL_OPTION_MASK_MAX_POWER_OVERRIDE) != 0))
|
||||||
if(prev_power != NRF_POWER_3) // prev_power is global variable for NRF24L01; NRF_POWER_3 is max power
|
{ // If we are not in range or bind mode and power setting override is in effect, then set max power, else standard power logic
|
||||||
{
|
if(prev_power != NRF_POWER_3) // prev_power is global variable for NRF24L01; NRF_POWER_3 is max power
|
||||||
uint8_t rf_setup = NRF24L01_ReadReg(NRF24L01_06_RF_SETUP);
|
{
|
||||||
rf_setup = (rf_setup & 0xF9) | (NRF_POWER_3 << 1);
|
uint8_t rf_setup = NRF24L01_ReadReg(NRF24L01_06_RF_SETUP);
|
||||||
NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup);
|
rf_setup = (rf_setup & 0xF9) | (NRF_POWER_3 << 1);
|
||||||
prev_power=NRF_POWER_3;
|
NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup);
|
||||||
}
|
prev_power=NRF_POWER_3;
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
NRF24L01_SetPower();
|
else
|
||||||
}
|
NRF24L01_SetPower();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
uint16_t CABELL_callback()
|
uint16_t CABELL_callback()
|
||||||
{
|
{
|
||||||
|
if (IS_BIND_DONE_on)
|
||||||
if (IS_BIND_DONE_on) {
|
{
|
||||||
CABELL_send_packet(0); // packet_period is set/adjusted in CABELL_send_packet
|
CABELL_send_packet(0); // packet_period is set/adjusted in CABELL_send_packet
|
||||||
return packet_period;
|
return packet_period;
|
||||||
}
|
}
|
||||||
else
|
if (bind_counter == 0)
|
||||||
{
|
{
|
||||||
if (bind_counter == 0)
|
BIND_DONE;
|
||||||
{
|
CABELL_init(); // non-bind address
|
||||||
BIND_DONE;
|
}
|
||||||
CABELL_init(); // non-bind address
|
else
|
||||||
}
|
{
|
||||||
else
|
CABELL_send_packet(1);
|
||||||
{
|
bind_counter--;
|
||||||
CABELL_send_packet(1);
|
}
|
||||||
bind_counter--;
|
return CABELL_PACKET_PERIOD;
|
||||||
}
|
|
||||||
return CABELL_PACKET_PERIOD;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
uint16_t initCABELL(void)
|
uint16_t initCABELL(void)
|
||||||
{
|
{
|
||||||
if (IS_BIND_DONE_on) {
|
if (IS_BIND_DONE_on)
|
||||||
bind_counter = 0;
|
bind_counter = 0;
|
||||||
}
|
else
|
||||||
else
|
bind_counter = CABELL_BIND_COUNT;
|
||||||
{
|
CABELL_init();
|
||||||
bind_counter = CABELL_BIND_COUNT;
|
#if defined CABELL_HUB_TELEMETRY
|
||||||
}
|
init_frskyd_link_telemetry();
|
||||||
CABELL_init();
|
telemetry_lost=1; // do not send telemetry to TX right away until we have a TX_RSSI value to prevent warning message...
|
||||||
#if defined TELEMETRY
|
#endif
|
||||||
init_frskyd_link_telemetry();
|
|
||||||
telemetry_lost=1; // do not send telemetry to TX right away until we have a TX_RSSI value to prevent warning message...
|
|
||||||
#endif
|
|
||||||
|
|
||||||
packet_period = CABELL_PACKET_PERIOD;
|
packet_period = CABELL_PACKET_PERIOD;
|
||||||
|
|
||||||
return packet_period;
|
return packet_period;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -78,6 +78,7 @@ uint8_t CYRF_Reset()
|
|||||||
*/
|
*/
|
||||||
void CYRF_GetMfgData(uint8_t data[])
|
void CYRF_GetMfgData(uint8_t data[])
|
||||||
{
|
{
|
||||||
|
#ifndef FORCE_CYRF_ID
|
||||||
/* Fuses power on */
|
/* Fuses power on */
|
||||||
CYRF_WriteRegister(CYRF_25_MFG_ID, 0xFF);
|
CYRF_WriteRegister(CYRF_25_MFG_ID, 0xFF);
|
||||||
|
|
||||||
@ -85,6 +86,9 @@ void CYRF_GetMfgData(uint8_t data[])
|
|||||||
|
|
||||||
/* Fuses power off */
|
/* Fuses power off */
|
||||||
CYRF_WriteRegister(CYRF_25_MFG_ID, 0x00);
|
CYRF_WriteRegister(CYRF_25_MFG_ID, 0x00);
|
||||||
|
#else
|
||||||
|
memcpy(data,FORCE_CYRF_ID,6);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
157
Multiprotocol/DM002_nrf24l01.ino
Normal file
157
Multiprotocol/DM002_nrf24l01.ino
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
This project is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Multiprotocol is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// compatible with DM002
|
||||||
|
|
||||||
|
#if defined(DM002_NRF24L01_INO)
|
||||||
|
|
||||||
|
#include "iface_nrf24l01.h"
|
||||||
|
|
||||||
|
#define DM002_PACKET_PERIOD 6100 // Timeout for callback in uSec
|
||||||
|
#define DM002_INITIAL_WAIT 500
|
||||||
|
#define DM002_PACKET_SIZE 12 // packets have 12-byte payload
|
||||||
|
#define DM002_RF_BIND_CHANNEL 0x27
|
||||||
|
#define DM002_BIND_COUNT 655 // 4 seconds
|
||||||
|
|
||||||
|
|
||||||
|
enum DM002_FLAGS {
|
||||||
|
// flags going to packet[9]
|
||||||
|
DM002_FLAG_FLIP = 0x01,
|
||||||
|
DM002_FLAG_LED = 0x02,
|
||||||
|
DM002_FLAG_MEDIUM = 0x04,
|
||||||
|
DM002_FLAG_HIGH = 0x08,
|
||||||
|
DM002_FLAG_RTH = 0x10,
|
||||||
|
DM002_FLAG_HEADLESS = 0x20,
|
||||||
|
DM002_FLAG_CAMERA1 = 0x40,
|
||||||
|
DM002_FLAG_CAMERA2 = 0x80,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __attribute__((unused)) DM002_send_packet(uint8_t bind)
|
||||||
|
{
|
||||||
|
memcpy(packet+5,(uint8_t *)"\x00\x7F\x7F\x7F\x00\x00\x00",7);
|
||||||
|
if(bind)
|
||||||
|
{
|
||||||
|
packet[0] = 0xAA;
|
||||||
|
packet[1] = rx_tx_addr[0];
|
||||||
|
packet[2] = rx_tx_addr[1];
|
||||||
|
packet[3] = rx_tx_addr[2];
|
||||||
|
packet[4] = rx_tx_addr[3];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet[0]=0x55;
|
||||||
|
// Throttle : 0 .. 200
|
||||||
|
packet[1]=convert_channel_8b_scale(THROTTLE,0,200);
|
||||||
|
// Other channels min 0x57, mid 0x7F, max 0xA7
|
||||||
|
packet[2] = convert_channel_8b_scale(RUDDER,0x57,0xA7);
|
||||||
|
packet[3] = convert_channel_8b_scale(AILERON, 0x57,0xA7);
|
||||||
|
packet[4] = convert_channel_8b_scale(ELEVATOR, 0xA7, 0x57);
|
||||||
|
// Features
|
||||||
|
packet[9] = GET_FLAG(Servo_AUX1,DM002_FLAG_FLIP)
|
||||||
|
| GET_FLAG(!Servo_AUX2,DM002_FLAG_LED)
|
||||||
|
| GET_FLAG(Servo_AUX3,DM002_FLAG_CAMERA1)
|
||||||
|
| GET_FLAG(Servo_AUX4,DM002_FLAG_CAMERA2)
|
||||||
|
| GET_FLAG(Servo_AUX5,DM002_FLAG_HEADLESS)
|
||||||
|
| GET_FLAG(Servo_AUX6,DM002_FLAG_RTH)
|
||||||
|
| GET_FLAG(!Servo_AUX7,DM002_FLAG_HIGH);
|
||||||
|
// Packet counter
|
||||||
|
if(packet_count&0x03)
|
||||||
|
{
|
||||||
|
packet_count++;
|
||||||
|
hopping_frequency_no++;
|
||||||
|
hopping_frequency_no&=4;
|
||||||
|
}
|
||||||
|
packet_count&=0x0F;
|
||||||
|
packet[10] = packet_count;
|
||||||
|
packet_count++;
|
||||||
|
}
|
||||||
|
//CRC
|
||||||
|
for(uint8_t i=0;i<DM002_PACKET_SIZE-1;i++)
|
||||||
|
packet[11]+=packet[i];
|
||||||
|
|
||||||
|
// Power on, TX mode, 2byte CRC
|
||||||
|
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
||||||
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||||
|
if (bind)
|
||||||
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, DM002_RF_BIND_CHANNEL);
|
||||||
|
else
|
||||||
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||||
|
// clear packet status bits and TX FIFO
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||||
|
NRF24L01_FlushTx();
|
||||||
|
XN297_WritePayload(packet, DM002_PACKET_SIZE);
|
||||||
|
|
||||||
|
NRF24L01_SetPower(); // Set tx_power
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) DM002_init()
|
||||||
|
{
|
||||||
|
NRF24L01_Initialize();
|
||||||
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
|
XN297_SetTXAddr((uint8_t *)"\x26\xA8\x67\x35\xCC", 5);
|
||||||
|
|
||||||
|
NRF24L01_FlushTx();
|
||||||
|
NRF24L01_FlushRx();
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||||
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||||
|
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||||
|
NRF24L01_SetPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t DM002_callback()
|
||||||
|
{
|
||||||
|
if(IS_BIND_DONE_on)
|
||||||
|
DM002_send_packet(0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bind_counter == 0)
|
||||||
|
{
|
||||||
|
BIND_DONE;
|
||||||
|
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DM002_send_packet(1);
|
||||||
|
bind_counter--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DM002_PACKET_PERIOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) DM002_initialize_txid()
|
||||||
|
{
|
||||||
|
// Only 2 IDs/RFs are available, RX_NUM is used to switch between them
|
||||||
|
if(rx_tx_addr[3]&1)
|
||||||
|
{
|
||||||
|
memcpy(hopping_frequency,(uint8_t *)"\x34\x39\x43\x48",4);
|
||||||
|
memcpy(rx_tx_addr,(uint8_t *)"\x47\x93\x00\x00\xD5",5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(hopping_frequency,(uint8_t *)"\x35\x39\x3B\x3D",4);
|
||||||
|
memcpy(rx_tx_addr,(uint8_t *)"\xAC\xA1\x00\x00\xD5",5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t initDM002(void)
|
||||||
|
{
|
||||||
|
BIND_IN_PROGRESS; // autobind protocol
|
||||||
|
bind_counter = DM002_BIND_COUNT;
|
||||||
|
DM002_initialize_txid();
|
||||||
|
DM002_init();
|
||||||
|
return DM002_INITIAL_WAIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -273,14 +273,10 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
|
|||||||
uint16_t value = 0xffff;;
|
uint16_t value = 0xffff;;
|
||||||
if (idx != 0xff)
|
if (idx != 0xff)
|
||||||
{
|
{
|
||||||
if (!IS_BIND_DONE_on)
|
/* Spektrum own remotes transmit normal values during bind and actually
|
||||||
{ // Failsafe position during binding
|
* use this (e.g. Nano CP X) to select the transmitter mode (e.g. computer vs
|
||||||
value=max/2; //all channels to middle
|
* non-computer radio, so always end normal output */
|
||||||
if(idx==0)
|
value=map(Servo_data[CH_TAER[idx]],servo_min_125,servo_max_125,0,max);
|
||||||
value=1; //except throttle
|
|
||||||
}
|
|
||||||
else
|
|
||||||
value=map(Servo_data[CH_TAER[idx]],servo_min_125,servo_max_125,0,max);
|
|
||||||
value |= (upper && i==0 ? 0x8000 : 0) | (idx << bits);
|
value |= (upper && i==0 ? 0x8000 : 0) | (idx << bits);
|
||||||
}
|
}
|
||||||
packet[i*2+2] = (value >> 8) & 0xff;
|
packet[i*2+2] = (value >> 8) & 0xff;
|
||||||
@ -582,4 +578,4 @@ uint16_t initDsm()
|
|||||||
return 10000;
|
return 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -133,7 +133,7 @@ static void __attribute__((unused)) flysky_build_packet(uint8_t init)
|
|||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
//servodata timing range for flysky.
|
//servodata timing range for flysky.
|
||||||
////-100% =~ 0x03e8//=1000us(min)
|
//-100% =~ 0x03e8//=1000us(min)
|
||||||
//+100% =~ 0x07ca//=1994us(max)
|
//+100% =~ 0x07ca//=1994us(max)
|
||||||
//Center = 0x5d9//=1497us(center)
|
//Center = 0x5d9//=1497us(center)
|
||||||
//channel order AIL;ELE;THR;RUD;AUX1;AUX2;AUX3;AUX4
|
//channel order AIL;ELE;THR;RUD;AUX1;AUX2;AUX3;AUX4
|
||||||
@ -147,6 +147,8 @@ static void __attribute__((unused)) flysky_build_packet(uint8_t init)
|
|||||||
uint16_t temp=Servo_data[CH_AETR[i]];
|
uint16_t temp=Servo_data[CH_AETR[i]];
|
||||||
if(sub_protocol == CX20 && CH_AETR[i] == ELEVATOR)
|
if(sub_protocol == CX20 && CH_AETR[i] == ELEVATOR)
|
||||||
temp=servo_mid-temp; //reverse channel
|
temp=servo_mid-temp; //reverse channel
|
||||||
|
if(mode_select != MODE_SERIAL) //if in PPM mode extend the output to 1000...2000µs
|
||||||
|
temp=map(temp,servo_min_100,servo_max_100,1000,2000);
|
||||||
packet[5 + i*2]=temp&0xFF; //low byte of servo timing(1000-2000us)
|
packet[5 + i*2]=temp&0xFF; //low byte of servo timing(1000-2000us)
|
||||||
packet[6 + i*2]=(temp>>8)&0xFF; //high byte of servo timing(1000-2000us)
|
packet[6 + i*2]=(temp>>8)&0xFF; //high byte of servo timing(1000-2000us)
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,11 @@
|
|||||||
#include "iface_cc2500.h"
|
#include "iface_cc2500.h"
|
||||||
|
|
||||||
uint8_t chanskip;
|
uint8_t chanskip;
|
||||||
uint8_t seq_last_sent;
|
//uint8_t seq_last_sent;
|
||||||
uint8_t seq_last_rcvd;
|
//uint8_t seq_last_rcvd;
|
||||||
|
|
||||||
|
uint8_t FrX_send_seq ;
|
||||||
|
uint8_t FrX_receive_seq ;
|
||||||
|
|
||||||
static void __attribute__((unused)) set_start(uint8_t ch )
|
static void __attribute__((unused)) set_start(uint8_t ch )
|
||||||
{
|
{
|
||||||
@ -151,11 +154,7 @@ static void __attribute__((unused)) frskyX_data_frame()
|
|||||||
packet[9+i+2]=chan_1>>4;
|
packet[9+i+2]=chan_1>>4;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet[21] = seq_last_sent << 4 | seq_last_rcvd;//8 at start
|
packet[21] = (FrX_receive_seq << 4) | FrX_send_seq ;//8 at start
|
||||||
if (seq_last_sent < 0x08 && seq_last_rcvd < 8)
|
|
||||||
seq_last_sent = (seq_last_sent + 1) % 4;
|
|
||||||
else if (seq_last_rcvd == 0x00)
|
|
||||||
seq_last_sent = 1;
|
|
||||||
|
|
||||||
if(sub_protocol & 1 )// in X8 mode send only 8ch every 9ms
|
if(sub_protocol & 1 )// in X8 mode send only 8ch every 9ms
|
||||||
lpass = 0 ;
|
lpass = 0 ;
|
||||||
@ -208,9 +207,9 @@ uint16_t ReadFrSkyX()
|
|||||||
CC2500_Strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
CC2500_WriteData(packet, packet[0]+1);
|
CC2500_WriteData(packet, packet[0]+1);
|
||||||
//
|
//
|
||||||
frskyX_data_frame();
|
// frskyX_data_frame();
|
||||||
state++;
|
state++;
|
||||||
return 5500;
|
return 5200;
|
||||||
case FRSKY_DATA2:
|
case FRSKY_DATA2:
|
||||||
CC2500_SetTxRxMode(RX_EN);
|
CC2500_SetTxRxMode(RX_EN);
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
@ -219,7 +218,7 @@ uint16_t ReadFrSkyX()
|
|||||||
case FRSKY_DATA3:
|
case FRSKY_DATA3:
|
||||||
CC2500_Strobe(CC2500_SRX);
|
CC2500_Strobe(CC2500_SRX);
|
||||||
state++;
|
state++;
|
||||||
return 3000;
|
return 3100;
|
||||||
case FRSKY_DATA4:
|
case FRSKY_DATA4:
|
||||||
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||||
if (len && (len<=(0x0E + 3))) //Telemetry frame is 17
|
if (len && (len<=(0x0E + 3))) //Telemetry frame is 17
|
||||||
@ -238,8 +237,10 @@ uint16_t ReadFrSkyX()
|
|||||||
// restart sequence on missed packet - might need count or timeout instead of one missed
|
// restart sequence on missed packet - might need count or timeout instead of one missed
|
||||||
if(packet_count>100)
|
if(packet_count>100)
|
||||||
{//~1sec
|
{//~1sec
|
||||||
seq_last_sent = 0;
|
// seq_last_sent = 0;
|
||||||
seq_last_rcvd = 8;
|
// seq_last_rcvd = 8;
|
||||||
|
FrX_send_seq = 0x08 ;
|
||||||
|
// FrX_receive_seq = 0 ;
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
#if defined TELEMETRY
|
#if defined TELEMETRY
|
||||||
telemetry_lost=1;
|
telemetry_lost=1;
|
||||||
@ -247,8 +248,13 @@ uint16_t ReadFrSkyX()
|
|||||||
}
|
}
|
||||||
CC2500_Strobe(CC2500_SFRX); //flush the RXFIFO
|
CC2500_Strobe(CC2500_SFRX); //flush the RXFIFO
|
||||||
}
|
}
|
||||||
|
frskyX_data_frame();
|
||||||
|
if ( FrX_send_seq != 0x08 )
|
||||||
|
{
|
||||||
|
FrX_send_seq = ( FrX_send_seq + 1 ) & 0x03 ;
|
||||||
|
}
|
||||||
state = FRSKY_DATA1;
|
state = FRSKY_DATA1;
|
||||||
return 300;
|
return 500;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -277,8 +283,10 @@ uint16_t initFrSkyX()
|
|||||||
state = FRSKY_DATA1;
|
state = FRSKY_DATA1;
|
||||||
initialize_data(0);
|
initialize_data(0);
|
||||||
}
|
}
|
||||||
seq_last_sent = 0;
|
// seq_last_sent = 0;
|
||||||
seq_last_rcvd = 8;
|
// seq_last_rcvd = 8;
|
||||||
|
FrX_send_seq = 0x08 ;
|
||||||
|
FrX_receive_seq = 0 ;
|
||||||
return 10000;
|
return 10000;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -11,7 +11,7 @@
|
|||||||
11,SLT,SLT,VISTA
|
11,SLT,SLT,VISTA
|
||||||
12,CX10,GREEN,BLUE,DM007,---,J3015_1,J3015_2,MK33041
|
12,CX10,GREEN,BLUE,DM007,---,J3015_1,J3015_2,MK33041
|
||||||
13,CG023,CG023,YD829,H8_3D
|
13,CG023,CG023,YD829,H8_3D
|
||||||
14,Bayang,Bayang,H8S3D
|
14,Bayang,Bayang,H8S3D,X16_AH
|
||||||
15,FrskyX,CH_16,CH_8,EU_16,EU_8
|
15,FrskyX,CH_16,CH_8,EU_16,EU_8
|
||||||
16,ESky
|
16,ESky
|
||||||
17,MT99xx,MT,H7,YZ,LS,FY805
|
17,MT99xx,MT,H7,YZ,LS,FY805
|
||||||
@ -29,4 +29,6 @@
|
|||||||
29,Q2X2,Q222,Q242,Q282
|
29,Q2X2,Q222,Q242,Q282
|
||||||
30,WK2x01,WK2801,WK2401,W6_5_1,W6_6_1,W6_HEL,W6_HEL_I
|
30,WK2x01,WK2801,WK2401,W6_5_1,W6_6_1,W6_HEL,W6_HEL_I
|
||||||
31,Q303,Q303,CX35,CX10D,CX10WD
|
31,Q303,Q303,CX35,CX10D,CX10WD
|
||||||
32,GW008
|
32,GW008
|
||||||
|
33,DM002
|
||||||
|
34,CABELL,CAB_V3,C_TELEM,-,-,-,-,F_SAFE,UNBIND
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#define VERSION_MAJOR 1
|
#define VERSION_MAJOR 1
|
||||||
#define VERSION_MINOR 1
|
#define VERSION_MINOR 1
|
||||||
#define VERSION_REVISION 6
|
#define VERSION_REVISION 6
|
||||||
#define VERSION_PATCH_LEVEL 20
|
#define VERSION_PATCH_LEVEL 29
|
||||||
//******************
|
//******************
|
||||||
// Protocols
|
// Protocols
|
||||||
//******************
|
//******************
|
||||||
@ -58,6 +58,7 @@ enum PROTOCOLS
|
|||||||
MODE_WK2x01 = 30, // =>CYRF6936
|
MODE_WK2x01 = 30, // =>CYRF6936
|
||||||
MODE_Q303 = 31, // =>NRF24L01
|
MODE_Q303 = 31, // =>NRF24L01
|
||||||
MODE_GW008 = 32, // =>NRF24L01
|
MODE_GW008 = 32, // =>NRF24L01
|
||||||
|
MODE_DM002 = 33, // =>NRF24L01
|
||||||
MODE_CABELL = 34, // =>NRF24L01
|
MODE_CABELL = 34, // =>NRF24L01
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -136,7 +137,8 @@ enum CG023
|
|||||||
enum BAYANG
|
enum BAYANG
|
||||||
{
|
{
|
||||||
BAYANG = 0,
|
BAYANG = 0,
|
||||||
H8S3D = 1
|
H8S3D = 1,
|
||||||
|
X16_AH = 2,
|
||||||
};
|
};
|
||||||
enum MT99XX
|
enum MT99XX
|
||||||
{
|
{
|
||||||
@ -197,10 +199,10 @@ enum Q303
|
|||||||
};
|
};
|
||||||
enum CABELL
|
enum CABELL
|
||||||
{
|
{
|
||||||
CABELL_V3 = 0,
|
CABELL_V3 = 0,
|
||||||
CABELL_V3_TELEMETRY = 1,
|
CABELL_V3_TELEMETRY = 1,
|
||||||
CABELL_SET_FAIL_SAFE = 6,
|
CABELL_SET_FAIL_SAFE= 6,
|
||||||
CABELL_UNBIND = 7
|
CABELL_UNBIND = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NONE 0
|
#define NONE 0
|
||||||
@ -400,7 +402,7 @@ enum CC2500_POWER
|
|||||||
CC2500_POWER_16 = 0xFE, // 0dbm
|
CC2500_POWER_16 = 0xFE, // 0dbm
|
||||||
CC2500_POWER_17 = 0xFF // +1dbm
|
CC2500_POWER_17 = 0xFF // +1dbm
|
||||||
};
|
};
|
||||||
#define CC2500_HIGH_POWER CC2500_POWER_16
|
#define CC2500_HIGH_POWER CC2500_POWER_17
|
||||||
#define CC2500_LOW_POWER CC2500_POWER_13
|
#define CC2500_LOW_POWER CC2500_POWER_13
|
||||||
#define CC2500_RANGE_POWER CC2500_POWER_1
|
#define CC2500_RANGE_POWER CC2500_POWER_1
|
||||||
#define CC2500_BIND_POWER CC2500_POWER_1
|
#define CC2500_BIND_POWER CC2500_POWER_1
|
||||||
@ -488,7 +490,8 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
WK2x01 30
|
WK2x01 30
|
||||||
Q303 31
|
Q303 31
|
||||||
GW008 32
|
GW008 32
|
||||||
CABELL 33
|
DM002 33
|
||||||
|
CABELL 34
|
||||||
BindBit=> 0x80 1=Bind/0=No
|
BindBit=> 0x80 1=Bind/0=No
|
||||||
AutoBindBit=> 0x40 1=Yes /0=No
|
AutoBindBit=> 0x40 1=Yes /0=No
|
||||||
RangeCheck=> 0x20 1=Yes /0=No
|
RangeCheck=> 0x20 1=Yes /0=No
|
||||||
@ -544,6 +547,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
sub_protocol==BAYANG
|
sub_protocol==BAYANG
|
||||||
BAYANG 0
|
BAYANG 0
|
||||||
H8S3D 1
|
H8S3D 1
|
||||||
|
X16_AH 2
|
||||||
sub_protocol==MT99XX
|
sub_protocol==MT99XX
|
||||||
MT99 0
|
MT99 0
|
||||||
H7 1
|
H7 1
|
||||||
@ -591,10 +595,10 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
CX10D 2
|
CX10D 2
|
||||||
CX10WD 3
|
CX10WD 3
|
||||||
sub_protocol==CABELL
|
sub_protocol==CABELL
|
||||||
CABELL_V3 0,
|
CABELL_V3 0
|
||||||
CABELL_V3_TELEMETRY 1,
|
CABELL_V3_TELEMETRY 1
|
||||||
CABELL_SET_FAIL_SAFE 6,
|
CABELL_SET_FAIL_SAFE 6
|
||||||
CABELL_UNBIND 7
|
CABELL_UNBIND 7
|
||||||
|
|
||||||
Power value => 0x80 0=High/1=Low
|
Power value => 0x80 0=High/1=Low
|
||||||
Stream[3] = option_protocol;
|
Stream[3] = option_protocol;
|
||||||
@ -690,4 +694,4 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
data[0] = RSSI value
|
data[0] = RSSI value
|
||||||
data[1-28] telemetry data
|
data[1-28] telemetry data
|
||||||
|
|
||||||
*/
|
*/
|
@ -22,13 +22,25 @@
|
|||||||
*/
|
*/
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
//#define DEBUG_TX
|
//#define DEBUG_TX
|
||||||
|
#define USE_MY_CONFIG
|
||||||
|
#ifdef ARDUINO_AVR_XMEGA32D4
|
||||||
|
#include "MultiOrange.h"
|
||||||
|
#endif
|
||||||
#include "Multiprotocol.h"
|
#include "Multiprotocol.h"
|
||||||
|
|
||||||
//Multiprotocol module configuration file
|
//Multiprotocol module configuration file
|
||||||
#include "_Config.h"
|
#include "_Config.h"
|
||||||
|
// Let's automatically select the board
|
||||||
|
// if arm is selected
|
||||||
#ifdef __arm__
|
#ifdef __arm__
|
||||||
#define STM32_BOARD // Let's automatically select this board if arm is selected since this is the only one for now...
|
#define STM32_BOARD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//Personal config file
|
||||||
|
#if defined USE_MY_CONFIG
|
||||||
|
#include "_MyConfig.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "Pins.h"
|
#include "Pins.h"
|
||||||
#include "TX_Def.h"
|
#include "TX_Def.h"
|
||||||
#include "Validate.h"
|
#include "Validate.h"
|
||||||
@ -97,6 +109,18 @@ uint8_t RX_num;
|
|||||||
uint8_t calData[48];
|
uint8_t calData[48];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CHECK_FOR_BOOTLOADER
|
||||||
|
uint8_t BootTimer ;
|
||||||
|
uint8_t BootState ;
|
||||||
|
uint8_t NotBootChecking ;
|
||||||
|
uint8_t BootCount ;
|
||||||
|
|
||||||
|
#define BOOT_WAIT_30_IDLE 0
|
||||||
|
#define BOOT_WAIT_30_DATA 1
|
||||||
|
#define BOOT_WAIT_20 2
|
||||||
|
#define BOOT_READY 3
|
||||||
|
#endif
|
||||||
|
|
||||||
//Channel mapping for protocols
|
//Channel mapping for protocols
|
||||||
const uint8_t CH_AETR[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8, AUX9, AUX10};
|
const uint8_t CH_AETR[]={AILERON, ELEVATOR, THROTTLE, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8, AUX9, AUX10};
|
||||||
const uint8_t CH_TAER[]={THROTTLE, AILERON, ELEVATOR, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8};
|
const uint8_t CH_TAER[]={THROTTLE, AILERON, ELEVATOR, RUDDER, AUX1, AUX2, AUX3, AUX4, AUX5, AUX6, AUX7, AUX8};
|
||||||
@ -145,7 +169,7 @@ uint8_t pkt[MAX_PKT];//telemetry receiving packets
|
|||||||
uint8_t pktt[MAX_PKT];//telemetry receiving packets
|
uint8_t pktt[MAX_PKT];//telemetry receiving packets
|
||||||
#ifdef BASH_SERIAL
|
#ifdef BASH_SERIAL
|
||||||
// For bit-bashed serial output
|
// For bit-bashed serial output
|
||||||
#define TXBUFFER_SIZE 128
|
#define TXBUFFER_SIZE 192
|
||||||
volatile struct t_serial_bash
|
volatile struct t_serial_bash
|
||||||
{
|
{
|
||||||
uint8_t head ;
|
uint8_t head ;
|
||||||
@ -155,7 +179,7 @@ uint8_t pkt[MAX_PKT];//telemetry receiving packets
|
|||||||
uint8_t speed ;
|
uint8_t speed ;
|
||||||
} SerialControl ;
|
} SerialControl ;
|
||||||
#else
|
#else
|
||||||
#define TXBUFFER_SIZE 64
|
#define TXBUFFER_SIZE 96
|
||||||
volatile uint8_t tx_buff[TXBUFFER_SIZE];
|
volatile uint8_t tx_buff[TXBUFFER_SIZE];
|
||||||
volatile uint8_t tx_head=0;
|
volatile uint8_t tx_head=0;
|
||||||
volatile uint8_t tx_tail=0;
|
volatile uint8_t tx_tail=0;
|
||||||
@ -198,6 +222,7 @@ void setup()
|
|||||||
TCC1.CTRLA = 0x0B ; // Event3 (prescale of 16)
|
TCC1.CTRLA = 0x0B ; // Event3 (prescale of 16)
|
||||||
#elif defined STM32_BOARD
|
#elif defined STM32_BOARD
|
||||||
//STM32
|
//STM32
|
||||||
|
afio_cfg_debug_ports(AFIO_DEBUG_NONE);
|
||||||
pinMode(A7105_CSN_pin,OUTPUT);
|
pinMode(A7105_CSN_pin,OUTPUT);
|
||||||
pinMode(CC25_CSN_pin,OUTPUT);
|
pinMode(CC25_CSN_pin,OUTPUT);
|
||||||
pinMode(NRF_CSN_pin,OUTPUT);
|
pinMode(NRF_CSN_pin,OUTPUT);
|
||||||
@ -382,7 +407,11 @@ void setup()
|
|||||||
protocol=0;
|
protocol=0;
|
||||||
servo_max_100=SERIAL_MAX_100; servo_min_100=SERIAL_MIN_100;
|
servo_max_100=SERIAL_MAX_100; servo_min_100=SERIAL_MIN_100;
|
||||||
servo_max_125=SERIAL_MAX_125; servo_min_125=SERIAL_MIN_125;
|
servo_max_125=SERIAL_MAX_125; servo_min_125=SERIAL_MIN_125;
|
||||||
Mprotocol_serial_init(); // Configure serial and enable RX interrupt
|
#ifdef CHECK_FOR_BOOTLOADER
|
||||||
|
Mprotocol_serial_init(1); // Configure serial and enable RX interrupt
|
||||||
|
#else
|
||||||
|
Mprotocol_serial_init(); // Configure serial and enable RX interrupt
|
||||||
|
#endif
|
||||||
#endif //ENABLE_SERIAL
|
#endif //ENABLE_SERIAL
|
||||||
}
|
}
|
||||||
servo_mid=servo_min_100+servo_max_100; //In fact 2* mid_value
|
servo_mid=servo_min_100+servo_max_100; //In fact 2* mid_value
|
||||||
@ -475,6 +504,11 @@ void loop()
|
|||||||
uint8_t Update_All()
|
uint8_t Update_All()
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_SERIAL
|
#ifdef ENABLE_SERIAL
|
||||||
|
#ifdef CHECK_FOR_BOOTLOADER
|
||||||
|
if ( (mode_select==MODE_SERIAL) && (NotBootChecking == 0) )
|
||||||
|
pollBoot() ;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received
|
if(mode_select==MODE_SERIAL && IS_RX_FLAG_on) // Serial mode and something has been received
|
||||||
{
|
{
|
||||||
update_serial_data(); // Update protocol and data
|
update_serial_data(); // Update protocol and data
|
||||||
@ -505,7 +539,7 @@ uint8_t Update_All()
|
|||||||
update_led_status();
|
update_led_status();
|
||||||
#if defined(TELEMETRY)
|
#if defined(TELEMETRY)
|
||||||
#if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) )
|
#if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) )
|
||||||
if((protocol==MODE_FRSKYD) || (protocol==MODE_BAYANG) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) || (protocol==MODE_CABELL) )
|
if( (protocol==MODE_FRSKYD) || (protocol==MODE_BAYANG) || (protocol==MODE_HUBSAN) || (protocol==MODE_AFHDS2A) || (protocol==MODE_FRSKYX) || (protocol==MODE_DSM) || (protocol==MODE_CABELL) )
|
||||||
#endif
|
#endif
|
||||||
TelemetryUpdate();
|
TelemetryUpdate();
|
||||||
#endif
|
#endif
|
||||||
@ -948,6 +982,12 @@ static void protocol_init()
|
|||||||
remote_callback = GW008_callback;
|
remote_callback = GW008_callback;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(DM002_NRF24L01_INO)
|
||||||
|
case MODE_DM002:
|
||||||
|
next_callback=initDM002();
|
||||||
|
remote_callback = DM002_callback;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#if defined(CABELL_NRF24L01_INO)
|
#if defined(CABELL_NRF24L01_INO)
|
||||||
case MODE_CABELL:
|
case MODE_CABELL:
|
||||||
next_callback=initCABELL();
|
next_callback=initCABELL();
|
||||||
@ -1083,7 +1123,11 @@ void modules_reset()
|
|||||||
prev_power=0xFD; // unused power value
|
prev_power=0xFD; // unused power value
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mprotocol_serial_init()
|
#ifdef CHECK_FOR_BOOTLOADER
|
||||||
|
void Mprotocol_serial_init( uint8_t boot )
|
||||||
|
#else
|
||||||
|
void Mprotocol_serial_init()
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef ORANGE_TX
|
#ifdef ORANGE_TX
|
||||||
PORTC.OUTSET = 0x08 ;
|
PORTC.OUTSET = 0x08 ;
|
||||||
@ -1093,18 +1137,41 @@ void Mprotocol_serial_init()
|
|||||||
USARTC0.BAUDCTRLB = 0 ;
|
USARTC0.BAUDCTRLB = 0 ;
|
||||||
|
|
||||||
USARTC0.CTRLB = 0x18 ;
|
USARTC0.CTRLB = 0x18 ;
|
||||||
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCF) | 0x10 ;
|
USARTC0.CTRLA = (USARTC0.CTRLA & 0xCC) | 0x11 ;
|
||||||
USARTC0.CTRLC = 0x2B ;
|
USARTC0.CTRLC = 0x2B ;
|
||||||
UDR0 ;
|
UDR0 ;
|
||||||
#ifdef INVERT_SERIAL
|
#ifdef INVERT_SERIAL
|
||||||
PORTC.PIN3CTRL |= 0x40 ;
|
PORTC.PIN3CTRL |= 0x40 ;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CHECK_FOR_BOOTLOADER
|
||||||
|
if ( boot )
|
||||||
|
{
|
||||||
|
USARTC0.BAUDCTRLB = 0 ;
|
||||||
|
USARTC0.BAUDCTRLA = 33 ; // 57600
|
||||||
|
USARTC0.CTRLA = (USARTC0.CTRLA & 0xC0) ;
|
||||||
|
USARTC0.CTRLC = 0x03 ; // 8 bit, no parity, 1 stop
|
||||||
|
USARTC0.CTRLB = 0x18 ; // Enable Tx and Rx
|
||||||
|
PORTC.PIN3CTRL &= ~0x40 ;
|
||||||
|
}
|
||||||
|
#endif // CHECK_FOR_BOOTLOADER
|
||||||
#elif defined STM32_BOARD
|
#elif defined STM32_BOARD
|
||||||
usart2_begin(100000,SERIAL_8E2);
|
#ifdef CHECK_FOR_BOOTLOADER
|
||||||
|
if ( boot )
|
||||||
|
{
|
||||||
|
usart2_begin(57600,SERIAL_8N1);
|
||||||
|
USART2_BASE->CR1 &= ~USART_CR1_RXNEIE ;
|
||||||
|
(void)UDR0 ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif // CHECK_FOR_BOOTLOADER
|
||||||
|
{
|
||||||
|
usart2_begin(100000,SERIAL_8E2);
|
||||||
|
USART2_BASE->CR1 |= USART_CR1_PCE_BIT;
|
||||||
|
}
|
||||||
usart3_begin(100000,SERIAL_8E2);
|
usart3_begin(100000,SERIAL_8E2);
|
||||||
USART2_BASE->CR1 |= USART_CR1_PCE_BIT;
|
|
||||||
USART3_BASE->CR1 &= ~ USART_CR1_RE;//disable
|
USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable
|
||||||
USART2_BASE->CR1 &= ~ USART_CR1_TE;//disable transmit
|
USART2_BASE->CR1 &= ~ USART_CR1_TE; //disable transmit
|
||||||
#else
|
#else
|
||||||
//ATMEGA328p
|
//ATMEGA328p
|
||||||
#include <util/setbaud.h>
|
#include <util/setbaud.h>
|
||||||
@ -1113,7 +1180,7 @@ void Mprotocol_serial_init()
|
|||||||
UCSR0A = 0 ; // Clear X2 bit
|
UCSR0A = 0 ; // Clear X2 bit
|
||||||
//Set frame format to 8 data bits, even parity, 2 stop bits
|
//Set frame format to 8 data bits, even parity, 2 stop bits
|
||||||
UCSR0C = _BV(UPM01)|_BV(USBS0)|_BV(UCSZ01)|_BV(UCSZ00);
|
UCSR0C = _BV(UPM01)|_BV(USBS0)|_BV(UCSZ01)|_BV(UCSZ00);
|
||||||
while ( UCSR0A & (1 << RXC0) )//flush receive buffer
|
while ( UCSR0A & (1 << RXC0) ) //flush receive buffer
|
||||||
UDR0;
|
UDR0;
|
||||||
//enable reception and RC complete interrupt
|
//enable reception and RC complete interrupt
|
||||||
UCSR0B = _BV(RXEN0)|_BV(RXCIE0);//rx enable and interrupt
|
UCSR0B = _BV(RXEN0)|_BV(RXCIE0);//rx enable and interrupt
|
||||||
@ -1122,9 +1189,130 @@ void Mprotocol_serial_init()
|
|||||||
initTXSerial( SPEED_100K ) ;
|
initTXSerial( SPEED_100K ) ;
|
||||||
#endif //TELEMETRY
|
#endif //TELEMETRY
|
||||||
#endif //DEBUG_TX
|
#endif //DEBUG_TX
|
||||||
|
#ifdef CHECK_FOR_BOOTLOADER
|
||||||
|
if ( boot )
|
||||||
|
{
|
||||||
|
UBRR0H = 0;
|
||||||
|
UBRR0L = 33; // 57600
|
||||||
|
UCSR0C &= ~_BV(UPM01); // No parity
|
||||||
|
UCSR0B &= ~_BV(RXCIE0); // No rx interrupt
|
||||||
|
UCSR0A |= _BV(U2X0); // Double speed mode USART0
|
||||||
|
}
|
||||||
|
#endif // CHECK_FOR_BOOTLOADER
|
||||||
#endif //ORANGE_TX
|
#endif //ORANGE_TX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CHECK_FOR_BOOTLOADER
|
||||||
|
void pollBoot()
|
||||||
|
{
|
||||||
|
uint8_t rxchar ;
|
||||||
|
uint8_t lState = BootState ;
|
||||||
|
uint8_t millisTime = millis(); // Call this once only
|
||||||
|
|
||||||
|
#ifdef ORANGE_TX
|
||||||
|
if ( USARTC0.STATUS & USART_RXCIF_bm )
|
||||||
|
#elif defined STM32_BOARD
|
||||||
|
if ( USART2_BASE->SR & USART_SR_RXNE )
|
||||||
|
#else
|
||||||
|
if ( UCSR0A & ( 1 << RXC0 ) )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
rxchar = UDR0 ;
|
||||||
|
BootCount += 1 ;
|
||||||
|
if ( ( lState == BOOT_WAIT_30_IDLE ) || ( lState == BOOT_WAIT_30_DATA ) )
|
||||||
|
{
|
||||||
|
if ( lState == BOOT_WAIT_30_IDLE ) // Waiting for 0x30
|
||||||
|
BootTimer = millisTime ; // Start timeout
|
||||||
|
if ( rxchar == 0x30 )
|
||||||
|
lState = BOOT_WAIT_20 ;
|
||||||
|
else
|
||||||
|
lState = BOOT_WAIT_30_DATA ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if ( lState == BOOT_WAIT_20 && rxchar == 0x20 ) // Waiting for 0x20
|
||||||
|
lState = BOOT_READY ;
|
||||||
|
}
|
||||||
|
else // No byte received
|
||||||
|
{
|
||||||
|
if ( lState != BOOT_WAIT_30_IDLE ) // Something received
|
||||||
|
{
|
||||||
|
uint8_t time = millisTime - BootTimer ;
|
||||||
|
if ( time > 5 )
|
||||||
|
{
|
||||||
|
#ifdef STM32_BOARD
|
||||||
|
if ( BootCount > 4 )
|
||||||
|
#else
|
||||||
|
if ( BootCount > 2 )
|
||||||
|
#endif
|
||||||
|
{ // Run normally
|
||||||
|
NotBootChecking = 0xFF ;
|
||||||
|
Mprotocol_serial_init( 0 ) ;
|
||||||
|
}
|
||||||
|
else if ( lState == BOOT_READY )
|
||||||
|
{
|
||||||
|
#ifdef STM32_BOARD
|
||||||
|
#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
|
||||||
|
#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */
|
||||||
|
#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */
|
||||||
|
#define __I volatile /*!< defines 'read only' permissions */
|
||||||
|
#define __IO volatile /*!< defines 'read / write' permissions */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__I uint32_t CPUID; /*!< Offset: 0x00 CPU ID Base Register */
|
||||||
|
__IO uint32_t ICSR; /*!< Offset: 0x04 Interrupt Control State Register */
|
||||||
|
__IO uint32_t VTOR; /*!< Offset: 0x08 Vector Table Offset Register */
|
||||||
|
__IO uint32_t AIRCR; /*!< Offset: 0x0C Application Interrupt / Reset Control Register */
|
||||||
|
__IO uint32_t SCR; /*!< Offset: 0x10 System Control Register */
|
||||||
|
__IO uint32_t CCR; /*!< Offset: 0x14 Configuration Control Register */
|
||||||
|
__IO uint8_t SHP[12]; /*!< Offset: 0x18 System Handlers Priority Registers (4-7, 8-11, 12-15) */
|
||||||
|
__IO uint32_t SHCSR; /*!< Offset: 0x24 System Handler Control and State Register */
|
||||||
|
__IO uint32_t CFSR; /*!< Offset: 0x28 Configurable Fault Status Register */
|
||||||
|
__IO uint32_t HFSR; /*!< Offset: 0x2C Hard Fault Status Register */
|
||||||
|
__IO uint32_t DFSR; /*!< Offset: 0x30 Debug Fault Status Register */
|
||||||
|
__IO uint32_t MMFAR; /*!< Offset: 0x34 Mem Manage Address Register */
|
||||||
|
__IO uint32_t BFAR; /*!< Offset: 0x38 Bus Fault Address Register */
|
||||||
|
__IO uint32_t AFSR; /*!< Offset: 0x3C Auxiliary Fault Status Register */
|
||||||
|
__I uint32_t PFR[2]; /*!< Offset: 0x40 Processor Feature Register */
|
||||||
|
__I uint32_t DFR; /*!< Offset: 0x48 Debug Feature Register */
|
||||||
|
__I uint32_t ADR; /*!< Offset: 0x4C Auxiliary Feature Register */
|
||||||
|
__I uint32_t MMFR[4]; /*!< Offset: 0x50 Memory Model Feature Register */
|
||||||
|
__I uint32_t ISAR[5]; /*!< Offset: 0x60 ISA Feature Register */
|
||||||
|
} SCB_Type;
|
||||||
|
#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
|
||||||
|
#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||||
|
#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */
|
||||||
|
#define SCB_AIRCR_PRIGROUP_Msk (7ul << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
|
||||||
|
#define SCB_AIRCR_SYSRESETREQ_Msk (1ul << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||||
|
|
||||||
|
// NVIC_SystemReset
|
||||||
|
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
|
||||||
|
(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
|
||||||
|
SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */
|
||||||
|
asm("dsb");
|
||||||
|
while(1); /* wait until reset */
|
||||||
|
#else
|
||||||
|
cli(); // Disable global int due to RW of 16 bits registers
|
||||||
|
void (*p)();
|
||||||
|
#ifndef ORANGE_TX
|
||||||
|
p = (void (*)())0x3F00 ; // Word address (0x7E00 byte)
|
||||||
|
#else
|
||||||
|
p = (void (*)())0x4000 ; // Word address (0x8000 byte)
|
||||||
|
#endif
|
||||||
|
(*p)() ; // go to boot
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lState = BOOT_WAIT_30_IDLE ;
|
||||||
|
BootCount = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BootState = lState ;
|
||||||
|
}
|
||||||
|
#endif //CHECK_FOR_BOOTLOADER
|
||||||
|
|
||||||
#if defined(TELEMETRY)
|
#if defined(TELEMETRY)
|
||||||
void PPM_Telemetry_serial_init()
|
void PPM_Telemetry_serial_init()
|
||||||
{
|
{
|
||||||
@ -1164,35 +1352,41 @@ static uint32_t random_value(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint32_t random_id(uint16_t adress, uint8_t create_new)
|
static uint32_t random_id(uint16_t address, uint8_t create_new)
|
||||||
{
|
{
|
||||||
uint32_t id=0;
|
#ifndef FORCE_GLOBAL_ID
|
||||||
|
uint32_t id=0;
|
||||||
|
|
||||||
if(eeprom_read_byte((EE_ADDR)(adress+10))==0xf0 && !create_new)
|
if(eeprom_read_byte((EE_ADDR)(address+10))==0xf0 && !create_new)
|
||||||
{ // TXID exists in EEPROM
|
{ // TXID exists in EEPROM
|
||||||
for(uint8_t i=4;i>0;i--)
|
for(uint8_t i=4;i>0;i--)
|
||||||
|
{
|
||||||
|
id<<=8;
|
||||||
|
id|=eeprom_read_byte((EE_ADDR)address+i-1);
|
||||||
|
}
|
||||||
|
if(id!=0x2AD141A7) //ID with seed=0
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
// Generate a random ID
|
||||||
|
#if defined STM32_BOARD
|
||||||
|
#define STM32_UUID ((uint32_t *)0x1FFFF7E8)
|
||||||
|
if (!create_new)
|
||||||
|
id = STM32_UUID[0] ^ STM32_UUID[1] ^ STM32_UUID[2];
|
||||||
|
#else
|
||||||
|
id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
|
||||||
|
#endif
|
||||||
|
for(uint8_t i=0;i<4;i++)
|
||||||
{
|
{
|
||||||
id<<=8;
|
eeprom_write_byte((EE_ADDR)address+i,id);
|
||||||
id|=eeprom_read_byte((EE_ADDR)adress+i-1);
|
id>>=8;
|
||||||
}
|
}
|
||||||
if(id!=0x2AD141A7) //ID with seed=0
|
eeprom_write_byte((EE_ADDR)(address+10),0xf0);//write bind flag in eeprom.
|
||||||
return id;
|
return id;
|
||||||
}
|
|
||||||
// Generate a random ID
|
|
||||||
#if defined STM32_BOARD
|
|
||||||
#define STM32_UUID ((uint32_t *)0x1FFFF7E8)
|
|
||||||
if (!create_new)
|
|
||||||
id = STM32_UUID[0] ^ STM32_UUID[1] ^ STM32_UUID[2];
|
|
||||||
#else
|
#else
|
||||||
id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
|
(void)address;
|
||||||
|
(void)create_new;
|
||||||
|
return FORCE_GLOBAL_ID;
|
||||||
#endif
|
#endif
|
||||||
for(uint8_t i=0;i<4;i++)
|
|
||||||
{
|
|
||||||
eeprom_write_byte((EE_ADDR)adress+i,id);
|
|
||||||
id>>=8;
|
|
||||||
}
|
|
||||||
eeprom_write_byte((EE_ADDR)(adress+10),0xf0);//write bind flag in eeprom.
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************/
|
/**************************/
|
||||||
@ -1369,4 +1563,4 @@ static uint32_t random_id(uint16_t adress, uint8_t create_new)
|
|||||||
WDTCSR = 0; // Disable Watchdog interrupt
|
WDTCSR = 0; // Disable Watchdog interrupt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -27,6 +27,7 @@ uint8_t rf_setup;
|
|||||||
void NRF24L01_Initialize()
|
void NRF24L01_Initialize()
|
||||||
{
|
{
|
||||||
rf_setup = 0x09;
|
rf_setup = 0x09;
|
||||||
|
prev_power = 0x00; // Make sure prev_power is inline with current power
|
||||||
XN297_SetScrambledMode(XN297_SCRAMBLED);
|
XN297_SetScrambledMode(XN297_SCRAMBLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,8 +134,8 @@ void NRF24L01_SetBitrate(uint8_t bitrate)
|
|||||||
|
|
||||||
// Bit 0 goes to RF_DR_HIGH, bit 1 - to RF_DR_LOW
|
// Bit 0 goes to RF_DR_HIGH, bit 1 - to RF_DR_LOW
|
||||||
rf_setup = (rf_setup & 0xD7) | ((bitrate & 0x02) << 4) | ((bitrate & 0x01) << 3);
|
rf_setup = (rf_setup & 0xD7) | ((bitrate & 0x02) << 4) | ((bitrate & 0x01) << 3);
|
||||||
NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup);
|
prev_power=(rf_setup>>1)&0x03; // Make sure prev_power is inline with current power
|
||||||
prev_power = NRF_POWER_0; // Power setting was just reset. This will get updated in the next call to SetPower
|
NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -168,9 +169,9 @@ void NRF24L01_SetPower()
|
|||||||
#endif
|
#endif
|
||||||
if(IS_RANGE_FLAG_on)
|
if(IS_RANGE_FLAG_on)
|
||||||
power=NRF_POWER_0;
|
power=NRF_POWER_0;
|
||||||
rf_setup = (rf_setup & 0xF9) | (power << 1);
|
|
||||||
if(prev_power != power)
|
if(prev_power != power)
|
||||||
{
|
{
|
||||||
|
rf_setup = (rf_setup & 0xF9) | (power << 1);
|
||||||
NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup);
|
NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup);
|
||||||
prev_power=power;
|
prev_power=power;
|
||||||
}
|
}
|
||||||
@ -682,4 +683,4 @@ void LT8900_WritePayload(uint8_t* msg, uint8_t len)
|
|||||||
NRF24L01_WritePayload(LT8900_buffer+LT8900_buffer_start,pos_final+pos-LT8900_buffer_start);
|
NRF24L01_WritePayload(LT8900_buffer+LT8900_buffer_start,pos_final+pos-LT8900_buffer_start);
|
||||||
}
|
}
|
||||||
// End of LT8900 emulation
|
// End of LT8900 emulation
|
||||||
#endif
|
#endif
|
@ -23,14 +23,14 @@
|
|||||||
#define SFHSS_PACKET_LEN 13
|
#define SFHSS_PACKET_LEN 13
|
||||||
#define SFHSS_TX_ID_LEN 2
|
#define SFHSS_TX_ID_LEN 2
|
||||||
|
|
||||||
uint8_t fhss_code; // 0-27
|
uint8_t fhss_code=0; // 0-27
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SFHSS_START = 0x00,
|
SFHSS_START = 0x00,
|
||||||
SFHSS_CAL = 0x01,
|
SFHSS_CAL = 0x01,
|
||||||
SFHSS_DATA1 = 0x02, // do not change this value
|
SFHSS_DATA1 = 0x02,
|
||||||
SFHSS_DATA2 = 0x0B, // do not change this value
|
SFHSS_DATA2 = 0x03,
|
||||||
SFHSS_TUNE = 0x0F
|
SFHSS_TUNE = 0x04
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SFHSS_FREQ0_VAL 0xC4
|
#define SFHSS_FREQ0_VAL 0xC4
|
||||||
@ -122,58 +122,78 @@ static void __attribute__((unused)) SFHSS_calc_next_chan()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*// Channel values are 10-bit values between 86 and 906, 496 is the middle.
|
|
||||||
// Values grow down and to the right.
|
|
||||||
static void __attribute__((unused)) SFHSS_build_data_packet()
|
|
||||||
{
|
|
||||||
#define spacer1 0x02
|
|
||||||
#define spacer2 (spacer1 << 4)
|
|
||||||
uint8_t ch_offset = phase == SFHSS_DATA1 ? 0 : 4;
|
|
||||||
uint16_t ch1 = convert_channel_16b_nolim(CH_AETR[ch_offset+0],86,906);
|
|
||||||
uint16_t ch2 = convert_channel_16b_nolim(CH_AETR[ch_offset+1],86,906);
|
|
||||||
uint16_t ch3 = convert_channel_16b_nolim(CH_AETR[ch_offset+2],86,906);
|
|
||||||
uint16_t ch4 = convert_channel_16b_nolim(CH_AETR[ch_offset+3],86,906);
|
|
||||||
|
|
||||||
packet[0] = 0x81; // can be 80 or 81 for Orange, only 81 for XK
|
|
||||||
packet[1] = rx_tx_addr[0];
|
|
||||||
packet[2] = rx_tx_addr[1];
|
|
||||||
packet[3] = 0;
|
|
||||||
packet[4] = 0;
|
|
||||||
packet[5] = (rf_ch_num << 3) | spacer1 | ((ch1 >> 9) & 0x01);
|
|
||||||
packet[6] = (ch1 >> 1);
|
|
||||||
packet[7] = (ch1 << 7) | spacer2 | ((ch2 >> 5) & 0x1F);
|
|
||||||
packet[8] = (ch2 << 3) | spacer1 | ((ch3 >> 9) & 0x01);
|
|
||||||
packet[9] = (ch3 >> 1);
|
|
||||||
packet[10] = (ch3 << 7) | spacer2 | ((ch4 >> 5) & 0x1F);
|
|
||||||
packet[11] = (ch4 << 3) | ((fhss_code >> 2) & 0x07);
|
|
||||||
packet[12] = (fhss_code << 6) | phase;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Channel values are 12-bit values between 1020 and 2020, 1520 is the middle.
|
// Channel values are 12-bit values between 1020 and 2020, 1520 is the middle.
|
||||||
// Futaba @140% is 2070...1520...970
|
// Futaba @140% is 2070...1520...970
|
||||||
// Values grow down and to the right.
|
// Values grow down and to the right.
|
||||||
static void __attribute__((unused)) SFHSS_build_data_packet()
|
static void __attribute__((unused)) SFHSS_build_data_packet()
|
||||||
{
|
{
|
||||||
uint8_t ch_offset = phase == SFHSS_DATA1 ? 0 : 4;
|
uint16_t ch1,ch2,ch3,ch4;
|
||||||
uint16_t ch1 = convert_channel_16b_nolim(CH_AETR[ch_offset+0],2020,1020);
|
// command.bit0 is the packet number indicator: =0 -> SFHSS_DATA1, =1 -> SFHSS_DATA2
|
||||||
uint16_t ch2 = convert_channel_16b_nolim(CH_AETR[ch_offset+1],2020,1020);
|
// command.bit1 is unknown but seems to be linked to the payload[0].bit0 but more dumps are needed: payload[0]=0x82 -> =0, payload[0]=0x81 -> =1
|
||||||
uint16_t ch3 = convert_channel_16b_nolim(CH_AETR[ch_offset+2],2020,1020);
|
// command.bit2 is the failsafe transmission indicator: =0 -> normal data, =1->failsafe data
|
||||||
uint16_t ch4 = convert_channel_16b_nolim(CH_AETR[ch_offset+3],2020,1020);
|
// command.bit3 is the channels indicator: =0 -> CH1-4, =1 -> CH5-8
|
||||||
|
|
||||||
|
//Coding below matches the Futaba T8J transmission scheme DATA1->CH1-4, DATA2->CH5-8, DATA1->CH5-8, DATA2->CH1-4,...
|
||||||
|
// XK, T10J and TM-FH are different with a classic DATA1->CH1-4, DATA2->CH5-8,...
|
||||||
|
//Failsafe is sent twice every couple of seconds (unknown but >5s)
|
||||||
|
|
||||||
|
uint8_t command= (phase == SFHSS_DATA1) ? 0 : 1; // Building packet for Data1 or Data2
|
||||||
|
counter+=command;
|
||||||
|
if( (counter&0x3FC) == 0x3FC )
|
||||||
|
{ // Transmit failsafe data twice every 7s
|
||||||
|
if( ((counter&1)^(command&1)) == 0 )
|
||||||
|
command|=0x04; // Failsafe
|
||||||
|
}
|
||||||
|
else
|
||||||
|
command|=0x02; // Assuming packet[0] == 0x81
|
||||||
|
counter&=0x3FF; // Reset failsafe counter
|
||||||
|
if(counter&1) command|=0x08; // Transmit lower and upper channels twice in a row
|
||||||
|
|
||||||
packet[0] = 0x81; // can be 80 or 81 for Orange, only 81 for XK
|
uint8_t ch_offset = ((command&0x08) >> 1) | ((command&0x04) << 1); // CH1..CH4 or CH5..CH8, if failsafe CH9..CH12 or CH13..CH16
|
||||||
|
ch1 = convert_channel_16b_nolim(CH_AETR[ch_offset+0],2020,1020);
|
||||||
|
ch2 = convert_channel_16b_nolim(CH_AETR[ch_offset+1],2020,1020);
|
||||||
|
ch3 = convert_channel_16b_nolim(CH_AETR[ch_offset+2],2020,1020);
|
||||||
|
ch4 = convert_channel_16b_nolim(CH_AETR[ch_offset+3],2020,1020);
|
||||||
|
|
||||||
|
if(command&0x04)
|
||||||
|
{ //Failsafe data are:
|
||||||
|
// 0 to 1023 -> no output on channel
|
||||||
|
// 1024-2047 -> hold output on channel
|
||||||
|
// 2048-4095 -> channel_output=(data&0x3FF)*5/4+880 in µs
|
||||||
|
// Notes:
|
||||||
|
// 2048-2559 -> does not look valid since it only covers the range from 1520µs to 2160µs
|
||||||
|
// 2560-3583 -> valid for any channel values from 880µs to 2160µs
|
||||||
|
// 3584-4095 -> looks to be used for the throttle channel with values ranging from 880µs to 1520µs
|
||||||
|
#ifdef SFHSS_FAILSAFE_CH9_16
|
||||||
|
ch1=((5360-ch1)<<2)/5; //((1520*2-ch1)<<2)/5+1856;
|
||||||
|
ch2=((5360-ch2)<<2)/5;
|
||||||
|
ch3=((5360-ch3)<<2)/5;
|
||||||
|
if((command&0x08)==0 && ch3<3072) // Throttle
|
||||||
|
ch3+=1024;
|
||||||
|
ch4=((5360-ch4)<<2)/5;
|
||||||
|
#else
|
||||||
|
ch1=1024;ch2=1024;ch4=1024; // All channels hold their positions
|
||||||
|
ch3=((command&0x08)==0)?3664:1024; // except throttle value set to 980µs
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// XK [0]=0x81 [3]=0x00 [4]=0x00
|
||||||
|
// T8J [0]=0x81 [3]=0x42 [4]=0x07
|
||||||
|
// T10J [0]=0x81 [3]=0x0F [4]=0x09
|
||||||
|
// TM-FH [0]=0x82 [3]=0x9A [4]=0x06
|
||||||
|
packet[0] = 0x81; // can be 80 or 81 for Orange, only 81 for XK
|
||||||
packet[1] = rx_tx_addr[0];
|
packet[1] = rx_tx_addr[0];
|
||||||
packet[2] = rx_tx_addr[1];
|
packet[2] = rx_tx_addr[1];
|
||||||
packet[3] = 0x0f; //10J
|
packet[3] = rx_tx_addr[2]; // ID?
|
||||||
packet[4] = 0x09; //10J
|
packet[4] = rx_tx_addr[3]; // ID?
|
||||||
packet[5] = (rf_ch_num << 3) | ((ch1 >> 9) & 0x07);
|
packet[5] = (rf_ch_num << 3) | ((ch1 >> 9) & 0x07);
|
||||||
packet[6] = (ch1 >> 1);
|
packet[6] = (ch1 >> 1);
|
||||||
packet[7] = (ch1 << 7) | ((ch2 >> 5) & 0x7F );
|
packet[7] = (ch1 << 7) | ((ch2 >> 5) & 0x7F );
|
||||||
packet[8] = (ch2 << 3) | ((ch3 >> 9) & 0x07);
|
packet[8] = (ch2 << 3) | ((ch3 >> 9) & 0x07 );
|
||||||
packet[9] = (ch3 >> 1);
|
packet[9] = (ch3 >> 1);
|
||||||
packet[10] = (ch3 << 7) | ((ch4 >> 5) & 0x7F );
|
packet[10] = (ch3 << 7) | ((ch4 >> 5) & 0x7F );
|
||||||
packet[11] = (ch4 << 3) | ((fhss_code >> 2) & 0x07 );
|
packet[11] = (ch4 << 3) | ((fhss_code >> 2) & 0x07 );
|
||||||
packet[12] = (fhss_code << 6) | phase;
|
packet[12] = (fhss_code << 6) | command;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) SFHSS_send_packet()
|
static void __attribute__((unused)) SFHSS_send_packet()
|
||||||
@ -197,28 +217,31 @@ uint16_t ReadSFHSS()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
rf_ch_num = 0;
|
rf_ch_num = 0;
|
||||||
|
counter = 0;
|
||||||
phase = SFHSS_DATA1;
|
phase = SFHSS_DATA1;
|
||||||
}
|
}
|
||||||
return 2000;
|
return 2000;
|
||||||
|
|
||||||
/* Work cycle, 6.8ms, second packet 1.65ms after first */
|
/* Work cycle: 6.8ms */
|
||||||
|
#define SFHSS_PACKET_PERIOD 6800
|
||||||
|
#define SFHSS_DATA2_TIMING 1630 // Adjust this value between 1600 and 1650 if your RX(s) are not operating properly
|
||||||
case SFHSS_DATA1:
|
case SFHSS_DATA1:
|
||||||
SFHSS_build_data_packet();
|
SFHSS_build_data_packet();
|
||||||
SFHSS_send_packet();
|
SFHSS_send_packet();
|
||||||
phase = SFHSS_DATA2;
|
phase = SFHSS_DATA2;
|
||||||
return 1650;
|
return SFHSS_DATA2_TIMING; // original 1650
|
||||||
case SFHSS_DATA2:
|
case SFHSS_DATA2:
|
||||||
SFHSS_build_data_packet();
|
SFHSS_build_data_packet();
|
||||||
SFHSS_send_packet();
|
SFHSS_send_packet();
|
||||||
SFHSS_calc_next_chan();
|
SFHSS_calc_next_chan();
|
||||||
phase = SFHSS_TUNE;
|
phase = SFHSS_TUNE;
|
||||||
return 2000;
|
return (SFHSS_PACKET_PERIOD -2000 -SFHSS_DATA2_TIMING); // original 2000
|
||||||
case SFHSS_TUNE:
|
case SFHSS_TUNE:
|
||||||
phase = SFHSS_DATA1;
|
phase = SFHSS_DATA1;
|
||||||
SFHSS_tune_freq();
|
SFHSS_tune_freq();
|
||||||
SFHSS_tune_chan_fast();
|
SFHSS_tune_chan_fast();
|
||||||
CC2500_SetPower();
|
CC2500_SetPower();
|
||||||
return 3150;
|
return 2000; // original 3150
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -226,13 +249,13 @@ uint16_t ReadSFHSS()
|
|||||||
// Generate internal id
|
// Generate internal id
|
||||||
static void __attribute__((unused)) SFHSS_get_tx_id()
|
static void __attribute__((unused)) SFHSS_get_tx_id()
|
||||||
{
|
{
|
||||||
uint32_t fixed_id;
|
|
||||||
// Some receivers (Orange) behaves better if they tuned to id that has
|
// Some receivers (Orange) behaves better if they tuned to id that has
|
||||||
// no more than 6 consecutive zeros and ones
|
// no more than 6 consecutive zeros and ones
|
||||||
|
uint32_t fixed_id;
|
||||||
uint8_t run_count = 0;
|
uint8_t run_count = 0;
|
||||||
// add guard for bit count
|
// add guard for bit count
|
||||||
fixed_id = 1 ^ (MProtocol_id & 1);
|
fixed_id = 1 ^ (MProtocol_id & 1);
|
||||||
for (uint8_t i = 0; i < 16; ++i)
|
for (uint8_t i = 0; i < 32; ++i)
|
||||||
{
|
{
|
||||||
fixed_id = (fixed_id << 1) | (MProtocol_id & 1);
|
fixed_id = (fixed_id << 1) | (MProtocol_id & 1);
|
||||||
MProtocol_id >>= 1;
|
MProtocol_id >>= 1;
|
||||||
@ -249,8 +272,10 @@ static void __attribute__((unused)) SFHSS_get_tx_id()
|
|||||||
run_count = 0;
|
run_count = 0;
|
||||||
}
|
}
|
||||||
// fixed_id = 0xBC11;
|
// fixed_id = 0xBC11;
|
||||||
rx_tx_addr[0] = fixed_id >> 8;
|
rx_tx_addr[0] = fixed_id >> 24;
|
||||||
rx_tx_addr[1] = fixed_id;
|
rx_tx_addr[1] = fixed_id >> 16;
|
||||||
|
rx_tx_addr[2] = fixed_id >> 8;
|
||||||
|
rx_tx_addr[3] = fixed_id >> 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t initSFHSS()
|
uint16_t initSFHSS()
|
||||||
@ -258,7 +283,7 @@ uint16_t initSFHSS()
|
|||||||
BIND_DONE; // Not a TX bind protocol
|
BIND_DONE; // Not a TX bind protocol
|
||||||
SFHSS_get_tx_id();
|
SFHSS_get_tx_id();
|
||||||
|
|
||||||
fhss_code=rx_tx_addr[2]%28; // Initialize it to random 0-27 inclusive
|
fhss_code=random(0xfefefefe)%28; // Initialize it to random 0-27 inclusive
|
||||||
|
|
||||||
SFHSS_rf_init();
|
SFHSS_rf_init();
|
||||||
phase = SFHSS_START;
|
phase = SFHSS_START;
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
// compatible with Syma X5C-1, X11, X11C, X12 and for sub protocol X5C Syma X5C (original), X2
|
// compatible with Syma X5C-1, X11, X11C, X12 and for sub protocol X5C Syma X5C (original), X2
|
||||||
// Last sync with hexfet new_protocols/cx10_nrf24l01.c dated 2015-09-28
|
|
||||||
|
|
||||||
#if defined(SYMAX_NRF24L01_INO)
|
#if defined(SYMAX_NRF24L01_INO)
|
||||||
|
|
||||||
@ -30,6 +29,7 @@
|
|||||||
#define SYMAX_FLAG_VIDEO 0x02
|
#define SYMAX_FLAG_VIDEO 0x02
|
||||||
#define SYMAX_FLAG_PICTURE 0x04
|
#define SYMAX_FLAG_PICTURE 0x04
|
||||||
#define SYMAX_FLAG_HEADLESS 0x08
|
#define SYMAX_FLAG_HEADLESS 0x08
|
||||||
|
#define SYMAX_XTRM_RATES 0x10
|
||||||
|
|
||||||
#define SYMAX_PAYLOADSIZE 10 // receive data pipes set to this size, but unused
|
#define SYMAX_PAYLOADSIZE 10 // receive data pipes set to this size, but unused
|
||||||
#define SYMAX_MAX_PACKET_LENGTH 16 // X11,X12,X5C-1 10-byte, X5C 16-byte
|
#define SYMAX_MAX_PACKET_LENGTH 16 // X11,X12,X5C-1 10-byte, X5C 16-byte
|
||||||
@ -58,6 +58,7 @@ static void __attribute__((unused)) SYMAX_read_controls()
|
|||||||
{
|
{
|
||||||
// Protocol is registered AETRF, that is
|
// Protocol is registered AETRF, that is
|
||||||
// Aileron is channel 1, Elevator - 2, Throttle - 3, Rudder - 4, Flip control - 5
|
// Aileron is channel 1, Elevator - 2, Throttle - 3, Rudder - 4, Flip control - 5
|
||||||
|
// Extended (trim-added) Rates - 6, Photo - 7, Video - 8, Headless - 9
|
||||||
aileron = convert_channel_s8b(AILERON);
|
aileron = convert_channel_s8b(AILERON);
|
||||||
elevator = convert_channel_s8b(ELEVATOR);
|
elevator = convert_channel_s8b(ELEVATOR);
|
||||||
throttle = convert_channel_8b(THROTTLE);
|
throttle = convert_channel_8b(THROTTLE);
|
||||||
@ -67,6 +68,9 @@ static void __attribute__((unused)) SYMAX_read_controls()
|
|||||||
// Channel 5
|
// Channel 5
|
||||||
if (Servo_AUX1)
|
if (Servo_AUX1)
|
||||||
flags = SYMAX_FLAG_FLIP;
|
flags = SYMAX_FLAG_FLIP;
|
||||||
|
// Channel 6
|
||||||
|
if (Servo_AUX2)
|
||||||
|
flags |= SYMAX_XTRM_RATES;
|
||||||
// Channel 7
|
// Channel 7
|
||||||
if (Servo_AUX3)
|
if (Servo_AUX3)
|
||||||
flags |= SYMAX_FLAG_PICTURE;
|
flags |= SYMAX_FLAG_PICTURE;
|
||||||
@ -75,7 +79,10 @@ static void __attribute__((unused)) SYMAX_read_controls()
|
|||||||
flags |= SYMAX_FLAG_VIDEO;
|
flags |= SYMAX_FLAG_VIDEO;
|
||||||
// Channel 9
|
// Channel 9
|
||||||
if (Servo_AUX5)
|
if (Servo_AUX5)
|
||||||
|
{
|
||||||
flags |= SYMAX_FLAG_HEADLESS;
|
flags |= SYMAX_FLAG_HEADLESS;
|
||||||
|
flags &= ~SYMAX_XTRM_RATES; // Extended rates & headless incompatible
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define X5C_CHAN2TRIM(X) ((((X) & 0x80 ? 0xff - (X) : 0x80 + (X)) >> 2) + 0x20)
|
#define X5C_CHAN2TRIM(X) ((((X) & 0x80 ? 0xff - (X) : 0x80 + (X)) >> 2) + 0x20)
|
||||||
@ -98,9 +105,18 @@ static void __attribute__((unused)) SYMAX_build_packet_x5c(uint8_t bind)
|
|||||||
packet[1] = rudder;
|
packet[1] = rudder;
|
||||||
packet[2] = elevator ^ 0x80; // reversed from default
|
packet[2] = elevator ^ 0x80; // reversed from default
|
||||||
packet[3] = aileron;
|
packet[3] = aileron;
|
||||||
packet[4] = X5C_CHAN2TRIM(rudder ^ 0x80);// drive trims for extra control range
|
if (flags & SYMAX_XTRM_RATES)
|
||||||
packet[5] = X5C_CHAN2TRIM(elevator);
|
{ // drive trims for extra control range
|
||||||
packet[6] = X5C_CHAN2TRIM(aileron ^ 0x80);
|
packet[4] = X5C_CHAN2TRIM(rudder ^ 0x80);
|
||||||
|
packet[5] = X5C_CHAN2TRIM(elevator);
|
||||||
|
packet[6] = X5C_CHAN2TRIM(aileron ^ 0x80);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet[4] = 0x00;
|
||||||
|
packet[5] = 0x00;
|
||||||
|
packet[6] = 0x00;
|
||||||
|
}
|
||||||
packet[7] = 0xae;
|
packet[7] = 0xae;
|
||||||
packet[8] = 0xa9;
|
packet[8] = 0xa9;
|
||||||
packet[9] = 0x00;
|
packet[9] = 0x00;
|
||||||
@ -138,9 +154,15 @@ static void __attribute__((unused)) SYMAX_build_packet(uint8_t bind)
|
|||||||
packet[2] = rudder;
|
packet[2] = rudder;
|
||||||
packet[3] = aileron;
|
packet[3] = aileron;
|
||||||
packet[4] = (flags & SYMAX_FLAG_VIDEO ? 0x80 : 0x00) | (flags & SYMAX_FLAG_PICTURE ? 0x40 : 0x00);
|
packet[4] = (flags & SYMAX_FLAG_VIDEO ? 0x80 : 0x00) | (flags & SYMAX_FLAG_PICTURE ? 0x40 : 0x00);
|
||||||
packet[5] = (elevator >> 2) | 0xc0; //always high rates (bit 7 is rate control)
|
packet[5] = 0xc0; //always high rates (bit 7 is rate control)
|
||||||
packet[6] = (rudder >> 2) | (flags & SYMAX_FLAG_FLIP ? 0x40 : 0x00);
|
packet[6] = flags & SYMAX_FLAG_FLIP ? 0x40 : 0x00;
|
||||||
packet[7] = (aileron >> 2) | (flags & SYMAX_FLAG_HEADLESS ? 0x80 : 0x00);
|
packet[7] = flags & SYMAX_FLAG_HEADLESS ? 0x80 : 0x00;
|
||||||
|
if (flags & SYMAX_XTRM_RATES)
|
||||||
|
{ // use trims to extend controls
|
||||||
|
packet[5] |= elevator >> 2;
|
||||||
|
packet[6] |= rudder >> 2;
|
||||||
|
packet[7] |= aileron >> 2;
|
||||||
|
}
|
||||||
packet[8] = 0x00;
|
packet[8] = 0x00;
|
||||||
}
|
}
|
||||||
packet[9] = SYMAX_checksum(packet);
|
packet[9] = SYMAX_checksum(packet);
|
||||||
|
@ -31,6 +31,34 @@ uint8_t RetrySequence ;
|
|||||||
uint8_t sport_counter=0;
|
uint8_t sport_counter=0;
|
||||||
uint8_t RxBt = 0;
|
uint8_t RxBt = 0;
|
||||||
uint8_t sport = 0;
|
uint8_t sport = 0;
|
||||||
|
#define MAX_PKTX 10
|
||||||
|
#define FX_BUFFERS 4
|
||||||
|
uint8_t pktx[MAX_PKTX];
|
||||||
|
uint8_t pktx1[FRSKY_SPORT_PACKET_SIZE*FX_BUFFERS];
|
||||||
|
uint8_t indx;
|
||||||
|
//struct t_fx_rx_packet
|
||||||
|
//{
|
||||||
|
// uint8_t validSequence ;
|
||||||
|
// uint8_t count ;
|
||||||
|
// uint8_t payload[6] ;
|
||||||
|
//} ;
|
||||||
|
|
||||||
|
// Store for out of sequence packet
|
||||||
|
//struct t_fx_rx_packet FrskyxRxTelemetry ;
|
||||||
|
|
||||||
|
uint8_t FrskyxRxTelemetryValidSequence ;
|
||||||
|
|
||||||
|
struct t_fx_rx_frame
|
||||||
|
{
|
||||||
|
uint8_t valid ;
|
||||||
|
uint8_t count ;
|
||||||
|
uint8_t payload[6] ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
// Store for FrskyX telemetry
|
||||||
|
struct t_fx_rx_frame FrskyxRxFrames[4] ;
|
||||||
|
uint8_t NextFxFrameToForward ;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#if defined HUB_TELEMETRY
|
#if defined HUB_TELEMETRY
|
||||||
#define USER_MAX_BYTES 6
|
#define USER_MAX_BYTES 6
|
||||||
@ -40,10 +68,6 @@ uint8_t RetrySequence ;
|
|||||||
#define START_STOP 0x7e
|
#define START_STOP 0x7e
|
||||||
#define BYTESTUFF 0x7d
|
#define BYTESTUFF 0x7d
|
||||||
#define STUFF_MASK 0x20
|
#define STUFF_MASK 0x20
|
||||||
#define MAX_PKTX 10
|
|
||||||
uint8_t pktx[MAX_PKTX];
|
|
||||||
uint8_t pktx1[MAX_PKTX];
|
|
||||||
uint8_t indx;
|
|
||||||
uint8_t frame[18];
|
uint8_t frame[18];
|
||||||
|
|
||||||
#if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) )
|
#if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) )
|
||||||
@ -155,7 +179,8 @@ void frskySendStuffed()
|
|||||||
|
|
||||||
void frsky_check_telemetry(uint8_t *pkt,uint8_t len)
|
void frsky_check_telemetry(uint8_t *pkt,uint8_t len)
|
||||||
{
|
{
|
||||||
if(pkt[1] == rx_tx_addr[3] && pkt[2] == rx_tx_addr[2] && len ==(pkt[0] + 3))
|
uint8_t clen = pkt[0] + 3 ;
|
||||||
|
if(pkt[1] == rx_tx_addr[3] && pkt[2] == rx_tx_addr[2] && len == clen )
|
||||||
{
|
{
|
||||||
telemetry_link|=1; // Telemetry data is available
|
telemetry_link|=1; // Telemetry data is available
|
||||||
/*previous version
|
/*previous version
|
||||||
@ -205,19 +230,144 @@ void frsky_check_telemetry(uint8_t *pkt,uint8_t len)
|
|||||||
telemetry_lost=0;
|
telemetry_lost=0;
|
||||||
if (protocol==MODE_FRSKYX)
|
if (protocol==MODE_FRSKYX)
|
||||||
{
|
{
|
||||||
if ((pktt[5] >> 4 & 0x0f) == 0x08)
|
uint16_t lcrc = crc_x(&pkt[3], len-7 ) ;
|
||||||
{
|
// if ( ( sub_protocol & 2 ) == 0 )
|
||||||
seq_last_sent = 8;
|
// {
|
||||||
seq_last_rcvd = 0;
|
// if ( ( (lcrc >> 8) == pkt[len-4]) && ( (lcrc & 0x00FF ) == pkt[len-3]) )
|
||||||
pass=0;
|
// {
|
||||||
}
|
// lcrc = 0 ;
|
||||||
else
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// lcrc = 1 ;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if ( lcrc == 0 )
|
||||||
|
|
||||||
|
if ( ( (lcrc >> 8) == pkt[len-4]) && ( (lcrc & 0x00FF ) == pkt[len-3]) )
|
||||||
{
|
{
|
||||||
if ((pktt[5] >> 4 & 0x03) == (seq_last_rcvd + 1) % 4)
|
// Check if in sequence
|
||||||
seq_last_rcvd = (seq_last_rcvd + 1) % 4;
|
if ( (pkt[5] & 0x0F) == 0x08 )
|
||||||
|
{
|
||||||
|
FrX_receive_seq = 0x08 ;
|
||||||
|
NextFxFrameToForward = 0 ;
|
||||||
|
FrskyxRxFrames[0].valid = 0 ;
|
||||||
|
FrskyxRxFrames[1].valid = 0 ;
|
||||||
|
FrskyxRxFrames[2].valid = 0 ;
|
||||||
|
FrskyxRxFrames[3].valid = 0 ;
|
||||||
|
}
|
||||||
|
else if ( (pkt[5] & 0x03) == (FrX_receive_seq & 0x03 ) )
|
||||||
|
{
|
||||||
|
// OK to process
|
||||||
|
struct t_fx_rx_frame *p ;
|
||||||
|
uint8_t count ;
|
||||||
|
p = &FrskyxRxFrames[FrX_receive_seq & 3] ;
|
||||||
|
count = pkt[6] ;
|
||||||
|
if ( count <= 6 )
|
||||||
|
{
|
||||||
|
p->count = count ;
|
||||||
|
for ( uint8_t i = 0 ; i < count ; i += 1 )
|
||||||
|
{
|
||||||
|
p->payload[i] = pkt[i+7] ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->count = 0 ;
|
||||||
|
}
|
||||||
|
p->valid = 1 ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FrX_receive_seq = ( FrX_receive_seq + 1 ) & 0x03 ;
|
||||||
|
|
||||||
|
if ( FrskyxRxTelemetryValidSequence & 0x80 )
|
||||||
|
{
|
||||||
|
FrX_receive_seq = ( FrskyxRxTelemetryValidSequence + 1 ) & 3 ;
|
||||||
|
FrskyxRxTelemetryValidSequence &= 0x7F ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if ( FrskyxRxTelemetry.validSequence & 0x80 )
|
||||||
|
// {
|
||||||
|
// FrX_receive_seq = ( FrskyxRxTelemetry.validSequence + 1 ) & 3 ;
|
||||||
|
|
||||||
|
// FrskyxRxTelemetry.validSequence &= 0x7F ;
|
||||||
|
|
||||||
|
// }
|
||||||
|
}
|
||||||
else
|
else
|
||||||
pass=0;//reset if sequence wrong
|
{
|
||||||
|
// Save and request correct packet
|
||||||
|
// struct t_fx_rx_packet *p ;
|
||||||
|
struct t_fx_rx_frame *q ;
|
||||||
|
uint8_t count ;
|
||||||
|
// pkt[4] RSSI
|
||||||
|
// pkt[5] sequence control
|
||||||
|
// pkt[6] payload count
|
||||||
|
// pkt[7-12] payload
|
||||||
|
pktt[6] = 0 ; // Don't process
|
||||||
|
if ( (pkt[5] & 0x03) == ( ( FrX_receive_seq +1 ) & 3 ) )
|
||||||
|
{
|
||||||
|
q = &FrskyxRxFrames[(pkt[5] & 0x03)] ;
|
||||||
|
count = pkt[6] ;
|
||||||
|
if ( count <= 6 )
|
||||||
|
{
|
||||||
|
q->count = count ;
|
||||||
|
for ( uint8_t i = 0 ; i < count ; i += 1 )
|
||||||
|
{
|
||||||
|
q->payload[i] = pkt[i+7] ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
q->count = 0 ;
|
||||||
|
}
|
||||||
|
q->valid = 1 ;
|
||||||
|
|
||||||
|
FrskyxRxTelemetryValidSequence = 0x80 | ( pkt[5] & 0x03 ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// p = &FrskyxRxTelemetry ;
|
||||||
|
// count = pkt[6] ;
|
||||||
|
// if ( count <= 6 )
|
||||||
|
// {
|
||||||
|
// p->count = count ;
|
||||||
|
// for ( uint8_t i = 0 ; i < count ; i += 1 )
|
||||||
|
// {
|
||||||
|
// p->payload[i] = pkt[i+7] ;
|
||||||
|
// }
|
||||||
|
// p->validSequence = 0x80 | ( pkt[5] & 0x03 ) ;
|
||||||
|
// }
|
||||||
|
FrX_receive_seq = ( FrX_receive_seq & 0x03 ) | 0x04 ; // Request re-transmission
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((pktt[5] >> 4) & 0x0f) == 0x08)
|
||||||
|
{
|
||||||
|
FrX_send_seq = 0 ;
|
||||||
|
// FrX_receive_seq = 0x08 ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// packet[21] = (FrX_receive_seq << 4) | FrX_send_seq ;//8 at start
|
||||||
|
// if ( FrX_send_seq != 0x08 )
|
||||||
|
// {
|
||||||
|
// FrX_send_seq = ( FrX_send_seq + 1 ) & 0x03 ;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if ((pktt[5] >> 4 & 0x0f) == 0x08)
|
||||||
|
// {
|
||||||
|
// seq_last_sent = 8;
|
||||||
|
// seq_last_rcvd = 0;
|
||||||
|
// pass=0;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// if ((pktt[5] >> 4 & 0x03) == (seq_last_rcvd + 1) % 4)
|
||||||
|
// seq_last_rcvd = (seq_last_rcvd + 1) % 4;
|
||||||
|
// else
|
||||||
|
// pass=0;//reset if sequence wrong
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -363,12 +513,25 @@ pkt[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
|||||||
0x34 0x0A 0xC3 0x56 0xF3
|
0x34 0x0A 0xC3 0x56 0xF3
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const uint8_t PROGMEM Indices[] = { 0x00, 0xA1, 0x22, 0x83, 0xE4, 0x45,
|
||||||
|
0xC6, 0x67, 0x48, 0xE9, 0x6A, 0xCB,
|
||||||
|
0xAC, 0x0D, 0x8E, 0x2F, 0xD0, 0x71,
|
||||||
|
0xF2, 0x53, 0x34, 0x95, 0x16, 0xB7,
|
||||||
|
0x98, 0x39, 0xBA, 0x1B } ;
|
||||||
|
|
||||||
|
|
||||||
#ifdef MULTI_TELEMETRY
|
#ifdef MULTI_TELEMETRY
|
||||||
void sportSend(uint8_t *p)
|
void sportSend(uint8_t *p)
|
||||||
{
|
{
|
||||||
multi_send_header(MULTI_TELEMETRY_SPORT, 9);
|
multi_send_header(MULTI_TELEMETRY_SPORT, 9);
|
||||||
uint16_t crc_s = 0;
|
uint16_t crc_s = 0;
|
||||||
Serial_write(p[0]) ;
|
uint8_t x = p[0] ;
|
||||||
|
if ( x <= 0x1B )
|
||||||
|
{
|
||||||
|
x = pgm_read_byte_near( &Indices[x] ) ;
|
||||||
|
}
|
||||||
|
Serial_write(x) ;
|
||||||
for (uint8_t i = 1; i < 9; i++)
|
for (uint8_t i = 1; i < 9; i++)
|
||||||
{
|
{
|
||||||
if (i == 8)
|
if (i == 8)
|
||||||
@ -462,7 +625,13 @@ void sportSendFrame()
|
|||||||
{
|
{
|
||||||
for (i=0;i<FRSKY_SPORT_PACKET_SIZE;i++)
|
for (i=0;i<FRSKY_SPORT_PACKET_SIZE;i++)
|
||||||
frame[i]=pktx1[i];
|
frame[i]=pktx1[i];
|
||||||
sport=0;
|
sport -= 1 ;
|
||||||
|
if ( sport )
|
||||||
|
{
|
||||||
|
uint8_t j = sport * FRSKY_SPORT_PACKET_SIZE ;
|
||||||
|
for (i=0;i<j;i++)
|
||||||
|
pktx1[i] = pktx1[i+FRSKY_SPORT_PACKET_SIZE] ;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -506,19 +675,20 @@ void proces_sport_data(uint8_t data)
|
|||||||
} // end switch
|
} // end switch
|
||||||
if (indx >= FRSKY_SPORT_PACKET_SIZE)
|
if (indx >= FRSKY_SPORT_PACKET_SIZE)
|
||||||
{//8 bytes no crc
|
{//8 bytes no crc
|
||||||
if ( sport )
|
if ( sport < FX_BUFFERS )
|
||||||
{
|
|
||||||
// overrun!
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
uint8_t dest = sport * FRSKY_SPORT_PACKET_SIZE ;
|
||||||
uint8_t i ;
|
uint8_t i ;
|
||||||
for ( i = 0 ; i < FRSKY_SPORT_PACKET_SIZE ; i += 1 )
|
for ( i = 0 ; i < FRSKY_SPORT_PACKET_SIZE ; i += 1 )
|
||||||
{
|
{
|
||||||
pktx1[i] = pktx[i] ; // Double buffer
|
pktx1[dest++] = pktx[i] ; // Triple buffer
|
||||||
}
|
}
|
||||||
sport = 1;//ok to send
|
sport += 1 ;//ok to send
|
||||||
}
|
}
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // Overrun
|
||||||
|
// }
|
||||||
pass = 0;//reset
|
pass = 0;//reset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -534,11 +704,14 @@ void TelemetryUpdate()
|
|||||||
h = SerialControl.head ;
|
h = SerialControl.head ;
|
||||||
t = SerialControl.tail ;
|
t = SerialControl.tail ;
|
||||||
if ( h >= t )
|
if ( h >= t )
|
||||||
t += 128 - h ;
|
t += 192 - h ;
|
||||||
else
|
else
|
||||||
t -= h ;
|
t -= h ;
|
||||||
|
// if ( t < 32 )
|
||||||
if ( t < 64 )
|
if ( t < 64 )
|
||||||
|
{
|
||||||
return ;
|
return ;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
uint8_t h ;
|
uint8_t h ;
|
||||||
uint8_t t ;
|
uint8_t t ;
|
||||||
@ -549,7 +722,9 @@ void TelemetryUpdate()
|
|||||||
else
|
else
|
||||||
t -= h ;
|
t -= h ;
|
||||||
if ( t < 32 )
|
if ( t < 32 )
|
||||||
|
{
|
||||||
return ;
|
return ;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) )
|
#if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) )
|
||||||
{
|
{
|
||||||
@ -566,15 +741,62 @@ void TelemetryUpdate()
|
|||||||
#if defined SPORT_TELEMETRY
|
#if defined SPORT_TELEMETRY
|
||||||
if (protocol==MODE_FRSKYX)
|
if (protocol==MODE_FRSKYX)
|
||||||
{ // FrSkyX
|
{ // FrSkyX
|
||||||
|
// struct t_fx_rx_frame *p ;
|
||||||
|
// uint8_t count ;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
struct t_fx_rx_frame *p ;
|
||||||
|
uint8_t count ;
|
||||||
|
p = &FrskyxRxFrames[NextFxFrameToForward] ;
|
||||||
|
if ( p->valid )
|
||||||
|
{
|
||||||
|
count = p->count ;
|
||||||
|
for (uint8_t i=0; i < count ; i++)
|
||||||
|
proces_sport_data(p->payload[i]) ;
|
||||||
|
p->valid = 0 ; // Sent on
|
||||||
|
NextFxFrameToForward = ( NextFxFrameToForward + 1 ) & 3 ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// p = &FrskyxRxFrames[NextFxFrameToForward] ;
|
||||||
|
// if ( p->valid )
|
||||||
|
// {
|
||||||
|
// count = p->count ;
|
||||||
|
// for (uint8_t i=0; i < count ; i++)
|
||||||
|
// proces_sport_data(p->payload[i]) ;
|
||||||
|
// p->valid = 0 ; // Sent on
|
||||||
|
// NextFxFrameToForward = ( NextFxFrameToForward + 1 ) & 3 ;
|
||||||
|
// }
|
||||||
|
|
||||||
if(telemetry_link)
|
if(telemetry_link)
|
||||||
{
|
{
|
||||||
if(pktt[4] & 0x80)
|
if(pktt[4] & 0x80)
|
||||||
RX_RSSI=pktt[4] & 0x7F ;
|
RX_RSSI=pktt[4] & 0x7F ;
|
||||||
else
|
else
|
||||||
RxBt = (pktt[4]<<1) + 1 ;
|
RxBt = (pktt[4]<<1) + 1 ;
|
||||||
if(pktt[6] && pktt[6]<=6)
|
|
||||||
for (uint8_t i=0; i < pktt[6]; i++)
|
// if(pktt[6] && pktt[6]<=6)
|
||||||
proces_sport_data(pktt[7+i]);
|
// {
|
||||||
|
// for (uint8_t i=0; i < pktt[6]; i++)
|
||||||
|
// proces_sport_data(pktt[7+i]);
|
||||||
|
// if ( FrskyxRxTelemetry.validSequence & 0x80 )
|
||||||
|
// {
|
||||||
|
// // Process out of sequence packet
|
||||||
|
// for (uint8_t i=0; i < FrskyxRxTelemetry.count ; i++)
|
||||||
|
// {
|
||||||
|
// proces_sport_data( FrskyxRxTelemetry.payload[i] ) ;
|
||||||
|
// }
|
||||||
|
//// FrX_receive_seq = ( FrskyxRxTelemetry.validSequence + 1 ) & 3 ;
|
||||||
|
// FrskyxRxTelemetry.validSequence = 0 ;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
telemetry_link=0;
|
telemetry_link=0;
|
||||||
}
|
}
|
||||||
uint32_t now = micros();
|
uint32_t now = micros();
|
||||||
@ -928,7 +1150,13 @@ ISR(TIMER0_COMPB_vect)
|
|||||||
{
|
{
|
||||||
GPIOR0 = ptr->data[ptr->tail] ;
|
GPIOR0 = ptr->data[ptr->tail] ;
|
||||||
GPIOR2 = ptr->data[ptr->tail+1] ;
|
GPIOR2 = ptr->data[ptr->tail+1] ;
|
||||||
ptr->tail = ( ptr->tail + 2 ) & 0x7F ;
|
uint8_t nextTail ;
|
||||||
|
nextTail = ptr->tail + 2 ;
|
||||||
|
if ( nextTail > 192 )
|
||||||
|
{
|
||||||
|
nextTail = 0 ;
|
||||||
|
}
|
||||||
|
ptr->tail = nextTail ;
|
||||||
GPIOR1 = 8 ;
|
GPIOR1 = 8 ;
|
||||||
OCR0A = OCR0B + 40 ;
|
OCR0A = OCR0B + 40 ;
|
||||||
OCR0B = OCR0A + 8 * 20 ;
|
OCR0B = OCR0A + 8 * 20 ;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#if not defined (ORANGE_TX) && not defined (STM32_BOARD)
|
#if not defined (ORANGE_TX) && not defined (STM32_BOARD)
|
||||||
//Atmega328p
|
//Atmega328p
|
||||||
#if not defined(ARDUINO_AVR_PRO) && not defined(ARDUINO_AVR_MINI) && not defined(ARDUINO_AVR_NANO)
|
#if not defined(ARDUINO_AVR_PRO) && not defined(ARDUINO_MULTI_NO_BOOT) && not defined(ARDUINO_MULTI_FLASH_FROM_TX) && not defined(ARDUINO_AVR_MINI) && not defined(ARDUINO_AVR_NANO)
|
||||||
#error You must select one of these boards: "Multi 4-in-1", "Arduino Pro or Pro Mini" or "Arduino Mini"
|
#error You must select one of these boards: "Multi 4-in-1", "Arduino Pro or Pro Mini" or "Arduino Mini"
|
||||||
#endif
|
#endif
|
||||||
#if F_CPU != 16000000L || not defined(__AVR_ATmega328P__)
|
#if F_CPU != 16000000L || not defined(__AVR_ATmega328P__)
|
||||||
@ -18,6 +18,14 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//Change/Force configuration for the bootloader option
|
||||||
|
#if defined ARDUINO_MULTI_FLASH_FROM_TX
|
||||||
|
#define CHECK_FOR_BOOTLOADER
|
||||||
|
#endif
|
||||||
|
#if defined ARDUINO_MULTI_NO_BOOT
|
||||||
|
#undef CHECK_FOR_BOOTLOADER
|
||||||
|
#endif
|
||||||
|
|
||||||
//Change/Force configuration if OrangeTX
|
//Change/Force configuration if OrangeTX
|
||||||
#ifdef ORANGE_TX
|
#ifdef ORANGE_TX
|
||||||
#undef ENABLE_PPM // Disable PPM for OrangeTX module
|
#undef ENABLE_PPM // Disable PPM for OrangeTX module
|
||||||
@ -70,6 +78,7 @@
|
|||||||
#undef HONTAI_NRF24L01_INO
|
#undef HONTAI_NRF24L01_INO
|
||||||
#undef Q303_NRF24L01_INO
|
#undef Q303_NRF24L01_INO
|
||||||
#undef GW008_NRF24L01_INO
|
#undef GW008_NRF24L01_INO
|
||||||
|
#undef DM002_NRF24L01_INO
|
||||||
#undef CABELL_NRF24L01_INO
|
#undef CABELL_NRF24L01_INO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -79,6 +88,7 @@
|
|||||||
#undef AFHDS2A_FW_TELEMETRY
|
#undef AFHDS2A_FW_TELEMETRY
|
||||||
#undef AFHDS2A_HUB_TELEMETRY
|
#undef AFHDS2A_HUB_TELEMETRY
|
||||||
#undef BAYANG_HUB_TELEMETRY
|
#undef BAYANG_HUB_TELEMETRY
|
||||||
|
#undef CABELL_HUB_TELEMETRY
|
||||||
#undef HUBSAN_HUB_TELEMETRY
|
#undef HUBSAN_HUB_TELEMETRY
|
||||||
#undef HUB_TELEMETRY
|
#undef HUB_TELEMETRY
|
||||||
#undef SPORT_TELEMETRY
|
#undef SPORT_TELEMETRY
|
||||||
@ -92,6 +102,9 @@
|
|||||||
#if not defined(BAYANG_NRF24L01_INO)
|
#if not defined(BAYANG_NRF24L01_INO)
|
||||||
#undef BAYANG_HUB_TELEMETRY
|
#undef BAYANG_HUB_TELEMETRY
|
||||||
#endif
|
#endif
|
||||||
|
#if not defined(CABELL_NRF24L01_INO)
|
||||||
|
#undef CABELL_HUB_TELEMETRY
|
||||||
|
#endif
|
||||||
#if not defined(HUBSAN_A7105_INO)
|
#if not defined(HUBSAN_A7105_INO)
|
||||||
#undef HUBSAN_HUB_TELEMETRY
|
#undef HUBSAN_HUB_TELEMETRY
|
||||||
#endif
|
#endif
|
||||||
@ -108,7 +121,7 @@
|
|||||||
#if not defined(DSM_CYRF6936_INO)
|
#if not defined(DSM_CYRF6936_INO)
|
||||||
#undef DSM_TELEMETRY
|
#undef DSM_TELEMETRY
|
||||||
#endif
|
#endif
|
||||||
#if not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS)
|
#if not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS)
|
||||||
#undef TELEMETRY
|
#undef TELEMETRY
|
||||||
#undef INVERT_TELEMETRY
|
#undef INVERT_TELEMETRY
|
||||||
#endif
|
#endif
|
||||||
@ -142,4 +155,4 @@
|
|||||||
#endif
|
#endif
|
||||||
#if MAX_PPM_CHANNELS>16
|
#if MAX_PPM_CHANNELS>16
|
||||||
#error MAX_PPM_CHANNELS must be below or equal to 16. The default for this value is 16.
|
#error MAX_PPM_CHANNELS must be below or equal to 16. The default for this value is 16.
|
||||||
#endif
|
#endif
|
@ -49,6 +49,13 @@
|
|||||||
//The goal is to prevent binding other people's model when powering up the TX, changing model or scanning through protocols.
|
//The goal is to prevent binding other people's model when powering up the TX, changing model or scanning through protocols.
|
||||||
#define WAIT_FOR_BIND
|
#define WAIT_FOR_BIND
|
||||||
|
|
||||||
|
/*************************/
|
||||||
|
/*** BOOTLOADER USE ***/
|
||||||
|
/*************************/
|
||||||
|
//Allow flashing multimodule directly with TX(erky9x or opentx modified firmwares)
|
||||||
|
//Check https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/tree/master/BootLoaders
|
||||||
|
//To enable this feature remove the "//" on the next line. It is automatically enabled/disabled when you use the AVR Multi boards.
|
||||||
|
//#define CHECK_FOR_BOOTLOADER
|
||||||
|
|
||||||
/****************/
|
/****************/
|
||||||
/*** RF CHIPS ***/
|
/*** RF CHIPS ***/
|
||||||
@ -71,6 +78,22 @@
|
|||||||
//#define NRF24L01_ENABLE_LOW_POWER
|
//#define NRF24L01_ENABLE_LOW_POWER
|
||||||
|
|
||||||
|
|
||||||
|
/*****************/
|
||||||
|
/*** GLOBAL ID ***/
|
||||||
|
/*****************/
|
||||||
|
//A global ID is used by most protocols to bind and retain the bind to models. To prevent duplicate IDs, it is automatically
|
||||||
|
// generated using a random 32 bits number the first time the eeprom is initialized.
|
||||||
|
//If you have 2 Multi modules which you want to share the same ID so you can use either to control the same RC model
|
||||||
|
// then you can force the ID to a certain known value using the lines below.
|
||||||
|
//Default is commented, you should uncoment only for test purpose or if you know exactly what you are doing!!!
|
||||||
|
//#define FORCE_GLOBAL_ID 0x12345678
|
||||||
|
|
||||||
|
//Protocols using the CYRF6936 (DSM, Devo, Walkera...) are using the CYRF ID instead which should prevent duplicated IDs.
|
||||||
|
//If you have 2 Multi modules which you want to share the same ID so you can use either to control the same RC model
|
||||||
|
// then you can force the ID to a certain known value using the lines below.
|
||||||
|
//Default is commented, you should uncoment only for test purpose or if you know exactly what you are doing!!!
|
||||||
|
//#define FORCE_CYRF_ID "\x12\x34\x56\x78\x9A\xBC"
|
||||||
|
|
||||||
/****************************/
|
/****************************/
|
||||||
/*** PROTOCOLS TO INCLUDE ***/
|
/*** PROTOCOLS TO INCLUDE ***/
|
||||||
/****************************/
|
/****************************/
|
||||||
@ -113,10 +136,51 @@
|
|||||||
#define FQ777_NRF24L01_INO
|
#define FQ777_NRF24L01_INO
|
||||||
#define ASSAN_NRF24L01_INO
|
#define ASSAN_NRF24L01_INO
|
||||||
#define HONTAI_NRF24L01_INO
|
#define HONTAI_NRF24L01_INO
|
||||||
#define Q303_NRF24L01_INO
|
#define Q303_NRF24L01_INO
|
||||||
#define GW008_NRF24L01_INO
|
#define GW008_NRF24L01_INO
|
||||||
|
#define DM002_NRF24L01_INO
|
||||||
#define CABELL_NRF24L01_INO
|
#define CABELL_NRF24L01_INO
|
||||||
|
|
||||||
|
/**************************/
|
||||||
|
/*** FAILSAFE SETTINGS ***/
|
||||||
|
/**************************/
|
||||||
|
//SHFSS failsafe is by default set to all channels hold their positions except throttle forced to low (980µs)
|
||||||
|
//You can uncomment the setting below to use channels 9(1) to 16(8) instead
|
||||||
|
//#define SFHSS_FAILSAFE_CH9_16
|
||||||
|
|
||||||
|
#define AFHDS2A_FAILSAFE
|
||||||
|
#ifdef AFHDS2A_FAILSAFE
|
||||||
|
/*
|
||||||
|
Failsafe Min/Max values 962 <-> 2038
|
||||||
|
*/
|
||||||
|
const int8_t AFHDS2AFailsafeMIN = -105;
|
||||||
|
const int8_t AFHDS2AFailsafeMAX = 105;
|
||||||
|
//
|
||||||
|
const int8_t AFHDS2AFailsafe[14]= {
|
||||||
|
/*
|
||||||
|
Failsafe examples
|
||||||
|
988 <-> 2012µs -100% = 988 = 1500 + (2012-988)/2 * (-100/100) = 1500 - 512 = 988
|
||||||
|
988 <-> 2012µs 0% = 1500 = 1500 + (2012-988)/2 * ( 0/100) = 1500 + 0 = 1500
|
||||||
|
988 <-> 2012µs 100% = 2012 = 1500 + (2012-988)/2 * ( 100/100) = 1500 + 512 = 2012
|
||||||
|
988 <-> 2012µs -105% = 962 = 1500 + (2012-988)/2 * (-105/100) = 1500 - 538 = 962
|
||||||
|
*/
|
||||||
|
/* ch 1 */ -1,
|
||||||
|
/* ch 2 */ -1,
|
||||||
|
/* ch 3 */ -105,
|
||||||
|
/* ch 4 */ -1,
|
||||||
|
/* ch 5 */ -1,
|
||||||
|
/* ch 6 */ -1,
|
||||||
|
/* ch 7 */ -1,
|
||||||
|
/* ch 8 */ -1,
|
||||||
|
/* ch 9 */ -1,
|
||||||
|
/* ch 10 */ -1,
|
||||||
|
/* ch 11 */ -1,
|
||||||
|
/* ch 12 */ -1,
|
||||||
|
/* ch 13 */ -1,
|
||||||
|
/* ch 14 */ -1
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/**************************/
|
/**************************/
|
||||||
/*** TELEMETRY SETTINGS ***/
|
/*** TELEMETRY SETTINGS ***/
|
||||||
/**************************/
|
/**************************/
|
||||||
@ -149,7 +213,7 @@
|
|||||||
#define AFHDS2A_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
#define AFHDS2A_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||||
#define BAYANG_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
#define BAYANG_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||||
#define HUBSAN_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
#define HUBSAN_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||||
|
#define CABELL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||||
|
|
||||||
/****************************/
|
/****************************/
|
||||||
/*** SERIAL MODE SETTINGS ***/
|
/*** SERIAL MODE SETTINGS ***/
|
||||||
@ -161,7 +225,6 @@
|
|||||||
//If you do not plan to use the Serial mode comment this line using "//" to save Flash space
|
//If you do not plan to use the Serial mode comment this line using "//" to save Flash space
|
||||||
#define ENABLE_SERIAL
|
#define ENABLE_SERIAL
|
||||||
|
|
||||||
|
|
||||||
/*************************/
|
/*************************/
|
||||||
/*** PPM MODE SETTINGS ***/
|
/*** PPM MODE SETTINGS ***/
|
||||||
/*************************/
|
/*************************/
|
||||||
@ -211,8 +274,8 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
/* 3 */ {MODE_FRSKYD, 0 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
/* 3 */ {MODE_FRSKYD, 0 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
||||||
/* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||||
/* 5 */ {MODE_V2X2 , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 5 */ {MODE_V2X2 , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||||
/* 6 */ {MODE_DSM , DSM2_22 , 0 , P_HIGH , NO_AUTOBIND , 6 }, // option=number of channels
|
/* 6 */ {MODE_DSM , DSMX_11 , 0 , P_HIGH , NO_AUTOBIND , 6 }, // option=number of channels
|
||||||
/* 7 */ {MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 7 */ {MODE_DSM , DSM2_22 , 0 , P_HIGH , NO_AUTOBIND , 6 },
|
||||||
/* 8 */ {MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 8 */ {MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||||
/* 9 */ {MODE_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 9 */ {MODE_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||||
/* 10 */ {MODE_SYMAX , SYMAX , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 10 */ {MODE_SYMAX , SYMAX , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
||||||
@ -288,6 +351,7 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
MODE_BAYANG
|
MODE_BAYANG
|
||||||
BAYANG
|
BAYANG
|
||||||
H8S3D
|
H8S3D
|
||||||
|
X16_AH
|
||||||
MODE_ESKY
|
MODE_ESKY
|
||||||
NONE
|
NONE
|
||||||
MODE_MT99XX
|
MODE_MT99XX
|
||||||
@ -340,6 +404,8 @@ const PPM_Parameters PPM_prot[15]= {
|
|||||||
CX10WD
|
CX10WD
|
||||||
MODE_GW008
|
MODE_GW008
|
||||||
NONE
|
NONE
|
||||||
|
MODE_DM002
|
||||||
|
NONE
|
||||||
MODE_CABELL
|
MODE_CABELL
|
||||||
CABELL_V3
|
CABELL_V3
|
||||||
CABELL_V3_TELEMETRY
|
CABELL_V3_TELEMETRY
|
||||||
|
24
Multiprotocol/_MyConfig.h
Normal file
24
Multiprotocol/_MyConfig.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//#define FORCE_GLOBAL_ID 0x12345678
|
||||||
|
|
||||||
|
#if not defined STM32_BOARD
|
||||||
|
// #undef AFHDS2A_A7105_INO
|
||||||
|
|
||||||
|
// #undef DEVO_CYRF6936_INO
|
||||||
|
// #undef J6PRO_CYRF6936_INO
|
||||||
|
// #undef WK2x01_CYRF6936_INO
|
||||||
|
|
||||||
|
// #undef FRSKYV_CC2500_INO
|
||||||
|
// #undef FRSKYX_CC2500_INO
|
||||||
|
|
||||||
|
// #undef KN_NRF24L01_INO
|
||||||
|
// #undef SLT_NRF24L01_INO
|
||||||
|
|
||||||
|
// #undef FY326_NRF24L01_INO
|
||||||
|
// #undef FQ777_NRF24L01_INO
|
||||||
|
// #undef ASSAN_NRF24L01_INO
|
||||||
|
// #undef HONTAI_NRF24L01_INO
|
||||||
|
// #undef Q303_NRF24L01_INO
|
||||||
|
// #undef GW008_NRF24L01_INO
|
||||||
|
// #undef DM002_NRF24L01_INO
|
||||||
|
// #undef CABELL_NRF24L01_INO
|
||||||
|
#endif
|
@ -1,4 +1,4 @@
|
|||||||
#Protocols details
|
# Protocols details
|
||||||
Here are detailed descriptions of every supported protocols (sorted by RF modules) as well as the available options for each protocol.
|
Here are detailed descriptions of every supported protocols (sorted by RF modules) as well as the available options for each protocol.
|
||||||
|
|
||||||
If you want to see a list of models that use these protocols see the [Models](docs/Models.md) page.
|
If you want to see a list of models that use these protocols see the [Models](docs/Models.md) page.
|
||||||
@ -37,24 +37,23 @@ Dial|Protocol|Sub_protocol|RX Num|Power|Auto Bind|Option|RF Module
|
|||||||
|
|
||||||
1. The transmitter will automatically initiate a bind sequence on power up. This is for models where the receiver expects to rebind every time it is powered up. In these protocols you do not need to press the bind button at power up to bind, it will be done automatically.
|
1. The transmitter will automatically initiate a bind sequence on power up. This is for models where the receiver expects to rebind every time it is powered up. In these protocols you do not need to press the bind button at power up to bind, it will be done automatically.
|
||||||
2. Enable Bind from channel feature:
|
2. Enable Bind from channel feature:
|
||||||
|
* Bind from channel can be globally enabled/disabled in _config.h using ENABLE_BIND_CH.
|
||||||
|
* Bind from channel can be locally enabled/disabled by setting Autobind to Y/N per model for serial or per dial switch number for ppm.
|
||||||
|
* Bind channel can be choosen on any channel between 5 and 16 using BIND_CH in _config.h.
|
||||||
|
* Bind will only happen if all these elements are happening at the same time:
|
||||||
|
- Autobind = Y
|
||||||
|
- Throttle = LOW (<-95%)
|
||||||
|
- Bind channel is going from -100% to +100%
|
||||||
|
|
||||||
* Bind from channel can be globally enabled/disabled in _config.h using ENABLE_BIND_CH.
|
|
||||||
* Bind from channel can be locally enabled/disabled by setting Autobind to Y/N per model for serial or per dial switch number for ppm.
|
|
||||||
* Bind channel can be choosen on any channel between 5 and 16 using BIND_CH in _config.h.
|
|
||||||
* Bind will only happen if all these elements are happening at the same time:
|
|
||||||
- Autobind = Y
|
|
||||||
- Throttle = LOW (<-95%)
|
|
||||||
- Bind channel is going from -100% to +100%
|
|
||||||
* Additional notes:
|
* Additional notes:
|
||||||
- It's recommended to combine Throttle cut with another button to drive the bind channel. This will prevent to launch a bind while flying...
|
- It's recommended to combine Throttle cut with another button to drive the bind channel. This will prevent to launch a bind while flying...
|
||||||
- Bind channel does not have to be assigned to a free channel. Since it only acts when Throttle is Low (and throttle cut active), it could be used on the same channel as Flip for example since you are not going to flip your model when Throttle is low... Same goes for RTH and such other features.
|
- Bind channel does not have to be assigned to a free channel. Since it only acts when Throttle is Low (and throttle cut active), it could be used on the same channel as Flip for example since you are not going to flip your model when Throttle is low... Same goes for RTH and such other features.
|
||||||
- Using channel 16 for the bind channel seems the most relevant as only one protocol so far is using 16 channels which is FrSkyX. But even on FrSkyX this feature won't have any impact since there is NO valid reason to have Autobind set to Y for such a protocol.
|
- Using channel 16 for the bind channel seems the most relevant as only one protocol so far is using 16 channels which is FrSkyX. But even on FrSkyX this feature won't have any impact since there is NO valid reason to have Autobind set to Y for such a protocol.
|
||||||
|
|
||||||
|
|
||||||
***
|
# A7105 RF Module
|
||||||
#A7105 RF Module
|
|
||||||
|
|
||||||
##FLYSKY - *1*
|
## FLYSKY - *1*
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
@ -63,30 +62,30 @@ A|E|T|R|CH5|CH6|CH7|CH8
|
|||||||
|
|
||||||
Note that the RX ouput will be AETR.
|
Note that the RX ouput will be AETR.
|
||||||
|
|
||||||
###Sub_protocol Flysky - *0*
|
### Sub_protocol Flysky - *0*
|
||||||
|
|
||||||
###Sub_protocol V9X9 - *1*
|
### Sub_protocol V9X9 - *1*
|
||||||
CH5|CH6|CH7|CH8
|
CH5|CH6|CH7|CH8
|
||||||
---|---|---|---
|
---|---|---|---
|
||||||
FLIP|LIGHT|PICTURE|VIDEO
|
FLIP|LIGHT|PICTURE|VIDEO
|
||||||
|
|
||||||
###Sub_protocol V6X6 - *2*
|
### Sub_protocol V6X6 - *2*
|
||||||
CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
FLIP|LIGHT|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
|
FLIP|LIGHT|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
|
||||||
|
|
||||||
###Sub_protocol V912 - *3*
|
### Sub_protocol V912 - *3*
|
||||||
CH5|CH6
|
CH5|CH6
|
||||||
---|---
|
---|---
|
||||||
BTMBTN|TOPBTN
|
BTMBTN|TOPBTN
|
||||||
|
|
||||||
###Sub_protocol CX20 - *4*
|
### Sub_protocol CX20 - *4*
|
||||||
Model: Cheerson Cx-20
|
Model: Cheerson Cx-20
|
||||||
|
|
||||||
CH5|CH6|CH7
|
CH5|CH6|CH7
|
||||||
---|---|---
|
---|---|---
|
||||||
|
|
||||||
##FLYSKY AFHDS2A - *28*
|
## FLYSKY AFHDS2A - *28*
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
|
|
||||||
Telemetry enabled for battery voltage and RX&TX RSSI using FrSky Hub protocol
|
Telemetry enabled for battery voltage and RX&TX RSSI using FrSky Hub protocol
|
||||||
@ -101,12 +100,12 @@ A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14
|
|||||||
|
|
||||||
Note that the RX ouput will be AETR.
|
Note that the RX ouput will be AETR.
|
||||||
|
|
||||||
###Sub_protocol PWM_IBUS - *0*
|
### Sub_protocol PWM_IBUS - *0*
|
||||||
###Sub_protocol PPM_IBUS - *1*
|
### Sub_protocol PPM_IBUS - *1*
|
||||||
###Sub_protocol PWM_SBUS - *2*
|
### Sub_protocol PWM_SBUS - *2*
|
||||||
###Sub_protocol PPM_SBUS - *3*
|
### Sub_protocol PPM_SBUS - *3*
|
||||||
|
|
||||||
##HUBSAN - *2*
|
## HUBSAN - *2*
|
||||||
Models: Hubsan H102D, H107/L/C/D and Hubsan H107P/C+/D+
|
Models: Hubsan H102D, H107/L/C/D and Hubsan H107P/C+/D+
|
||||||
|
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
@ -120,9 +119,9 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
|||||||
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
***
|
***
|
||||||
#CC2500 RF Module
|
# CC2500 RF Module
|
||||||
|
|
||||||
##FRSKYV = FrSky 1 way - *25*
|
## FRSKYV = FrSky 1 way - *25*
|
||||||
Models: FrSky receivers V8R4, V8R7 and V8FR.
|
Models: FrSky receivers V8R4, V8R7 and V8FR.
|
||||||
|
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
@ -137,7 +136,7 @@ CH1|CH2|CH3|CH4
|
|||||||
---|---|---|---
|
---|---|---|---
|
||||||
CH1|CH2|CH3|CH4
|
CH1|CH2|CH3|CH4
|
||||||
|
|
||||||
##FRSKYD - *3*
|
## FRSKYD - *3*
|
||||||
Models: FrSky receivers D4R and D8R. DIY RX-F801 and RX-F802 receivers. Also known as D8.
|
Models: FrSky receivers D4R and D8R. DIY RX-F801 and RX-F802 receivers. Also known as D8.
|
||||||
|
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
@ -154,7 +153,7 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
|||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
|
|
||||||
##FRSKYX - *15*
|
## FRSKYX - *15*
|
||||||
Models: FrSky receivers X4R, X6R and X8R. Also known as D16.
|
Models: FrSky receivers X4R, X6R and X8R. Also known as D16.
|
||||||
|
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
@ -167,35 +166,35 @@ Option for this protocol is fine frequency tuning. This value is different for e
|
|||||||
- set the value to half way between min and max.
|
- set the value to half way between min and max.
|
||||||
- [video showing the process](https://youtu.be/C483uNWwAaM)
|
- [video showing the process](https://youtu.be/C483uNWwAaM)
|
||||||
|
|
||||||
###Sub_protocol CH_16 - *0*
|
### Sub_protocol CH_16 - *0*
|
||||||
FCC protocol 16 channels @18ms.
|
FCC protocol 16 channels @18ms.
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
|
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
|
||||||
###Sub_protocol CH_8 - *1*
|
### Sub_protocol CH_8 - *1*
|
||||||
FCC protocol 8 channels @9ms.
|
FCC protocol 8 channels @9ms.
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
|
|
||||||
###Sub_protocol EU_16 - *2*
|
### Sub_protocol EU_16 - *2*
|
||||||
EU-LBT protocol 16 channels @18ms. Note that the LBT part is not implemented, the TX transmits right away.
|
EU-LBT protocol 16 channels @18ms. Note that the LBT part is not implemented, the TX transmits right away.
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
|
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
|
||||||
###Sub_protocol EU_8 - *3*
|
### Sub_protocol EU_8 - *3*
|
||||||
EU-LBT protocol 8 channels @9ms. Note that the LBT part is not implemented, the TX transmits right away.
|
EU-LBT protocol 8 channels @9ms. Note that the LBT part is not implemented, the TX transmits right away.
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
|
|
||||||
##SFHSS - *21*
|
## SFHSS - *21*
|
||||||
Models: Futaba RXs and XK models.
|
Models: Futaba RXs and XK models.
|
||||||
|
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
@ -210,10 +209,12 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
|||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|CH5|CH6|CH7|CH8
|
A|E|T|R|CH5|CH6|CH7|CH8
|
||||||
|
|
||||||
***
|
Channels 9 to 16 are used as failsafe values for the channels 1 to 8.
|
||||||
#CYRF6936 RF Module
|
|
||||||
|
|
||||||
##DEVO - *7*
|
***
|
||||||
|
# CYRF6936 RF Module
|
||||||
|
|
||||||
|
## DEVO - *7*
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
@ -243,13 +244,13 @@ Bind procedure using PPM:
|
|||||||
- To verify that the TX is in fixed mode: power cycle the TX, the module LED should be solid ON (no blink).
|
- To verify that the TX is in fixed mode: power cycle the TX, the module LED should be solid ON (no blink).
|
||||||
- Note: Autobind/fixed ID mode is linked to the dial number. Which means that you can have multiple dial numbers set to the same protocol DEVO with different RX_Num and have different bind modes at the same time. It enables PPM users to get model match under DEVO.
|
- Note: Autobind/fixed ID mode is linked to the dial number. Which means that you can have multiple dial numbers set to the same protocol DEVO with different RX_Num and have different bind modes at the same time. It enables PPM users to get model match under DEVO.
|
||||||
|
|
||||||
##WK2X01 - *30*
|
## WK2X01 - *30*
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
Note: RX ouput will always be AETR independently of the input AETR, RETA...
|
Note: RX ouput will always be AETR independently of the input AETR, RETA...
|
||||||
|
|
||||||
###Sub_protocol WK2801 - *0*
|
### Sub_protocol WK2801 - *0*
|
||||||
This roughly corresponds to the number of channels supported, but many of the newer 6-channel receivers actually support the WK2801 protocol. It is recommended to try the WK2801 protocol 1st when working with older Walkera models before attempting the WK2601 or WK2401 mode, as the WK2801 is a superior protocol. The WK2801 protocol supports up to 8 channels.
|
This roughly corresponds to the number of channels supported, but many of the newer 6-channel receivers actually support the WK2801 protocol. It is recommended to try the WK2801 protocol 1st when working with older Walkera models before attempting the WK2601 or WK2401 mode, as the WK2801 is a superior protocol. The WK2801 protocol supports up to 8 channels.
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
@ -277,28 +278,28 @@ Bind procedure using PPM:
|
|||||||
- To verify that the TX is in fixed mode: power cycle the TX, the module LED should be solid ON (no blink).
|
- To verify that the TX is in fixed mode: power cycle the TX, the module LED should be solid ON (no blink).
|
||||||
- Note: Autobind/fixed ID mode is linked to the dial number. Which means that you can have multiple dial numbers set to the same protocol WK2X01 and sub_protocol WK2801 with different RX_Num and have different bind modes at the same time. It enables PPM users to get model match.
|
- Note: Autobind/fixed ID mode is linked to the dial number. Which means that you can have multiple dial numbers set to the same protocol WK2X01 and sub_protocol WK2801 with different RX_Num and have different bind modes at the same time. It enables PPM users to get model match.
|
||||||
|
|
||||||
###Sub_protocol WK2401 - *1*
|
### Sub_protocol WK2401 - *1*
|
||||||
The WK2401 protocol is used to control older Walkera models.
|
The WK2401 protocol is used to control older Walkera models.
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4
|
CH1|CH2|CH3|CH4
|
||||||
---|---|---|---
|
---|---|---|---
|
||||||
A|E|T|R
|
A|E|T|R
|
||||||
|
|
||||||
###Sub_protocol W6_5_1 - *2*
|
### Sub_protocol W6_5_1 - *2*
|
||||||
WK2601 5+1: AIL, ELE, THR, RUD, GYRO (ch 7) are proportional. Gear (ch 5) is binary. Ch 6 is disabled
|
WK2601 5+1: AIL, ELE, THR, RUD, GYRO (ch 7) are proportional. Gear (ch 5) is binary. Ch 6 is disabled
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
||||||
---|---|---|---|---|---|---
|
---|---|---|---|---|---|---
|
||||||
A|E|T|R|GEAR|DIS|GYRO
|
A|E|T|R|GEAR|DIS|GYRO
|
||||||
|
|
||||||
###Sub_protocol W6_6_1 - *3*
|
### Sub_protocol W6_6_1 - *3*
|
||||||
WK2601 6+1: AIL, ELE, THR, RUD, COL (ch 6), GYRO (ch 7) are proportional. Gear (ch 5) is binary. **This mode is highly experimental.**
|
WK2601 6+1: AIL, ELE, THR, RUD, COL (ch 6), GYRO (ch 7) are proportional. Gear (ch 5) is binary. **This mode is highly experimental.**
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
||||||
---|---|---|---|---|---|---
|
---|---|---|---|---|---|---
|
||||||
A|E|T|R|GEAR|COL|GYRO
|
A|E|T|R|GEAR|COL|GYRO
|
||||||
|
|
||||||
###Sub_protocol W6_HEL - *4* and W6HEL_I - *5*
|
### Sub_protocol W6_HEL - *4* and W6HEL_I - *5*
|
||||||
WK2601 Heli: AIL, ELE, THR, RUD, GYRO are proportional. Gear (ch 5) is binary. COL (ch 6) is linked to Thr. If Ch6 >= 0, the receiver will apply a 3D curve to the Thr. If Ch6 < 0, the receiver will apply normal curves to the Thr. The value of Ch6 defines the ratio of COL to THR.
|
WK2601 Heli: AIL, ELE, THR, RUD, GYRO are proportional. Gear (ch 5) is binary. COL (ch 6) is linked to Thr. If Ch6 >= 0, the receiver will apply a 3D curve to the Thr. If Ch6 < 0, the receiver will apply normal curves to the Thr. The value of Ch6 defines the ratio of COL to THR.
|
||||||
|
|
||||||
W6HEL_I: Invert COL servo
|
W6HEL_I: Invert COL servo
|
||||||
@ -309,7 +310,7 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
|||||||
---|---|---|---|---|---|---
|
---|---|---|---|---|---|---
|
||||||
A|E|T|R|GEAR|COL|GYRO
|
A|E|T|R|GEAR|COL|GYRO
|
||||||
|
|
||||||
##DSM - *6*
|
## DSM - *6*
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
|
|
||||||
Telemetry enabled for TSSI and plugins
|
Telemetry enabled for TSSI and plugins
|
||||||
@ -324,31 +325,31 @@ Notes:
|
|||||||
- model/type/number of channels indicated on the RX can be different from what the RX is in fact wanting to see. So don't hesitate to test different combinations until you have something working. Using Auto is the best way to find these settings.
|
- model/type/number of channels indicated on the RX can be different from what the RX is in fact wanting to see. So don't hesitate to test different combinations until you have something working. Using Auto is the best way to find these settings.
|
||||||
- RX ouput will always be TAER independently of the input AETR, RETA...
|
- RX ouput will always be TAER independently of the input AETR, RETA...
|
||||||
|
|
||||||
###Sub_protocol DSM2_22 - *0*
|
### Sub_protocol DSM2_22 - *0*
|
||||||
DSM2, Resolution 1024, refresh rate 22ms
|
DSM2, Resolution 1024, refresh rate 22ms
|
||||||
###Sub_protocol DSM2_11 - *1*
|
### Sub_protocol DSM2_11 - *1*
|
||||||
DSM2, Resolution 2048, refresh rate 11ms
|
DSM2, Resolution 2048, refresh rate 11ms
|
||||||
###Sub_protocol DSMX_22 - *2*
|
### Sub_protocol DSMX_22 - *2*
|
||||||
DSMX, Resolution 2048, refresh rate 22ms
|
DSMX, Resolution 2048, refresh rate 22ms
|
||||||
###Sub_protocol DSMX_11 - *3*
|
### Sub_protocol DSMX_11 - *3*
|
||||||
DSMX, Resolution 2048, refresh rate 11ms
|
DSMX, Resolution 2048, refresh rate 11ms
|
||||||
###Sub_protocol AUTO - *4*
|
### Sub_protocol AUTO - *4*
|
||||||
The "AUTO" feature enables the TX to automatically choose what are the best settings for your DSM RX and update your model protocol settings accordingly.
|
The "AUTO" feature enables the TX to automatically choose what are the best settings for your DSM RX and update your model protocol settings accordingly.
|
||||||
|
|
||||||
The current radio firmware which are able to use the "AUTO" feature are ersky9x (9XR Pro, 9Xtreme, Taranis, ...) and er9x for M128 (9XR) and M2561.
|
The current radio firmware which are able to use the "AUTO" feature are ersky9x (9XR Pro, 9Xtreme, Taranis, ...) and er9x for M128 (9XR) and M2561.
|
||||||
For these firmwares, you must have a telemetry enabled TX and you have to make sure you set the Telemetry "Usr proto" to "DSMx".
|
For these firmwares, you must have a telemetry enabled TX and you have to make sure you set the Telemetry "Usr proto" to "DSMx".
|
||||||
Also on er9x you will need to be sure to match the polarity of the telemetry serial (normal or inverted by bitbashing), while on ersky9x you can set "Invert COM1" accordinlgy.
|
Also on er9x you will need to be sure to match the polarity of the telemetry serial (normal or inverted by bitbashing), while on ersky9x you can set "Invert COM1" accordinlgy.
|
||||||
|
|
||||||
##J6Pro - *22*
|
## J6Pro - *22*
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
---|---|---|---|---|---|---|---|---|----|----|----
|
---|---|---|---|---|---|---|---|---|----|----|----
|
||||||
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
|
|
||||||
***
|
***
|
||||||
#NRF24L01 RF Module
|
# NRF24L01 RF Module
|
||||||
|
|
||||||
##ASSAN - *24*
|
## ASSAN - *24*
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
@ -357,47 +358,69 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
|||||||
|
|
||||||
The transmitter must be close to the receiver while binding.
|
The transmitter must be close to the receiver while binding.
|
||||||
|
|
||||||
##BAYANG - *14*
|
## BAYANG - *14*
|
||||||
Models: EAchine H8(C) mini, BayangToys X6/X7/X9, JJRC JJ850, Floureon H101 ...
|
Models: EAchine H8(C) mini, BayangToys X6/X7/X9, JJRC JJ850, Floureon H101 ...
|
||||||
|
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||||
---|---|---|---|---|---|---|---|---|----
|
---|---|---|---|---|---|---|---|---|----|---
|
||||||
A|E|T|R|FLIP|RTH|PICTURE|VIDEO|HEADLESS|INVERTED
|
A|E|T|R|FLIP|RTH|PICTURE|VIDEO|HEADLESS|INVERTED|TAKE_OFF
|
||||||
|
|
||||||
###Sub_protocol BAYANG - *0*
|
### Sub_protocol BAYANG - *0*
|
||||||
Option=0 -> normal Bayang protocol
|
Option=0 -> normal Bayang protocol
|
||||||
|
|
||||||
Option=1 -> enable telemetry with [Silverxxx firmware](https://github.com/silver13/H101-acro/tree/master). Value returned to the TX using FrSkyD Hub are RX RSSI, TX RSSI, A1=uncompensated battery voltage, A2=compensated battery voltage
|
Option=1 -> enable telemetry with [Silverxxx firmware](https://github.com/silver13/H101-acro/tree/master). Value returned to the TX using FrSkyD Hub are RX RSSI, TX RSSI, A1=uncompensated battery voltage, A2=compensated battery voltage
|
||||||
|
|
||||||
###Sub_protocol H8S3D - *1*
|
### Sub_protocol H8S3D - *1*
|
||||||
Model: H8S 3D
|
Model: H8S 3D
|
||||||
|
|
||||||
Same channels assignement as above.
|
Same channels assignement as above.
|
||||||
|
|
||||||
##CG023 - *13*
|
### Sub_protocol X16_AH - *2*
|
||||||
|
Model: X16 AH
|
||||||
|
|
||||||
|
Same channels assignement as above.
|
||||||
|
|
||||||
|
## Cabell - *34*
|
||||||
|
Homegrown protocol with variable number of channels (4-16) and telemetry (RSSI, V1, V2).
|
||||||
|
|
||||||
|
RXs details are located here: https://github.com/soligen2010/RC_RX_CABELL_V3_FHSS
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
|
||||||
|
### Sub_protocol CABELL_V3 - *0*
|
||||||
|
|
||||||
|
### Sub_protocol CABELL_V3_TELEMETRY - *1*
|
||||||
|
|
||||||
|
### Sub_protocol CABELL_SET_FAIL_SAFE - *6*
|
||||||
|
|
||||||
|
### Sub_protocol CABELL_UNBIND - *7*
|
||||||
|
|
||||||
|
## CG023 - *13*
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol CG023 - *0*
|
### Sub_protocol CG023 - *0*
|
||||||
Models: EAchine CG023/CG031/3D X4
|
Models: EAchine CG023/CG031/3D X4
|
||||||
|
|
||||||
###Sub_protocol YD829 - *1*
|
### Sub_protocol YD829 - *1*
|
||||||
Models: Attop YD-822/YD-829/YD-829C ...
|
Models: Attop YD-822/YD-829/YD-829C ...
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8|CH9
|
CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---
|
---|---|---|---|---
|
||||||
FLIP||PICTURE|VIDEO|HEADLESS
|
FLIP||PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol H8_3D - *2*
|
### Sub_protocol H8_3D - *2*
|
||||||
Models: EAchine H8 mini 3D, JJRC H20/H22/H11D
|
Models: EAchine H8 mini 3D, JJRC H20/H22/H11D
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13
|
CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
FLIP|LIGTH|PICTURE|VIDEO|OPT1|OPT2|CAL1|CAL2|GIMBAL
|
FLIP|LIGTH|PICTURE|VIDEO|OPT1|OPT2|CAL1|CAL2|GIMBAL
|
||||||
|
|
||||||
JJRC H20: OPT1=Headless, OPT2=RTH
|
JJRC H20: OPT1=Headless, OPT2=RTH
|
||||||
@ -409,7 +432,7 @@ H8 3D: OPT1=RTH then press a direction to enter headless mode (like stock TX), O
|
|||||||
CAL1: H8 3D acc calib, H20 headless calib
|
CAL1: H8 3D acc calib, H20 headless calib
|
||||||
CAL2: H11D/H20 acc calib
|
CAL2: H11D/H20 acc calib
|
||||||
|
|
||||||
##CX10 - *12*
|
## CX10 - *12*
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6
|
CH1|CH2|CH3|CH4|CH5|CH6
|
||||||
@ -418,12 +441,12 @@ A|E|T|R|FLIP|RATE
|
|||||||
|
|
||||||
Rate: -100%=rate 1, 0%=rate 2, +100%=rate 3
|
Rate: -100%=rate 1, 0%=rate 2, +100%=rate 3
|
||||||
|
|
||||||
###Sub_protocol GREEN - *0*
|
### Sub_protocol GREEN - *0*
|
||||||
Models: Cheerson CX-10 green pcb
|
Models: Cheerson CX-10 green pcb
|
||||||
|
|
||||||
Same channels assignement as above.
|
Same channels assignement as above.
|
||||||
|
|
||||||
###Sub_protocol BLUE - *1*
|
### Sub_protocol BLUE - *1*
|
||||||
Models: Cheerson CX-10 blue pcb & some newer red pcb, CX-10A, CX-10C, CX11, CX12, Floureon FX10, JJRC DHD D1
|
Models: Cheerson CX-10 blue pcb & some newer red pcb, CX-10A, CX-10C, CX11, CX12, Floureon FX10, JJRC DHD D1
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8
|
CH5|CH6|CH7|CH8
|
||||||
@ -432,66 +455,59 @@ FLIP|RATE|PICTURE|VIDEO
|
|||||||
|
|
||||||
Rate: -100%=rate 1, 0%=rate 2, +100%=rate 3 or headless for CX-10A
|
Rate: -100%=rate 1, 0%=rate 2, +100%=rate 3 or headless for CX-10A
|
||||||
|
|
||||||
###Sub_protocol DM007 - *2*
|
### Sub_protocol DM007 - *2*
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8|CH9
|
CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---
|
---|---|---|---|---
|
||||||
FLIP|MODE|PICTURE|VIDEO|HEADLESS
|
FLIP|MODE|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol JC3015_1 - *4*
|
### Sub_protocol JC3015_1 - *4*
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8
|
CH5|CH6|CH7|CH8
|
||||||
---|---|---|---
|
---|---|---|---
|
||||||
FLIP|MODE|PICTURE|VIDEO
|
FLIP|MODE|PICTURE|VIDEO
|
||||||
|
|
||||||
###Sub_protocol JC3015_2 - *5*
|
### Sub_protocol JC3015_2 - *5*
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8
|
CH5|CH6|CH7|CH8
|
||||||
---|---|---|---
|
---|---|---|---
|
||||||
FLIP|MODE|LED|DFLIP
|
FLIP|MODE|LED|DFLIP
|
||||||
|
|
||||||
###Sub_protocol MK33041 - *6*
|
### Sub_protocol MK33041 - *6*
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8|CH9|CH10
|
CH5|CH6|CH7|CH8|CH9|CH10
|
||||||
---|---|---|---|---|---
|
---|---|---|---|---|---
|
||||||
FLIP|MODE|PICTURE|VIDEO|HEADLESS|RTH
|
FLIP|MODE|PICTURE|VIDEO|HEADLESS|RTH
|
||||||
|
|
||||||
##Q2X2 - *29*
|
## DM002 - *33*
|
||||||
###Sub_protocol Q222 - *0*
|
Autobind protocol
|
||||||
Models: Q222 v1 and V686 v2
|
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
**Only 2 TX IDs available, change RX_Num value 0-1 to cycle through them**
|
||||||
---|---|---|---|---|---|---|---|---|---|---|---
|
|
||||||
A|E|T|R|FLIP|LED|MODULE2|MODULE1|HEADLESS|RTH|XCAL|YCAL
|
|
||||||
|
|
||||||
###Sub_protocol Q242 - *1* and Q282 - *2*
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||||
|
---|---|---|---|---|---|---|---|---|----|----
|
||||||
|
A|E|T|R|FLIP|LED|CAMERA1|CAMERA2|HEADLESS|RTH|RATE_LOW
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
## ESKY - *16*
|
||||||
---|---|---|---|---|---|---|---|---|---|---|---
|
|
||||||
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
|
|
||||||
|
|
||||||
Model: JXD 509 is using Q282 with CH12=Start/Stop motors
|
|
||||||
|
|
||||||
##ESKY - *16*
|
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6
|
CH1|CH2|CH3|CH4|CH5|CH6
|
||||||
---|---|---|---|---|---
|
---|---|---|---|---|---
|
||||||
A|E|T|R|GYRO|PITCH
|
A|E|T|R|GYRO|PITCH
|
||||||
|
|
||||||
##FY326 - *20*
|
## FY326 - *20*
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|RTH|HEADLESS|EXPERT|CALIBRATE
|
A|E|T|R|FLIP|RTH|HEADLESS|EXPERT|CALIBRATE
|
||||||
|
|
||||||
##FQ777 - *23*
|
## FQ777 - *23*
|
||||||
Model: FQ777-124 (with SV7241A)
|
Model: FQ777-124 (with SV7241A)
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|RTH|HEADLESS|EXPERT
|
A|E|T|R|FLIP|RTH|HEADLESS|EXPERT
|
||||||
|
|
||||||
##GW008 - *32*
|
## GW008 - *32*
|
||||||
Model: Global Drone GW008 from Banggood
|
Model: Global Drone GW008 from Banggood
|
||||||
|
|
||||||
There are 3 versions of this small quad, this protocol is for the one with a XNS104 IC in the stock Tx and PAN159CY IC in the quad. The xn297 version is compatible with the CX10 protocol (green pcb). The LT8910 version is not supported yet.
|
There are 3 versions of this small quad, this protocol is for the one with a XNS104 IC in the stock Tx and PAN159CY IC in the quad. The xn297 version is compatible with the CX10 protocol (green pcb). The LT8910 version is not supported yet.
|
||||||
@ -500,96 +516,96 @@ CH1|CH2|CH3|CH4|CH5
|
|||||||
---|---|---|---|---
|
---|---|---|---|---
|
||||||
A|E|T|R|FLIP
|
A|E|T|R|FLIP
|
||||||
|
|
||||||
##HISKY - *4*
|
## HISKY - *4*
|
||||||
###Sub_protocol Hisky - *0*
|
### Sub_protocol Hisky - *0*
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|GEAR|PITCH|GYRO|CH8
|
A|E|T|R|GEAR|PITCH|GYRO|CH8
|
||||||
|
|
||||||
GYRO: -100%=6G, +100%=3G
|
GYRO: -100%=6G, +100%=3G
|
||||||
|
|
||||||
###Sub_protocol HK310 - *1*
|
### Sub_protocol HK310 - *1*
|
||||||
Models: RX HK-3000, HK3100 and XY3000 (TX are HK-300, HK-310 and TL-3C)
|
Models: RX HK-3000, HK3100 and XY3000 (TX are HK-300, HK-310 and TL-3C)
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
|||T|R|AUX|T_FSAFE|R_FSAFE|AUX_FSAFE
|
| | |T|R|AUX|T_FSAFE|R_FSAFE|AUX_FSAFE
|
||||||
|
|
||||||
##KN - *9*
|
## KN - *9*
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||||
---|---|---|---|---|---|---|---|---|----|----
|
---|---|---|---|---|---|---|---|---|----|----
|
||||||
A|E|T|R|DR|THOLD|IDLEUP|GYRO|Ttrim|Atrim|Etrim
|
A|E|T|R|DR|THOLD|IDLEUP|GYRO|Ttrim|Atrim|Etrim
|
||||||
|
|
||||||
Dual Rate: +100%=full range, Throttle Hold: +100%=hold, Idle Up: +100%=3D, GYRO: -100%=6G, +100%=3G
|
Dual Rate: +100%=full range, Throttle Hold: +100%=hold, Idle Up: +100%=3D, GYRO: -100%=6G, +100%=3G
|
||||||
|
|
||||||
###Sub_protocol WLTOYS - *0*
|
### Sub_protocol WLTOYS - *0*
|
||||||
###Sub_protocol FEILUN - *1*
|
### Sub_protocol FEILUN - *1*
|
||||||
Same channels assignement as above.
|
Same channels assignement as above.
|
||||||
|
|
||||||
##HONTAI - *26*
|
## HONTAI - *26*
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||||
---|---|---|---|---|---|---|---|---|----|----
|
---|---|---|---|---|---|---|---|---|----|----
|
||||||
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|CAL
|
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|CAL
|
||||||
|
|
||||||
###Sub_protocol HONTAI - *0*
|
### Sub_protocol HONTAI - *0*
|
||||||
###Sub_protocol JJRCX1 - *1*
|
### Sub_protocol JJRCX1 - *1*
|
||||||
CH6|
|
CH6|
|
||||||
---|
|
---|
|
||||||
ARM|
|
ARM|
|
||||||
|
|
||||||
###Sub_protocol X5C1 clone - *2*
|
### Sub_protocol X5C1 clone - *2*
|
||||||
|
|
||||||
###Sub_protocol FQ777_951 - *3*
|
### Sub_protocol FQ777_951 - *3*
|
||||||
|
|
||||||
##MJXQ - *18*
|
## MJXQ - *18*
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13
|
||||||
---|---|---|---|---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|AUTOFLIP|PAN|TILT
|
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|AUTOFLIP|PAN|TILT
|
||||||
|
|
||||||
###Sub_protocol WLH08 - *0*
|
### Sub_protocol WLH08 - *0*
|
||||||
###Sub_protocol X600 - *1*
|
### Sub_protocol X600 - *1*
|
||||||
Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
||||||
###Sub_protocol X800 - *2*
|
### Sub_protocol X800 - *2*
|
||||||
Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
||||||
###Sub_protocol H26D - *3*
|
### Sub_protocol H26D - *3*
|
||||||
Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
||||||
###Sub_protocol E010 - *4*
|
### Sub_protocol E010 - *4*
|
||||||
15 TX IDs available, change RX_Num value 0..14 to cycle through them
|
15 TX IDs available, change RX_Num value 0..14 to cycle through them
|
||||||
|
|
||||||
If the E010 does not respond well to inputs or hard to bind, set Power to Low.
|
If the E010 does not respond well to inputs or hard to bind, set Power to Low.
|
||||||
###Sub_protocol H26WH - *5*
|
### Sub_protocol H26WH - *5*
|
||||||
CH6|
|
CH6|
|
||||||
---|
|
---|
|
||||||
ARM|
|
ARM|
|
||||||
|
|
||||||
Only 1 TX ID available
|
Only 1 TX ID available
|
||||||
|
|
||||||
##MT99XX - *17*
|
## MT99XX - *17*
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS
|
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol MT99 - *0*
|
### Sub_protocol MT99 - *0*
|
||||||
Models: MT99xx
|
Models: MT99xx
|
||||||
###Sub_protocol H7 - *1*
|
### Sub_protocol H7 - *1*
|
||||||
Models: Eachine H7, Cheerson CX023
|
Models: Eachine H7, Cheerson CX023
|
||||||
###Sub_protocol YZ - *2*
|
### Sub_protocol YZ - *2*
|
||||||
Model: Yi Zhan i6S
|
Model: Yi Zhan i6S
|
||||||
Only one model can be flown at the same time since the ID is hardcoded.
|
Only one model can be flown at the same time since the ID is hardcoded.
|
||||||
###Sub_protocol LS - *3*
|
### Sub_protocol LS - *3*
|
||||||
Models: LS114, 124, 215
|
Models: LS114, 124, 215
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|INVERT|PICTURE|VIDEO|HEADLESS
|
A|E|T|R|FLIP|INVERT|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol FY805 - *4*
|
### Sub_protocol FY805 - *4*
|
||||||
Model: FY805
|
Model: FY805
|
||||||
|
|
||||||
Only 1 ID available
|
Only 1 ID available
|
||||||
@ -598,14 +614,30 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
|||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP||||HEADLESS
|
A|E|T|R|FLIP||||HEADLESS
|
||||||
|
|
||||||
##Q303 - *31*
|
## Q2X2 - *29*
|
||||||
|
### Sub_protocol Q222 - *0*
|
||||||
|
Models: Q222 v1 and V686 v2
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
|
---|---|---|---|---|---|---|---|---|---|---|---
|
||||||
|
A|E|T|R|FLIP|LED|MODULE2|MODULE1|HEADLESS|RTH|XCAL|YCAL
|
||||||
|
|
||||||
|
### Sub_protocol Q242 - *1* and Q282 - *2*
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
|
---|---|---|---|---|---|---|---|---|---|---|---
|
||||||
|
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
|
||||||
|
|
||||||
|
Model: JXD 509 is using Q282 with CH12=Start/Stop motors
|
||||||
|
|
||||||
|
## Q303 - *31*
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4
|
CH1|CH2|CH3|CH4
|
||||||
---|---|---|---
|
---|---|---|---
|
||||||
A|E|T|R
|
A|E|T|R
|
||||||
|
|
||||||
###Sub_protocol Q303 - *0*
|
### Sub_protocol Q303 - *0*
|
||||||
Q303 warning: this sub_protocol is known to not work at all/properly with 4in1 RF modules.
|
Q303 warning: this sub_protocol is known to not work at all/properly with 4in1 RF modules.
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||||
@ -614,7 +646,7 @@ AHOLD|FLIP|PICTURE|VIDEO|HEADLESS|RTH|GIMBAL
|
|||||||
|
|
||||||
GIMBAL needs 3 position -100%/0%/100%
|
GIMBAL needs 3 position -100%/0%/100%
|
||||||
|
|
||||||
###Sub_protocol CX35 - *1*
|
### Sub_protocol CX35 - *1*
|
||||||
CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||||
---|---|---|---|---|---|---
|
---|---|---|---|---|---|---
|
||||||
ARM|VTX|PICTURE|VIDEO||RTH|GIMBAL
|
ARM|VTX|PICTURE|VIDEO||RTH|GIMBAL
|
||||||
@ -625,14 +657,14 @@ Each toggle of VTX will increment the channel.
|
|||||||
|
|
||||||
Gimbal is full range.
|
Gimbal is full range.
|
||||||
|
|
||||||
###Sub_protocol CX10D - *2* and Sub_protocol CX10WD - *3*
|
### Sub_protocol CX10D - *2* and Sub_protocol CX10WD - *3*
|
||||||
CH5|CH6
|
CH5|CH6
|
||||||
---|---
|
---|---
|
||||||
ARM|FLIP
|
ARM|FLIP
|
||||||
|
|
||||||
ARM is 3 positions: -100%=land / 0%=manual / +100%=take off
|
ARM is 3 positions: -100%=land / 0%=manual / +100%=take off
|
||||||
|
|
||||||
##Shenqi - *19*
|
## Shenqi - *19*
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
Model: Shenqiwei 1/20 Mini Motorcycle
|
Model: Shenqiwei 1/20 Mini Motorcycle
|
||||||
@ -643,57 +675,55 @@ CH1|CH2|CH3|CH4
|
|||||||
|
|
||||||
Throttle +100%=full forward,0%=stop,-100%=full backward.
|
Throttle +100%=full forward,0%=stop,-100%=full backward.
|
||||||
|
|
||||||
##SLT - *11*
|
## SLT - *11*
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6
|
CH1|CH2|CH3|CH4|CH5|CH6
|
||||||
---|---|---|---|---|---
|
---|---|---|---|---|---
|
||||||
A|E|T|R|GEAR|PITCH
|
A|E|T|R|GEAR|PITCH
|
||||||
|
|
||||||
##Symax - *10*
|
## Symax - *10*
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP||PICTURE|VIDEO|HEADLESS
|
A|E|T|R|FLIP|RATES|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol SYMAX - *0*
|
### Sub_protocol SYMAX - *0*
|
||||||
Models: Syma X5C-1/X11/X11C/X12
|
Models: Syma X5C-1/X11/X11C/X12
|
||||||
|
|
||||||
###Sub_protocol SYMAX5C - *1*
|
### Sub_protocol SYMAX5C - *1*
|
||||||
Model: Syma X5C (original) and X2
|
Model: Syma X5C (original) and X2
|
||||||
|
|
||||||
##V2X2 - *5*
|
## V2X2 - *5*
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||||
---|---|---|---|---|---|---|---|---|----|----
|
---|---|---|---|---|---|---|---|---|----|----
|
||||||
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS|MAG_CAL_X|MAG_CAL_Y
|
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS|MAG_CAL_X|MAG_CAL_Y
|
||||||
|
|
||||||
###Sub_protocol V2x2 - *0*
|
### Sub_protocol V2x2 - *0*
|
||||||
Models: WLToys V202/252/272, JXD 385/388, JJRC H6C, Yizhan Tarantula X6 ...
|
Models: WLToys V202/252/272, JXD 385/388, JJRC H6C, Yizhan Tarantula X6 ...
|
||||||
|
|
||||||
PICTURE: also automatic Missile Launcher and Hoist in one direction
|
PICTURE: also automatic Missile Launcher and Hoist in one direction
|
||||||
|
|
||||||
VIDEO: also Sprayer, Bubbler, Missile Launcher(1), and Hoist in the other dir
|
VIDEO: also Sprayer, Bubbler, Missile Launcher(1), and Hoist in the other dir
|
||||||
|
|
||||||
###Sub_protocol JXD506 - *1*
|
### Sub_protocol JXD506 - *1*
|
||||||
Model: JXD 506
|
Model: JXD 506
|
||||||
|
|
||||||
CH10|CH11|CH12
|
CH10|CH11|CH12
|
||||||
---|---|---
|
---|---|---
|
||||||
Start/Stop|EMERGENCY|CAMERA_UP/DN
|
Start/Stop|EMERGENCY|CAMERA_UP/DN
|
||||||
|
|
||||||
##YD717 - *8*
|
## YD717 - *8*
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol YD717 - *0*
|
### Sub_protocol YD717 - *0*
|
||||||
###Sub_protocol SKYWLKR - *1*
|
### Sub_protocol SKYWLKR - *1*
|
||||||
###Sub_protocol SYMAX4 - *2*
|
### Sub_protocol SYMAX4 - *2*
|
||||||
###Sub_protocol XINXUN - *3*
|
### Sub_protocol XINXUN - *3*
|
||||||
###Sub_protocol NIHUI - *4*
|
### Sub_protocol NIHUI - *4*
|
||||||
Same channels assignement as above.
|
Same channels assignement as above.
|
||||||
|
|
||||||
|
|
||||||
|
53
README.md
53
README.md
@ -18,8 +18,8 @@ The source code is partly based on the [Deviation TX project](http://www.deviati
|
|||||||
1. [Transmitters and serial/telemetry options](docs/Transmitters.md)
|
1. [Transmitters and serial/telemetry options](docs/Transmitters.md)
|
||||||
1. [Module Hardware options](docs/Hardware.md)
|
1. [Module Hardware options](docs/Hardware.md)
|
||||||
1. Compiling and programming the module
|
1. Compiling and programming the module
|
||||||
* [4in1/DIY Mutliprotocol module based on ATmega328](docs/Compiling.md)
|
* [4in1/DIY Multiprotocol module based on ATmega328](docs/Compiling.md)
|
||||||
* [DIY Mutliprotocol module based on STM32](docs/Compiling_STM32.md)
|
* [DIY Multiprotocol module based on STM32](docs/Compiling_STM32.md)
|
||||||
1. [Transmitter Setup](docs/Transmitters.md)
|
1. [Transmitter Setup](docs/Transmitters.md)
|
||||||
1. [How to for popular models](docs/Models.md)
|
1. [How to for popular models](docs/Models.md)
|
||||||
1. [Troubleshooting](docs/Troubleshooting.md)
|
1. [Troubleshooting](docs/Troubleshooting.md)
|
||||||
@ -32,12 +32,9 @@ A functioning MULTI-Module consists of (see image below):
|
|||||||
1. A host RC Tx
|
1. A host RC Tx
|
||||||
|
|
||||||
1. A Multiprotocol Transmitter Module (MULTI-Module) that connects to a host transmitter. This module is typically comprised of
|
1. A Multiprotocol Transmitter Module (MULTI-Module) that connects to a host transmitter. This module is typically comprised of
|
||||||
|
* A microcontroller (currently ATMega328P or STM32) that interfaces with the Tx, controls the module functions and forwards the RC commands to the RF hardware
|
||||||
* A microcontroller (currently ATMega328P or STM32) that interfaces with the Tx, controls the module functions and forwards the RC commands to the RF hardware
|
* One or more (but at least one) RF modules that provide the capability to communicate with RC receivers. To communicate with the receiver the RF module in the Tx must match with the RF module type in the receiver. The four most common 2.4GHz RF chips on the market are supported TI CC2500, Nordic NRF24L01, Cypress CYRF6936, and the Amiccom A7105
|
||||||
|
* MULTI-firmware loaded on to the microprocessor. At a high level, this firmware performs a few different functions:
|
||||||
* One or more (but at least one) RF modules that provide the capability to communicate with RC receivers. To communicate with the receiver the RF module in the Tx must match with the RF module type in the receiver. The four most common 2.4GHz RF chips on the market are supported TI CC2500, Nordic NRF24L01, Cypress CYRF6936, and the Amiccom A7105
|
|
||||||
|
|
||||||
* MULTI-firmware loaded on to the microprocessor. At a high level, this firmware performs a few different functions:
|
|
||||||
* It interfaces with signals from the host Tx and decodes these for transmission to the model, it manages the activation of the correct hardware RF module for each protocol
|
* It interfaces with signals from the host Tx and decodes these for transmission to the model, it manages the activation of the correct hardware RF module for each protocol
|
||||||
* It implements the unique communication protocols for each receiver/model and manages the all-important binding process with a receiver/model
|
* It implements the unique communication protocols for each receiver/model and manages the all-important binding process with a receiver/model
|
||||||
* In the case of some protocols (for example DSMX and FrSky) it receives and decodes the telemetry information and makes this available to the radio.
|
* In the case of some protocols (for example DSMX and FrSky) it receives and decodes the telemetry information and makes this available to the radio.
|
||||||
@ -47,7 +44,7 @@ One of the most attractive features of the MULTI-module is the ability to send t
|
|||||||
|
|
||||||
In constructing a functioning MULTI-Module there are important choices to be made and tradeoffs to be aware of. The most important are:
|
In constructing a functioning MULTI-Module there are important choices to be made and tradeoffs to be aware of. The most important are:
|
||||||
|
|
||||||
##**Choice 1:** Which MULTI-Module hardware option
|
## **Choice 1:** Which MULTI-Module hardware option
|
||||||
|
|
||||||
There are currently four generic paths to get your hands on an MULTI-Module. These are outlined in detail on the [hardware](docs/Hardware.md) page. Here they are, in order of increasing difficulty:
|
There are currently four generic paths to get your hands on an MULTI-Module. These are outlined in detail on the [hardware](docs/Hardware.md) page. Here they are, in order of increasing difficulty:
|
||||||
- **Ready-made MULTI-Module** - Available from Banggood which includes a 4-in-1 RF module and an antenna switcher
|
- **Ready-made MULTI-Module** - Available from Banggood which includes a 4-in-1 RF module and an antenna switcher
|
||||||
@ -59,35 +56,35 @@ The last option is where it all started and how the pioneers in this project mad
|
|||||||
|
|
||||||
For more information on these options see the [hardware](docs/Hardware.md) page
|
For more information on these options see the [hardware](docs/Hardware.md) page
|
||||||
|
|
||||||
##**Choice 2:** Which RF modules to include in the MULTI-Module
|
## **Choice 2:** Which RF modules to include in the MULTI-Module
|
||||||
|
|
||||||
This depends on your specific needs. However, recent the availability of the 4-in-1 RF modules from Banggood for less than $35 makes it easy to “have it all”. Most manufacturers of RC systems (Spektrum, FrSky, FlySky) and toys (Syma, Hubsan, etc.) use one of these four RF chips to manage the RF link between the transmitter and the reciever/model. Here is an incomplete list of the RF modules and some of the most popular toys that use them. For the complete list see the [Protocol Details](Protocols_Details.md) page.
|
This depends on your specific needs. However, recent the availability of the 4-in-1 RF modules from Banggood for less than $35 makes it easy to “have it all”. Most manufacturers of RC systems (Spektrum, FrSky, FlySky) and toys (Syma, Hubsan, etc.) use one of these four RF chips to manage the RF link between the transmitter and the reciever/model. Here is an incomplete list of the RF modules and some of the most popular toys that use them. For the complete list see the [Protocol Details](Protocols_Details.md) page.
|
||||||
|
|
||||||
Manufacturer|RF Chip|Example Protocols
|
|Manufacturer|RF Chip|Example Protocols|
|
||||||
:-----------|-------|:-------
|
|---|---|---|
|
||||||
Cyprus Semiconductor| CYRF6936|DSM/DSMX
|
|Cyprus Semiconductor|CYRF6936|DSM/DSMX|
|
||||||
| |Walkera Devo
|
|||Walkera Devo|
|
||||||
| |J6Pro
|
|||J6Pro|
|
||||||
Texas Instruments|CC2500|FrSky
|
|Texas Instruments|CC2500|FrSky|
|
||||||
| |Futaba SFHSS
|
|||Futaba SFHSS|
|
||||||
Amiccom|A7105|FlySky
|
|Amiccom|A7105|FlySky|
|
||||||
| |FlySky AFHDS2A
|
|||FlySky AFHDS2A|
|
||||||
| |Hubsan
|
|||Hubsan|
|
||||||
Nordic Semiconductor|NRF24L01|HiSky
|
|Nordic Semiconductor|NRF24L01|HiSky|
|
||||||
| |Syma
|
|||Syma|
|
||||||
| |ASSAN
|
|||ASSAN|
|
||||||
| |and most other Chinese models
|
|||and most other Chinese models|
|
||||||
|
|
||||||
For example, if you have no interest in binding your Tx to an model with and FrSky or Futaba SFHSS receiver you do not need to include the CC2500 RF module in your system.
|
For example, if you have no interest in binding your Tx to an model with and FrSky or Futaba SFHSS receiver you do not need to include the CC2500 RF module in your system.
|
||||||
|
|
||||||
##**Choice 3:** Which protocols to upload to the MULTI-Module
|
## **Choice 3:** Which protocols to upload to the MULTI-Module
|
||||||
|
|
||||||
Of course there is always a catch. In this case it is the 32KB memory limit on the ATmega328 processor. Due to the amazing work done by devs on this project, the memory required by all the possible protocols exceeds this limit considerably. This means that you will need to make a choice of which protocols you will compile into your firmware. Fortunately, the process of selecting and compiling is not too difficult and it is fully documented on the [Compiling and Programming](docs/Compiling.md) page.
|
Of course there is always a catch. In this case it is the 32KB memory limit on the ATmega328 processor. Due to the amazing work done by devs on this project, the memory required by all the possible protocols exceeds this limit considerably. This means that you will need to make a choice of which protocols you will compile into your firmware. Fortunately, the process of selecting and compiling is not too difficult and it is fully documented on the [Compiling and Programming](docs/Compiling.md) page.
|
||||||
Also, the lead dev Pascal Langer (rcgroups:hpnuts) makes this process even easier for many users by making compiled binaries available for three popular combinations of RF modules. These are always “fresh” (based on the latest stable firmware) and available on the [Releases](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases) page.
|
Also, the lead dev Pascal Langer (rcgroups:hpnuts) makes this process even easier for many users by making compiled binaries available for three popular combinations of RF modules. These are always “fresh” (based on the latest stable firmware) and available on the [Releases](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases) page.
|
||||||
|
|
||||||
An alternatice is to use a STM32 ARM microcontroller based module. If you go the route of building this version of the DIY MULTI-Module then the memory limits do not apply anymore.
|
An alternatice is to use a STM32 ARM microcontroller based module. If you go the route of building this version of the DIY MULTI-Module then the memory limits do not apply anymore.
|
||||||
|
|
||||||
##**Choice 4:** Choosing the type of interface between the MULTI-Module and your radio (PPM or Serial)
|
## **Choice 4:** Choosing the type of interface between the MULTI-Module and your radio (PPM or Serial)
|
||||||
|
|
||||||
The MULTI-Module supports industry standard PPM interface that works with all transmitters with either:
|
The MULTI-Module supports industry standard PPM interface that works with all transmitters with either:
|
||||||
- a module bay or
|
- a module bay or
|
||||||
@ -100,7 +97,7 @@ If you are the owner of a transmitter that supports the er9X/erSky9X or OpenTX f
|
|||||||
- The model protocol selection and binding is done from the Model Settings menu on the Tx
|
- The model protocol selection and binding is done from the Model Settings menu on the Tx
|
||||||
- For telemetry capable transmitters, the telemetry integration is done seamlessly with the Tx firmware. (Note that FrSky TH9X/Turnigy 9X/R transmitters require a telemetry mod to be done before telemetry can work). Click on the link corressponding to your Tx on the [Transmitters](docs/Transmitters.md) page for more details.
|
- For telemetry capable transmitters, the telemetry integration is done seamlessly with the Tx firmware. (Note that FrSky TH9X/Turnigy 9X/R transmitters require a telemetry mod to be done before telemetry can work). Click on the link corressponding to your Tx on the [Transmitters](docs/Transmitters.md) page for more details.
|
||||||
|
|
||||||
#How to get started?
|
# How to get started?
|
||||||
1. Browse the [Protocols](Protocols_Details.md) page to see which protocols you would like on your module
|
1. Browse the [Protocols](Protocols_Details.md) page to see which protocols you would like on your module
|
||||||
1. Go to the [Hardware Options](docs/Hardware.md) page to decide which of the MULTI-Module hardware options appeals to you and which RF modules you plan to integrate
|
1. Go to the [Hardware Options](docs/Hardware.md) page to decide which of the MULTI-Module hardware options appeals to you and which RF modules you plan to integrate
|
||||||
1. Once you have your module, you should review what jumper settings or modifications are required to the module to support serial communication and possibly telemetry
|
1. Once you have your module, you should review what jumper settings or modifications are required to the module to support serial communication and possibly telemetry
|
||||||
@ -108,7 +105,7 @@ If you are the owner of a transmitter that supports the er9X/erSky9X or OpenTX f
|
|||||||
1. Finally, you should visit the setup page for your transmitter by clicking on the link corressponding to your Tx on the [Transmitters](docs/Transmitters.md) page to configure the last few settings before you can fly to your heart’s content!!!!!
|
1. Finally, you should visit the setup page for your transmitter by clicking on the link corressponding to your Tx on the [Transmitters](docs/Transmitters.md) page to configure the last few settings before you can fly to your heart’s content!!!!!
|
||||||
|
|
||||||
# Troubleshooting
|
# Troubleshooting
|
||||||
Visit the [Troubleshooting](docs/Troubleshooting.md) page. Please bear in mind that the MULTI-Module is a complex system of hardware and software and it make take some patience to get it up and running. Also remember that the developers of the system are actual users of the system. This means that at any moment in time the system is working perfectly for them. A corollary to this is that if you are struggling there are likely two scenarios. First, that the problem is with your hardware or with your configuration, second, and much more unlikely but not impossible scenario, is that you are struggling with a new undiscovered bug. (The author of this documentation speaks from experience ;-) Please check the RC Groups forum and search for keywords relating to your problem before posting a reply. When you do post a reply please so humbly and respectfully – you will find many helpful people there. In your reply please include as much relevant information as possible and attach compilation output and _Config.h files as text attachments to keep the forum clean.
|
Visit the [Troubleshooting](docs/Troubleshooting.md) page. Please bear in mind that the MULTI-Module is a complex system of hardware and software and it make take some patience to get it up and running. Also remember that the developers of the system are actual users of the system. This means that at any moment in time the system is working perfectly for them. A corollary to this is that if you are struggling there are likely two scenarios. First, that the problem is with your hardware or with your configuration, second, and much more unlikely but not impossible scenario, is that you are struggling with a new undiscovered bug. (The author of this documentation speaks from experience ;-) Please check the RC Groups forum and search for keywords relating to your problem before posting a reply. When you do post a reply please so humbly and respectfully – you will find many helpful people there. In your reply please include as much relevant information as possible and attach compilation output and ```_Config.h``` files as text attachments to keep the forum clean.
|
||||||
# A final word
|
# A final word
|
||||||
A very big thanks to all the people who have shared their time so graciously to create this great project. If you come across them on RC Groups, please be kind and show appreciation. In no particular order:
|
A very big thanks to all the people who have shared their time so graciously to create this great project. If you come across them on RC Groups, please be kind and show appreciation. In no particular order:
|
||||||
* Pascal Langer (rcgroups: hpnuts)
|
* Pascal Langer (rcgroups: hpnuts)
|
||||||
|
5272
STM32 PCB/V1.1/Multiprotocol_STM32_MB_1.1_t.brd
Normal file
5272
STM32 PCB/V1.1/Multiprotocol_STM32_MB_1.1_t.brd
Normal file
File diff suppressed because it is too large
Load Diff
17649
STM32 PCB/V1.1/Multiprotocol_STM32_MB_1.1_t.sch
Normal file
17649
STM32 PCB/V1.1/Multiprotocol_STM32_MB_1.1_t.sch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
#ATmega Serial Uploader
|
# ATmega Serial Uploader
|
||||||
|
|
||||||
Mike Blandford adapted the optiboot bootloader for the 4-in-1 module to allow flashing of the module using a standard Arduino USB to serial adapter or FTDI adapter. No need to open the module case. Once set up is very easy to use:
|
Mike Blandford adapted the optiboot bootloader for the 4-in-1 module to allow flashing of the module using a standard Arduino USB to serial adapter or FTDI adapter. No need to open the module case. Once set up is very easy to use:
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ While the bootloader is running, if it detects a communication problem, it confi
|
|||||||
|
|
||||||
This bootloader is for reading and writing the flash only, the EEPROM is not supported, neither is reading/writing the fuses, but it only uses 512 bytes of flash.
|
This bootloader is for reading and writing the flash only, the EEPROM is not supported, neither is reading/writing the fuses, but it only uses 512 bytes of flash.
|
||||||
|
|
||||||
##Install the bootloader
|
## Install the bootloader
|
||||||
To get the bootloader onto the ATmega you need to connect an flashing tool (like USBasp) to the 6-pin ISP connector on the board.
|
To get the bootloader onto the ATmega you need to connect an flashing tool (like USBasp) to the 6-pin ISP connector on the board.
|
||||||
Simply flash the .hex file to get the bootloader on the chip, and change the high fuse at the same time.
|
Simply flash the .hex file to get the bootloader on the chip, and change the high fuse at the same time.
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#Bluetooth Telemetry in PPM Mode
|
# Bluetooth Telemetry in PPM Mode
|
||||||
###Telemetry
|
|
||||||
|
## Telemetry
|
||||||
|
|
||||||
There are 4 protocols supporting telemetry: Hubsan, DSM, FrSkyD and FrSkyX.
|
There are 4 protocols supporting telemetry: Hubsan, DSM, FrSkyD and FrSkyX.
|
||||||
|
|
||||||
@ -11,7 +12,7 @@ FrSkyD displays full telemetry (A0, A1, RX RSSI, TX RSSI and Hub).
|
|||||||
|
|
||||||
FrSkyX displays full telemetry (A1, A2, RX RSSI, TX RSSI and Hub).
|
FrSkyX displays full telemetry (A1, A2, RX RSSI, TX RSSI and Hub).
|
||||||
|
|
||||||
### If used in PPM mode
|
## If used in PPM mode
|
||||||
|
|
||||||
Telemetry is available as a serial output on the TX pin of the Atmega328p using the FrSky hub format for Hubsan, FrSkyD, FrSkyX and DSM format for DSM2/X. The serial paramets depends on the protocol:
|
Telemetry is available as a serial output on the TX pin of the Atmega328p using the FrSky hub format for Hubsan, FrSkyD, FrSkyX and DSM format for DSM2/X. The serial paramets depends on the protocol:
|
||||||
|
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
#Manually Uploading HEX files and setting Fuses on ATmega328
|
# Manually Uploading HEX files and setting Fuses on ATmega328
|
||||||
|
|
||||||
|
|
||||||
**The .hex files provided are only for tests purpose. The recommended method is to use [Compiling and Programming](Compiling.md).**
|
**The .hex files provided are only for tests purpose. The recommended method is to use [Compiling and Programming](Compiling.md).**
|
||||||
|
|
||||||
There are many different options to upload a .hex firmware file to the MULTI-Module and to set the correct fuses. This document outlines an approach that uses a USBASP programmer and which is equally compatible with OSX, Windows and Linux operating systems.
|
There are many different options to upload a .hex firmware file to the MULTI-Module and to set the correct fuses. This document outlines an approach that uses a USBASP programmer and which is equally compatible with OSX, Windows and Linux operating systems.
|
||||||
|
|
||||||
1. Follow this section: [Material you need to upload the firmware](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/docs/Compiling.md#material-you-need-to-upload-the-firmware)
|
1. Follow this section: [Material you need to upload the firmware](Compiling.md#material-you-need-to-upload-the-firmware)
|
||||||
1. Follow this section: [Install the Arduino IDE](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/docs/Compiling.md#install-the-arduino-ide-and-the-multiprotocol-project-firmware)
|
1. Follow this section: [Install the Arduino IDE](Compiling.md#install-the-arduino-ide-and-the-multiprotocol-project-firmware)
|
||||||
1. Make sure to write down the location of your installation since you need to know where avrdude is installed to configure the AVR8 Burn-O-Mat. For example on a default windows installation, avrdude.exe is located in "C:\Program Files (x86)\Arduino\hardware\tools\avr\bin" where "C:\Program Files (x86)\Arduino" is the installation path.
|
1. Make sure to write down the location of your installation since you need to know where avrdude is installed to configure the AVR8 Burn-O-Mat. For example on a default windows installation, avrdude.exe is located in "C:\Program Files (x86)\Arduino\hardware\tools\avr\bin" where "C:\Program Files (x86)\Arduino" is the installation path.
|
||||||
1. Install [AVR8 Burn-O-Mat](http://avr8-burn-o-mat.brischalle.de/avr8_burn_o_mat_avrdude_gui_en.php) which is available for all platforms. Installation instructions are on the software page (Don't forget to install [Java](http://java.sun.com/javase/downloads) as explained).
|
1. Install [AVR8 Burn-O-Mat](http://avr8-burn-o-mat.brischalle.de/avr8_burn_o_mat_avrdude_gui_en.php) which is available for all platforms. Installation instructions are on the software page (Don't forget to install [Java](http://java.sun.com/javase/downloads) as explained).
|
||||||
1. Launch AVR8 Burn-O-Mat.
|
1. Launch AVR8 Burn-O-Mat.
|
||||||
1. You should now have a window which looks like this:
|
1. You should now have a window which looks like this: <br> <img src="images/AVR8BurnOMat-main.png" />
|
||||||
<img src="images/AVR8BurnOMat-main.png" />
|
1. Click on **Settings->AVRDUDE** and fill in the details about avrdude location using the installation path written previously as well as selecting USBASP for the programmer: <br> <img src="images/AVR8BurnOMat-settings.png" />
|
||||||
1. Click on **Settings->AVRDUDE** and fill in the details about avrdude location using the installation path written previously as well as selecting USBASP for the programmer:
|
|
||||||
<img src="images/AVR8BurnOMat-settings.png" />
|
|
||||||
1. Once done click on OK.
|
1. Once done click on OK.
|
||||||
1. You are now done with all the installations/configuration and ready to program your Multi-module.
|
1. You are now done with all the installations/configuration and ready to program your Multi-module.
|
||||||
|
|
||||||
@ -32,15 +30,14 @@ Banggood 4-in-1 module with [custom mikeb bootloader](Advanced_ATmega_Serial_Upl
|
|||||||
|
|
||||||
If you don't know which one to take the 1st line is the one you want.
|
If you don't know which one to take the 1st line is the one you want.
|
||||||
|
|
||||||
###Burn the fuses
|
### Burn the fuses
|
||||||
1. Follow this section: [Connect the programmer](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/docs/Compiling.md#connect-the-programmer)
|
1. Follow this section: [Connect the programmer](Compiling.md#connect-the-programmer)
|
||||||
1. Launch AVR8 Burn-O-Mat.
|
1. Launch AVR8 Burn-O-Mat.
|
||||||
1. In the **AVR type** drop down select **ATmega328P** and click on **Fuses**
|
1. In the **AVR type** drop down select **ATmega328P** and click on **Fuses**
|
||||||
1. In the **ATmega328P Fuses** window which just open click on read fuses.
|
1. In the **ATmega328P Fuses** window which just open click on read fuses.
|
||||||
1. Ignore the error "warning : Can not Set sck period . usbasp please check for firmware update .".
|
1. Ignore the error "warning : Can not Set sck period . usbasp please check for firmware update .".
|
||||||
1. If you get an error there is something wrong with your connections, your programmer, or your board. Verify everything and go back to the 1st bullet point.
|
1. If you get an error there is something wrong with your connections, your programmer, or your board. Verify everything and go back to the 1st bullet point.
|
||||||
1. Set the 3 Fuse values
|
1. Set the 3 Fuse values <br> <img src="images/AVR8BurnOMat-fuses.png" />
|
||||||
<img src="images/AVR8BurnOMat-fuses.png" />
|
|
||||||
1. Click on **apply**
|
1. Click on **apply**
|
||||||
1. Click on **write fuses**
|
1. Click on **write fuses**
|
||||||
1. Ignore the error "warning : Can not Set sck period . usbasp please check for firmware update .".
|
1. Ignore the error "warning : Can not Set sck period . usbasp please check for firmware update .".
|
||||||
@ -48,7 +45,7 @@ If you don't know which one to take the 1st line is the one you want.
|
|||||||
1. You are done with setting the Fuses and can close the **ATmega328P Fuses** window
|
1. You are done with setting the Fuses and can close the **ATmega328P Fuses** window
|
||||||
|
|
||||||
## Upload the firmware
|
## Upload the firmware
|
||||||
1. Follow this section: [Connect the programmer](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/docs/Compiling.md#connect-the-programmer)
|
1. Follow this section: [Connect the programmer](Compiling.md#connect-the-programmer)
|
||||||
1. Download the [latest release firmware](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases) you want to burn and store it in a knwon location
|
1. Download the [latest release firmware](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases) you want to burn and store it in a knwon location
|
||||||
1. Launch AVR8 Burn-O-Mat.
|
1. Launch AVR8 Burn-O-Mat.
|
||||||
1. In the **AVR type** drop down select **ATmega328P**
|
1. In the **AVR type** drop down select **ATmega328P**
|
||||||
|
@ -1,26 +1,28 @@
|
|||||||
#Advanced Topics {This page is currently a proof of concept}
|
# Advanced Topics {This page is currently a proof of concept}
|
||||||
Warning: the topics on this page are not for the fainthearted. It is strongly recommended that you have some experience in getting up and runnning with your module before you dive in there. On the other hand what is described on this page are some very useful options that could greatly increase the value and the enjoyment of your Multiprotocol module.
|
Warning: the topics on this page are not for the fainthearted. It is strongly recommended that you have some experience in getting up and runnning with your module before you dive in there. On the other hand what is described on this page are some very useful options that could greatly increase the value and the enjoyment of your Multiprotocol module.
|
||||||
#Serial uploader that works through the transmitter pins
|
|
||||||
|
# Serial uploader that works through the transmitter pins
|
||||||
This document describes how you can set up your ATmega-based Mulitprotocol module to allow you to update the firmware by connecting a USB to TTL serial (like a FTDI) adapter to the module's transmitter interface pins. It is great if you exclusively use the Serial interface with your transmitter because the Bind button is used as "bootloader" button. It requires a small custom bootloader to be uploaded and a simple interface cable to be soldered up. See the [Advanced ATmega Serial Uploader](Advanced_ATmega_Serial_Uploader.md) page for more details.
|
This document describes how you can set up your ATmega-based Mulitprotocol module to allow you to update the firmware by connecting a USB to TTL serial (like a FTDI) adapter to the module's transmitter interface pins. It is great if you exclusively use the Serial interface with your transmitter because the Bind button is used as "bootloader" button. It requires a small custom bootloader to be uploaded and a simple interface cable to be soldered up. See the [Advanced ATmega Serial Uploader](Advanced_ATmega_Serial_Uploader.md) page for more details.
|
||||||
Created and supported by: Mike Blandford
|
Created and supported by: Mike Blandford
|
||||||
|
|
||||||
RCGroups page: http://www.rcgroups.com/forums/showpost.php?p=35584619&postcount=4867
|
RCGroups page: http://www.rcgroups.com/forums/showpost.php?p=35584619&postcount=4867
|
||||||
|
|
||||||
#Telemetry in PPM mode
|
# Telemetry in PPM mode
|
||||||
It is possible to access the telemetry stream coming from the receiver through the MULTI-module. This document describes a simple bluetooth module to stream telemetry information to a mobile device like an Android smartphone or tablet. The method may be generalized to feed telemetry to the transmitter if the transmitter has the capabilities to process the information. This is very useful with modules used in the PPM mode with transmitters that do not support telemetry. See the [Advanced Bluetooth Telemetry](Advanced_Bluetooth_Telemetry.md) page for more details.
|
It is possible to access the telemetry stream coming from the receiver through the MULTI-module. This document describes a simple bluetooth module to stream telemetry information to a mobile device like an Android smartphone or tablet. The method may be generalized to feed telemetry to the transmitter if the transmitter has the capabilities to process the information. This is very useful with modules used in the PPM mode with transmitters that do not support telemetry. See the [Advanced Bluetooth Telemetry](Advanced_Bluetooth_Telemetry.md) page for more details.
|
||||||
Created and supported by: Midelic
|
Created and supported by: Midelic
|
||||||
|
|
||||||
RCGroups page: None
|
RCGroups page: None
|
||||||
|
|
||||||
|
|
||||||
#Manually setting fuses on ATmega328
|
# Manually setting fuses on ATmega328
|
||||||
This document describes a relatively simple process to set the fuses on ATmega328 using the flexibility of the command line. It does not require installation of AVRdude because it uses the AVRdude that is bundled with the Arduino IDE. See the [Advanced Manually Setting ATmega328 Fuses](Advanced_Manually_Setting_ATmega328_Fuses.md) page for more details.
|
This document describes a relatively simple process to set the fuses on ATmega328 using the flexibility of the command line. It does not require installation of AVRdude because it uses the AVRdude that is bundled with the Arduino IDE. See the [Advanced Manually Setting ATmega328 Fuses](Advanced_Manually_Setting_ATmega328_Fuses.md) page for more details.
|
||||||
|
|
||||||
Created and supported by: hpnuts
|
Created and supported by: hpnuts
|
||||||
|
|
||||||
## Flashing Multi_STM32 module.
|
## Flashing Multi_STM32 module.
|
||||||
|
|
||||||
####Flashing without Tx power
|
#### Flashing without Tx power
|
||||||
|
|
||||||
This is another method of Flshing Multi_STM32 which is riskier.This method is for skilled users who understand the task.
|
This is another method of Flshing Multi_STM32 which is riskier.This method is for skilled users who understand the task.
|
||||||
|
|
||||||
The key difference of this method is that the 3.3V FTDI cable must also provide power to the 5V circuitry during the flashing process. To do this, a jumper must be enabled connecting the 3.3V VCC to the 5V line. The risk is to forget 3.3V jumper in, after flashing and when TX restarted.
|
The key difference of this method is that the 3.3V FTDI cable must also provide power to the 5V circuitry during the flashing process. To do this, a jumper must be enabled connecting the 3.3V VCC to the 5V line. The risk is to forget 3.3V jumper in, after flashing and when TX restarted.
|
||||||
@ -32,18 +34,19 @@ The key difference of this method is that the 3.3V FTDI cable must also provide
|
|||||||
1. Remove the module from the transmitter bay
|
1. Remove the module from the transmitter bay
|
||||||
1. Set BOOT0 jumper Skip this step if you made your own cable.
|
1. Set BOOT0 jumper Skip this step if you made your own cable.
|
||||||
1. Set the 3.3V jumper.
|
1. Set the 3.3V jumper.
|
||||||
1. Connect your 3.3V FTDI cable (USB - TTL serial) to Multiprotocol serial port (RX,TX,GND,5V). Connect the pins as follows:
|
1. Connect your 3.3V FTDI cable (USB - TTL serial) to Multiprotocol serial port (RX,TX,GND,5V).
|
||||||
- Module RX pin to FTDI TX pin
|
Connect the pins as follows:
|
||||||
- Module TX pin to FTDI Rx pin
|
* Module RX pin to FTDI TX pin
|
||||||
- Module GND to FTDI GND
|
* Module TX pin to FTDI Rx pin
|
||||||
- Module 5V to FTDI 3.3V FTDI power supply.
|
* Module GND to FTDI GND
|
||||||
|
* Module 5V to FTDI 3.3V FTDI power supply
|
||||||
1. In arduino IDE under the **Tools** -> **Board:** check that you have selected the **Generic STM32F103C series** board
|
1. In arduino IDE under the **Tools** -> **Board:** check that you have selected the **Generic STM32F103C series** board
|
||||||
1. Under **Tools** -> **Upload Method:** select **Serial**.
|
1. Under **Tools** -> **Upload Method:** select **Serial**.
|
||||||
1. Click "Upload" and the sketch will be uploaded normally.
|
1. Click "Upload" and the sketch will be uploaded normally.
|
||||||
1. Once the firmware has uploaded:
|
1. Once the firmware has uploaded:
|
||||||
- Remove the 3.3V jumper!!!!
|
* Remove the 3.3V jumper!!!!
|
||||||
- Remove the BOOT0 jumper
|
* Remove the BOOT0 jumper
|
||||||
- Check that you removed the 3.3V jumper
|
* Check that you removed the 3.3V jumper
|
||||||
1. Insert the module into the transmitter bay
|
1. Insert the module into the transmitter bay
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#Bill of Materials DIY ATmega Module
|
# Bill of Materials DIY ATmega Module
|
||||||
|
|
||||||
Here is the bill of materials for the ATmega328 version of the DIY MPTM.
|
Here is the bill of materials for the ATmega328 version of the DIY MPTM.
|
||||||
|
|
||||||
If you are looking for the BOM for the DIY STM32 version click [here](BOM_DIY_STM32.md).
|
If you are looking for the BOM for the DIY STM32 version click [here](BOM_DIY_STM32%20&%20Schematic.md).
|
||||||
|
|
||||||
Digikey may not be your preferred supplier, but you should find enough information on their page to cross reference parts.
|
Digikey may not be your preferred supplier, but you should find enough information on their page to cross reference parts.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#Bill of Materials DIY STM32 Module
|
# Bill of Materials DIY STM32 Module
|
||||||
|
|
||||||
Here is the bill of materials for the STM32 version of the DIY MPTM. There are three versions. Carefully compare your board with the pictures below to determine which version you have.
|
Here is the bill of materials for the STM32 version of the DIY MPTM. There are three versions. Carefully compare your board with the pictures below to determine which version you have.
|
||||||
|
|
||||||
@ -7,19 +7,32 @@ All diagrams and eagle files are available [here](https://github.com/pascallange
|
|||||||
If you are looking for the BOM for the DIY ATmega328 3.2d version click [here](BOM_DIY_ATmega.md).
|
If you are looking for the BOM for the DIY ATmega328 3.2d version click [here](BOM_DIY_ATmega.md).
|
||||||
|
|
||||||
Digikey may not be your preferred supplier, but you should find enough information on their page to cross reference parts.
|
Digikey may not be your preferred supplier, but you should find enough information on their page to cross reference parts.
|
||||||
|
If digikey is your prefered supplier, their is a link to shared carts to make checkout easier at the begining of the BOM.
|
||||||
|
|
||||||
## IMPORTANT NOTE on Telemetry
|
## IMPORTANT NOTE on Telemetry
|
||||||
In the case of the Turnigy 9X/9XR/9XR Pro you don't need to invert the telemetry signal therefore the instalation of the inverter chip SN74LVC2G86DCTR is **OPTIONAL**. In this case and in order to have telemetry you need to solder **SJ1/SJ301** on the back of the board depending on which board version you have.
|
In the case of the Turnigy 9X/9XR/9XR Pro you don't need to invert the telemetry signal therefore the instalation of the inverter chip SN74LVC2G86DCTR is **OPTIONAL**. In this case and in order to have telemetry you need to solder **SJ1/SJ301** on the back of the board depending on which board version you have.
|
||||||
|
|
||||||
The inverted telemetry signal is required by TARANIS TX and other boards so for telemetry to work properly the inverter chip must be installed.
|
The inverted telemetry signal is required by TARANIS TX and other boards so for telemetry to work properly the inverter chip must be installed.
|
||||||
|
|
||||||
## BOM DIY STM32 PCB V1.0t - the USB version
|
## BOM DIY STM32 PCB V1.1t - USB version update
|
||||||
|
The board is available at OSHpark [here](https://oshpark.com/shared_projects/eWtNW6jo)
|
||||||
|
|
||||||
|
<img src="images/Board_PCB_STM32_USB_V1.1-2.png" width="300" height="400"/> <img src="images/Board_PCB_STM32_USB_V1.1-1.png" width="300" height="400"/>
|
||||||
|
|
||||||
|
|
||||||
|
## BOM DIY STM32 PCB V1.0t & V1.1 - the USB version
|
||||||
This BOM is for the board with the USB port which allows firmware upload.
|
This BOM is for the board with the USB port which allows firmware upload.
|
||||||
|
|
||||||
The board is available at OSHpark [here](https://oshpark.com/shared_projects/GX51nEoH)
|
The board is available at OSHpark [here](https://oshpark.com/shared_projects/GX51nEoH)
|
||||||
|
|
||||||
<img src="images/Board_PCB_STM32_USB-1.png" width="300" height="400"/> <img src="images/Board_PCB_STM32_USB-2.png" width="300" height="400"/>
|
<img src="images/Board_PCB_STM32_USB-1.png" width="300" height="400"/> <img src="images/Board_PCB_STM32_USB-2.png" width="300" height="400"/>
|
||||||
|
|
||||||
|
Digikey BOM shared cart for building 1 module [here](http://www.digikey.com/short/3dn71h)
|
||||||
|
|
||||||
|
Digikey BOM shared cart for building 3 modules [here](http://www.digikey.com/short/3dnt2r)
|
||||||
|
|
||||||
|
Please Note - With the Digikey shared carts it is cheaper to order 10 piece stips with some parts like resistors and capacitors. These extra parts are not reflected or needed in the followong BOM list.
|
||||||
|
|
||||||
Qty|Part|Description|Value|Package|Digikey Part Number
|
Qty|Part|Description|Value|Package|Digikey Part Number
|
||||||
---|----|-----------|-----|-------|-------------------
|
---|----|-----------|-----|-------|-------------------
|
||||||
1|J301|Receptacle|5-pin||[WM3103-ND](http://www.digikey.com/product-search/en?keywords=WM3103-ND)
|
1|J301|Receptacle|5-pin||[WM3103-ND](http://www.digikey.com/product-search/en?keywords=WM3103-ND)
|
||||||
@ -33,7 +46,7 @@ Qty|Part|Description|Value|Package|Digikey Part Number
|
|||||||
1|C203|Cap Ceramic|4u7|0805|[311-1371-1-ND](https://www.digikey.com/product-detail/en/yageo/CC0805ZRY5V6BB475/311-1371-1-ND/2103155)
|
1|C203|Cap Ceramic|4u7|0805|[311-1371-1-ND](https://www.digikey.com/product-detail/en/yageo/CC0805ZRY5V6BB475/311-1371-1-ND/2103155)
|
||||||
1|C207|Cap Ceramic|1uF|0805|[311-1365-1-ND](https://www.digikey.com/product-detail/en/yageo/CC0805KKX7R7BB105/311-1365-1-ND/2103149)
|
1|C207|Cap Ceramic|1uF|0805|[311-1365-1-ND](https://www.digikey.com/product-detail/en/yageo/CC0805KKX7R7BB105/311-1365-1-ND/2103149)
|
||||||
1|C208|Cap Ceramic|10nF|0805|[311-1136-1-ND](http://www.digikey.com/products/en?keywords=311-1136-1-ND)
|
1|C208|Cap Ceramic|10nF|0805|[311-1136-1-ND](http://www.digikey.com/products/en?keywords=311-1136-1-ND)
|
||||||
4|D201,301,302,303|Diode Shottky|BAT48|SOD123|[497-5712-1-ND](http://www.digikey.com/products/en?keywords=497-5712-1-ND)
|
5|D101*,201,301,302,303|Diode Shottky|BAT48|SOD123|[497-5712-1-ND](http://www.digikey.com/products/en?keywords=497-5712-1-ND)
|
||||||
1|IC101|Voltage reg 5V|AMS1117-50|SOT223|[LM1117MP-5.0/NOPBCT-ND](https://www.digikey.com/product-detail/en/texas-instruments/LM1117MP-5.0-NOPB/LM1117MP-5.0-NOPBCT-ND/363589)
|
1|IC101|Voltage reg 5V|AMS1117-50|SOT223|[LM1117MP-5.0/NOPBCT-ND](https://www.digikey.com/product-detail/en/texas-instruments/LM1117MP-5.0-NOPB/LM1117MP-5.0-NOPBCT-ND/363589)
|
||||||
1|IC102|Voltage reg 3.3V|AMS1117-33|SOT223|[LM1117MPX-3.3/NOPBCT-ND](https://www.digikey.com/product-detail/en/texas-instruments/LM1117MPX-3.3-NOPB/LM1117MPX-3.3-NOPBCT-ND/1010516)
|
1|IC102|Voltage reg 3.3V|AMS1117-33|SOT223|[LM1117MPX-3.3/NOPBCT-ND](https://www.digikey.com/product-detail/en/texas-instruments/LM1117MPX-3.3-NOPB/LM1117MPX-3.3-NOPBCT-ND/1010516)
|
||||||
1|L101|High Freq Inductor|10uH|1812|[CM453232-100KLCT-ND](https://www.digikey.com/product-detail/en/bourns-inc/CM453232-100KL/CM453232-100KLCT-ND/3437938)
|
1|L101|High Freq Inductor|10uH|1812|[CM453232-100KLCT-ND](https://www.digikey.com/product-detail/en/bourns-inc/CM453232-100KL/CM453232-100KLCT-ND/3437938)
|
||||||
@ -55,6 +68,8 @@ Qty|Part|Description|Value|Package|Digikey Part Number
|
|||||||
1|U301|Dual INPUT-XOR|SN74LVC2G86DCTR|SSM8|[296-13274-1-ND](http://www.digikey.com/product-detail/en/texas-instruments/SN74LVC2G86DCTR/296-13274-1-ND/484501)
|
1|U301|Dual INPUT-XOR|SN74LVC2G86DCTR|SSM8|[296-13274-1-ND](http://www.digikey.com/product-detail/en/texas-instruments/SN74LVC2G86DCTR/296-13274-1-ND/484501)
|
||||||
1|CON401|ANT.conn SMD|||[WM5587CT-ND](https://www.digikey.com/product-detail/en/molex-llc/0734120110/WM5587CT-ND/1894612)
|
1|CON401|ANT.conn SMD|||[WM5587CT-ND](https://www.digikey.com/product-detail/en/molex-llc/0734120110/WM5587CT-ND/1894612)
|
||||||
|
|
||||||
|
* Diode D101 is only required for the V1.1 board
|
||||||
|
|
||||||
PCB STM32 V1.0t Schematic
|
PCB STM32 V1.0t Schematic
|
||||||
<img src="https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/STM32%20PCB/Schematic_Multiprotocol_STM32_MB_v1.0_t.jpg" width="1000" height="500" />
|
<img src="https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/STM32%20PCB/Schematic_Multiprotocol_STM32_MB_v1.0_t.jpg" width="1000" height="500" />
|
||||||
|
|
||||||
@ -98,9 +113,8 @@ Qty|Part|Description|Value|Package|Digikey Part Number
|
|||||||
## BOM DIY STM32 PCB - the first Version
|
## BOM DIY STM32 PCB - the first Version
|
||||||
This BOM is for the board that looks like this - check carefully:
|
This BOM is for the board that looks like this - check carefully:
|
||||||
|
|
||||||
<img src="https://camo.githubusercontent.com/9b8dc4eb5618583ebe8fc01f03f2da75766080b3/68747470733a2f2f36343464623464653335303563343061303434342d33323737323362636532393865336666353831336662343262616565666261612e73736c2e6366312e7261636b63646e2e636f6d2f66326435393865616364386539656562633338313861646634373737373139392e706e67" width="300" height="400"/>
|
|
||||||
<img
|
<img
|
||||||
src="https://644db4de3505c40a0444-327723bce298e3ff5813fb42baeefbaa.ssl.cf1.rackcdn.com/2026cfd1d0187a770570052590168df1.png" width="300" height="400"/>
|
src="https://644db4de3505c40a0444-327723bce298e3ff5813fb42baeefbaa.ssl.cf1.rackcdn.com/2026cfd1d0187a770570052590168df1.png" width="300" height="400"/> <img src="https://camo.githubusercontent.com/9b8dc4eb5618583ebe8fc01f03f2da75766080b3/68747470733a2f2f36343464623464653335303563343061303434342d33323737323362636532393865336666353831336662343262616565666261612e73736c2e6366312e7261636b63646e2e636f6d2f66326435393865616364386539656562633338313861646634373737373139392e706e67" width="300" height="400"/>
|
||||||
|
|
||||||
|
|
||||||
Qty|Part|Description|Value|Package|Digikey Part Number
|
Qty|Part|Description|Value|Package|Digikey Part Number
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#Getting your Bind timing right.
|
# Getting your Bind timing right.
|
||||||
On many consumer models it it important for the Tx to send a bind signal in a narrow window once the model has powered up.
|
On many consumer models it it important for the Tx to send a bind signal in a narrow window once the model has powered up.
|
||||||
|
|
||||||
If the bind signal is not recieved during this window, the bind sequence times out. Try this:
|
If the bind signal is not recieved during this window, the bind sequence times out. Try this:
|
||||||
|
@ -4,7 +4,7 @@ Multiprotocol source are compiled using the well known Arduino IDE.
|
|||||||
|
|
||||||
The procedure below will guide you through all the steps to upload successfully a customized firmware.
|
The procedure below will guide you through all the steps to upload successfully a customized firmware.
|
||||||
|
|
||||||
##Install the Arduino IDE and the Multiprotocol project firmware
|
## Install the Arduino IDE and the Multiprotocol project firmware
|
||||||
1. Download and install the Arduino IDE. The currently supported Arduino version is 1.6.12. available for [Windows]( https://www.arduino.cc/download_handler.php?f=/arduino-1.6.12-windows.exe) and [Mac OSX](https://www.arduino.cc/download_handler.php?f=/arduino-1.6.12-macosx.zip)
|
1. Download and install the Arduino IDE. The currently supported Arduino version is 1.6.12. available for [Windows]( https://www.arduino.cc/download_handler.php?f=/arduino-1.6.12-windows.exe) and [Mac OSX](https://www.arduino.cc/download_handler.php?f=/arduino-1.6.12-macosx.zip)
|
||||||
1. It is recommended to upgrade Java to the [latest version](https://www.java.com/en/download/)
|
1. It is recommended to upgrade Java to the [latest version](https://www.java.com/en/download/)
|
||||||
1. Download the zip file with the Multiprotocol module source code from [here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/archive/master.zip)
|
1. Download the zip file with the Multiprotocol module source code from [here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/archive/master.zip)
|
||||||
@ -13,50 +13,42 @@ The procedure below will guide you through all the steps to upload successfully
|
|||||||
|
|
||||||
## Upload the firmware
|
## Upload the firmware
|
||||||
|
|
||||||
###Material you need to upload the firmware
|
### Material you need to upload the firmware
|
||||||
1. USBASP programmer supporting 3.3V: <img src="images/USBasp_Programmer.jpeg" width="200" height="200" /> [(example aliexpress link)](https://www.aliexpress.com/item/USBasp-USB-ISP-3-3V-5V-AVR-Programmer-USB-ATMEGA8-ATMEGA128-New-10PIN-Wire-Support/2036402518.html?spm=2114.30010308.8.10.jIbHzs). There are reports that some of the cheap programmers are not safe to use with 3.3V units, usually the black PCB versions are ok.
|
|
||||||
1. 10pin to 6pin adapter: <img src="images/10pin_2_6pin.JPG" width="150" height="150" /> [(example ebay link)](http://www.ebay.fr/itm/10-Pin-a-6-Pin-Carte-Adaptateur-M-F-pour-AVRISP-USBASP-STK500-Noir-Bleu-WT-/291862396761?hash=item43f45abf59:g:gXsAAOSwMgdXyGnh)
|
|
||||||
1. 6 pin header like this one: <img src="images/6pin_header.jpg" width="100" height="100" /> [(example Digi-Key link)](http://www.digikey.com/products/en?keywords=3M%20961206-6404-AR)
|
|
||||||
|
|
||||||
The 6 Pin header needs to be solder on the board like indicated by the red rectangle:
|
1. USBASP programmer supporting 3.3V: <br> <img src="images/USBasp_Programmer.jpeg" width="200" height="200"/> <br> [(example aliexpress link)](https://www.aliexpress.com/item/USBasp-USB-ISP-3-3V-5V-AVR-Programmer-USB-ATMEGA8-ATMEGA128-New-10PIN-Wire-Support/2036402518.html?spm=2114.30010308.8.10.jIbHzs) <br> There are reports that some of the cheap programmers are not safe to use with 3.3V units, usually the black PCB versions are ok. <br>
|
||||||
* Banggood readymade 4-in-1 module:
|
1. 10pin to 6pin adapter: <br> <img src="images/10pin_2_6pin.JPG" width="150" height="150"/> <br> [(example ebay link)](http://www.ebay.fr/itm/10-Pin-a-6-Pin-Carte-Adaptateur-M-F-pour-AVRISP-USBASP-STK500-Noir-Bleu-WT-/291862396761?hash=item43f45abf59:g:gXsAAOSwMgdXyGnh) <br>
|
||||||
<img src="images/V2b_ISP.jpeg" width="189" height="200" />
|
1. 6 pin header like this one: <br> <img src="images/6pin_header.jpg" width="100" height="100"/> <br> [(example Digi-Key link)](http://www.digikey.com/products/en?keywords=3M%20961206-6404-AR) <br>
|
||||||
* DIY Mulitprotocol modules (like the 2.3d board):
|
1. The 6 Pin header needs to be solder on the board like indicated by the red rectangle:
|
||||||
<img src="images/MPTM_PCB_2.3d_ISP.png" width="486" height="201" />
|
* Banggood readymade 4-in-1 module: <br><img src="images/V2b_ISP.jpeg" width="189" height="200"/> <br>
|
||||||
* Arduino Pro Mini module:
|
* DIY Mulitprotocol modules (like the 2.3d board): <br><img src="images/MPTM_PCB_2.3d_ISP.png" width="486" height="201"/> <br>
|
||||||
<img src="images/ProMini_ISP.png" width="195" height="200" />
|
* Arduino Pro Mini module: <br><img src="images/ProMini_ISP.png" width="195" height="200"/> <br>
|
||||||
|
|
||||||
###Connect the programmer
|
### Connect the programmer
|
||||||
|
|
||||||
1. Before you connect the programmer make sure that you have selected the 3.3V mode and not 5V. The RF Modules are not 5V tolerant and you will break them with 5V. On most programmers this is done by moving a jumper.
|
1. Before you connect the programmer make sure that you have selected the 3.3V mode and not 5V. The RF Modules are not 5V tolerant and you will break them with 5V. On most programmers this is done by moving a jumper. <br> <img src="images/USBasp_Programmer_jumper.png" width="200" height="200" />
|
||||||
<img src="images/USBasp_Programmer_jumper.png" width="200" height="200" />
|
|
||||||
1. Please re-read item 1. above before going on.
|
1. Please re-read item 1. above before going on.
|
||||||
1. Turn the rotary switch on the DIY Multiprotocol module to the 0 position. If you do not have a switch for Serial mode only then it is the same as being in the 0 position. The upload will not work if the switch is in any other position.
|
1. Turn the rotary switch on the DIY Multiprotocol module to the 0 position. If you do not have a switch for Serial mode only then it is the same as being in the 0 position. The upload will not work if the switch is in any other position.
|
||||||
1. Connect the 6-pin programming connector to the 6-pin ASP IVR connector on the DIY Multiprotocol board. Be sure to match the ground pin of the programmer connector to the ground pin on the board.
|
1. Connect the 6-pin programming connector to the 6-pin ASP IVR connector on the DIY Multiprotocol board. Be sure to match the ground pin of the programmer connector to the ground pin on the board.
|
||||||
|
|
||||||
The images below indicates the pin layout and the location of the ground pin on the board:
|
The images below indicates the pin layout and the location of the ground pin on the board:
|
||||||
* Banggood readymade 4-in-1 module:
|
* Banggood readymade 4-in-1 module: <br> <img src="images/V2b_ISP.jpeg" width="189" height="200" /> <br>
|
||||||
<img src="images/V2b_ISP.jpeg" width="189" height="200" />
|
* DIY Mulitprotocol modules (like the 2.3d board): <br> <img src="images/MPTM_PCB_2.3d_ISP.png" width="486" height="201" /> <br>
|
||||||
* DIY Mulitprotocol modules (like the 2.3d board):
|
* Arduino Pro Mini module: <br> <img src="images/ProMini_ISP.png" width="195" height="200" /> <br>
|
||||||
<img src="images/MPTM_PCB_2.3d_ISP.png" width="486" height="201" />
|
|
||||||
* Arduino Pro Mini module:
|
|
||||||
<img src="images/ProMini_ISP.png" width="195" height="200" />
|
|
||||||
|
|
||||||
You are now ready to plug in the USB programmer to the computer
|
You are now ready to plug in the USB programmer to the computer
|
||||||
|
|
||||||
If you are looking for a good working USBASP Windows driver, [use this one](http://www.protostack.com/download/USBasp-win-driver-x86-x64-v3.0.7.zip).
|
If you are looking for a good working USBASP Windows driver, [use this one](http://www.protostack.com/download/USBasp-win-driver-x86-x64-v3.0.7.zip).
|
||||||
|
|
||||||
###Configure Arduino IDE for Multiprotocol
|
### Configure Arduino IDE for Multiprotocol
|
||||||
1. Under Tools -> Board select the Arduino Pro or Pro Mini
|
1. Under Tools -> Board select the Arduino Pro or Pro Mini
|
||||||
1. Under Tools -> Processor select the ATmega328 (5V, 16MHz)
|
1. Under Tools -> Processor select the ATmega328 (5V, 16MHz)
|
||||||
1. Under Tools -> Programmer select your programmer type (probably USBASP from the shopping list above)
|
1. Under Tools -> Programmer select your programmer type (probably USBASP from the shopping list above)
|
||||||
|
|
||||||
<a name="CustomizeFirmareToYourNeeds"></a>
|
<a name="CustomizeFirmareToYourNeeds"></a>
|
||||||
###Customize the firmware to match your hardware and your needs
|
### Customize the firmware to match your hardware and your needs
|
||||||
All customization is done by editing the ```_Config.h ``` file in the Multiprotocol Arduino project.
|
All customization is done by editing the ```_Config.h ``` file in the Multiprotocol Arduino project.
|
||||||
|
|
||||||
In the Arduino IDE, click on the down arrow on the far right of the tab bar to show a list of project files (see the red circle on the screenshot below). Scroll down and select the _Config.h file.
|
In the Arduino IDE, click on the down arrow on the far right of the tab bar to show a list of project files (see the red circle on the screenshot below). Scroll down and select the _Config.h file. <br> <img src="images/Arduino.png" width="600" height="400" />
|
||||||
<img src="images/Arduino.png" width="600" height="400" />
|
|
||||||
|
|
||||||
The file has different sections which are explained in details. The best is to go through them one by one carefully and apply the configuration which matches your needs.
|
The file has different sections which are explained in details. The best is to go through them one by one carefully and apply the configuration which matches your needs.
|
||||||
|
|
||||||
@ -64,9 +56,7 @@ Most of the default settings should get you started quickly. But on modules with
|
|||||||
|
|
||||||
To fill in the "PROTOCOLS TO INCLUDE" section, it would be good to review all the available protocols on the [Protocol Details](../Protocols_Details.md) page and identify which one you would like to add on your module.
|
To fill in the "PROTOCOLS TO INCLUDE" section, it would be good to review all the available protocols on the [Protocol Details](../Protocols_Details.md) page and identify which one you would like to add on your module.
|
||||||
|
|
||||||
To check that the program will compile correctly and fit in the Atmega press the Check mark as shown below.
|
To check that the program will compile correctly and fit in the Atmega press the Check mark as shown below. <br> <img src="images/Arduino_check.jpg" width="99" height="130" />
|
||||||
|
|
||||||
<img src="images/Arduino_check.jpg" width="99" height="130" />
|
|
||||||
|
|
||||||
If you see something like the following, your firmware is still too big and you need to deselect additional protocols:
|
If you see something like the following, your firmware is still too big and you need to deselect additional protocols:
|
||||||
> Sketch uses 34,096 bytes (104%) of program storage space. Maximum is 32,768 bytes.
|
> Sketch uses 34,096 bytes (104%) of program storage space. Maximum is 32,768 bytes.
|
||||||
@ -75,13 +65,12 @@ If you see something like the following, your firmware is still too big and you
|
|||||||
|
|
||||||
If there is another error carefully read it, go to the line number indicated and correct your typo.
|
If there is another error carefully read it, go to the line number indicated and correct your typo.
|
||||||
|
|
||||||
###Flash the firmware
|
### Flash the firmware
|
||||||
|
|
||||||
1. If you have a 4in1 Multiprotocol module you can skip this step. If you've just finished to build your DIY Multiprotocol module (like v2.3d), the first step is to flash the fuses of the microcontroller. This needs to be done only once. For this purpose, click on **Tools -> Burn Bootloader**
|
1. If you have a 4in1 Multiprotocol module you can skip this step. If you've just finished to build your DIY Multiprotocol module (like v2.3d), the first step is to flash the fuses of the microcontroller. This needs to be done only once. For this purpose, click on **Tools -> Burn Bootloader**
|
||||||
|
|
||||||
1. You are now ready to flash the firmware. In the Arduino IDE click **Sketch -> Upload Using Programmer**.
|
1. You are now ready to flash the firmware. In the Arduino IDE click **Sketch -> Upload Using Programmer**.
|
||||||
|
|
||||||
If the output indicates that the firmware has been uploaded successfully - give yourself a pat on the back. Well done, you have successfully programmed your DIY Multiprotocol module. You can already go to the final step [Setting up your Transmitter](TransmitterSetup.md) and begin to fly!!!! But don't forget to visit the next topic [Advanced settings](#AdvancedSettings) which has some extra steps needed to use your module at his full potential.
|
If the output indicates that the firmware has been uploaded successfully - give yourself a pat on the back. Well done, you have successfully programmed your DIY Multiprotocol module. You can already go to the final step [Setting up your Transmitter](Transmitters.md#compatible-transmitters) and begin to fly!!!! But don't forget to visit the next topic [Advanced settings](#AdvancedSettings) which has some extra steps needed to use your module at his full potential.
|
||||||
|
|
||||||
**Troubleshooting**
|
**Troubleshooting**
|
||||||
|
|
||||||
@ -105,49 +94,47 @@ First, we need to append some text to the Arduino file boards.txt.
|
|||||||
|
|
||||||
#### On Windows
|
#### On Windows
|
||||||
1. Close the Arduino IDE
|
1. Close the Arduino IDE
|
||||||
1. Search Windows for the application WordPad (DO NOT USE Notepad). Right click on WordPad and select "Run as Administrator":
|
1. Search Windows for the application WordPad (DO NOT USE Notepad). <br> Right click on WordPad and select "Run as Administrator": <br> <img src="images/WordPad_Admin.jpg" height="200" /> <br>
|
||||||
<img src="images/WordPad_Admin.jpg" height="200" />
|
|
||||||
1. Open the file ```boards.txt``` located in this folder ```C:\Program Files(x86)\Arduino\hardware\arduino\avr ``` or the equivalent if you have installed Aduino in a different directory.
|
1. Open the file ```boards.txt``` located in this folder ```C:\Program Files(x86)\Arduino\hardware\arduino\avr ``` or the equivalent if you have installed Aduino in a different directory.
|
||||||
1. Append the following text into the end of the file and save it:
|
1. Append the following text into the end of the file and save it:
|
||||||
|
```
|
||||||
```
|
##############################################################
|
||||||
##############################################################
|
## Multi 4-in-1 (3.3V, 16 MHz) w/ ATmega328
|
||||||
## Multi 4-in-1 (3.3V, 16 MHz) w/ ATmega328
|
## --------------------------------------------------
|
||||||
## --------------------------------------------------
|
multi.name=Multi 4-in-1
|
||||||
multi.name=Multi 4-in-1
|
|
||||||
|
multi.upload.tool=avrdude
|
||||||
multi.upload.tool=avrdude
|
multi.upload.protocol=arduino
|
||||||
multi.upload.protocol=arduino
|
|
||||||
|
multi.bootloader.tool=avrdude
|
||||||
multi.bootloader.tool=avrdude
|
multi.bootloader.unlock_bits=0x3F
|
||||||
multi.bootloader.unlock_bits=0x3F
|
multi.bootloader.lock_bits=0x0F
|
||||||
multi.bootloader.lock_bits=0x0F
|
|
||||||
|
multi.build.board=AVR_PRO
|
||||||
multi.build.board=AVR_PRO
|
multi.build.core=arduino
|
||||||
multi.build.core=arduino
|
multi.build.variant=eightanaloginputs
|
||||||
multi.build.variant=eightanaloginputs
|
multi.build.extra_flags=-Wl,--relax
|
||||||
multi.build.extra_flags=-Wl,--relax
|
|
||||||
|
multi.menu.cpu.16MHzatmega328=ATmega328 (3.3V, 16 MHz)
|
||||||
multi.menu.cpu.16MHzatmega328=ATmega328 (3.3V, 16 MHz)
|
|
||||||
|
multi.menu.cpu.16MHzatmega328.upload.maximum_size=32768
|
||||||
multi.menu.cpu.16MHzatmega328.upload.maximum_size=32768
|
multi.menu.cpu.16MHzatmega328.upload.maximum_data_size=2048
|
||||||
multi.menu.cpu.16MHzatmega328.upload.maximum_data_size=2048
|
multi.menu.cpu.16MHzatmega328.upload.speed=57600
|
||||||
multi.menu.cpu.16MHzatmega328.upload.speed=57600
|
|
||||||
|
multi.menu.cpu.16MHzatmega328.bootloader.low_fuses=0xFF
|
||||||
multi.menu.cpu.16MHzatmega328.bootloader.low_fuses=0xFF
|
multi.menu.cpu.16MHzatmega328.bootloader.high_fuses=0xD3
|
||||||
multi.menu.cpu.16MHzatmega328.bootloader.high_fuses=0xD3
|
multi.menu.cpu.16MHzatmega328.bootloader.extended_fuses=0xFD
|
||||||
multi.menu.cpu.16MHzatmega328.bootloader.extended_fuses=0xFD
|
|
||||||
|
multi.menu.cpu.16MHzatmega328.build.mcu=atmega328p
|
||||||
multi.menu.cpu.16MHzatmega328.build.mcu=atmega328p
|
multi.menu.cpu.16MHzatmega328.build.f_cpu=16000000L
|
||||||
multi.menu.cpu.16MHzatmega328.build.f_cpu=16000000L
|
##############################################################
|
||||||
##############################################################
|
```
|
||||||
```
|
|
||||||
|
|
||||||
#### On Mac OSX:
|
#### On Mac OSX:
|
||||||
1. Close the Arduino IDE
|
1. Close the Arduino IDE
|
||||||
1. Using finder navigate to ```Applications``` folder
|
1. Using finder navigate to ```Applications``` folder
|
||||||
1. Ctl-Click on the Arduino application and select **Show Package Contents**.
|
1. Ctl-Click on the Arduino application and select **Show Package Contents**.
|
||||||
1. Browse to ```Contents/Java/hardware/arduino/avr`` and double click on boards.txt
|
1. Browse to ```Contents/Java/hardware/arduino/avr``` and double click on boards.txt
|
||||||
1. Copy and paste the "Multi 4-in-1" text listed above into the end of the file and save it.
|
1. Copy and paste the "Multi 4-in-1" text listed above into the end of the file and save it.
|
||||||
|
|
||||||
### Burn Bootloader
|
### Burn Bootloader
|
||||||
|
@ -7,71 +7,58 @@ Multiprotocol source can be compiled using the Arduino IDE using STM32 Core (Map
|
|||||||
On all modules with STM32F103 microcontroller, the program flash memory on the microcontroller is large enough to accommodate all the protocols. You do not have to make choices on which protocols to upload. Also, it is likely that you used the Banggood 4-in-1 RF module and you will therefore have access to all the RF modules.Now for programmng multimodule with STM32 chip you have 2 options presented below.
|
On all modules with STM32F103 microcontroller, the program flash memory on the microcontroller is large enough to accommodate all the protocols. You do not have to make choices on which protocols to upload. Also, it is likely that you used the Banggood 4-in-1 RF module and you will therefore have access to all the RF modules.Now for programmng multimodule with STM32 chip you have 2 options presented below.
|
||||||
|
|
||||||
1. Compiling and flashing in Arduino IDE.
|
1. Compiling and flashing in Arduino IDE.
|
||||||
|
|
||||||
1. Flashing precompiled binaries from [here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases)
|
1. Flashing precompiled binaries from [here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases)
|
||||||
|
- If using one of these TX with multimodule like Turnigy 9X,9XR,9X+ the binary file for flashing is **Multiprotocol_V1.X.X_STM32.bin**.
|
||||||
- If using one of these TX with multimodule like Turnigy 9X,9XR,9X+ the binary file for flashing is **Multiprotocol_V1.X.X_STM32.bin**.
|
- If using TARANIS TX the binary file is **Multiprotocol_V1.X.X_STM32_INV.bin**
|
||||||
|
|
||||||
- If using TARANIS TX the binary file is **Multiprotocol_V1.X.X_STM32_INV.bin**
|
|
||||||
|
|
||||||
Flashing precompiled **binaries** is done very simple with the cable setup presented below and an utility(GUI) **ST Flash Loader Demonstrator.**
|
Flashing precompiled **binaries** is done very simple with the cable setup presented below and an utility(GUI) **ST Flash Loader Demonstrator.**
|
||||||
|
|
||||||
|
## Compiling source and flashing in Arduino.
|
||||||
|
|
||||||
|
### Install the Arduino IDE and the Multiprotocol project
|
||||||
##Compiling source and flashing in Arduino.
|
|
||||||
|
|
||||||
###Install the Arduino IDE and the Multiprotocol project
|
|
||||||
1. Download the Arduino IDE. The currently supported Arduino version is 1.6.11 available for [Windows]( https://www.arduino.cc/download_handler.php?f=/arduino-1.6.12-windows.exe) and [Mac OSX](http://arduino.cc/download_handler.php?f=/arduino-1.6.12-macosx.zip)
|
1. Download the Arduino IDE. The currently supported Arduino version is 1.6.11 available for [Windows]( https://www.arduino.cc/download_handler.php?f=/arduino-1.6.12-windows.exe) and [Mac OSX](http://arduino.cc/download_handler.php?f=/arduino-1.6.12-macosx.zip)
|
||||||
1. It is recommended to upgrade Java to the [latest version](https://www.java.com/en/download/)
|
1. It is recommended to upgrade Java to the [latest version](https://www.java.com/en/download/)
|
||||||
1. Download the [STM32 Core](https://github.com/rogerclarkmelbourne/Arduino_STM32/archive/master.zip) and copy the Arduino_STM32 folder to:
|
1. Download the [STM32 Core](https://github.com/rogerclarkmelbourne/Arduino_STM32/archive/master.zip) and copy the Arduino_STM32 folder to:
|
||||||
- OSX: ```Arduino.app/Contents/Java/hardware``` (you can open Arduino.app by Ctl Clicking on Arduino.app and selecting "Show Package Contents")
|
- OSX: ```Arduino.app/Contents/Java/hardware``` (you can open Arduino.app by Ctl Clicking on Arduino.app and selecting "Show Package Contents")
|
||||||
- Windows: ```C:\Program Files (x86)\Arduino\hardware```
|
- Windows: ```C:\Program Files (x86)\Arduino\hardware```
|
||||||
- Make sure the folder tree structure is like this .....\hardware\Arduino_STM32\.....and **NOT** ...... \hardware\Arduino_STM32-master\Arduino_STM32-master\......So move the folders /rename accordingly.
|
- Make sure the folder tree structure is like this .....\hardware\Arduino_STM32\.....and **NOT** ...... \hardware\Arduino_STM32-master\Arduino_STM32-master\......So move the folders /rename accordingly.
|
||||||
|
|
||||||
1. Download the zip file with the Multiprotocol module source code from [here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)
|
1. Download the zip file with the Multiprotocol module source code from [here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)
|
||||||
1. Unzip and copy the source code folder ```Multiprotocol``` to a folder of your choosing
|
1. Unzip and copy the source code folder ```Multiprotocol``` to a folder of your choosing
|
||||||
1. Click on the ```Multiprotocol.ino file``` in the ```Multiprotocol``` folder and the Arduino environment should appear and the Multiprotocol project will be loaded.
|
1. Click on the ```Multiprotocol.ino file``` in the ```Multiprotocol``` folder and the Arduino environment should appear and the Multiprotocol project will be loaded.
|
||||||
|
|
||||||
###Prepare the Arduino IDE:
|
### Prepare the Arduino IDE:
|
||||||
|
|
||||||
1. In order to compile successfully you need also to modify a maple library file. In ```....\hardware\Arduino_STM32\STM32F1\cores\maple\libmaple\usart_f1.c``` comment out the 2 functions as shown below. This is required to have low-level access to the USART interrupt.
|
1. In order to compile successfully you need also to modify a maple library file. In ```....\hardware\Arduino_STM32\STM32F1\cores\maple\libmaple\usart_f1.c``` comment out the 2 functions as shown below. This is required to have low-level access to the USART interrupt. <br>
|
||||||
|
```
|
||||||
**/***
|
/* void __irq_usart2(void){
|
||||||
**void __irq_usart2(void){**
|
usart_irq(&usart2_rb, USART2_BASE);
|
||||||
|
}
|
||||||
**usart_irq(&usart2_rb, USART2_BASE);**
|
|
||||||
|
void __irq_usart3(void) {
|
||||||
**}**
|
usart_irq(&usart3_rb, USART3_BASE);
|
||||||
|
} */
|
||||||
**void __irq_usart3(void) {**
|
```
|
||||||
|
1. Run the IDE, and on the **Tools** menu, select **Board** and then **Boards manager**. <br> Click on the Arduino DUE (32 Bits ARM-Cortex M3) from the list of available boards. You must do this step, it installs the arm-none-eabi-g++ toolchain!
|
||||||
**usart_irq(&usart3_rb, USART3_BASE);**
|
|
||||||
|
|
||||||
**}
|
|
||||||
*/**
|
|
||||||
|
|
||||||
|
|
||||||
1. Run the IDE, and on the **Tools** menu, select **Board** and then **Boards manager**. Click on the Arduino DUE (32 Bits ARM-Cortex M3) from the list of available boards. You must do this step, it installs the arm-none-eabi-g++ toolchain!
|
|
||||||
1. Close and reopen the Arduino IDE and load the Multiprotocol project.
|
1. Close and reopen the Arduino IDE and load the Multiprotocol project.
|
||||||
1. In arduino IDE under the **Tools** -> **Board:** select the **Generic STM32F103C series** board
|
1. In arduino IDE under the **Tools** -> **Board:** select the **Generic STM32F103C series** board
|
||||||
1. Click on the **Verify** button to test compile the before you make any changes. If there are any errors check the process above and be sure to have the right version of the Arduino IDE.The binary file generated location is presented at the bottom of Arduino IDE compiling window.Now continue with flashing procedure.
|
1. Click on the **Verify** button to test compile the before you make any changes. <br> If there are any errors check the process above and be sure to have the right version of the Arduino IDE.The binary file generated location is presented at the bottom of Arduino IDE compiling window.Now continue with flashing procedure.
|
||||||
|
|
||||||
|
|
||||||
### Flashing the multimodule
|
### Flashing the multimodule
|
||||||
|
|
||||||
There are three options for flashing the firmware. But We will present here only 2 methods ,the third one is presented in advanced topics.
|
There are three options for flashing the firmware. But We will present here only 3 methods ,the 4-th one is presented in advanced topics.
|
||||||
The first (and strongly recommended) is flashing it while it is plugged into and powered by the transmitter.The second is preparing the board for flashing with a USB cable.
|
The first (and strongly recommended) is flashing it while it is plugged into and powered by the transmitter.The second is preparing the board for flashing with a USB cable.
|
||||||
The second method is definitely the easiest in the long-term, but it does require the USB bord and setting up the bootloader on the STM32 MCU.
|
The second method is definitely the easiest in the long-term, but it does require the USB bord and setting up the bootloader on the STM32 MCU.
|
||||||
|
The third method is also highly recommended and involving flashing using TX (firmware).At this methid is available for 9X ,9X pro ,Taranis with ersky9X fimrware.
|
||||||
|
|
||||||
####Option 1: Flashing with Tx power(highly recommended)
|
#### Option 1: Flashing with Tx power(highly recommended)
|
||||||
|
|
||||||
1. Put the module in the Tx
|
1. Put the module in the Tx
|
||||||
1. Place a jumper over the BOOT0 pins.Skip this one if you made your own cable for flashing ,see below.
|
1. Place a jumper over the BOOT0 pins.Skip this one if you made your own cable for flashing ,see below.
|
||||||
1. Connect your 3.3V/5V FTDI cable (USB - TTL serial) to Multiprotocol serial port. Connect only RX, TX and GND. **Do not connect the 5V or 3.3V between the FTDI cable and the module - the power will be supplied by the transmitter**. Connect the pins as follows:
|
1. Connect your 3.3V/5V FTDI cable (USB - TTL serial) to Multiprotocol serial port. <br> Connect only RX, TX and GND. **Do not connect the 5V or 3.3V between the FTDI cable and the module - the power will be supplied by the transmitter**. Connect the pins as follows:
|
||||||
- Module RX pin to FTDI TX pin
|
- Module RX pin to FTDI TX pin
|
||||||
- Module TX pin to FTDI Rx pin
|
- Module TX pin to FTDI Rx pin
|
||||||
- Module GND to FTDI GND
|
- Module GND to FTDI GND
|
||||||
|
|
||||||
1. In arduino IDE under the **Tools** -> **Board:** check that you have selected the **Generic STM32F103C series** board
|
1. In arduino IDE under the **Tools** -> **Board:** check that you have selected the **Generic STM32F103C series** board
|
||||||
1. Under **Tools** -> **Upload Method:** select **Serial**
|
1. Under **Tools** -> **Upload Method:** select **Serial**
|
||||||
1. Click "Upload" and the sketch will be uploaded normally. This is valid for all arduino versions.
|
1. Click "Upload" and the sketch will be uploaded normally. This is valid for all arduino versions.
|
||||||
@ -80,28 +67,41 @@ The second method is definitely the easiest in the long-term, but it does requi
|
|||||||
If you have the module inside a box and to be inserted in TX bay, you may build a flashing cable like in the picture below.
|
If you have the module inside a box and to be inserted in TX bay, you may build a flashing cable like in the picture below.
|
||||||
You can attach and solder a 5 pin header female and top outside the box.**ALways insert first the USB serial device in USB port , and TX start after.**
|
You can attach and solder a 5 pin header female and top outside the box.**ALways insert first the USB serial device in USB port , and TX start after.**
|
||||||
|
|
||||||
[<img src="images/Multi_STM32_ flashing.jpg" />]
|
<img src="images/Multi_STM32_ flashing.jpg" />
|
||||||
|
|
||||||
See below my module for reference
|
See below my module for reference
|
||||||
|
|
||||||
[<img src="images/Multi_STM32 module.JPG" width="600" height="400" />]
|
<img src="images/Multi_STM32 module.JPG" width="600" height="400" />
|
||||||
|
|
||||||
####Option 2: Flashing with USB cable.
|
#### Option 2: Flashing with USB cable.
|
||||||
|
|
||||||
This method use USB connector on the STM32 V1.0 board or on the maple clone board.
|
This method use USB connector on the STM32 V1.0 board or on the maple clone board.
|
||||||
|
1. Install first maple USB driver by running the batch file found in Arduino STM32 package folder ```..\hardware\Arduino_STM32\drivers\win\install_drivers.bat```
|
||||||
1. Install first maple USB driver by running the batch file found in Arduino STM32 package folder "..\hardware\Arduino_STM32\drivers\win\install_drivers.bat"
|
1. Download the free STM32 flash loader demonstrator from [ST.com](http://www.st.com/en/development-tools/flasher-stm32.html) and use a USB-TTL device (like FTDI cable) to flash the [StmMultiUSB.bin](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/raw/master/BootLoaders/StmMultiUSB/StmMultiUSB.bin) bootloader.
|
||||||
1. Download the free STM32 flash loader demonstrator from [ST.com](http://www.st.com/en/development-tools/flasher-stm32.html) and using a USB-TTL device (like FTDI cable) flash the STM32duino bootloader available from Roger Clark's great STM32 site [here](https://github.com/rogerclarkmelbourne/STM32duino-bootloader/tree/master/STM32F1/binaries) .Use bootloader **generic_boot20_pa1.bin**
|
1. Open Arduino IDE,browse to multiprotocol folder,load the sketch multiprotocol.ino.Select the serial COM port(see notes below)
|
||||||
1. Open Arduino IDE,browse to multiprotocol folder,load the sketch multiprotocol.ino.
|
1. In Arduino IDE under "Upload method" select **STM32duino**-bootloader.Click upload ,wait until upload is complete.
|
||||||
1. In Arduino IDE under "Upload method" select **STM32duino**-bootloader.Wait until upload is complete.
|
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- When you use multiSTM32_USB for the first time,the USB drivers are not recognized and port is not open/recognized(arduino IDE port selection is grey/unavailable). After this first time use, any subsequent update of the program, you'll have to select the correct serial port and upload sketches normally in Arduino using USB port.
|
- When you use multiSTM32_USB for the first time,the USB drivers are not recognized and com port is not open/recognized(arduino IDE port selection is grey/unavailable). After this first time use, any subsequent update of the program, you'll have to select the correct serial port and upload sketches normally in Arduino using USB port.
|
||||||
|
- More explanations how all these work you find [here](http://www.stm32duino.com/viewtopic.php?f=32&t=1774_)
|
||||||
- If the initial upload fails, make sure you are running the latest [Java version](https://www.java.com/en/download/)
|
- If the initial upload fails, make sure you are running the latest [Java version](https://www.java.com/en/download/)
|
||||||
|
- If using Banggood multiSTM32_USB module, follow instructions from step1(USB drivers on your computer) and jump after, to step 3(most probably generic bootloader is installed on multi module and no need to be installed again).I don't have one for test so this is an educated guess.
|
||||||
|
|
||||||
|
|
||||||
|
#### Option 3: Flashing with TX radio(firmware)
|
||||||
|
1. Flash new STM32 bootloader(StmMultiBoot) on multimodule:
|
||||||
|
- Flash precompiled binary [**StmMuliBoot.bin**](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/raw/master/BootLoaders/StmMultiBoot/StmMultiBoot.bin) using **ST Flash loader demonstrator** and USB serial device(FTDI) , with same custom cable presented above.This process is the same as flashing with precompiled binaries.For BG(green) module you can folow the paper instructions for flashing coming with the module using bridge pins provided.
|
||||||
|
- After this process is complete switch off TX,remove cables FTDI serila device and/or mutimodule jumper used for flashing.The multimodule should be back in the same state as before.
|
||||||
|
|
||||||
|
1. Compile multiprotocol source in arduino IDE ,choose this time Upload method **STM32duino bootloader** ,select **"Export compiled Binary"** to show the binary file in the same folder as source.
|
||||||
|
1. Copy the resulted binary file to the TX radio SD card in the "/firmware" folder.
|
||||||
|
1. Now flash the TX radio with the latest firmware(for ersky9x it's version P221 "e2" test version or higher).
|
||||||
|
1. Enter in TX radio maintenance mode (for ersky9X, start the transmitter with both bottom trims pushed outwards). Select **Update Multi** press menu button select also the right com port,update ,then the multiprotocol.bin file (see the correct name) and press menu and again for flashing. You'll see a bar fill slowly .Wait for the procces to be complete.Press exit( or switch off TX) several times to come out of the maintenace mode.
|
||||||
|
1. Any subsequent update of the multiprotocol will follow 2-3 and 5-6 steps. There is no need anymore to use a USB serial device or cables for flashing.
|
||||||
|
|
||||||
## Flashing precompiled binaries:
|
## Flashing precompiled binaries:
|
||||||
|
|
||||||
If you want to flash a pre-compiled binary file (like the Release .bin files) you need specialized software and the same FTDI cable setup already posted [here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/docs/Compiling_STM32.md#option-1-flashing-with-tx-powerhighly-recommended).
|
If you want to flash a pre-compiled binary file (like the Release .bin files) you need specialized software and the same FTDI cable setup already posted [here](Compiling_STM32.md#option-1-flashing-with-tx-powerhighly-recommended).
|
||||||
|
|
||||||
1. Set BOOT0 jumper(skip this step if you aready made your own cable ,see above)
|
1. Set BOOT0 jumper(skip this step if you aready made your own cable ,see above)
|
||||||
1. Connect your 3.3V FTDI cable (USB - TTL serial) to Multiprotocol serial port (RX,TX,GND pins when flashing with TX power).
|
1. Connect your 3.3V FTDI cable (USB - TTL serial) to Multiprotocol serial port (RX,TX,GND pins when flashing with TX power).
|
||||||
@ -113,14 +113,12 @@ For uploading binaries(.bin files) there is a specialized software you need to i
|
|||||||
#### Windows:
|
#### Windows:
|
||||||
Download the **ST Flash Loader Demonstrator** from here: http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-programmers/flasher-stm32.html
|
Download the **ST Flash Loader Demonstrator** from here: http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-programmers/flasher-stm32.html
|
||||||
|
|
||||||
Run the ST Flash Loader program. There are many tutorials on the web on how to use this program.For example
|
Run the ST Flash Loader program. There are many tutorials on the web on how to use this program.For example: [here](http://www.scienceprog.com/flashing-programs-to-stm32-embedded-bootloader)
|
||||||
|
|
||||||
[here](http://www.scienceprog.com/flashing-programs-to-stm32-embedded-bootloader)
|
|
||||||
|
|
||||||
#### OSX:
|
#### OSX:
|
||||||
To be checked.
|
To be checked.
|
||||||
|
|
||||||
###Report issues for the STM32 board
|
### Report issues for the STM32 board
|
||||||
You can report your problem using the [GitHub issue](https://github.com/midelic/DIY-Multiprotocol-TX-Module/issues) system or go to the [Main thread on RCGROUPS](http://www.rcgroups.com/forums/showthread.php?t=2165676) to ask your question.
|
You can report your problem using the [GitHub issue](https://github.com/midelic/DIY-Multiprotocol-TX-Module/issues) system or go to the [Main thread on RCGROUPS](http://www.rcgroups.com/forums/showthread.php?t=2165676) to ask your question.
|
||||||
Please provide the following information:
|
Please provide the following information:
|
||||||
|
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
#Documentation ToDos
|
# Documentation ToDos
|
||||||
1. Documentation on all the FlySky boards: (MikeB?)
|
- [ ] Documentation on all the FlySky boards: (MikeB?)
|
||||||
- SKY board erSky9x
|
- SKY board erSky9x
|
||||||
- AR9X board erSky9x
|
- AR9X board erSky9x
|
||||||
- 9Xtreme board erSky9x
|
- 9Xtreme board erSky9x
|
||||||
- AR9X UNI board
|
- AR9X UNI board
|
||||||
1. Add to the troubleshooting page
|
- [ ] Add to the troubleshooting page
|
||||||
1. Add how to do custom protocol setup on er9x and OpenTx
|
- [ ] Add how to do custom protocol setup on er9x and OpenTx
|
||||||
1. Document the OrangeRx Transmitter module (Mikeb?)
|
- [ ] Document the OrangeRx Transmitter module (Mikeb?)
|
||||||
1. enabling Serial on the DIY PCB page
|
- [ ] enabling Serial on the DIY PCB page
|
||||||
1. lots of pictures mentioned between the {} markers
|
- [ ] lots of pictures mentioned between the {} markers
|
||||||
1. Someone to add the Build the board from scratch if it is still relevant
|
- [ ] Someone to add the Build the board from scratch if it is still relevant
|
||||||
|
- [ ] Move to atmega specific and add ftdi to stm32 AVR ISP programmer like the popular USBASP programming dongle that is 3.3V safe - available from many sellers on ebay. There are reports that some of the cheap programmers are not safe to use with 3.3V units (like this unit). Look for USBAsp programmers with the “LC Technologies” label. {Pascal to confirm these reports are true} Also, you will need a 10-pin to 6-pin connector to connect the USBASP to the board.
|
||||||
1. Move to atmega specific and add ftdi to stm32 AVR ISP programmer like the popular USBASP programming dongle that is 3.3V safe - available from many sellers on ebay. There are reports that some of the cheap programmers are not safe to use with 3.3V units (like this unit). Look for USBAsp programmers with the “LC Technologies” label. {Pascal to confirm these reports are true} Also, you will need a 10-pin to 6-pin connector to connect the USBASP to the board.
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
The choice of **Multiprotocol Transmitter Module (MULTI-Module)** hardware is the single biggest choice you will make. Due to the growing popularity of this project the number of hardware choices is growing almost monthly.
|
The choice of **Multiprotocol Transmitter Module (MULTI-Module)** hardware is the single biggest choice you will make. Due to the growing popularity of this project the number of hardware choices is growing almost monthly.
|
||||||
|
|
||||||
There are currently four common hardware options. They are (click on the pictures for more info):
|
There are currently four common hardware options. They are (`click on the pictures for more info`):
|
||||||
|
|
||||||
1. A ready-made 4-in-1 MULTI-Module which integrates the microcontroller with all four supported RF modules and a hardware antenna switcher.
|
1. A ready-made 4-in-1 MULTI-Module which integrates the microcontroller with all four supported RF modules and a hardware antenna switcher.
|
||||||
[<img src="images/4-in-1_Module_BG.jpeg" width="200" height="200" />](Module_BG_4-in-1.md)
|
[<img src="images/4-in-1_Module_BG.jpeg" width="200" height="200" />](Module_BG_4-in-1.md)
|
||||||
|
@ -1,19 +1,24 @@
|
|||||||
#Model Setup
|
# Model Setup
|
||||||
This is the page to document model or receiver specific setup instructions.
|
This is the page to document model or receiver specific setup instructions.
|
||||||
|
|
||||||
The Deviation project (on which this project was based) have a useful list of models [here](http://www.deviationtx.com/wiki/supported_models).
|
The Deviation project (on which this project was based) have a useful list of models [here](http://www.deviationtx.com/wiki/supported_models).
|
||||||
|
|
||||||
#Syma X5C
|
# Syma X5C
|
||||||
<img src="http://img2.cheapdrone.co.uk/images/upload/2014/12/X5C%203/SKU115108-7.jpg" Width="200" Height="200" />
|
<img src="http://img2.cheapdrone.co.uk/images/upload/2014/12/X5C%203/SKU115108-7.jpg" Width="200" Height="200" />
|
||||||
##Channel Map
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
## Channel Map
|
||||||
---|---|---|---|---|---|---|---
|
|
||||||
A|E|T|R|FLIP|RATES|PICTURE|VIDEO
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
##Binding
|
---|---|---|---|---|---|---|---|---
|
||||||
|
A|E|T|R|FLIP|RATES|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
|
## Binding
|
||||||
There are no special binding instructions. The model powers up in Autobind mode and expects the bind sequence from the transmitter within the first 4-5 seconds.
|
There are no special binding instructions. The model powers up in Autobind mode and expects the bind sequence from the transmitter within the first 4-5 seconds.
|
||||||
##Tx Setup
|
|
||||||
|
## Tx Setup
|
||||||
A basic 4-channel setup works perfectly, but some improvements are possible:
|
A basic 4-channel setup works perfectly, but some improvements are possible:
|
||||||
###Setting up a switch to Flip
|
|
||||||
|
### Setting up a switch to Flip
|
||||||
|
|
||||||
1. Choose your "Rates" switch - typically the momentary TRN switch
|
1. Choose your "Rates" switch - typically the momentary TRN switch
|
||||||
1. In the Mixer create an entry for CH5
|
1. In the Mixer create an entry for CH5
|
||||||
@ -21,7 +26,7 @@ A basic 4-channel setup works perfectly, but some improvements are possible:
|
|||||||
- er9X: Source: sTRN, Weight 100 (or whatever switch you selected)
|
- er9X: Source: sTRN, Weight 100 (or whatever switch you selected)
|
||||||
- OpenTx: Source: SH, Weight 200 (or whatever switch you selected)
|
- OpenTx: Source: SH, Weight 200 (or whatever switch you selected)
|
||||||
|
|
||||||
###Setting up a swich for high rates
|
### Setting up a swich for high rates
|
||||||
|
|
||||||
1. Choose your "Rates" switch
|
1. Choose your "Rates" switch
|
||||||
1. In the Mixer create an entry for CH6
|
1. In the Mixer create an entry for CH6
|
||||||
@ -31,7 +36,7 @@ A basic 4-channel setup works perfectly, but some improvements are possible:
|
|||||||
|
|
||||||
When the switch is in the rear position the rates will be standard, when the switch is forward rates will be high. There is no need to move the throttle stick to the full up and full down position as with the standard controller.
|
When the switch is in the rear position the rates will be standard, when the switch is forward rates will be high. There is no need to move the throttle stick to the full up and full down position as with the standard controller.
|
||||||
|
|
||||||
###Setting up Idle-up
|
### Setting up Idle-up
|
||||||
One of the most annoying functions on the Syma X5C is that the motors stop when the throttle is pulled back. This can be fixed by implmenting Idle-up on the transmitter (think of this as a very simple version of the Betaflight "Air Mode"). Idle up will ensure that even when the throttle is all the way down, a minimum command is passed to the motor to keep them spinning and to activate the stabilization.
|
One of the most annoying functions on the Syma X5C is that the motors stop when the throttle is pulled back. This can be fixed by implmenting Idle-up on the transmitter (think of this as a very simple version of the Betaflight "Air Mode"). Idle up will ensure that even when the throttle is all the way down, a minimum command is passed to the motor to keep them spinning and to activate the stabilization.
|
||||||
|
|
||||||
**To do this**:
|
**To do this**:
|
||||||
@ -41,49 +46,73 @@ One of the most annoying functions on the Syma X5C is that the motors stop when
|
|||||||
1. When you want to fly in "idle-up" mode flick the switch and your stabilization will always be active.
|
1. When you want to fly in "idle-up" mode flick the switch and your stabilization will always be active.
|
||||||
1. Remeber to switch off idle-up as soon as the quad lands (or crashes - to avoid damage to the motors)
|
1. Remeber to switch off idle-up as soon as the quad lands (or crashes - to avoid damage to the motors)
|
||||||
|
|
||||||
#Inductrix (Horizon Hobby)
|
### Additional notes on rates:
|
||||||
|
|
||||||
|
The SymaX driver can add full trim to the control output. Doing so enables
|
||||||
|
dramatic rates, steep angles, and high speeds. If CH6 is low, the usual Syma
|
||||||
|
full rates will be in effect. If CH6 is high, the SymaX extreme trim rates will be
|
||||||
|
in effect. Be cautious when first trying out the extreme rates.
|
||||||
|
|
||||||
|
The extreme rates do not work with with headless mode because in this
|
||||||
|
mode the trim and the primary control directions may not be aligned - the
|
||||||
|
primary control directions will be based on the headless mode, but the trims
|
||||||
|
remain based upon the quadcopter's heading. So extreme rates are disabled
|
||||||
|
when headless mode is selected.
|
||||||
|
|
||||||
|
Be aware that the use of extreme rates and the resulting steep angles will
|
||||||
|
disorient the gyro responsible for maintaining headless mode, and that the
|
||||||
|
direction the quadcopter thinks you selected for headless mode may not be
|
||||||
|
correct after especially wild flights.
|
||||||
|
|
||||||
|
|
||||||
|
# Inductrix (Horizon Hobby)
|
||||||
|
|
||||||
<img src="https://s7d5.scene7.com/is/image/horizonhobby/BLH8700_a0" Width="200" Height="200" />
|
<img src="https://s7d5.scene7.com/is/image/horizonhobby/BLH8700_a0" Width="200" Height="200" />
|
||||||
|
|
||||||
##Binding
|
## Binding
|
||||||
For telemetry enabled modules, you should just let the remote autodetect the settings. Otherwise choose DSMX 22ms with 6ch or 7ch. To bind the model, keep the transmitter off, power on the Inductrix. Wait until it flashes fast and then power up the Tx and use Bind.
|
For telemetry enabled modules, you should just let the remote autodetect the settings. Otherwise choose DSMX 22ms with 6ch or 7ch. To bind the model, keep the transmitter off, power on the Inductrix. Wait until it flashes fast and then power up the Tx and use Bind.
|
||||||
|
|
||||||
##Tx Setup
|
### Throttle
|
||||||
Remember that 100% on your transmitter using the MULTI-Module corresponds to 125% on the DSM receiver side. On some functions sending 100% will confuse the model. Conversely 80% on your Tx is interpreted to be 100% at the model. Consider this when implementing the suggestions below.
|
|
||||||
###Throttle
|
|
||||||
For Inductrix FPV you might need to adjust the lower end of throttle to be a higher than default, otherwise motors will be spinning on minimal throttle. One way to do this is to set the throttle to 80% output (100% of DSM output) and then to enable the **Throttle Idle Trim Only** under the Model Setup menu. See image below:
|
For Inductrix FPV you might need to adjust the lower end of throttle to be a higher than default, otherwise motors will be spinning on minimal throttle. One way to do this is to set the throttle to 80% output (100% of DSM output) and then to enable the **Throttle Idle Trim Only** under the Model Setup menu. See image below:
|
||||||
|
|
||||||
<img src="images/Inductrix_Throttle_Setup.png" Width="600" Height="200" />
|
<img src="images/Inductrix_Throttle_Setup.png" Width="600" Height="200" />
|
||||||
###Acro and Level Mode
|
|
||||||
|
### Acro and Level Mode
|
||||||
Setup channel 6 with a momemtary button or switch (e.g. SH on the Taranis) and use that switch to switch between modes. Set the output to somewhere between 40% to 60% for best results.
|
Setup channel 6 with a momemtary button or switch (e.g. SH on the Taranis) and use that switch to switch between modes. Set the output to somewhere between 40% to 60% for best results.
|
||||||
|
|
||||||
An addition consideration when flying in Acro mode is to reduce stick sensitivity and to add some expo. The screens below show one way of doing this. Customize to your needs.
|
An addition consideration when flying in Acro mode is to reduce stick sensitivity and to add some expo. The screens below show one way of doing this. Customize to your needs.
|
||||||
|
|
||||||
####Inputs Screen
|
#### Inputs Screen
|
||||||
The follwing INPUTS screen shows one potential setup to introduce expo for Acro mode. The activation of the expo on Roll, Pitch and Yaw is when the SG switch is not in the back position. Add to taste.
|
The follwing INPUTS screen shows one potential setup to introduce expo for Acro mode. The activation of the expo on Roll, Pitch and Yaw is when the SG switch is not in the back position. Add to taste.
|
||||||
|
|
||||||
<img src="images/Inductrix_Inputs.png" Width="600" Height="200" />
|
<img src="images/Inductrix_Inputs.png" Width="600" Height="200" />
|
||||||
|
|
||||||
####Aileron Rates attached to Switch !SG-up
|
#### Aileron Rates attached to Switch !SG-up
|
||||||
The next screen shows and example of how the expo (50%) was set up on the stick input and how it is activated by !SG-up:
|
The next screen shows and example of how the expo (50%) was set up on the stick input and how it is activated by !SG-up:
|
||||||
|
|
||||||
<img src="images/Inductrix_Aileron_Expo.png" Width="600" Height="200" />
|
<img src="images/Inductrix_Aileron_Expo.png" Width="600" Height="200" />
|
||||||
|
|
||||||
####Mixer Menu
|
#### Mixer Menu
|
||||||
The next screen shows the mixer menu with the mode change on momentary switch SH and High-Low rates on switch SC:
|
The next screen shows the mixer menu with the mode change on momentary switch SH and High-Low rates on switch SC:
|
||||||
|
|
||||||
<img src="images/Inductrix_Mixer.png" Width="600" Height="200" />
|
<img src="images/Inductrix_Mixer.png" Width="600" Height="200" />
|
||||||
|
|
||||||
# Cheerson CX-20 / Quanum Nova
|
# Cheerson CX-20 / Quanum Nova
|
||||||
<img src="http://uaequadcopters.com/images/products/Large/932-cheersoncx20dronquad.jpg" Width="200" Height="155" />
|
<img src="http://uaequadcopters.com/images/products/Large/932-cheersoncx20dronquad.jpg" Width="200" Height="155" />
|
||||||
##Channel Map
|
|
||||||
|
## Channel Map
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
||||||
---|---|---|---|---|---|---
|
---|---|---|---|---|---|---
|
||||||
A|E|T|R|MODE|AUX1|AUX2
|
A|E|T|R|MODE|AUX1|AUX2
|
||||||
|
|
||||||
##Binding
|
## Binding
|
||||||
The Rx powers up in binding mode so the transmitter should be set to autobind. If the Tx signal is lost due to power-off or going out of range the Rx will not re-bind, and requires power-cycling before it will bind again.
|
The Rx powers up in binding mode so the transmitter should be set to autobind. If the Tx signal is lost due to power-off or going out of range the Rx will not re-bind, and requires power-cycling before it will bind again.
|
||||||
|
|
||||||
##Tx Setup
|
## Tx Setup
|
||||||
AETR are simple +100% mixes. Note that the model expects Elevator (CH2) to be reversed, which is handled in the module firmware, so no need to reverse it on the Tx.
|
AETR are simple +100% mixes. Note that the model expects Elevator (CH2) to be reversed, which is handled in the module firmware, so no need to reverse it on the Tx.
|
||||||
|
|
||||||
###Flight modes
|
### Flight modes
|
||||||
CH5 is used to transmit the flight mode to the APM flight controller by setting the output to a value in a pre-defined range. The original Tx uses a 3-pos switch (SWA) and a 2-pos switch (SWB) to achieve six different combinations, but only five are used - with SWA at 0, 1500 is sent when SWB is at 0 and 1, leaving flight mode 3 unused. However, in the stock CX-20 flight controller settings, both flight mode 3 and 4 are set to the same flight mode, meaning we can configure our new Tx settings to send a value for mode 3 without changing the standard flight mode behaviour. Afterwards, you can optionally use Mission Planner to assign a new flight mode to mode 3 or mode 4, or reconfigure them altogether.
|
CH5 is used to transmit the flight mode to the APM flight controller by setting the output to a value in a pre-defined range. The original Tx uses a 3-pos switch (SWA) and a 2-pos switch (SWB) to achieve six different combinations, but only five are used - with SWA at 0, 1500 is sent when SWB is at 0 and 1, leaving flight mode 3 unused. However, in the stock CX-20 flight controller settings, both flight mode 3 and 4 are set to the same flight mode, meaning we can configure our new Tx settings to send a value for mode 3 without changing the standard flight mode behaviour. Afterwards, you can optionally use Mission Planner to assign a new flight mode to mode 3 or mode 4, or reconfigure them altogether.
|
||||||
|
|
||||||
The values, modes, and switch positions for the stock Tx are:
|
The values, modes, and switch positions for the stock Tx are:
|
||||||
@ -113,7 +142,7 @@ One easy way to acheive this is to configure six logical switches mapped to two
|
|||||||
|
|
||||||
To simply map the old Tx modes to the new Tx using the same switch positions, use the following configuration. The stock SWA switch is replaced with the ID0/1/2 switch, SWB is replaced with the AIL D/R switch.
|
To simply map the old Tx modes to the new Tx using the same switch positions, use the following configuration. The stock SWA switch is replaced with the ID0/1/2 switch, SWB is replaced with the AIL D/R switch.
|
||||||
|
|
||||||
####Logical switches:
|
#### Logical switches:
|
||||||
|
|
||||||
Switch|Function|V1|V2
|
Switch|Function|V1|V2
|
||||||
---|---|---|---
|
---|---|---|---
|
||||||
@ -124,7 +153,7 @@ L. Switch 4|AND|ID0|AIL
|
|||||||
L. Switch 5|AND|ID1|AIL
|
L. Switch 5|AND|ID1|AIL
|
||||||
L. Switch 6|AND|ID1|!AIL
|
L. Switch 6|AND|ID1|!AIL
|
||||||
|
|
||||||
####Flight modes (using CX-20 names):
|
#### light modes (using CX-20 names):
|
||||||
|
|
||||||
Mode|Name|Switch
|
Mode|Name|Switch
|
||||||
---|---|---
|
---|---|---
|
||||||
@ -135,7 +164,7 @@ Mode|Name|Switch
|
|||||||
5|DirLock|L5
|
5|DirLock|L5
|
||||||
6|Stable|L6
|
6|Stable|L6
|
||||||
|
|
||||||
####Mixer setup:
|
#### Mixer setup:
|
||||||
|
|
||||||
Channel|Weight|Source|Switch|Multiplex
|
Channel|Weight|Source|Switch|Multiplex
|
||||||
---|---|---|---|---
|
---|---|---|---|---
|
||||||
@ -154,11 +183,11 @@ CH6 and CH7 can be assigned to switches or pots to provide additionaly functiona
|
|||||||
Replicating the stock setup of two pots, you would assign:
|
Replicating the stock setup of two pots, you would assign:
|
||||||
|
|
||||||
Channel|Weight|Source|Multiplex
|
Channel|Weight|Source|Multiplex
|
||||||
---|---|---|---|---
|
---|---|---|---
|
||||||
CH6|+100%|P1|ADD
|
CH6|+100%|P1|ADD
|
||||||
CH7|+100%|P3|ADD
|
CH7|+100%|P3|ADD
|
||||||
|
|
||||||
##Full Mixer Setup
|
## Full Mixer Setup
|
||||||
|
|
||||||
Channel|Source|Weight|Switch|Multiplex
|
Channel|Source|Weight|Switch|Multiplex
|
||||||
---|---|---|---|---
|
---|---|---|---|---
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
#4-in-1 module
|
# 4-in-1 module
|
||||||
Currently the form factor of this module is designed for the JR-style module bay. Many of the popular RC transmitters use the JR-style module bay: FrSky Taranis, FlySky Th9x, Turnigy 9X/R/Pro
|
Currently the form factor of this module is designed for the JR-style module bay. Many of the popular RC transmitters use the JR-style module bay: FrSky Taranis, FlySky Th9x, Turnigy 9X/R/Pro
|
||||||
##What you need
|
## What you need
|
||||||
A fully assembled module + case available from Banggood.com [here](http://www.banggood.com/CC2500-NRF24L01-A7105-CYRF693-4-In-1-RF-Module-With-Case-For-Futaba-JR-Frsky-Transmitter-p-1116892.html)
|
A fully assembled module + case available from Banggood.com [here](http://www.banggood.com/CC2500-NRF24L01-A7105-CYRF693-4-In-1-RF-Module-With-Case-For-Futaba-JR-Frsky-Transmitter-p-1116892.html)
|
||||||
|
|
||||||
<img src="images/4-in-1_Module_Case_BG.jpeg" width="221" height="200" />
|
<img src="images/4-in-1_Module_Case_BG.jpeg" width="221" height="200" />
|
||||||
@ -21,9 +21,9 @@ For 9XR/9XR Pro, a new 3D printed module is available which makes use of the bui
|
|||||||
|
|
||||||
<img src="images/9XR_module.jpg" width="113" height="200" /> <img src="images/9XR_module_connector.jpg" width="274" height="200" />
|
<img src="images/9XR_module.jpg" width="113" height="200" /> <img src="images/9XR_module_connector.jpg" width="274" height="200" />
|
||||||
|
|
||||||
##Different working modes
|
## Different working modes
|
||||||
|
|
||||||
###PPM mode
|
### PPM mode
|
||||||
If you are only planning on using the PPM interface with your transmitter, you need to connect it as described:
|
If you are only planning on using the PPM interface with your transmitter, you need to connect it as described:
|
||||||
|
|
||||||
<img src="images/PPM.png" width="574" height="340" />
|
<img src="images/PPM.png" width="574" height="340" />
|
||||||
@ -34,7 +34,7 @@ The same plug is available on all versions of the module with the same signal lo
|
|||||||
|
|
||||||
If you wish to add an external device reading the telemetry, you need to enable serial mode as explained in the next topics otherwise you are now ready to go over to [Compiling and Programming](Compiling.md).
|
If you wish to add an external device reading the telemetry, you need to enable serial mode as explained in the next topics otherwise you are now ready to go over to [Compiling and Programming](Compiling.md).
|
||||||
|
|
||||||
###Serial mode
|
### Serial mode
|
||||||
If you have a transmitter that can support serial communication with the board then you need to wire up the board appropriately. There are three versions of the module and the steps are slightly different.
|
If you have a transmitter that can support serial communication with the board then you need to wire up the board appropriately. There are three versions of the module and the steps are slightly different.
|
||||||
|
|
||||||
Check which module you have and based on the pictures below. If you purchased the module after June 2016 then it is likely that you have a V1.1 type module. If you have purchased the version with case it is likely that you have a V1.2 type module.
|
Check which module you have and based on the pictures below. If you purchased the module after June 2016 then it is likely that you have a V1.1 type module. If you have purchased the version with case it is likely that you have a V1.2 type module.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#Build from stratch
|
# Build from stratch
|
||||||
|
|
||||||
If you can help to fully document this page, or just add additional detail please let us know on the rcgroups [forum](http://www.rcgroups.com/forums/showthread.php?t=2165676).
|
If you can help to fully document this page, or just add additional detail please let us know on the rcgroups [forum](http://www.rcgroups.com/forums/showthread.php?t=2165676).
|
||||||
|
|
||||||
@ -14,9 +14,9 @@ A module case that fits your receiver like the one [here](https://www.xtremepowe
|
|||||||
For 9XR/9XR Pro, a new 3D printed module is available which makes use of the built in antenna in the handle. This means nothing is getting out of the radio back. You can find all details of this module case on [Thingiverse](http://www.thingiverse.com/thing:2050717).
|
For 9XR/9XR Pro, a new 3D printed module is available which makes use of the built in antenna in the handle. This means nothing is getting out of the radio back. You can find all details of this module case on [Thingiverse](http://www.thingiverse.com/thing:2050717).
|
||||||
<img src="images/9XR_module.jpg" width="113" height="200" /> <img src="images/9XR_module_connector.jpg" width="274" height="200" />
|
<img src="images/9XR_module.jpg" width="113" height="200" /> <img src="images/9XR_module_connector.jpg" width="274" height="200" />
|
||||||
|
|
||||||
##Reference Schematic <a name="Schematic"></a>
|
## Reference Schematic <a name="Schematic"></a>
|
||||||
Here is the schematic you can use to troubleshoot the module
|
Here is the schematic you can use to troubleshoot the module
|
||||||
<img src="images/DIY_Mulitprotocol_Module_Schematic.jpeg" width="1000" height="500" />
|
<img src="images/DIY_Mulitprotocol_Module_Schematic.jpeg" width="1000" height="500" />
|
||||||
|
|
||||||
##Compiling and programming
|
## Compiling and programming
|
||||||
Follow the instruction on the [Compiling and programming page](Compiling.md)
|
Follow the instruction on the [Compiling and programming page](Compiling.md)
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
|
||||||
#DIY MULTI-module by soldering components on a PCB
|
# DIY MULTI-module by soldering components on a PCB
|
||||||
Currently the form factor of this module is designed for the JR-style module bay. Many of the popular RC transmitters use the JR-style module bay: FrSky Taranis, FlySky Th9x, Turnigy 9X/R/Pro
|
Currently the form factor of this module is designed for the JR-style module bay. Many of the popular RC transmitters use the JR-style module bay: FrSky Taranis, FlySky Th9x, Turnigy 9X/R/Pro
|
||||||
##What you need
|
|
||||||
|
## What you need
|
||||||
First you must choose the PCB onto which to solder all the components. There are two PCB options:
|
First you must choose the PCB onto which to solder all the components. There are two PCB options:
|
||||||
- ATmega (8-bit) powered PCB V2.3d supporting individual RF modules
|
- ATmega (8-bit) powered PCB V2.3d supporting individual RF modules
|
||||||
- STM32 (32-bit) powered PCB V1.0t supporting the 4-in-1 RF module
|
- STM32 (32-bit) powered PCB V1.0t supporting the 4-in-1 RF module
|
||||||
|
|
||||||
The **ATmega-based board** has been designed to accept individual RF modules. This way you can select just the module or modules you want. The downside is that each module requires its own antenna. It can become cumbersome with 4 antennas protruding from the module. It is possible to soder the 4-in-1 module to the PCB using thin insulated wire. This 4-in-1 module requires only one antenna. Finally, the Atmega board has a 32KB flash memory. This is big enough to accommodate more than 15 protocols, but it cannot accommodate all the available protocols.
|
The **ATmega-based board** has been designed to accept individual RF modules. This way you can select just the module or modules you want. The downside is that each module requires its own antenna. It can become cumbersome with 4 antennas protruding from the module. It is possible to soder the 4-in-1 module to the PCB using thin insulated wire. This 4-in-1 module requires only one antenna. Finally, the Atmega board has a 32KB flash memory. This is big enough to accommodate more than 15 protocols, but it cannot accommodate all the available protocols.
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ The **STM32-based** board has been designed to accept the 4-in-1 RF module with
|
|||||||
|
|
||||||
<img src="images/Board_PCB_STM32.jpeg" width="100" height="125" /> <img src="images/Multi_4-in-1_RF_module.jpg" width="65" height="82" />
|
<img src="images/Board_PCB_STM32.jpeg" width="100" height="125" /> <img src="images/Multi_4-in-1_RF_module.jpg" width="65" height="82" />
|
||||||
|
|
||||||
###ATmega board V2.3d
|
### ATmega board V2.3d
|
||||||
1. ATmega (8-bit) powered PCB V2.3d available from OSHPark [here](https://oshpark.com/shared_projects/Ztus1ah8).
|
1. ATmega (8-bit) powered PCB V2.3d available from OSHPark [here](https://oshpark.com/shared_projects/Ztus1ah8).
|
||||||
2. Individual RF modules The modules are available here:
|
2. Individual RF modules The modules are available here:
|
||||||
- [CC2500](http://www.banggood.com/2_4G-500K-CC2500-Long-Range-Wireless-Transceiver-Module-p-1075492.html) for FrSkyV, FrSkyD, FrSkyX and SFHSS
|
- [CC2500](http://www.banggood.com/2_4G-500K-CC2500-Long-Range-Wireless-Transceiver-Module-p-1075492.html) for FrSkyV, FrSkyD, FrSkyX and SFHSS
|
||||||
@ -26,48 +27,39 @@ The **STM32-based** board has been designed to accept the 4-in-1 RF module with
|
|||||||
|
|
||||||
The schematic for the board is [here](#V23D_Schematic). Please note that is is the general schematic - there will be some minor differences (like solder jumpers) between this and the board.
|
The schematic for the board is [here](#V23D_Schematic). Please note that is is the general schematic - there will be some minor differences (like solder jumpers) between this and the board.
|
||||||
|
|
||||||
###STM32 powered PCB
|
### STM32 powered PCB
|
||||||
1. The latest STM32 (32-bit) powered PCB V1.0t supporting the 4-in-1 RF module available from OSHPark [here](https://oshpark.com/shared_projects/GX51nEoH).
|
1. The latest STM32 (32-bit) powered PCB V1.0t supporting the 4-in-1 RF module available from OSHPark [here](https://oshpark.com/shared_projects/GX51nEoH).
|
||||||
2. The 4-in-1 RF module is available [here](http://www.banggood.com/DIY-2_4G-CC2500-NRF24L01-A7105-CYRF6936-Multi-RF-4-IN-1-Wireless-Module-p-1046308.html)
|
2. The 4-in-1 RF module is available [here](http://www.banggood.com/DIY-2_4G-CC2500-NRF24L01-A7105-CYRF6936-Multi-RF-4-IN-1-Wireless-Module-p-1046308.html)
|
||||||
1. The schematic and BOM for this board V1.0t and older boards are available [here](BOM_DIY_STM32 & Schematic.md).
|
1. The schematic and BOM for this board V1.0t and older boards are available [here](BOM_DIY_STM32%20\&%20Schematic.md).
|
||||||
|
|
||||||
###Common parts
|
|
||||||
1. A module case that fits your module like the one [here](https://www.xtremepowersystems.net/proddetail.php?prod=XPS-J1CASE)
|
|
||||||
<img src="https://www.xtremepowersystems.net/prodimages/j1case.jpg" width="200" height="180" />
|
|
||||||
or you can 3D print your own from a selection on Thingiverse ([Example 1](http://www.thingiverse.com/thing:1852868) [Example 2](http://www.thingiverse.com/thing:1661833)).
|
|
||||||
[<img src="http://thingiverse-production-new.s3.amazonaws.com/renders/55/1c/cb/0a/e4/5d2c2b06be7f3f6f8f0ab4638dd7c6fc_preview_featured.jpg" width="250" height="200" /> ](http://www.thingiverse.com/thing:1852868)
|
|
||||||
For 9XR/9XR Pro, a new 3D printed module is available which makes use of the built in antenna in the handle. This means nothing is getting out of the radio back! You can find all details of this module case on [Thingiverse](http://www.thingiverse.com/thing:2050717).
|
|
||||||
<img src="images/9XR_module.jpg" width="113" height="200" /> <img src="images/9XR_module_connector.jpg" width="274" height="200" />
|
|
||||||
|
|
||||||
|
|
||||||
|
### Common parts
|
||||||
|
1. A module case that fits your module like the one [here](https://www.xtremepowersystems.net/proddetail.php?prod=XPS-J1CASE) <br> <img src="https://www.xtremepowersystems.net/prodimages/j1case.jpg" width="200" height="180" /> <br> or you can 3D print your own from a selection on Thingiverse ([Example 1](http://www.thingiverse.com/thing:1852868) [Example 2](http://www.thingiverse.com/thing:1661833)). <br> [<img src="http://thingiverse-production-new.s3.amazonaws.com/renders/55/1c/cb/0a/e4/5d2c2b06be7f3f6f8f0ab4638dd7c6fc_preview_featured.jpg" width="250" height="200" /> ](http://www.thingiverse.com/thing:1852868) <br> For 9XR/9XR Pro, a new 3D printed module is available which makes use of the built in antenna in the handle. This means nothing is getting out of the radio back! You can find all details of this module case on [Thingiverse](http://www.thingiverse.com/thing:2050717). <br> <img src="images/9XR_module.jpg" width="113" height="200" /> <img src="images/9XR_module_connector.jpg" width="274" height="200" />
|
||||||
1. A 2.4GHz antenna and pigtail
|
1. A 2.4GHz antenna and pigtail
|
||||||
|
|
||||||
##Build instructions
|
## Build instructions
|
||||||
If you got this far you already know what you are doing!!
|
If you got this far you already know what you are doing!!
|
||||||
|
|
||||||
###Common steps
|
### Common steps
|
||||||
|
|
||||||
1. Solder all the parts according to the BOM part numbering and the images for your board (see OSHPARK for the images)
|
1. Solder all the parts according to the BOM part numbering and the images for your board (see OSHPARK for the images)
|
||||||
1. Fit the module into the module case. This may require some careful filing or sanding of the module to ensure a nice fit.
|
1. Fit the module into the module case. This may require some careful filing or sanding of the module to ensure a nice fit.
|
||||||
|
|
||||||
###PPM interface
|
### PPM interface
|
||||||
If you are only planning on using the PPM interface with transmitter you are ready to program the module as described in [Compiling and Programming](Compiling.md) the module.
|
If you are only planning on using the PPM interface with transmitter you are ready to program the module as described in [Compiling and Programming](Compiling.md) the module.
|
||||||
|
|
||||||
###Enabling Serial and Telemetry interface
|
### Enabling Serial and Telemetry interface
|
||||||
If you have a transmitter that can support serial communication with the board then you need to solder some jumpers.
|
If you have a transmitter that can support serial communication with the board then you need to solder some jumpers.
|
||||||
|
|
||||||
|
|
||||||
#### **ATmega V2.3d board**
|
#### **ATmega V2.3d board**
|
||||||
|
|
||||||
There are four solder type jumpers on the bottom side of the board near the lower left corner when the bottom of the board is facing towards you. The silkscreen shows which jumper is which. These four jumpers enable the board to be configured in several ways as explaned below.
|
There are four solder type jumpers on the bottom side of the board near the lower left corner when the bottom of the board is facing towards you. The silkscreen shows which jumper is which. These four jumpers enable the board to be configured in several ways as explaned below.
|
||||||
|
```
|
||||||
(J-1) Use (PPM V/V) if the incoming PPM signal is at a higher voltage level, leave open if ~~5V.
|
(J-1) Use (PPM V/V) if the incoming PPM signal is at a higher voltage level, leave open if ~~5V.
|
||||||
|
|
||||||
(J-2) Use (Jumper 2) to connect the incomming PPM signal to the RX pin on the processor
|
(J-2) Use (Jumper 2) to connect the incomming PPM signal to the RX pin on the processor
|
||||||
|
|
||||||
(J-3) Short (TELEM) only if you have done a telemetry mod to your radio, leave open if not needed. When connected, pin 2 of the two pin header (P3) is also connected.
|
(J-3) Short (TELEM) only if you have done a telemetry mod to your radio, leave open if not needed. When connected, pin 2 of the two pin header (P3) is also connected.
|
||||||
|
(J-4) Use (MOD) only to connect the transmitter pin 2 to pin 1 of the two pin header (P3).
|
||||||
(J-4) Use (MOD) only to connect the transmitter pin 2 to pin 1 of the two pin header (P3).
|
```
|
||||||
|
|
||||||
**It is most likely J-2 will be the only one needing to be shorted for the serial method of sending model protocols. If you plan to use telemetry you will also need to solder J-3**
|
**It is most likely J-2 will be the only one needing to be shorted for the serial method of sending model protocols. If you plan to use telemetry you will also need to solder J-3**
|
||||||
|
|
||||||
@ -77,13 +69,13 @@ You are now ready to go over to [Compiling and Programming](Compiling.md).
|
|||||||
|
|
||||||
You are now ready to go over to [Compiling and Programming STM32](Compiling_STM32.md).
|
You are now ready to go over to [Compiling and Programming STM32](Compiling_STM32.md).
|
||||||
|
|
||||||
#Reference Schematic <a name="Schematic"></a>
|
# Reference Schematic <a name="Schematic"></a>
|
||||||
Here is the schematic you can use to troubleshoot the module
|
Here is the schematic you can use to troubleshoot the module
|
||||||
## <a name="V23D_Schematic"></a> PCB 2.3d Schematic
|
## <a name="V23D_Schematic"></a> PCB 2.3d Schematic
|
||||||
General module schematic (reference)
|
General module schematic (reference)
|
||||||
<img src="images/DIY_Mulitprotocol_Module_Schematic.jpeg" width="1000" height="500" />
|
<img src="images/DIY_Mulitprotocol_Module_Schematic.jpeg" width="1000" height="500" />
|
||||||
V2.3d Board Schematic
|
V2.3d Board Schematic
|
||||||
<img src="https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/PCB%20v2.3d/Schematic_v2.3d.jpg" width="1000" height="500" />
|
<img src="../PCB%20v2.3d/Schematic_v2.3d.jpg" width="1000" height="500" />
|
||||||
|
|
||||||
## <a name="STM32_Schematic"></a> PCB STM32 V1.0t Schematic
|
## <a name="STM32_Schematic"></a> PCB STM32 V1.0t Schematic
|
||||||
<img src="https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/STM32%20PCB/Schematic_Multiprotocol_STM32_MB_v1.0_t.jpg" width="1000" height="500" />
|
<img src="../STM32%20PCB/Schematic_Multiprotocol_STM32_MB_v1.0_t.jpg" width="1000" height="500" />
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#OrangeRx Transmitter module
|
# OrangeRx Transmitter module
|
||||||
|
|
||||||
The OrangeRx transmitter module uses an Atmel XMega MCU. This requires a PDI programmer to flash firmware, the USBASP programmers do not work.
|
The OrangeRx transmitter module uses an Atmel XMega MCU. This requires a PDI programmer to flash firmware, the USBASP programmers do not work.
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#PPM Setup
|
# PPM Setup
|
||||||
|
|
||||||
The Multiprotocol Module is compatible with any transmitter that is able to generate a PPM (Pulse Postion Modulation) output. This includes all transmitters with a module bay or a trainer port. It supports up to 16 channels from a PPM frame in the normal or inverted format (sometimes called positive or negative format in some transmitters).
|
The Multiprotocol Module is compatible with any transmitter that is able to generate a PPM (Pulse Postion Modulation) output. This includes all transmitters with a module bay or a trainer port. It supports up to 16 channels from a PPM frame in the normal or inverted format (sometimes called positive or negative format in some transmitters).
|
||||||
If you want the best performance you can set the number of channels and framerate corresponding to the number of channels of the specific receiver/model.
|
If you want the best performance you can set the number of channels and framerate corresponding to the number of channels of the specific receiver/model.
|
||||||
|
|
||||||
##PPM Connections
|
## PPM Connections
|
||||||
If you do not have a module bay, there are only three wires you need to connect to get PPM to work. (The pins are numbered from top to bottom)
|
If you do not have a module bay, there are only three wires you need to connect to get PPM to work. (The pins are numbered from top to bottom)
|
||||||
- PPM on pin 1
|
- PPM on pin 1
|
||||||
- vbat on pin 3
|
- vbat on pin 3
|
||||||
@ -12,7 +12,7 @@ If you do not have a module bay, there are only three wires you need to connect
|
|||||||
Note: vbat should be between 6V and 13V when using the 4-in-1 and 2.3 PCB boards. If you built a module from scratch it depends on the voltage regulator you chose.
|
Note: vbat should be between 6V and 13V when using the 4-in-1 and 2.3 PCB boards. If you built a module from scratch it depends on the voltage regulator you chose.
|
||||||
|
|
||||||
|
|
||||||
##Enabling PPM mode in your transmitter
|
## Enabling PPM mode in your transmitter
|
||||||
|
|
||||||
1. Enable the default Tx mode to be AETR. If you do not want to change the default channel order on your Tx you must remember to change the channel order for each new model using the module to AETR under the Model Mixer menu. (**This is really important - this is for all protocols - even for DSM as the MULTI-module firware will change the transmitted channel order according to the protocol.**)
|
1. Enable the default Tx mode to be AETR. If you do not want to change the default channel order on your Tx you must remember to change the channel order for each new model using the module to AETR under the Model Mixer menu. (**This is really important - this is for all protocols - even for DSM as the MULTI-module firware will change the transmitted channel order according to the protocol.**)
|
||||||
1. The default PPM settings is 8 channels with a frame period of 22.5 ms (sometimes called the frame rate). If you want to optimize performance you should change the channels to the actual number of channels required by your model. The corresponding frame period should be set to (number of channels + 1) * 2.5 ms. For example:
|
1. The default PPM settings is 8 channels with a frame period of 22.5 ms (sometimes called the frame rate). If you want to optimize performance you should change the channels to the actual number of channels required by your model. The corresponding frame period should be set to (number of channels + 1) * 2.5 ms. For example:
|
||||||
@ -29,7 +29,7 @@ The default mapping of protocols to switch positions can be viewed on the Protoc
|
|||||||
|
|
||||||
The mapping of protocols to protocol selection switch positions can be changed in configuration settings as described on the [Compiling and Programming page](Compiling.md).
|
The mapping of protocols to protocol selection switch positions can be changed in configuration settings as described on the [Compiling and Programming page](Compiling.md).
|
||||||
|
|
||||||
##Binding in PPM mode
|
## Binding in PPM mode
|
||||||
|
|
||||||
In PPM mode follow the standard transmitter - receiver binding process:
|
In PPM mode follow the standard transmitter - receiver binding process:
|
||||||
1. Switch off the transmitter
|
1. Switch off the transmitter
|
||||||
@ -41,17 +41,17 @@ In PPM mode follow the standard transmitter - receiver binding process:
|
|||||||
|
|
||||||
If you are having trouble binding to a consumer quad check the section below on [Getting your Bind Timing right](Bind_Timing.md). For more details on setting up specific receivers or models, check out the [Protocol Details page](Protocol_Details.md).
|
If you are having trouble binding to a consumer quad check the section below on [Getting your Bind Timing right](Bind_Timing.md). For more details on setting up specific receivers or models, check out the [Protocol Details page](Protocol_Details.md).
|
||||||
|
|
||||||
##Telemetry in PPM mode
|
## Telemetry in PPM mode
|
||||||
|
|
||||||
Telemetry is available as a serial stream on the TX pin of the Atmega328p in the FrSky HUB format. The serial parameters are based on the protocol selected by the protocol selection dial.
|
Telemetry is available as a serial stream on the TX pin of the Atmega328p in the FrSky HUB format. The serial parameters are based on the protocol selected by the protocol selection dial.
|
||||||
|
|
||||||
Protocol|Serial Parameters
|
Protocol|Serial Parameters
|
||||||
--------|-----------------
|
---|---
|
||||||
Hubsan|9600bps 8n1
|
Hubsan|9600bps 8n1
|
||||||
FrSkyD|9600bps 8n1
|
FrSkyD|9600bps 8n1
|
||||||
FrSkyX|57,600bps 8n1
|
FrSkyX|57,600bps 8n1
|
||||||
DSM2/X|125,000bps 8n1
|
DSM2/X|125,000bps 8n1
|
||||||
|
|
||||||
The serial stream is also available on pin 5 of the Module connector (pins numbered from top to bottom) on the [4-in-1 module]() and the [V2.3d modules]() provided the Tx jumper has been soldered. See the linked module documentation for what this means.
|
The serial stream is also available on pin 5 of the Module connector (pins numbered from top to bottom) on the [4-in-1 module](Module_BG_4-in-1.md) and the [V2.3d modules](Module_Build_yourself_PCB.md#atmega-board-v23d) provided the Tx jumper has been soldered. See the linked module documentation for what this means.
|
||||||
|
|
||||||
You can connect it to your TX if it is telemetry enabled or use a bluetooth adapter (HC05/HC06) along with an app on your phone/tablet [(app example)](https://play.google.com/store/apps/details?id=biz.onomato.frskydash&hl=fr) to display telemetry information and setup alerts.
|
You can connect it to your TX if it is telemetry enabled or use a bluetooth adapter (HC05/HC06) along with an app on your phone/tablet [(app example)](https://play.google.com/store/apps/details?id=biz.onomato.frskydash&hl=fr) to display telemetry information and setup alerts.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#MULTI-Module Protocol Details
|
# MULTI-Module Protocol Details
|
||||||
**You'll find below a detailed description of every supported protocols sorted by RF modules.**
|
**You'll find below a detailed description of every supported protocols sorted by RF modules.**
|
||||||
|
|
||||||
Legend:
|
Legend:
|
||||||
@ -8,9 +8,9 @@ Legend:
|
|||||||
The AETR mentionned here for all protocols depends on the TX settings compilation option set in _Config.h.
|
The AETR mentionned here for all protocols depends on the TX settings compilation option set in _Config.h.
|
||||||
|
|
||||||
***
|
***
|
||||||
#A7105 RF Module
|
# A7105 RF Module
|
||||||
|
|
||||||
##FLYSKY
|
## FLYSKY
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
@ -19,22 +19,22 @@ A|E|T|R|CH5|CH6|CH7|CH8
|
|||||||
|
|
||||||
Note that the RX ouput will be AETR.
|
Note that the RX ouput will be AETR.
|
||||||
|
|
||||||
###Sub_protocol V9X9
|
### Sub_protocol V9X9
|
||||||
CH5|CH6|CH7|CH8
|
CH5|CH6|CH7|CH8
|
||||||
---|---|---|---
|
---|---|---|---
|
||||||
FLIP|LIGHT|PICTURE|VIDEO
|
FLIP|LIGHT|PICTURE|VIDEO
|
||||||
|
|
||||||
###Sub_protocol V6X6
|
### Sub_protocol V6X6
|
||||||
CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
FLIP|LIGHT|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
|
FLIP|LIGHT|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
|
||||||
|
|
||||||
###Sub_protocol V912
|
### Sub_protocol V912
|
||||||
CH5|CH6
|
CH5|CH6
|
||||||
---|---
|
---|---
|
||||||
BTMBTN|TOPBTN
|
BTMBTN|TOPBTN
|
||||||
|
|
||||||
##HUBSAN
|
## HUBSAN
|
||||||
Models: Hubsan H102D, H107/L/C/D and Hubsan H107P/C+/D+
|
Models: Hubsan H102D, H107/L/C/D and Hubsan H107P/C+/D+
|
||||||
|
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
@ -47,10 +47,9 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
|||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
***
|
# CC2500 RF Module
|
||||||
#CC2500 RF Module
|
|
||||||
|
|
||||||
##FRSKYV = FrSky 1 way
|
## FRSKYV = FrSky 1 way
|
||||||
Models: FrSky receivers V8R4, V8R7 and V8FR.
|
Models: FrSky receivers V8R4, V8R7 and V8FR.
|
||||||
|
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
@ -61,7 +60,7 @@ CH1|CH2|CH3|CH4
|
|||||||
---|---|---|---
|
---|---|---|---
|
||||||
CH1|CH2|CH3|CH4
|
CH1|CH2|CH3|CH4
|
||||||
|
|
||||||
##FRSKYD
|
## FRSKYD
|
||||||
Models: FrSky receivers D4R and D8R. DIY RX-F801 and RX-F802 receivers.
|
Models: FrSky receivers D4R and D8R. DIY RX-F801 and RX-F802 receivers.
|
||||||
|
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
@ -74,7 +73,7 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
|||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
|
|
||||||
##FRSKYX
|
## FRSKYX
|
||||||
Models: FrSky receivers X4R, X6R and X8R.
|
Models: FrSky receivers X4R, X6R and X8R.
|
||||||
|
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
@ -83,17 +82,17 @@ Telemetry enabled for A1 (RxBatt), A2, RSSI, TSSI and Hub
|
|||||||
|
|
||||||
Option=fine frequency tuning. This value is different for each board. To determine the option value, find the two limits where the RX loses connection then set the option value to half way between them. If you have a 4in1 V2 board the value is around 40.
|
Option=fine frequency tuning. This value is different for each board. To determine the option value, find the two limits where the RX loses connection then set the option value to half way between them. If you have a 4in1 V2 board the value is around 40.
|
||||||
|
|
||||||
###Sub_protocol CH_16
|
### Sub_protocol CH_16
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
|
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
|
||||||
###Sub_protocol CH_8
|
### Sub_protocol CH_8
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
|
|
||||||
##SFHSS
|
## SFHSS
|
||||||
Models: Futaba RXs and XK models.
|
Models: Futaba RXs and XK models.
|
||||||
|
|
||||||
Option=fine frequency tuning. This value is different for each board. To determine the option value, find the two limits where the RX loses connection then set the option value to half way between them. If you have a 4in1 V2 board the value is around 40.
|
Option=fine frequency tuning. This value is different for each board. To determine the option value, find the two limits where the RX loses connection then set the option value to half way between them. If you have a 4in1 V2 board the value is around 40.
|
||||||
@ -102,10 +101,9 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
|||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|CH5|CH6|CH7|CH8
|
A|E|T|R|CH5|CH6|CH7|CH8
|
||||||
|
|
||||||
***
|
# CYRF6936 RF Module
|
||||||
#CYRF6936 RF Module
|
|
||||||
|
|
||||||
##DEVO
|
## DEVO
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
@ -135,7 +133,7 @@ Bind procedure using PPM:
|
|||||||
- To verify that the TX is in fixed mode: power cycle the TX, the module LED should be solid ON (no blink).
|
- To verify that the TX is in fixed mode: power cycle the TX, the module LED should be solid ON (no blink).
|
||||||
- Note: Autobind/fixed ID mode is linked to the dial number. Which means that you can have multiple dial numbers set to the same protocol DEVO with different RX_Num and have different bind modes at the same time. It enables PPM users to get model match under DEVO.
|
- Note: Autobind/fixed ID mode is linked to the dial number. Which means that you can have multiple dial numbers set to the same protocol DEVO with different RX_Num and have different bind modes at the same time. It enables PPM users to get model match under DEVO.
|
||||||
|
|
||||||
##DSM
|
## DSM
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
|
|
||||||
Telemetry enabled for TSSI and plugins
|
Telemetry enabled for TSSI and plugins
|
||||||
@ -150,31 +148,34 @@ Notes:
|
|||||||
- model/type/number of channels indicated on the RX can be different from what the RX is in fact wanting to see. So don't hesitate to test different combinations until you have something working. Using Auto is the best way to find these settings.
|
- model/type/number of channels indicated on the RX can be different from what the RX is in fact wanting to see. So don't hesitate to test different combinations until you have something working. Using Auto is the best way to find these settings.
|
||||||
- RX ouput will always be TAER independently of the input AETR, RETA...
|
- RX ouput will always be TAER independently of the input AETR, RETA...
|
||||||
|
|
||||||
###Sub_protocol DSM2_22
|
### Sub_protocol DSM2_22
|
||||||
DSM2, Resolution 1024, refresh rate 22ms
|
DSM2, Resolution 1024, refresh rate 22ms
|
||||||
###Sub_protocol DSM2_11
|
|
||||||
|
### Sub_protocol DSM2_11
|
||||||
DSM2, Resolution 2048, refresh rate 11ms
|
DSM2, Resolution 2048, refresh rate 11ms
|
||||||
###Sub_protocol DSMX_22
|
|
||||||
|
### Sub_protocol DSMX_22
|
||||||
DSMX, Resolution 2048, refresh rate 22ms
|
DSMX, Resolution 2048, refresh rate 22ms
|
||||||
###Sub_protocol DSMX_11
|
|
||||||
|
### Sub_protocol DSMX_11
|
||||||
DSMX, Resolution 2048, refresh rate 11ms
|
DSMX, Resolution 2048, refresh rate 11ms
|
||||||
###Sub_protocol AUTO
|
|
||||||
|
### Sub_protocol AUTO
|
||||||
The "AUTO" feature enables the TX to automatically choose what are the best settings for your DSM RX and update your model protocol settings accordingly.
|
The "AUTO" feature enables the TX to automatically choose what are the best settings for your DSM RX and update your model protocol settings accordingly.
|
||||||
|
|
||||||
The current radio firmware which are able to use the "AUTO" feature are ersky9x (9XR Pro, 9Xtreme, Taranis, ...) and er9x for M128 (9XR) and M2561.
|
The current radio firmware which are able to use the "AUTO" feature are ersky9x (9XR Pro, 9Xtreme, Taranis, ...) and er9x for M128 (9XR) and M2561.
|
||||||
For these firmwares, you must have a telemetry enabled TX and you have to make sure you set the Telemetry "Usr proto" to "DSMx".
|
For these firmwares, you must have a telemetry enabled TX and you have to make sure you set the Telemetry "Usr proto" to "DSMx".
|
||||||
Also on er9x you will need to be sure to match the polarity of the telemetry serial (normal or inverted by bitbashing), while on ersky9x you can set "Invert COM1" accordinlgy.
|
Also on er9x you will need to be sure to match the polarity of the telemetry serial (normal or inverted by bitbashing), while on ersky9x you can set "Invert COM1" accordinlgy.
|
||||||
|
|
||||||
##J6Pro
|
## J6Pro
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
---|---|---|---|---|---|---|---|---|----|----|----
|
---|---|---|---|---|---|---|---|---|----|----|----
|
||||||
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
|
|
||||||
***
|
# NRF24L01 RF Module
|
||||||
#NRF24L01 RF Module
|
|
||||||
|
|
||||||
##ASSAN
|
## ASSAN
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
||||||
@ -183,7 +184,7 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
|||||||
|
|
||||||
The transmitter must be close to the receiver while binding.
|
The transmitter must be close to the receiver while binding.
|
||||||
|
|
||||||
##BAYANG
|
## BAYANG
|
||||||
Models: EAchine H8(C) mini, BayangToys X6/X7/X9, JJRC JJ850, Floureon H101 ...
|
Models: EAchine H8(C) mini, BayangToys X6/X7/X9, JJRC JJ850, Floureon H101 ...
|
||||||
|
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
@ -192,7 +193,7 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
|||||||
---|---|---|---|---|---|---|---|---|----
|
---|---|---|---|---|---|---|---|---|----
|
||||||
A|E|T|R|FLIP|RTH|PICTURE|VIDEO|HEADLESS|INVERTED
|
A|E|T|R|FLIP|RTH|PICTURE|VIDEO|HEADLESS|INVERTED
|
||||||
|
|
||||||
##CG023
|
## CG023
|
||||||
Models: EAchine CG023/CG031/3D X4
|
Models: EAchine CG023/CG031/3D X4
|
||||||
|
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
@ -201,14 +202,14 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
|||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol YD829
|
### Sub_protocol YD829
|
||||||
Models: Attop YD-822/YD-829/YD-829C ...
|
Models: Attop YD-822/YD-829/YD-829C ...
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8|CH9
|
CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---
|
---|---|---|---|---
|
||||||
FLIP||PICTURE|VIDEO|HEADLESS
|
FLIP||PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol H8_3D
|
### Sub_protocol H8_3D
|
||||||
Models: EAchine H8 mini 3D, JJRC H20/H22
|
Models: EAchine H8 mini 3D, JJRC H20/H22
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8|CH9
|
CH5|CH6|CH7|CH8|CH9
|
||||||
@ -223,7 +224,7 @@ H8 3D: OPT1=RTH then press a direction to enter headless mode (like stock TX), O
|
|||||||
|
|
||||||
CAL: calibrate accelerometers
|
CAL: calibrate accelerometers
|
||||||
|
|
||||||
##CX10
|
## CX10
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
|
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
@ -234,12 +235,12 @@ A|E|T|R|FLIP|RATE
|
|||||||
|
|
||||||
Rate: -100%=rate 1, 0%=rate 2, +100%=rate 3
|
Rate: -100%=rate 1, 0%=rate 2, +100%=rate 3
|
||||||
|
|
||||||
###Sub_protocol GREEN
|
### Sub_protocol GREEN
|
||||||
Models: Cheerson CX-10 green pcb
|
Models: Cheerson CX-10 green pcb
|
||||||
|
|
||||||
Same channels assignement as above.
|
Same channels assignement as above.
|
||||||
|
|
||||||
###Sub_protocol BLUE
|
### Sub_protocol BLUE
|
||||||
Models: Cheerson CX-10 blue pcb & some newer red pcb, CX-10A, CX-10C, CX11, CX12, Floureon FX10, JJRC DHD D1
|
Models: Cheerson CX-10 blue pcb & some newer red pcb, CX-10A, CX-10C, CX11, CX12, Floureon FX10, JJRC DHD D1
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8
|
CH5|CH6|CH7|CH8
|
||||||
@ -248,13 +249,13 @@ FLIP|RATE|PICTURE|VIDEO
|
|||||||
|
|
||||||
Rate: -100%=rate 1, 0%=rate 2, +100%=rate 3 or headless for CX-10A
|
Rate: -100%=rate 1, 0%=rate 2, +100%=rate 3 or headless for CX-10A
|
||||||
|
|
||||||
###Sub_protocol DM007
|
### Sub_protocol DM007
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8|CH9
|
CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---
|
---|---|---|---|---
|
||||||
FLIP|MODE|PICTURE|VIDEO|HEADLESS
|
FLIP|MODE|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol Q282 and Q242
|
### Sub_protocol Q282 and Q242
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
@ -262,120 +263,129 @@ FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
|
|||||||
|
|
||||||
Model: JXD 509 is using Q282 with CH12=Start/Stop motors
|
Model: JXD 509 is using Q282 with CH12=Start/Stop motors
|
||||||
|
|
||||||
###Sub_protocol JC3015_1
|
### Sub_protocol JC3015_1
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8
|
CH5|CH6|CH7|CH8
|
||||||
---|---|---|---
|
---|---|---|---
|
||||||
FLIP|MODE|PICTURE|VIDEO
|
FLIP|MODE|PICTURE|VIDEO
|
||||||
|
|
||||||
###Sub_protocol JC3015_2
|
### Sub_protocol JC3015_2
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8
|
CH5|CH6|CH7|CH8
|
||||||
---|---|---|---
|
---|---|---|---
|
||||||
FLIP|MODE|LED|DFLIP
|
FLIP|MODE|LED|DFLIP
|
||||||
|
|
||||||
###Sub_protocol MK33041
|
### Sub_protocol MK33041
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8|CH9|CH10
|
CH5|CH6|CH7|CH8|CH9|CH10
|
||||||
---|---|---|---|---|---
|
---|---|---|---|---|---
|
||||||
FLIP|MODE|PICTURE|VIDEO|HEADLESS|RTH
|
FLIP|MODE|PICTURE|VIDEO|HEADLESS|RTH
|
||||||
|
|
||||||
##ESKY
|
## ESKY
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6
|
CH1|CH2|CH3|CH4|CH5|CH6
|
||||||
---|---|---|---|---|---
|
---|---|---|---|---|---
|
||||||
A|E|T|R|GYRO|PITCH
|
A|E|T|R|GYRO|PITCH
|
||||||
|
|
||||||
##FY326
|
## FY326
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|RTH|HEADLESS|EXPERT|CALIBRATE
|
A|E|T|R|FLIP|RTH|HEADLESS|EXPERT|CALIBRATE
|
||||||
|
|
||||||
##FQ777
|
## FQ777
|
||||||
Model: FQ777-124
|
Model: FQ777-124
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|RTH|HEADLESS|EXPERT
|
A|E|T|R|FLIP|RTH|HEADLESS|EXPERT
|
||||||
|
|
||||||
##HISKY
|
## HISKY
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|GEAR|PITCH|GYRO|CH8
|
A|E|T|R|GEAR|PITCH|GYRO|CH8
|
||||||
|
|
||||||
GYRO: -100%=6G, +100%=3G
|
GYRO: -100%=6G, +100%=3G
|
||||||
|
|
||||||
###HK310
|
### HK310
|
||||||
Models: RX HK-3000, HK3100 and XY3000 (TX are HK-300, HK-310 and TL-3C)
|
Models: RX HK-3000, HK3100 and XY3000 (TX are HK-300, HK-310 and TL-3C)
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
|||T|R|AUX|T_FSAFE|R_FSAFE|AUX_FSAFE
|
|||T|R|AUX|T_FSAFE|R_FSAFE|AUX_FSAFE
|
||||||
|
|
||||||
##KN
|
## KN
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||||
---|---|---|---|---|---|---|---|---|----|----
|
---|---|---|---|---|---|---|---|---|----|----
|
||||||
A|E|T|R|DR|THOLD|IDLEUP|GYRO|Ttrim|Atrim|Etrim
|
A|E|T|R|DR|THOLD|IDLEUP|GYRO|Ttrim|Atrim|Etrim
|
||||||
|
|
||||||
Dual Rate: +100%=full range, Throttle Hold: +100%=hold, Idle Up: +100%=3D, GYRO: -100%=6G, +100%=3G
|
Dual Rate: +100%=full range, Throttle Hold: +100%=hold, Idle Up: +100%=3D, GYRO: -100%=6G, +100%=3G
|
||||||
|
|
||||||
###Sub_protocol WLTOYS
|
### Sub_protocol WLTOYS
|
||||||
###Sub_protocol FEILUN
|
|
||||||
|
### Sub_protocol FEILUN
|
||||||
Same channels assignement as above.
|
Same channels assignement as above.
|
||||||
|
|
||||||
##HONTAI
|
## HONTAI
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||||
---|---|---|---|---|---|---|---|---|----|----
|
---|---|---|---|---|---|---|---|---|----|----
|
||||||
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|CAL
|
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|CAL
|
||||||
|
|
||||||
###Sub_protocol HONTAI
|
### Sub_protocol HONTAI
|
||||||
###Sub_protocol JJRCX1
|
|
||||||
|
### Sub_protocol JJRCX1
|
||||||
CH6|
|
CH6|
|
||||||
---|
|
---|
|
||||||
ARM|
|
ARM|
|
||||||
|
|
||||||
###Sub_protocol X5C1 clone
|
### Sub_protocol X5C1 clone
|
||||||
|
|
||||||
##MJXQ
|
## MJXQ
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13
|
||||||
---|---|---|---|---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|AUTOFLIP|PAN|TILT
|
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|AUTOFLIP|PAN|TILT
|
||||||
|
|
||||||
###Sub_protocol WLH08
|
### Sub_protocol WLH08
|
||||||
###Sub_protocol X600
|
|
||||||
Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
|
||||||
###Sub_protocol X800
|
|
||||||
Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
|
||||||
###Sub_protocol H26D
|
|
||||||
###Sub_protocol E010
|
|
||||||
|
|
||||||
##MT99XX
|
### Sub_protocol X600
|
||||||
|
Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
||||||
|
|
||||||
|
### Sub_protocol X800
|
||||||
|
Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
||||||
|
|
||||||
|
### Sub_protocol H26D
|
||||||
|
|
||||||
|
### Sub_protocol E010
|
||||||
|
|
||||||
|
## MT99XX
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS
|
A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol MT
|
### Sub_protocol MT
|
||||||
Models: MT99xx
|
Models: MT99xx
|
||||||
###Sub_protocol H7
|
|
||||||
|
### Sub_protocol H7
|
||||||
Models: Eachine H7, Cheerson CX023
|
Models: Eachine H7, Cheerson CX023
|
||||||
###Sub_protocol YZ
|
|
||||||
|
### Sub_protocol YZ
|
||||||
Model: Yi Zhan i6S
|
Model: Yi Zhan i6S
|
||||||
Only one model can be flown at the same time since the ID is hardcoded.
|
Only one model can be flown at the same time since the ID is hardcoded.
|
||||||
###Sub_protocol LS
|
|
||||||
|
### Sub_protocol LS
|
||||||
Models: LS114, 124, 215
|
Models: LS114, 124, 215
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|INVERT|PICTURE|VIDEO|HEADLESS
|
A|E|T|R|FLIP|INVERT|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
##Shenqi
|
## Shenqi
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
Model: Shenqiwei 1/20 Mini Motorcycle
|
Model: Shenqiwei 1/20 Mini Motorcycle
|
||||||
@ -386,27 +396,27 @@ CH1|CH2|CH3|CH4
|
|||||||
|
|
||||||
Throttle +100%=full forward,0%=stop,-100%=full backward.
|
Throttle +100%=full forward,0%=stop,-100%=full backward.
|
||||||
|
|
||||||
##SLT
|
## SLT
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6
|
CH1|CH2|CH3|CH4|CH5|CH6
|
||||||
---|---|---|---|---|---
|
---|---|---|---|---|---
|
||||||
A|E|T|R|GEAR|PITCH
|
A|E|T|R|GEAR|PITCH
|
||||||
|
|
||||||
##Symax
|
## Symax
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP||PICTURE|VIDEO|HEADLESS
|
A|E|T|R|FLIP||PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol SYMAX
|
### Sub_protocol SYMAX
|
||||||
Models: Syma X5C-1/X11/X11C/X12
|
Models: Syma X5C-1/X11/X11C/X12
|
||||||
|
|
||||||
###Sub_protocol SYMAX5C
|
### Sub_protocol SYMAX5C
|
||||||
Model: Syma X5C (original) and X2
|
Model: Syma X5C (original) and X2
|
||||||
|
|
||||||
##V2X2
|
## V2X2
|
||||||
Models: WLToys V202/252/272, JXD 385/388, JJRC H6C, Yizhan Tarantula X6 ...
|
Models: WLToys V202/252/272, JXD 385/388, JJRC H6C, Yizhan Tarantula X6 ...
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||||
@ -417,17 +427,21 @@ PICTURE: also automatic Missile Launcher and Hoist in one direction
|
|||||||
|
|
||||||
VIDEO: also Sprayer, Bubbler, Missile Launcher(1), and Hoist in the other dir
|
VIDEO: also Sprayer, Bubbler, Missile Launcher(1), and Hoist in the other dir
|
||||||
|
|
||||||
##YD717
|
## YD717
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS
|
||||||
|
|
||||||
###Sub_protocol YD717
|
### Sub_protocol YD717
|
||||||
###Sub_protocol SKYWLKR
|
|
||||||
###Sub_protocol SYMAX4
|
### Sub_protocol SKYWLKR
|
||||||
###Sub_protocol XINXUN
|
|
||||||
###Sub_protocol NIHUI
|
### Sub_protocol SYMAX4
|
||||||
|
|
||||||
|
### Sub_protocol XINXUN
|
||||||
|
|
||||||
|
### Sub_protocol NIHUI
|
||||||
Same channels assignement as above.
|
Same channels assignement as above.
|
||||||
|
|
||||||
|
@ -10,21 +10,21 @@ The source code is partly based on the Deviation TX project, thanks to all the d
|
|||||||
|
|
||||||
**To download the latest compiled version (hex file), click on [Release](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases) on the top menu.**
|
**To download the latest compiled version (hex file), click on [Release](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases) on the top menu.**
|
||||||
|
|
||||||
##Contents
|
## Contents
|
||||||
|
|
||||||
[Compatible TX](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module#compatible-tx)
|
[Compatible TX](README-old.md#compatible-tx)
|
||||||
|
|
||||||
[Protocols](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module#protocols)
|
[Protocols](README-old.md#protocols)
|
||||||
|
|
||||||
[Hardware](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module#hardware)
|
[Hardware](README-old.md#hardware)
|
||||||
|
|
||||||
[Compilation and programmation](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module#compilation-and-programmation)
|
[Compilation and programmation](README-old.md#compilation-and-programmation)
|
||||||
|
|
||||||
[Troubleshooting](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module#troubleshooting)
|
[Troubleshooting](README-old.md#troubleshooting)
|
||||||
|
|
||||||
##Compatible TX
|
## Compatible TX
|
||||||
|
|
||||||
###Using standard PPM output (trainer port)
|
### Using standard PPM output (trainer port)
|
||||||
The multiprotocol TX module can be used on any TX with a trainer port.
|
The multiprotocol TX module can be used on any TX with a trainer port.
|
||||||
|
|
||||||
Channels order is AETR by default but can be changed in the _Config.h.
|
Channels order is AETR by default but can be changed in the _Config.h.
|
||||||
@ -44,7 +44,7 @@ Settings per selection are located in _Config.h:
|
|||||||
- Option: -127..+127 allowing to set specific protocol options. Like for Hubsan to set the video frequency.
|
- Option: -127..+127 allowing to set specific protocol options. Like for Hubsan to set the video frequency.
|
||||||
- Autobind: Yes or No. At the model selection (or power applied to the TX) a bind sequence will be initiated
|
- Autobind: Yes or No. At the model selection (or power applied to the TX) a bind sequence will be initiated
|
||||||
|
|
||||||
###Using a serial output
|
### Using a serial output
|
||||||
The multiprotocol TX module takes full advantage of being used on a Turnigy 9X, 9XR, 9XR Pro, Taranis, 9Xtreme, AR9X, ... running [er9x](http://openrcforums.com/forum/viewtopic.php?f=5&t=4598) or [ersky9X](http://openrcforums.com/forum/viewtopic.php?f=7&t=4676). An OpenTX version for Taranis is available [here](http://plaisthos.de/opentx/).
|
The multiprotocol TX module takes full advantage of being used on a Turnigy 9X, 9XR, 9XR Pro, Taranis, 9Xtreme, AR9X, ... running [er9x](http://openrcforums.com/forum/viewtopic.php?f=5&t=4598) or [ersky9X](http://openrcforums.com/forum/viewtopic.php?f=7&t=4676). An OpenTX version for Taranis is available [here](http://plaisthos.de/opentx/).
|
||||||
|
|
||||||
This enables full integration using the radio GUI to setup models with all the available protocols options.
|
This enables full integration using the radio GUI to setup models with all the available protocols options.
|
||||||
@ -65,7 +65,7 @@ Notes:
|
|||||||
- There are 2 versions of serial protocol either 8 or 16 channels. 16 channels is the latest and only available version going forward. Make sure to use the right version based on your version of er9x/ersky9x.
|
- There are 2 versions of serial protocol either 8 or 16 channels. 16 channels is the latest and only available version going forward. Make sure to use the right version based on your version of er9x/ersky9x.
|
||||||
- Channels order is AETR by default but can be changed in _Config.h.
|
- Channels order is AETR by default but can be changed in _Config.h.
|
||||||
|
|
||||||
###Telemetry
|
### Telemetry
|
||||||
|
|
||||||
There are 4 protocols supporting telemetry: Hubsan, DSM, FrSkyD and FrSkyX.
|
There are 4 protocols supporting telemetry: Hubsan, DSM, FrSkyD and FrSkyX.
|
||||||
|
|
||||||
@ -94,9 +94,9 @@ Enabling telemetry on a 9XR PRO and may be other TXs does not require any hardwa
|
|||||||
|
|
||||||
Once the TX is telemetry enabled, it just needs to be configured on the model (see er9x/ersky9x documentation).
|
Once the TX is telemetry enabled, it just needs to be configured on the model (see er9x/ersky9x documentation).
|
||||||
|
|
||||||
##Protocols
|
## Protocols
|
||||||
|
|
||||||
###TX ID
|
### TX ID
|
||||||
The multiprotocol TX module is using a 32bits ID generated randomly at first power up. This global ID is used by nearly all protocols.
|
The multiprotocol TX module is using a 32bits ID generated randomly at first power up. This global ID is used by nearly all protocols.
|
||||||
There are little chances to get a duplicated ID.
|
There are little chances to get a duplicated ID.
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ For DSM2/X and Devo the CYRF6936 unique manufacturer ID is used.
|
|||||||
|
|
||||||
It's possible to generate a new ID using bind button on the Hubsan protocol during power up.
|
It's possible to generate a new ID using bind button on the Hubsan protocol during power up.
|
||||||
|
|
||||||
###Bind
|
### Bind
|
||||||
To bind a model in PPM Mode press the physical bind button, apply power and then release.
|
To bind a model in PPM Mode press the physical bind button, apply power and then release.
|
||||||
|
|
||||||
In Serial Mode you have 2 options:
|
In Serial Mode you have 2 options:
|
||||||
@ -115,9 +115,9 @@ Notes:
|
|||||||
- the physical bind button is only effective at power up. Pressing the button later has no effects.
|
- the physical bind button is only effective at power up. Pressing the button later has no effects.
|
||||||
- a bind in progress is indicated by the LED fast blinking. Make sure to bind during this period.
|
- a bind in progress is indicated by the LED fast blinking. Make sure to bind during this period.
|
||||||
|
|
||||||
###Protocol selection
|
### Protocol selection
|
||||||
|
|
||||||
####Using the dial for PPM input
|
#### Using the dial for PPM input
|
||||||
PPM is only allowing access to a subset of existing protocols.
|
PPM is only allowing access to a subset of existing protocols.
|
||||||
The protocols, subprotocols and all other settings can be personalized by modifying the **_Config.h** file.
|
The protocols, subprotocols and all other settings can be personalized by modifying the **_Config.h** file.
|
||||||
|
|
||||||
@ -145,10 +145,10 @@ Dial|Protocol|Sub_protocol|RX Num|Power|Auto Bind|Option|RF Module
|
|||||||
Note:
|
Note:
|
||||||
- The dial selection must be done before the power is applied.
|
- The dial selection must be done before the power is applied.
|
||||||
|
|
||||||
####Using serial input with er9x/ersky9x
|
#### Using serial input with er9x/ersky9x
|
||||||
Serial is allowing access to all existing protocols & sub_protocols listed below.
|
Serial is allowing access to all existing protocols & sub_protocols listed below.
|
||||||
|
|
||||||
#####A7105 RF module
|
##### A7105 RF module
|
||||||
Protocol|Sub_protocol
|
Protocol|Sub_protocol
|
||||||
--------|------------
|
--------|------------
|
||||||
Flysky|
|
Flysky|
|
||||||
@ -158,7 +158,7 @@ Flysky|
|
|||||||
|V912
|
|V912
|
||||||
Hubsan|
|
Hubsan|
|
||||||
|
|
||||||
#####CC2500 RF module
|
##### CC2500 RF module
|
||||||
Protocol|Sub_protocol
|
Protocol|Sub_protocol
|
||||||
--------|------------
|
--------|------------
|
||||||
FrSkyV|
|
FrSkyV|
|
||||||
@ -168,7 +168,7 @@ FrSkyX|
|
|||||||
|CH_8
|
|CH_8
|
||||||
SFHSS|
|
SFHSS|
|
||||||
|
|
||||||
#####CYRF6936 RF module
|
##### CYRF6936 RF module
|
||||||
Protocol|Sub_protocol
|
Protocol|Sub_protocol
|
||||||
--------|------------
|
--------|------------
|
||||||
DSM|
|
DSM|
|
||||||
@ -177,7 +177,7 @@ DSM|
|
|||||||
Devo|
|
Devo|
|
||||||
J6Pro|
|
J6Pro|
|
||||||
|
|
||||||
#####NRF24L01 RF module
|
##### NRF24L01 RF module
|
||||||
Protocol|Sub_protocol
|
Protocol|Sub_protocol
|
||||||
--------|------------
|
--------|------------
|
||||||
Hisky|
|
Hisky|
|
||||||
@ -235,12 +235,12 @@ HONTAI|
|
|||||||
Note:
|
Note:
|
||||||
- The dial should be set to 0 for serial. Which means all protocol selection pins should be left unconnected.
|
- The dial should be set to 0 for serial. Which means all protocol selection pins should be left unconnected.
|
||||||
|
|
||||||
###Protocols details
|
### Protocols details
|
||||||
**Check the [Protocols_Details.md](./Protocols_Details.md) file for a detailed description of every protocols with channels assignements.**
|
**Check the [Protocols_Details.md](./Protocols_Details.md) file for a detailed description of every protocols with channels assignements.**
|
||||||
|
|
||||||
##Hardware
|
## Hardware
|
||||||
|
|
||||||
###RF modules
|
### RF modules
|
||||||
Up to 4 RF modules can be installed:
|
Up to 4 RF modules can be installed:
|
||||||
- [A7105](http://www.banggood.com/XL7105-D03-A7105-Modification-Module-Support-Deviation-Galee-Flysky-p-922603.html) for Flysky, Hubsan
|
- [A7105](http://www.banggood.com/XL7105-D03-A7105-Modification-Module-Support-Deviation-Galee-Flysky-p-922603.html) for Flysky, Hubsan
|
||||||
- [CC2500](http://www.banggood.com/CC2500-PA-LNA-Romote-Wireless-Module-CC2500-SI4432-NRF24L01-p-922595.html) for FrSkyV, FrSkyD, FrSkyX and SFHSS
|
- [CC2500](http://www.banggood.com/CC2500-PA-LNA-Romote-Wireless-Module-CC2500-SI4432-NRF24L01-p-922595.html) for FrSkyV, FrSkyD, FrSkyX and SFHSS
|
||||||
@ -251,21 +251,21 @@ RF modules can be installed for protocols need only. Example: if you only need t
|
|||||||
|
|
||||||
You also need some [antennas](http://www.banggood.com/2_4GHz-3dBi-RP-SMA-Connector-Booster-Wireless-Antenna-Modem-Router-p-979407.html) and [cables](http://www.banggood.com/10cm-PCI-UFL-IPX-to-RPSMA-Female-Jack-Pigtail-Cable-p-924933.html).
|
You also need some [antennas](http://www.banggood.com/2_4GHz-3dBi-RP-SMA-Connector-Booster-Wireless-Antenna-Modem-Router-p-979407.html) and [cables](http://www.banggood.com/10cm-PCI-UFL-IPX-to-RPSMA-Female-Jack-Pigtail-Cable-p-924933.html).
|
||||||
|
|
||||||
###Board
|
### Board
|
||||||
The main program is running on an ATMEGA328p running @16MHz and 3.3V.
|
The main program is running on an ATMEGA328p running @16MHz and 3.3V.
|
||||||
An [Arduino pro mini 16Mhz/5V](http://www.banggood.com/Wholesale-New-Ver-Pro-Mini-ATMEGA328-328p-5V-16MHz-Arduino-Compatible-Nano-Size-p-68534.html) powered at 3.3V (yes it works) can be used to build your own Multimodule. An Arduino Mini based on Atmega328p can also be used.
|
An [Arduino pro mini 16Mhz/5V](http://www.banggood.com/Wholesale-New-Ver-Pro-Mini-ATMEGA328-328p-5V-16MHz-Arduino-Compatible-Nano-Size-p-68534.html) powered at 3.3V (yes it works) can be used to build your own Multimodule. An Arduino Mini based on Atmega328p can also be used.
|
||||||
|
|
||||||
####Using stripboard:
|
#### Using stripboard:
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
####Using a [home made PCB](http://www.rcgroups.com/forums/showpost.php?p=32645328&postcount=1621):
|
#### Using a [home made PCB](http://www.rcgroups.com/forums/showpost.php?p=32645328&postcount=1621):
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
####Build your own board using [SMD components](http://www.rcgroups.com/forums/showpost.php?p=31064232&postcount=1020) and an [associated PCB v2.3c](https://oshpark.com/shared_projects/MaGYDg0y):
|
#### Build your own board using [SMD components](http://www.rcgroups.com/forums/showpost.php?p=31064232&postcount=1020) and an [associated PCB v2.3c](https://oshpark.com/shared_projects/MaGYDg0y):
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
@ -284,7 +284,7 @@ lines through them.
|
|||||||
|
|
||||||
[OSH Park link](https://oshpark.com/shared_projects/Ztus1ah8) if you want to order.
|
[OSH Park link](https://oshpark.com/shared_projects/Ztus1ah8) if you want to order.
|
||||||
|
|
||||||
####Buy a ready to use and complete Multi module
|
#### Buy a ready to use and complete Multi module
|
||||||

|

|
||||||
|
|
||||||
This module can be purchased [here](http://www.banggood.com/2_4G-CC2500-A7105-Flysky-Frsky-Devo-DSM2-Multiprotocol-TX-Module-With-Antenna-p-1048377.html). All the 4 RF modules are already implemented A7105, NRF24L01, CC2500 and CYRF6936. The board is also equiped with an antenna switcher which means only one antenna for all.
|
This module can be purchased [here](http://www.banggood.com/2_4G-CC2500-A7105-Flysky-Frsky-Devo-DSM2-Multiprotocol-TX-Module-With-Antenna-p-1048377.html). All the 4 RF modules are already implemented A7105, NRF24L01, CC2500 and CYRF6936. The board is also equiped with an antenna switcher which means only one antenna for all.
|
||||||
@ -293,20 +293,18 @@ This module can be purchased [here](http://www.banggood.com/2_4G-CC2500-A7105-Fl
|
|||||||
|
|
||||||
If you want to enable serial mode for er9x/ersky9x/Taranis/... and depending on your board revision, you have to do one of these modifications:
|
If you want to enable serial mode for er9x/ersky9x/Taranis/... and depending on your board revision, you have to do one of these modifications:
|
||||||
- 1st revision, add 2 resistors as shown here: 
|
- 1st revision, add 2 resistors as shown here: 
|
||||||
- 2nd revision, solder pads together as shown:
|
- 2nd revision, solder pads together as shown: <br> <img src="http://static.rcgroups.net/forums/attachments/4/8/3/5/8/4/a9206217-177-IMG_5790.jpg" width="350">
|
||||||
|
|
||||||
<img src="http://static.rcgroups.net/forums/attachments/4/8/3/5/8/4/a9206217-177-IMG_5790.jpg" width="350">
|
|
||||||
|
|
||||||
Note: if you have the 1st board revision (check pictures above), sometime bind occures at power up even without pressing the bind button or not having an autobind protocol. To solve this issue, replacing the BIND led resistor (on the board back) of 1.2K by a 4.7K.
|
Note: if you have the 1st board revision (check pictures above), sometime bind occures at power up even without pressing the bind button or not having an autobind protocol. To solve this issue, replacing the BIND led resistor (on the board back) of 1.2K by a 4.7K.
|
||||||
|
|
||||||
###Schematic
|
### Schematic
|
||||||

|

|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- Attention: All modules are 3.3V only, never power them with 5V.
|
- Attention: All modules are 3.3V only, never power them with 5V.
|
||||||
- For serial, the dial switch is not needed and the bind button optionnal
|
- For serial, the dial switch is not needed and the bind button optionnal
|
||||||
|
|
||||||
###Radio integration
|
### Radio integration
|
||||||
If you build your own version of the board you can 3D print this case (details [here](http://www.rcgroups.com/forums/showpost.php?p=33294140&postcount=2034)):
|
If you build your own version of the board you can 3D print this case (details [here](http://www.rcgroups.com/forums/showpost.php?p=33294140&postcount=2034)):
|
||||||
|
|
||||||

|

|
||||||
@ -318,9 +316,9 @@ If you have the Banggood ready to use board you can 3D print this case (details
|
|||||||
<img src="http://static.rcgroups.net/forums/attachments/4/8/3/5/8/4/a9206411-90-IMG_5793.jpeg" width="200">
|
<img src="http://static.rcgroups.net/forums/attachments/4/8/3/5/8/4/a9206411-90-IMG_5793.jpeg" width="200">
|
||||||
<img src="http://static.rcgroups.net/forums/attachments/4/8/3/5/8/4/a9206445-131-IMG_5796.jpeg" width="200">
|
<img src="http://static.rcgroups.net/forums/attachments/4/8/3/5/8/4/a9206445-131-IMG_5796.jpeg" width="200">
|
||||||
|
|
||||||
##Compilation and programmation
|
## Compilation and programmation
|
||||||
|
|
||||||
###Toolchain
|
### Toolchain
|
||||||
Multiprotocol source can be compiled using the Arduino IDE.
|
Multiprotocol source can be compiled using the Arduino IDE.
|
||||||
|
|
||||||
The currently supported Arduino version is [1.6.10](https://www.arduino.cc/download_handler.php?f=/arduino-1.6.10-windows.exe).
|
The currently supported Arduino version is [1.6.10](https://www.arduino.cc/download_handler.php?f=/arduino-1.6.10-windows.exe).
|
||||||
@ -335,7 +333,7 @@ Notes:
|
|||||||
- Compilation of the code posted here works. So if it doesn't for you this is a problem with your setup, please double check everything before asking.
|
- Compilation of the code posted here works. So if it doesn't for you this is a problem with your setup, please double check everything before asking.
|
||||||
- If you want to reduce the code size even further, you can modify the file platform.txt located in "C:\Program Files (x86)\Arduino\hardware\arduino\avr". Set the line "compiler.c.elf.extra_flags=" to "compiler.c.elf.extra_flags=-Wl,--relax".
|
- If you want to reduce the code size even further, you can modify the file platform.txt located in "C:\Program Files (x86)\Arduino\hardware\arduino\avr". Set the line "compiler.c.elf.extra_flags=" to "compiler.c.elf.extra_flags=-Wl,--relax".
|
||||||
|
|
||||||
###Upload the code using ISP (In System Programming)
|
### Upload the code using ISP (In System Programming)
|
||||||
It is recommended to use an external programmer like [USBASP](http://www.banggood.com/USBASP-USBISP-3_3-5V-AVR-Downloader-Programmer-With-ATMEGA8-ATMEGA128-p-934425.html) to upload the code in the Atmega328. The programmer should be set to 3.3V or nothing to not supply any over voltage to the multimodule and avoid any damages.
|
It is recommended to use an external programmer like [USBASP](http://www.banggood.com/USBASP-USBISP-3_3-5V-AVR-Downloader-Programmer-With-ATMEGA8-ATMEGA128-p-934425.html) to upload the code in the Atmega328. The programmer should be set to 3.3V or nothing to not supply any over voltage to the multimodule and avoid any damages.
|
||||||
|
|
||||||
The dial must be set to 0 before flashing!
|
The dial must be set to 0 before flashing!
|
||||||
@ -344,7 +342,7 @@ From the Arduino environment, you can use this shortcut to compile and upload to
|
|||||||
|
|
||||||
To flash the latest provided hex file under [Release](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases), you can use a tool like [AVR Burn-O-Mat](http://avr8-burn-o-mat.aaabbb.de/), set the microcontroller to m328p and flash it.
|
To flash the latest provided hex file under [Release](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases), you can use a tool like [AVR Burn-O-Mat](http://avr8-burn-o-mat.aaabbb.de/), set the microcontroller to m328p and flash it.
|
||||||
|
|
||||||
###Upload the code using FTDI (USB serial to TTL)
|
### Upload the code using FTDI (USB serial to TTL)
|
||||||
Use this method only for Arduino Pro Mini boards with bootloader.
|
Use this method only for Arduino Pro Mini boards with bootloader.
|
||||||
|
|
||||||
Use an external FTDI adapter like [this one](http://www.banggood.com/FT232RL-FTDI-USB-To-TTL-Serial-Converter-Adapter-Module-For-Arduino-p-917226.html).
|
Use an external FTDI adapter like [this one](http://www.banggood.com/FT232RL-FTDI-USB-To-TTL-Serial-Converter-Adapter-Module-For-Arduino-p-917226.html).
|
||||||
@ -355,7 +353,7 @@ From the Arduino environment, you can use Upload button which will compile and u
|
|||||||
|
|
||||||
To upload the latest provided hex file under [Release](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases), you can use a tool like [XLoader](http://russemotto.com/xloader/), set the microcontroller to Atmega328 and upload it.
|
To upload the latest provided hex file under [Release](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases), you can use a tool like [XLoader](http://russemotto.com/xloader/), set the microcontroller to Atmega328 and upload it.
|
||||||
|
|
||||||
###Set fuses
|
### Set fuses
|
||||||
Use a tool like [AVR Burn-O-Mat](http://avr8-burn-o-mat.aaabbb.de/) to set the fuses of the Atmega328 to:
|
Use a tool like [AVR Burn-O-Mat](http://avr8-burn-o-mat.aaabbb.de/) to set the fuses of the Atmega328 to:
|
||||||
- Extended Fuse 0x05 (or 0xFD which is the same)
|
- Extended Fuse 0x05 (or 0xFD which is the same)
|
||||||
- High Fuse 0xD2
|
- High Fuse 0xD2
|
||||||
@ -363,25 +361,25 @@ Use a tool like [AVR Burn-O-Mat](http://avr8-burn-o-mat.aaabbb.de/) to set the f
|
|||||||
|
|
||||||
This will make sure your ATMEGA328 is well configured and the global TX ID is not erased at each updates.
|
This will make sure your ATMEGA328 is well configured and the global TX ID is not erased at each updates.
|
||||||
|
|
||||||
##Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
###LED status
|
### LED status
|
||||||
- off: program not running or a protocol selected with the associated module not installed.
|
- off: program not running or a protocol selected with the associated module not installed.
|
||||||
- flash(on=0.1s,off=1s): invalid protocol selected (excluded from compilation or invalid protocol number)
|
- flash(on=0.1s,off=1s): invalid protocol selected (excluded from compilation or invalid protocol number)
|
||||||
- slow blink(on=0.5s,off=0.5s): serial has been selected but no valid signal has been seen on the RX pin.
|
- slow blink(on=0.5s,off=0.5s): serial has been selected but no valid signal has been seen on the RX pin.
|
||||||
- fast blink(on=0.1s,off=0.1s): bind in progress.
|
- fast blink(on=0.1s,off=0.1s): bind in progress.
|
||||||
- on: normal operation.
|
- on: normal operation.
|
||||||
|
|
||||||
###Protocol selection
|
### Protocol selection
|
||||||
####Input Mode - PPM
|
#### Input Mode - PPM
|
||||||
- The protocol/mode selection must be done before the power is applied.
|
- The protocol/mode selection must be done before the power is applied.
|
||||||
- Connect 1 to 4 of the selection protocol pins to GND.
|
- Connect 1 to 4 of the selection protocol pins to GND.
|
||||||
|
|
||||||
####Input Mode - Serial
|
#### Input Mode - Serial
|
||||||
- Make sure you have done the mods to the v2.3c PCB by adding the 2.2k and 470 ohm resistors as indicated in the [Board section] (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module#board).
|
- Make sure you have done the mods to the v2.3c PCB by adding the 2.2k and 470 ohm resistors as indicated in the [Board section] (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module#board).
|
||||||
- Leave all 4 selection pins unconnected.
|
- Leave all 4 selection pins unconnected.
|
||||||
|
|
||||||
###Bind
|
### Bind
|
||||||
Make sure to follow this procedure: press the bind button, apply power and then release it after 1sec. The LED should be blinking fast indicating a bind status and then fixed on when the bind period is over. It's normal that the LED turns off when you press the bind button, this behavior is not controlled by the Atmega328.
|
Make sure to follow this procedure: press the bind button, apply power and then release it after 1sec. The LED should be blinking fast indicating a bind status and then fixed on when the bind period is over. It's normal that the LED turns off when you press the bind button, this behavior is not controlled by the Atmega328.
|
||||||
For serial, the preffered method is to bind via the GUI protocol page.
|
For serial, the preffered method is to bind via the GUI protocol page.
|
||||||
|
|
||||||
@ -389,7 +387,7 @@ If your module is always/sometime binding at power up without pressing the butto
|
|||||||
- Arduino Pro Mini with an external status LED: to work around this issue connect a 10K resistor between D13 and 3.3V.
|
- Arduino Pro Mini with an external status LED: to work around this issue connect a 10K resistor between D13 and 3.3V.
|
||||||
- 4in1 module V1 (check 4in1 pictures): to solve this issue, replacing the BIND led resistor (on the board back) of 1.2K by a 4.7K.
|
- 4in1 module V1 (check 4in1 pictures): to solve this issue, replacing the BIND led resistor (on the board back) of 1.2K by a 4.7K.
|
||||||
|
|
||||||
###Report issues
|
### Report issues
|
||||||
You can report your problem using the [GitHub issue](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/issues) system or go to the [Main thread on RCGROUPS](http://www.rcgroups.com/forums/showthread.php?t=2165676) to ask your question.
|
You can report your problem using the [GitHub issue](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/issues) system or go to the [Main thread on RCGROUPS](http://www.rcgroups.com/forums/showthread.php?t=2165676) to ask your question.
|
||||||
Please provide the following information:
|
Please provide the following information:
|
||||||
- Multiprotocol code version
|
- Multiprotocol code version
|
||||||
|
@ -7,7 +7,7 @@ There are two different modes to interface the MULTI-Module and the transmitter:
|
|||||||
|
|
||||||
Any Tx providing a PPM output (like a trainer port, or a transmitter with a RF module bay) is compatible with the MULTI-module.
|
Any Tx providing a PPM output (like a trainer port, or a transmitter with a RF module bay) is compatible with the MULTI-module.
|
||||||
|
|
||||||
##PPM
|
## PPM
|
||||||
The DIY Mulitprotocol module supports industry standard PPM interface that works with all transmitters with either a module bay, and/or a trainer port. Even the older 72MHz FM radios support this standard.
|
The DIY Mulitprotocol module supports industry standard PPM interface that works with all transmitters with either a module bay, and/or a trainer port. Even the older 72MHz FM radios support this standard.
|
||||||
|
|
||||||
<img src="images/PPM.png" width="338" height="200" />
|
<img src="images/PPM.png" width="338" height="200" />
|
||||||
@ -22,7 +22,7 @@ Even in PPM mode it may still be possible to access telemetry information from s
|
|||||||
|
|
||||||
For transmitter setup using the PPM protocol go to the [PPM Setup page](PPM_Setup.md)
|
For transmitter setup using the PPM protocol go to the [PPM Setup page](PPM_Setup.md)
|
||||||
|
|
||||||
##Serial
|
## Serial
|
||||||
Transmitters that run er9X, erSky9X or OpenTx firmwares (like the FrSky Taranis, FlySky TH9X and Turnigy 9X family of transmitters) have the option of using a fast serial communication protocol between the Tx and the DIY Multiprotocol module. Using this serial communication protocol has some significant advantages:
|
Transmitters that run er9X, erSky9X or OpenTx firmwares (like the FrSky Taranis, FlySky TH9X and Turnigy 9X family of transmitters) have the option of using a fast serial communication protocol between the Tx and the DIY Multiprotocol module. Using this serial communication protocol has some significant advantages:
|
||||||
|
|
||||||
1. selecting the specific radio protocol (e.g. DSM) and the sub protocol (e.g. DSMX22) is done directly in the menu system of the Tx (see the picture below)
|
1. selecting the specific radio protocol (e.g. DSM) and the sub protocol (e.g. DSMX22) is done directly in the menu system of the Tx (see the picture below)
|
||||||
@ -50,7 +50,7 @@ Transmitter|Firmware Options|Telemetry Enabled
|
|||||||
Click on your transmitter above to view specific setup instructions.
|
Click on your transmitter above to view specific setup instructions.
|
||||||
|
|
||||||
|
|
||||||
##Telemetry
|
## Telemetry
|
||||||
|
|
||||||
To enable serial telemetry you need one of the radios and firmwares listed in the table above and **may** require modifications to your Tx. See the table above. Before attempting telemetry check the following:
|
To enable serial telemetry you need one of the radios and firmwares listed in the table above and **may** require modifications to your Tx. See the table above. Before attempting telemetry check the following:
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ To enable serial telemetry you need one of the radios and firmwares listed in th
|
|||||||
1. Your transmitter hardware is telemetry enabled, or you have done the required mods. Check the table above.
|
1. Your transmitter hardware is telemetry enabled, or you have done the required mods. Check the table above.
|
||||||
|
|
||||||
<a name="Telemetry_Mod"></a>
|
<a name="Telemetry_Mod"></a>
|
||||||
##Optional Telemetry mod for 9X/R TH9X transmitters
|
## Optional Telemetry mod for 9X/R TH9X transmitters
|
||||||
The telemetry mod for these transmitters has evolved. The original and popular "FrSky Telemetry Mod" requires 2 pins on the transmitter module board to be modified (RX on pin 5 and TX on pin 2). All the recent MULTI-Module hardware options supports serial transmission on pin 1 (the same pin as the PPM signal) so, in this case, only the mod on pin 5 is required.
|
The telemetry mod for these transmitters has evolved. The original and popular "FrSky Telemetry Mod" requires 2 pins on the transmitter module board to be modified (RX on pin 5 and TX on pin 2). All the recent MULTI-Module hardware options supports serial transmission on pin 1 (the same pin as the PPM signal) so, in this case, only the mod on pin 5 is required.
|
||||||
|
|
||||||
A good tutorial to follow is Oscar Liang's [here](http://blog.oscarliang.net/turnigy-9x-advance-mod/) but when you get to wiring up the Tx Module bay pins, you only need to perform the steps relevant for Pin 5.
|
A good tutorial to follow is Oscar Liang's [here](http://blog.oscarliang.net/turnigy-9x-advance-mod/) but when you get to wiring up the Tx Module bay pins, you only need to perform the steps relevant for Pin 5.
|
||||||
@ -67,7 +67,7 @@ A good tutorial to follow is Oscar Liang's [here](http://blog.oscarliang.net/tur
|
|||||||
You can see Midelic's original instructions [here](http://www.rcgroups.com/forums/showpost.php?p=28359305&postcount=2)
|
You can see Midelic's original instructions [here](http://www.rcgroups.com/forums/showpost.php?p=28359305&postcount=2)
|
||||||
|
|
||||||
|
|
||||||
##Other Notes:
|
## Other Notes:
|
||||||
- er9X and erSky9X firmware already supports Multiprotocol Module as a standard feature. The next major release of OpenTx - OpenTx 2.2 - will have DIY Mulitprotocol support as a standard feature.
|
- er9X and erSky9X firmware already supports Multiprotocol Module as a standard feature. The next major release of OpenTx - OpenTx 2.2 - will have DIY Mulitprotocol support as a standard feature.
|
||||||
|
|
||||||
- Owners of Walkera Devo transmitters should look at the [Deviation-Tx](http://www.deviationtx.com) project for how to achieve the same end goal with your transmitters.
|
- Owners of Walkera Devo transmitters should look at the [Deviation-Tx](http://www.deviationtx.com) project for how to achieve the same end goal with your transmitters.
|
||||||
|
@ -1,32 +1,39 @@
|
|||||||
# Troubleshooting
|
# Troubleshooting
|
||||||
|
|
||||||
##LED status
|
## LED status
|
||||||
###Green LED
|
|
||||||
- Off: no power to the module
|
|
||||||
- On: module is powered up
|
|
||||||
|
|
||||||
###Red LED (bind LED)
|
### Green LED
|
||||||
- Off: program not running or a protocol selected with the associated module not installed
|
|
||||||
- Flash(on=0.05s,off=1s): invalid protocol selected (excluded from compilation or invalid protocol number)
|
- **_Off_**: no power to the module
|
||||||
- Inverted Flash(on=1s,off=0.1s): module is waiting for a bind event (Bind from channel or Bind in radio GUI) to launch the protocol in bind mode
|
- **_On_**: module is powered up
|
||||||
- Fast blink(on=0.1s,off=0.1s): bind in progress
|
|
||||||
- Slow blink(on=0.5s,off=0.5s): serial has been selected but no valid signal is being seen on the RX pin.
|
### Red LED (bind LED)
|
||||||
- Slower blink(on=1s,off=1s): PPM has been selected but no valid signal is being seen on the PPM pin.
|
|
||||||
- On: Module is in normal operation mode (transmitting control signals).
|
- **_Off_**: program not running or a protocol selected with the associated module not installed
|
||||||
|
- **_Flash(on=0.05s,off=1s)_**: invalid protocol selected (excluded from compilation or invalid protocol number)
|
||||||
|
- **_Inverted Flash(on=1s,off=0.1s)_**: module is waiting for a bind event (Bind from channel or Bind in radio GUI) to launch the protocol in bind mode
|
||||||
|
- **_Fast blink(on=0.1s,off=0.1s)_**: bind in progress
|
||||||
|
- **_Slow blink(on=0.5s,off=0.5s)_**: serial has been selected but no valid signal is being seen on the RX pin.
|
||||||
|
- **_Slower blink(on=1s,off=1s)_**: PPM has been selected but no valid signal is being seen on the PPM pin.
|
||||||
|
- **_On_**: Module is in normal operation mode (transmitting control signals).
|
||||||
|
|
||||||
|
## Protocol selection
|
||||||
|
|
||||||
|
### Input Mode - PPM
|
||||||
|
|
||||||
##Protocol selection
|
|
||||||
###Input Mode - PPM
|
|
||||||
- The protocol/mode selection must be done before the power is applied to the module
|
- The protocol/mode selection must be done before the power is applied to the module
|
||||||
- Often the signal is not sent to the module until the transmitter has performed safety checks (like switch and throttle position settings)
|
- Often the signal is not sent to the module until the transmitter has performed safety checks (like switch and throttle position settings)
|
||||||
- Check that at least one of the protocol selection pins is connected to GND.
|
- Check that at least one of the protocol selection pins is connected to GND.
|
||||||
- Some radios have an open collector output (Futaba, Graupner...), in this case add a 4.7K resistor between PPM and BATT.
|
- Some radios have an open collector output (Futaba, Graupner...), in this case add a 4.7K resistor between PPM and BATT.
|
||||||
|
|
||||||
###Input Mode - Serial
|
### Input Mode - Serial
|
||||||
- Make sure you have done the serial mods as indicated in the [hardware page for your board] (Hardware.md).
|
|
||||||
|
- Make sure you have done the serial mods as indicated in the [hardware page for your board](Hardware.md).
|
||||||
- Protocol selection dial must be in the 0 position or leave all 4 selection pins unconnected.
|
- Protocol selection dial must be in the 0 position or leave all 4 selection pins unconnected.
|
||||||
- Often the signal is not sent to the module until the transmitter has performed safety checks (like switch and throttle position settings)
|
- Often the signal is not sent to the module until the transmitter has performed safety checks (like switch and throttle position settings)
|
||||||
|
|
||||||
##Bind
|
## Bind
|
||||||
|
|
||||||
Make sure to follow this procedure: press the bind button, apply power and then release after the red LED starts flashing. The LED should be blinking fast indicating a bind status and then fixed on when the bind period is over. It's normal that the LED turns off when you press the bind button, this behavior is not controlled by the Atmega328.
|
Make sure to follow this procedure: press the bind button, apply power and then release after the red LED starts flashing. The LED should be blinking fast indicating a bind status and then fixed on when the bind period is over. It's normal that the LED turns off when you press the bind button, this behavior is not controlled by the Atmega328.
|
||||||
For serial, the preffered method is to bind via the GUI protocol page.
|
For serial, the preffered method is to bind via the GUI protocol page.
|
||||||
|
|
||||||
@ -39,7 +46,8 @@ FrSky & SFHSS bind issues are ususally due to Option=fine frequency tuning not s
|
|||||||
- find the values min/max where the RX loses connection. In serial mode you can change the value and see the effect live.
|
- find the values min/max where the RX loses connection. In serial mode you can change the value and see the effect live.
|
||||||
- set the value to half way between min and max.
|
- set the value to half way between min and max.
|
||||||
|
|
||||||
##Report issues
|
## Report issues
|
||||||
|
|
||||||
You can report your problem using the [GitHub issue](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/issues) system or go to the [Main thread on RCGROUPS](http://www.rcgroups.com/forums/showthread.php?t=2165676) to ask your question.
|
You can report your problem using the [GitHub issue](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/issues) system or go to the [Main thread on RCGROUPS](http://www.rcgroups.com/forums/showthread.php?t=2165676) to ask your question.
|
||||||
Please provide the following information:
|
Please provide the following information:
|
||||||
- Multiprotocol code version
|
- Multiprotocol code version
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#Flysky TH9X family of transmitters
|
# Flysky TH9X family of transmitters
|
||||||
This page is relevant to the following transmitters:
|
This page is relevant to the following transmitters:
|
||||||
* FlySky TH9X
|
* FlySky TH9X
|
||||||
* Turnigy 9X, Turnigy 9XR
|
* Turnigy 9X, Turnigy 9XR
|
||||||
@ -19,21 +19,21 @@ Serial mode is only supported by the er9X firmware. Loading this firmware is be
|
|||||||
|
|
||||||
er9X is very well documented, see [here](http://openrcforums.com/forum/viewtopic.php?f=5&t=6473#p90349)
|
er9X is very well documented, see [here](http://openrcforums.com/forum/viewtopic.php?f=5&t=6473#p90349)
|
||||||
|
|
||||||
###Enabling Serial Mode
|
### Enabling Serial Mode
|
||||||
1. Confirm that the MULTI-Module has the required physical connections between the pins on the back of the Tx and the ATMega328 microprocessor. This may require some soldering and depends on which version of the MULTI-Module you have. Check out your module’s hardware page under the section **Enabling your MULTI-Module for Serial** for details. Click here for the [hardware](Hardware.md) pages.
|
1. Confirm that the MULTI-Module has the required physical connections between the pins on the back of the Tx and the ATMega328 microprocessor. This may require some soldering and depends on which version of the MULTI-Module you have. Check out your module’s hardware page under the section **Enabling your MULTI-Module for Serial** for details. Click here for the [hardware](Hardware.md) pages.
|
||||||
1. Plug in your DIY Multiprotocol module into the transmitter module bay. If you have a rotary protocol selection switch, turn the switch to position 0 to put the unit into Serial mode.
|
1. Plug in your DIY Multiprotocol module into the transmitter module bay. If you have a rotary protocol selection switch, turn the switch to position 0 to put the unit into Serial mode.
|
||||||
1. Ensure throttle is down and all switches are in the start position and power up the Tx. The red LED on the DIY Multiprotocol module should be flashing with a period of about 1 second indicating that it has not established a valid serial link with the Tx. This is expected as we have not set up the Tx yet.
|
1. Ensure throttle is down and all switches are in the start position and power up the Tx. The red LED on the DIY Multiprotocol module should be flashing with a period of about 1 second indicating that it has not established a valid serial link with the Tx. This is expected as we have not set up the Tx yet.
|
||||||
1. Create a new model and confirm that the channel order is set to AETR (**This is really important - this is for all protocols - even for DSM as the MULTI-module firware will change the transmitted channel order according to the protocol.**
|
1. Create a new model and confirm that the channel order is set to AETR (**This is really important - this is for all protocols - even for DSM as the MULTI-module firware will change the transmitted channel order according to the protocol.**
|
||||||
1. In the Model Settings menu scroll down to change the RF settings to MULTI {mikeb - can you write this line }
|
1. In the Model Settings menu scroll down to change the RF settings to MULTI {mikeb - can you write this line }
|
||||||
1. The red LED on the MULTI-Module should briefly flash and then go off. This confirms that the MULTI-Module has established serial communication with the Tx. If the red LED on the module continues to flash at a period of about 1 seconds then it signals that serial communication has not been established. Check your settings under the model menu as described above and check that the protocol selection switch on the module is at 0 (enable Serial mode). If there is still no communication, power down and power up the Tx. Finally check that you have correctly enabled your module for serial as described on the hardware page for your module under the heading "Enabling your module for Serial". Click here to access the [hardware](Hardware.md) and then click on the picture of your module.
|
1. The red LED on the MULTI-Module should briefly flash and then go off. This confirms that the MULTI-Module has established serial communication with the Tx. If the red LED on the module continues to flash at a period of about 1 seconds then it signals that serial communication has not been established. Check your settings under the model menu as described above and check that the protocol selection switch on the module is at 0 (enable Serial mode). If there is still no communication, power down and power up the Tx. Finally check that you have correctly enabled your module for serial as described on the hardware page for your module under the heading "Enabling your module for Serial". Click here to access the [hardware](Hardware.md) and then click on the picture of your module.
|
||||||
|
|
||||||
###Protocol Selection in Serial mode
|
### Protocol Selection in Serial mode
|
||||||
To select the protocol:
|
To select the protocol:
|
||||||
1. In the Model Setting menu, scroll through the available options under the MULTI option {mikeb to confirm}.
|
1. In the Model Setting menu, scroll through the available options under the MULTI option {mikeb to confirm}.
|
||||||
1. Depending on which protocol you have selected you may be required to select a sup-protocol and options. For example, the FrSky protocol has three sub-protocols FrSky_V, FrSky_D and FrSky_X. In some cases the sub-protocols have options that could specify the number of channels, packet frame rate or fine frequency tuning. Check out the [Protocol Details](Protocol_Details.md) page for detailed information and suggestions regarding the sub-protocols and options. The picture below shows the settings in the erSky Model Setup menu for FrSkyX subprotocol with {mike to insert} options:
|
1. Depending on which protocol you have selected you may be required to select a sup-protocol and options. For example, the FrSky protocol has three sub-protocols FrSky_V, FrSky_D and FrSky_X. In some cases the sub-protocols have options that could specify the number of channels, packet frame rate or fine frequency tuning. Check out the [Protocol Details](../Protocols_Details.md) page for detailed information and suggestions regarding the sub-protocols and options. The picture below shows the settings in the erSky Model Setup menu for FrSkyX subprotocol with {mike to insert} options:
|
||||||
{mikeb to send simple picture}
|
{mikeb to send simple picture}
|
||||||
|
|
||||||
###Binding in Serial mode
|
### Binding in Serial mode
|
||||||
1. Switch on the model or put the receiver into bind mode
|
1. Switch on the model or put the receiver into bind mode
|
||||||
1. On the transmitter go to the Model Settings menu and scroll down to the [Bind] menu option and press Enter.
|
1. On the transmitter go to the Model Settings menu and scroll down to the [Bind] menu option and press Enter.
|
||||||
1. Press Enter again to exit Bind mode
|
1. Press Enter again to exit Bind mode
|
||||||
|
@ -17,15 +17,13 @@ The MULTI-module can be used with all transmitters and firmwares in PPM mode. T
|
|||||||
## PPM Mode
|
## PPM Mode
|
||||||
Please refer to the [PPM Setup](PPM_Setup.md) page.
|
Please refer to the [PPM Setup](PPM_Setup.md) page.
|
||||||
|
|
||||||
##Serial mode
|
## Serial mode
|
||||||
###Enabling Serial Mode
|
### Enabling Serial Mode
|
||||||
To operate in serial mode, you need one of these firmwares:
|
To operate in serial mode, you need one of these firmwares:
|
||||||
1. erSky9x
|
1. erSky9x Revision 218 or later - the hex files are available [here](http://www.er9x.com) (Mike's latests test versions are available [here](http://openrcforums.com/forum/viewtopic.php?f=7&t=4676)).
|
||||||
1. OpenTx supporting the MULTI-Module (Version 2.1.8 Multi or later)
|
1. OpenTx supporting the MULTI-Module (Version 2.1.8 Multi or later, 2.2 recommended). Check and upload a supported firmware. The latest available version at time of writing are:
|
||||||
|
- OpenTx 2.2RC16 or later [www.open-tx.org](http://www.open-tx.org/)
|
||||||
Check and upload a supported firmware. The latest available version at time of writing are:
|
- Please make sure that the "multimodule" option in OpenTX Companion is checked: <br> <img src="images/opentx-config-multi.png"> <br>
|
||||||
- erSky9x Revision 218 or later - the hex files are available [here](http://www.er9x.com) (Mike's latests test versions are available [here](http://openrcforums.com/forum/viewtopic.php?f=7&t=4676)).
|
|
||||||
- OpenTx 2.1.8 Multi or later - the hex files are available [here](http://plaisthos.de/opentx/)
|
|
||||||
|
|
||||||
Tutorials for uploading new firmware using the SD Card are available [here](http://www.dronetrest.com/t/how-to-upgrade-firmware-for-frsky-taranis-x9d/959) or the CompanionTx or eepe software (recommended) are available [here](http://open-txu.org/home/undergraduate-courses/fund-of-opentx/part-2-flashing-opentx/).
|
Tutorials for uploading new firmware using the SD Card are available [here](http://www.dronetrest.com/t/how-to-upgrade-firmware-for-frsky-taranis-x9d/959) or the CompanionTx or eepe software (recommended) are available [here](http://open-txu.org/home/undergraduate-courses/fund-of-opentx/part-2-flashing-opentx/).
|
||||||
|
|
||||||
@ -33,38 +31,22 @@ Tutorials for uploading new firmware using the SD Card are available [here](http
|
|||||||
|
|
||||||
First, confirm that the MULTI-Module has the required physical connections between the pins on the back of the Tx and the ATMega328 microprocessor. This may require some soldering and depends on which version of the DIY Multiprotocol module you have. Check out the specific pages for your module hardware (under the section "Enabling Serial") linked [here](Hardware.md) for details.
|
First, confirm that the MULTI-Module has the required physical connections between the pins on the back of the Tx and the ATMega328 microprocessor. This may require some soldering and depends on which version of the DIY Multiprotocol module you have. Check out the specific pages for your module hardware (under the section "Enabling Serial") linked [here](Hardware.md) for details.
|
||||||
|
|
||||||
1. Plug in your MULTI-Module into the transmitter's module bay.
|
1. Plug in your MULTI-Module into the transmitter's module bay.
|
||||||
2. If you have a rotary protocol selection switch, turn the switch to position 0 to put the unit into Serial mode.
|
1. If you have a rotary protocol selection switch, turn the switch to position 0 to put the unit into Serial mode.
|
||||||
2. Ensure throttle is down and all switches are in the start position and power up the Transmitter. The red LED on the MULTI-Module should be flashing with a period of about 1s indicating that it has not established a valid serial link with the Tx. This is expected as we have not set up the Tx yet.
|
1. Ensure throttle is down and all switches are in the start position and power up the Transmitter. The red LED on the MULTI-Module should be flashing with a period of about 1s indicating that it has not established a valid serial link with the Tx. This is expected as we have not set up the Tx yet.
|
||||||
3. Create a new model (make sure channel order is AETR - **This is really important - this is for all protocols - even for DSM as the MULTI-module firware will change the transmitted channel order according to the protocol.**) and on the first Model Settings page scroll down to disable the internal RF and enable the external RF by selecting MULTI as the external RF. Your Transmitter settings should look like this:
|
1. Create a new model (make sure channel order is AETR - **This is really important - this is for all protocols - even for DSM as the MULTI-module firware will change the transmitted channel order according to the protocol.**) and on the first Model Settings page scroll down to disable the internal RF and enable the external RF by selecting MULTI as the external RF. Your Transmitter settings should look like this: <br> <img src="images/settings-horus.png" /> <br> or <br> <img src="images/settings-taranis.png" /> <br> The Red LED on the MULTI-Module should briefly flash and then stay on. This confirms that the MULTI-Module module has established serial communication with the Tx.
|
||||||
|
1. If the red LED on the module continues to flash at a period of about 1s then it signals that serial communication has not been established. Check your settings under the model menu as described above and check that the protocol selection switch on the module is at 0 (zero). If there is still no communication, power down and power up the Tx. Finally check that you have correctly enabled your module for serial as described in specific pages for your module hardware (under the section "Enabling Serial") linked [here](Hardware.md)
|
||||||
<img src="images/settings-horus.png" /> or <img src="images/settings-taranis.png" />
|
|
||||||
|
|
||||||
The Red LED on the MULTI-Module should briefly flash and then stay on. This confirms that the MULTI-Module module has established serial communication with the Tx.
|
### Protocol Selection in Serial mode
|
||||||
4. If the red LED on the module continues to flash at a period of about 1s then it signals that serial communication has not been established. Check your settings under the model menu as described above and check that the protocol selection switch on the module is at 0 (zero). If there is still no communication, power down and power up the Tx. Finally check that you have correctly enabled your module for serial as described in specific pages for your module hardware (under the section "Enabling Serial") linked [here](Hardware.md)
|
|
||||||
|
|
||||||
###Protocol Selection in Serial mode
|
|
||||||
To select the protocol, scroll through the available options under the Model Settings menu. Depending on which protocol you have selected you may be required to select a sup-protocol and options. For example, the FrSky protocol has three sub-protocols FrSkyV, FrSkyD and FrSkyX. Each of the sub-protocols may have options that specify the number of channels and the packet frame rate, etc.
|
To select the protocol, scroll through the available options under the Model Settings menu. Depending on which protocol you have selected you may be required to select a sup-protocol and options. For example, the FrSky protocol has three sub-protocols FrSkyV, FrSkyD and FrSkyX. Each of the sub-protocols may have options that specify the number of channels and the packet frame rate, etc.
|
||||||
|
|
||||||
The following picture shows DSM – DSMX – Option 6 (6 channels and 11ms frame rate). Check out the [Protocol Details](Protocol_Details.md) page for detailed information and suggestions regarding the sub-protocols and options.
|
The following picture shows DSM – DSMX – Option 6 (6 channels and 11ms frame rate). Check out the [Protocol Details](Protocol_Details.md) page for detailed information and suggestions regarding the sub-protocols and options.
|
||||||
|
|
||||||
###Protcol Status in Serial mode (OpenTX)
|
### Protcol Status in Serial mode (OpenTX)
|
||||||
If you see ```NO MULTI_TELEMETRY``` or no ```NO TELEMETRY``` in the setup screen of the external module, like this:
|
If you see ```NO MULTI_TELEMETRY``` or no ```NO TELEMETRY``` in the setup screen of the external module, like this: <br> <img width="594" height="213" src="images/X7-no-telemetry.png" /> <br> you are missing the ```MULTI_TELEMETRY``` and/or ```INVERT_TELEMTRY``` option in your ```_Config.h``` and/or [you need to hardware modifications to enable telemetry](Hardware.md). OpenTX also shows the ```NO TELEMETRY``` message if no module status has been received in the last 2s which can indicate a non working module if the telemetry status worked before. With the option enabled, the right telemetry type is automatically detected and you will see the status of the module: <br> <img width="580" height="210" src="images/X7-protocol-invalid.png"> <br> (Selected protocol is not available, most probably mssing from ```_Config.h```) <br> <img width="576" height="209" src="images/X7-bind.png"> <br> (Module is currently binding and code on the module is running V1.1.6.10)
|
||||||
|
|
||||||
<img width="594" height="213" src="images/X7-no-telemetry.png" />
|
|
||||||
|
|
||||||
you are missing the ```MULTI_TELEMETRY``` and/or ```INVERT_TELEMTRY``` option in your ```_Config.h``` and/or [you need to hardware modifications to enable telemetry](Hardware.md). OpenTX also shows the ```NO TELEMETRY``` message if no module status has been received in the last 2s which can indicate a non working module if the telemetry status worked before. With the option enabled, the right telemetry type is automatically detected and you will see the status of the module:
|
|
||||||
|
|
||||||
<img width="580" height="210" src="images/X7-protocol-invalid.png">
|
|
||||||
|
|
||||||
(Selected protocol is not available, most probably mssing from ```_Config.h```)
|
|
||||||
|
|
||||||
<img width="576" height="209" src="images/X7-bind.png">
|
|
||||||
|
|
||||||
(Module is currently binding and code on the module is running V1.1.6.10)
|
|
||||||
|
|
||||||
|
|
||||||
###Binding in Serial mode
|
### Binding in Serial mode
|
||||||
1. Switch on the model or put the receiver into bind mode
|
1. Switch on the model or put the receiver into bind mode
|
||||||
1. On the transmitter go to the Model Settings menu and scroll down to the [Bind] menu option and press Enter.
|
1. On the transmitter go to the Model Settings menu and scroll down to the [Bind] menu option and press Enter.
|
||||||
1. Press Enter again to exit Bind mode
|
1. Press Enter again to exit Bind mode
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#erSky9X family of transmitters
|
# erSky9X family of transmitters
|
||||||
This page is relevant to the following transmitters:
|
This page is relevant to the following transmitters:
|
||||||
- Taranis running erSky9X (for the Taranis running OpenTx see [here](Tx-Taranis.md))
|
- Taranis running erSky9X (for the Taranis running OpenTx see [here](Tx-Taranis.md))
|
||||||
- Turnigy 9XR Pro (for Turnigy 9X see [here](Tx-FlyskyTH9X.md))
|
- Turnigy 9XR Pro (for Turnigy 9X see [here](Tx-FlyskyTH9X.md))
|
||||||
@ -21,7 +21,7 @@ Serial mode is only supported by the erSky9X firmware. Loading this firmware is
|
|||||||
|
|
||||||
erSky9X is well documented, the slightly outdated erSky9X documentation is [here](http://openrcforums.com/forum/viewtopic.php?f=5&t=6473#p90349). You may find the new Er9x manual very helpful in understanding Ersky9x as the two firmwares are very closely related. It provides more detailed explanations and numerous relevant programming examples and is available [here](http://openrcforums.com/forum/viewtopic.php?f=5&t=6473#p90349).
|
erSky9X is well documented, the slightly outdated erSky9X documentation is [here](http://openrcforums.com/forum/viewtopic.php?f=5&t=6473#p90349). You may find the new Er9x manual very helpful in understanding Ersky9x as the two firmwares are very closely related. It provides more detailed explanations and numerous relevant programming examples and is available [here](http://openrcforums.com/forum/viewtopic.php?f=5&t=6473#p90349).
|
||||||
|
|
||||||
###Enabling Serial Mode
|
### Enabling Serial Mode
|
||||||
1. Confirm that the MULTI-Module has the required physical connections between the pins on the back of the Tx and the ATMega328 microprocessor. This may require some soldering and depends on which version of the MULTI-Module you have. Check out your module’s hardware page under the section **Enabling your module for Serial** for details. Click on the image that corresponds to your MULTI-Module on the [hardware](Hardware.md) page.
|
1. Confirm that the MULTI-Module has the required physical connections between the pins on the back of the Tx and the ATMega328 microprocessor. This may require some soldering and depends on which version of the MULTI-Module you have. Check out your module’s hardware page under the section **Enabling your module for Serial** for details. Click on the image that corresponds to your MULTI-Module on the [hardware](Hardware.md) page.
|
||||||
1. Plug in your MULTI-Module into the transmitter module bay. If you have a rotary protocol selection switch, turn the switch to position 0 to put the unit into Serial mode.
|
1. Plug in your MULTI-Module into the transmitter module bay. If you have a rotary protocol selection switch, turn the switch to position 0 to put the unit into Serial mode.
|
||||||
1. Ensure throttle is down and all switches are in the start position and power up the Tx. The red LED on the MULTI-Module should be flashing with a period of about 1 second indicating that it has not established a valid serial link with the Tx. This is expected as we have not set up the Tx yet.
|
1. Ensure throttle is down and all switches are in the start position and power up the Tx. The red LED on the MULTI-Module should be flashing with a period of about 1 second indicating that it has not established a valid serial link with the Tx. This is expected as we have not set up the Tx yet.
|
||||||
@ -29,13 +29,13 @@ erSky9X is well documented, the slightly outdated erSky9X documentation is [here
|
|||||||
1. In the Model Setup menu scroll down to the **Protocol** submenu and change the RF settings to MULTI. This should reveal a set of additional options (like Protocol and Options)
|
1. In the Model Setup menu scroll down to the **Protocol** submenu and change the RF settings to MULTI. This should reveal a set of additional options (like Protocol and Options)
|
||||||
1. The red LED on the MULTI-Module should briefly flash and then remain solid. This confirms that the MULTI-Module has established serial communication with the Tx. If the red LED on the module continues to flash at a period of about 1 seconds then it signals that serial communication has not been established. Check your settings under the model menu as described above and check that the protocol selection switch on the module is at 0 (enable Serial mode). If there is still no communication, power down and power up the Tx. Finally check that you have correctly enabled your module for serial as described on the hardware page for your module under the heading "Enabling your module for Serial". Click here to access the [hardware](Hardware.md) and then click on the picture of your module.
|
1. The red LED on the MULTI-Module should briefly flash and then remain solid. This confirms that the MULTI-Module has established serial communication with the Tx. If the red LED on the module continues to flash at a period of about 1 seconds then it signals that serial communication has not been established. Check your settings under the model menu as described above and check that the protocol selection switch on the module is at 0 (enable Serial mode). If there is still no communication, power down and power up the Tx. Finally check that you have correctly enabled your module for serial as described on the hardware page for your module under the heading "Enabling your module for Serial". Click here to access the [hardware](Hardware.md) and then click on the picture of your module.
|
||||||
|
|
||||||
###Protocol Selection in Serial mode
|
### Protocol Selection in Serial mode
|
||||||
To select the protocol:
|
To select the protocol:
|
||||||
1. In the Model Setting menu, scroll through the available options under the MULTI protocol
|
1. In the Model Setting menu, scroll through the available options under the MULTI protocol
|
||||||
1. Depending on which protocol you have selected you may be required to select a sup-protocol and options. For example, there are three protocols that correspond to FrSky recievers: FrSky_V, FrSky_D and FrSky_X. In some cases the sub-protocols have options that could specify the number of channels, packet frame rate or fine frequency tuning. Check out the [Protocol Details](Protocol_Details.md) page for detailed information and suggestions regarding the sub-protocols and options. The picture below shows the settings in the erSky Model Setup menu for FrSkyX subprotocol with {mike to insert} options:
|
1. Depending on which protocol you have selected you may be required to select a sup-protocol and options. For example, there are three protocols that correspond to FrSky recievers: FrSky_V, FrSky_D and FrSky_X. In some cases the sub-protocols have options that could specify the number of channels, packet frame rate or fine frequency tuning. Check out the [Protocol Details](../Protocols_Details.md) page for detailed information and suggestions regarding the sub-protocols and options. The picture below shows the settings in the erSky Model Setup menu for FrSkyX subprotocol with {mike to insert} options:
|
||||||
{mikeb to send simple picture}
|
{mikeb to send simple picture}
|
||||||
|
|
||||||
###Binding in Serial mode
|
### Binding in Serial mode
|
||||||
1. Switch on the model or put the receiver into bind mode
|
1. Switch on the model or put the receiver into bind mode
|
||||||
1. On the transmitter go to the Model Settings menu and scroll down to the [Bind] menu option and press Enter.
|
1. On the transmitter go to the Model Settings menu and scroll down to the [Bind] menu option and press Enter.
|
||||||
1. Press Enter again to exit Bind mode
|
1. Press Enter again to exit Bind mode
|
||||||
|
BIN
docs/images/Board_PCB_STM32_USB_V1.1-1.png
Normal file
BIN
docs/images/Board_PCB_STM32_USB_V1.1-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
BIN
docs/images/Board_PCB_STM32_USB_V1.1-2.png
Normal file
BIN
docs/images/Board_PCB_STM32_USB_V1.1-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
BIN
docs/images/opentx-config-multi.png
Normal file
BIN
docs/images/opentx-config-multi.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 96 KiB |
Loading…
x
Reference in New Issue
Block a user