Skip to content

Commit

Permalink
added bindings for xmlmbus
Browse files Browse the repository at this point in the history
  • Loading branch information
xaelsouth committed Nov 10, 2024
1 parent fefa19e commit d0aef35
Show file tree
Hide file tree
Showing 17 changed files with 2,075 additions and 127 deletions.
5 changes: 3 additions & 2 deletions testhal/SILABS/EFR32FG23x0xx/TEMPLATE/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ include $(CHIBIOS_CONTRIB)/os/hal/hal.mk
include $(CHIBIOS)/os/hal/osal/rt-nil/osal.mk
include $(CHIBIOS_CONTRIB)/os/hal/ports/SILABS/EFR32FG23/platform.mk
include $(CHIBIOS_CONTRIB)/os/hal/boards/SILABS_EFR32FG23_DK2600A/board.mk
include $(CHIBIOS_CONTRIB)/ext/xmlmbus/xmlmbus_chibios.mk
include xmlmbus/xmlmbus_chibios.mk
include emlib/emlib.mk
include raillib/raillib.mk
# RTOS files (optional).
Expand Down Expand Up @@ -178,7 +178,8 @@ UDEFS += \
-DCLKIN0_FREQ=0UL \
-DLFRCO_FREQ=32768UL \
-DULFRCO_FREQ=1000UL \
-DLFXO_FREQ=LFRCO_FREQ
-DLFXO_FREQ=LFRCO_FREQ \
-DXMLMBUS_SERVER_HAS_MALLOC=0
# -DSL_TRUSTZONE_NONSECURE
# -DSL_TRUSTZONE_SECURE \
Expand Down
6 changes: 3 additions & 3 deletions testhal/SILABS/EFR32FG23x0xx/TEMPLATE/cfg/mcuconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
#define EFR32_EM4GRPACLKSEL EFR32_EM4GRPACLKSEL_LFXO
#define EFR32_EM4GRPACLK_ENABLED (EFR32_EM4GRPACLKSEL != EFR32_EM4GRPACLKSEL_NOCLOCK)

#define EFR32_EUSART1SEL EFR32_EUSART1SEL_EM01GRPCCLK
#define EFR32_EUSART1SEL EFR32_EUSART1SEL_LFXO

#define EFR32_EUSART23SEL EFR32_EUSART23SEL_HFRCODPLL

Expand All @@ -92,9 +92,9 @@
* SIO driver system settings.
*/
#define EFR32_SIO_USE_EUSART1 TRUE
#define EFR32_SIO_USE_EUSART2 TRUE
#define EFR32_SIO_USE_EUSART2 FALSE
#define EFR32_SIO_USE_EUSART3 FALSE
#define EFR32_SIO_USE_USART1 TRUE
#define EFR32_SIO_USE_USART1 FALSE
#define EFR32_EUSART1_RX_IRQ_PRIORITY 4
#define EFR32_EUSART1_TX_IRQ_PRIORITY 4
#define EFR32_EUSART2_RX_IRQ_PRIORITY 4
Expand Down
302 changes: 180 additions & 122 deletions testhal/SILABS/EFR32FG23x0xx/TEMPLATE/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
#include "cmsis_os.h"
#include "hal.h"

#include "rail.h"
#include "sli_rail_util_callbacks.h" // for internal-only callback signatures
#include "sl_rail_util_init.h"
#include "sl_rail_util_protocol.h"
#include <xmlmbus_chibios.h>
#include <xmlmbus_util.h>
#include <xmlmbus_server.h>
#include <xmlmbus_mbus_frame.h>

static void led_on(void) {

Expand All @@ -43,143 +43,163 @@ static void led_toggle(void) {
palTogglePad(GPIOB, 2);
}

void st_callback(unsigned alarm) {
/* Must return XMLMBUS_SERVER_OK if no error. */
static int req_ud2_handler(struct xmlmbus_server_ctx *ctx, void *arg) {

stStopAlarmN(alarm);
stStartAlarmN(alarm, stGetCounter() + chTimeMS2I(3000));
}
(void)arg;
int rc;

extern const RAIL_ChannelConfig_t *channelConfigs[];
if (XMLMBUS_SERVER_OK != (rc = xmlmbus_server_write_fixed_header(ctx)))
return rc;

static RAIL_Handle_t railHandle;
return XMLMBUS_SERVER_OK;
}

enum {
WMBUS_MODE_T1A = 0,
WMBUS_MODE_C1A = 1,
WMBUS_MODE_S1 = 2
};
/* Must return XMLMBUS_SERVER_OK if no error. */
static int snd_ud_read_memory(struct xmlmbus_server_ctx *ctx, void *arg, const uint8_t *in, uint32_t inlen, void *out, uint32_t *outlen) {

static void send_datagram(void) {
(void)ctx;
(void)arg;

static const uint8_t wmbus_datagram_1[] = {
0x31, 0x44, 0x93, 0x44, 0x48, 0x32, 0x75, 0x26, 0x35, 0x08, // 0x6D, 0x95,
0x7A, 0xA3, 0x00, 0x00, 0x20, 0x0B, 0x6E, 0x16, 0x00, 0x00, 0x4B, 0x6E, 0x21, 0x02, 0x00, 0x42, // 0x91, 0xDD,
0x6C, 0xBF, 0x2A, 0xCB, 0x08, 0x6E, 0x16, 0x00, 0x00, 0xC2, 0x08, 0x6C, 0xDE, 0x29, 0x32, 0x6C, // 0x8C, 0xC4,
0xFF, 0xFF, 0x04, 0x6D, 0x27, 0x0E, 0xD2, 0x2A, // 0x3D, 0x89
};
const uint32_t outlen_max = *outlen;

CC_ALIGN_DATA(16)static uint8_t railFifo[1024];
static uint8_t simulated_memory[256];

static int config_nr = WMBUS_MODE_T1A;
const RAIL_ChannelConfig_t *channel_config = channelConfigs[config_nr];
config_nr = (config_nr + 1) % 3;
(void)RAIL_ConfigChannels(railHandle, channel_config,
&sli_rail_util_on_channel_config_change);
MemoryBlock_t memory_block;
if (inlen != sizeof(memory_block))
return XMLMBUS_SERVER_ERROR_WRONG_DATA_LENGTH;

led_toggle();
memcpy(&memory_block, in, sizeof(memory_block));

#define RAIL_CHANNEL_0 0
memcpy(railFifo, wmbus_datagram_1, sizeof(wmbus_datagram_1));
RAIL_SetTxFifo(railHandle, railFifo, sizeof(wmbus_datagram_1), sizeof(railFifo));
RAIL_StartTx(railHandle, RAIL_CHANNEL_0, RAIL_TX_OPTIONS_DEFAULT, NULL);
*outlen = MIN(outlen_max, MIN(memory_block.size, sizeof(simulated_memory)));
memcpy(out, simulated_memory, *outlen);

return XMLMBUS_SERVER_OK;
}

/* Overload weak function from sl_rail_util_callbacks.c. */
void sl_rail_util_on_assert_failed(RAIL_Handle_t rail_handle,
RAIL_AssertErrorCodes_t error_code) {
static int snd_nke_handler(struct xmlmbus_server_ctx *ctx) {

if (0 != xmlmbus_buffer_write_cfield(&ctx->buffer, MBUS_ACK))
return (-1);

(void)rail_handle;
(void)error_code;
osalDbgAssert(false, "rail_handle with error_code");
return 0;
}

/* Overload weak function from sl_rail_util_callbacks.c. */
void sl_rail_util_on_rf_ready(RAIL_Handle_t rail_handle) {
static const struct ctrl_cmd ctrl_cmd_table[] = {
{ MBUS_REQ_UD2 | MBUS_CFIELD_FCB | MBUS_CFIELD_FCV, req_ud2_handler, NULL },
{ MBUS_REQ_UD2 | MBUS_CFIELD_FCV, req_ud2_handler, NULL },
{ MBUS_REQ_UD2 | MBUS_CFIELD_FCB, req_ud2_handler, NULL },
{ MBUS_REQ_UD2, req_ud2_handler, NULL },
};

static const struct appl_cmd appl_cmd_table[] = {
{ VIFE_LAYER1_APPLICATION & VIFE_LAYER_MASK,
VIFE_REQUEST_TYPE_MEMORY & VIFE_REQUEST_MASK,
VIFE_FUNCTION_READ_MEMORY & VIFE_FUNCTION_MASK,
snd_ud_read_memory, NULL },
};

static const struct ci_cmd ci_cmd_table[] = {
{ MBUS_SND_UD | MBUS_CFIELD_FCB | MBUS_CFIELD_FCV, MBUS_CI_DATA_SEND, xmlmbus_server_snd_ud_handler, NULL },
{ MBUS_SND_UD | MBUS_CFIELD_FCV, MBUS_CI_DATA_SEND, xmlmbus_server_snd_ud_handler, NULL },
{ MBUS_SND_UD | MBUS_CFIELD_FCB, MBUS_CI_DATA_SEND, xmlmbus_server_snd_ud_handler, NULL },
{ MBUS_SND_UD, MBUS_CI_DATA_SEND, xmlmbus_server_snd_ud_handler, NULL },
};

static const SIOConfig sio_config = {
.baud = 2400U, /* Baudrate (2400 max. for LF operation) */
.cfg0 = (0U << 0) | /* ASYNC operation */
(4U << 5), /* Disable oversampling (for LF operation) */
.framecfg = EFR32_SIO_LLD_EUSART_8E1,
};

static struct xmlmbus_server_ctx server_ctx = {

.address = MBUS_ADDRESS_UNCONFIGURED,
.ident_no = 0x12345678, /* BCD number. */
.manufacturer = 0xAABB,
.version = 0,
.medium = 0xFF,

.ctrl_cmd_table = ctrl_cmd_table,
.ctrl_cmd_table_size = ARRAY_SIZE(ctrl_cmd_table),
.ci_cmd_table = ci_cmd_table,
.ci_cmd_table_size = ARRAY_SIZE(ci_cmd_table),
.appl_cmd_table = appl_cmd_table,
.appl_cmd_table_size = ARRAY_SIZE(appl_cmd_table),
.single_character_handler = snd_nke_handler,
};

static int cmd_read_timeout = 5000; /* Milliseconds. */
static int cmd_write_timeout = 5000; /* Milliseconds. */
static uint8_t buffer[MBUS_FRAME_SIZE_MAX];

static int server_iface_open(struct xmlmbus_interface *iface, int flags) {

(void)flags;

(void)rail_handle;
#if EFR32_SIO_USE_EUSART1 == TRUE
palSetPadMode(GPIOA, 7, PAL_MODE_OUTPUT_PUSHPULL | PAL_MODE_ALTERNATE(CLKOUT2_LFXO));

palSetPadMode(GPIOA, 9, PAL_MODE_OUTPUT_PUSHPULL | PAL_MODE_ALTERNATE(EUSART0_TX));
palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLUP | PAL_MODE_ALTERNATE(EUSART0_RX));

sioStart(iface->siop, &sio_config);
#else
#error "EUSART1 disabled!"
#endif

return 0;
}

/* Overload weak function from sl_rail_util_callbacks.c. */
void sl_rail_util_on_channel_config_change(RAIL_Handle_t rail_handle,
const RAIL_ChannelConfigEntry_t *entry) {
static int server_iface_close(struct xmlmbus_interface *iface) {

sioStop(iface->siop);

palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(EUSART0_TX_DIS));
palSetPadMode(GPIOA, 10, PAL_MODE_ALTERNATE(EUSART0_RX_DIS));

(void)rail_handle;
(void)entry;
return 0;
}

/* Overload weak function from sl_rail_util_callbacks.c. */
void sl_rail_util_on_event(RAIL_Handle_t rail_handle,
RAIL_Events_t events) {
static int server_iface_read(struct xmlmbus_interface *iface, void *buf, unsigned long len, int flags, int timeout_msec) {

(void)rail_handle;
(void)events;
(void)flags;

msg_t msg = sioSynchronizeRX(iface->siop, TIME_MS2I(timeout_msec));
if (msg == MSG_OK) {
return (sioAsyncRead(iface->siop, buf, len));
}

return (-1);
}

void custom_RAIL_Init(void) {

RAIL_Status_t status;
(void)status;

RAIL_Config_t sl_rail_config = {
.eventsCallback = &sli_rail_util_on_event,
// Other fields are ignored nowadays
};
railHandle = RAIL_Init(&sl_rail_config, &sli_rail_util_on_rf_ready);

RAIL_DataConfig_t data_config = {
.txSource = SL_RAIL_UTIL_INIT_DATA_FORMAT_INST0_TX_SOURCE,
.rxSource = SL_RAIL_UTIL_INIT_DATA_FORMAT_INST0_RX_SOURCE,
.txMethod = SL_RAIL_UTIL_INIT_DATA_FORMAT_INST0_TX_MODE,
.rxMethod = SL_RAIL_UTIL_INIT_DATA_FORMAT_INST0_RX_MODE,
};
status = RAIL_ConfigData(railHandle, &data_config);
osalDbgCheck(status == RAIL_STATUS_NO_ERROR);

const RAIL_ChannelConfig_t *channel_config = channelConfigs[WMBUS_MODE_C1A];

(void)RAIL_ConfigChannels(railHandle,
channel_config,
&sli_rail_util_on_channel_config_change);
status = sl_rail_util_protocol_config(railHandle,
SL_RAIL_UTIL_INIT_PROTOCOL_INST0_DEFAULT);
osalDbgCheck(status == RAIL_STATUS_NO_ERROR);

status = RAIL_ConfigCal(railHandle,
0U
| (SL_RAIL_UTIL_INIT_CALIBRATION_TEMPERATURE_NOTIFY_INST0_ENABLE
? RAIL_CAL_TEMP : 0U)
| (SL_RAIL_UTIL_INIT_CALIBRATION_ONETIME_NOTIFY_INST0_ENABLE
? RAIL_CAL_ONETIME : 0U));
osalDbgCheck(status == RAIL_STATUS_NO_ERROR);

status = RAIL_ConfigEvents(railHandle, RAIL_EVENTS_ALL,
SL_RAIL_UTIL_INIT_EVENT_INST0_MASK);
osalDbgCheck(status == RAIL_STATUS_NO_ERROR);

RAIL_StateTransitions_t tx_transitions = {
.success = SL_RAIL_UTIL_INIT_TRANSITION_INST0_TX_SUCCESS,
.error = SL_RAIL_UTIL_INIT_TRANSITION_INST0_TX_ERROR
};
status = RAIL_SetTxTransitions(railHandle,
&tx_transitions);
osalDbgCheck(status == RAIL_STATUS_NO_ERROR);

RAIL_StateTransitions_t rx_transitions = {
.success = SL_RAIL_UTIL_INIT_TRANSITION_INST0_RX_SUCCESS,
.error = SL_RAIL_UTIL_INIT_TRANSITION_INST0_RX_ERROR
};
status = RAIL_SetRxTransitions(railHandle,
&rx_transitions);
osalDbgCheck(status == RAIL_STATUS_NO_ERROR);
static int server_iface_write(struct xmlmbus_interface *iface, const void *buf, unsigned long len, int flags, int timeout_msec) {

(void)flags;

msg_t msg = sioSynchronizeTX(iface->siop, TIME_MS2I(timeout_msec));
if (msg == MSG_OK) {
return (sioAsyncWrite(iface->siop, buf, len));
}

return (-1);
}

static struct xmlmbus_interface server_iface = {
.siop = &SIOD1,
.open = server_iface_open,
.close = server_iface_close,
.read = server_iface_read,
.write = server_iface_write,
};

/*
* Application entry point.
*/
int main(void) {

int unused = 0;
(void)unused;
int rc;

/* HAL initialization, this also initializes the configured device drivers
and performs the board-specific initializations.*/
Expand All @@ -194,24 +214,62 @@ int main(void) {
by default.*/
osKernelStart();

led_off();
custom_RAIL_Init();
stSetCallback(1, st_callback);
stStartAlarmN(1, stGetCounter() + chTimeMS2I(3000));
led_on();

//RAIL_TxStreamStart(railHandle, RAIL_STREAM_PN9_STREAM);
//RAIL_TxStreamStart(railHandle, RAIL_STREAM_CARRIER_WAVE);

systime_t prev = chVTGetSystemTime();
xmlmbus_interface_open(&server_iface, 0);

/*
* Normal main() thread activity, in this demo it does nothing except
* sleeping in a loop and check the button state.
*/
while (true) {
send_datagram();
prev = chThdSleepUntilWindowed(prev, chTimeAddX(prev, TIME_MS2I(3000)));
led_off();

int mbus_packet_size = xmlmbus_interface_read(&server_iface, buffer, sizeof(buffer), 0, cmd_read_timeout);

if (mbus_packet_size > 0) {
led_on();

//log_buffer("REQUEST >>", buffer, mbus_packet_size);

rc = xmlmbus_server_process_client_request(&server_ctx, buffer, mbus_packet_size);
if (rc != XMLMBUS_SERVER_OK) {
//fprintf(stderr, "Error processing client request: %d.\n", rc);
continue;
}

unsigned long response_len = xmlmbus_server_get_response_buffer_used(&server_ctx);
if (response_len == 0) {
/* It must have been SND-NKE - don't respond at all. */
continue;
}

unsigned long buffer_used = 0;
rc = xmlmbus_interface_create_packet(&server_iface, buffer, &buffer_used,
xmlmbus_server_get_response_buffer(&server_ctx),
response_len);
if (rc != 0) {
//fprintf(stderr, "Error creating packet: %d.\n", rc);
continue;
}

//log_buffer("RESPOND <<", buffer, buffer_used);

if ((int)buffer_used != xmlmbus_interface_write(&server_iface, buffer, buffer_used, 0, cmd_write_timeout)) {
//fprintf(stderr, "Error writing response: %d.\n", rc);
continue;
}

led_toggle();
}
else if (mbus_packet_size < 0) {
rc = XMLMBUS_SERVER_ERROR;
//fprintf(stderr, "Error reading request: %d.\n", rc);
break;
}
else {
/* Nothing read. */
}
}

xmlmbus_interface_close(&server_iface);
}

Loading

0 comments on commit d0aef35

Please sign in to comment.