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

Upgrade HardwareSPI library with Rp2040 support #2470

Merged
merged 8 commits into from
Jan 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions Sming/Arch/Host/Components/driver/hw_timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
#include <driver/hw_timer.h>
#include <hostlib/threads.h>
#include <sys/time.h>
#include <errno.h>
#include <cerrno>
#include <hostlib/hostmsg.h>
#include <cassert>
#include <muldiv.h>
#include <esp_system.h>
#include <memory>

/* Timer 1 */

Expand Down Expand Up @@ -207,41 +208,49 @@ void* CTimerThread::thread_routine()
return nullptr;
}

static CTimerThread timer1("Timer1");
static std::unique_ptr<CTimerThread> timer1;

void hw_timer_init(void)
{
timer1.reset(new CTimerThread("Timer1"));
}

void hw_timer_cleanup()
{
timer1.terminate();
if(timer1) {
timer1->terminate();
timer1.reset();
}
}

void hw_timer1_attach_interrupt(hw_timer_source_type_t source_type, hw_timer_callback_t callback, void* arg)
{
timer1.attach_interrupt(source_type, callback, arg);
timer1->attach_interrupt(source_type, callback, arg);
}

void hw_timer1_enable(hw_timer_clkdiv_t div, hw_timer_intr_type_t intr_type, bool auto_load)
{
timer1.enable(div, intr_type, auto_load);
timer1->enable(div, intr_type, auto_load);
}

void hw_timer1_write(uint32_t ticks)
{
timer1.write(ticks);
timer1->write(ticks);
}

void hw_timer1_disable()
{
timer1.stop();
timer1->stop();
}

void hw_timer1_detach_interrupt()
{
timer1.detach_interrupt();
timer1->detach_interrupt();
}

uint32_t hw_timer1_read()
{
return timer1.read();
return timer1->read();
}

uint32_t hw_timer2_read()
Expand Down
4 changes: 1 addition & 3 deletions Sming/Arch/Host/Components/driver/include/driver/hw_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@ inline uint32_t NOW()
return hw_timer2_read();
}

inline void hw_timer_init(void)
{
}
void hw_timer_init(void);

void hw_timer_cleanup();

Expand Down
4 changes: 4 additions & 0 deletions Sming/Arch/Host/Components/driver/os_timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ void os_timer_disarm(struct os_timer_t* ptimer)
{
assert(ptimer != nullptr);

if(int(ptimer->timer_next) == -1) {
return;
}

mutex.lock();
if(timer_list != nullptr) {
// Remove timer from list
Expand Down
2 changes: 1 addition & 1 deletion Sming/Arch/Host/Components/driver/uart_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ std::unique_ptr<CUart> servers[UART_COUNT];
class KeyboardThread : public CThread
{
public:
KeyboardThread() : CThread("keyboard", 0)
KeyboardThread() : CThread("keyboard", 1)
{
}

Expand Down
3 changes: 2 additions & 1 deletion Sming/Arch/Host/Components/gdbstub/gdbcmds
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
handle SIGUSR1 nostop noprint
# Used for interrupt emulation
handle SIG34 SIG35 nostop noprint

# Enable this if you want to log all traffic between GDB and the stub
#set remotelogfile gdb_rsp_logfile.txt
Expand Down
11 changes: 7 additions & 4 deletions Sming/Arch/Host/Components/hostlib/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,16 @@ Ideally we'd use SCHED_FIFO to disable time-slicing and more closely resemble ho
on a single-core CPU. However, this mode isn't supported in Windows, and Linux requires privileged
access and can potentially crash the system. Best avoided, I think.

All ESP code runs at a specific interrupt level, where 0 represents regular code. When an interrupt
All ESP code runs at a specific interrupt level, where 0 represents regular code.
Interrupts are triggered from a separate thread (a CThread instance) which calls :cpp:func:`
When an interrupt
occurs, the level is raised according to the priority of that interrupt. Until that code has finished,
only interrupts of a higher priority will preempt it.

The ``set_interrupt_level`` function is used to ensure that threads running at different interrupt
levels do not pre-empty each other, as this would introduce problems that do not exist on real hardware.
The main thread is also suspended during interrupt execution.
Thread 'interrupt' code is sandwiched between calls to `interrupt_begin()` and `interrupt_end()`,
which blocks interrupts from other threads at the same or lower level.
The threads aren't suspended but will block if they call `interrupt_begin()`.
However, the main thread (level 0) is halted to reflect normal interrupt behaviour.


.. envvar:: LWIP_SERVICE_INTERVAL
Expand Down
2 changes: 2 additions & 0 deletions Sming/Arch/Host/Components/hostlib/component.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ EXTRA_LIBS := pthread

ifeq ($(UNAME),Windows)
EXTRA_LIBS += wsock32
else
EXTRA_LIBS += rt
endif

COMPONENT_DEPENDS := \
Expand Down
5 changes: 3 additions & 2 deletions Sming/Arch/Host/Components/hostlib/hostmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
****/

#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include "include/hostlib/hostmsg.h"
Expand Down Expand Up @@ -72,10 +73,10 @@ void host_printfp(const char* fmt, const char* pretty_function, ...)

size_t host_nputs(const char* str, size_t length)
{
return fwrite(str, 1, length, stderr);
return write(STDERR_FILENO, str, length);
}

void host_puts(const char* str)
{
fputs(str, stderr);
host_nputs(str, strlen(str));
}
Loading