diff --git a/sw/airborne/subsystems/datalink/Makefile b/sw/airborne/subsystems/datalink/Makefile new file mode 100644 index 0000000000..a36beab5db --- /dev/null +++ b/sw/airborne/subsystems/datalink/Makefile @@ -0,0 +1,72 @@ +# +# Copyright (C) 2013 Gautier Hattenberger +# +# This file is part of paparazzi. +# +# paparazzi 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, or (at your option) +# any later version. +# +# paparazzi 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 paparazzi; see the file COPYING. If not, write to +# the Free Software Foundation, 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# + +# +# Export downlink library source code using PPRZ transport protocol +# +# The library as to be compiled by the target application +# after implementing the dl_parse function (for parsing incoming messages) +# + +# Quiet compilation +Q=@ + +TAR= tar +INCLUDES= -I$(PAPARAZZI_SRC)/sw/include -I$(PAPARAZZI_SRC)/sw/airborne + +ifeq ($(PAPARAZZI_HOME),) +PAPARAZZI_HOME=$(PAPARAZZI_SRC) +endif + +# export in $(PAPARAZZI_HOME)/var/export/datalink +EXPORT_ROOT ?= $(PAPARAZZI_HOME)/var/export +EXPORT_DIR = $(EXPORT_ROOT)/datalink + +EXPORT_FILES = \ + downlink.h \ + downlink.c \ + pprz_transport.h \ + pprz_transport.c \ + transport.h \ + datalink.h \ + $(PAPARAZZI_SRC)/sw/include/std.h \ + $(PAPARAZZI_HOME)/var/include/messages.h \ + $(PAPARAZZI_HOME)/var/include/dl_protocol.h + +MAKEFILE_EXPORT = pprz_datalink.mk +TAR_EXPORT = pprz_datalink.tar + +all: + @cat README + +export_lib: + @echo Exporting datalink lib to $(EXPORT_DIR) + $(Q)test -d $(EXPORT_DIR) || mkdir -p $(EXPORT_DIR) + $(Q)cp $(EXPORT_FILES) $(EXPORT_DIR) + $(Q)cp $(MAKEFILE_EXPORT) $(EXPORT_DIR) + $(Q)cp README.md $(EXPORT_DIR) + $(Q)cd $(EXPORT_ROOT); $(TAR) -cf $(TAR_EXPORT) datalink/* + +clean: + $(Q)rm -rf $(EXPORT_DIR) + +.PHONY: all clean export_lib + diff --git a/sw/airborne/subsystems/datalink/README.md b/sw/airborne/subsystems/datalink/README.md new file mode 100644 index 0000000000..b28d1bd0ab --- /dev/null +++ b/sw/airborne/subsystems/datalink/README.md @@ -0,0 +1,179 @@ +Datalink (uplink and downlink) lib using PPRZ protocol +====================================================== + +HOWTO export +------------ + +- Export library: in this folder, type + ``` + make export_lib + ``` + be sure that you have correctly build the paparazzi project (`make` in the main directory) + +- The default export directory is `${PAPARAZZI_HOME}/var/export`, to change it: + ``` + EXPORT_ROOT= make export_lib + ``` + +- `make clean` will only remove the export directory + +HOWTO use the datalink library +------------------------------ + +1. Copy the folder `datalink` in the export directory to your project directory (or untar the file `pprz_datalink.tar`) + +2. In your project makefile: + * define the variable `PPRZ_DATALINK_PORT` to your device (ex: `PPRZ_DATALINK_PORT=XXX`) + * define the variable `PPRZ_DATALINK_DIR` to your extract folder + * include the library makefile `include ${PPRZ_DATALINK_DIR}/datalink/pprz_datalink.mk` + * add `PPRZ_DATALINK_CFLAGS` to your cflags + * add `PPRZ_DATALINK_SRCS` to your sources (if your project requires a list of object files, you can use `PPRZ_DATALINK_OBJS` instead) + +3. Device interface + You need to provide an interface to send the data. If your device is named `XXX`, you need to provide the following functions or macros + * `XXXCheckFreeSpace(len)` that return true if your device has enough space for `len` bytes + * `XXXTransmit(c)` that send a single byte `c` using the device `XXX` (or store them in a buffer) + * `XXXSendMessage()` that flushs the bytes to send (if needed) + * `XXXChAvailable()` that returns true new characters are available for reading + * `XXXGetch()` taht returns the next character to parse + + Usually, an UART interface is used for datalink. + +4. Message parsing and includes: + in a C file of you project (for example a file named `datalink.c`), add the following lines: + ``` + #define DATALINK_C 1 // this should be placed before the includes + + #inlcude "uart.h" // or change this include to the header of your actual device interface + #include "downlink.h" + + void dl_parse_msg(void) { + + } + ``` + You also need to poll for new characters, which means that you have to call the `DatalinkEvent()` function in your main loop. + This function is non-blocking and calls the decoder on each received byte. Finally the `dl_parse_msg` function is called when a complete message is received (checksum is valid). + +Example project for Mbeb dev board +================================== + +Test file `test_dl.cpp` (assuming you already have the Mbed library) +``` + #include "mbed.h" + + Ticker daq; + Serial uart1(p9, p10); + DigitalOut led1(LED1); + DigitalOut led2(LED2); + + /**** PPRZ interface ****/ + #define DATALINK_C 1 + #define UartCheckFreeSpace(_len) uart1.writeable() + #define UartTransmit(_c) uart1.putc(_c) + #define UartSendMessage() {} + #define UartChAvailable() uart1.readable() + #define UartGetch() uart1.getc() + + #include "downlink.h" + + void dl_parse_msg(void) { + int msg_id = dl_buffer[1]; + + switch (msg_id) { + case DL_PONG: + led2 =! led2; // toggle led on new PONG message + break; + default: + break; + } + + } + /************************/ + + void cb() + { + // Toggle led 1 when sending PING + led1 =! led1; + // Send PPRZ message + DOWNLINK_SEND_PING(DefaultChannel, DefaultDevice); + } + + int main() + { + uart1.baud(57600); // set serial baud rate for PPRZ + led1 = led2 = 0; // turn off all LEDs + + daq.attach(&cb, 1); // callback + + while(1) { + + // Your (non-blocking) code + + // Poll new bytes on uart + DatalinkEvent(); + + } // ~while + } // ~main +``` + +With the makefile: +``` + # This file was automagically generated by mbed.org with PPRZ datalink library addition + + GCC_BIN = /usr/bin/ + PROJECT = Test_PPRZ_Datalink + OBJECTS = ./test_dl.o + SYS_OBJECTS = ./mbed/LPC1768/GCC_CS/sys.o ./mbed/LPC1768/GCC_CS/cmsis_nvic.o ./mbed/LPC1768/GCC_CS/system_LPC17xx.o ./mbed/LPC1768/GCC_CS/core_cm3.o ./mbed/LPC1768/GCC_CS/startup_LPC17xx.o + INCLUDE_PATHS = -I. -I./mbed -I./mbed/LPC1768 -I./mbed/LPC1768/GCC_CS + LIBRARY_PATHS = -L./mbed/LPC1768/GCC_CS + LIBRARIES = -lmbed -lcapi + LINKER_SCRIPT = ./mbed/LPC1768/GCC_CS/LPC1768.ld + + CC = $(GCC_BIN)arm-none-eabi-gcc + CPP = $(GCC_BIN)arm-none-eabi-g++ + CC_FLAGS = -c -Os -fno-common -fmessage-length=0 -Wall -fno-exceptions -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections + ONLY_C_FLAGS = -std=gnu99 + ONLY_CPP_FLAGS = -std=gnu++98 + CC_SYMBOLS = -DTARGET_LPC1768 -DTOOLCHAIN_GCC_CS -DNDEBUG + + + ### PPRZ Datalink ### + + PPRZ_DATALINK_PORT = Uart + PPRZ_DATALINK_DIR = . + include $(PPRZ_DATALINK_DIR)/datalink/pprz_datalink.mk + OBJECTS += $(PPRZ_DATALINK_OBJS) + CC_SYMBOLS += $(PPRZ_DATALINK_CFLAGS) + + ##################### + + + AS = $(GCC_BIN)arm-none-eabi-as + + LD = $(GCC_BIN)arm-none-eabi-gcc + LD_FLAGS = -mcpu=cortex-m3 -mthumb -Wl,--gc-sections + LD_SYS_LIBS = -lstdc++ -lsupc++ -lm -lc -lgcc + + OBJCOPY = $(GCC_BIN)arm-none-eabi-objcopy + + all: $(PROJECT).bin + + clean: + rm -f $(PROJECT).bin $(PROJECT).elf $(OBJECTS) + + .s.o: + $(AS) $(CC_FLAGS) $(CC_SYMBOLS) -o $@ $< + + .c.o: + $(CC) $(CC_FLAGS) $(CC_SYMBOLS) $(ONLY_C_FLAGS) $(INCLUDE_PATHS) -o $@ $< + + .cpp.o: + $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) $(ONLY_CPP_FLAGS) $(INCLUDE_PATHS) -o $@ $< + + + $(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS) + $(LD) $(LD_FLAGS) -T$(LINKER_SCRIPT) $(LIBRARY_PATHS) -o $@ $^ $(LIBRARIES) $(LD_SYS_LIBS) $(LIBRARIES) $(LD_SYS_LIBS) + + $(PROJECT).bin: $(PROJECT).elf + $(OBJCOPY) -O binary $< $@ +``` diff --git a/sw/airborne/subsystems/datalink/downlink.c b/sw/airborne/subsystems/datalink/downlink.c index c7f9ce5feb..ac628f2ce4 100644 --- a/sw/airborne/subsystems/datalink/downlink.c +++ b/sw/airborne/subsystems/datalink/downlink.c @@ -27,7 +27,6 @@ #include "std.h" -#include "generated/airframe.h" uint8_t downlink_nb_ovrn; uint16_t downlink_nb_bytes; diff --git a/sw/airborne/subsystems/datalink/downlink.h b/sw/airborne/subsystems/datalink/downlink.h index 38db001cc9..4f6fc8a40e 100644 --- a/sw/airborne/subsystems/datalink/downlink.h +++ b/sw/airborne/subsystems/datalink/downlink.h @@ -30,6 +30,8 @@ #include +#ifndef PPRZ_DATALINK_EXPORT + #include "generated/modules.h" #include "messages.h" #include "generated/airframe.h" // AC_ID is required @@ -64,6 +66,16 @@ #endif /** !SITL */ +#else /* PPRZ_DATALINK_EXPORT defined */ + +#include "messages.h" +#include "pprz_transport.h" +#ifndef AC_ID +#define AC_ID 0 +#endif + +#endif + #ifndef DefaultChannel #define DefaultChannel DOWNLINK_TRANSPORT #endif diff --git a/sw/airborne/subsystems/datalink/pprz_datalink.mk b/sw/airborne/subsystems/datalink/pprz_datalink.mk new file mode 100644 index 0000000000..80e41406c7 --- /dev/null +++ b/sw/airborne/subsystems/datalink/pprz_datalink.mk @@ -0,0 +1,36 @@ +# +# Copyright (C) 2013 Gautier Hattenberger +# +# This file is part of paparazzi. +# +# paparazzi 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, or (at your option) +# any later version. +# +# paparazzi 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 paparazzi; see the file COPYING. If not, write to +# the Free Software Foundation, 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# + +# +# PPRZ datalink makefile to include to your project +# +# define PPRZ_DATALINK_DIR variable to your extract folder +# define PPRZ_DATALINK_PORT variable to your UART port +# add PPRZ_DATALINK_CFLAGS to your CFLAGS +# and PPRZ_DATALINK_SRCS to your sources list +# + +PPRZ_DATALINK_CFLAGS = -DPPRZ_DATALINK_EXPORT -I$(PPRZ_DATALINK_DIR)/datalink +PPRZ_DATALINK_CFLAGS += -DDOWNLINK -DDOWNLINK_DEVICE=$(PPRZ_DATALINK_PORT) -DPPRZ_UART=$(PPRZ_DATALINK_PORT) -DDOWNLINK_TRANSPORT=PprzTransport +PPRZ_DATALINK_CFLAGS += -DDATALINK=PPRZ +PPRZ_DATALINK_SRCS = $(PPRZ_DATALINK_DIR)/datalink/downlink.c $(PPRZ_DATALINK_DIR)/datalink/pprz_transport.c +PPRZ_DATALINK_OBJS = $(PPRZ_DATALINK_SRCS:.c=.o) + diff --git a/sw/airborne/subsystems/datalink/pprz_transport.c b/sw/airborne/subsystems/datalink/pprz_transport.c index 20db99e5c0..05ac097bd3 100644 --- a/sw/airborne/subsystems/datalink/pprz_transport.c +++ b/sw/airborne/subsystems/datalink/pprz_transport.c @@ -21,8 +21,11 @@ */ #include +#ifndef PPRZ_DATALINK_EXPORT #include "subsystems/datalink/pprz_transport.h" -#include "mcu_periph/uart.h" +#else /* PPRZ_DATALINK_EXPORT defined */ +#include "pprz_transport.h" +#endif uint8_t ck_a, ck_b; diff --git a/sw/airborne/subsystems/datalink/pprz_transport.h b/sw/airborne/subsystems/datalink/pprz_transport.h index 6f3aaa649b..f04261c6cc 100644 --- a/sw/airborne/subsystems/datalink/pprz_transport.h +++ b/sw/airborne/subsystems/datalink/pprz_transport.h @@ -43,8 +43,13 @@ #include #include "std.h" +#ifndef PPRZ_DATALINK_EXPORT #include "subsystems/datalink/datalink.h" #include "subsystems/datalink/transport.h" +#else /* PPRZ_DATALINK_EXPORT defined */ +#include "datalink.h" +#include "transport.h" +#endif /* PPRZ Transport * downlink macros