1+ // Copyright 2025 Google LLC
2+ //
3+ // Licensed under the Apache License, Version 2.0 (the "License");
4+ // you may not use this file except in compliance with the License.
5+ // You may obtain a copy of the License at
6+ //
7+ // http://www.apache.org/licenses/LICENSE-2.0
8+ //
9+ // Unless required by applicable law or agreed to in writing, software
10+ // distributed under the License is distributed on an "AS IS" BASIS,
11+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ // See the License for the specific language governing permissions and
13+ // limitations under the License.
14+
15+ // Code for performing a device-firmware update using host commands.
16+
17+ #ifndef _LIBHOTH_PROTOCOL_DFU_HOSTCMD_H_
18+ #define _LIBHOTH_PROTOCOL_DFU_HOSTCMD_H_
19+
20+ #include <assert.h>
21+ #include <stddef.h>
22+ #include <stdint.h>
23+
24+ #include "protocol/host_cmd.h"
25+ #include "transports/libhoth_device.h"
26+
27+ #ifdef __cplusplus
28+ extern "C" {
29+ #endif
30+
31+ #define HOTH_CMD_DFU_WRITE 0x3e4f
32+ #define HOTH_CMD_DFU_COMPLETE 0x3e50
33+
34+ enum {
35+ HOTH_DFU_TARGET_EARLGREY_FW_UPDATE = 0x77664745 ,
36+ };
37+
38+ struct hoth_dfu_nonce {
39+ uint32_t low ;
40+ uint32_t high ;
41+ };
42+
43+ struct hoth_dfu_session_id {
44+ /// The nonce should be randomly generated at the start of the session; it
45+ /// is used to detect simultaneous use of the DFU functionality.
46+ struct hoth_dfu_nonce nonce ;
47+
48+ // One of HOTH_DFU_TARGET_* constants
49+ uint32_t target ;
50+ };
51+ static_assert (offsetof(struct hoth_dfu_session_id , nonce ) == 0 );
52+ static_assert (offsetof(struct hoth_dfu_session_id , target ) == 8 );
53+ static_assert (sizeof (struct hoth_dfu_session_id ) == 12 );
54+
55+ enum {
56+ // Set if this is the first chunk of a new DFU session.
57+ HOTH_DFU_WRITE_FLAGS_NEW_SESSION = (1 << 0 )
58+ };
59+
60+ struct hoth_dfu_write_request_header {
61+ struct hoth_dfu_session_id session_id ;
62+
63+ // combination of HOTH_DFU_WRITE_FLAGS_*
64+ uint32_t flags ;
65+ };
66+ static_assert (offsetof(struct hoth_dfu_write_request_header , session_id ) == 0 );
67+ static_assert (offsetof(struct hoth_dfu_write_request_header , flags ) == 12 );
68+ static_assert (sizeof (struct hoth_dfu_write_request_header ) == 16 );
69+
70+ enum {
71+ // Set ifwe should restart the chip into the new firmware.
72+ HOTH_DFU_COMPLETE_FLAGS_COLD_RESTART = (1 << 0 ),
73+
74+ // Set if we should do a warm restart the chip into the new firmware.
75+ HOTH_DFU_COMPLETE_FLAGS_WARM_RESTART = (1 << 1 ),
76+ };
77+
78+ struct hoth_dfu_complete_request {
79+ struct hoth_dfu_session_id session_id ;
80+
81+ // combination of HOTH_DFU_COMPLETE_FLAGS_*
82+ uint32_t flags ;
83+ };
84+ static_assert (offsetof(struct hoth_dfu_complete_request , session_id ) == 0 );
85+ static_assert (offsetof(struct hoth_dfu_complete_request , flags ) == 12 );
86+ static_assert (sizeof (struct hoth_dfu_complete_request ) == 16 );
87+
88+ /**
89+ * @brief Update the firmware on the device using DFU host commands.
90+ *
91+ * This function sends the provided firmware image to the device in chunks
92+ * and then sends a DFU complete command to finalize the update.
93+ *
94+ * @param dev The libhoth device handle.
95+ * @param image A pointer to the firmware image data.
96+ * @param image_size The size of the firmware image in bytes.
97+ * @param complete_flags Flags to be passed to the DFU complete command,
98+ * e.g., HOTH_DFU_COMPLETE_FLAGS_COLD_RESTART.
99+ * @return 0 on success, -1 on failure.
100+ */
101+ int libhoth_dfu_update (struct libhoth_device * dev , const uint8_t * image ,
102+ size_t image_size , uint32_t complete_flags );
103+
104+ #ifdef __cplusplus
105+ }
106+ #endif
107+
108+ #endif // _LIBHOTH_PROTOCOL_DFU_HOSTCMD_H_
0 commit comments