Compare commits
1 Commits
d58a18bd4b
...
rev.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
| 401d8f5c1b |
@@ -1,14 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.20.0)
|
|
||||||
|
|
||||||
# Set board root to find our custom board
|
|
||||||
set(BOARD_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
|
|
||||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
|
||||||
project(ews_canfd_cdc_composite)
|
|
||||||
|
|
||||||
target_sources(app PRIVATE
|
|
||||||
src/main.c
|
|
||||||
src/cdc_handler.c
|
|
||||||
src/pfet_control.c
|
|
||||||
src/gs_usb_can.c
|
|
||||||
)
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
# CAN FD CDC Composite Firmware
|
|
||||||
|
|
||||||
A Zephyr-based firmware for the EWS board that provides:
|
|
||||||
- CAN FD to gs_usb interface (similar to candlelight)
|
|
||||||
- USB CDC interface for PFET control
|
|
||||||
- USB composite device functionality
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- **CAN FD Support**: Full CAN FD protocol support via gs_usb interface
|
|
||||||
- **USB Composite**: Single USB device with multiple interfaces:
|
|
||||||
- gs_usb interface for CAN communication
|
|
||||||
- CDC ACM interface for PFET control and status
|
|
||||||
- **PFET Control**: Control both output PFETs via CDC commands
|
|
||||||
- **Status LEDs**: Control status LEDs for visual feedback
|
|
||||||
- **Compatible**: Works with standard CAN utilities (can-utils, etc.)
|
|
||||||
|
|
||||||
## Hardware Target
|
|
||||||
|
|
||||||
- **MCU**: STM32G0B1KBU6 (on EWS board)
|
|
||||||
- **CAN**: CAN FD via FDCAN1 (PB0/PB1) with SN65HVD230 transceiver
|
|
||||||
- **USB**: USB 2.0 Full Speed (PA11/PA12)
|
|
||||||
- **GPIOs**:
|
|
||||||
- PFET1 control: PA8
|
|
||||||
- PFET2 control: PB2
|
|
||||||
- Status LED: PB4
|
|
||||||
|
|
||||||
## Build Requirements
|
|
||||||
|
|
||||||
- Zephyr RTOS (v3.5+)
|
|
||||||
- West build tool
|
|
||||||
- ARM GCC toolchain
|
|
||||||
|
|
||||||
## Building
|
|
||||||
|
|
||||||
```bash
|
|
||||||
west build -b ews
|
|
||||||
```
|
|
||||||
|
|
||||||
## CDC Protocol
|
|
||||||
|
|
||||||
The CDC interface uses simple text commands:
|
|
||||||
- `PFET1_ON\n` - Turn on PFET1
|
|
||||||
- `PFET1_OFF\n` - Turn off PFET1
|
|
||||||
- `PFET2_ON\n` - Turn on PFET2
|
|
||||||
- `PFET2_OFF\n` - Turn off PFET2
|
|
||||||
- `STATUS\n` - Get current PFET status
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
if(CONFIG_BOARD_EWS)
|
|
||||||
board_runner_args(jlink "--device=STM32G0B1KB" "--speed=4000")
|
|
||||||
board_runner_args(pyocd "--target=stm32g0b1kbux")
|
|
||||||
|
|
||||||
include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake)
|
|
||||||
include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake)
|
|
||||||
include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake)
|
|
||||||
endif()
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
board:
|
|
||||||
name: ews
|
|
||||||
vendor: ews
|
|
||||||
socs:
|
|
||||||
- name: stm32g0b1xx
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
# EWS Board
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
The EWS Board is based on the STM32G0B1KBU6 microcontroller in UFQFPN32 package.
|
|
||||||
|
|
||||||
## Hardware Features
|
|
||||||
|
|
||||||
- STM32G0B1KBU6 MCU (Arm Cortex-M0+ core, 128 KB Flash, 36 KB RAM)
|
|
||||||
- Internal HSI oscillator with USB clock recovery
|
|
||||||
- USB 2.0 Full Speed interface
|
|
||||||
- CAN FD interface
|
|
||||||
- Status LED on PB4
|
|
||||||
- Two PFET control outputs (PA8, PB2)
|
|
||||||
|
|
||||||
## Pin Configuration
|
|
||||||
|
|
||||||
| Function | Pin | Notes |
|
|
||||||
|----------|-----|-------|
|
|
||||||
| Status LED | PB4 | Active high |
|
|
||||||
| PFET1 Control | PA8 | Active high |
|
|
||||||
| PFET2 Control | PB2 | Active high |
|
|
||||||
| CAN RX | PB0 | FDCAN1_RX |
|
|
||||||
| CAN TX | PB1 | FDCAN1_TX |
|
|
||||||
| USB D- | PA11 | USB_DM |
|
|
||||||
| USB D+ | PA12 | USB_DP |
|
|
||||||
|
|
||||||
## Clock Configuration
|
|
||||||
|
|
||||||
The board uses the internal HSI oscillator (16 MHz) with PLL to generate:
|
|
||||||
- System clock: 64 MHz
|
|
||||||
- USB clock: 48 MHz (from PLL Q output)
|
|
||||||
- CAN clock: 64 MHz
|
|
||||||
|
|
||||||
No external crystal is used; USB clock recovery ensures accurate timing for USB communication.
|
|
||||||
|
|
||||||
## Programming and Debugging
|
|
||||||
|
|
||||||
The board supports programming via:
|
|
||||||
- USB DFU (built-in STM32 bootloader)
|
|
||||||
- SWD interface (if exposed)
|
|
||||||
|
|
||||||
## Building Firmware
|
|
||||||
|
|
||||||
```bash
|
|
||||||
west build -b ews
|
|
||||||
```
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
/dts-v1/;
|
|
||||||
#include <st/g0/stm32g0b1Xb.dtsi>
|
|
||||||
#include <st/g0/stm32g0b1k(b-c-e)ux-pinctrl.dtsi>
|
|
||||||
|
|
||||||
/ {
|
|
||||||
model = "EWS Board STM32G0B1KBU6";
|
|
||||||
compatible = "ews,ews";
|
|
||||||
|
|
||||||
chosen {
|
|
||||||
zephyr,console = &cdc_acm_uart0;
|
|
||||||
zephyr,shell-uart = &cdc_acm_uart0;
|
|
||||||
zephyr,sram = &sram0;
|
|
||||||
zephyr,flash = &flash0;
|
|
||||||
zephyr,canbus = &fdcan1;
|
|
||||||
};
|
|
||||||
|
|
||||||
leds {
|
|
||||||
compatible = "gpio-leds";
|
|
||||||
status_led: led_0 {
|
|
||||||
gpios = <&gpiob 4 GPIO_ACTIVE_HIGH>;
|
|
||||||
label = "Status LED";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
pfets {
|
|
||||||
compatible = "gpio-leds";
|
|
||||||
pfet1: pfet_1 {
|
|
||||||
gpios = <&gpioa 8 GPIO_ACTIVE_HIGH>;
|
|
||||||
label = "PFET1 Control";
|
|
||||||
};
|
|
||||||
pfet2: pfet_2 {
|
|
||||||
gpios = <&gpiob 2 GPIO_ACTIVE_HIGH>;
|
|
||||||
label = "PFET2 Control";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
aliases {
|
|
||||||
led0 = &status_led;
|
|
||||||
pfet0 = &pfet1;
|
|
||||||
pfet1 = &pfet2;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
&clk_hsi {
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
|
|
||||||
&pll {
|
|
||||||
div-m = <1>;
|
|
||||||
mul-n = <8>;
|
|
||||||
div-q = <2>;
|
|
||||||
div-r = <2>;
|
|
||||||
clocks = <&clk_hsi>;
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
|
|
||||||
&rcc {
|
|
||||||
clocks = <&pll>;
|
|
||||||
clock-frequency = <DT_FREQ_M(64)>;
|
|
||||||
ahb-prescaler = <1>;
|
|
||||||
apb1-prescaler = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
&fdcan1 {
|
|
||||||
pinctrl-0 = <&fdcan1_rx_pb0 &fdcan1_tx_pb1>;
|
|
||||||
pinctrl-names = "default";
|
|
||||||
bus-speed = <500000>;
|
|
||||||
bus-speed-data = <2000000>;
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
|
|
||||||
&usb {
|
|
||||||
pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>;
|
|
||||||
pinctrl-names = "default";
|
|
||||||
status = "okay";
|
|
||||||
cdc_acm_uart0: cdc_acm_uart0 {
|
|
||||||
compatible = "zephyr,cdc-acm-uart";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
&gpioa {
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
|
|
||||||
&gpiob {
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
|
|
||||||
&flash0 {
|
|
||||||
partitions {
|
|
||||||
compatible = "fixed-partitions";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
|
|
||||||
boot_partition: partition@0 {
|
|
||||||
label = "mcuboot";
|
|
||||||
reg = <0x00000000 0x00002000>;
|
|
||||||
};
|
|
||||||
slot0_partition: partition@2000 {
|
|
||||||
label = "image-0";
|
|
||||||
reg = <0x00002000 0x0001E000>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
# EWS Board Configuration
|
|
||||||
|
|
||||||
CONFIG_BOARD_EWS=y
|
|
||||||
CONFIG_SOC_SERIES_STM32G0X=y
|
|
||||||
CONFIG_SOC_STM32G0B1XX=y
|
|
||||||
|
|
||||||
# Clock configuration - USB clock sync, no external crystal
|
|
||||||
CONFIG_CLOCK_CONTROL=y
|
|
||||||
CONFIG_CLOCK_STM32_HSI=y
|
|
||||||
CONFIG_CLOCK_STM32_PLL_SRC_HSI=y
|
|
||||||
CONFIG_CLOCK_STM32_PLL_M_DIVISOR=1
|
|
||||||
CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=8
|
|
||||||
CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=2
|
|
||||||
CONFIG_CLOCK_STM32_PLL_R_DIVISOR=2
|
|
||||||
|
|
||||||
# USB 48MHz from PLL
|
|
||||||
CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=2
|
|
||||||
|
|
||||||
# Enable GPIO
|
|
||||||
CONFIG_GPIO=y
|
|
||||||
|
|
||||||
# Enable CAN
|
|
||||||
CONFIG_CAN=y
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
CONFIG_USB_DEVICE_STACK=y
|
|
||||||
CONFIG_USB_DEVICE_COMPOSITE=y
|
|
||||||
|
|
||||||
# USB CDC ACM
|
|
||||||
CONFIG_USB_CDC_ACM=y
|
|
||||||
CONFIG_SERIAL=y
|
|
||||||
CONFIG_UART_CONSOLE=n
|
|
||||||
CONFIG_USB_UART_CONSOLE=y
|
|
||||||
|
|
||||||
# CAN configuration
|
|
||||||
CONFIG_CAN=y
|
|
||||||
CONFIG_CAN_FD_MODE=y
|
|
||||||
|
|
||||||
# Networking for gs_usb
|
|
||||||
CONFIG_NETWORKING=y
|
|
||||||
CONFIG_NET_SOCKETS=y
|
|
||||||
CONFIG_NET_SOCKETS_CAN=y
|
|
||||||
|
|
||||||
# GPIO for PFET control
|
|
||||||
CONFIG_GPIO=y
|
|
||||||
|
|
||||||
# Logging
|
|
||||||
CONFIG_LOG=y
|
|
||||||
CONFIG_USB_DEVICE_LOG_LEVEL_DBG=y
|
|
||||||
|
|
||||||
# System
|
|
||||||
CONFIG_MAIN_STACK_SIZE=2048
|
|
||||||
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* CDC Handler Module
|
|
||||||
* Handles USB CDC ACM commands for PFET control
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#include <zephyr/device.h>
|
|
||||||
#include <zephyr/drivers/uart.h>
|
|
||||||
#include <zephyr/usb/usb_device.h>
|
|
||||||
#include <zephyr/logging/log.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "cdc_handler.h"
|
|
||||||
#include "pfet_control.h"
|
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(cdc_handler, LOG_LEVEL_DBG);
|
|
||||||
|
|
||||||
#define CDC_DEVICE_NAME "CDC_ACM_0"
|
|
||||||
#define RX_BUF_SIZE 64
|
|
||||||
|
|
||||||
static const struct device *cdc_dev;
|
|
||||||
static char rx_buf[RX_BUF_SIZE];
|
|
||||||
static int rx_pos = 0;
|
|
||||||
|
|
||||||
static void process_command(char *cmd)
|
|
||||||
{
|
|
||||||
char response[128];
|
|
||||||
|
|
||||||
if (strncmp(cmd, "PFET1_ON", 8) == 0) {
|
|
||||||
pfet_set_state(1, true);
|
|
||||||
strcpy(response, "PFET1 ON\r\n");
|
|
||||||
} else if (strncmp(cmd, "PFET1_OFF", 9) == 0) {
|
|
||||||
pfet_set_state(1, false);
|
|
||||||
strcpy(response, "PFET1 OFF\r\n");
|
|
||||||
} else if (strncmp(cmd, "PFET2_ON", 8) == 0) {
|
|
||||||
pfet_set_state(2, true);
|
|
||||||
strcpy(response, "PFET2 ON\r\n");
|
|
||||||
} else if (strncmp(cmd, "PFET2_OFF", 9) == 0) {
|
|
||||||
pfet_set_state(2, false);
|
|
||||||
strcpy(response, "PFET2 OFF\r\n");
|
|
||||||
} else if (strncmp(cmd, "STATUS", 6) == 0) {
|
|
||||||
snprintf(response, sizeof(response),
|
|
||||||
"PFET1: %s, PFET2: %s\r\n",
|
|
||||||
pfet_get_state(1) ? "ON" : "OFF",
|
|
||||||
pfet_get_state(2) ? "ON" : "OFF");
|
|
||||||
} else {
|
|
||||||
strcpy(response, "ERROR: Unknown command\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send response */
|
|
||||||
uart_poll_out_string(cdc_dev, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cdc_handler_init(void)
|
|
||||||
{
|
|
||||||
cdc_dev = device_get_binding(CDC_DEVICE_NAME);
|
|
||||||
if (!cdc_dev) {
|
|
||||||
LOG_ERR("CDC ACM device not found");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INF("CDC handler initialized");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cdc_handler_process(void)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
|
|
||||||
/* Check for incoming characters */
|
|
||||||
while (uart_poll_in(cdc_dev, (unsigned char *)&c) == 0) {
|
|
||||||
if (c == '\n' || c == '\r') {
|
|
||||||
/* End of command */
|
|
||||||
if (rx_pos > 0) {
|
|
||||||
rx_buf[rx_pos] = '\0';
|
|
||||||
process_command(rx_buf);
|
|
||||||
rx_pos = 0;
|
|
||||||
}
|
|
||||||
} else if (rx_pos < (RX_BUF_SIZE - 1)) {
|
|
||||||
/* Add character to buffer */
|
|
||||||
rx_buf[rx_pos++] = c;
|
|
||||||
} else {
|
|
||||||
/* Buffer full, reset */
|
|
||||||
rx_pos = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* CDC Handler Header
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CDC_HANDLER_H
|
|
||||||
#define CDC_HANDLER_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize CDC handler
|
|
||||||
* @return 0 on success, negative error code on failure
|
|
||||||
*/
|
|
||||||
int cdc_handler_init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process incoming CDC commands
|
|
||||||
* Should be called regularly from main loop
|
|
||||||
*/
|
|
||||||
void cdc_handler_process(void);
|
|
||||||
|
|
||||||
#endif /* CDC_HANDLER_H */
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* gs_usb CAN Interface
|
|
||||||
* Implements gs_usb protocol for CAN FD communication
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#include <zephyr/device.h>
|
|
||||||
#include <zephyr/drivers/can.h>
|
|
||||||
#include <zephyr/logging/log.h>
|
|
||||||
|
|
||||||
#include "gs_usb_can.h"
|
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(gs_usb_can, LOG_LEVEL_DBG);
|
|
||||||
|
|
||||||
/* CAN device */
|
|
||||||
static const struct device *can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
|
|
||||||
|
|
||||||
int gs_usb_can_init(void)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!device_is_ready(can_dev)) {
|
|
||||||
LOG_ERR("CAN device not ready");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure CAN timing for 500kbps (adjust as needed) */
|
|
||||||
struct can_timing timing = {
|
|
||||||
.sjw = 1,
|
|
||||||
.prop_seg = 6,
|
|
||||||
.phase_seg1 = 7,
|
|
||||||
.phase_seg2 = 2,
|
|
||||||
.prescaler = 6
|
|
||||||
};
|
|
||||||
|
|
||||||
ret = can_set_timing(can_dev, &timing);
|
|
||||||
if (ret < 0) {
|
|
||||||
LOG_ERR("Failed to set CAN timing: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start CAN controller */
|
|
||||||
ret = can_start(can_dev);
|
|
||||||
if (ret < 0) {
|
|
||||||
LOG_ERR("Failed to start CAN: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INF("gs_usb CAN interface initialized");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int gs_usb_can_send_frame(const struct can_frame *frame)
|
|
||||||
{
|
|
||||||
return can_send(can_dev, frame, K_FOREVER, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Implement full gs_usb protocol */
|
|
||||||
/* This would require implementing the USB bulk endpoints and
|
|
||||||
gs_usb command/response protocol as defined in:
|
|
||||||
https://github.com/candle-usb/candleLight_fw
|
|
||||||
*/
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* gs_usb CAN Interface Header
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GS_USB_CAN_H
|
|
||||||
#define GS_USB_CAN_H
|
|
||||||
|
|
||||||
#include <zephyr/drivers/can.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize gs_usb CAN interface
|
|
||||||
* @return 0 on success, negative error code on failure
|
|
||||||
*/
|
|
||||||
int gs_usb_can_init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a CAN frame
|
|
||||||
* @param frame CAN frame to send
|
|
||||||
* @return 0 on success, negative error code on failure
|
|
||||||
*/
|
|
||||||
int gs_usb_can_send_frame(const struct can_frame *frame);
|
|
||||||
|
|
||||||
#endif /* GS_USB_CAN_H */
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* EWS CAN FD CDC Composite Firmware
|
|
||||||
* Main application entry point
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#include <zephyr/device.h>
|
|
||||||
#include <zephyr/drivers/gpio.h>
|
|
||||||
#include <zephyr/usb/usb_device.h>
|
|
||||||
#include <zephyr/logging/log.h>
|
|
||||||
|
|
||||||
#include "cdc_handler.h"
|
|
||||||
#include "pfet_control.h"
|
|
||||||
#include "gs_usb_can.h"
|
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);
|
|
||||||
|
|
||||||
/* LED definitions - adjust to actual EWS board pins */
|
|
||||||
#define LED_STATUS_NODE DT_ALIAS(led0)
|
|
||||||
static const struct gpio_dt_spec led_status = GPIO_DT_SPEC_GET(LED_STATUS_NODE, gpios);
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
LOG_INF("EWS CAN FD CDC Composite Firmware starting...");
|
|
||||||
|
|
||||||
/* Initialize status LED */
|
|
||||||
if (!gpio_is_ready_dt(&led_status)) {
|
|
||||||
LOG_ERR("Status LED device not ready");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = gpio_pin_configure_dt(&led_status, GPIO_OUTPUT_ACTIVE);
|
|
||||||
if (ret < 0) {
|
|
||||||
LOG_ERR("Error configuring status LED: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize PFET control */
|
|
||||||
ret = pfet_control_init();
|
|
||||||
if (ret < 0) {
|
|
||||||
LOG_ERR("Failed to initialize PFET control: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize USB composite device */
|
|
||||||
ret = usb_enable(NULL);
|
|
||||||
if (ret != 0) {
|
|
||||||
LOG_ERR("Failed to enable USB: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize CDC handler */
|
|
||||||
ret = cdc_handler_init();
|
|
||||||
if (ret < 0) {
|
|
||||||
LOG_ERR("Failed to initialize CDC handler: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize gs_usb CAN interface */
|
|
||||||
ret = gs_usb_can_init();
|
|
||||||
if (ret < 0) {
|
|
||||||
LOG_ERR("Failed to initialize gs_usb CAN: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INF("EWS firmware initialized successfully");
|
|
||||||
|
|
||||||
/* Main loop */
|
|
||||||
while (1) {
|
|
||||||
/* Toggle status LED to show activity */
|
|
||||||
gpio_pin_toggle_dt(&led_status);
|
|
||||||
|
|
||||||
/* Handle CDC commands */
|
|
||||||
cdc_handler_process();
|
|
||||||
|
|
||||||
k_msleep(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* PFET Control Module
|
|
||||||
* Controls the two output PFETs on the EWS board
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#include <zephyr/device.h>
|
|
||||||
#include <zephyr/drivers/gpio.h>
|
|
||||||
#include <zephyr/logging/log.h>
|
|
||||||
|
|
||||||
#include "pfet_control.h"
|
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(pfet_control, LOG_LEVEL_DBG);
|
|
||||||
|
|
||||||
/* PFET control pin definitions */
|
|
||||||
static const struct gpio_dt_spec pfet1 = GPIO_DT_SPEC_GET(DT_ALIAS(pfet0), gpios);
|
|
||||||
static const struct gpio_dt_spec pfet2 = GPIO_DT_SPEC_GET(DT_ALIAS(pfet1), gpios);
|
|
||||||
static bool pfet1_state = false;
|
|
||||||
static bool pfet2_state = false;
|
|
||||||
|
|
||||||
int pfet_control_init(void)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!gpio_is_ready_dt(&pfet1) || !gpio_is_ready_dt(&pfet2)) {
|
|
||||||
LOG_ERR("PFET GPIO devices not ready");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure PFET pins as output, initially off */
|
|
||||||
ret = gpio_pin_configure_dt(&pfet1, GPIO_OUTPUT_INACTIVE);
|
|
||||||
if (ret < 0) {
|
|
||||||
LOG_ERR("Failed to configure PFET1 pin: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = gpio_pin_configure_dt(&pfet2, GPIO_OUTPUT_INACTIVE);
|
|
||||||
if (ret < 0) {
|
|
||||||
LOG_ERR("Failed to configure PFET2 pin: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INF("PFET control initialized");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pfet_set_state(int pfet_num, bool state)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (pfet_num == 1) {
|
|
||||||
ret = gpio_pin_set_dt(&pfet1, state ? 1 : 0);
|
|
||||||
if (ret == 0) {
|
|
||||||
pfet1_state = state;
|
|
||||||
LOG_INF("PFET1 %s", state ? "ON" : "OFF");
|
|
||||||
}
|
|
||||||
} else if (pfet_num == 2) {
|
|
||||||
ret = gpio_pin_set_dt(&pfet2, state ? 1 : 0);
|
|
||||||
if (ret == 0) {
|
|
||||||
pfet2_state = state;
|
|
||||||
LOG_INF("PFET2 %s", state ? "ON" : "OFF");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pfet_get_state(int pfet_num)
|
|
||||||
{
|
|
||||||
if (pfet_num == 1) {
|
|
||||||
return pfet1_state;
|
|
||||||
} else if (pfet_num == 2) {
|
|
||||||
return pfet2_state;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* PFET Control Header
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PFET_CONTROL_H
|
|
||||||
#define PFET_CONTROL_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize PFET control
|
|
||||||
* @return 0 on success, negative error code on failure
|
|
||||||
*/
|
|
||||||
int pfet_control_init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set PFET state
|
|
||||||
* @param pfet_num PFET number (1 or 2)
|
|
||||||
* @param state true for ON, false for OFF
|
|
||||||
* @return 0 on success, negative error code on failure
|
|
||||||
*/
|
|
||||||
int pfet_set_state(int pfet_num, bool state);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get current PFET state
|
|
||||||
* @param pfet_num PFET number (1 or 2)
|
|
||||||
* @return current state (true=ON, false=OFF)
|
|
||||||
*/
|
|
||||||
bool pfet_get_state(int pfet_num);
|
|
||||||
|
|
||||||
#endif /* PFET_CONTROL_H */
|
|
||||||
Reference in New Issue
Block a user