Added device types and vest mini app
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 22s

This commit is contained in:
2026-01-10 09:07:49 +01:00
parent 978f93ec3d
commit ce4d0d1a44
31 changed files with 621 additions and 273 deletions

View File

@@ -0,0 +1,2 @@
add_subdirectory(send)
add_subdirectory(recv)

73
firmware/libs/ir/Kconfig Normal file
View File

@@ -0,0 +1,73 @@
menu "IR protocol"
config IR_PROTO
bool "IR protocol core"
help
Enable shared IR protocol settings used by send/receive libraries.
if IR_PROTO
menu "IR protocol configuration"
config IR_SEND_CARRIER_HZ
int "IR carrier frequency (Hz)"
default 38000
range 30000 45000
help
Carrier frequency for PWM generation. Standard value is 38 kHz for TSOP48xx receivers.
config IR_SEND_DUTY_CYCLE_PERCENT
int "Carrier duty cycle (%)"
default 50
range 25 75
help
PWM duty cycle percentage. Some receivers prefer 33%, others 50%.
Default 50% works with most TSOP-series receivers.
config IR_PROTO_BASE_US
int "IR base period (microseconds)"
default 600
range 300 1000
help
Base timing used for start/mark/space. Default 600 µs (similar to Sony SIRC).
config IR_PROTO_START_MULT
int "Start burst factor"
default 4
range 2 8
help
Start burst duration = base × factor. Default 4× for robust sync.
config IR_PROTO_GAP_MULT
int "Start gap factor"
default 1
range 0 4
help
Gap after start burst (carrier off) = base × factor. 0 disables the gap.
config IR_PROTO_MARK_MULT
int "Mark factor"
default 1
range 1 2
help
Mark duration = base × factor. Default 1×.
config IR_PROTO_SPACE0_MULT
int "Space0 factor (bit 0)"
default 1
range 1 3
help
Space for bit 0 = base × factor. Default 1×.
config IR_PROTO_SPACE1_MULT
int "Space1 factor (bit 1)"
default 2
range 1 4
help
Space for bit 1 = base × factor. Default 2× (double base time).
endmenu
endif
endmenu

View File

@@ -0,0 +1,5 @@
if(CONFIG_IR_RECV)
zephyr_library()
zephyr_sources(src/ir_recv.c)
zephyr_include_directories(include)
endif()

View File

@@ -0,0 +1,6 @@
config IR_RECV
bool "IR Receive Library"
select IR_PROTO
help
Enable IR receive library for the laser tag system.
Placeholder implementation; timing parameters come from IR_PROTO.*

View File

@@ -0,0 +1,14 @@
#ifndef IR_RECV_H
#define IR_RECV_H
#include <zephyr/device.h>
/**
* @brief Initialize IR receive pipeline (stub).
*
* Intended to configure GPIO/interrupts/ppi for future implementation.
* @return 0 on success, negative errno otherwise.
*/
int ir_recv_init(void);
#endif /* IR_RECV_H */

View File

@@ -0,0 +1,12 @@
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include "ir_recv.h"
LOG_MODULE_REGISTER(ir_recv, LOG_LEVEL_INF);
int ir_recv_init(void)
{
LOG_INF("IR receive stub initialized (no implementation yet)");
return 0;
}

View File

@@ -0,0 +1,5 @@
if(CONFIG_IR_SEND)
zephyr_library()
zephyr_sources(src/ir_send.c)
zephyr_include_directories(include)
endif()

View File

@@ -0,0 +1,6 @@
config IR_SEND
bool "IR Send Library"
select IR_PROTO
help
Enable IR transmission library for laser tag system.
Provides PWM-based IR carrier generation with pulse-distance coding.

View File

@@ -0,0 +1,45 @@
#ifndef IR_SEND_H
#define IR_SEND_H
/**
* @file ir_send.h
* @brief Infrared transmission library for laser tag system.
*/
#include <stdint.h>
/**
* @brief Initialize IR output hardware (PWM backend).
* @return 0 on success, negative error code otherwise.
*/
int ir_send_init(void);
/**
* @brief Send a single IR pulse (carrier burst).
* @param duration_us Pulse duration in microseconds.
* @return 0 on success.
*/
int ir_send_pulse(uint32_t duration_us);
/**
* @brief Send a carrier burst of given duration (us) at configured frequency.
* @param burst_us Duration in microseconds.
* @return 0 on success.
*/
int ir_send_burst_us(uint32_t burst_us);
/**
* @brief Send IR message (sequence of pulses and gaps).
* @param data IR payload (e.g., shooter ID, power-up type).
* @param len Length of data in bytes.
* @return 0 on success.
*/
int ir_send_message(const uint8_t *data, uint8_t len);
/**
* @brief Set IR carrier frequency.
* @param freq_hz Carrier frequency in Hz (typically 38000 Hz).
*/
void ir_send_set_frequency(uint32_t freq_hz);
#endif /* IR_SEND_H */

View File

@@ -0,0 +1,78 @@
/*
* IR Send Library - PWM-based carrier generation
*/
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/pwm.h>
#include "ir_send.h"
LOG_MODULE_REGISTER(ir_send_lib);
static const struct pwm_dt_spec ir_pwm = PWM_DT_SPEC_GET(DT_ALIAS(ir_output));
static uint32_t carrier_freq = 38000; /* Standard IR carrier frequency in Hz */
int ir_send_init(void)
{
if (!device_is_ready(ir_pwm.dev)) {
LOG_ERR("IR PWM device not ready!");
return -ENODEV;
}
LOG_INF("IR output PWM ready: dev=%p, channel=%u", ir_pwm.dev, ir_pwm.channel);
return 0;
}
int ir_send_pulse(uint32_t duration_us)
{
return ir_send_burst_us(duration_us);
}
int ir_send_message(const uint8_t *data, uint8_t len)
{
if (!device_is_ready(ir_pwm.dev)) {
return -ENODEV;
}
LOG_DBG("Sending IR message (%u bytes)", len);
/* TODO: Implement IR protocol encoding (e.g., NEC, custom protocol)
* For now, just a placeholder that sends a test pulse.
*/
ir_send_pulse(1000); /* 1ms test pulse */
return 0;
}
void ir_send_set_frequency(uint32_t freq_hz)
{
carrier_freq = freq_hz;
LOG_DBG("IR carrier frequency set to %u Hz", carrier_freq);
}
int ir_send_burst_us(uint32_t burst_us)
{
if (!device_is_ready(ir_pwm.dev)) {
return -ENODEV;
}
uint64_t period_ns = PWM_HZ(carrier_freq);
uint64_t duty_ns = period_ns / 2U; /* 50% duty cycle */
int ret = pwm_set_dt(&ir_pwm, period_ns, duty_ns);
if (ret != 0) {
LOG_ERR("Failed to enable PWM burst: %d", ret);
return ret;
}
k_usleep(burst_us);
/* Stop carrier after burst */
ret = pwm_set_dt(&ir_pwm, period_ns, 0);
if (ret != 0) {
LOG_ERR("Failed to stop PWM after burst: %d", ret);
}
return ret;
}