编程技术分享

分享编程知识,探讨技术创新

0%

简介:基于ASM1153E,VL160的TYPEC接口的MSATA硬盘盒子

我将基于你提供的需求,详细说明一个基于ASM1153E和VL160的Type-C接口mSATA硬盘盒的完整嵌入式系统开发流程,并给出适合的代码架构以及相应的C代码实现。
关注微信公众号,提前获取相关推文

1. 需求分析

  • 核心功能:
    • 将mSATA SSD转换为USB Type-C接口的外部存储设备。
    • 支持高速数据传输,符合USB 3.1 Gen 1 (或更高) 标准。
    • 良好的兼容性,支持各种操作系统 (Windows, macOS, Linux)。
    • 即插即用,无需额外驱动 (在大部分情况下)。
  • 硬件组件:
    • ASM1153E: USB 3.1 to SATA 桥接芯片,负责将USB数据转换为SATA数据。
    • VL160: USB Type-C 接口控制芯片,负责USB PD、Type-C 连接和高速数据传输。
    • mSATA 连接器: 用于连接 mSATA SSD。
    • USB Type-C 接口: 用于连接主机。
    • 电源管理: 供电电路,确保整个系统稳定运行。
    • LED指示灯: 显示设备状态(如电源/读写状态)。
  • 软件需求:
    • 固件: 负责初始化硬件、处理USB和SATA数据传输、管理电源和指示灯。
    • 可靠性: 确保数据传输的可靠性和系统稳定性,防止数据损坏或设备崩溃。
    • 可扩展性: 方便后期功能添加和固件更新。
    • 易维护性: 代码结构清晰,易于理解和修改。
    • 功耗控制: 合理控制功耗,延长电池寿命 (如果采用电池供电)。
  • 测试需求:
    • 功能测试: 验证基本的数据传输功能。
    • 性能测试: 测试数据传输速率,确保满足USB 3.1 Gen 1 或更高标准。
    • 兼容性测试: 在不同操作系统和设备上进行测试。
    • 压力测试: 长时间高负载测试,验证系统的稳定性。

2. 系统架构设计

为了满足上述需求,我们将采用分层架构,主要分为以下几层:

  • 硬件抽象层 (HAL):
    • 封装底层硬件访问,提供统一的接口给上层软件使用。
    • 包括:
      • ASM1153E 驱动: 初始化和控制ASM1153E芯片,包括SATA接口的初始化、数据传输控制等。
      • VL160 驱动: 初始化和控制VL160芯片,包括USB Type-C端口的配置,USB PD控制等。
      • GPIO 驱动: 控制LED指示灯和其他GPIO。
      • 定时器驱动: 用于延时和定时操作。
  • 设备驱动层:
    • 提供具体设备的逻辑控制,基于HAL层提供的接口实现。
    • 包括:
      • USB 驱动: 基于VL160提供的USB接口实现USB设备枚举、数据传输处理。
      • SATA 驱动: 基于ASM1153E提供的SATA接口实现SATA设备初始化,数据传输处理。
  • 逻辑控制层:
    • 实现业务逻辑,控制数据传输流程,管理设备状态。
    • 包括:
      • 数据传输模块: 负责USB和SATA之间的数据传输。
      • 状态管理模块: 管理设备状态,例如电源状态、读写状态。
      • 错误处理模块: 处理各种错误,例如USB连接错误,SATA设备错误等。
  • 应用层:
    • 提供应用程序入口,初始化整个系统,并启动数据传输服务。
    • 包括:
      • 系统初始化模块: 初始化所有模块。
      • 主循环: 监控设备状态,处理数据传输。

3. 代码实现 (C语言)

以下代码只提供关键部分的示例,实际实现会更复杂,需要根据具体的硬件和需求进行调整:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
//  包含头文件
#include <stdint.h>
#include <stdbool.h>
// 硬件配置
#define LED_PIN 13 // 假设 LED 连接到 GPIO13
#define USB_DATA_OUT_EP 0x01 // USB 输出端点
#define USB_DATA_IN_EP 0x81 // USB 输入端点

// 定义状态枚举
typedef enum {
DEVICE_STATE_IDLE,
DEVICE_STATE_CONNECTED,
DEVICE_STATE_TRANSFERRING,
DEVICE_STATE_ERROR
} device_state_t;

// 全局变量
volatile device_state_t device_state = DEVICE_STATE_IDLE;


// -------------------- 硬件抽象层 (HAL) --------------------
// GPIO 控制函数 (示例)
void gpio_set(uint8_t pin, bool value);
void gpio_init(uint8_t pin);

// 定时器驱动 (示例)
void delay_ms(uint32_t ms);
// ASM1153E 驱动 (示例)
void asm1153e_init();
bool asm1153e_read(uint8_t* buffer, uint32_t length);
bool asm1153e_write(const uint8_t* buffer, uint32_t length);
// VL160 驱动 (示例)
void vl160_init();
bool vl160_usb_send(uint8_t endpoint,const uint8_t* buffer,uint32_t length);
bool vl160_usb_receive(uint8_t endpoint, uint8_t* buffer, uint32_t* length);


// -------------------- 设备驱动层 --------------------
// USB 驱动 (基于VL160)
bool usb_init();
bool usb_send(const uint8_t* buffer,uint32_t length);
bool usb_receive(uint8_t* buffer, uint32_t* length);

// SATA 驱动 (基于ASM1153E)
bool sata_init();
bool sata_read(uint8_t* buffer, uint32_t length);
bool sata_write(const uint8_t* buffer, uint32_t length);

// -------------------- 逻辑控制层 --------------------
// 数据传输函数
bool data_transfer();
// 错误处理函数
void error_handler(int errcode);

// -------------------- 应用层 --------------------
// 系统初始化函数
void system_init();
// 主函数
int main();

// -------------------- 硬件抽象层 (HAL) 实现 --------------------

// GPIO 控制函数 (示例)
void gpio_set(uint8_t pin, bool value) {
// 这里是实际操作GPIO的代码,例如直接操作寄存器
if (value) {
// 设置引脚为高电平
// 示例: GPIO_PORTA_DATA |= (1 << pin);
} else {
// 设置引脚为低电平
// 示例: GPIO_PORTA_DATA &= ~(1 << pin);
}
}

void gpio_init(uint8_t pin) {
// 这里是初始化 GPIO 的代码, 例如设置引脚模式为输出
// 示例: GPIO_PORTA_MODE |= (1 << pin); // 设置为输出模式
}

// 定时器驱动 (示例)
void delay_ms(uint32_t ms){
for(uint32_t i = 0;i < ms; ++i){
// 简单延时实现
volatile uint32_t j = 10000;
while(j--);
}
}


// ASM1153E 驱动
void asm1153e_init() {
// 初始化 ASM1153E
// 配置 I2C 或 SPI 总线通信,设置SATA接口等
delay_ms(50); // 适当的初始化延时
}

bool asm1153e_read(uint8_t* buffer, uint32_t length) {
// 通过I2C或SPI总线读取ASM1153E的数据
// 这里需要具体实现,根据芯片手册进行操作
// 例如:
// I2C_start();
// I2C_write_addr(ASM1153E_ADDR | WRITE_BIT);
// I2C_write_data(SATA_READ_CMD);
// I2C_restart();
// I2C_write_addr(ASM1153E_ADDR | READ_BIT);
// I2C_read_data(buffer, length);
// I2C_stop();
delay_ms(1); //模拟读延时
// 根据读取情况返回状态
return true;
}

bool asm1153e_write(const uint8_t* buffer, uint32_t length) {
// 通过I2C或SPI总线写入ASM1153E的数据
// 这里需要具体实现,根据芯片手册进行操作
// 例如:
// I2C_start();
// I2C_write_addr(ASM1153E_ADDR | WRITE_BIT);
// I2C_write_data(SATA_WRITE_CMD);
// I2C_write_data(buffer, length);
// I2C_stop();
delay_ms(1); //模拟写延时
// 根据写入情况返回状态
return true;
}

// VL160 驱动
void vl160_init() {
// 初始化 VL160
// 配置 USB Type-C 端口,电源管理,USB速度模式等
delay_ms(50); // 适当的初始化延时
}

bool vl160_usb_send(uint8_t endpoint,const uint8_t* buffer,uint32_t length)
{
// 通过VL160发送USB数据
// 这里需要具体实现,根据芯片手册进行操作
// 例如:
// USB_send(endpoint, buffer, length);
delay_ms(1);
return true;
}
bool vl160_usb_receive(uint8_t endpoint, uint8_t* buffer, uint32_t* length) {
// 通过VL160接收USB数据
// 这里需要具体实现,根据芯片手册进行操作
// 例如:
// *length = USB_receive(endpoint, buffer);
*length = 64; //模拟收到的数据长度
delay_ms(1);
return true;
}


// -------------------- 设备驱动层实现 --------------------
// USB 驱动 (基于VL160)
bool usb_init() {
// 初始化 USB 设备,设置端点,注册回调函数等
vl160_init(); // 初始化 VL160 芯片
return true;
}

bool usb_send(const uint8_t* buffer, uint32_t length) {
return vl160_usb_send(USB_DATA_OUT_EP,buffer,length);
}

bool usb_receive(uint8_t* buffer, uint32_t* length) {
return vl160_usb_receive(USB_DATA_IN_EP,buffer,length);
}

// SATA 驱动 (基于ASM1153E)
bool sata_init() {
// 初始化 SATA 设备,例如初始化 ASM1153E 芯片,开启SATA通道等
asm1153e_init();
return true;
}

bool sata_read(uint8_t* buffer, uint32_t length) {
return asm1153e_read(buffer,length);
}

bool sata_write(const uint8_t* buffer, uint32_t length) {
return asm1153e_write(buffer, length);
}

// -------------------- 逻辑控制层实现 --------------------
// 数据传输函数
bool data_transfer() {
uint8_t usb_buffer[64];
uint8_t sata_buffer[64];
uint32_t usb_length, sata_length;
device_state = DEVICE_STATE_TRANSFERRING;
gpio_set(LED_PIN, true); // LED指示灯闪烁,表示数据传输中
while (device_state == DEVICE_STATE_TRANSFERRING)
{
// 从USB接收数据
if (usb_receive(usb_buffer,&usb_length))
{
if (usb_length > 0) {
// 将数据转发到SATA
if(sata_write(usb_buffer,usb_length)){
// 从SATA读取数据
if (sata_read(sata_buffer,usb_length)){
// 将数据发送回USB
usb_send(sata_buffer,usb_length);
}
else{
error_handler(2); // SATA读取错误
return false;
}
}else{
error_handler(1); //SATA 写入错误
return false;
}
}
} else {
error_handler(0); // USB 接收错误
return false;
}
delay_ms(1);
}
gpio_set(LED_PIN, false); // LED指示灯熄灭,表示数据传输完成
return true;
}

// 错误处理函数
void error_handler(int errcode) {
// 处理错误,例如记录日志,设置错误状态,发送错误报告等
device_state = DEVICE_STATE_ERROR;
// 这里可以添加错误代码处理逻辑
switch (errcode) {
case 0:
// 处理 USB 接收错误
gpio_set(LED_PIN,true);
delay_ms(100);
gpio_set(LED_PIN,false);
delay_ms(100);
gpio_set(LED_PIN,true);
delay_ms(100);
gpio_set(LED_PIN,false);

break;
case 1:
// 处理SATA写入错误
gpio_set(LED_PIN,true);
delay_ms(500);
gpio_set(LED_PIN,false);

break;
case 2:
// 处理SATA读取错误
gpio_set(LED_PIN,true);
delay_ms(100);
gpio_set(LED_PIN,false);
delay_ms(100);
gpio_set(LED_PIN,true);
delay_ms(100);
gpio_set(LED_PIN,false);
break;
default:
break;
}
delay_ms(2000); // 等待一段时间
device_state = DEVICE_STATE_IDLE;
}


// -------------------- 应用层实现 --------------------
// 系统初始化函数
void system_init() {
// 初始化 GPIO 引脚
gpio_init(LED_PIN);
gpio_set(LED_PIN,false); // 初始化LED灯状态为熄灭

// 初始化 USB 设备
if (!usb_init()) {
error_handler(-1); // 初始化失败
}
// 初始化 SATA 设备
if (!sata_init()) {
error_handler(-2); // 初始化失败
}

device_state = DEVICE_STATE_CONNECTED;
}


// 主函数
int main() {
// 初始化系统
system_init();
// 进入主循环
while (1) {
if (device_state == DEVICE_STATE_CONNECTED){
// 设备连接,执行数据传输任务
data_transfer();
} else if(device_state == DEVICE_STATE_IDLE){
// 设备空闲状态,执行其他操作
delay_ms(100);
}
else if (device_state == DEVICE_STATE_ERROR){
// 设备出现错误,进入错误处理
delay_ms(100);
}
}
return 0;
}

4. 代码说明

  • 分层结构: 代码严格按照之前设计的架构分层,每个层负责不同的功能,提高了代码的可读性和可维护性。
  • HAL层: gpio_set, gpio_initasm1153e_init,asm1153e_read, asm1153e_write, vl160_init, vl160_usb_send, vl160_usb_receive 函数都是硬件操作,需要根据实际硬件进行修改。
  • 设备驱动层: usb_init, usb_send, usb_receive, sata_init, sata_read, sata_write 函数封装了对具体设备的访问。
  • 逻辑控制层: data_transfer 函数实现了数据传输的逻辑,error_handler 函数用于处理错误。
  • 应用层: system_init 函数初始化系统,main 函数是主程序入口,实现循环处理。
  • 示例代码: 为了演示,代码中使用了模拟的延时,实际开发需要使用准确的定时器或硬件延时。
  • 错误处理: 增加了简单的错误处理机制,可以根据具体需求扩展。
  • 状态管理: 使用了枚举类型 device_state_t 来管理设备状态。

5. 技术和方法

  • 分层架构: 使代码模块化,易于维护和扩展。
  • 抽象层: HAL 层隔离了硬件差异,方便代码移植。
  • 有限状态机 (FSM): 使用 device_state_t 实现简单的状态管理。
  • 错误处理: 使用了 error_handler 函数统一处理错误。
  • 模块化编程: 将系统分解为不同的模块,各模块之间相互独立。
  • 注释: 代码中添加了注释,便于理解。
  • 可扩展性: 模块化的结构便于后期添加新的功能。

6. 测试和验证

  • 单元测试: 测试每个模块的功能,例如测试 gpio_setusb_sendsata_read 等。
  • 集成测试: 测试不同模块之间的协同工作,例如测试整个数据传输过程。
  • 系统测试: 在实际环境中测试设备的性能和稳定性,例如在不同操作系统和设备上进行测试。
  • 压力测试: 进行长时间高负载的数据传输,检测系统的稳定性。

7. 维护和升级

  • 代码版本控制: 使用Git等版本控制工具管理代码。
  • 固件升级机制: 设计固件升级功能,方便后期bug修复和功能添加。
  • 日志系统: 记录设备运行状态和错误信息,方便故障排除。

8. 总结

这是一个基于ASM1153E和VL160的Type-C接口mSATA硬盘盒的完整嵌入式系统开发流程,涵盖了需求分析、系统架构、代码实现、测试验证和维护升级。虽然提供的代码只是一个基础框架,但它展示了如何使用分层架构来构建一个可靠、高效和可扩展的系统。实际开发需要根据具体的硬件和需求进行详细的实现和测试。

这个框架可以为你的嵌入式开发项目提供一个良好的起点,希望它能帮助你构建出更加可靠和优秀的嵌入式系统。 需要注意的是,这只是一个简化的示例,真实的嵌入式系统开发会更加复杂,涉及更多的细节,比如中断处理,DMA传输,电源管理等等。 为了完成一个完整的产品开发,你需要仔细研究相关芯片的数据手册,并进行充分的测试和验证。 在实际的开发过程中,你还需要使用各种调试工具,比如逻辑分析仪,JTAG调试器等来辅助开发。

为了完成一个完整的项目,你还需要:

  1. 仔细阅读芯片手册: 认真阅读ASM1153E和VL160的数据手册,了解它们的寄存器配置,以及各种功能和限制。
  2. 完善硬件驱动: 根据芯片手册,实现更加完整的HAL层驱动,例如 I2C/SPI 读写,USB 控制传输等等。
  3. 添加异常处理: 添加更多的异常处理机制,比如 USB 连接断开处理,SATA 设备错误处理等。
  4. 优化数据传输: 使用 DMA 传输,提高数据传输的效率和性能。
  5. 添加电源管理: 如果系统需要电池供电,你需要添加电源管理功能,降低功耗。
  6. 完善测试: 进行更加全面的测试,确保产品的稳定性和可靠性。

希望这个详细的解答对你有所帮助!

欢迎关注我的其它发布渠道