diff --git a/Arduino/Drv/HardwareRateDriver/CMakeLists.txt b/Arduino/Drv/HardwareRateDriver/CMakeLists.txt index 0049595..744fbfe 100644 --- a/Arduino/Drv/HardwareRateDriver/CMakeLists.txt +++ b/Arduino/Drv/HardwareRateDriver/CMakeLists.txt @@ -19,15 +19,12 @@ if (NOT FPRIME_ARDUINO) list(APPEND SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/HardwareRateDriverLinux.cpp") elseif (IS_TEENSY) target_use_arduino_libraries("IntervalTimer") - list(APPEND MOD_DEPS "IntervalTimer") list(APPEND SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/HardwareRateDriverTeensy.cpp") elseif (IS_ATMEGA) target_use_arduino_libraries("TimerOne") - list(APPEND MOD_DEPS "TimerOne") list(APPEND SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/HardwareRateDriverAvr.cpp") elseif (IS_MBED) target_use_arduino_libraries("mbed") - list(APPEND MOD_DEPS "mbed") list(APPEND SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/HardwareRateDriverMbed.cpp") else() set(COMPILE_DEFINITIONS "USE_BASIC_TIMER") diff --git a/Arduino/Drv/I2cDriver/CMakeLists.txt b/Arduino/Drv/I2cDriver/CMakeLists.txt new file mode 100644 index 0000000..e838b36 --- /dev/null +++ b/Arduino/Drv/I2cDriver/CMakeLists.txt @@ -0,0 +1,19 @@ +#### +# F prime CMakeLists.txt: +# +# SOURCE_FILES: combined list of source and autocoding files +# MOD_DEPS: (optional) module dependencies +# UT_SOURCE_FILES: list of source files for unit tests +# +#### +set(SOURCE_FILES + "${CMAKE_CURRENT_LIST_DIR}/I2cDriver.fpp" + "${CMAKE_CURRENT_LIST_DIR}/I2cDriver.cpp" +) +if(FPRIME_ARDUINO) + list(APPEND SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/I2cDriverArduino.cpp") + target_use_arduino_libraries("Wire") +else() + list(APPEND SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/I2cDriverLinux.cpp") +endif() +register_fprime_module() diff --git a/Arduino/Drv/I2cDriver/I2cDriver.cpp b/Arduino/Drv/I2cDriver/I2cDriver.cpp new file mode 100644 index 0000000..993518e --- /dev/null +++ b/Arduino/Drv/I2cDriver/I2cDriver.cpp @@ -0,0 +1,63 @@ +// ====================================================================== +// \title I2cDriver.cpp +// \author ethanchee +// \brief cpp file for I2cDriver component implementation class +// ====================================================================== + + +#include +#include +#include "Fw/Types/Assert.hpp" + +namespace Arduino { + + // ---------------------------------------------------------------------- + // Construction, initialization, and destruction + // ---------------------------------------------------------------------- + + I2cDriver :: + I2cDriver( + const char *const compName + ) : I2cDriverComponentBase(compName), + m_port_pointer(static_cast(NULL)) + { + + } + + I2cDriver :: + ~I2cDriver() + { + + } + + // ---------------------------------------------------------------------- + // Handler implementations for user-defined typed input ports + // ---------------------------------------------------------------------- + + Drv::I2cStatus I2cDriver :: + read_handler( + const NATIVE_INT_TYPE portNum, + U32 addr, + Fw::Buffer &serBuffer + ) + { + // Ensure buffer is not a nullptr + FW_ASSERT(serBuffer.getData()); + + return read_data(addr, serBuffer); + } + + Drv::I2cStatus I2cDriver :: + write_handler( + const NATIVE_INT_TYPE portNum, + U32 addr, + Fw::Buffer &serBuffer + ) + { + // Ensure buffer is not a nullptr + FW_ASSERT(serBuffer.getData()); + + return write_data(addr, serBuffer); + } + +} // end namespace Arduino diff --git a/Arduino/Drv/I2cDriver/I2cDriver.fpp b/Arduino/Drv/I2cDriver/I2cDriver.fpp new file mode 100644 index 0000000..cd6ce30 --- /dev/null +++ b/Arduino/Drv/I2cDriver/I2cDriver.fpp @@ -0,0 +1,10 @@ +module Arduino { + @ I2C Driver for Arduino + passive component I2cDriver { + + guarded input port write: Drv.I2c + + guarded input port read: Drv.I2c + + } +} diff --git a/Arduino/Drv/I2cDriver/I2cDriver.hpp b/Arduino/Drv/I2cDriver/I2cDriver.hpp new file mode 100644 index 0000000..127a083 --- /dev/null +++ b/Arduino/Drv/I2cDriver/I2cDriver.hpp @@ -0,0 +1,80 @@ +// ====================================================================== +// \title I2cDriver.hpp +// \author ethanchee +// \brief hpp file for I2cDriver component implementation class +// ====================================================================== + +#ifndef I2cDriver_HPP +#define I2cDriver_HPP + +#include "Arduino/Drv/I2cDriver/I2cDriverComponentAc.hpp" +#include + +namespace Arduino { + + class I2cDriver : + public I2cDriverComponentBase + { + + public: + + // ---------------------------------------------------------------------- + // Construction, initialization, and destruction + // ---------------------------------------------------------------------- + + //! Construct object I2cDriver + //! + I2cDriver( + const char *const compName /*!< The component name*/ + ); + + void open(TwoWire* wire); + void close(); + + //! Destroy object I2cDriver + //! + ~I2cDriver(); + + PRIVATE: + + //! Read the actual data + Drv::I2cStatus read_data(U32 addr, Fw::Buffer& fwBuffer); + //! Write the actual data + Drv::I2cStatus write_data(U32 addr, Fw::Buffer& fwBuffer); + + // ---------------------------------------------------------------------- + // Handler implementations for user-defined typed input ports + // ---------------------------------------------------------------------- + + //! Handler implementation for read + //! + Drv::I2cStatus read_handler( + const NATIVE_INT_TYPE portNum, /*!< The port number*/ + U32 addr, /*!< + I2C slave device address + */ + Fw::Buffer &serBuffer /*!< + Buffer with data to read/write to/from + */ + ); + + //! Handler implementation for write + //! + Drv::I2cStatus write_handler( + const NATIVE_INT_TYPE portNum, /*!< The port number*/ + U32 addr, /*!< + I2C slave device address + */ + Fw::Buffer &serBuffer /*!< + Buffer with data to read/write to/from + */ + ); + + //! Stores the open wire port, POINTER_CAST so Linux and Ardunio may use different types + void* m_port_pointer; + + }; + +} // end namespace Arduino + +#endif diff --git a/Arduino/Drv/I2cDriver/I2cDriverArduino.cpp b/Arduino/Drv/I2cDriver/I2cDriverArduino.cpp new file mode 100644 index 0000000..e8a33c9 --- /dev/null +++ b/Arduino/Drv/I2cDriver/I2cDriverArduino.cpp @@ -0,0 +1,56 @@ +// ====================================================================== +// \title I2cDriver.cpp +// \author ethanchee +// \brief cpp file for I2cDriver component implementation class +// ====================================================================== + + +#include +#include +#include "Fw/Types/Assert.hpp" + +namespace Arduino { + + void I2cDriver::open(TwoWire *wire) { + FW_ASSERT(wire != nullptr); + m_port_pointer = wire; + wire->begin(); + } + + void I2cDriver::close() { + FW_ASSERT(m_port_pointer != 0); + TwoWire* wire_ptr = reinterpret_cast(m_port_pointer); + wire_ptr->end(); + } + + Drv::I2cStatus I2cDriver::read_data(U32 addr, Fw::Buffer& fwBuffer) + { + TwoWire* wire_ptr = reinterpret_cast(m_port_pointer); + + wire_ptr->requestFrom(static_cast(addr), fwBuffer.getSize()); + + int byte = 0; + NATIVE_UINT_TYPE count = 0; + U8* raw_data = reinterpret_cast(fwBuffer.getData()); + while ((wire_ptr->available() > 0) && (count < fwBuffer.getSize()) && ((byte = wire_ptr->read()) != -1)) { + *(raw_data + count) = static_cast(byte); + count++; + } + fwBuffer.setSize(count); + + return Drv::I2cStatus::I2C_OK; + } + + Drv::I2cStatus I2cDriver::write_data(U32 addr, Fw::Buffer& fwBuffer) + { + FW_ASSERT(m_port_pointer != 0); + TwoWire* wire_ptr = reinterpret_cast(m_port_pointer); + + wire_ptr->beginTransmission(static_cast(addr)); + wire_ptr->write(reinterpret_cast(fwBuffer.getData()), fwBuffer.getSize()); + wire_ptr->endTransmission(); + + return Drv::I2cStatus::I2C_OK; + } + +} // end namespace Arduino diff --git a/Arduino/Drv/I2cDriver/I2cDriverLinux.cpp b/Arduino/Drv/I2cDriver/I2cDriverLinux.cpp new file mode 100644 index 0000000..f9cd315 --- /dev/null +++ b/Arduino/Drv/I2cDriver/I2cDriverLinux.cpp @@ -0,0 +1,27 @@ +// ====================================================================== +// \title I2cDriver.cpp +// \author ethanchee +// \brief cpp file for I2cDriver component implementation class +// ====================================================================== + + +#include +#include + +namespace Arduino { + + void I2cDriver::close() { + + } + + Drv::I2cStatus I2cDriver::read_data(U32 addr, Fw::Buffer& fwBuffer) + { + return Drv::I2cStatus::I2C_OK; + } + + Drv::I2cStatus I2cDriver::write_data(U32 addr, Fw::Buffer& fwBuffer) + { + return Drv::I2cStatus::I2C_OK; + } + +} // end namespace Arduino diff --git a/Arduino/Drv/StreamDriver/CMakeLists.txt b/Arduino/Drv/StreamDriver/CMakeLists.txt new file mode 100644 index 0000000..a1eab19 --- /dev/null +++ b/Arduino/Drv/StreamDriver/CMakeLists.txt @@ -0,0 +1,17 @@ +#### +# F prime CMakeLists.txt: +# +# SOURCE_FILES: combined list of source and autocoding diles +# MOD_DEPS: (optional) module dependencies +# +#### +set(SOURCE_FILES + "${CMAKE_CURRENT_LIST_DIR}/StreamDriver.fpp" + "${CMAKE_CURRENT_LIST_DIR}/StreamDriver.cpp" +) +if(FPRIME_ARDUINO) + list(APPEND SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/StreamDriverArduino.cpp") +else() + list(APPEND SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/StreamDriverLinux.cpp") +endif() +register_fprime_module() diff --git a/Arduino/Drv/StreamDriver/StreamDriver.cpp b/Arduino/Drv/StreamDriver/StreamDriver.cpp new file mode 100644 index 0000000..203fc7e --- /dev/null +++ b/Arduino/Drv/StreamDriver/StreamDriver.cpp @@ -0,0 +1,39 @@ +// ====================================================================== +// \title StreamDriverImpl.cpp +// \author lestarch +// \brief cpp file for StreamDriver component implementation class +// ====================================================================== + +#include +#include "Fw/Types/BasicTypes.hpp" + +namespace Arduino { + +// ---------------------------------------------------------------------- +// Construction, initialization, and destruction +// ---------------------------------------------------------------------- + +StreamDriver ::StreamDriver(const char* compName) + : StreamDriverComponentBase(compName), + m_port_number(0), + m_port_pointer(static_cast(NULL)) {} + +StreamDriver ::~StreamDriver(void) {} + +// ---------------------------------------------------------------------- +// Handler implementations for user-defined typed input ports +// ---------------------------------------------------------------------- + +Drv::SendStatus StreamDriver ::send_handler(const NATIVE_INT_TYPE portNum, Fw::Buffer& fwBuffer) { + write_data(fwBuffer); + deallocate_out(0, fwBuffer); + return Drv::SendStatus::SEND_OK; +} + +void StreamDriver ::schedIn_handler(const NATIVE_INT_TYPE portNum, NATIVE_UINT_TYPE context) { + Fw::Buffer recv_buffer = this->allocate_out(0, SERIAL_BUFFER_SIZE); + read_data(recv_buffer); + recv_out(0, recv_buffer, Drv::RecvStatus::RECV_OK); +} + +} // namespace Arduino diff --git a/Arduino/Drv/StreamDriver/StreamDriver.fpp b/Arduino/Drv/StreamDriver/StreamDriver.fpp new file mode 100644 index 0000000..ed82f6f --- /dev/null +++ b/Arduino/Drv/StreamDriver/StreamDriver.fpp @@ -0,0 +1,23 @@ +module Arduino { + + passive component StreamDriver { + + @ Polling for receiving data + sync input port schedIn: Svc.Sched + + @ Indicates the driver has connected to the UART device + output port ready: Drv.ByteStreamReady + + @Allocate new buffer + output port allocate: Fw.BufferGet + + @return the allocated buffer + output port deallocate: Fw.BufferSend + + @ Takes data to transmit out the UART device + guarded input port send: Drv.ByteStreamSend + + @ Takes data to transmit out the UART device + output port $recv: Drv.ByteStreamRecv + } +} diff --git a/Arduino/Drv/StreamDriver/StreamDriver.hpp b/Arduino/Drv/StreamDriver/StreamDriver.hpp new file mode 100644 index 0000000..2acb79e --- /dev/null +++ b/Arduino/Drv/StreamDriver/StreamDriver.hpp @@ -0,0 +1,68 @@ +// ====================================================================== +// \title StreamDriverImpl.hpp +// \author lestarch +// \brief hpp file for StreamDriver component implementation class +// ====================================================================== + +#ifndef StreamDriver_HPP +#define StreamDriver_HPP + +#include "Arduino/Drv/StreamDriver/StreamDriverComponentAc.hpp" +#include "Os/Task.hpp" +#include + +namespace Arduino { +// Allow for setting serial ports on linux from the inputs +#ifndef ARDUINO +extern char** SERIAL_PORT; +#endif + +class StreamDriver : public StreamDriverComponentBase { + public: + const static FwSizeType SERIAL_BUFFER_SIZE = 64; // Maximum Arduino buffer size + // ---------------------------------------------------------------------- + // Construction, initialization, and destruction + // ---------------------------------------------------------------------- + + //! Construct object StreamDriver + //! + StreamDriver(const char* compName /*!< The component name*/ + ); + + //! Destroy object StreamDriver + //! + ~StreamDriver(void); + + //! Configure this port + //! + void configure(Stream* streamDriver); + + private: + //! Read the actual data + void read_data(Fw::Buffer& fwBuffer); + //! Write the actual data + void write_data(Fw::Buffer& fwBuffer); + // ---------------------------------------------------------------------- + // Handler implementations for user-defined typed input ports + // ---------------------------------------------------------------------- + + //! Handler implementation for send + //! + Drv::SendStatus send_handler(const NATIVE_INT_TYPE portNum, /*!< The port number*/ + Fw::Buffer& fwBuffer) override; + + //! Handler implementation for schedIn + //! + void schedIn_handler(const NATIVE_INT_TYPE portNum, /*!< The port number*/ + NATIVE_UINT_TYPE context /*!< The call order*/ + ); + + //! Port number to open + NATIVE_UINT_TYPE m_port_number; + //! Stores the open stream port, POINTER_CAST so Linux and Ardunio may use different types + void* m_port_pointer; +}; + +} // end namespace Arduino + +#endif diff --git a/Arduino/Drv/StreamDriver/StreamDriverArduino.cpp b/Arduino/Drv/StreamDriver/StreamDriverArduino.cpp new file mode 100644 index 0000000..0d7b4cc --- /dev/null +++ b/Arduino/Drv/StreamDriver/StreamDriverArduino.cpp @@ -0,0 +1,44 @@ +// ====================================================================== +// \title StreamDriverImpl.cpp +// \author lestarch +// \brief cpp file for StreamDriver component implementation class +// ====================================================================== + +#include +#include +#include +#include "Fw/Types/BasicTypes.hpp" +#include "Fw/Types/Assert.hpp" + +namespace Arduino { + +void StreamDriver::configure(Stream* streamDriver) { + FW_ASSERT(streamDriver != nullptr); + m_port_pointer = streamDriver; + if (this->isConnected_ready_OutputPort(0)) { + this->ready_out(0); + } +} + +// ---------------------------------------------------------------------- +// Handler implementations for user-defined typed input ports +// ---------------------------------------------------------------------- + +void StreamDriver ::write_data(Fw::Buffer& fwBuffer) { + FW_ASSERT(m_port_pointer != 0); + reinterpret_cast(m_port_pointer) + ->write(reinterpret_cast(fwBuffer.getData()), fwBuffer.getSize()); +} + +void StreamDriver ::read_data(Fw::Buffer& fwBuffer) { + Stream* stream_ptr = reinterpret_cast(m_port_pointer); + int byte = 0; + NATIVE_UINT_TYPE count = 0; + U8* raw_data = reinterpret_cast(fwBuffer.getData()); + while ((stream_ptr->available() > 0) && (count < fwBuffer.getSize()) && ((byte = stream_ptr->read()) != -1)) { + *(raw_data + count) = static_cast(byte); + count++; + } + fwBuffer.setSize(count); +} +} // namespace Arduino diff --git a/Arduino/Drv/StreamDriver/StreamDriverLinux.cpp b/Arduino/Drv/StreamDriver/StreamDriverLinux.cpp new file mode 100644 index 0000000..7856064 --- /dev/null +++ b/Arduino/Drv/StreamDriver/StreamDriverLinux.cpp @@ -0,0 +1,50 @@ +// ====================================================================== +// \title StreamDriverImpl.cpp +// \author lestarch +// \brief cpp file for StreamDriver component implementation class +// ====================================================================== + +#include +#include +#include +#include +#include "Fw/Types/BasicTypes.hpp" + +#define SERIAL_FILE_LINUX_TMPL "/dev/pts/%d" + +namespace Arduino { +char** SERIAL_PORT = NULL; +void StreamDriver ::init(const FwIndexType port_number, const PlatformIntType baud) { + char name[1024]; + StreamDriverComponentBase::init(instance); + // NULL ports use above template + if (SERIAL_PORT == NULL) { + snprintf(name, 1024, SERIAL_FILE_LINUX_TMPL, m_port_number + 20); + SERIAL_PORT = reinterpret_cast(&name); + } + printf("Opening serial port: '%s'\n", *SERIAL_PORT); + m_port_pointer = open(*SERIAL_PORT, O_RDWR); + int flags = fcntl(m_port_pointer, F_GETFL, 0); + fcntl(m_port_pointer, F_SETFL, flags | O_NONBLOCK); +} + +// ---------------------------------------------------------------------- +// Handler implementations for user-defined typed input ports +// ---------------------------------------------------------------------- + +void StreamDriver ::write_data(Fw::Buffer& fwBuffer) { + if (m_port_pointer != -1) { + write(m_port_pointer, reinterpret_cast(fwBuffer.getdata()), fwBuffer.getsize()); + } +} + +void StreamDriver ::read_data(Fw::Buffer& fwBuffer) { + NATIVE_INT_TYPE result; + if ((m_port_pointer != -1) && + (-1 != (result = read(m_port_pointer, reinterpret_cast(fwBuffer.getdata()), fwBuffer.getsize())))) { + fwBuffer.setsize(result); + } else { + fwBuffer.setsize(0); + } +} +} // namespace Arduino diff --git a/cmake/platform/FprimeArduino.hpp b/cmake/platform/FprimeArduino.hpp index cb9e98e..c622f73 100644 --- a/cmake/platform/FprimeArduino.hpp +++ b/cmake/platform/FprimeArduino.hpp @@ -22,7 +22,8 @@ enum ARDUINO_DEFINITION_REMAP { DEF_LOW = LOW, DEF_INPUT = INPUT, DEF_OUTPUT = OUTPUT, - DEF_INPUT_PULLUP = INPUT_PULLUP + DEF_INPUT_PULLUP = INPUT_PULLUP, + DEF_LED_BUILTIN = LED_BUILTIN }; }; #undef INPUT @@ -30,6 +31,7 @@ enum ARDUINO_DEFINITION_REMAP { #undef INPUT_PULLUP #undef HIGH #undef LOW - +#undef LED_BUILTIN +#undef SERIAL_BUFFER_SIZE #endif // ARDUINOBLINK_FPRIMEARDUINO_HPP diff --git a/cmake/toolchain/featherM0.cmake b/cmake/toolchain/featherM0.cmake index 7dfcb22..bfa32f7 100644 --- a/cmake/toolchain/featherM0.cmake +++ b/cmake/toolchain/featherM0.cmake @@ -9,7 +9,7 @@ set(CMAKE_SYSTEM_NAME "ArduinoFw") set(CMAKE_SYSTEM_PROCESSOR "arm") set(CMAKE_CROSSCOMPILING 1) -set(FPRIME_USE_BAREMETAL_SCHEDULER OFF) +set(FPRIME_USE_BAREMETAL_SCHEDULER ON) set(ARDUINO_BUILD_PROPERTIES) set(ARDUINO_FQBN "adafruit:samd:adafruit_feather_m0") diff --git a/cmake/toolchain/featherrp2040rfm.cmake b/cmake/toolchain/featherrp2040rfm.cmake new file mode 100644 index 0000000..4c1c4ab --- /dev/null +++ b/cmake/toolchain/featherrp2040rfm.cmake @@ -0,0 +1,15 @@ +#### +# thingplusrp2040.cmake: +# +# RP2040 support. +#### +# System setup for Teensyduino +set(CMAKE_SYSTEM_NAME "ArduinoFw") +set(CMAKE_SYSTEM_PROCESSOR "arm") +set(CMAKE_CROSSCOMPILING 1) +set(FPRIME_USE_BAREMETAL_SCHEDULER ON) + + +set(ARDUINO_FQBN "rp2040:rp2040:adafruit_feather_rfm") +# Run the base arduino setup which should detect settings! +include("${CMAKE_CURRENT_LIST_DIR}/support/arduino-support.cmake") diff --git a/cmake/toolchain/support/arduino-support.cmake b/cmake/toolchain/support/arduino-support.cmake index c46a007..5ad633f 100644 --- a/cmake/toolchain/support/arduino-support.cmake +++ b/cmake/toolchain/support/arduino-support.cmake @@ -55,6 +55,7 @@ function(set_arduino_build_settings) # Flags for each of the tools read_json(ARDUINO_AR_FLAGS "${WRAPPER_OUTPUT}" flags AR) read_json(CMAKE_EXE_LINKER_FLAGS_INIT "${WRAPPER_OUTPUT}" flags LINKER_EXE) + string(REPLACE ".map" "link.map" CMAKE_EXE_LINKER_FLAGS_INIT "${CMAKE_EXE_LINKER_FLAGS_INIT}") # Convert lists to the INIT " " separated format foreach(LIST_VARIABLE IN ITEMS @@ -65,12 +66,11 @@ function(set_arduino_build_settings) read_json(INCLUDES "${WRAPPER_OUTPUT}" includes CXX) include_directories(${INCLUDES}) - if (NOT TARGET fprime_arduino_base_libraries) - add_library(fprime_arduino_base_libraries INTERFACE) - add_dependencies(fprime_arduino_base_libraries core fprime_arduino_loose_object_library) - target_link_libraries(fprime_arduino_base_libraries INTERFACE core fprime_arduino_loose_object_library fprime_arduino_patcher) + if (NOT TARGET fprime_arduino_libraries) + add_library(fprime_arduino_libraries INTERFACE) endif() - link_libraries(fprime_arduino_base_libraries) + link_libraries(fprime_arduino_libraries) + link_libraries(fprime_arduino_patcher) # Setup misc commands SET(CMAKE_C_ARCHIVE_CREATE " ${ARDUINO_AR_FLAGS} ") SET(CMAKE_CXX_ARCHIVE_CREATE " ${ARDUINO_AR_FLAGS} ") @@ -101,6 +101,8 @@ function(target_use_arduino_libraries) list(APPEND ARDUINO_LIBRARY_LIST_LOCAL ${ARGN}) list(REMOVE_DUPLICATES ARDUINO_LIBRARY_LIST_LOCAL) set_property(GLOBAL PROPERTY ARDUINO_LIBRARY_LIST ${ARDUINO_LIBRARY_LIST_LOCAL}) + list(APPEND MOD_DEPS fprime_arduino_libraries) + set(MOD_DEPS "${MOD_DEPS}" PARENT_SCOPE) endfunction(target_use_arduino_libraries) #### @@ -111,7 +113,7 @@ endfunction(target_use_arduino_libraries) #### function(setup_arduino_libraries) get_property(ARDUINO_LIBRARY_LIST_LOCAL GLOBAL PROPERTY ARDUINO_LIBRARY_LIST) - prevent_prescan(${ARDUINO_LIBRARY_LIST_LOCAL} fprime-arduino-patcher core fprime_arduino_loose_object_library) + prevent_prescan(${ARDUINO_LIBRARY_LIST_LOCAL} fprime_arduino_patcher fprime_arduino_loose_object_library) run_arduino_wrapper( -b "${ARDUINO_FQBN}" --properties ${ARDUINO_BUILD_PROPERTIES} -j "${ARDUINO_WRAPPER_JSON_OUTPUT}" @@ -123,36 +125,45 @@ function(setup_arduino_libraries) read_json(LIBRARIES "${WRAPPER_OUTPUT}" libraries) read_json(OBJECTS "${WRAPPER_OUTPUT}" objects) - # Setup an extra arduino libraries - add_library(fprime_arduino_patcher ${EXTRA_LIBRARY_SOURCE}) - add_library(fprime_arduino_loose_object_library OBJECT IMPORTED GLOBAL) - set_target_properties(fprime_arduino_loose_object_library PROPERTIES IMPORTED_OBJECTS "${OBJECTS}") - target_include_directories(fprime_arduino_loose_object_library INTERFACE ${INCLUDES}) + # Setup arduino missing C/C++ function patch library + if (NOT TARGET fprime_arduino_patcher) + add_library(fprime_arduino_patcher ${EXTRA_LIBRARY_SOURCE}) + get_target_property(TARGET_LIBRARIES fprime_arduino_patcher LINK_LIBRARIES) + LIST(REMOVE_ITEM TARGET_LIBRARIES fprime_arduino_libraries) + LIST(REMOVE_ITEM TARGET_LIBRARIES fprime_arduino_patcher) + set_property(TARGET fprime_arduino_patcher PROPERTY LINK_LIBRARIES ${TARGET_LIBRARIES}) + endif() + + # Setup library to capture loose object files from arduino-cli compile + if (NOT TARGET fprime_arduino_loose_object_library) + add_library(fprime_arduino_loose_object_library OBJECT IMPORTED GLOBAL) + set_target_properties(fprime_arduino_loose_object_library PROPERTIES IMPORTED_OBJECTS "${OBJECTS}") + target_include_directories(fprime_arduino_loose_object_library INTERFACE ${INCLUDES}) + target_link_libraries(fprime_arduino_libraries INTERFACE fprime_arduino_loose_object_library) + endif() # Import all of the libraries including core - list(APPEND ARDUINO_LIBRARY_LIST_LOCAL core) - message(STATUS "${LIBRARIES}") - foreach(NEEDED_LIBRARY IN LISTS ARDUINO_LIBRARY_LIST_LOCAL) - set(FOUND OFF) - foreach(BUILT_LIBRARY IN LISTS LIBRARIES) - ends_with(IS_NEEDLE "${BUILT_LIBRARY}" "${NEEDED_LIBRARY}.a") - # If a matching library was built, use it - if (IS_NEEDLE) - message(STATUS "Adding Arduino Library: ${NEEDED_LIBRARY}") - add_library(${NEEDED_LIBRARY} STATIC IMPORTED GLOBAL) - set_target_properties(${NEEDED_LIBRARY} PROPERTIES IMPORTED_LOCATION "${BUILT_LIBRARY}") - set(FOUND ON) - break() + foreach(BUILT_LIBRARY IN LISTS LIBRARIES) + string(SUBSTRING "${BUILT_LIBRARY}" 0 1 MAYBE_DASH) + if (MAYBE_DASH STREQUAL "-") + message(STATUS "Adding Arduino Library Flag: ${BUILT_LIBRARY}") + target_link_libraries(fprime_arduino_libraries INTERFACE ${BUILT_LIBRARY}) + else() + get_filename_component(LIBRARY_BASE "${BUILT_LIBRARY}" NAME_WE) + + # Add new imported library + if (NOT TARGET ${LIBRARY_BASE}) + message(STATUS "Adding Arduino Library: ${LIBRARY_BASE}") + add_library(${LIBRARY_BASE} STATIC IMPORTED GLOBAL) + set_target_properties(${LIBRARY_BASE} PROPERTIES IMPORTED_LOCATION "${BUILT_LIBRARY}") + add_dependencies(${LIBRARY_BASE} fprime_arduino_loose_object_library) + target_link_libraries(${LIBRARY_BASE} INTERFACE fprime_arduino_loose_object_library) + + # Setup detected dependencies to the interface library + add_dependencies(fprime_arduino_libraries ${LIBRARY_BASE}) + target_link_libraries(fprime_arduino_libraries INTERFACE ${LIBRARY_BASE}) endif() - endforeach() - # If the matching library was not found, create an interface to the object library - if (NOT FOUND) - message(STATUS "Adding Arduino Interface: ${NEEDED_LIBRARY}") - add_library(${NEEDED_LIBRARY} INTERFACE) endif() - # Add dependencies and header information - add_dependencies(${NEEDED_LIBRARY} fprime_arduino_loose_object_library) - target_link_libraries(${NEEDED_LIBRARY} INTERFACE fprime_arduino_loose_object_library) endforeach() set(WRAPPER_OUTPUT "${WRAPPER_OUTPUT}" PARENT_SCOPE) endfunction(setup_arduino_libraries) @@ -162,32 +173,27 @@ endfunction(setup_arduino_libraries) # # Attach the arduino libraries to a given target (e.g. executable/deployment). Additionally sets up finalization steps # for the executable (e.g. building hex files, calculating size, etc). -# -# Args: -# TARGET_NAME: target name to setup and build a hex file #### -function(finalize_arduino_executable TARGET_NAME) +function(finalize_arduino_executable) setup_arduino_libraries() prevent_prescan() - # Add link dependency on target_link_libraries( - "${TARGET_NAME}" - PUBLIC $ fprime_arduino_patcher + "${FPRIME_CURRENT_MODULE}" + PUBLIC fprime_arduino_libraries $ ) read_json(POST_COMMANDS "${WRAPPER_OUTPUT}" post) set(COMMAND_SET_ARGUMENTS) foreach(COMMAND IN LISTS POST_COMMANDS) - string(REPLACE "" "$" COMMAND_WITH_INPUT "${COMMAND}") - string(REPLACE "" "$" COMMAND_WITH_INPUT "${COMMAND_WITH_INPUT}") - string(REPLACE "" "$" COMMAND_WITH_INPUT "${COMMAND_WITH_INPUT}") + string(REPLACE "" "$" COMMAND_WITH_INPUT "${COMMAND}") + string(REPLACE "" "$" COMMAND_WITH_INPUT "${COMMAND_WITH_INPUT}") + string(REPLACE "" "$" COMMAND_WITH_INPUT "${COMMAND_WITH_INPUT}") string(REPLACE " " ";" COMMAND_WITH_INPUT "${COMMAND_WITH_INPUT}") - list(APPEND COMMAND_SET_ARGUMENTS COMMAND ${COMMAND_WITH_INPUT}) + list(APPEND COMMAND_SET_ARGUMENTS COMMAND ${COMMAND_WITH_INPUT} || true) endforeach() - message(STATUS ">>>>>${COMMAND_SET_ARGUMENTS}") - list(APPEND COMMAND_SET_ARGUMENTS COMMAND "${CMAKE_COMMAND}" "-E" "copy_if_different" "$*" "${CMAKE_INSTALL_PREFIX}/${TOOLCHAIN_NAME}/bin") + list(APPEND COMMAND_SET_ARGUMENTS COMMAND "${CMAKE_COMMAND}" "-E" "copy_if_different" "$*" "${CMAKE_INSTALL_PREFIX}/${TOOLCHAIN_NAME}/${FPRIME_CURRENT_MODULE}/bin") add_custom_command( - TARGET "${TARGET_NAME}" POST_BUILD ${COMMAND_SET_ARGUMENTS} + TARGET "${FPRIME_CURRENT_MODULE}" POST_BUILD ${COMMAND_SET_ARGUMENTS} ) endfunction(finalize_arduino_executable) diff --git a/cmake/toolchain/support/arduino-wrapper.cmake b/cmake/toolchain/support/arduino-wrapper.cmake index a5c495c..167091e 100644 --- a/cmake/toolchain/support/arduino-wrapper.cmake +++ b/cmake/toolchain/support/arduino-wrapper.cmake @@ -29,7 +29,6 @@ function(ends_with OUTPUT_VAR STRING SUFFIX) endif() endfunction(ends_with) - #### # Function `run_arduino_wrapper`: # diff --git a/cmake/toolchain/support/sources/extras.cpp b/cmake/toolchain/support/sources/extras.cpp index 07b6897..17f9c96 100644 --- a/cmake/toolchain/support/sources/extras.cpp +++ b/cmake/toolchain/support/sources/extras.cpp @@ -1,4 +1,6 @@ #include + +#ifdef FPRIME_ARUDINO_SYNTHETIC_WRITE extern "C" { #include int _write( int handle, char *buf, int count) { @@ -11,9 +13,13 @@ int _write( int handle, char *buf, int count) { return count; } }; +#endif + +#ifdef FPRIME_ARUDINO_SYNTHETIC_NEW_NOTHROW #include namespace std { const std::nothrow_t nothrow; } void* operator new(unsigned int size, std::nothrow_t const&){ return malloc(size); } void* operator new[](unsigned int size, std::nothrow_t const&){ return malloc(size); } +#endif diff --git a/cmake/toolchain/teensy32.cmake b/cmake/toolchain/teensy32.cmake index 86197ea..8aad65a 100644 --- a/cmake/toolchain/teensy32.cmake +++ b/cmake/toolchain/teensy32.cmake @@ -1,5 +1,5 @@ #### -# Teensyduino.cmake: +# teensy32.cmake: # # Toolchain file setup for building F prime for the Teensy hardware platform. This must, by definition, include the # Arduino framework in order to ensure that basic functions of the Teensy hardware platform are available. This @@ -14,5 +14,6 @@ set(ARDUINO_BUILD_PROPERTIES) # Teensy 31 is used to compile for the teensy 3.2 board set(ARDUINO_FQBN "teensy:avr:teensy31") +add_compile_options(-DFPRIME_ARUDINO_SYNTHETIC_WRITE -DFPRIME_ARUDINO_SYNTHETIC_NEW_NOTHROW) # Run the base arduino setup which should detect settings! include("${CMAKE_CURRENT_LIST_DIR}/support/arduino-support.cmake") diff --git a/cmake/toolchain/teensy40.cmake b/cmake/toolchain/teensy40.cmake index 2346520..89a605d 100644 --- a/cmake/toolchain/teensy40.cmake +++ b/cmake/toolchain/teensy40.cmake @@ -14,5 +14,6 @@ set(ARDUINO_BUILD_PROPERTIES) # Teensy 40 is used to compile for the teensy 4.0 board set(ARDUINO_FQBN "teensy:avr:teensy40") +add_compile_options(-DFPRIME_ARUDINO_SYNTHETIC_WRITE -DFPRIME_ARUDINO_SYNTHETIC_NEW_NOTHROW) # Run the base arduino setup which should detect settings! include("${CMAKE_CURRENT_LIST_DIR}/support/arduino-support.cmake") diff --git a/cmake/toolchain/teensy41.cmake b/cmake/toolchain/teensy41.cmake index 795d8ae..8eff27e 100644 --- a/cmake/toolchain/teensy41.cmake +++ b/cmake/toolchain/teensy41.cmake @@ -14,5 +14,6 @@ set(ARDUINO_BUILD_PROPERTIES) # Teensy 40 is used to compile for the teensy 4.1 board set(ARDUINO_FQBN "teensy:avr:teensy41") +add_compile_options(-DFPRIME_ARUDINO_SYNTHETIC_WRITE -DFPRIME_ARUDINO_SYNTHETIC_NEW_NOTHROW) # Run the base arduino setup which should detect settings! include("${CMAKE_CURRENT_LIST_DIR}/support/arduino-support.cmake") diff --git a/cmake/toolchain/thingplusrp2040.cmake b/cmake/toolchain/thingplusrp2040.cmake new file mode 100644 index 0000000..9c657a8 --- /dev/null +++ b/cmake/toolchain/thingplusrp2040.cmake @@ -0,0 +1,15 @@ +#### +# thingplusrp2040.cmake: +# +# RP2040 support. +#### +# System setup for Teensyduino +set(CMAKE_SYSTEM_NAME "ArduinoFw") +set(CMAKE_SYSTEM_PROCESSOR "arm") +set(CMAKE_CROSSCOMPILING 1) +set(FPRIME_USE_BAREMETAL_SCHEDULER ON) + + +set(ARDUINO_FQBN "rp2040:rp2040:sparkfun_thingplusrp2040") +# Run the base arduino setup which should detect settings! +include("${CMAKE_CURRENT_LIST_DIR}/support/arduino-support.cmake") diff --git a/fprime-arduino.cmake b/fprime-arduino.cmake index 5a72b6c..01c2a74 100644 --- a/fprime-arduino.cmake +++ b/fprime-arduino.cmake @@ -1,3 +1,4 @@ +restrict_platforms(ArduinoFw) starts_with(IS_MBED "${ARDUINO_FQBN}" "arduino:mbed") if (IS_MBED) set(CMAKE_CXX_STANDARD 14) @@ -6,6 +7,8 @@ endif() add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Arduino/Os") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Arduino/ArduinoTime") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Arduino/Drv/GpioDriver") -add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Arduino/Drv/SerialDriver") +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Arduino/Drv/StreamDriver") +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Arduino/Drv/I2cDriver") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Arduino/Drv/HardwareRateDriver") +setup_arduino_libraries()