ether2ser 0.1.0
Ethernet <-> synchronous V.24 bridge firmware for RP2040 + W5500
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1/*
2 * ether2ser — Ethernet ↔ synchronous V.24 (RS-232/V.28) bridge
3 *
4 * File: src/main.c
5 * Purpose: Firmware entry point and high-level scheduler.
6 *
7 * This project targets the W55RP20-EVB-PICO (RP2040 + W5500). The RP2040 CPU
8 * runs the control plane and protocol processing (L3 forwarding, framing/CRC,
9 * buffering, configuration). The RP2040 PIO implements the time-critical
10 * synchronous serial “PHY” (TXD/RXD with TXC/RXC).
11 *
12 * Notes:
13 * - USB CDC is used for a simple CLI and status output.
14 * - PIO programs live in /pio (top-level); PIO C glue lives in src/pio/.
15 *
16 * SPDX-License-Identifier: Apache-2.0
17 *
18 * Copyright (c) 2026 Florian <f.leuze@outlook.de>
19 */
20
21// Related headers
22#include "system/app_context.h"
23
24// Standard library headers
25#include <stdbool.h>
26#include <stdio.h>
27
28// Library Headers
29#include "hardware/gpio.h"
30#include "hardware/pio.h"
31#include "hardware/sync.h"
32#include "hardware/watchdog.h"
33#include "pico/multicore.h"
34#include "pico/stdio.h"
35#include "pico/time.h"
36
37// Project Headers
38#include "drivers/gpio_driver.h"
40#include "drivers/tx_queue.h"
42#include "platform/pinmap.h"
44#include "system/common.h"
45#include "system/error.h"
46#include "system/event_loop.h"
47#include "system/event_queue.h"
49#include "version.h"
50
51// Generated headers
52
53// USB CDC enumeration delay in milliseconds
54#define USB_ENUMERATION_DELAY_MS 1500
55#define GLOBAL_WATCHDOG_TIMEOUT_MS 5000
56#define WATCHDOG_DISABLED_FOR_DEBUGGING 1
57
58static void core1_entry(void)
59{
60 __sev();
61 __wfe();
62 __wfe();
63 while (true)
64 {
66 __wfe(); // sleep until interrupt/event, minimal contention
67 }
68}
69
70int main(void)
71{
72 e2s_error_t err;
73
74 // Application Context
75 static app_ctx_t app_context = {0};
76
77 // Config variables
78 config_t persistent_config;
79
80 // Initialize USB CDC
81 stdio_init_all();
82
83 // Give the USB CDC a moment to enumerate (harmless even if not using USB)
85
86 // Initialize W5500
88 // Initialize GPIOs
89 init_pins();
90
91 if (config_is_valid())
92 {
93 app_context.config_valid = config_read(&persistent_config);
94 }
95 else
96 {
97 app_context.config_valid = false;
98 }
99
100 init_app(&app_context, &persistent_config);
101
102 if ((err = w5500_open_udp_socket(&app_context.local_config)) != E2S_OK)
103 {
104 fatal_panic(err);
105 }
107
108 // Initialize TX Queue
109 tx_queue_init(&app_context.tx_queue, app_context.tx_queue_buffer);
110
111 // Initialize PIO
112 // Currently anything faster than 38400 is not supported
113 tx_clock_init(pio0, 0, &app_context.v24_config);
114 rx_clock_init(pio0, 1, &(app_context.v24_config.polarities.rx_polarities));
116 if (app_context.v24_config.external_clock)
117 {
119 }
120
121 // Enable watchdog, 5s timeout, disabled in debugging
123
124 LOG_PLAIN("\r\nv24-eth-bridge: hello from RP2040\r\n");
125 LOG_PLAIN("\r\nType 'help' in USB serial.\r\n");
126 LOG_PLAIN("Version: %s\r\n", VERSION_STRING);
127
129 {
130 LOG_PLAIN("\r\nDebug logging enabled.\r\n> ");
131 dump_config();
132 app_context.need_prompt = true;
133 }
134 multicore_launch_core1(core1_entry);
135
136 // Initialize event queue finally
138
139 // Indicate DTE is present just before we enter the event loop
140 gpio_put(V24_DTR, 1);
141
142 event_loop(&app_context);
143}
void init_app(app_ctx_t *app, const config_t *persistent_config)
Initialize application context from persistent/default configuration.
Definition app_init.c:39
void baudrate_estimator_init(V24_PIN_T pin)
Initialize baudrate estimator on a specific RX clock pin.
log_level_t get_loglevel(void)
Get current global log level.
Definition log.c:61
void log_core1_drain(void)
Definition log.c:115
#define LOG_PLAIN(...)
Definition common.h:162
@ LOG_LEVEL_DEBUG
Definition common.h:91
void fatal_panic(e2s_error_t reason)
Print error message and panic.
Definition error.c:30
e2s_error_t
Common error codes returned by ether2ser modules.
Definition error.h:27
@ E2S_OK
Definition error.h:28
void event_loop(app_ctx_t *app)
Run the main application polling loop.
Definition event_loop.c:383
void event_queue_init(void)
Initialize the event queue storage.
Definition event_queue.c:40
void init_pins(void)
Initialize all board GPIOs used by the application.
Definition gpio_driver.c:53
static void core1_entry(void)
Definition main.c:58
#define WATCHDOG_DISABLED_FOR_DEBUGGING
Definition main.c:56
int main(void)
Definition main.c:70
#define GLOBAL_WATCHDOG_TIMEOUT_MS
Definition main.c:55
#define USB_ENUMERATION_DELAY_MS
Definition main.c:54
void dump_config(void)
Print current configuration to console/log output.
bool config_read(config_t *cfg)
Read configuration from flash.
bool config_is_valid(void)
Check if flash configuration magic marker is valid.
#define V24_RXC
Definition pinmap.h:28
#define V24_DTR
Definition pinmap.h:37
#define V24_TXC_DCE
Definition pinmap.h:27
void tx_clock_init(PIO pio, uint pio_sm, V24_CONFIG_T *config)
Initialize TX clock/data PIO state machine.
void rx_clock_init(PIO pio, uint pio_sm, V24_RX_POLARITIES_T *polarities)
Initialize RX clock/data PIO state machine.
V24_POLARITIES_T polarities
Definition v24_config.h:91
bool external_clock
Definition v24_config.h:97
V24_RX_POLARITIES_T rx_polarities
Definition v24_config.h:80
Global application context shared across modules.
Definition app_context.h:98
bool need_prompt
TX_QUEUE_T tx_queue
UDP_CONFIG_T local_config
V24_CONFIG_T v24_config
uint8_t tx_queue_buffer[TX_FRAME_QUEUE_SIZE *sizeof(TX_QUEUE_ENTRY_T)]
bool config_valid
Persistent configuration blob stored in flash.
e2s_error_t tx_queue_init(TX_QUEUE_T *queue, uint8_t *buffer_data)
Initialize TX queue and ring buffer storage.
Definition tx_queue.c:38
void w5500_driver_init(void)
Initialize W5500 driver and low-level interface.
e2s_error_t w5500_open_udp_socket(UDP_CONFIG_T *config)
Open configured UDP socket.
void w5500_debug_status(void)
Print W5500 socket/PHY debug status.