适配定义

修改 Fixture 和 Hardware Definitions

新示例使用两个配置头文件。这样产品设置不会和 MCU 存储器参数混在一起:

  • Fixture/Inc/fixture_defines.h:产品 features、identity、defaults 和 limits。灯具开发人员修改这个文件。
  • Hardware/<Board_MCU>/Inc/hw_defines.h:物理 Flash layout 和 MCU write properties。只有更换 Hardware variant 时才修改。

不要为这些设置创建 IDE project constants。每个 Application 工程都会 pre-include fixture_defines.h。BUILD_FOR_BOOTLOADER 是唯一共享的自定义 build define。

命名规则保持一致:所有客户可修改的开关都以 FIXTURE_ENABLE_ 开头,其他客户可修改的产品参数都以 FIXTURE_ 开头。INPUT_WIRELESS_DMX_PROTOCOL_CRMX 等常量是固定选项,不应修改。

安全启用一个功能的顺序

  1. 先把该功能的 FIXTURE_ENABLE_... 保持为 0。
  2. 阅读 Framework/Interfaces/Fixture 或 Framework/Interfaces/Hardware 中对应的稳定头文件。
  3. 在 Examples 中查找同名的完整实现。如果它与产品或外设接近,请复制该实现;否则从 Template 复制伪实现。
  4. 把文件复制到新示例自己的 Fixture/Src 或所选 Hardware/.../Src。绝不能直接修改或编译 Template 文件。
  5. 替换每个伪操作,并手动把本地文件加入所有需要的 CubeIDE 配置或 Keil Target。
  6. 如果可以,先在功能关闭时编译一次。然后把 enable 设为 1,重新编译并测试真实 PCB。

始终需要的文件是 fixture_dmx_mapping.c、fixture_rdm.c、hw_flash.c 和 hw_system.c。可选文件只有在对应功能启用时才存在于示例中,这是有意设计。不要为了让文件夹看起来完整而复制全部 Template 文件。

1. 选择输入源

#define FIXTURE_ENABLE_INPUT_WIRED_DMX       0
#define FIXTURE_ENABLE_INPUT_WIRELESS_DMX    0
#define FIXTURE_ENABLE_INPUT_VISION          1
#define FIXTURE_ENABLE_INPUT_MANUAL          0
#define FIXTURE_ENABLE_INPUT_AUTO            0

/* 数字越小,优先级越高。 */
#define FIXTURE_INPUT_PRIORITY_WIRED_DMX     1U
#define FIXTURE_INPUT_PRIORITY_WIRELESS      2U
#define FIXTURE_INPUT_PRIORITY_VISION        3U
  • WIRED_DMX 需要 hw_wired_dmx.c 中的 UART/transceiver 实现。
  • WIRELESS_DMX 需要 hw_wireless_dmx.c 和一个选定的无线协议。
  • VISION 通过 Vision SPI 接收 DMX 和 RDM。
  • MANUAL 允许本地控制在没有 DMX 输入时提供灯具值。
  • AUTO 让 Framework 根据 reception state 和 priority 选择活动输入。

Vision 会持续发送 frames,因此 Auto mode 必须使用 Vision library 的 DMX reception state,不能用 frame 是否到达来判断。当 Vision 或 wireless control 变为活动状态后,Framework 会关闭冲突的无线 receiver,直到活动输入 timeout。

2. 选择 CRMX 或 W-DMX

#define INPUT_WIRELESS_DMX_PROTOCOL_NONE   0
#define INPUT_WIRELESS_DMX_PROTOCOL_CRMX   1
#define INPUT_WIRELESS_DMX_PROTOCOL_WDMX   2

#define FIXTURE_INPUT_WIRELESS_DMX_PROTOCOL \
        INPUT_WIRELESS_DMX_PROTOCOL_NONE

一个产品只能使用 CRMX 或 W-DMX,不能同时使用。先选择一个协议,再把 FIXTURE_ENABLE_INPUT_WIRELESS_DMX 设置为 1。

3. 启用灯具功能

#define FIXTURE_ENABLE_LED_OUTPUT                  1
#define FIXTURE_ENABLE_DISPLAY                     0
#define FIXTURE_ENABLE_MENU                        0

#define FIXTURE_ENABLE_COLOR_CONVERTER             0
#define FIXTURE_ENABLE_COLOR_CONVERTER_CALIBRATION 0
#define FIXTURE_ENABLE_COLOR_CONVERTER_DITHERING   0

#define FIXTURE_ENABLE_SETTING_DIMMER_CURVE        1
#define FIXTURE_ENABLE_SETTING_DIMMER_SPEED        0

只有对应 Hardware/.../Src/hw_*.c 已经可以工作时才启用功能。编译器会检查重要的 dependencies:

  • FIXTURE_ENABLE_MENU 需要 FIXTURE_ENABLE_DISPLAY。
  • Dimmer speed 和 LED dithering 需要 ColorConverter。
  • ColorConverter 需要 fixture_color_converter_model.c 中有效的生成模型。
  • ColorConverter 还需要 LED PCB 温度传感器。

LED output 需要 fixture_led.c 和 hw_led.c。Display 需要 hw_display.c;自定义菜单页面还需要 fixture_menu.c。ColorConverter 需要 fixture_color_converter_model.c、匹配的预编译 ColorConverter 库、hw_sensors.c 和真实 LED-PCB 温度转换。不要仅为了绕过编译检查就把 FIXTURE_COLOR_CONVERTER_MODEL_IS_VALID 设为 1。

4. 选择持久化存储

#define MANAGED_FLASH_LIBRARY_MANAGED_FLASH         0
#define MANAGED_FLASH_LIBRARY_MANAGED_FLASH_SECTOR  1

#define FIXTURE_MANAGED_FLASH_LIBRARY \
        MANAGED_FLASH_LIBRARY_MANAGED_FLASH_SECTOR
#define FIXTURE_ENABLE_MANAGED_FLASH_CRC 1

新灯具推荐使用 ManagedFlashSector,因为它支持 CRC、持久 object IDs、共享 page 使用,以及写入中断后的恢复。只有需要兼容现有 Flash format 或必须使用更小代码时才选择 classic ManagedFlash。切换实现或 CRC 设置会重新格式化已保存设置。

5. 设置 RDM 产品标识

#define FIXTURE_RDM_MANUFACTURER_ID        0xF00AU
#define FIXTURE_RDM_DEVICE_MODEL_ID        2U
#define FIXTURE_RDM_PRODUCT_CATEGORY       1U
#define FIXTURE_RDM_PRODUCT_DETAIL         0x0004U
#define FIXTURE_RDM_MODEL_DESCRIPTION      "External Example"
#define FIXTURE_RDM_MANUFACTURER_LABEL     "KKT"
#define FIXTURE_RDM_DEFAULT_DEVICE_LABEL   "Vision External Example"

必须把所有示例值替换成产品注册的真实值。生成 DFU 和 production files 时也必须输入相同的 Manufacturer ID 和 Device Model ID。如果不匹配,一个灯具型号的固件不能安装到另一个型号。

#define FIXTURE_SECURITY_KEY {114U, 194U, 199U, 205U, 253U, 181U, 228U, 103U}

把示例 security key 替换成 Vision web service 生成的 Fixture Security Key。产品中不能使用示例 key。

RDM 是 Framework 的固定部分,没有通用 enable switch。Device Info、labels、DMX address/personality、lamp settings、标准 sensors、errors 和 warnings 等通用 PIDs 由 Framework/Src/rdm.c 处理。只有产品专用 PID 或特殊行为放在 Fixture/Src/fixture_rdm.c。

6. 设置 DMX 和 App Control defaults

#define FIXTURE_DMX_DEFAULT_PERSONALITY    1U
#define FIXTURE_DMX_DEFAULT_START_ADDRESS  1U
#define FIXTURE_DMX_DEFAULT_DIMMER_CURVE   0U
#define FIXTURE_DMX_DEFAULT_DIMMER_SPEED   0U
#define FIXTURE_INPUT_SOURCE_VISION        0U
#define FIXTURE_INPUT_SOURCE_WIRED_DMX     1U
#define FIXTURE_INPUT_SOURCE_WIRELESS_DMX  2U
#define FIXTURE_INPUT_SOURCE_MANUAL        3U
#define FIXTURE_INPUT_SOURCE_AUTO          4U
#define FIXTURE_DEFAULT_INPUT_SOURCE       FIXTURE_INPUT_SOURCE_VISION
#define FIXTURE_DMX_TIMEOUT_MS             2000UL

#define FIXTURE_APP_DMX_FOOTPRINT          27U
#define FIXTURE_APP_DIMMER_CURVE           0U
#define FIXTURE_APP_DIMMER_SPEED           0U

必须使用一个带名称的 FIXTURE_INPUT_SOURCE_... 选项来设置 FIXTURE_DEFAULT_INPUT_SOURCE,不要直接填写数字。所选输入源也必须已启用;Manual 只有在产品实现明确的本地/App control 时才可作为例外使用。

FIXTURE_APP_DMX_FOOTPRINT 是明确的 channel count,必须和 FixtureDmxMappingApplyAppFrame() 中实现的 channel mapping 完全一致。不要只根据 LED count 计算,因为 resolution、master dimmer、control channels 和 color channels 都会改变 footprint。

App Control 使用临时的 curve 和 speed 设置,不覆盖保存的 DMX 设置。

7. 理解 Auto mode 优先级

每个启用的自动输入必须使用不同且非零的 priority。Manual/App control 在明确选择时使用;在 Auto mode 中,只有没有更高优先级输入控制时才使用。

8. 描述 LED 灯具

#define FIXTURE_LED_COUNT             9U
#define FIXTURE_LED_COLOR_COUNT       3U
#define FIXTURE_LED_MAX_COLOR_COUNT   6U

#define FIXTURE_LED_POWER_RED_MW      1578UL
#define FIXTURE_LED_POWER_GREEN_MW    3150UL
#define FIXTURE_LED_POWER_BLUE_MW     2600UL

FIXTURE_LED_COUNT 是独立控制的 LED 数量。FIXTURE_LED_COLOR_COUNT 是每个 LED 的 color channel 数量,本参考支持三到六个。没有单独的 pixel enable;LED 数量大于一时自然表示 multi-LED/pixel 灯具。

Runtime 和 battery 计算使用 power values。如果产品使用 RGBW、RGBA、RGBAL 或其他支持的模型,请增加其他颜色的值。

9. 配置 ColorConverter timing

#define FIXTURE_COLOR_CONVERTER_CALCULATION_PERIOD_MS 1U
#define FIXTURE_LED_OUTPUT_PERIOD_US       1000U
#define FIXTURE_LED_OUTPUT_RESOLUTION      0xFFFFU
#define FIXTURE_LED_MINIMUM_WORKING_PWM    1U
#define FIXTURE_DIMMER_SLOW_RESPONSE_MS    100U
#define FIXTURE_COLOR_CONVERTER_MODEL_IS_VALID 0

在 fixture_color_converter_model.c 包含为真实 LED 生成的有效模型以前,保持 ColorConverter 关闭。Framework 按设置周期调用 calculation interrupt,并在 output period 提交完成的结果。可选 dithering 可以改善低亮度 PWM,但需要更多 Flash 和 CPU。

FIXTURE_ENABLE_COLOR_CONVERTER_CALIBRATION 为单灯校准添加存储和 RDM write/save/check 处理。校准温度与校准值一起接收,不是 define。只有启用此功能时,Variables 才注册并保存校准对象。

10. 配置主电源输入按钮

#define FIXTURE_ENABLE_INPUT_POWER_BUTTON        1
#define FIXTURE_POWER_BUTTON_ACTIVE_STATE        0
#define FIXTURE_POWER_BUTTON_LONG_PRESS_STEP_MS  500U
#define FIXTURE_POWER_BUTTON_ON_COUNT            1U
#define FIXTURE_POWER_BUTTON_OFF_COUNT           4U

这是灯具主要的 power/menu input button,不是显示器的其他 navigation buttons。它在 hw_power_button.c 中实现。显示 navigation buttons 属于 display/menu Hardware interface。

11. 配置电池和传感器

#define FIXTURE_ENABLE_BATTERY                         0
#define FIXTURE_ENABLE_BATTERY_HEALTH                  0
#define FIXTURE_BATTERY_CAPACITY_MWH     0UL
#define FIXTURE_BATTERY_LOW_PERCENT      5U

#define FIXTURE_ENABLE_SENSOR_LED_PCB_TEMPERATURE 0
#define FIXTURE_LED_PCB_TEMPERATURE_DIM_C         65U
#define FIXTURE_LED_PCB_TEMPERATURE_MAX_C         85U

hw_battery.c 保存 ADC 或 I2C fuel-gauge 状态,并在 task 中进行异步测量。启用 Battery 后会自动添加 Battery Charge RDM 传感器。只有电量计能提供有效健康度百分比时才启用 Battery Health;Framework 会同时添加该 RDM 传感器。

hw_sensors.c 负责采集和换算 LED PCB 温度。Framework 将其提供给 RDM 和 ColorConverter。ColorConverter 必须使用此传感器。fixture_sensors.c 只添加其他产品传感器;不再需要单独的 standard-sensor 或 battery-voltage 开关。

启用前,把对应 Hardware 源码加入每个 Application Target,并检查非阻塞 task 行为。等待 ADC 或 I2C 时不能停止 SystemTask。只有启用 FIXTURE_ENABLE_CUSTOM_SENSORS 时才加入 fixture_sensors.c。

12. 配置错误和警告代码

#define FIXTURE_ENABLE_ERROR_CODES 1
typedef enum
{
    FIXTURE_ERROR_CODE_NONE = 0,
    FIXTURE_ERROR_CODE_EXAMPLE
} fixture_error_code_t;

#define FIXTURE_ENABLE_WARNING_CODES 1
typedef enum
{
    FIXTURE_WARNING_CODE_NONE = 0,
    FIXTURE_WARNING_CODE_EXAMPLE
} fixture_warning_code_t;

在 fixture_defines.h 中,把灯具特定 ID 直接定义在对应 enable 旁边。两个 NONE 值必须保持为零,并在 fixture_rdm.c 中把其他每个 ID 映射到可打印字符代码。Framework 用固定大小数组保存当前 ID。重复添加同一个值不会产生重复项。RDM 在 GET 请求时按需把 ID 转换成字符代码,多个代码用空格分开。Reset 会清除两个列表。功能关闭时,自定义 RDM PID 仍然 ACK,并返回空列表/计数,而不是 NACK。

13. 配置系统行为

#define FIXTURE_ENABLE_FEATURE_RUNTIME_LIMIT  0
#define FIXTURE_ENABLE_FEATURE_SLEEP          1
#define FIXTURE_ENABLE_FEATURE_EMERGENCY      0
#define FIXTURE_ENABLE_FEATURE_SHIPPING_MODE  0
#define FIXTURE_ENABLE_FEATURE_ANTITHEFT       1

Sleep 只是低功耗状态,灯具仍然开启并可通信,所以 Fixture Is On 保持有效。Wakeup 期间它保持无效,直到 Vision wake signal 可以释放。Turn-off 的短暂过渡期间可以继续保持有效。

参考灯具的开关动画属于 fixture_led.c。请在该文件中修改或删除,它不是 Framework 功能开关。

14. 配置两种 DFU transport

#define FIXTURE_ENABLE_DFU_USING_VISION              1
#define FIXTURE_ENABLE_DFU_USING_VISION_DMX_ADAPTER  0

#define DFU_RECEIVER_BOOTLOADER        0
#define DFU_RECEIVER_APPLICATION       1
#define FIXTURE_DFU_RECEIVER           DFU_RECEIVER_BOOTLOADER
  • FIXTURE_ENABLE_DFU_USING_VISION:通过 Vision SPI module 接收灯具固件。
  • FIXTURE_ENABLE_DFU_USING_VISION_DMX_ADAPTER:通过 Vision DMX Adapter 以 wired RDM 接收,需要启用 wired DMX。
  • DFU_RECEIVER_BOOTLOADER:推荐。对于 Vision SPI,Application 保存重启请求并复位,但不应答仍在等待的 start flag。Bootloader 接收并应答该 flag,然后接收并写入 image。
  • DFU_RECEIVER_APPLICATION:伪集成接口。选择它以前,必须复制并完整实现 Template/Fixture/Src/fixture_dfu_staging.c。

Transport 和 receiver 是两个独立选择。例如 Vision SPI 可以把数据直接发给 Bootloader,也可以让 Application 把任一 transport 收到的数据暂存到 external Flash。

Application 暂存必须检查文件头、保存并跟踪编号数据包、防止两种传输同时写入、检查外部 CRC、请求 DFU_REBOOT_APPLY_STAGED_UPDATE,并按照正确应答时序复位。Bootloader 安装时必须在擦除内部 Flash 前检查外部数据,按正确对齐复制,再次检查内部 Flash,最后才标记完成。量产前必须测试每个阶段发生断电的情况。

15. 设置版本和序列号默认值

#define FIXTURE_DFU_MAX_FIRMWARE_SIZE      \
    (HW_FLASH_APPLICATION_END - HW_FLASH_APPLICATION_ADDRESS + 1UL)
#define FIXTURE_DFU_CONFIG_VERSION         1UL
#define FIXTURE_DEFAULT_SERIAL_NUMBER      1ULL

#define FIXTURE_BOOTLOADER_VERSION_MAJOR   1U
#define FIXTURE_BOOTLOADER_VERSION_MINOR   2U
#define FIXTURE_BOOTLOADER_VERSION_PATCH   0U
#define FIXTURE_BOOTLOADER_VERSION_RELEASE 255U

#define FIXTURE_FIRMWARE_VERSION_MAJOR     0U
#define FIXTURE_FIRMWARE_VERSION_MINOR     1U
#define FIXTURE_FIRMWARE_VERSION_PATCH     0U
#define FIXTURE_FIRMWARE_VERSION_RELEASE   255U

FIXTURE_DFU_MAX_FIRMWARE_SIZE 必须表示完整的 Application 区域,绝不能延伸到 Managed Flash 或其他保留区域。除非产品经过验证必须使用更小的限制,否则应保留基于所选 Hardware 地址的计算方式。

序列号保存在共享 DFU configuration block 中,因为 Bootloader 和 Application 都需要它。只有没有有效 configuration 时才使用 default。Firmware package 的版本必须和这些值完全相同。

16. 配置 Hardware Flash layout

只修改所选 Hardware variant 的 hw_defines.h:

#define HW_FLASH_BOOTLOADER_ADDRESS   ...
#define HW_FLASH_CONFIG_ADDRESS       ...
#define HW_FLASH_APPLICATION_ADDRESS  ...
#define HW_FLASH_APPLICATION_END      ...
#define HW_FLASH_STORAGE_ADDRESS      ...
#define HW_FLASH_STORAGE_SIZE         ...
#define HW_FLASH_PAGE_SIZE            ...
#define HW_FLASH_WRITE_ALIGNMENT      ...

根据 MCU datasheet 检查 erase page/sector boundaries 和 write alignment。Bootloader、共享 configuration、Application 和 Managed Flash 区域不能重叠。每个 IDE linker target 必须使用相同的值。

17. 实现 Fixture 源文件

  • fixture_dmx_mapping.c:将 personalities 和 App Control frames 映射到灯具输出,然后调用 LED layer。
  • fixture_rdm.c:通过 RDM library callbacks 实现 special/custom PIDs。
  • fixture_led.c:所有 LEDs 和 color channels 的产品 output mapping。
  • fixture_color_converter_model.c:为灯具 LED 生成的 ColorConverter model。
  • fixture_sensors.c:附加产品 sensors。
  • fixture_menu.c:产品专用 menu pages。

只有启用 FIXTURE_ENABLE_CUSTOM_VARIABLES 时才加入 fixture_variables.c 和 fixture_variables_custom.h;只有 Application 接收 DFU 时才加入 fixture_dfu_staging.c。每个文件都优先使用功能接近的完整示例实现;没有匹配示例时使用对应 Template 伪文件。启用前必须把复制后的文件加入所有需要的 IDE Target。

需要新截图:当前 fixture_defines.h groups 和 Fixture 文件夹。以前扁平 configuration 和 implementation 结构的截图已经不符合新工程。

18. 最终检查

  1. 所有不支持的 feature 保持为 0。
  2. 构建 Debug、ReleaseBL 和 Bootloader。
  3. 运行 VisionExternalExamples/Tools/TestExamples.ps1。
  4. 生成 DFU package 前确认 RDM identity、DMX footprint、input priorities、versions、security key 和 Flash layout。
  5. 确认每个已启用 Fixture 和 Hardware 实现都存在于所有需要的 IDE Target 中,并且示例中没有保留已关闭功能的可选实现。
  6. 在真实 PCB 上测试全部已启用功能、输入 timeout、保存参数复位行为和两种已选择 DFU transport。

更多说明请参阅 System、Vision DMX、RDM Library、Input Sources、Vision Features 和 Display。

© KKT Künzler Technologies GbR.
Developed by KKT - Künzler Technologies GbR