Merge pull request #1 from microsoft/jacdac-c

Jacdac c
This commit is contained in:
James Devine 2020-06-23 21:48:40 +01:00 коммит произвёл GitHub
Родитель 770a5fcd75 d3679aecae
Коммит 364b767cb3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
72 изменённых файлов: 156 добавлений и 995 удалений

3
.gitmodules поставляемый
Просмотреть файл

@ -4,3 +4,6 @@
[submodule "pxt-common-packages"]
path = pxt-common-packages
url = https://github.com/microsoft/pxt-common-packages
[submodule "jacdac-c"]
path = jacdac-c
url = https://github.com/microsoft/jacdac-c

Просмотреть файл

@ -9,7 +9,7 @@ endif
FORCE ?=
JD_CORE = jacdac-core
JD_CORE = jacdac-c
PREFIX = arm-none-eabi-
CC = $(PREFIX)gcc
@ -24,7 +24,8 @@ CFLAGS = $(DEFINES) \
-ffunction-sections -fdata-sections -nostartfiles \
$(WARNFLAGS)
CONFIG_DEPS = \
$(wildcard jd/*.h) \
$(wildcard jacdac-c/inc/*.h) \
$(wildcard jacdac-c/inc/interfaces/*.h) \
$(wildcard lib/*.h) \
$(wildcard bl/*.h) \
$(wildcard $(PLATFORM)/*.h) \
@ -47,11 +48,14 @@ PROFILES = $(patsubst targets/$(TARGET)/profile/%.c,%,$(wildcard targets/$(TARGE
ifeq ($(BL),)
DEFINES += -DDEVICE_DMESG_BUFFER_SIZE=1024
C_SRC += $(wildcard jd/*.c)
C_SRC += $(wildcard jacdac-c/source/*.c)
C_SRC += $(wildcard services/*.c)
C_SRC += $(wildcard jacdac-c/implementation/simple_alloc.c)
C_SRC += $(wildcard jacdac-c/implementation/sensor.c)
C_SRC += $(wildcard jacdac-c/implementation/simple_rx.c)
C_SRC += $(wildcard jacdac-c/implementation/tx_queue.c)
C_SRC += $(wildcard lib/*.c)
C_SRC += $(wildcard $(PLATFORM)/*.c)
C_SRC += $(JD_CORE)/jdlow.c
C_SRC += $(JD_CORE)/jdutil.c
C_SRC += $(HALSRC)
else
DEFINES += -DDEVICE_DMESG_BUFFER_SIZE=0 -DBL
@ -62,7 +66,7 @@ C_SRC += $(PLATFORM)/init.c
C_SRC += $(PLATFORM)/flash.c
C_SRC += $(PLATFORM)/adc.c
C_SRC += lib/dmesg.c
C_SRC += $(JD_CORE)/jdutil.c
C_SRC += $(JD_CORE)/source/jd_util.c
AS_SRC += bl/boothandler.s
endif
@ -81,7 +85,8 @@ CPPFLAGS += \
-Itargets/$(TARGET) \
-Itargets/$(BASE_TARGET) \
-I$(PLATFORM) \
-Ijd \
-Ijacdac-c/inc \
-Iservices \
-Ilib \
-I$(JD_CORE) \
-I$(BUILT)
@ -89,8 +94,8 @@ CPPFLAGS += \
LDFLAGS = -specs=nosys.specs -specs=nano.specs \
-T"$(LD_SCRIPT)" -Wl,--gc-sections
all: $(JD_CORE)/jdlow.c
$(MAKE) -j8 build
all:
$(MAKE) -j1 build
ifeq ($(BL),)
$(MAKE) -j8 BL=1 build
endif
@ -99,12 +104,12 @@ ifeq ($(BL),)
endif
$(V)$(PREFIX)size $(BUILT_BIN)/*.elf
$(JD_CORE)/jdlow.c:
if test -f ../pxt-common-packages/libs/jacdac/jdlow.c ; then \
ln -s ../pxt-common-packages/libs/jacdac jacdac-core; \
else \
ln -s pxt-common-packages/libs/jacdac jacdac-core; \
fi
# $(JD_CORE)/jdlow.c:
# if test -f ../pxt-common-packages/libs/jacdac/jdlow.c ; then \
# ln -s ../pxt-common-packages/libs/jacdac jacdac-core; \
# else \
# ln -s pxt-common-packages/libs/jacdac jacdac-core; \
# fi
r: run
l: flash-loop
@ -195,7 +200,7 @@ $(BUILT_BIN)/$(PREF)-%.elf: $(BUILT)/jd/prof-%.o $(OBJ) Makefile $(LD_SCRIPT) sc
@echo LD $@
$(V)$(CC) $(CFLAGS) $(LDFLAGS) -Wl,-Map=$@.map -o $@ $(OBJ) $< -lm
@echo BIN-PATCH $@
$(V)node scripts/patch-bin.js -q $@ $(FLASH_SIZE) $(BL_SIZE) targets/$(TARGET)/profile
$(V)node scripts/patch-bin.js -q $@ $(FLASH_SIZE) $(BL_SIZE) targets/$(TARGET)/profile
build: $(addsuffix .hex,$(addprefix $(BUILT_BIN)/$(PREF)-,$(PROFILES)))

Просмотреть файл

@ -11,7 +11,8 @@
#error "invalid CPU"
#endif
#include "jdprotocol.h"
#include "jd_physical.h"
#include "jd_control.h"
#define CPU_MHZ PLL_MHZ

1
jacdac-c Submodule

@ -0,0 +1 @@
Subproject commit 83189fcdba2072ee603a8b1de479573dc7fc142d

Просмотреть файл

@ -1,60 +0,0 @@
#include "jdsimple.h"
/*
Timings, for 256 byte packet, 64MHz STM32G031:
Hardware: 40us
Software fast: 88us
Software slow: 388us
*/
#if defined(CRC_POL_POL)
static uint8_t inited;
uint16_t crc16(const void *data, uint32_t size) {
if (!inited) {
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_CRC);
// reset value
// LL_CRC_SetInputDataReverseMode(CRC, LL_CRC_INDATA_REVERSE_NONE);
// LL_CRC_SetOutputDataReverseMode(CRC, LL_CRC_OUTDATA_REVERSE_NONE);
LL_CRC_SetPolynomialCoef(CRC, 0x1021);
LL_CRC_SetPolynomialSize(CRC, LL_CRC_POLYLENGTH_16B);
inited = 1;
}
LL_CRC_SetInitialData(CRC, LL_CRC_DEFAULT_CRC_INITVALUE);
const uint8_t *ptr = (const uint8_t *)data;
while (size--)
LL_CRC_FeedData8(CRC, *ptr++);
return LL_CRC_ReadData16(CRC);
}
#else
#if 0
uint16_t crc16soft_slow(const void *data, uint32_t size) {
const uint8_t *ptr = (const uint8_t *)data;
uint16_t crc = 0xffff;
while (size--) {
uint8_t data = *ptr++;
crc = crc ^ ((uint16_t)data << 8);
for (int i = 0; i < 8; i++) {
if (crc & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
}
}
return crc;
}
#endif
// https://wiki.nicksoft.info/mcu:pic16:crc-16:home
uint16_t crc16(const void *data, uint32_t size) {
const uint8_t *ptr = (const uint8_t *)data;
uint16_t crc = 0xffff;
while (size--) {
uint8_t data = *ptr++;
uint8_t x = (crc >> 8) ^ data;
x ^= x >> 4;
crc = (crc << 8) ^ (x << 12) ^ (x << 5) ^ x;
}
return crc;
}
#endif

Просмотреть файл

@ -1,68 +0,0 @@
#include "jdsimple.h"
// do not use _state parameter in this file - it can be NULL in bootloader mode
struct srv_state {
SRV_COMMON;
};
static uint8_t id_counter;
static uint32_t nextblink;
static void identify(void) {
if (!id_counter)
return;
if (!should_sample(&nextblink, 150000))
return;
id_counter--;
led_blink(50000);
}
void ctrl_process(srv_t *_state) {
identify();
}
static void send_value(jd_packet_t *pkt, uint32_t v) {
txq_push(JD_SERVICE_NUMBER_CTRL, pkt->service_command, &v, sizeof(v));
}
void ctrl_handle_packet(srv_t *_state, jd_packet_t *pkt) {
switch (pkt->service_command) {
case JD_CMD_ADVERTISEMENT_DATA:
app_queue_annouce();
break;
case JD_CMD_CTRL_IDENTIFY:
id_counter = 7;
nextblink = now;
identify();
break;
case JD_CMD_CTRL_RESET:
target_reset();
break;
case (JD_CMD_GET_REG | JD_REG_CTRL_DEVICE_DESCRIPTION):
txq_push(JD_SERVICE_NUMBER_CTRL, pkt->service_command, app_dev_class_name,
strlen(app_dev_class_name));
break;
case (JD_CMD_GET_REG | JD_REG_CTRL_DEVICE_CLASS):
send_value(pkt, app_dev_info.device_class);
break;
case (JD_CMD_GET_REG | JD_REG_CTRL_BL_DEVICE_CLASS):
send_value(pkt, bl_dev_info.device_class);
break;
case (JD_CMD_GET_REG | JD_REG_CTRL_TEMPERATURE):
send_value(pkt, adc_read_temp());
break;
}
}
SRV_DEF(ctrl, JD_SERVICE_CLASS_CTRL);
void ctrl_init() {
SRV_ALLOC(ctrl);
}

Просмотреть файл

@ -1,27 +0,0 @@
#include "jdsimple.h"
static jd_frame_t *frameToHandle;
int app_handle_frame(jd_frame_t *frame) {
if (frameToHandle)
return -1;
frameToHandle = frame;
return 0;
}
void app_process_frame() {
if (frameToHandle) {
if (frameToHandle->flags & JD_FRAME_FLAG_ACK_REQUESTED &&
frameToHandle->flags & JD_FRAME_FLAG_COMMAND &&
frameToHandle->device_identifier == device_id())
txq_push(JD_SERVICE_NUMBER_CRC_ACK, frameToHandle->crc, NULL, 0);
for (;;) {
app_handle_packet((jd_packet_t *)frameToHandle);
if (!jd_shift_frame(frameToHandle))
break;
}
frameToHandle = NULL;
}
}

Просмотреть файл

@ -1,98 +0,0 @@
#include "jdsimple.h"
//#define LOG DMESG
#define LOG(...) ((void)0)
#define REG_IS_SIGNED(r) ((r) <= 4 && !((r)&1))
static const uint8_t regSize[16] = {1, 1, 2, 2, 4, 4, 4, 8, 1};
int srv_handle_reg(srv_t *state, jd_packet_t *pkt, const uint16_t sdesc[]) {
bool is_get = (pkt->service_command >> 12) == (JD_CMD_GET_REG >> 12);
bool is_set = (pkt->service_command >> 12) == (JD_CMD_SET_REG >> 12);
if (!is_get && !is_set)
return 0;
if (is_set && pkt->service_size == 0)
return 0;
int reg = pkt->service_command & 0xfff;
if (reg >= 0xf00) // these are reserved
return 0;
if (is_set && (reg & 0xf00) == 0x100)
return 0; // these are read-only
uint32_t offset = 0;
uint8_t bitoffset = 0;
LOG("handle %x", reg);
for (int i = 0; sdesc[i] != JD_REG_END; ++i) {
uint16_t sd = sdesc[i];
int tp = sd >> 12;
int regsz = regSize[tp];
if (tp == _REG_BYTES)
regsz = sdesc[++i];
if (!regsz)
jd_panic();
if (tp != _REG_BIT) {
if (bitoffset) {
bitoffset = 0;
offset++;
}
int align = regsz < 4 ? regsz - 1 : 3;
offset = (offset + align) & ~align;
}
LOG("%x:%d:%d", (sd & 0xfff), offset, regsz);
if ((sd & 0xfff) == reg) {
uint8_t *sptr = (uint8_t *)state + offset;
if (is_get) {
if (tp == _REG_BIT) {
uint8_t v = *sptr & (1 << bitoffset) ? 1 : 0;
txq_push(pkt->service_number, pkt->service_command, &v, 1);
} else {
txq_push(pkt->service_number, pkt->service_command, sptr, regSize[tp]);
}
return -reg;
} else {
if (tp == _REG_BIT) {
LOG("bit @%d - %x", offset, reg);
if (pkt->data[0])
*sptr |= 1 << bitoffset;
else
*sptr &= ~(1 << bitoffset);
} else if (regsz <= pkt->service_size) {
LOG("exact @%d - %x", offset, reg);
memcpy(sptr, pkt->data, regsz);
} else {
LOG("too little @%d - %x", offset, reg);
memcpy(sptr, pkt->data, pkt->service_size);
int fill = !REG_IS_SIGNED(tp)
? 0
: (pkt->data[pkt->service_size - 1] & 0x80) ? 0xff : 0;
memset(sptr + pkt->service_size, fill, regsz - pkt->service_size);
}
return reg;
}
}
if (tp == _REG_BIT) {
bitoffset++;
if (bitoffset == 8) {
offset++;
bitoffset = 0;
}
} else {
offset += regsz;
}
}
return 0;
}

Просмотреть файл

@ -1,85 +0,0 @@
#pragma once
#define PKT_UNHANDLED 0
#define PKT_HANDLED_RO 1
#define PKT_HANDLED_RW 2
#define JD_REG_PADDING 0xff0
#define JD_REG_END 0xff1
#define JD_REG_SERVICE_DISABLED 0xff2
#define _REG_(tp, v) (((tp) << 12) | (v))
#define _REG_S8 0
#define _REG_U8 1
#define _REG_S16 2
#define _REG_U16 3
#define _REG_S32 4
#define _REG_U32 5
#define _REG_BYTE4 6
#define _REG_BYTE8 7
#define _REG_BIT 8
#define _REG_BYTES 9
#define REG_S8(v) _REG_(_REG_S8, (v))
#define REG_U8(v) _REG_(_REG_U8, (v))
#define REG_S16(v) _REG_(_REG_S16, (v))
#define REG_U16(v) _REG_(_REG_U16, (v))
#define REG_S32(v) _REG_(_REG_S32, (v))
#define REG_U32(v) _REG_(_REG_U32, (v))
#define REG_BYTE4(v) _REG_(_REG_BYTE4, (v))
#define REG_BYTE8(v) _REG_(_REG_BYTE8, (v))
#define REG_BIT(v) _REG_(_REG_BIT, (v))
#define REG_BYTES(v, n) _REG_(_REG_BYTES, (v)), n
#define REG_DEFINITION(name, ...) static const uint16_t name[] = {__VA_ARGS__ JD_REG_END};
typedef struct srv_state srv_t;
typedef void (*srv_pkt_cb_t)(srv_t *state, jd_packet_t *pkt);
typedef void (*srv_cb_t)(srv_t *state);
struct _srv_vt {
uint32_t service_class;
uint16_t state_size;
srv_cb_t process;
srv_pkt_cb_t handle_pkt;
};
typedef struct _srv_vt srv_vt_t;
#define SRV_COMMON \
const srv_vt_t *vt; \
uint8_t service_number; \
uint8_t padding0;
#define REG_SRV_BASE REG_BYTES(JD_REG_PADDING, 6)
struct srv_state_common {
SRV_COMMON;
};
typedef struct srv_state_common srv_common_t;
srv_t *srv_alloc(const srv_vt_t *vt);
int srv_handle_reg(srv_t *state, jd_packet_t *pkt, const uint16_t sdesc[]);
#define SRV_DEF(id, service_cls) \
static const srv_vt_t id##_vt = { \
.service_class = service_cls, \
.state_size = sizeof(srv_t), \
.process = id##_process, \
.handle_pkt = id##_handle_packet, \
}
#define SRV_ALLOC(id) \
srv_t *state = srv_alloc(&id##_vt); \
(void)state;
#define SENSOR_COMMON \
SRV_COMMON; \
uint8_t is_streaming : 1; \
uint8_t got_query : 1; \
uint32_t streaming_interval; \
uint32_t next_streaming
#define REG_SENSOR_BASE REG_BYTES(JD_REG_PADDING, 16)
int sensor_handle_packet(srv_t *state, jd_packet_t *pkt);
int sensor_should_stream(srv_t *state);
int sensor_handle_packet_simple(srv_t *state, jd_packet_t *pkt, const void *sample,
uint32_t sample_size);
void sensor_process_simple(srv_t *state, const void *sample, uint32_t sample_size);

Просмотреть файл

@ -1,131 +0,0 @@
#include "jdsimple.h"
#define MAX_SERV 32
static srv_t **services;
static uint8_t num_services;
static uint64_t maxId;
static uint32_t lastMax, lastDisconnectBlink;
struct srv_state {
SRV_COMMON;
};
srv_t *srv_alloc(const srv_vt_t *vt) {
// always allocate instances idx - it should be stable when we disable some services
if (num_services >= MAX_SERV)
jd_panic();
srv_t *r = alloc(vt->state_size);
r->vt = vt;
r->service_number = num_services;
services[num_services++] = r;
return r;
}
void app_init_services() {
srv_t *tmp[MAX_SERV + 1];
uint16_t hashes[MAX_SERV];
tmp[MAX_SERV] = (srv_t *)hashes; // avoid global variable
services = tmp;
ctrl_init();
jdcon_init();
init_services();
services = alloc(sizeof(void *) * num_services);
memcpy(services, tmp, sizeof(void *) * num_services);
}
void app_queue_annouce() {
alloc_stack_check();
uint32_t *dst =
txq_push(JD_SERVICE_NUMBER_CTRL, JD_CMD_ADVERTISEMENT_DATA, NULL, num_services * 4);
if (!dst)
return;
for (int i = 0; i < num_services; ++i)
dst[i] = services[i]->vt->service_class;
#if 0
static uint32_t pulsesample;
static uint32_t pulse = 850 * 1000;
if (should_sample(&pulsesample, 15 * 1000 * 1000)) {
pwr_pin_enable(1);
target_wait_us(pulse);
pwr_pin_enable(0);
jdcon_warn("P: %d t=%ds", pulse, now / 1000000);
pulse = (pulse * 9) / 10;
#if 1
if(pulse<1000)
pulse=1000;
#endif
}
#endif
}
static void handle_ctrl_tick(jd_packet_t *pkt) {
if (pkt->service_command == JD_CMD_ADVERTISEMENT_DATA) {
// if we have not seen maxId for 1.1s, find a new maxId
if (pkt->device_identifier < maxId && in_past(lastMax + 1100000)) {
maxId = pkt->device_identifier;
}
// maxId? blink!
if (pkt->device_identifier >= maxId) {
maxId = pkt->device_identifier;
lastMax = now;
led_blink(50);
}
}
}
void app_handle_packet(jd_packet_t *pkt) {
if (!(pkt->flags & JD_FRAME_FLAG_COMMAND)) {
if (pkt->service_number == 0)
handle_ctrl_tick(pkt);
return;
}
bool matched_devid = pkt->device_identifier == device_id();
if (pkt->flags & JD_FRAME_FLAG_IDENTIFIER_IS_SERVICE_CLASS) {
for (int i = 0; i < num_services; ++i) {
if (pkt->device_identifier == services[i]->vt->service_class) {
pkt->service_number = i;
matched_devid = true;
break;
}
}
}
if (!matched_devid)
return;
if (pkt->service_number < num_services) {
srv_t *s = services[pkt->service_number];
s->vt->handle_pkt(s, pkt);
}
}
void app_process() {
app_process_frame();
if (should_sample(&lastDisconnectBlink, 250000)) {
if (in_past(lastMax + 2000000)) {
led_blink(5000);
}
}
for (int i = 0; i < num_services; ++i) {
services[i]->vt->process(services[i]);
}
txq_flush();
}
void dump_pkt(jd_packet_t *pkt, const char *msg) {
DMESG("pkt[%s]; s#=%d sz=%d %x", msg, pkt->service_number, pkt->service_size,
pkt->service_command);
}

Просмотреть файл

@ -1,60 +0,0 @@
#include "jdsimple.h"
#define PRI_DEBUG 0
#define PRI_LOG 1
#define PRI_WARNING 2
#define PRI_ERROR 3
#define CMD_MSG_START 0x80
#define REG_MIN_PRI 0x80
struct srv_state {
SRV_COMMON;
uint8_t minPri;
};
REG_DEFINITION( //
jdcon_regs, //
REG_SRV_BASE, //
REG_U8(REG_MIN_PRI), //
)
static srv_t *state_;
void jdcon_logv(int level, const char *format, va_list ap) {
srv_t *ctx = state_;
if (!ctx)
return;
if (level < ctx->minPri)
return;
char buf[100];
codal_vsprintf(buf, sizeof(buf), format, ap);
txq_push(ctx->service_number, CMD_MSG_START + level, buf, strlen(buf));
}
void jdcon_log(const char *format, ...) {
va_list arg;
va_start(arg, format);
jdcon_logv(PRI_LOG, format, arg);
va_end(arg);
}
void jdcon_warn(const char *format, ...) {
va_list arg;
va_start(arg, format);
jdcon_logv(PRI_WARNING, format, arg);
va_end(arg);
}
void jdcon_process(srv_t *state) {}
void jdcon_handle_packet(srv_t *state, jd_packet_t *pkt) {
srv_handle_reg(state, pkt, jdcon_regs);
}
SRV_DEF(jdcon, JD_SERVICE_CLASS_LOGGER);
void jdcon_init(void) {
SRV_ALLOC(jdcon);
state_ = state;
state->minPri = PRI_WARNING;
}

Просмотреть файл

@ -1,36 +0,0 @@
#ifndef __JDSERVICES_H
#define __JDSERVICES_H
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#define JD_SERVICE_CLASS_CAPTOUCH 0x6cf77465
typedef struct {
uint8_t flags;
uint8_t numchannels; // up to 32
} jd_captouch_advertisement_data_t;
#define JD_CAPTOUCH_COMMAND_CALIBRATE 0x01
#define JD_CAPTOUCH_COMMAND_READ 0x02
typedef struct {
uint32_t command;
uint32_t channels;
} jd_captouch_command_t;
typedef struct {
uint32_t channels;
uint16_t readings[0];
} jd_captouch_reading_t;
#ifdef __cplusplus
}
#endif
#endif

Просмотреть файл

@ -1,33 +0,0 @@
#pragma once
#include "jdprofile.h"
#include "jdlow.h"
#include "host.h"
#include "lib.h"
// main.c
void led_set(int state);
void led_blink(int us);
void pwr_pin_enable(int en);
// jdapp.c
void app_process(void);
void app_init_services(void);
// txq.c
void txq_init(void);
void txq_flush(void);
int txq_is_idle(void);
void *txq_push(unsigned service_num, unsigned service_cmd, const void *data, unsigned service_size);
void txq_push_event_ex(srv_t *srv, uint32_t eventid, uint32_t arg);
static inline void txq_push_event(srv_t *srv, uint32_t eventid) {
txq_push_event_ex(srv, eventid, 0);
}
void ctrl_process(srv_t *_state);
void ctrl_handle_packet(srv_t *_state, jd_packet_t *pkt);
void app_handle_packet(jd_packet_t *pkt);
void app_process_frame(void);
void dump_pkt(jd_packet_t *pkt, const char *msg);

Просмотреть файл

@ -1,58 +0,0 @@
#include "jdsimple.h"
REG_DEFINITION( //
sensor_regs, //
REG_SRV_BASE, //
REG_BIT(JD_REG_IS_STREAMING), //
REG_U32(JD_REG_STREAMING_INTERVAL), //
REG_U32(JD_REG_PADDING), // next_streaming not accesible
);
struct srv_state {
SENSOR_COMMON;
};
int sensor_handle_packet(srv_t *state, jd_packet_t *pkt) {
int r = srv_handle_reg(state, pkt, sensor_regs);
switch (r) {
case JD_REG_IS_STREAMING:
if (state->is_streaming) {
if (state->streaming_interval == 0)
state->streaming_interval = 100;
state->next_streaming = now;
state->got_query = 1;
}
break;
case JD_REG_STREAMING_INTERVAL:
if (state->streaming_interval < 20)
state->streaming_interval = 20;
if (state->streaming_interval > 100000)
state->streaming_interval = 100000;
break;
}
return r;
}
void sensor_process_simple(srv_t *state, const void *sample, uint32_t sample_size) {
if (sensor_should_stream(state))
txq_push(state->service_number, JD_CMD_GET_REG | JD_REG_READING, sample, sample_size);
}
int sensor_handle_packet_simple(srv_t *state, jd_packet_t *pkt, const void *sample,
uint32_t sample_size) {
int r = sensor_handle_packet(state, pkt);
if (pkt->service_command == (JD_CMD_GET_REG | JD_REG_READING)) {
state->got_query = 1;
txq_push(pkt->service_number, pkt->service_command, sample, sample_size);
r = -JD_REG_READING;
}
return r;
}
int sensor_should_stream(srv_t *state) {
if (!state->is_streaming)
return false;
return should_sample(&state->next_streaming, state->streaming_interval * 1000);
}

Просмотреть файл

@ -1,41 +0,0 @@
#pragma once
#define JD_SERVICE_CLASS_LOGGER 0x12dc1fca
#define JD_SERVICE_CLASS_BATTERY 0x1d2a2acd
#define JD_SERVICE_CLASS_ACCELEROMETER 0x1f140409
#define JD_SERVICE_CLASS_BUTTON 0x1473a263
#define JD_SERVICE_CLASS_TOUCHBUTTON 0x130cf5be
#define JD_SERVICE_CLASS_LIGHT_SENSOR 0x15e7a0ff
#define JD_SERVICE_CLASS_MICROPHONE 0x1a5c5866
#define JD_SERVICE_CLASS_THERMOMETER 0x1421bac7
#define JD_SERVICE_CLASS_SWITCH 0x14218172
#define JD_SERVICE_CLASS_PIXEL 0x1768fbbf
#define JD_SERVICE_CLASS_HAPTIC 0x116b14a3
#define JD_SERVICE_CLASS_LIGHT 0x126f00e0
#define JD_SERVICE_CLASS_KEYBOARD 0x1ae4812d
#define JD_SERVICE_CLASS_MOUSE 0x14bc97bf
#define JD_SERVICE_CLASS_GAMEPAD 0x100527e8
#define JD_SERVICE_CLASS_MUSIC 0x1b57b1d7
#define JD_SERVICE_CLASS_SERVO 0x12fc9103
#define JD_SERVICE_CLASS_CONTROLLER 0x188ae4b8
#define JD_SERVICE_CLASS_LCD 0x18d5284c
#define JD_SERVICE_CLASS_MESSAGE_BUS 0x115cabf5
#define JD_SERVICE_CLASS_COLOR_SENSOR 0x14d6dda2
#define JD_SERVICE_CLASS_LIGHT_SPECTRUM_SENSOR 0x16fa0c0d
#define JD_SERVICE_CLASS_PROXIMITY 0x14c1791b
#define JD_SERVICE_CLASS_TOUCH_BUTTONS 0x1acb49d5
#define JD_SERVICE_CLASS_SERVOS 0x182988d8
#define JD_SERVICE_CLASS_ROTARY_ENCODER 0x10fa29c9
#define JD_SERVICE_CLASS_DEVICE_NAME 0x117729bd
#define JD_SERVICE_CLASS_PWM_LIGHT 0x1fb57453
#define JD_SERVICE_CLASS_BOOTLOADER 0x1ffa9948
#define JD_SERVICE_CLASS_HUMIDITY 0x16c810b8
#define JD_SERVICE_CLASS_MONO_DISPLAY 0x1f43e195
#define JD_SERVICE_CLASS_ARCADE_CONTROLS 0x1deaa06e
#define JD_SERVICE_CLASS_POWER 0x1fa4c95a
#define JD_SERVICE_CLASS_SLIDER 0x1f274746
#define JD_SERVICE_CLASS_MOTOR 0x17004cd8
// to generate a new class number, head to https://microsoft.github.io/uf2/patcher/
// click link at the bottom and replace first digit with '1'

Просмотреть файл

@ -1,55 +0,0 @@
#include "jdsimple.h"
static jd_frame_t *sendFrame;
static uint8_t bufferPtr, isSending;
int txq_is_idle() {
return !isSending && sendFrame[bufferPtr].size == 0;
}
void txq_init(void) {
if (!sendFrame)
sendFrame = alloc(sizeof(jd_frame_t) * 2);
}
void *txq_push(unsigned service_num, unsigned service_cmd, const void *data,
unsigned service_size) {
void *trg = jd_push_in_frame(&sendFrame[bufferPtr], service_num, service_cmd, service_size);
if (!trg) {
DMESG("send overflow!");
return NULL;
}
if (data)
memcpy(trg, data, service_size);
return trg;
}
void txq_push_event_ex(srv_t *srv, uint32_t eventid, uint32_t arg) {
srv_common_t *state = (srv_common_t *)srv;
if (eventid >> 16)
jd_panic();
uint32_t data[] = {eventid, arg};
txq_push(state->service_number, JD_CMD_EVENT, data, 8);
}
jd_frame_t *app_pull_frame(void) {
isSending = true;
return &sendFrame[bufferPtr ^ 1];
}
void app_frame_sent(jd_frame_t *pkt) {
isSending = false;
}
void txq_flush() {
if (isSending)
return;
if (sendFrame[bufferPtr].size == 0)
return;
sendFrame[bufferPtr].device_identifier = device_id();
jd_compute_crc(&sendFrame[bufferPtr]);
bufferPtr ^= 1;
jd_packet_ready();
jd_reset_frame(&sendFrame[bufferPtr]);
}

Просмотреть файл

@ -1,55 +0,0 @@
#include "lib.h"
#define STACK_SIZE 512
#define STACK_BASE ((uint32_t)&_estack)
#define HEAP_BASE ((uint32_t)&_end)
#define HEAP_END (STACK_BASE - STACK_SIZE)
#define HEAP_SIZE (HEAP_END - HEAP_BASE)
extern uint32_t _end;
extern uint32_t _estack;
static uint32_t *aptr;
static uint16_t maxStack;
void alloc_stack_check() {
uint32_t *ptr = (uint32_t *)(STACK_BASE - STACK_SIZE);
while (ptr < (uint32_t *)STACK_BASE) {
if (*ptr != 0x33333333)
break;
ptr++;
}
int sz = STACK_BASE - (uint32_t)ptr;
if (sz > maxStack)
DMESG("used stack: %d", maxStack = sz);
}
void alloc_init() {
DMESG("space: %d", HEAP_END - HEAP_BASE);
aptr = (uint32_t *)HEAP_BASE;
int p = 0;
int sz = (uint32_t)&p - HEAP_BASE - 32;
// seed PRNG with random RAM contents (later we add ADC readings)
jd_seed_random(jd_hash_fnv1a((void *)HEAP_BASE, sz));
memset((void *)HEAP_BASE, 0x33, sz);
alloc_stack_check();
}
void *alloc(uint32_t size) {
alloc_stack_check();
size = (size + 3) >> 2;
void *r = aptr;
aptr += size;
if ((uint32_t)aptr > HEAP_END)
fail_and_reset();
memset(r, 0, size << 2);
return r;
}
void *alloc_emergency_area(uint32_t size) {
if (size > HEAP_SIZE)
jd_panic();
return (void *)HEAP_BASE;
}

26
lib/blhw.c Normal file
Просмотреть файл

@ -0,0 +1,26 @@
#include "blhw.h"
#include "jd_protocol.h"
#include "tinyhw.h"
#include "pinnames.h"
#include "board.h"
uint64_t hw_device_id(void) {
return app_dev_info.device_id;
}
uint32_t app_get_device_class(void) {
return app_dev_info.device_class;
}
void power_pin_enable(int en) {
#ifdef PWR_PIN_PULLUP
if (en) {
pin_setup_output(PIN_PWR);
pin_set(PIN_PWR, 0);
} else {
pin_setup_input(PIN_PWR, 0);
}
#else
pin_set(PIN_PWR, !en);
#endif
}

Просмотреть файл

@ -1,5 +1,7 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "hwconfig.h"
#define CONCAT_1(a, b) a##b
@ -87,10 +89,6 @@ struct app_top_handlers {
#define app_handlers ((struct app_top_handlers *)0x8000000)
#define app_dev_info app_handlers->devinfo
static inline uint64_t device_id(void) {
return app_dev_info.device_id;
}
#ifndef BL
#define bl_info (*((struct bl_info_block*)(0x8000000 + FLASH_SIZE - BL_SIZE)))
#endif

Просмотреть файл

@ -7,29 +7,15 @@
#include "pinnames.h"
#include "board.h"
typedef void (*cb_t)(void);
// Required by jdlow.c
void jd_panic(void);
void target_enable_irq(void);
void target_disable_irq(void);
void target_wait_us(uint32_t n);
#include "jd_protocol.h"
void tim_init(void);
uint64_t tim_get_micros(void);
void tim_set_timer(int delta, cb_t cb);
// Provided jdutil.c
uint32_t jd_random_around(uint32_t v);
uint32_t jd_random(void);
void jd_seed_random(uint32_t s);
uint32_t jd_hash_fnv1a(const void *data, unsigned len);
uint16_t jd_crc16(const void *data, uint32_t size);
int jd_is_busy(void);
void fail_and_reset(void);
#include "tinyhw.h"
#include "dmesg.h"
#define RTC_ALRM_US 10000
@ -38,12 +24,6 @@ int itoa(int n, char *s);
int string_reverse(char *s);
uint32_t random_int(uint32_t max);
// alloc.c
void alloc_init(void);
void *alloc(uint32_t size);
void alloc_stack_check(void);
void *alloc_emergency_area(uint32_t size);
// pwr.c
// enter/leave high-speed no-deep-sleep mode
void pwr_enter_pll(void);
@ -57,23 +37,9 @@ void pwr_sleep(void);
// do WFI until PLL/TIM mode is left
void pwr_wait_tim(void);
extern uint32_t now;
// check if given timestamp is already in the past, regardless of overflows on 'now'
// the moment has to be no more than ~500 seconds in the past
static inline bool in_past(uint32_t moment) {
return ((now - moment) >> 29) == 0;
}
static inline bool in_future(uint32_t moment) {
return ((moment - now) >> 29) == 0;
}
// keep sampling at period, using state at *sample
bool should_sample(uint32_t *sample, uint32_t period);
#define CHECK(cond) \
if (!(cond)) \
jd_panic()
jd_panic()
uint32_t hw_temp(void);

Просмотреть файл

@ -49,7 +49,7 @@ static void weather_hw_process(void) {
}
// the 50ms here is just for readings, we actually sample at SAMPLING_MS
if (should_sample(&ctx->nextsample, 50000)) {
if (jd_should_sample(&ctx->nextsample, 50000)) {
if (ctx->in_temp) {
int v = read_data();
if (v >= 0) {

Просмотреть файл

@ -122,15 +122,4 @@ uint32_t random_int(uint32_t max) {
}
}
bool should_sample(uint32_t *sample, uint32_t period) {
if (in_future(*sample))
return false;
*sample += period;
if (!in_future(*sample))
// we lost some samples
*sample = now + period;
return true;
}

@ -1 +1 @@
Subproject commit 61a25f97c1414abbbd61417a8d8897a52753c6a1
Subproject commit bd0ff204ff8ab6dc94efb47fa51959e99d673e5c

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
// shake/gesture detection based on
// https://github.com/lancaster-university/codal-core/blob/master/source/driver-models/Accelerometer.cpp
@ -79,7 +79,7 @@ static void emit_g_event(srv_t *state, int ev) {
if (state->g_events & (1 << ev))
return;
state->g_events |= 1 << ev;
txq_push_event(state, ev);
jd_send_event(state, ev);
}
static uint16_t instantaneousPosture(srv_t *state, uint32_t force) {
@ -196,7 +196,7 @@ static void process_events(srv_t *state) {
uint16_t g = instantaneousPosture(state, force);
if (g == ACCELEROMETER_EVT_SHAKE) {
txq_push_event(state, ACCELEROMETER_EVT_SHAKE);
jd_send_event(state, ACCELEROMETER_EVT_SHAKE);
} else {
// Perform some low pass filtering to reduce jitter from any detected effects
if (g == state->currentGesture) {
@ -211,7 +211,7 @@ static void process_events(srv_t *state) {
if (state->currentGesture != state->lastGesture &&
state->sigma >= ACCELEROMETER_GESTURE_DAMPING) {
state->lastGesture = state->currentGesture;
txq_push_event(state, state->lastGesture);
jd_send_event(state, state->lastGesture);
}
}
}
@ -222,7 +222,7 @@ void acc_process(srv_t *state) {
return;
got_acc_int = 0;
#else
if (!should_sample(&state->nextSample, SAMPLING_PERIOD))
if (!jd_should_sample(&state->nextSample, SAMPLING_PERIOD))
return;
#endif
@ -244,7 +244,7 @@ void acc_handle_packet(srv_t *state, jd_packet_t *pkt) {
}
SRV_DEF(acc, JD_SERVICE_CLASS_ACCELEROMETER);
void acc_init() {
void acc_init(void) {
SRV_ALLOC(acc);
acc_hw_init();
#ifdef PIN_ACC_INT

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
#define EVT_DOWN 1
#define EVT_UP 2
@ -23,27 +23,27 @@ static void update(srv_t *state) {
state->prev_pressed = state->pressed;
pin_set(state->blpin, state->pressed);
if (state->pressed) {
txq_push_event(state, EVT_DOWN);
jd_send_event(state, EVT_DOWN);
state->press_time = now;
} else {
txq_push_event(state, EVT_UP);
jd_send_event(state, EVT_UP);
uint32_t presslen = now - state->press_time;
if (presslen > 500000)
txq_push_event(state, EVT_LONG_CLICK);
jd_send_event(state, EVT_LONG_CLICK);
else
txq_push_event(state, EVT_CLICK);
jd_send_event(state, EVT_CLICK);
state->num_zero = 0;
}
}
}
void btn_process(srv_t *state) {
if (should_sample(&state->nextSample, 9000)) {
if (jd_should_sample(&state->nextSample, 9000)) {
update(state);
if (sensor_should_stream(state) && (state->pressed || state->num_zero < 20)) {
state->num_zero++;
txq_push(state->service_number, JD_CMD_GET_REG | JD_REG_READING, &state->pressed,
jd_send(state->service_number, JD_CMD_GET_REG | JD_REG_READING, &state->pressed,
sizeof(state->pressed));
}
}

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
struct srv_state {
SENSOR_COMMON;
@ -37,7 +37,7 @@ static void maybe_init(srv_t *state) {
void crank_process(srv_t *state) {
maybe_init(state);
if (should_sample(&state->nextSample, 900) && state->inited)
if (jd_should_sample(&state->nextSample, 900) && state->inited)
update(state);
sensor_process_simple(state, &state->sample, sizeof(state->sample));

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
#define JD_ARCADE_CONTROLS_BUTTON_LEFT 0x0001
#define JD_ARCADE_CONTROLS_BUTTON_UP 0x0002
@ -85,7 +85,7 @@ static void update(srv_t *state) {
if (isPressed != wasPressed) {
if (state->led_pins && state->led_pins[i] != 0xff)
pin_set(state->led_pins[i], isPressed);
txq_push_event_ex(state, isPressed ? EVT_DOWN : EVT_UP, i + 1);
jd_send_event_ext(state, isPressed ? EVT_DOWN : EVT_UP, i + 1);
}
}
state->btn_state = newstate;
@ -105,7 +105,7 @@ static void send_report(srv_t *state) {
}
}
txq_push(state->service_number, JD_CMD_GET_REG | JD_REG_READING, reports,
jd_send(state->service_number, JD_CMD_GET_REG | JD_REG_READING, reports,
(uint8_t *)report - (uint8_t *)reports);
}
@ -118,12 +118,12 @@ static void ad_data(srv_t *state) {
*dst++ = i + 1;
}
}
txq_push(state->service_number, JD_CMD_ADVERTISEMENT_DATA, addata,
jd_send(state->service_number, JD_CMD_ADVERTISEMENT_DATA, addata,
(uint8_t *)dst - (uint8_t *)addata);
}
void gamepad_process(srv_t *state) {
if (should_sample(&state->nextSample, 9000)) {
if (jd_should_sample(&state->nextSample, 9000)) {
update(state);
if (sensor_should_stream(state) && (state->btn_state || state->num_zero < 20)) {

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
struct srv_state {
SENSOR_COMMON;
@ -16,7 +16,7 @@ void humidity_handle_packet(srv_t *state, jd_packet_t *pkt) {
SRV_DEF(humidity, JD_SERVICE_CLASS_HUMIDITY);
void humidity_init() {
void humidity_init(void) {
SRV_ALLOC(humidity);
state->streaming_interval = 1000;
}

Просмотреть файл

@ -7,7 +7,7 @@
#include "board.h"
#include "dmesg.h"
#include "pinnames.h"
#include "services.h"
#include "jd_services.h"
#include "blhw.h"
#ifdef BL
@ -28,7 +28,7 @@
#define DEVICE_CLASS(dev_class, dev_class_name) const char app_dev_class_name[] = dev_class_name;
#endif
void init_services(void);
void app_init_services(void);
void ctrl_init(void);

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
#define DEFAULT_INTENSITY 15
#define DEFAULT_NUMPIXELS 15
@ -12,8 +12,8 @@
#define LIGHT_CMD_RUN 0x81
//#define LOG DMESG
#define LOG NOLOG
// #define LOG DMESG
// #define LOG NOLOG
/*
@ -533,10 +533,10 @@ void light_process(srv_t *state) {
if (state->dirty && !state->in_tx) {
state->dirty = 0;
if (is_empty((uint32_t *)state->pxbuffer, PX_WORDS(state->numpixels))) {
pwr_pin_enable(0);
jd_power_enable(0);
return;
} else {
pwr_pin_enable(1);
jd_power_enable(1);
}
state->in_tx = 1;
pwr_enter_pll();
@ -547,7 +547,7 @@ void light_process(srv_t *state) {
static void sync_config(srv_t *state) {
if (!is_enabled(state)) {
pwr_pin_enable(0);
jd_power_enable(0);
return;
}
@ -559,10 +559,10 @@ static void sync_config(srv_t *state) {
int needed = PX_WORDS(state->numpixels);
if (needed > state->pxbuffer_allocated) {
state->pxbuffer_allocated = needed;
state->pxbuffer = alloc(needed * 4);
state->pxbuffer = jd_alloc(needed * 4);
}
pwr_pin_enable(1);
jd_power_enable(1);
}
static void handle_run_cmd(srv_t *state, jd_packet_t *pkt) {
@ -584,13 +584,13 @@ void light_handle_packet(srv_t *state, jd_packet_t *pkt) {
handle_run_cmd(state, pkt);
break;
default:
srv_handle_reg(state, pkt, light_regs);
service_handle_register(state, pkt, light_regs);
break;
}
}
SRV_DEF(light, JD_SERVICE_CLASS_LIGHT);
void light_init() {
void light_init(void) {
SRV_ALLOC(light);
state_ = state; // there is global singleton state
state->intensity = DEFAULT_INTENSITY;

Просмотреть файл

@ -1,22 +1,9 @@
#include "jdsimple.h"
#include "lib.h"
uint32_t now;
static const uint8_t output_pins[] = {OUTPUT_PINS};
void pwr_pin_enable(int en) {
#ifdef PWR_PIN_PULLUP
if (en) {
pin_setup_output(PIN_PWR);
pin_set(PIN_PWR, 0);
} else {
pin_setup_input(PIN_PWR, 0);
}
#else
pin_set(PIN_PWR, !en);
#endif
}
void led_init(void) {
// To save power, especially in STOP mode,
// configure all pins in GPIOA,B,C as analog inputs (except for SWD)
@ -38,7 +25,7 @@ void led_init(void) {
// all power pins are reverse polarity
#ifndef PWR_PIN_PULLUP
pwr_pin_enable(0);
jd_power_enable(0);
#endif
#ifdef PIN_GLO0
@ -107,23 +94,15 @@ int main(void) {
led_init();
led_set(1);
if ((device_id() + 1) == 0)
if ((jd_device_id() + 1) == 0)
target_reset();
alloc_init();
tim_init();
adc_init_random(); // 300b
rtc_init();
// sleep_forever();
txq_init();
uart_init();
jd_init();
app_init_services();
#if 0
while(1) {
led_set(1);
@ -147,7 +126,7 @@ int main(void) {
uint64_t now_long = tim_get_micros();
now = (uint32_t)now_long;
app_process();
jd_services_tick();
if (led_off_time) {
int timeLeft = led_off_time - now_long;

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
struct srv_state {
SRV_COMMON;
@ -15,7 +15,7 @@ REG_DEFINITION( //
void oled_process(srv_t *state) {}
void oled_handle_packet(srv_t *state, jd_packet_t *pkt) {
if (srv_handle_reg(state, pkt, oled_regs)) {
if (service_handle_register(state, pkt, oled_regs)) {
}
}

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
#define CHECK_PERIOD 1000 // how often to probe the ADC, in us
#define OVERLOAD_MS 1000 // how long to shut down the power for after overload, in ms
@ -62,7 +62,7 @@ static void sort_ints(uint16_t arr[], int n) {
}
static void overload(srv_t *state) {
pwr_pin_enable(0);
jd_power_enable(0);
state->pwr_on = 0;
state->overloadExpire = now + OVERLOAD_MS * 1000;
state->overload = 1;
@ -86,7 +86,7 @@ static void turn_on_power(srv_t *state) {
unsigned rp = 0;
adc_prep_read_pin(PIN_GND_SENSE);
uint32_t t0 = tim_get_micros();
pwr_pin_enable(1);
jd_power_enable(1);
for (int i = 0; i < 1000; ++i) {
int gnd = adc_convert();
readings[rp++] = gnd;
@ -106,7 +106,7 @@ static void turn_on_power(srv_t *state) {
void power_process(srv_t *state) {
sensor_process_simple(state, &state->curr_power, sizeof(state->curr_power));
if (!should_sample(&state->nextSample, CHECK_PERIOD * 9 / 10))
if (!jd_should_sample(&state->nextSample, CHECK_PERIOD * 9 / 10))
return;
if (state->pulse_period && state->pulse_duration) {
@ -129,7 +129,7 @@ void power_process(srv_t *state) {
} else {
DMESG("power off");
state->pwr_on = 0;
pwr_pin_enable(0);
jd_power_enable(0);
}
}
@ -166,7 +166,7 @@ void power_handle_packet(srv_t *state, jd_packet_t *pkt) {
if (sensor_handle_packet_simple(state, pkt, &state->curr_power, sizeof(state->curr_power)))
return;
switch (srv_handle_reg(state, pkt, power_regs)) {
switch (service_handle_register(state, pkt, power_regs)) {
case PWR_REG_KEEP_ON_PULSE_PERIOD:
case PWR_REG_KEEP_ON_PULSE_DURATION:
if (state->pulse_period && state->pulse_duration) {

Просмотреть файл

@ -1,9 +1,7 @@
#include "jdsimple.h"
#include "lib.h"
#define DEFAULT_MAXPOWER 100
#define LOG DMESG
#define PWM_REG_CURR_ITERATION 0x80
#define PWM_REG_MAX_ITERATIONS 0x81
#define PWM_REG_STEPS 0x82
@ -68,7 +66,7 @@ static void set_pwr(srv_t *state, int on) {
}
void pwm_light_process(srv_t *state) {
if (!should_sample(&state->nextFrame, UPDATE_US))
if (!jd_should_sample(&state->nextFrame, UPDATE_US))
return;
int step_intensity = -1;
@ -116,7 +114,7 @@ void pwm_light_process(srv_t *state) {
}
void pwm_light_handle_packet(srv_t *state, jd_packet_t *pkt) {
switch (srv_handle_reg(state, pkt, pwm_light_regs)) {
switch (service_handle_register(state, pkt, pwm_light_regs)) {
case PWM_REG_STEPS:
state->curr_iteration = 0;
state->step_start_time = tim_get_micros() >> 10;

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
#define SERVO_PERIOD 20000
@ -32,14 +32,14 @@ static void set_pwr(srv_t *state, int on) {
pwm_enable(state->pwm_pin, 0);
pwr_leave_pll();
}
pwr_pin_enable(on);
jd_power_enable(on);
state->is_on = on;
}
void servo_process(srv_t *state) {}
void servo_handle_packet(srv_t *state, jd_packet_t *pkt) {
if (srv_handle_reg(state, pkt, servo_regs)) {
if (service_handle_register(state, pkt, servo_regs)) {
set_pwr(state, !!state->intensity);
if (state->is_on)
pwm_set_duty(state->pwm_pin, state->pulse);

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
struct srv_state {
SENSOR_COMMON;
@ -31,7 +31,7 @@ static void maybe_init(srv_t *state) {
void slider_process(srv_t *state) {
maybe_init(state);
if (should_sample(&state->nextSample, 9000) && state->inited)
if (jd_should_sample(&state->nextSample, 9000) && state->inited)
update(state);
sensor_process_simple(state, &state->sample, sizeof(state->sample));

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
#define CMD_PLAY_TONE 0x80
@ -55,7 +55,7 @@ void snd_process(srv_t *state) {
}
void snd_handle_packet(srv_t *state, jd_packet_t *pkt) {
srv_handle_reg(state, pkt, snd_regs);
service_handle_register(state, pkt, snd_regs);
switch (pkt->service_command) {
case CMD_PLAY_TONE:
if (pkt->service_size >= 6) {

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
struct srv_state {
SENSOR_COMMON;
@ -16,7 +16,7 @@ void temp_handle_packet(srv_t *state, jd_packet_t *pkt) {
SRV_DEF(temp, JD_SERVICE_CLASS_THERMOMETER);
void temp_init() {
void temp_init(void) {
SRV_ALLOC(temp);
state->streaming_interval = 1000;
}

Просмотреть файл

@ -1,4 +1,4 @@
#include "jdsimple.h"
#include "lib.h"
#define EVT_DOWN 1
#define EVT_UP 2
@ -22,7 +22,7 @@ static void update(srv_t *state) {
}
void touch_process(srv_t *state) {
if (should_sample(&state->nextSample, 50000)) {
if (jd_should_sample(&state->nextSample, 50000)) {
update(state);
sensor_process_simple(state, &state->reading, sizeof(state->reading));
}

Просмотреть файл

@ -1,4 +1,5 @@
#include "jdstm.h"
#include "dmesg.h"
static bool adc_calibrated;

Просмотреть файл

@ -260,7 +260,7 @@ static void px_dma(void) {
void px_tx(const void *data, uint32_t numbytes, uint8_t intensity, cb_t doneHandler) {
if (px_state.pxscratch == NULL) {
px_state.pxscratch = alloc(PX_SCRATCH_LEN);
px_state.pxscratch = jd_alloc(PX_SCRATCH_LEN);
dma_handler = px_dma;
}

Просмотреть файл

@ -13,7 +13,7 @@
#error "invalid CPU"
#endif
#include "jdsimple.h"
#include "lib.h"
extern uint8_t cpu_mhz;

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x3a3314ae, "JDF030 OLED v0");
void init_services() {
void app_init_services() {
oled_init();
}

Просмотреть файл

@ -2,7 +2,7 @@
DEVICE_CLASS(0x379c2450, "JDF030 weather v0");
void init_services() {
void app_init_services() {
temp_init();
humidity_init();
}

Просмотреть файл

@ -1,7 +1,8 @@
#include "jd_services.h"
#include "jdprofile.h"
DEVICE_CLASS(0x3d216fd4, "JDF030 btn v0");
void init_services() {
btn_init(PA_4);
void app_init_services(void) {
btn_init(PA_4, -1);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x3f7c8355, "JDF030 crank v0");
void init_services() {
void app_init_services() {
crank_init(PIN_P0, PIN_P1);
}

Просмотреть файл

@ -4,6 +4,6 @@
DEVICE_CLASS(0x3faf16db, "JDF030 servo v0");
void init_services() {
void app_init_services() {
servo_init(PIN_SERVO);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x39a9dc81, "JDF030 touch v0");
void init_services() {
void app_init_services() {
touch_init(PA_4);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x334b4fb6, "JDM3 acc");
void init_services() {
void app_init_services() {
acc_init();
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x3beb4448, "JDM3 crank");
void init_services() {
void app_init_services() {
crank_init(PIN_P0, PIN_P1);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x33498f7e, "JDM3 mono");
void init_services() {
void app_init_services() {
pwm_light_init(PIN_GLO1);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x3479bec3, "JDM3 light");
void init_services() {
void app_init_services() {
light_init();
}

Просмотреть файл

@ -4,6 +4,6 @@
DEVICE_CLASS(0x3a1a3a06, "JDM3 servo");
void init_services() {
void app_init_services() {
servo_init(PIN_SERVO);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x325325f2, "JM BTN1 v1.0");
void init_services() {
void app_init_services() {
btn_init(PA_2);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x32bffe5b, "JM D-Pad v1.0");
void init_services() {
void app_init_services() {
gamepad_init();
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x33991b74, "JM PWM (npx) v1.0");
void init_services() {
void app_init_services() {
light_init();
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x30a16d3c, "JM Power v1.0");
void init_services() {
void app_init_services() {
power_init();
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x3142fd1f, "JM PWM (servo) v1.0");
void init_services() {
void app_init_services() {
servo_init(PIN_SERVO);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x3707f76a, "JM SND v1.0");
void init_services() {
void app_init_services() {
snd_init(PIN_PWR);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x36ed0f96, "JM TOUCH v1.0");
void init_services() {
void app_init_services() {
touch_init(PA_4); // TODO - we have 8 channel touch there
}

Просмотреть файл

@ -6,6 +6,6 @@ DEVICE_CLASS(0x38e3c25c, "JM ArcadeCtrls v2.0");
static const uint8_t btnPins[] = {PA_2, PA_5, PA_4, PA_3, PF_0, PF_1, PA_10, -1, PA_0};
static const uint8_t ledPins[] = {-1, -1, -1, -1, PA_6, PA_7, PB_1, -1, -1};
void init_services() {
void app_init_services() {
gamepad_init(sizeof(btnPins), btnPins, ledPins);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x34dd5196, "JM ArcadeBtn v2.0");
void init_services() {
void app_init_services() {
btn_init(PA_10, PA_4);
}

Просмотреть файл

@ -2,7 +2,7 @@
DEVICE_CLASS(0x30838b8e, "JM Crank+Btn v2.0");
void init_services() {
void app_init_services() {
crank_init(PA_6, PA_5);
btn_init(PA_4, -1);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x33a8780b, "JM Crank v2.0");
void init_services() {
void app_init_services() {
crank_init(PA_6, PA_5);
}

Просмотреть файл

@ -5,6 +5,6 @@ DEVICE_CLASS(0x36d257aa, "JM D-Pad v2.0");
// left, up, right, down, a, b, menu, menu2, reset, exit
static const uint8_t btnPins[] = {PA_2, PA_5, PA_4, PA_3, PA_6, PA_7, PB_1, -1, PA_10};
void init_services() {
void app_init_services() {
gamepad_init(sizeof(btnPins), btnPins, NULL);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x35643e91, "JM PWM (npx) v2.0");
void init_services() {
void app_init_services() {
light_init();
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x30a16d3c, "JM Power v1.0");
void init_services() {
void app_init_services() {
power_init();
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x30b0c24e, "JM PWM (Servo) v2.0");
void init_services() {
void app_init_services() {
servo_init(PA_7);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x3e344e1d, "JM Slider v2.0");
void init_services() {
void app_init_services() {
slider_init(PA_3, PA_5, PA_4);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x32f59e1b, "JM SND v2.0");
void init_services() {
void app_init_services() {
snd_init(PA_4);
}

Просмотреть файл

@ -2,6 +2,6 @@
DEVICE_CLASS(0x3ccea1a9, "JM Acc v2.0");
void init_services() {
void app_init_services() {
acc_init();
}

Просмотреть файл

@ -2,4 +2,4 @@
DEVICE_CLASS(0x3eb65a14, "JM Proto v2.0");
void init_services() {}
void app_init_services() {}