Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix support for NRF52 #442

Merged
merged 12 commits into from
Jul 1, 2024
5 changes: 3 additions & 2 deletions lib/schedule.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ trigger_handle_t lf_schedule_trigger(environment_t* env, trigger_t* trigger, int
// If the event is early, see which policy applies.
if (earliest_time > intended_tag.time) {
LF_PRINT_DEBUG("Event is early.");
event_t *dummy, *found;
switch (trigger->policy) {
case drop:
LF_PRINT_DEBUG("Policy is drop. Dropping the event.");
Expand All @@ -247,10 +248,10 @@ trigger_handle_t lf_schedule_trigger(environment_t* env, trigger_t* trigger, int
// If the event with the previous tag is still on the event
// queue, then replace the token. To find this event, we have
// to construct a dummy event_t struct.
event_t* dummy = lf_get_new_event(env);
dummy = lf_get_new_event(env);
dummy->trigger = trigger;
dummy->base.tag = trigger->last_tag;
event_t* found = (event_t*)pqueue_tag_find_equal_same_tag(env->event_q, (pqueue_tag_element_t*)dummy);
found = (event_t*)pqueue_tag_find_equal_same_tag(env->event_q, (pqueue_tag_element_t*)dummy);

if (found != NULL) {
// Recycle the existing token and the new event
Expand Down
2 changes: 1 addition & 1 deletion low_level_platform/api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ target_include_directories(lf-low-level-platform-api INTERFACE ${CMAKE_CURRENT_L
add_library(lf::low-level-platform-api ALIAS lf-low-level-platform-api)
target_link_libraries(lf-low-level-platform-api INTERFACE lf::tag-api)

if(${CMAKE_SYSTEM_NAME} STREQUAL "Nrf52")
if(${CMAKE_SYSTEM_NAME} STREQUAL "nRF52")
edwardalee marked this conversation as resolved.
Show resolved Hide resolved
target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_NRF52)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr")
target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_ZEPHYR)
Expand Down
11 changes: 6 additions & 5 deletions low_level_platform/api/platform/lf_nrf52_support.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* nRF52832 API support for the C target of Lingua Franca. */
/* nRF52 API support for the C target of Lingua Franca. */

/*************
Copyright (c) 2021, The University of California at Berkeley.
Expand All @@ -24,11 +24,12 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***************/

/** nrf52 API support for the C target of Lingua Franca.
/**
* nRF52 API support for the C target of Lingua Franca.
*
* @author{Soroush Bateni <[email protected]>}
* @author{Abhi Gundrala <[email protected]>}
* @author{Erling Rennemo Jellum <[email protected]>}
* @author{Soroush Bateni <[email protected]>}
* @author{Abhi Gundrala <[email protected]>}
* @author{Erling Rennemo Jellum <[email protected]>}
*/

#ifndef LF_NRF52_SUPPORT_H
Expand Down
6 changes: 3 additions & 3 deletions low_level_platform/impl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
${CMAKE_CURRENT_LIST_DIR}/src/lf_macos_support.c
${CMAKE_CURRENT_LIST_DIR}/src/lf_atomic_gcc_clang.c
)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Nrf52")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "nRF52")
set(LF_LOW_LEVEL_PLATFORM_FILES
${CMAKE_CURRENT_LIST_DIR}/src/lf_nrf52_support.c
${CMAKE_CURRENT_LIST_DIR}/src/lf_atomic_irq.c
Expand All @@ -45,7 +45,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET")
${CMAKE_CURRENT_LIST_DIR}/src/lf_atomic_irq.c
)
else()
message(FATAL_ERROR "Your platform is not supported! The C target supports FlexPRET, Linux, MacOS, Nrf52, RP2040, Windows, and Zephyr.")
message(FATAL_ERROR "Your platform is not supported! The C target supports FlexPRET, Linux, MacOS, nRF52, RP2040, Windows, and Zephyr.")
endif()

list(APPEND LF_LOW_LEVEL_PLATFORM_FILES ${CMAKE_CURRENT_LIST_DIR}/src/lf_platform_util.c)
Expand Down Expand Up @@ -109,7 +109,7 @@ target_link_libraries(lf-low-level-platform-impl PRIVATE lf::low-level-platform-
target_link_libraries(lf-low-level-platform-impl PUBLIC lf-logging-api)

target_compile_definitions(lf-low-level-platform-impl PUBLIC PLATFORM_${CMAKE_SYSTEM_NAME})
message(STATUS "Applying preprocessor definitions to platform...")
message(STATUS "Applying preprocessor definitions to low-level-platform...")
macro(low_level_platform_define X)
if(DEFINED ${X})
message(STATUS ${X}=${${X}})
Expand Down
47 changes: 35 additions & 12 deletions low_level_platform/impl/src/lf_nrf52_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h>

#include "platform/lf_nrf52_support.h"
#include "../platform.h"
#include "../utils/util.h"
#include "../tag.h"
#include "low_level_platform.h"
#include "tag.h"

#include "nrf.h"
#include "nrfx_timer.h"
Expand Down Expand Up @@ -74,9 +73,9 @@ static const nrfx_timer_t g_lf_timer_inst = NRFX_TIMER_INSTANCE(3);
static volatile uint32_t _lf_time_us_high = 0;

/**
* Flag passed to sd_nvic_critical_region_*
* Flag used to count nested interrupt disables.
*/
uint8_t _lf_nested_region = 0;
static volatile uint8_t _lf_nested_count = 0;

/**
* @brief Handle LF timer interrupts
Expand All @@ -95,7 +94,7 @@ void lf_timer_event_handler(nrf_timer_event_t event_type, void* p_context) {
if (event_type == NRF_TIMER_EVENT_COMPARE2) {
_lf_sleep_interrupted = false;
} else if (event_type == NRF_TIMER_EVENT_COMPARE3) {
_lf_time_us_high = +1;
_lf_time_us_high += 1;
}
}

Expand Down Expand Up @@ -193,13 +192,19 @@ static void lf_busy_wait_until(instant_t wakeup_time) {
}

/**
* @brief Sleep until the given wakeup time. There are a couple of edge cases to consider
* @brief Sleep until the given wakeup time.
*
* There are a couple of edge cases to consider:
* 1. Wakeup time is already past
* 2. Implied sleep duration is below `LF_MAX_SLEEP_NS` threshold
* 3. Implied sleep duration is above `LF_MAX_SLEEP_NS` limit
*
* This function assumes the caller is in a critical section, so interrupts are disabled.
* It may exit the critical section while waiting for an event, but it will re-enter the
* critical section before returning.
*
* @param wakeup_time The time instant at which to wake up.
* @return int 0 if sleep completed, or -1 if it was interrupted.
* @return 0 if sleep completed, or -1 if it was interrupted.
*/
int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_time) {
instant_t now;
Expand Down Expand Up @@ -258,23 +263,41 @@ int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_ti
if (!_lf_async_event) {
return 0;
} else {
LF_PRINT_DEBUG("Sleep got interrupted...\n");
// LF_PRINT_DEBUG("Sleep got interrupted...\n");
return -1;
}
}

// Definition required by sd_nvic_critical_region_enter() and exit() below.
nrf_nvic_state_t nrf_nvic_state = {0};

/**
* @brief Enter critical section. Let NRF Softdevice handle nesting
* @return int
* @return 0
*/
int lf_enable_interrupts_nested() { return sd_nvic_critical_region_enter(&_lf_nested_region); }
int lf_enable_interrupts_nested() {
if (_lf_nested_count == 0)
return 1; // Error. Interrupts have not been disabled.
_lf_nested_count--;
return sd_nvic_critical_region_exit(0);
// FIXME: If softdevice is not enabled, do the following instead of above:
edwardalee marked this conversation as resolved.
Show resolved Hide resolved
// __enable_irq();
// return 0;
}

/**
* @brief Exit citical section. Let NRF SoftDevice handle nesting
*
* @return int
*/
int lf_disable_interrupts_nested() { return sd_nvic_critical_region_exit(_lf_nested_region); }
int lf_disable_interrupts_nested() {
_lf_nested_count++;
uint8_t success = 0;
return sd_nvic_critical_region_enter(&success);
// FIXME: If softdevice is not enabled, do the following instead of the above:
// __disable_irq();
// return 0;
}

/**
* @brief Set global flag to true so that sleep will return when woken
Expand Down
10 changes: 10 additions & 0 deletions platform/impl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,13 @@ endif()
add_library(lf::platform-impl ALIAS lf-platform-impl)
target_link_libraries(lf-platform-impl PRIVATE lf::low-level-platform-api)
target_link_libraries(lf-platform-impl PRIVATE lf::platform-api)
message(STATUS "Applying preprocessor definitions to platform...")
macro(platform_define X)
if(DEFINED ${X})
message(STATUS ${X}=${${X}})
target_compile_definitions(lf-platform-impl PUBLIC ${X}=${${X}})
endif(DEFINED ${X})
endmacro()
platform_define(LF_SINGLE_THREADED)
platform_define(LOG_LEVEL)
platform_define(MODAL_REACTORS)
Loading