diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 956cc9fe..8d4ed693 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,33 +12,30 @@ jobs: - name: Checkout uses: actions/checkout@v4 with: - path: Arduino-Zephyr-API + path: ArduinoCore-zephyr - name: Initialize - working-directory: Arduino-Zephyr-API + working-directory: ArduinoCore-zephyr run: | - west init -m https://github.com/zephyrproject-rtos/gsoc-2022-arduino-core.git + mkdir build && cd build + west init -m https://github.com/arduino/ArduinoCore-zephyr.git west update - git clone https://github.com/arduino/ArduinoCore-API.git ArduinoCore-API - cp -r ArduinoCore-API/api modules/lib/Arduino-Zephyr-API/cores/arduino/. + rm -rf modules/lib/ArduinoCore-zephyr/* + cp -r ../* modules/lib/ArduinoCore-zephyr || true + rm modules/lib/ArduinoCore-zephyr/cores/arduino/api + cp -r modules/lib/ArduinoCore-API/api modules/lib/ArduinoCore-zephyr/cores/arduino/api - name: Build fade - working-directory: Arduino-Zephyr-API + working-directory: ArduinoCore-zephyr/build run: | - west build -p -b arduino_nano_33_ble_sense samples/fade + west build -p -b arduino_nano_33_ble//sense ../samples/fade - name: Build i2cdemo - working-directory: Arduino-Zephyr-API + working-directory: ArduinoCore-zephyr/build run: | - west build -p -b arduino_nano_33_ble_sense samples/i2cdemo + west build -p -b ek_ra8d1 ../samples/i2cdemo - name: Build adc - working-directory: Arduino-Zephyr-API + working-directory: ArduinoCore-zephyr/build run: | - west build -p -b beagleconnect_freedom samples/analog_input - - - name: Archive firmware - uses: actions/upload-artifact@v2 - with: - name: firmware - path: Arduino-Zephyr-API/build/zephyr/zephyr.* + west build -p -b arduino_nano_33_ble//sense ../samples/analog_input \ No newline at end of file diff --git a/.github/workflows/license_check.yml b/.github/workflows/license_check.yml index bce1fb66..3d14abed 100644 --- a/.github/workflows/license_check.yml +++ b/.github/workflows/license_check.yml @@ -15,7 +15,7 @@ jobs: with: directory-to-scan: 'scan/' - name: Artifact Upload - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v3 with: name: scancode path: ./artifacts diff --git a/CMakeLists.txt b/CMakeLists.txt index cfc60ce2..8ea476a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,15 @@ # SPDX-License-Identifier: Apache-2.0 +string(REPLACE "__" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") + if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/variants/${BOARD}) set(variant_dir variants/${BOARD}) -elseif (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/variants/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}) - set(variant_dir variants/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}) +elseif (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/variants/${NORMALIZED_BOARD_TARGET}) + set(variant_dir variants/${NORMALIZED_BOARD_TARGET}) else() - message(INFO "Variant dir not found: variants/${BOARD}, variants/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}") +if (CONFIG_ARDUINO_API) + message(FATAL_ERROR "Variant dir not found: variants/${BOARD}, variants/${NORMALIZED_BOARD_TARGET}") +endif() endif() if (CONFIG_ARDUINO_API) diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index beefd337..1b7bd953 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -100,6 +101,20 @@ enum digitalPins { enum analogPins { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), adc_pin_gpios, AN_ENUMS) }; +// We provide analogReadResolution APIs +void analogReadResolution(int bits); + +#endif + +#ifdef CONFIG_DAC + +#undef DAC0 +#undef DAC1 +#undef DAC2 +#undef DAC3 +#define DAC_ENUMS(n, p, i) DAC ## i = i, +enum dacPins { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), dac_channels, DAC_ENUMS) NUM_OF_DACS }; + #endif void interrupts(void); @@ -112,6 +127,9 @@ int digitalPinToInterrupt(pin_size_t pin); #define portOutputRegister(x) (x) #define portInputRegister(x) (x) +void analogReadResolution(int bits); +void analogWriteResolution(int bits); + #include #ifdef __cplusplus #include @@ -119,6 +137,7 @@ int digitalPinToInterrupt(pin_size_t pin); #include #include #include +#include // Allow namespace-less operations if Arduino.h is included using namespace arduino; diff --git a/cores/arduino/CMakeLists.txt b/cores/arduino/CMakeLists.txt index ca21a2c3..db1412f3 100644 --- a/cores/arduino/CMakeLists.txt +++ b/cores/arduino/CMakeLists.txt @@ -6,6 +6,8 @@ if(NOT DEFINED ARDUINO_BUILD_PATH) zephyr_sources(zephyrSerial.cpp) zephyr_sources(zephyrCommon.cpp) +zephyr_sources(USB.cpp) +zephyr_sources(itoa.cpp) if(DEFINED CONFIG_ARDUINO_ENTRY) zephyr_sources(main.cpp) diff --git a/cores/arduino/SerialUSB.h b/cores/arduino/SerialUSB.h index 0e67dc71..f26de64a 100644 --- a/cores/arduino/SerialUSB.h +++ b/cores/arduino/SerialUSB.h @@ -31,6 +31,6 @@ class SerialUSB_ : public ZephyrSerial { }; } // namespace arduino -#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) +#if (DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) && CONFIG_USB_CDC_ACM) extern arduino::SerialUSB_ Serial; #endif \ No newline at end of file diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp index 3847d96d..735f2350 100644 --- a/cores/arduino/USB.cpp +++ b/cores/arduino/USB.cpp @@ -4,23 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -// Make PluggableUSB link happy -#include "api/PluggableUSB.h" - -static uint8_t _epBuffer[1]; -void* epBuffer(unsigned int n) { - return &_epBuffer[n]; -}; - -arduino::PluggableUSB_::PluggableUSB_() {} - #include #include #include #include #include -#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) +#if (DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) && CONFIG_USB_CDC_ACM) const struct device *const usb_dev = DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), cdc_acm, 0)); void usb_status_cb(enum usb_dc_status_code cb_status, const uint8_t *param) { diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index 88874624..dff4d605 100644 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -10,14 +10,16 @@ #endif int main(void) { -#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) || DT_NODE_HAS_PROP(DT_PATH(zephyr_user), serials) +#if (DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) && CONFIG_USB_CDC_ACM) Serial.begin(115200); #endif setup(); for (;;) { loop(); + #if (DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) && CONFIG_USB_CDC_ACM) || DT_NODE_HAS_PROP(DT_PATH(zephyr_user), serials) if (arduino::serialEventRun) arduino::serialEventRun(); + #endif } return 0; diff --git a/cores/arduino/overloads.h b/cores/arduino/overloads.h new file mode 100644 index 00000000..5670b270 --- /dev/null +++ b/cores/arduino/overloads.h @@ -0,0 +1,9 @@ +#ifdef CONFIG_DAC + +void analogWrite(enum dacPins pinNumber, int value); + +#endif + +// In c++ mode, we also provide analogReadResolution and analogWriteResolution getters +int analogReadResolution(); +int analogWriteResolution(); \ No newline at end of file diff --git a/cores/arduino/zephyrCommon.cpp b/cores/arduino/zephyrCommon.cpp index 178704cd..4e1ef95a 100644 --- a/cores/arduino/zephyrCommon.cpp +++ b/cores/arduino/zephyrCommon.cpp @@ -163,7 +163,7 @@ size_t pwm_pin_index(pin_size_t pinNumber) { DT_PHA_BY_IDX(DT_PATH(zephyr_user), p, i, pin)), #define ADC_CH_CFG(n,p,i) arduino_adc[i].channel_cfg, -const struct adc_dt_spec arduino_adc[] = +static const struct adc_dt_spec arduino_adc[] = { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels, ADC_DT_SPEC) }; /* io-channel-pins node provides a mapping digital pin numbers to adc channels */ @@ -184,6 +184,28 @@ size_t analog_pin_index(pin_size_t pinNumber) { #endif //CONFIG_ADC +#ifdef CONFIG_DAC + +#if (DT_NODE_HAS_PROP(DT_PATH(zephyr_user), dac)) + +#define DAC_NODE DT_PHANDLE(DT_PATH(zephyr_user), dac) +#define DAC_RESOLUTION DT_PROP(DT_PATH(zephyr_user), dac_resolution) +static const struct device *const dac_dev = DEVICE_DT_GET(DAC_NODE); + +#define DAC_CHANNEL_DEFINE(n, p, i) \ + { \ + .channel_id = DT_PROP_BY_IDX(n, p, i), \ + .resolution = DAC_RESOLUTION, \ + .buffered = true, \ + }, + +static const struct dac_channel_cfg dac_ch_cfg[] = + { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), dac_channels, DAC_CHANNEL_DEFINE) }; + +#endif + +#endif //CONFIG_DAC + static unsigned int irq_key; static bool interrupts_disabled = false; } @@ -271,25 +293,37 @@ void delay(unsigned long ms) { k_sleep(K_MSEC(ms)); } void delayMicroseconds(unsigned int us) { k_sleep(K_USEC(us)); } unsigned long micros(void) { - return k_cyc_to_us_floor32(k_cycle_get_32()); + return k_cyc_to_us_floor32(k_cycle_get_64()); } unsigned long millis(void) { return k_uptime_get_32(); } +#if defined(CONFIG_DAC) || defined(CONFIG_PWM) +static int _analog_write_resolution = 8; +void analogWriteResolution(int bits) { + _analog_write_resolution = bits; +} +int analogWriteResolution() { + return _analog_write_resolution; +} +#endif + #ifdef CONFIG_PWM void analogWrite(pin_size_t pinNumber, int value) { size_t idx = pwm_pin_index(pinNumber); - if (!pwm_is_ready_dt(&arduino_pwm[idx])) { + if (idx >= ARRAY_SIZE(arduino_pwm) ) { return; } - if (idx >= ARRAY_SIZE(arduino_pwm) ) { + if (!pwm_is_ready_dt(&arduino_pwm[idx])) { return; } + value = map(value, 0, 1 << _analog_write_resolution, 0, arduino_pwm[idx].period); + if (((uint32_t)value) > arduino_pwm[idx].period) { value = arduino_pwm[idx].period; } else if (value < 0) { @@ -305,6 +339,21 @@ void analogWrite(pin_size_t pinNumber, int value) #endif +#ifdef CONFIG_DAC +void analogWrite(enum dacPins dacName, int value) +{ + if (dacName >= NUM_OF_DACS) { + return; + } + + dac_channel_setup(dac_dev, &dac_ch_cfg[dacName]); + + const int max_dac_value = 1U << dac_ch_cfg[dacName].resolution; + dac_write_value(dac_dev, dac_ch_cfg[dacName].channel_id, map(value, 0, 1 << _analog_write_resolution, 0, max_dac_value)); +} +#endif + + #ifdef CONFIG_ADC void analogReference(uint8_t mode) @@ -319,10 +368,21 @@ void analogReference(uint8_t mode) } } +// Note: We can not update the arduino_adc structure as it is read only... +static int read_resolution = 10; + +void analogReadResolution(int bits) +{ + read_resolution = bits; + //for(size_t i=0; i 1) #define ARDUINO_SERIAL_DEFINED_0 1 diff --git a/cores/arduino/zephyrSerial.h b/cores/arduino/zephyrSerial.h index 7e7a160a..047262e8 100644 --- a/cores/arduino/zephyrSerial.h +++ b/cores/arduino/zephyrSerial.h @@ -81,7 +81,7 @@ class ZephyrSerial : public HardwareSerial } // namespace arduino #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), serials) -#if !DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) +#if !(DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) && CONFIG_USB_CDC_ACM) // If CDC USB, use that object as Serial (and SerialUSB) extern arduino::ZephyrSerial Serial; #endif diff --git a/extra/bootstrap.sh b/extra/bootstrap.sh index 796be9e4..512c0aad 100755 --- a/extra/bootstrap.sh +++ b/extra/bootstrap.sh @@ -12,3 +12,6 @@ west init -l . west update pip install -r ../zephyr/scripts/requirements-base.txt # download slim toolchain from https://github.com/zephyrproject-rtos/sdk-ng/releases/tag/v0.16.8 + +# add here the required blobs based on supported platforms +west blobs fetch hal_nxp \ No newline at end of file diff --git a/libraries/Zephyr_SDRAM/examples/SDRAM_operations/SDRAM_operations.ino b/libraries/Zephyr_SDRAM/examples/SDRAM_operations/SDRAM_operations.ino new file mode 100644 index 00000000..c55795ea --- /dev/null +++ b/libraries/Zephyr_SDRAM/examples/SDRAM_operations/SDRAM_operations.ino @@ -0,0 +1,68 @@ +/* + How to interact with external SDRAM on Portenta H7 + + The board comes with an hefty 8MB of external fast RAM, which can be used: + - as a framebuffer (raw mode) + - as an expansion of on-chip RAM to store "standard" data + + This example shows both the usages +*/ + +#include "SDRAM.h" + +void nonFrameBuffer() { + // Initilize SDRAM for non-framebuffer operations + SDRAM.begin(); // is the same as SDRAM.begin(SDRAM_START_ADDRESS); + + // Now we can malloc() and free() in the whole RAM space + // For example, let's create a 7MB array + uint8_t* myVeryBigArray = (uint8_t*)SDRAM.malloc(7 * 1024 * 1024); + + // and a small one + uint8_t* mySmallArray = (uint8_t*)SDRAM.malloc(128); + + // and use then as usual + for (int i = 0; i<128; i++) { + myVeryBigArray[i] = i; + mySmallArray[i] = i*2; + } + + // free the memory when you don't need them anymore + SDRAM.free(myVeryBigArray); +} + +void frameBuffer() { + // In case we want a framebuffer-like area at the beginning of the flash, + // simply initialize the memory as + + SDRAM.begin(SDRAM_START_ADDRESS + 2 * 1024 * 1024); + // 2MB of contiguous memory available at the beginning + + uint32_t* framebuffer = (uint32_t*)SDRAM_START_ADDRESS; + + // We can't allocate anymore the huge 7MB array + + uint8_t* myVeryBigArray = (uint8_t*)SDRAM.malloc(7 * 1024 * 1024); + if (myVeryBigArray == NULL) { + Serial.println("Oops, too big :)"); + } + +} + +void setup() { + Serial.begin(115200); + while (!Serial); + + frameBuffer(); + // Uncomment to test the other functionality + // nonFrameBuffer(); + + // Sort of memtest for stability, useful for testing when overclocking + if (SDRAM.test()) { + Serial.println("SDRAM completely functional"); + } +} + +void loop() { + +} \ No newline at end of file diff --git a/libraries/Zephyr_SDRAM/library.properties b/libraries/Zephyr_SDRAM/library.properties new file mode 100644 index 00000000..cc80e102 --- /dev/null +++ b/libraries/Zephyr_SDRAM/library.properties @@ -0,0 +1,9 @@ +name=Portenta_SDRAM +version=1.0 +author=Arduino +maintainer=Arduino +sentence=Interact with external SDRAM chip on Portenta H7 +paragraph= +category=Other +url=https://github.com/arduino/ArduinoCore-mbed/tree/master/libraries/Portenta_SDRAM +architectures=* diff --git a/libraries/Zephyr_SDRAM/src/SDRAM.cpp b/libraries/Zephyr_SDRAM/src/SDRAM.cpp new file mode 100644 index 00000000..23c93f03 --- /dev/null +++ b/libraries/Zephyr_SDRAM/src/SDRAM.cpp @@ -0,0 +1,69 @@ +#include "SDRAM.h" +#include "Arduino.h" + +int SDRAMClass::begin(uint32_t start_address) { + if (start_address) { + malloc_addblock((void*)start_address, SDRAM_END_ADDRESS - start_address); + } + + return 1; +} + +void* SDRAMClass::malloc(size_t size) { + return ea_malloc(size); +} + +void SDRAMClass::free(void* ptr) { + ea_free(ptr); +} + +bool SDRAMClass::test(bool fast, Stream& _serial) { + uint8_t const pattern = 0xaa; + uint8_t const antipattern = 0x55; + uint8_t *const mem_base = (uint8_t*)SDRAM_START_ADDRESS; + + /* test data bus */ + for (uint8_t i = 1; i; i <<= 1) { + *mem_base = i; + if (*mem_base != i) { + _serial.println("data bus lines test failed! data (" + String(i) + ")"); + __asm__ volatile ("BKPT"); + } + } + + /* test address bus */ + /* Check individual address lines */ + for (uint32_t i = 1; i < HW_SDRAM_SIZE; i <<= 1) { + mem_base[i] = pattern; + if (mem_base[i] != pattern) { + _serial.println("address bus lines test failed! address ("+ String((uint32_t)&mem_base[i], HEX) + ")"); + __asm__ volatile ("BKPT"); + } + } + + /* Check for aliasing (overlaping addresses) */ + mem_base[0] = antipattern; + for (uint32_t i = 1; i < HW_SDRAM_SIZE; i <<= 1) { + if (mem_base[i] != pattern) { + _serial.println("address bus overlap! address ("+ String((uint32_t)&mem_base[i], HEX) + ")"); + __asm__ volatile ("BKPT"); + } + } + + /* test all ram cells */ + if (!fast) { + for (uint32_t i = 0; i < HW_SDRAM_SIZE; ++i) { + mem_base[i] = pattern; + if (mem_base[i] != pattern) { + _serial.println("address bus test failed! address ("+ String((uint32_t)&mem_base[i], HEX) + ")"); + __asm__ volatile ("BKPT"); + } + } + } else { + memset(mem_base, pattern, HW_SDRAM_SIZE); + } + + return true; +} + +SDRAMClass SDRAM; \ No newline at end of file diff --git a/libraries/Zephyr_SDRAM/src/SDRAM.h b/libraries/Zephyr_SDRAM/src/SDRAM.h new file mode 100644 index 00000000..853b705a --- /dev/null +++ b/libraries/Zephyr_SDRAM/src/SDRAM.h @@ -0,0 +1,27 @@ +#ifndef __SDRAM_H +#define __SDRAM_H + +#include "ea_malloc.h" + +#ifdef __cplusplus + +#include "Arduino.h" + +#define SDRAM_END_ADDRESS (0xc0800000) +#define SDRAM_START_ADDRESS (0xc0000000) +#define HW_SDRAM_SIZE (8 * 1024 * 1024) + +class SDRAMClass { +public: + SDRAMClass() {} + int begin(uint32_t start_address = SDRAM_START_ADDRESS); + void* malloc(size_t size); + void free(void* ptr); + bool test(bool fast = false, Stream& _serial = Serial); +private: + +}; +extern SDRAMClass SDRAM; + +#endif +#endif // __SDRAM_H diff --git a/libraries/ea_malloc/ea_malloc.h b/libraries/ea_malloc/ea_malloc.h new file mode 100644 index 00000000..1fd54287 --- /dev/null +++ b/libraries/ea_malloc/ea_malloc.h @@ -0,0 +1,46 @@ +/* +* Copyright © 2017 Embedded Artistry LLC. +* License: MIT. See LICENSE file for details. +*/ + +#ifndef MALLOC_H_ +#define MALLOC_H_ + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +#include + +/** +* @brief Assign blocks of memory for use by malloc(). +* +* Initializes the malloc() backend with a memory address and memory pool size. +* This memory is assumed to be owned by malloc() and is vended out when memory is requested. +* Multiple blocks can be added. +* +* NOTE: This API must be called before malloc() can be used. If you call malloc() before +* allocating memory, malloc() will return NULL because there is no available memory +* to provide to the user. +* +* @param addr Pointer to the memory block address that you are providing to malloc() +* @param size Size of the memory block that you are providing to malloc() +*/ +void malloc_addblock(void* addr, size_t size); + +/** +* @brief Initialize Malloc +* +* Weakly linked, can be overridden based on your needs. +* Each malloc implementation contains a different set of initialization requirements +*/ +void malloc_init(void); + +void* ea_malloc(size_t size); +void ea_free(void* ptr); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //MALLOC_H_ \ No newline at end of file diff --git a/libraries/ea_malloc/ll.h b/libraries/ea_malloc/ll.h new file mode 100644 index 00000000..a83be8ff --- /dev/null +++ b/libraries/ea_malloc/ll.h @@ -0,0 +1,367 @@ +#ifndef LL_H__ +#define LL_H__ + +#include +#include //size_t, NULL + +/** @defgroup linkedlist-C C Linked List Interface + * A linked list library for C modules + * + * @ingroup FrameworkUtils + * @{ + */ + +/** + * Define offsetof if we don't have it already + */ +#ifndef offsetof +#ifdef __compiler_offsetof +#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER) +#else +#define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE*)0)->MEMBER) +#endif +#endif // offsetof + +/** + * Define container_of if we don't have it already + */ +#ifndef container_of +#ifdef __GNUC__ +#ifndef __clang__ +// Isolate the GNU-specific expression +#define container_of(ptr, type, member) \ + __extension__ ({ \ + const __typeof__(((type*)0)->member)* __mptr = (ptr); \ + (type*)((uintptr_t)__mptr - offsetof(type, member)); \ + }) +#else // we are clang - avoid GNU expression +#define container_of(ptr, type, member) ((type*)((uintptr_t)(ptr)-offsetof(type, member))) +#endif // GNU and not clang +#else +#define container_of(ptr, type, member) ((type*)((uintptr_t)(ptr)-offsetof(type, member))) +#endif // not GNU +#endif // container_of + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +/** Linked list struct + * + * This is a doubly linked list structure. + * The ll_t structure should be embedded in a container structure that you want to list. + * + * Example: + * + * @code + * typedef struct + * { + * ll_t node; + * size_t size; + * char* block; + * } alloc_node_t; + * @endcode + */ +typedef struct ll_head +{ + /// Pointer to the next element in the list. + struct ll_head* next; + /// Pointer to the previous element in the list. + struct ll_head* prev; +} ll_t; + +//#pragma mark - List Manipulation - + +/// @name Get Containers +/// @{ + +/** Get the container for a list entry + * + * @param[in] ptr The pointer to the target ll_t node. + * @param[in] type The struct type which contains the ll_t node. For this example struct, + * type would refer to alloc_node_t: + * @code + * typedef struct + * { + * ll_t node; + * size_t size; + * char* block; + * } alloc_node_t; + * @endcode + * + * @param[in] member The member which corresponds to the member name of the ll_t entry. For this + * example struct, member would refer to `node`. + * @code + * typedef struct + * { + * ll_t node; + * size_t size; + * char* block; + * } alloc_node_t; + * @endcode + * + * @returns a pointer to the struct containing the linked list node at `ptr`, cast to type `type`. + */ +#define list_entry(ptr, type, member) container_of(ptr, type, member) + +/** Get the container for the first item in the list + * + * @param[in] head The pointer to the head of the list. + * @param[in] type The struct type which contains the ll_t node. For this example struct, + * type would refer to alloc_node_t: + * @code + * typedef struct + * { + * ll_t node; + * size_t size; + * char* block; + * } alloc_node_t; + * @endcode + + * @param[in] member The member which corresponds to the member name of the ll_t entry. For this + * example struct, member would refer to `node`. + * @code + * typedef struct + * { + * ll_t node; + * size_t size; + * char* block; + * } alloc_node_t; + * @endcode + * + * @returns a pointer to the struct containing the linked list node at `ptr`, cast to type `type`. + */ +#define list_first_entry(head, type, member) list_entry((head)->next, type, member) + +/// @} +// Get containers + +//#pragma mark - Foreach - + +/// @name Foreach Operations +/// @{ + +/** Declare a foreach loop which iterates over the list + * + * list_for_each() will run as long as the current object's next pointer is not equal to the + * head of the list. It's possible for a malformed list to loop forever. + * + * @param[in] pos The variable which will hold the current iteration's position value. + * This variable must be a pointer and should be pre-declared before instantiating the loop. + * @code + * ll_t *b; + * list_for_each(b, &free_list) + * { + * ... + * } + * @endcode + * @param[in] head The head of of the linked list. Input should be a pointer. + */ +#define list_for_each(pos, head) for(pos = (head)->next; pos != (head); pos = pos->next) + +/** Declare a foreach loop which iterates over the list, copy current node pointer. + * + * list_for_each_safe() will run as long as the current object's next pointer is not equal to the + * head of the list. It's possible for a malformed list to loop forever. + * + * The list_for_each_safe() variant makes a copy of the current node pointer, enabling the loop + * to get to the next pointer if there is a deletion. + * + * @param[in] pos The variable which will hold the current iteration's position value. + * This variable must be a pointer should be pre-declared before instantiating the loop. + * @code + * ll_t *b, *t; + * list_for_each_safe(b, t, &free_list) + * { + * ... + * } + * @endcode + * @param[in] n The variable which will hold the current iteration's position value **copy**. + * This variable must be a pointer and should be pre-declared before instantiating the loop. + * @code + * alloc_node_t *b, *t; + * list_for_each_safe(b, t, &free_list) + * { + * ... + * } + * @endcode + * @param[in] head The head of of the linked list. Input should be a pointer. + */ +#define list_for_each_safe(pos, n, head) \ + for(pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next) + +/** Declare a for loop which operates on each node in the list using the container value. + * + * @param[in] pos The variable which will hold the current iteration's position value. + * This variable must be a pointer and should be pre-declared before instantiating the loop. + * The `pos` variable must be the container type. + * @code + * alloc_node_t *b, *t; + * list_for_each_entry(b, &free_list, node) + * { + * ... + * } + * @endcode + * + * @param[in] head The head of of the linked list. Input should be a pointer. + * + * @param[in] member The member which corresponds to the member name of the ll_t entry. For this + * example struct, member would refer to `node`. + * @code + * typedef struct + * { + * ll_t node; + * size_t size; + * char* block; + * } alloc_node_t; + * @endcode + */ +#define list_for_each_entry(pos, head, member) \ + for(pos = list_entry((head)->next, __typeof__(*pos), member); &pos->member != (head); \ + pos = list_entry(pos->member.next, __typeof__(*pos), member)) + +/** Declare a for loop which operates on each node in the list using a copy of the container value. + * + * @param[in] pos The variable which will hold the current iteration's position value. + * This variable must be a pointer and should be pre-declared before instantiating the loop. + * The `pos` variable must be the container type. + * @code + * alloc_node_t *b, *t; + * list_for_each_entry(b, &free_list, node) + * { + * ... + * } + * @endcode + * @param[in] n The variable which will hold the current iteration's position value **copy**. + * This variable must be a pointer and should be pre-declared before instantiating the loop. + * The `n` variable must be the container type. + * @code + * typedef struct + * { + * ll_t node; + * size_t size; + * char* block; + * } alloc_node_t; + * + * alloc_node_t *b, *t; + * list_for_each_entrysafe(b, t, &free_list, node) + * { + * ... + * } + * @endcode + * @param[in] head The head of of the linked list. Input should be a pointer. + * @param[in] member The member which corresponds to the member name of the ll_t entry. For this + * example struct, member would refer to `node`. + * @code + * typedef struct + * { + * ll_t node; + * size_t size; + * char* block; + * } alloc_node_t; + * @endcode + */ +#define list_for_each_entry_safe(pos, n, head, member) \ + for(pos = list_entry((head)->next, __typeof__(*pos), member), \ + n = list_entry(pos->member.next, __typeof__(*pos), member); \ + &pos->member != (head); pos = n, n = list_entry(n->member.next, __typeof__(*n), member)) + +/// @} +// End foreach + +//#pragma mark - Init - + +/// @name Initialization +/// @{ + +/// Initialize a linked list so it points to itself +/// @param[in] name of the linked list object +#define ll_head_INIT(name) \ + { \ + &(name), &(name) \ + } + +/** Initialize a linked list + * + * @code + * // This macro declares and initializes our linked list + * static LIST_INIT(free_list); + * @endcode + * @param[in] name The name of the linked list object to declare + */ +#define LIST_INIT(name) struct ll_head name = ll_head_INIT(name) + +/// @} + +//#pragma mark - Add - + +/// @name Addition +/// @{ + +/// Insert a new element between two existing elements. +/// @param[in] n The node to add to the list. +/// @param[in] prev The pointer to the node before where the new node will be inserted. +/// @param[in] next The pointer to the new node after where the new node will be inserted. +static inline void list_insert(struct ll_head* n, struct ll_head* prev, struct ll_head* next) +{ + next->prev = n; + n->next = next; + n->prev = prev; + prev->next = n; +} + +/// Add a node to the front of the list +/// @param[in] n The node to add to the list. +/// @param[in] head The head of the list. +static inline void list_add(struct ll_head* n, struct ll_head* head) +{ + list_insert(n, head, head->next); +} + +/// Add a node to the end of the list +/// @param[in] n The node to add to the list. +/// @param[in] head The head of the list. +static inline void list_add_tail(struct ll_head* n, struct ll_head* head) +{ + list_insert(n, head->prev, head); +} + +/// @} + +//#pragma mark - Delete - + +/// @name Deletion +/// @{ + +/// Remove the node between two element pointers. +/// +/// Joins the `prev` and `next` elements together, effectively removing +/// the element in the middle. +/// +/// @param[in] prev The previous element in the list, which will now be joined to next. +/// @param[in] next The next element in the list, which will now be joined to prev. +static inline void list_join_nodes(struct ll_head* prev, struct ll_head* next) +{ + next->prev = prev; + prev->next = next; +} + +/// Remove an entry from the list +/// @param[in] entry The pointer to the entry to remove from the list. +static inline void list_del(struct ll_head* entry) +{ + list_join_nodes(entry->prev, entry->next); + entry->next = NULL; + entry->prev = NULL; +} + +/// @} + +/// @} +// end group + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif // LL_H__ diff --git a/libraries/ea_malloc/malloc_freelist.c b/libraries/ea_malloc/malloc_freelist.c new file mode 100644 index 00000000..4fb1f7b3 --- /dev/null +++ b/libraries/ea_malloc/malloc_freelist.c @@ -0,0 +1,168 @@ +/* + * Copyright © 2017 Embedded Artistry LLC. + * License: MIT. See LICENSE file for details. + */ + +#include +#include +#include +#include + +//#pragma mark - Definitions - + +/** + * Simple macro for making sure memory addresses are aligned + * to the nearest power of two + */ +#ifndef align_up +#define align_up(num, align) (((num) + ((align)-1)) & ~((align)-1)) +#endif + +/* + * This is the container for our free-list. + * Note the usage of the linked list here: the library uses offsetof + * and container_of to manage the list and get back to the parent struct. + */ +typedef struct +{ + ll_t node; + size_t size; + char* block; +} alloc_node_t; + +/** + * We vend a memory address to the user. This lets us translate back and forth + * between the vended pointer and the container we use for managing the data. + */ +#define ALLOC_HEADER_SZ offsetof(alloc_node_t, block) + +// We are enforcing a minimum allocation size of 32B. +#define MIN_ALLOC_SZ ALLOC_HEADER_SZ + 32 + +//#pragma mark - Prototypes - + +static void defrag_free_list(void); + +//#pragma mark - Declarations - + +// This macro simply declares and initializes our linked list +static LIST_INIT(free_list); + +//#pragma mark - Private Functions - + +/** + * When we free, we can take our node and check to see if any memory blocks + * can be combined into larger blocks. This will help us fight against + * memory fragmentation in a simple way. + */ +void defrag_free_list(void) +{ + alloc_node_t* b; + alloc_node_t* lb = NULL; + alloc_node_t* t; + + list_for_each_entry_safe(b, t, &free_list, node) + { + if(lb) + { + if((((uintptr_t)&lb->block) + lb->size) == (uintptr_t)b) + { + lb->size += ALLOC_HEADER_SZ + b->size; + list_del(&b->node); + continue; + } + } + lb = b; + } +} + +//#pragma mark - APIs - + +__attribute__((weak)) void malloc_init(void) +{ + // Unused here, override to specify your own init functin + // Which includes malloc_addblock calls +} + +void* ea_malloc(size_t size) +{ + void* ptr = NULL; + alloc_node_t* blk = NULL; + + if(size > 0) + { + // Align the pointer + size = align_up(size, sizeof(void*)); + + // try to find a big enough block to alloc + list_for_each_entry(blk, &free_list, node) + { + if(blk->size >= size) + { + ptr = &blk->block; + break; + } + } + + // we found something + if(ptr) + { + // Can we split the block? + if((blk->size - size) >= MIN_ALLOC_SZ) + { + alloc_node_t* new_blk; + new_blk = (alloc_node_t*)((uintptr_t)(&blk->block) + size); + new_blk->size = blk->size - size - ALLOC_HEADER_SZ; + blk->size = size; + list_insert(&new_blk->node, &blk->node, blk->node.next); + } + + list_del(&blk->node); + } + + } // else NULL + + return ptr; +} + +void ea_free(void* ptr) +{ + alloc_node_t* free_blk; + alloc_node_t* blk; + + // Don't free a NULL pointer.. + if(ptr) + { + // we take the pointer and use container_of to get the corresponding alloc block + blk = container_of(ptr, alloc_node_t, block); + + // Let's put it back in the proper spot + list_for_each_entry(free_blk, &free_list, node) + { + if(free_blk > blk) + { + list_insert(&blk->node, free_blk->node.prev, &free_blk->node); + goto blockadded; + } + } + list_add_tail(&blk->node, &free_list); + + blockadded: + // Let's see if we can combine any memory + defrag_free_list(); + } +} + +void malloc_addblock(void* addr, size_t size) +{ + alloc_node_t* blk; + + // let's align the start address of our block to the next pointer aligned number + blk = (void*)align_up((uintptr_t)addr, sizeof(void*)); + + // calculate actual size - remove our alignment and our header space from the availability + blk->size = (uintptr_t)addr + size - (uintptr_t)blk - ALLOC_HEADER_SZ; + + // and now our giant block of memory is added to the list! + list_add(&blk->node, &free_list); +} diff --git a/loader/boards/arduino_giga_r1_m7.conf b/loader/boards/arduino_giga_r1_m7.conf index 7b3f94ea..ac1366a3 100644 --- a/loader/boards/arduino_giga_r1_m7.conf +++ b/loader/boards/arduino_giga_r1_m7.conf @@ -10,16 +10,26 @@ CONFIG_UART_LINE_CTRL=y CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT=y CONFIG_LLEXT_STORAGE_WRITABLE=n +CONFIG_HEAP_MEM_POOL_SIZE=2048 +CONFIG_SHELL_STACK_SIZE=32768 +CONFIG_MAIN_STACK_SIZE=32768 +CONFIG_LLEXT_HEAP_SIZE=128 CONFIG_FPU=y CONFIG_ADC=y +CONFIG_DAC=y CONFIG_PWM=y CONFIG_DMA=y CONFIG_MEMC=y +CONFIG_SPI_ASYNC=y +CONFIG_SPI_STM32_INTERRUPT=y #CONFIG_VIDEO=y CONFIG_VIDEO_STM32_DCMI=y CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=1 -CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=160000 \ No newline at end of file +CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=160000 + +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y \ No newline at end of file diff --git a/loader/boards/arduino_giga_r1_m7.overlay b/loader/boards/arduino_giga_r1_m7.overlay index fef941a7..03c2ae54 100644 --- a/loader/boards/arduino_giga_r1_m7.overlay +++ b/loader/boards/arduino_giga_r1_m7.overlay @@ -57,26 +57,80 @@ clock-frequency = ; }; -// XCLK as PWM from PJ9 &timers1 { status = "okay"; - st,prescaler = <0>; + st,prescaler = <4>; - cam_clock_pwm: pwm { + pwm1: pwm { status = "okay"; - pinctrl-0 = <&tim1_ch3_pj9>; + pinctrl-0 = <&tim1_ch3_pj9 &tim1_ch1_pk1 &tim1_ch2_pj11>; pinctrl-names = "default"; }; }; -&cam_clock_pwm { - /* ...then use the pwmclock node to start the clock generation */ +&timers2 { + status = "okay"; + st,prescaler = <100>; + + pwm2: pwm { + status = "okay"; + pinctrl-0 = <&tim2_ch4_pa3 &tim2_ch3_pa2>; + pinctrl-names = "default"; + }; +}; + +&timers3 { + status = "okay"; + st,prescaler = <100>; + + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&tim3_ch2_pa7 &tim3_ch1_pb4>; + pinctrl-names = "default"; + }; +}; + +&timers4 { + status = "okay"; + st,prescaler = <100>; + + pwm4: pwm { + status = "okay"; + pinctrl-0 = <&tim4_ch2_pd13 &tim4_ch3_pb8 &tim4_ch4_pb9>; + pinctrl-names = "default"; + }; +}; + +&timers8 { + status = "okay"; + st,prescaler = <100>; + + pwm8: pwm { + status = "okay"; + pinctrl-0 = <&tim8_ch1_pj8 &tim8_ch2_pj10>; + pinctrl-names = "default"; + }; +}; + +&timers12 { + status = "okay"; + st,prescaler = <100>; + + pwm12: pwm { + status = "okay"; + pinctrl-0 = <&tim12_ch1_ph6>; + pinctrl-names = "default"; + }; +}; + +&pwm1 { + /* Use the pwmclock node to start the clock generation */ pwmclock: pwmclock { status = "okay"; compatible = "pwm-clock"; clock-frequency = <0>; #clock-cells = <1>; - pwms = <&cam_clock_pwm 3 PWM_HZ(6000000) PWM_POLARITY_NORMAL>; + pwms = <&pwm1 3 PWM_HZ(12000000) PWM_POLARITY_NORMAL>; }; }; @@ -422,14 +476,18 @@ <&gpioe 3 GPIO_ACTIVE_LOW>; pwm-pin-gpios = <&gpioj 9 0>, - <&arduino_header 6 0>, - <&arduino_header 5 0>, - <&arduino_header 17 0>, - <&arduino_header 12 0>, - <&arduino_header 2 0>, - <&arduino_header 3 0>, + <&arduino_header 8 0>, <&arduino_header 9 0>, - <&arduino_header 10 0>; + <&arduino_header 10 0>, + <&arduino_header 11 0>, + <&arduino_header 12 0>, + <&arduino_header 13 0>, + <&arduino_header 14 0>, + <&arduino_header 15 0>, + <&arduino_header 16 0>, + <&arduino_header 17 0>, + <&arduino_header 18 0>, + <&arduino_header 19 0>; adc-pin-gpios = <&gpioc 4 0>, <&gpioc 5 0>, @@ -450,7 +508,19 @@ cdc-acm = <&cdc_acm_uart0>; i2cs = <&i2c2>, <&i2c4>, <&i2c1>; spis = <&spi1>, <&spi5>; - pwms = <&cam_clock_pwm 3 PWM_HZ(6000000) PWM_POLARITY_NORMAL>; + pwms = <&pwm1 3 PWM_HZ(6000000) PWM_POLARITY_NORMAL>, + <&pwm2 4 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm2 3 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm8 1 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm3 2 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm4 2 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm3 1 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm4 3 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm4 4 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm1 1 PWM_HZ(5000) PWM_POLARITY_NORMAL>, + <&pwm8 2 PWM_HZ(500) PWM_POLARITY_NORMAL>, + <&pwm1 2 PWM_HZ(5000) PWM_POLARITY_NORMAL>, + <&pwm12 1 PWM_HZ(500) PWM_POLARITY_NORMAL>; io-channels = <&adc1 4>, <&adc1 8>, @@ -466,5 +536,9 @@ <&adc1 0>, <&adc1 18>, <&adc1 19>; + + dac = <&dac1>; + dac-channels = <1>, <2>; + dac-resolution = <12>; }; }; diff --git a/loader/llext_exports.c b/loader/llext_exports.c index 3f4e34ef..618e6538 100644 --- a/loader/llext_exports.c +++ b/loader/llext_exports.c @@ -32,6 +32,7 @@ EXPORT_SYMBOL(free); EXPORT_SYMBOL(rand); EXPORT_SYMBOL(srand); +EXPORT_SYMBOL(atoi); EXPORT_SYMBOL(atof); EXPORT_SYMBOL(atol); EXPORT_SYMBOL(isspace); @@ -44,8 +45,10 @@ EXPORT_SYMBOL(isdigit); EXPORT_SYMBOL(isgraph); EXPORT_SYMBOL(isprint); EXPORT_SYMBOL(isupper); +EXPORT_SYMBOL(islower); EXPORT_SYMBOL(isxdigit); + #if defined(CONFIG_USB_DEVICE_STACK) EXPORT_SYMBOL(usb_enable); EXPORT_SYMBOL(usb_disable); @@ -124,6 +127,7 @@ FORCE_EXPORT_SYM(cdc_acm_dte_rate_callback_set); EXPORT_SYMBOL(k_timer_init); EXPORT_SYMBOL(k_fatal_halt); +EXPORT_SYMBOL(k_work_schedule); //FORCE_EXPORT_SYM(k_timer_user_data_set); //FORCE_EXPORT_SYM(k_timer_start); @@ -138,7 +142,7 @@ EXPORT_SYMBOL(printf); EXPORT_SYMBOL(sprintf); EXPORT_SYMBOL(snprintf); EXPORT_SYMBOL(cbvprintf); - +; FORCE_EXPORT_SYM(abort); #if defined(CONFIG_RING_BUFFER) FORCE_EXPORT_SYM(ring_buf_get); @@ -171,3 +175,5 @@ FORCE_EXPORT_SYM(__aeabi_d2iz); FORCE_EXPORT_SYM(__aeabi_f2d); FORCE_EXPORT_SYM(__aeabi_idivmod); FORCE_EXPORT_SYM(__aeabi_ldivmod); +FORCE_EXPORT_SYM(__aeabi_ul2f); +FORCE_EXPORT_SYM(__cxa_pure_virtual); \ No newline at end of file diff --git a/loader/prj.conf b/loader/prj.conf index 77390514..e00535b6 100644 --- a/loader/prj.conf +++ b/loader/prj.conf @@ -40,3 +40,6 @@ CONFIG_UART_CONSOLE=y CONFIG_FLASH=y CONFIG_FLASH_MAP=y + +CONFIG_CPP=y +CONFIG_STD_CPP17=y \ No newline at end of file diff --git a/samples/analog_input/CMakeLists.txt b/samples/analog_input/CMakeLists.txt index 83ac0d6b..87169d5c 100644 --- a/samples/analog_input/CMakeLists.txt +++ b/samples/analog_input/CMakeLists.txt @@ -3,7 +3,10 @@ cmake_minimum_required(VERSION 3.20.0) cmake_path(SET ZephyrBase $ENV{ZEPHYR_BASE}) -set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/Arduino-Zephyr-API/variants/${BOARD}/${BOARD}.overlay) +set(NORMALIZED_BOARD_TARGET "${BOARD}${BOARD_QUALIFIERS}") +string(REPLACE "/" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +string(REPLACE "__" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/ArduinoCore-zephyr/loader/boards/${NORMALIZED_BOARD_TARGET}.overlay) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(analog_input) diff --git a/samples/attach_interrupt/CMakeLists.txt b/samples/attach_interrupt/CMakeLists.txt index 711b9673..991732b5 100644 --- a/samples/attach_interrupt/CMakeLists.txt +++ b/samples/attach_interrupt/CMakeLists.txt @@ -3,7 +3,10 @@ cmake_minimum_required(VERSION 3.20.0) cmake_path(SET ZephyrBase $ENV{ZEPHYR_BASE}) -set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/Arduino-Zephyr-API/variants/${BOARD}/${BOARD}.overlay) +set(NORMALIZED_BOARD_TARGET "${BOARD}${BOARD_QUALIFIERS}") +string(REPLACE "/" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +string(REPLACE "__" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/ArduinoCore-zephyr/loader/boards/${NORMALIZED_BOARD_TARGET}.overlay) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(attach_interrupt) diff --git a/samples/blinky_arduino/CMakeLists.txt b/samples/blinky_arduino/CMakeLists.txt index e5c58ee3..3d78417b 100644 --- a/samples/blinky_arduino/CMakeLists.txt +++ b/samples/blinky_arduino/CMakeLists.txt @@ -3,7 +3,10 @@ cmake_minimum_required(VERSION 3.20.0) cmake_path(SET ZephyrBase $ENV{ZEPHYR_BASE}) -set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/Arduino-Zephyr-API/variants/${BOARD}/${BOARD}.overlay) +set(NORMALIZED_BOARD_TARGET "${BOARD}${BOARD_QUALIFIERS}") +string(REPLACE "/" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +string(REPLACE "__" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/ArduinoCore-zephyr/loader/boards/${NORMALIZED_BOARD_TARGET}.overlay) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(blinky) diff --git a/samples/button_press_led/CMakeLists.txt b/samples/button_press_led/CMakeLists.txt index e5c58ee3..3d78417b 100644 --- a/samples/button_press_led/CMakeLists.txt +++ b/samples/button_press_led/CMakeLists.txt @@ -3,7 +3,10 @@ cmake_minimum_required(VERSION 3.20.0) cmake_path(SET ZephyrBase $ENV{ZEPHYR_BASE}) -set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/Arduino-Zephyr-API/variants/${BOARD}/${BOARD}.overlay) +set(NORMALIZED_BOARD_TARGET "${BOARD}${BOARD_QUALIFIERS}") +string(REPLACE "/" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +string(REPLACE "__" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/ArduinoCore-zephyr/loader/boards/${NORMALIZED_BOARD_TARGET}.overlay) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(blinky) diff --git a/samples/fade/CMakeLists.txt b/samples/fade/CMakeLists.txt index 6f3c4cff..84053036 100644 --- a/samples/fade/CMakeLists.txt +++ b/samples/fade/CMakeLists.txt @@ -3,7 +3,10 @@ cmake_minimum_required(VERSION 3.20.0) cmake_path(SET ZephyrBase $ENV{ZEPHYR_BASE}) -set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/Arduino-Zephyr-API/variants/${BOARD}/${BOARD}.overlay) +set(NORMALIZED_BOARD_TARGET "${BOARD}${BOARD_QUALIFIERS}") +string(REPLACE "/" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +string(REPLACE "__" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/ArduinoCore-zephyr/loader/boards/${NORMALIZED_BOARD_TARGET}.overlay) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(fade) diff --git a/samples/hello_arduino/CMakeLists.txt b/samples/hello_arduino/CMakeLists.txt index 0675b10d..b18bdf5c 100644 --- a/samples/hello_arduino/CMakeLists.txt +++ b/samples/hello_arduino/CMakeLists.txt @@ -3,7 +3,10 @@ cmake_minimum_required(VERSION 3.20.0) cmake_path(SET ZephyrBase $ENV{ZEPHYR_BASE}) -set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/Arduino-Zephyr-API/variants/${BOARD}/${BOARD}.overlay) +set(NORMALIZED_BOARD_TARGET "${BOARD}${BOARD_QUALIFIERS}") +string(REPLACE "/" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +string(REPLACE "__" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/ArduinoCore-zephyr/loader/boards/${NORMALIZED_BOARD_TARGET}.overlay) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(hello_world) diff --git a/samples/i2cdemo/CMakeLists.txt b/samples/i2cdemo/CMakeLists.txt index e79ab241..e9e9c0b6 100644 --- a/samples/i2cdemo/CMakeLists.txt +++ b/samples/i2cdemo/CMakeLists.txt @@ -3,7 +3,10 @@ cmake_minimum_required(VERSION 3.20.0) cmake_path(SET ZephyrBase $ENV{ZEPHYR_BASE}) -set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/Arduino-Zephyr-API/variants/${BOARD}/${BOARD}.overlay) +set(NORMALIZED_BOARD_TARGET "${BOARD}${BOARD_QUALIFIERS}") +string(REPLACE "/" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +string(REPLACE "__" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/ArduinoCore-zephyr/loader/boards/${NORMALIZED_BOARD_TARGET}.overlay) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(blinky) diff --git a/samples/serial_event/CMakeLists.txt b/samples/serial_event/CMakeLists.txt index a275e3cc..b06eb6f1 100644 --- a/samples/serial_event/CMakeLists.txt +++ b/samples/serial_event/CMakeLists.txt @@ -3,7 +3,10 @@ cmake_minimum_required(VERSION 3.20.0) cmake_path(SET ZephyrBase $ENV{ZEPHYR_BASE}) -set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/Arduino-Zephyr-API/variants/${BOARD}/${BOARD}.overlay) +set(NORMALIZED_BOARD_TARGET "${BOARD}${BOARD_QUALIFIERS}") +string(REPLACE "/" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +string(REPLACE "__" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/ArduinoCore-zephyr/loader/boards/${NORMALIZED_BOARD_TARGET}.overlay) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(serial_event) diff --git a/samples/spi_controller/CMakeLists.txt b/samples/spi_controller/CMakeLists.txt index 824634e5..f296c294 100644 --- a/samples/spi_controller/CMakeLists.txt +++ b/samples/spi_controller/CMakeLists.txt @@ -3,7 +3,10 @@ cmake_minimum_required(VERSION 3.20.0) cmake_path(SET ZephyrBase $ENV{ZEPHYR_BASE}) -set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/Arduino-Zephyr-API/variants/${BOARD}/${BOARD}.overlay) +set(NORMALIZED_BOARD_TARGET "${BOARD}${BOARD_QUALIFIERS}") +string(REPLACE "/" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +string(REPLACE "__" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/ArduinoCore-zephyr/loader/boards/${NORMALIZED_BOARD_TARGET}.overlay) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(spi_controller) diff --git a/samples/threads_arduino/CMakeLists.txt b/samples/threads_arduino/CMakeLists.txt index f9aea636..3976c817 100644 --- a/samples/threads_arduino/CMakeLists.txt +++ b/samples/threads_arduino/CMakeLists.txt @@ -3,7 +3,10 @@ cmake_minimum_required(VERSION 3.20.0) cmake_path(SET ZephyrBase $ENV{ZEPHYR_BASE}) -set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/Arduino-Zephyr-API/variants/${BOARD}/${BOARD}.overlay) +set(NORMALIZED_BOARD_TARGET "${BOARD}${BOARD_QUALIFIERS}") +string(REPLACE "/" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +string(REPLACE "__" "_" NORMALIZED_BOARD_TARGET "${NORMALIZED_BOARD_TARGET}") +set(DTC_OVERLAY_FILE ${ZephyrBase}/../modules/lib/ArduinoCore-zephyr/loader/boards/${NORMALIZED_BOARD_TARGET}.overlay) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(threads) diff --git a/west.yml b/west.yml index 3b008357..caec7476 100644 --- a/west.yml +++ b/west.yml @@ -41,6 +41,7 @@ manifest: - mbedtls - segger - thrift + - mcuboot - name: ArduinoCore-API path: modules/lib/ArduinoCore-API revision: master