Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • card10/firmware
  • annejan/firmware
  • astro/firmware
  • fpletz/firmware
  • gerd/firmware
  • fleur/firmware
  • swym/firmware
  • l/firmware
  • uberardy/firmware
  • wink/firmware
  • madonius/firmware
  • mot/firmware
  • filid/firmware
  • q3k/firmware
  • hauke/firmware
  • Woazboat/firmware
  • pink/firmware
  • mossmann/firmware
  • omniskop/firmware
  • zenox/firmware
  • trilader/firmware
  • Danukeru/firmware
  • shoragan/firmware
  • zlatko/firmware
  • sistason/firmware
  • datenwolf/firmware
  • bene/firmware
  • amedee/firmware
  • martinling/firmware
  • griffon/firmware
  • chris007/firmware
  • adisbladis/firmware
  • dbrgn/firmware
  • jelly/firmware
  • rnestler/firmware
  • mh/firmware
  • ln/firmware
  • penguineer/firmware
  • monkeydom/firmware
  • jens/firmware
  • jnaulty/firmware
  • jeffmakes/firmware
  • marekventur/firmware
  • pete/firmware
  • h2obrain/firmware
  • DooMMasteR/firmware
  • jackie/firmware
  • prof_r/firmware
  • Draradech/firmware
  • Kartoffel/firmware
  • hinerk/firmware
  • abbradar/firmware
  • JustTB/firmware
  • LuKaRo/firmware
  • iggy/firmware
  • ente/firmware
  • flgr/firmware
  • Lorphos/firmware
  • matejo/firmware
  • ceddral7/firmware
  • danb/firmware
  • joshi/firmware
  • melle/firmware
  • fitch/firmware
  • deurknop/firmware
  • sargon/firmware
  • markus/firmware
  • kloenk/firmware
  • lucaswerkmeister/firmware
  • derf/firmware
  • meh/firmware
  • dx/card10-firmware
  • torben/firmware
  • yuvadm/firmware
  • AndyBS/firmware
  • klausdieter1/firmware
  • katzenparadoxon/firmware
  • xiretza/firmware
  • ole/firmware
  • techy/firmware
  • thor77/firmware
  • TilCreator/firmware
  • fuchsi/firmware
  • dos/firmware
  • yrlf/firmware
  • PetePriority/firmware
  • SuperVirus/firmware
  • sur5r/firmware
  • tazz/firmware
  • Alienmaster/firmware
  • flo_h/firmware
  • baldo/firmware
  • mmu_man/firmware
  • Foaly/firmware
  • sodoku/firmware
  • Guinness/firmware
  • ssp/firmware
  • led02/firmware
  • Stormwind/firmware
  • arist/firmware
  • coon/firmware
  • mdik/firmware
  • pippin/firmware
  • royrobotiks/firmware
  • zigot83/firmware
  • mo_k/firmware
106 results
Select Git revision
Loading items
Show changes
Showing
with 1032 additions and 246 deletions
......@@ -18,7 +18,8 @@ static char heap[4096];
int mp_hal_stdin_rx_chr(void);
int main(int argc, char **argv) {
int main(int argc, char **argv)
{
int stack_dummy;
stack_top = (char *)&stack_dummy;
leds_init();
......@@ -33,39 +34,52 @@ int main(int argc, char **argv) {
return 0;
}
void gc_collect(void) {
void gc_collect(void)
{
// WARNING: This gc_collect implementation doesn't try to get root
// pointers from CPU registers, and thus may function incorrectly.
void *dummy;
gc_collect_start();
gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t));
gc_collect_root(
&dummy,
((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t)
);
gc_collect_end();
gc_dump_info();
}
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
mp_lexer_t *mp_lexer_new_from_file(const char *filename)
{
mp_raise_OSError(MP_ENOENT);
}
mp_import_stat_t mp_import_stat(const char *path) {
mp_import_stat_t mp_import_stat(const char *path)
{
return MP_IMPORT_STAT_NO_EXIST;
}
mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs)
{
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
void nlr_jump_fail(void *val) {
while (1);
void nlr_jump_fail(void *val)
{
while (1)
;
}
void NORETURN __fatal_error(const char *msg) {
while (1);
void NORETURN __fatal_error(const char *msg)
{
while (1)
;
}
#ifndef NDEBUG
void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
void MP_WEAK
__assert_func(const char *file, int line, const char *func, const char *expr)
{
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
__fatal_error("Assertion failed");
}
......
......@@ -11,11 +11,8 @@ STATIC mp_obj_t mp_leds_set(size_t n_args, const mp_obj_t *args)
int g = mp_obj_get_int(args[2]);
int b = mp_obj_get_int(args[3]);
if ( (0 > led || 256 < led) &&
(0 > r || 256 < r) &&
(0 > g || 256 < g) &&
(0 > b || 256 < b) )
{
if ((0 > led || 256 < led) && (0 > r || 256 < r) &&
(0 > g || 256 < g) && (0 > b || 256 < b)) {
mp_raise_ValueError("out of bounds");
}
printf("Set %u to (%x %x %x)\n", led, r, g, b);
......@@ -31,9 +28,7 @@ STATIC mp_obj_t mp_leds_set_dim(mp_obj_t led_obj, mp_obj_t dim_obj)
int led = mp_obj_get_int(led_obj);
int dim = mp_obj_get_int(dim_obj);
if ( (0 > led || 256 < led) &&
(0 > dim || 256 < dim) )
{
if ((0 > led || 256 < led) && (0 > dim || 256 < dim)) {
mp_raise_ValueError("out of bounds");
}
leds_set_dim(led, dim);
......
......@@ -16,7 +16,8 @@ STATIC const mp_rom_map_elem_t time_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_ticks_us), MP_ROM_PTR(&mp_utime_ticks_us_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_diff),
MP_ROM_PTR(&mp_utime_ticks_diff_obj) },
};
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
......
#include "py/mpconfig.h"
#include "mxc_delay.h"
void mp_hal_delay_ms(mp_uint_t ms) {
void mp_hal_delay_ms(mp_uint_t ms)
{
mxc_delay(ms * 1000); // TODO check return value
}
void mp_hal_delay_us(mp_uint_t us) {
void mp_hal_delay_us(mp_uint_t us)
{
mxc_delay(us); // TODO check return value
}
mp_uint_t mp_hal_ticks_ms(void) {
mp_uint_t mp_hal_ticks_ms(void)
{
return 0;
}
mp_uint_t mp_hal_ticks_us(void) {
mp_uint_t mp_hal_ticks_us(void)
{
return 0;
}
mp_uint_t mp_hal_ticks_cpu(void) {
mp_uint_t mp_hal_ticks_cpu(void)
{
return 0;
}
......@@ -9,15 +9,18 @@
extern mxc_uart_regs_t *ConsoleUart;
// Receive single character
int mp_hal_stdin_rx_chr(void) {
int mp_hal_stdin_rx_chr(void)
{
return UART_ReadByte(ConsoleUart);
}
// Send string of given length
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len)
{
UART_Write(ConsoleUart, (uint8_t *)str, len);
}
void mp_hal_set_interrupt_char(char c) {
void mp_hal_set_interrupt_char(char c)
{
return;
}
......@@ -3,3 +3,33 @@ target remote localhost:3333
define reset
mon mww 0x40000004 0x80000000
end
# usage: task_backtrace <tskTCB*>
define task_backtrace
set $taskbt_task_ptr = $arg0
set $taskbt_stack_ptr = $taskbt_task_ptr->pxTopOfStack
set $taskbt_frame_offset = 9
if ((*(uint32_t*)($taskbt_stack_ptr + 8)) & 0x10 == 0)
echo FPU is on\n
set $taskbt_frame_offset += 16
else
echo FPU is off\n
end
set $taskbt_reg_lr = $lr
set $taskbt_reg_pc = $pc
set $taskbt_reg_sp = $sp
set $lr = *($taskbt_stack_ptr + $taskbt_frame_offset + 5)
set $pc = *($taskbt_stack_ptr + $taskbt_frame_offset + 6)
set $sp = $taskbt_stack_ptr + $taskbt_frame_offset + 8
bt
set $lr = $taskbt_reg_lr
set $pc = $taskbt_reg_pc
set $sp = $taskbt_reg_sp
end
alias tbt = task_backtrace
blinky
======
It works! Blink it!
This is a battery-hungry l0dable that shows you how to blink some LEDs while burning CPU time and battery.
#include "epicardium.h"
#include <math.h>
#include <stdio.h>
int levels[11] = { 0 };
int levels_display[11] = { 0 };
void fade()
{
for (int i = 0; i < 11; i++) {
int level = levels[i];
if (levels_display[i] > 0) {
epic_leds_set(i, level, 0, 0);
if (level == 0) {
levels_display[i] = 0;
}
}
if (levels[i] > 0) {
levels[i]--;
}
}
}
/*
* main() is called when l0dable is loaded and executed.
*
* When main() returns, card10 goes back to the menu. A non-zero return value
* can be used to signal some kind of failure during l0dable execution.
*/
int main(void)
{
printf("Hello from blinky!\n");
epic_leds_dim_top(6);
// l0dables are running on a separate, exclusive-to-l0dables core.
// Busy-waiting will not block the main operating system on core0 from
// running - but it will drain batteries.
for (;;) {
for (int i = 0; i < 11; i++) {
levels[i] = 128;
levels_display[i] = 1;
for (int j = 0; j < 32; j++) {
fade();
}
}
for (int i = 9; i > 0; i--) {
levels[i] = 128;
levels_display[i] = 1;
for (int j = 0; j < 32; j++) {
fade();
}
}
}
}
name = 'blinky'
elf = executable(
name + '.elf',
'main.c',
build_by_default: true,
dependencies: [l0dable_startup, api_caller],
link_whole: [l0dable_startup_lib],
link_args: [
'-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
],
pie: true,
)
/*
* C Runtime for l0dable.
*
* Also known as a startup file.
*
* We provide the following to l0dables:
* - calling GCC initializers.
* - an ISR vector.
*
* The stack is provided by l0der.
*/
.syntax unified
.arch armv7-m
/*
* ISR Vector.
*
* All of the following (apart from Reset_Handler, which calls main())
* are backed by weak referenced symbols, which you can override just
* by defining them in C code.
*/
.section .text.isr_vector
.align 7
.globl __isr_vector
__isr_vector:
.long 0 /* Top of Stack, overriden by l0der at load time */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long MemManage_Handler /* MPU Fault Handler */
.long BusFault_Handler /* Bus Fault Handler */
.long UsageFault_Handler /* Usage Fault Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long 0 /* Reserved */ /* @TODO: Is this the Debug Montior Interrupt? */
.long 0 /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* Device-specific Interrupts */
.long PF_IRQHandler /* 0x10 0x0040 16: Power Fail */
.long WDT0_IRQHandler /* 0x11 0x0044 17: Watchdog 0 */
.long DefaultHandler /* 0x12 0x0048 18: USB, used by core0, unoverridable */
.long RTC_IRQHandler /* 0x13 0x004C 19: RTC */
.long TRNG_IRQHandler /* 0x14 0x0050 20: True Random Number Generator */
.long TMR0_IRQHandler /* 0x15 0x0054 21: Timer 0 */
.long TMR1_IRQHandler /* 0x16 0x0058 22: Timer 1 */
.long TMR2_IRQHandler /* 0x17 0x005C 23: Timer 2 */
.long TMR3_IRQHandler /* 0x18 0x0060 24: Timer 3*/
.long TMR4_IRQHandler /* 0x19 0x0064 25: Timer 4*/
.long TMR5_IRQHandler /* 0x1A 0x0068 26: Timer 5 */
.long RSV11_IRQHandler /* 0x1B 0x006C 27: Reserved */
.long RSV12_IRQHandler /* 0x1C 0x0070 28: Reserved */
.long I2C0_IRQHandler /* 0x1D 0x0074 29: I2C0 */
.long DefaultHandler /* 0x1E 0x0078 30: UART 0, used by core0, unoverridable */
.long UART1_IRQHandler /* 0x1F 0x007C 31: UART 1 */
.long SPI1_IRQHandler /* 0x20 0x0080 32: SPI1 */
.long SPI2_IRQHandler /* 0x21 0x0084 33: SPI2 */
.long RSV18_IRQHandler /* 0x22 0x0088 34: Reserved */
.long RSV19_IRQHandler /* 0x23 0x008C 35: Reserved */
.long ADC_IRQHandler /* 0x24 0x0090 36: ADC */
.long RSV21_IRQHandler /* 0x25 0x0094 37: Reserved */
.long RSV22_IRQHandler /* 0x26 0x0098 38: Reserved */
.long FLC0_IRQHandler /* 0x27 0x009C 39: Flash Controller */
.long DefaultHandler /* 0x28 0x00A0 40: GPIO0, used by core0, unoverridable */
.long DefaultHandler /* 0x29 0x00A4 41: GPIO2, used by core0, unoverridable */
.long RSV26_IRQHandler /* 0x2A 0x00A8 42: GPIO3 */
.long TPU_IRQHandler /* 0x2B 0x00AC 43: Crypto */
.long DMA0_IRQHandler /* 0x2C 0x00B0 44: DMA0 */
.long DMA1_IRQHandler /* 0x2D 0x00B4 45: DMA1 */
.long DMA2_IRQHandler /* 0x2E 0x00B8 46: DMA2 */
.long DMA3_IRQHandler /* 0x2F 0x00BC 47: DMA3 */
.long RSV32_IRQHandler /* 0x30 0x00C0 48: Reserved */
.long RSV33_IRQHandler /* 0x31 0x00C4 49: Reserved */
.long UART2_IRQHandler /* 0x32 0x00C8 50: UART 2 */
.long RSV35_IRQHandler /* 0x33 0x00CC 51: Reserved */
.long I2C1_IRQHandler /* 0x34 0x00D0 52: I2C1 */
.long RSV37_IRQHandler /* 0x35 0x00D4 53: Reserved */
.long SPIXFC_IRQHandler /* 0x36 0x00D8 54: SPI execute in place */
.long BTLE_TX_DONE_IRQHandler /* 0x37 0x00DC 55: BTLE TX Done */
.long BTLE_RX_RCVD_IRQHandler /* 0x38 0x00E0 56: BTLE RX Recived */
.long BTLE_RX_ENG_DET_IRQHandler /* 0x39 0x00E4 57: BTLE RX Energy Dectected */
.long BTLE_SFD_DET_IRQHandler /* 0x3A 0x00E8 58: BTLE SFD Detected */
.long BTLE_SFD_TO_IRQHandler /* 0x3B 0x00EC 59: BTLE SFD Timeout*/
.long BTLE_GP_EVENT_IRQHandler /* 0x3C 0x00F0 60: BTLE Timestamp*/
.long BTLE_CFO_IRQHandler /* 0x3D 0x00F4 61: BTLE CFO Done */
.long BTLE_SIG_DET_IRQHandler /* 0x3E 0x00F8 62: BTLE Signal Detected */
.long BTLE_AGC_EVENT_IRQHandler /* 0x3F 0x00FC 63: BTLE AGC Event */
.long BTLE_RFFE_SPIM_IRQHandler /* 0x40 0x0100 64: BTLE RFFE SPIM Done */
.long BTLE_TX_AES_IRQHandler /* 0x41 0x0104 65: BTLE TX AES Done */
.long BTLE_RX_AES_IRQHandler /* 0x42 0x0108 66: BTLE RX AES Done */
.long BTLE_INV_APB_ADDR_IRQHandler /* 0x43 0x010C 67: BTLE Invalid APB Address*/
.long BTLE_IQ_DATA_VALID_IRQHandler /* 0x44 0x0110 68: BTLE IQ Data Valid */
.long WUT_IRQHandler /* 0x45 0x0114 69: WUT Wakeup */
.long GPIOWAKE_IRQHandler /* 0x46 0x0118 70: GPIO Wakeup */
.long RSV55_IRQHandler /* 0x47 0x011C 71: Reserved */
.long SPI0_IRQHandler /* 0x48 0x0120 72: SPI AHB */
.long WDT1_IRQHandler /* 0x49 0x0124 73: Watchdog 1 */
.long RSV58_IRQHandler /* 0x4A 0x0128 74: Reserved */
.long PT_IRQHandler /* 0x4B 0x012C 75: Pulse train */
.long SDMA0_IRQHandler /* 0x4C 0x0130 76: Smart DMA 0 */
.long RSV61_IRQHandler /* 0x4D 0x0134 77: Reserved */
.long I2C2_IRQHandler /* 0x4E 0x0138 78: I2C 2 */
.long RSV63_IRQHandler /* 0x4F 0x013C 79: Reserved */
.long RSV64_IRQHandler /* 0x50 0x0140 80: Reserved */
.long RSV65_IRQHandler /* 0x51 0x0144 81: Reserved */
.long SDHC_IRQHandler /* 0x52 0x0148 82: SDIO/SDHC */
.long OWM_IRQHandler /* 0x53 0x014C 83: One Wire Master */
.long DMA4_IRQHandler /* 0x54 0x0150 84: DMA4 */
.long DMA5_IRQHandler /* 0x55 0x0154 85: DMA5 */
.long DMA6_IRQHandler /* 0x56 0x0158 86: DMA6 */
.long DMA7_IRQHandler /* 0x57 0x015C 87: DMA7 */
.long DMA8_IRQHandler /* 0x58 0x0160 88: DMA8 */
.long DMA9_IRQHandler /* 0x59 0x0164 89: DMA9 */
.long DMA10_IRQHandler /* 0x5A 0x0168 90: DMA10 */
.long DMA11_IRQHandler /* 0x5B 0x016C 91: DMA11 */
.long DMA12_IRQHandler /* 0x5C 0x0170 92: DMA12 */
.long DMA13_IRQHandler /* 0x5D 0x0174 93: DMA13 */
.long DMA14_IRQHandler /* 0x5E 0x0178 94: DMA14 */
.long DMA15_IRQHandler /* 0x5F 0x017C 95: DMA15 */
.long USBDMA_IRQHandler /* 0x60 0x0180 96: USB DMA */
.long WDT2_IRQHandler /* 0x61 0x0184 97: Watchdog Timer 2 */
.long ECC_IRQHandler /* 0x62 0x0188 98: Error Correction */
.long DVS_IRQHandler /* 0x63 0x018C 99: DVS Controller */
.long SIMO_IRQHandler /* 0x64 0x0190 100: SIMO Controller */
.long RPU_IRQHandler /* 0x65 0x0194 101: RPU */ /* @TODO: Is this correct? */
.long AUDIO_IRQHandler /* 0x66 0x0198 102: Audio subsystem */
.long FLC1_IRQHandler /* 0x67 0x019C 103: Flash Control 1 */
.long RSV88_IRQHandler /* 0x68 0x01A0 104: UART 3 */
.long RSV89_IRQHandler /* 0x69 0x01A4 105: UART 4 */
.long RSV90_IRQHandler /* 0x6A 0x01A8 106: UART 5 */
.long RSV91_IRQHandler /* 0x6B 0x01AC 107: Camera IF */
.long RSV92_IRQHandler /* 0x6C 0x01B0 108: I3C */
.long HTMR0_IRQHandler /* 0x6D 0x01B4 109: HTmr */
.long HTMR1_IRQHandler /* 0x6E 0x01B8 109: HTmr */
/*
* Reset_Handler, or, l0dable entrypoint.
*/
.text
.thumb
.thumb_func
.align 2
Reset_Handler:
/* Call system initialization from l0dables/lib/hardware.c. */
blx SystemInit
/* Call GCC constructors. */
ldr r0, =__libc_init_array
blx r0
/* Jump to C code */
ldr r0, =main
blx r0
/* C code done, return to menu. Return code is what main() returned. */
ldr r4, =epic_exit
blx r4
/*
* Used by __libc_init_array.
*/
.globl _init
_init:
bx lr
/*
* The default handler for all IRQs just spins forwever.
* TODO(q3k): let epicardium know we've reached an infinite loop due to
* an exception and/or unhandled IRQ, perhaps by splitting
* DefaultHandler into multiple handlers that report different
* error conditions to epicardium (eg. unhandled IRQ, fault, ...)
*/
.thumb_func
.type DefaultHandler, %function
DefaultHandler:
b .
.macro def_irq_handler handler_name
.weakref \handler_name, DefaultHandler
.endm
/*
* Declare all default ISRs.
*/
def_irq_handler PF_IRQHandler
def_irq_handler WDT0_IRQHandler
def_irq_handler RTC_IRQHandler
def_irq_handler TRNG_IRQHandler
def_irq_handler TMR0_IRQHandler
def_irq_handler TMR1_IRQHandler
def_irq_handler TMR2_IRQHandler
def_irq_handler TMR3_IRQHandler
def_irq_handler TMR4_IRQHandler
def_irq_handler RSV11_IRQHandler
def_irq_handler RSV12_IRQHandler
def_irq_handler I2C0_IRQHandler
def_irq_handler UART1_IRQHandler
def_irq_handler SPI1_IRQHandler
def_irq_handler SPI2_IRQHandler
def_irq_handler RSV18_IRQHandler
def_irq_handler RSV19_IRQHandler
def_irq_handler ADC_IRQHandler
def_irq_handler RSV21_IRQHandler
def_irq_handler RSV22_IRQHandler
def_irq_handler FLC0_IRQHandler
def_irq_handler RSV26_IRQHandler
def_irq_handler TPU_IRQHandler
def_irq_handler DMA0_IRQHandler
def_irq_handler DMA1_IRQHandler
def_irq_handler DMA2_IRQHandler
def_irq_handler DMA3_IRQHandler
def_irq_handler RSV32_IRQHandler
def_irq_handler RSV33_IRQHandler
def_irq_handler UART2_IRQHandler
def_irq_handler RSV35_IRQHandler
def_irq_handler I2C1_IRQHandler
def_irq_handler RSV37_IRQHandler
def_irq_handler SPIXFC_IRQHandler
def_irq_handler BTLE_TX_DONE_IRQHandler
def_irq_handler BTLE_RX_RCVD_IRQHandler
def_irq_handler BTLE_RX_ENG_DET_IRQHandler
def_irq_handler BTLE_SFD_DET_IRQHandler
def_irq_handler BTLE_SFD_TO_IRQHandler
def_irq_handler BTLE_GP_EVENT_IRQHandler
def_irq_handler BTLE_CFO_IRQHandler
def_irq_handler BTLE_SIG_DET_IRQHandler
def_irq_handler BTLE_AGC_EVENT_IRQHandler
def_irq_handler BTLE_RFFE_SPIM_IRQHandler
def_irq_handler BTLE_TX_AES_IRQHandler
def_irq_handler BTLE_RX_AES_IRQHandler
def_irq_handler BTLE_INV_APB_ADDR_IRQHandler
def_irq_handler BTLE_IQ_DATA_VALID_IRQHandler
def_irq_handler WUT_IRQHandler
def_irq_handler GPIOWAKE_IRQHandler
def_irq_handler RSV55_IRQHandler
def_irq_handler SPI0_IRQHandler
def_irq_handler WDT1_IRQHandler
def_irq_handler RSV58_IRQHandler
def_irq_handler PT_IRQHandler
def_irq_handler SDMA0_IRQHandler
def_irq_handler RSV61_IRQHandler
def_irq_handler I2C2_IRQHandler
def_irq_handler RSV63_IRQHandler
def_irq_handler RSV64_IRQHandler
def_irq_handler RSV65_IRQHandler
def_irq_handler SDHC_IRQHandler
def_irq_handler OWM_IRQHandler
def_irq_handler DMA4_IRQHandler
def_irq_handler DMA5_IRQHandler
def_irq_handler DMA6_IRQHandler
def_irq_handler DMA7_IRQHandler
def_irq_handler DMA8_IRQHandler
def_irq_handler DMA9_IRQHandler
def_irq_handler DMA10_IRQHandler
def_irq_handler DMA11_IRQHandler
def_irq_handler DMA12_IRQHandler
def_irq_handler DMA13_IRQHandler
def_irq_handler DMA14_IRQHandler
def_irq_handler DMA15_IRQHandler
def_irq_handler USBDMA_IRQHandler
def_irq_handler WDT2_IRQHandler
def_irq_handler ECC_IRQHandler
def_irq_handler DVS_IRQHandler
def_irq_handler SIMO_IRQHandler
def_irq_handler RPU_IRQHandler
def_irq_handler AUDIO_IRQHandler
def_irq_handler FLC1_IRQHandler
def_irq_handler RSV88_IRQHandler
def_irq_handler RSV89_IRQHandler
def_irq_handler RSV90_IRQHandler
def_irq_handler RSV91_IRQHandler
def_irq_handler RSV92_IRQHandler
def_irq_handler HTMR0_IRQHandler
def_irq_handler HTMR1_IRQHandler
.section .cinterp
.asciz "card10-l0dable"
.byte
/*
* Hardware routines for l0dables.
*
* You shouldn't have to do much here. SystemInit/SystemCoreClockUpdate are
* called automatically before main(), and provide you with a sensible execution
* environment.
*
* However, if you wish, you can define your own SystemInit and take over the
* initialization before main() gets called.
*/
#include <stddef.h>
#include "epicardium.h"
#include "max32665.h"
#include "mxc_sys.h"
#include "gcr_regs.h"
#include "icc_regs.h"
#include "pwrseq_regs.h"
uint32_t SystemCoreClock = HIRC_FREQ >> 1;
void SystemCoreClockUpdate(void)
{
uint32_t base_freq, div, clk_src;
// Determine the clock source and frequency
clk_src = (MXC_GCR->clkcn & MXC_F_GCR_CLKCN_CLKSEL);
switch (clk_src) {
case MXC_S_GCR_CLKCN_CLKSEL_HIRC:
base_freq = HIRC_FREQ;
break;
case MXC_S_GCR_CLKCN_CLKSEL_XTAL32M:
base_freq = XTAL32M_FREQ;
break;
case MXC_S_GCR_CLKCN_CLKSEL_LIRC8:
base_freq = LIRC8_FREQ;
break;
case MXC_S_GCR_CLKCN_CLKSEL_HIRC96:
base_freq = HIRC96_FREQ;
break;
case MXC_S_GCR_CLKCN_CLKSEL_HIRC8:
base_freq = HIRC8_FREQ;
break;
case MXC_S_GCR_CLKCN_CLKSEL_XTAL32K:
base_freq = XTAL32K_FREQ;
break;
default:
// Values 001 and 111 are reserved, and should never be encountered.
base_freq = HIRC_FREQ;
break;
}
// Clock divider is retrieved to compute system clock
div = (MXC_GCR->clkcn & MXC_F_GCR_CLKCN_PSC) >> MXC_F_GCR_CLKCN_PSC_POS;
SystemCoreClock = base_freq >> div;
}
__weak void SystemInit()
{
// Enable FPU.
SCB->CPACR |= SCB_CPACR_CP10_Msk | SCB_CPACR_CP11_Msk;
__DSB();
__ISB();
// Enable ICache1 Clock
MXC_GCR->perckcn1 &= ~(1 << 22);
// Invalidate cache and wait until ready
MXC_ICC1->invalidate = 1;
while (!(MXC_ICC1->cache_ctrl & MXC_F_ICC_CACHE_CTRL_CACHE_RDY))
;
// Enable Cache
MXC_ICC1->cache_ctrl |= MXC_F_ICC_CACHE_CTRL_CACHE_EN;
SystemCoreClockUpdate();
// Enable API interrupt.
NVIC_EnableIRQ(TMR5_IRQn);
}
// newlib syscall to allow printf to work.
long _write(int fd, const char *buf, size_t cnt)
{
// Only print one line at a time. Insert `\r` between lines so
// they are properly displayed on the serial console.
size_t i, last = 0;
for (i = 0; i < cnt; i++) {
if (buf[i] == '\n') {
epic_uart_write_str(&buf[last], i - last);
epic_uart_write_str("\r", 1);
last = i;
}
}
epic_uart_write_str(&buf[last], cnt - last);
return cnt;
}
// newlib syscall to allow for a heap
extern uint32_t __heap_start;
uint32_t _sbrk(int incr)
{
static char *brk = NULL;
if (brk == NULL) {
brk = (char *)&__heap_start;
}
// Ensure we don't overflow the heap by checking agsinst the current stack
// pointer (the heap grows towards the stack, and vice-versa).
//
// This is only a last-ditch attempt at saving ourselves from memory
// corruption. It doesn't prevent the stack from growing into the heap
// first.
void *sp;
__asm__ __volatile__("mov %0, sp" : "=r"(sp));
// Require a 'safe margin' of 4k between the heap and stack.
uint32_t stack_bottom = (uint32_t)sp - 4096;
if (((uint32_t)brk + incr) > stack_bottom) {
errno = ENOMEM;
return (uint32_t)-1;
}
char *prev_brk = brk;
brk += incr;
return (uint32_t)prev_brk;
}
void HardFault_Handler(void)
{
/*
* We pray that we're not currently in an API call and attempt
* returning. This is okay because a HardFault during an API call is
* extremely unlikely.
*
* In the future, we could improve this by "finishing" an ongoing API
* call before firing epic_exit().
*/
epic_exit(255);
}
/* Alias all other exception handlers to the HardFault_Handler. */
void NMI_Handler(void) __attribute__((alias("HardFault_Handler")));
void MemManage_Handler(void) __attribute__((alias("HardFault_Handler")));
void BusFault_Handler(void) __attribute__((alias("HardFault_Handler")));
void UsageFault_Handler(void) __attribute__((alias("HardFault_Handler")));
void SVC_Handler(void) __attribute__((alias("HardFault_Handler")));
void DebugMon_Handler(void) __attribute__((alias("HardFault_Handler")));
void PendSV_Handler(void) __attribute__((alias("HardFault_Handler")));
ENTRY(__isr_vector);
/*
* Segment in the output l0dable.
*
* They are mostly standard, but we define them explicitely so that we can
* target them in sections.
*/
PHDRS
{
header PT_PHDR PHDRS ;
interp PT_INTERP ;
text PT_LOAD FILEHDR PHDRS ;
data PT_LOAD ;
}
/*
* ELF sections.
*/
SECTIONS {
. = SIZEOF_HEADERS;
/*
* Customer card10-l0dable INTERP/intepreter path.
*
* We nuke the original one (.interp) provided by gcc/ld, and inject out
* own. This section is populated in l0dable.ld.
*/
.cinterp :
{
*(.cinterp);
} :interp :text
.text :
{
/* The vector table needs 128 byte alignment */
. = ALIGN(128);
KEEP(*(.text.isr_vector))
*(.text*)
*(.rodata*)
KEEP(*(.init))
KEEP(*(.fini))
} :text
.data :
{
. = ALIGN(4);
*(.data*)
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
} :data
.bss :
{
. = ALIGN(4);
*(.bss*)
*(COMMON)
} :data
/* Used by hardware.c as start of heap. */
__heap_start = .;
/* Limit based on current limitations of l0dable setup - only uses core1 RAM. */
ASSERT(. < 0x40000, "Exceeded available RAM")
/DISCARD/ :
{
/* Compiler version - nuke. */
*(.comment)
/* ARM attributes - nuke. */
*(.ARM.attributes)
/* Original interpreter path from gcc/ld - nuke. */
*(.interp)
/* Dynamic linking section - nuke, we're not a .so and nothing is going to link against us. */
*(.dynamic)
}
}
l0dable_startup_lib = static_library(
'l0dable-startup',
'crt.s',
'hardware.c',
dependencies: [api_caller],
c_args: ['-fpie'],
)
l0dable_startup = declare_dependency(
link_args: [
'-nostdlib', '-n',
'-T', meson.current_source_dir() + 'l0dable.ld',
],
compile_args: [
'-fPIE', '-pie',
],
)
subdir('lib/')
subdir('blinky/')
......@@ -20,7 +20,8 @@ static void hexdump(uint8_t *data, uint8_t len)
}
#endif
int8_t card10_bosch_i2c_write(uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_t size)
int8_t
card10_bosch_i2c_write(uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_t size)
{
uint8_t buf[size + 1];
......@@ -34,7 +35,8 @@ int8_t card10_bosch_i2c_write(uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_
//return l == size + 1 ? BHY_SUCCESS : BHY_ERROR;
}
int8_t card10_bosch_i2c_read(uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_t size)
int8_t
card10_bosch_i2c_read(uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_t size)
{
//printf("sensor_i2c_read 0x%02x %d\n", reg, size);
if (I2C_MasterWrite(I2C_DEVICE, addr << 1, &reg, 1, 1) == 1) {
......@@ -43,7 +45,6 @@ int8_t card10_bosch_i2c_read(uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_t
//printf("read:"); hexdump(p_buf, l);
return l == size ? 0 : -1;
//return l == size ? BHY_SUCCESS : BHY_ERROR;
}
return -1;
//return BHY_ERROR;
......@@ -54,12 +55,14 @@ void card10_bosch_delay(uint32_t msec)
TMR_Delay(MXC_TMR0, MSEC(msec), 0);
}
int8_t card10_bosch_i2c_write_ex(void *_, uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_t size)
{
int8_t card10_bosch_i2c_write_ex(
void *_, uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_t size
) {
return card10_bosch_i2c_write(addr, reg, p_buf, size);
}
int8_t card10_bosch_i2c_read_ex(void *_, uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_t size)
{
int8_t card10_bosch_i2c_read_ex(
void *_, uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_t size
) {
return card10_bosch_i2c_read(addr, reg, p_buf, size);
}
#include "card10.h"
#include "pmic.h"
#include "bosch.h"
#include "display.h"
......@@ -24,13 +25,13 @@
#include <stdint.h>
#include <string.h>
/* XXX: The display supports max 15 Mhz, but we have stability issues at that rate.
* Current suspicion is that the SDK is buggy.
*
* At 12 MHz things seem stable*/
#define SPI_SPEED (12 * 1000 * 1000) // Bit Rate. Display has 15 MHz limit
const gpio_cfg_t bhi_interrupt_pin = {
PORT_0, PIN_13, GPIO_FUNC_IN, GPIO_PAD_PULL_UP
};
const gpio_cfg_t bhi_interrupt_pin = {PORT_0, PIN_13, GPIO_FUNC_IN, GPIO_PAD_PULL_UP};
static const gpio_cfg_t pwr_hold_pin = {
PORT_0, PIN_30, GPIO_FUNC_OUT, GPIO_PAD_NONE
};
void card10_init(void)
{
......@@ -43,20 +44,33 @@ void card10_init(void)
I2C_Shutdown(MXC_I2C1_BUS0);
I2C_Init(MXC_I2C1_BUS0, I2C_FAST_MODE, NULL);
portexpander_init();
GPIO_Init();
PB_Init();
GPIO_Config(&pwr_hold_pin);
GPIO_OutSet(&pwr_hold_pin);
pmic_init();
pmic_set_led(0, 0);
pmic_set_led(1, 0);
pmic_set_led(2, 0);
portexpander_init();
PB_Init();
TMR_Delay(MXC_TMR0, MSEC(1000), 0);
// Enable 32 kHz output
RTC_SquareWave(MXC_RTC, SQUARE_WAVE_ENABLED, F_32KHZ, NOISE_IMMUNE_MODE, NULL);
while (RTC_SquareWave(MXC_RTC, SQUARE_WAVE_ENABLED, F_32KHZ, NULL) ==
E_BUSY)
;
/* If we don't have a valid time yet, set it to 2019-01-01 */
if (RTC_GetSecond() < 1546300800L) {
while (RTC_Init(MXC_RTC, 1546300800UL, 0, NULL) == E_BUSY)
;
}
while (RTC_EnableRTCE(MXC_RTC) == E_BUSY)
;
// Enable SPI
sys_cfg_spi_t spi17y_master_cfg;
......@@ -65,15 +79,11 @@ void card10_init(void)
spi17y_master_cfg.ss0 = Enable;
spi17y_master_cfg.ss1 = Disable;
spi17y_master_cfg.ss2 = Disable;
spi17y_master_cfg.num_io = 2;
if (SPI_Init(SPI0, 0, SPI_SPEED, spi17y_master_cfg) != 0) {
printf("Error configuring SPI\n");
while (1);
}
if (SPI_Init(SPI2, 0, SPI_SPEED, spi17y_master_cfg) != 0) {
printf("Error configuring SPI\n");
while (1);
while (1)
;
}
display_init();
......@@ -81,7 +91,6 @@ void card10_init(void)
leds_init();
GPIO_Config(&bhi_interrupt_pin);
}
static uint32_t ecg_read_reg(uint8_t reg)
......@@ -111,7 +120,8 @@ void card10_diag(void)
// "7-bit addresses 0b0000xxx and 0b1111xxx are reserved"
for (int addr = 0x8; addr < 0x78; ++addr) {
// A 0 byte write does not seem to work so always send a single byte.
int res = I2C_MasterWrite(MXC_I2C0_BUS0, addr << 1, dummy, 1, 0);
int res =
I2C_MasterWrite(MXC_I2C0_BUS0, addr << 1, dummy, 1, 0);
if (res == 1) {
printf("Found (7 bit) address 0x%02x on I2C0\n", addr);
}
......@@ -126,26 +136,35 @@ void card10_diag(void)
printf("Failed to init bhy\n");
} else {
/* wait for the bhy trigger the interrupt pin go down and up again */
while (GPIO_InGet(&bhi_interrupt_pin));
while (!GPIO_InGet(&bhi_interrupt_pin));
while (GPIO_InGet(&bhi_interrupt_pin))
;
while (!GPIO_InGet(&bhi_interrupt_pin))
;
/* the remapping matrix for BHI and Magmetometer should be configured here to make sure rotation vector is */
/* calculated in a correct coordinates system. */
int8_t bhy_mapping_matrix_config[3*3] = {0,-1,0,1,0,0,0,0,1};
int8_t mag_mapping_matrix_config[3*3] = {-1,0,0,0,1,0,0,0,-1};
bhy_mapping_matrix_set(PHYSICAL_SENSOR_INDEX_ACC, bhy_mapping_matrix_config);
bhy_mapping_matrix_set(PHYSICAL_SENSOR_INDEX_MAG, mag_mapping_matrix_config);
bhy_mapping_matrix_set(PHYSICAL_SENSOR_INDEX_GYRO, bhy_mapping_matrix_config);
int8_t bhy_mapping_matrix_config[3 * 3] = { 0, -1, 0, 1, 0,
0, 0, 0, 1 };
int8_t mag_mapping_matrix_config[3 * 3] = { -1, 0, 0, 0, 1,
0, 0, 0, -1 };
bhy_mapping_matrix_set(
PHYSICAL_SENSOR_INDEX_ACC, bhy_mapping_matrix_config
);
bhy_mapping_matrix_set(
PHYSICAL_SENSOR_INDEX_MAG, mag_mapping_matrix_config
);
bhy_mapping_matrix_set(
PHYSICAL_SENSOR_INDEX_GYRO, bhy_mapping_matrix_config
);
/* the sic matrix should be calculated for customer platform by logging uncalibrated magnetometer data. */
/* the sic matrix here is only an example array (identity matrix). Customer should generate their own matrix. */
/* This affects magnetometer fusion performance. */
float sic_array[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
float sic_array[9] = { 1.0, 0.0, 0.0, 0.0, 1.0,
0.0, 0.0, 0.0, 1.0 };
bhy_set_sic_matrix(sic_array);
}
struct bme680_dev gas_sensor;
gas_sensor.dev_id = BME680_I2C_ADDR_PRIMARY;
gas_sensor.intf = BME680_I2C_INTF;
......@@ -182,22 +201,39 @@ void card10_diag(void)
uint32_t val = ecg_read_reg(0xf);
printf("ECG: %02x: 0x%06lx (should be 0x5139a0)\n", 0xf, val);
#endif
}
void core1_start(void) {
//MXC_GCR->gp0 = (uint32_t)(&__isr_vector_core1);
MXC_GCR->gp0 = 0x10080000;
void core1_start(void *isr)
{
MXC_GCR->gp0 = (uint32_t)isr;
MXC_GCR->perckcn1 &= ~MXC_F_GCR_PERCKCN1_CPU1;
}
void core1_stop(void) {
void core1_stop(void)
{
MXC_GCR->perckcn1 |= MXC_F_GCR_PERCKCN1_CPU1;
}
void card10_poll(void)
{
pmic_poll();
portexpander_poll();
}
void __attribute__((noreturn)) card10_reset(void)
{
printf("Resetting ...\n");
/*
* Give the UART fifo time to clear.
* TODO: Do this properly
*/
for (int i = 0; i < 0x1000000; i++) {
__asm volatile("nop");
}
MXC_GCR->rstr0 = MXC_F_GCR_RSTR0_SYSTEM;
while (1)
__WFI();
}
void GPIO0_IRQHandler(void)
......@@ -219,4 +255,3 @@ void GPIO3_IRQHandler(void)
{
GPIO_Handler(PORT_3);
}
......@@ -4,13 +4,16 @@
#include <stdint.h>
#define SPI_SPEED (15 * 1000 * 1000) // Bit Rate
extern const gpio_cfg_t bhi_interrupt_pin;
void card10_init(void);
void card10_diag(void);
void core1_start(void);
void core1_start(void *isr);
void core1_stop(void);
void card10_poll(void);
void card10_reset(void) __attribute__((noreturn));
#endif
#include "LCD/LCD_Driver.h"
#include "framebuffer.h"
#include "gfx.h"
#include "textbuffer.h"
#include "gpio.h"
#include "portexpander.h"
#include "MAX77650-Arduino-Library.h"
#include <stdint.h>
#include <stdio.h>
/***** Globals *****/
const gpio_cfg_t DEV_DC_PIN = { PORT_1, PIN_6, GPIO_FUNC_OUT, GPIO_PAD_NONE };
struct gfx_region display_screen;
struct txt_buffer display_textb;
/***** Functions *****/
void display_set_reset_pin(uint8_t state)
{
if (!portexpander_detected()) {
MAX77650_setDO(state ? true : false);
} else {
portexpander_out_put(PIN_4, state ? 0xFF : 0);
}
}
void display_init(void)
{
if (!portexpander_detected()) {
// Open-drain
MAX77650_setDRV(false);
// Output
MAX77650_setDIR(false);
}
GPIO_Config(&DEV_DC_PIN);
LCD_SetBacklight(20);
LCD_Init();
display_screen = gfx_screen(LCD_framebuffer());
txt_init(&display_textb, &display_screen, &Font12);
gfx_clear(&display_screen);
}
void display_init_slim(void)
{
if (!portexpander_detected()) {
// Open-drain
MAX77650_setDRV(false);
// Output
MAX77650_setDIR(false);
}
GPIO_Config(&DEV_DC_PIN);
display_screen = gfx_screen(LCD_framebuffer());
txt_init(&display_textb, &display_screen, &Font12);
}
#ifndef DISPLAY_H
#include "framebuffer.h"
#include "textbuffer.h"
extern struct gfx_region display_screen;
extern struct txt_buffer display_textb;
void display_init(void);
void display_init_slim(void);
#endif