Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
混口饭吃,
rt-thread
提交
8421ecfa
R
rt-thread
项目概览
混口饭吃,
/
rt-thread
与 Fork 源项目一致
Fork自
Mr_Pangza / rt-thread
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
8421ecfa
编写于
2月 21, 2013
作者:
wuyangyong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update SD card driver: use RT-Thread SPI driver.
上级
5c17c2e6
变更
13
显示空白变更内容
内联
并排
Showing
13 changed file
with
2323 addition
and
1293 deletion
+2323
-1293
bsp/stm32f107/drivers/SConscript
bsp/stm32f107/drivers/SConscript
+9
-0
bsp/stm32f107/drivers/board.c
bsp/stm32f107/drivers/board.c
+6
-7
bsp/stm32f107/drivers/board.h
bsp/stm32f107/drivers/board.h
+3
-0
bsp/stm32f107/drivers/msd.c
bsp/stm32f107/drivers/msd.c
+1603
-863
bsp/stm32f107/drivers/msd.h
bsp/stm32f107/drivers/msd.h
+122
-163
bsp/stm32f107/drivers/platform.c
bsp/stm32f107/drivers/platform.c
+85
-5
bsp/stm32f107/drivers/rt_stm32f10x_spi.c
bsp/stm32f107/drivers/rt_stm32f10x_spi.c
+372
-0
bsp/stm32f107/drivers/rt_stm32f10x_spi.h
bsp/stm32f107/drivers/rt_stm32f10x_spi.h
+38
-0
bsp/stm32f107/drivers/stm32f10x_it.c
bsp/stm32f107/drivers/stm32f10x_it.c
+4
-10
bsp/stm32f107/drivers/usart.c
bsp/stm32f107/drivers/usart.c
+1
-0
bsp/stm32f107/project.uvproj
bsp/stm32f107/project.uvproj
+78
-243
bsp/stm32f107/readme.txt
bsp/stm32f107/readme.txt
+1
-1
bsp/stm32f107/rtconfig.h
bsp/stm32f107/rtconfig.h
+1
-1
未找到文件。
bsp/stm32f107/drivers/SConscript
浏览文件 @
8421ecfa
...
...
@@ -4,6 +4,15 @@ from building import *
cwd
=
os
.
path
.
join
(
str
(
Dir
(
'#'
)),
'drivers'
)
src
=
Glob
(
'*.c'
)
# remove no need file.
if
GetDepend
(
'RT_USING_LWIP'
)
==
False
:
SrcRemove
(
src
,
'stm32_eth.c'
)
if
GetDepend
(
'RT_USING_SPI'
)
==
False
:
SrcRemove
(
src
,
'rt_stm32f10x_spi.c'
)
SrcRemove
(
src
,
'msd.c'
)
CPPPATH
=
[
cwd
]
group
=
DefineGroup
(
'Drivers'
,
src
,
depend
=
[
''
],
CPPPATH
=
CPPPATH
)
...
...
bsp/stm32f107/drivers/board.c
浏览文件 @
8421ecfa
...
...
@@ -14,7 +14,6 @@
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
/**
...
...
@@ -45,7 +44,7 @@ void NVIC_Configuration(void)
* This is the timer interrupt service routine.
*
*/
void
rt_hw_timer_h
andler
(
void
)
void
SysTick_H
andler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
...
...
bsp/stm32f107/drivers/board.h
浏览文件 @
8421ecfa
...
...
@@ -40,6 +40,9 @@
#define STM32_SRAM_SIZE 64
#define STM32_SRAM_END (0x20000000 + STM32_SRAM_SIZE * 1024)
#define RT_USING_UART1
#define RT_USING_SPI1
void
rt_hw_board_init
(
void
);
void
rt_hw_usart_init
(
void
);
...
...
bsp/stm32f107/drivers/msd.c
浏览文件 @
8421ecfa
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : msd.c
* Author : MCD Application Team
* Version : V2.1
* Date : 05/30/2008
* Description : MSD card driver source file.
* Pin assignment:
* ----------------------------------------------
* | STM32F10x | MSD Pin |
* ----------------------------------------------
* | P0.4 | ChipSelect 1 |
* | P0.1 / MOSI | DataIn 2 |
* | | GND 3 (0 V) |
* | | VDD 4 (3.3 V) |
* | P0.2 / SCLK | Clock 5 |
* | | GND 6 (0 V) |
* | P0.0 / MISO | DataOut 7 |
* -----------------------------------------------
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
* FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED
* IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
/*
* File : msd.c
* SPI mode SD Card Driver
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-04-17 Bernard first version.
* 2010-07-15 aozima Modify read/write according new block driver interface.
* 2012-02-01 aozima use new RT-Thread SPI drivers.
* 2012-04-11 aozima get max. data transfer rate from CSD[TRAN_SPEED].
* 2012-05-21 aozima update MMC card support.
*/
#include <string.h>
#include "msd.h"
#include <stm32f10x_spi.h>
#include <rtthread.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Select MSD Card: ChipSelect pin low */
#define MSD_CS_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_4)
/* Deselect MSD Card: ChipSelect pin high */
#define MSD_CS_HIGH() GPIO_SetBits(GPIOA, GPIO_Pin_4)
#define MSD_SPI SPI1
#define MSD_RCC_SPI RCC_APB2Periph_SPI1
/* Private function prototypes -----------------------------------------------*/
static
void
SPI_Config
(
void
);
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : MSD_Init
* Description : Initializes the MSD/SD communication.
* Input : None
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8
MSD_Init
(
void
)
//#define MSD_TRACE
#ifdef MSD_TRACE
#define MSD_DEBUG(...) rt_kprintf("[MSD] %d ", rt_tick_get()); rt_kprintf(__VA_ARGS__);
#else
#define MSD_DEBUG(...)
#endif
/* #ifdef MSD_TRACE */
#define DUMMY 0xFF
#define CARD_NCR_MAX 8
#define CARD_NRC 1
#define CARD_NCR 1
static
struct
msd_device
_msd_device
;
/* function define */
static
rt_bool_t
rt_tick_timeout
(
rt_tick_t
tick_start
,
rt_tick_t
tick_long
);
static
rt_err_t
MSD_take_owner
(
struct
rt_spi_device
*
spi_device
);
static
void
MSD_take_cs
(
struct
rt_spi_device
*
device
);
static
void
MSD_release_cs
(
struct
rt_spi_device
*
device
);
static
rt_err_t
_wait_token
(
struct
rt_spi_device
*
device
,
uint8_t
token
);
static
rt_err_t
_wait_ready
(
struct
rt_spi_device
*
device
);
static
rt_size_t
rt_msd_write
(
rt_device_t
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
);
static
rt_size_t
rt_msd_read
(
rt_device_t
dev
,
rt_off_t
pos
,
void
*
buffer
,
rt_size_t
size
);
static
rt_size_t
rt_msd_sdhc_read
(
rt_device_t
dev
,
rt_off_t
pos
,
void
*
buffer
,
rt_size_t
size
);
static
rt_size_t
rt_msd_sdhc_write
(
rt_device_t
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
);
static
rt_err_t
MSD_take_owner
(
struct
rt_spi_device
*
spi_device
)
{
rt_err_t
result
;
result
=
rt_mutex_take
(
&
(
spi_device
->
bus
->
lock
),
RT_WAITING_FOREVER
);
if
(
result
==
RT_EOK
)
{
if
(
spi_device
->
bus
->
owner
!=
spi_device
)
{
/* not the same owner as current, re-configure SPI bus */
result
=
spi_device
->
bus
->
ops
->
configure
(
spi_device
,
&
spi_device
->
config
);
if
(
result
==
RT_EOK
)
{
/* set SPI bus owner */
spi_device
->
bus
->
owner
=
spi_device
;
}
}
}
return
result
;
}
static
void
MSD_take_cs
(
struct
rt_spi_device
*
device
)
{
u32
i
=
0
;
/* Initialize SPI */
SPI_Config
();
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send dummy byte 0xFF, 10 times with CS high*/
/* rise CS and MOSI for 80 clocks cycles */
for
(
i
=
0
;
i
<
10
;
i
++
)
{
/* Send dummy byte 0xFF */
MSD_WriteByte
(
DUMMY
);
}
/*------------Put MSD in SPI mode--------------*/
/* MSD initialized and set to SPI mode properly */
return
(
MSD_GoIdleState
());
struct
rt_spi_message
message
;
/* initial message */
message
.
send_buf
=
RT_NULL
;
message
.
recv_buf
=
RT_NULL
;
message
.
length
=
0
;
message
.
cs_take
=
1
;
message
.
cs_release
=
0
;
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
}
/*******************************************************************************
* Function Name : MSD_WriteBlock
* Description : Writes a block on the MSD
* Input : - pBuffer : pointer to the buffer containing the data to be
* written on the MSD.
* - WriteAddr : address to write on.
* - NumByteToWrite: number of data to write
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8
MSD_WriteBlock
(
u8
*
pBuffer
,
u32
WriteAddr
,
u16
NumByteToWrite
)
static
void
MSD_release_cs
(
struct
rt_spi_device
*
device
)
{
u32
i
=
0
;
u8
rvalue
=
MSD_RESPONSE_FAILURE
;
struct
rt_spi_message
message
;
/* initial message */
message
.
send_buf
=
RT_NULL
;
message
.
recv_buf
=
RT_NULL
;
message
.
length
=
0
;
message
.
cs_take
=
0
;
message
.
cs_release
=
1
;
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
}
/* MSD chip select low */
MSD_CS_LOW
();
/* Send CMD24 (MSD_WRITE_BLOCK) to write multiple block */
MSD_SendCmd
(
MSD_WRITE_BLOCK
,
WriteAddr
,
0xFF
);
static
rt_bool_t
rt_tick_timeout
(
rt_tick_t
tick_start
,
rt_tick_t
tick_long
)
{
rt_tick_t
tick_end
=
tick_start
+
tick_long
;
rt_tick_t
tick_now
=
rt_tick_get
();
rt_bool_t
result
=
RT_FALSE
;
/* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */
if
(
!
MSD_GetResponse
(
MSD_RESPONSE_NO_ERROR
))
if
(
tick_end
>=
tick_start
)
{
/* Send a dummy byte */
MSD_WriteByte
(
DUMMY
);
/* Send the data token to signify the start of the data */
MSD_WriteByte
(
0xFE
);
/* Write the block data to MSD : write count data by block */
for
(
i
=
0
;
i
<
NumByteToWrite
;
i
++
)
if
(
tick_now
>=
tick_end
)
{
/* Send the pointed byte */
MSD_WriteByte
(
*
pBuffer
);
/* Point to the next location where the byte read will be saved */
pBuffer
++
;
result
=
RT_TRUE
;
}
/* Put CRC bytes (not really needed by us, but required by MSD) */
MSD_ReadByte
();
MSD_ReadByte
();
/* Read data response */
if
(
MSD_GetDataResponse
()
==
MSD_DATA_OK
)
else
{
rvalue
=
MSD_RESPONSE_NO_ERROR
;
result
=
RT_FALSE
;
}
}
else
{
if
((
tick_now
<
tick_start
)
&&
(
tick_now
>=
tick_end
)
)
{
result
=
RT_TRUE
;
}
else
{
result
=
RT_FALSE
;
}
}
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte
(
DUMMY
);
/* Returns the reponse */
return
rvalue
;
return
result
;
}
/*******************************************************************************
* Function Name : MSD_ReadBlock
* Description : Reads a block of data from the MSD.
* Input : - pBuffer : pointer to the buffer that receives the data read
* from the MSD.
* - ReadAddr : MSD's internal address to read from.
* - NumByteToRead : number of bytes to read from the MSD.
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8
MSD_ReadBlock
(
u8
*
pBuffer
,
u32
ReadAddr
,
u16
NumByteToRead
)
static
uint8_t
crc7
(
const
uint8_t
*
buf
,
int
len
)
{
u32
i
=
0
;
u8
rvalue
=
MSD_RESPONSE_FAILURE
;
unsigned
char
i
,
j
,
crc
,
ch
,
ch2
,
ch3
;
crc
=
0
;
/* MSD chip select low */
MSD_CS_LOW
();
/* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block */
MSD_SendCmd
(
MSD_READ_SINGLE_BLOCK
,
ReadAddr
,
0xFF
);
for
(
i
=
0
;
i
<
len
;
i
++
)
{
ch
=
buf
[
i
];
/* Check if the MSD acknowledged the read block command: R1 response (0x00: no errors) */
if
(
!
MSD_GetResponse
(
MSD_RESPONSE_NO_ERROR
))
for
(
j
=
0
;
j
<
8
;
j
++
,
ch
<<=
1
)
{
/* Now look for the data token to signify the start of the data */
if
(
!
MSD_GetResponse
(
MSD_START_DATA_SINGLE_BLOCK_READ
))
ch2
=
(
crc
&
0x40
)
?
1
:
0
;
ch3
=
(
ch
&
0x80
)
?
1
:
0
;
if
(
ch2
^
ch3
)
{
/* Read the MSD block data : read NumByteToRead data */
for
(
i
=
0
;
i
<
NumByteToRead
;
i
++
)
crc
^=
0x04
;
crc
<<=
1
;
crc
|=
0x01
;
}
else
{
/* Save the received data */
*
pBuffer
=
MSD_ReadByte
();
/* Point to the next location where the byte read will be saved */
pBuffer
++
;
crc
<<=
1
;
}
/* Get CRC bytes (not really needed by us, but required by MSD) */
MSD_ReadByte
();
MSD_ReadByte
();
/* Set response value to success */
rvalue
=
MSD_RESPONSE_NO_ERROR
;
}
}
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte
(
DUMMY
);
/* Returns the reponse */
return
rvalue
;
return
crc
;
}
/*******************************************************************************
* Function Name : MSD_WriteBuffer
* Description : Writes many blocks on the MSD
* Input : - pBuffer : pointer to the buffer containing the data to be
* written on the MSD.
* - WriteAddr : address to write on.
* - NumByteToWrite: number of data to write
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8
MSD_WriteBuffer
(
u8
*
pBuffer
,
u32
WriteAddr
,
u32
NumByteToWrite
)
static
rt_err_t
_send_cmd
(
struct
rt_spi_device
*
device
,
uint8_t
cmd
,
uint32_t
arg
,
uint8_t
crc
,
response_type
type
,
uint8_t
*
response
)
{
u32
i
=
0
,
NbrOfBlock
=
0
,
Offset
=
0
;
u8
rvalue
=
MSD_RESPONSE_FAILURE
;
struct
rt_spi_message
message
;
uint8_t
cmd_buffer
[
8
];
uint8_t
recv_buffer
[
sizeof
(
cmd_buffer
)];
uint32_t
i
;
cmd_buffer
[
0
]
=
DUMMY
;
cmd_buffer
[
1
]
=
(
cmd
|
0x40
);
cmd_buffer
[
2
]
=
(
uint8_t
)(
arg
>>
24
);
cmd_buffer
[
3
]
=
(
uint8_t
)(
arg
>>
16
);
cmd_buffer
[
4
]
=
(
uint8_t
)(
arg
>>
8
);
cmd_buffer
[
5
]
=
(
uint8_t
)(
arg
);
if
(
crc
==
0x00
)
{
crc
=
crc7
(
&
cmd_buffer
[
1
],
5
);
crc
=
(
crc
<<
1
)
|
0x01
;
}
cmd_buffer
[
6
]
=
(
crc
);
cmd_buffer
[
7
]
=
DUMMY
;
/* initial message */
message
.
send_buf
=
cmd_buffer
;
message
.
recv_buf
=
recv_buffer
;
message
.
length
=
sizeof
(
cmd_buffer
);
message
.
cs_take
=
message
.
cs_release
=
0
;
/* Calculate number of blocks to write */
NbrOfBlock
=
NumByteToWrite
/
BLOCK_SIZE
;
/* MSD chip select low */
MSD_CS_LOW
();
_wait_ready
(
device
);
/* Data transfer */
while
(
NbrOfBlock
--
)
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
for
(
i
=
CARD_NCR
;
i
<
(
CARD_NCR_MAX
+
1
);
i
++
)
{
/* Send CMD24 (MSD_WRITE_BLOCK) to write blocks */
MSD_SendCmd
(
MSD_WRITE_BLOCK
,
WriteAddr
+
Offset
,
0xFF
);
uint8_t
send
=
DUMMY
;
/* initial message */
message
.
send_buf
=
&
send
;
message
.
recv_buf
=
response
;
message
.
length
=
1
;
message
.
cs_take
=
message
.
cs_release
=
0
;
/* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */
if
(
MSD_GetResponse
(
MSD_RESPONSE_NO_ERROR
))
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
if
(
0
==
(
response
[
0
]
&
0x80
))
{
return
MSD_RESPONSE_FAILURE
;
break
;
}
/* Send dummy byte */
MSD_WriteByte
(
DUMMY
);
/* Send the data token to signify the start of the data */
MSD_WriteByte
(
MSD_START_DATA_SINGLE_BLOCK_WRITE
);
/* Write the block data to MSD : write count data by block */
for
(
i
=
0
;
i
<
BLOCK_SIZE
;
i
++
)
}
/* wait response */
if
((
CARD_NCR_MAX
+
1
)
==
i
)
{
/* Send the pointed byte */
MSD_WriteByte
(
*
pBuffer
);
/* Point to the next location where the byte read will be saved */
pBuffer
++
;
return
RT_ERROR
;
//fail
}
/* Set next write address */
Offset
+=
512
;
/* Put CRC bytes (not really needed by us, but required by MSD) */
MSD_ReadByte
();
MSD_ReadByte
();
/* Read data response */
if
(
MSD_GetDataResponse
()
==
MSD_DATA_OK
)
//recieve other byte
if
(
type
==
response_r1
)
{
/* Set response value to success */
rvalue
=
MSD_RESPONSE_NO_ERROR
;
return
RT_EOK
;
}
else
else
if
(
type
==
response_r1b
)
{
/* Set response value to failure */
rvalue
=
MSD_RESPONSE_FAILURE
;
rt_tick_t
tick_start
=
rt_tick_get
();
uint8_t
recv
;
while
(
1
)
{
/* initial message */
message
.
send_buf
=
RT_NULL
;
message
.
recv_buf
=
&
recv
;
message
.
length
=
1
;
message
.
cs_take
=
message
.
cs_release
=
0
;
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
if
(
recv
==
DUMMY
)
{
return
RT_EOK
;
}
if
(
rt_tick_timeout
(
tick_start
,
rt_tick_from_millisecond
(
2000
)))
{
return
RT_ETIMEOUT
;
}
}
}
else
if
(
type
==
response_r2
)
{
/* initial message */
message
.
send_buf
=
RT_NULL
;
message
.
recv_buf
=
response
+
1
;
message
.
length
=
1
;
message
.
cs_take
=
message
.
cs_release
=
0
;
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
}
else
if
((
type
==
response_r3
)
||
(
type
==
response_r7
))
{
/* initial message */
message
.
send_buf
=
RT_NULL
;
message
.
recv_buf
=
response
+
1
;
message
.
length
=
4
;
message
.
cs_take
=
message
.
cs_release
=
0
;
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
}
else
{
return
RT_ERROR
;
// unknow type?
}
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte
(
DUMMY
);
/* Returns the reponse */
return
rvalue
;
return
RT_EOK
;
}
/*******************************************************************************
* Function Name : MSD_ReadBuffer
* Description : Reads multiple block of data from the MSD.
* Input : - pBuffer : pointer to the buffer that receives the data read
* from the MSD.
* - ReadAddr : MSD's internal address to read from.
* - NumByteToRead : number of bytes to read from the MSD.
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8
MSD_ReadBuffer
(
u8
*
pBuffer
,
u32
ReadAddr
,
u32
NumByteToRead
)
static
rt_err_t
_wait_token
(
struct
rt_spi_device
*
device
,
uint8_t
token
)
{
u32
i
=
0
,
NbrOfBlock
=
0
,
Offset
=
0
;
u8
rvalue
=
MSD_RESPONSE_FAILURE
;
struct
rt_spi_message
message
;
rt_tick_t
tick_start
;
uint8_t
send
,
recv
;
tick_start
=
rt_tick_get
();
/* Calculate number of blocks to read */
NbrOfBlock
=
NumByteToRead
/
BLOCK_SIZE
;
/* MSD chip select low */
MSD_CS_LOW
();
/* wati token */
/* initial message */
send
=
DUMMY
;
message
.
send_buf
=
&
send
;
message
.
recv_buf
=
&
recv
;
message
.
length
=
1
;
message
.
cs_take
=
message
.
cs_release
=
0
;
/* Data transfer */
while
(
NbrOfBlock
--
)
while
(
1
)
{
/* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block
*/
MSD_SendCmd
(
MSD_READ_SINGLE_BLOCK
,
ReadAddr
+
Offset
,
0xFF
);
/* Check if the MSD acknowledged the read block command: R1 response (0x00: no errors) */
if
(
MSD_GetResponse
(
MSD_RESPONSE_NO_ERROR
)
)
/* transfer message
*/
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
if
(
recv
==
token
)
{
return
MSD_RESPONSE_FAILURE
;
return
RT_EOK
;
}
/* Now look for the data token to signify the start of the data */
if
(
!
MSD_GetResponse
(
MSD_START_DATA_SINGLE_BLOCK_READ
))
{
/* Read the MSD block data : read NumByteToRead data */
for
(
i
=
0
;
i
<
BLOCK_SIZE
;
i
++
)
if
(
rt_tick_timeout
(
tick_start
,
rt_tick_from_millisecond
(
CARD_WAIT_TOKEN_TIMES
)))
{
/* Read the pointed data */
*
pBuffer
=
MSD_ReadByte
();
/* Point to the next location where the byte read will be saved */
pBuffer
++
;
MSD_DEBUG
(
"[err] wait data start token timeout!
\r\n
"
);
return
RT_ETIMEOUT
;
}
/* Set next read address*/
Offset
+=
512
;
/* get CRC bytes (not really needed by us, but required by MSD) */
MSD_ReadByte
();
MSD_ReadByte
();
/* Set response value to success */
rvalue
=
MSD_RESPONSE_NO_ERROR
;
}
/* wati token */
}
static
rt_err_t
_wait_ready
(
struct
rt_spi_device
*
device
)
{
struct
rt_spi_message
message
;
rt_tick_t
tick_start
;
uint8_t
send
,
recv
;
tick_start
=
rt_tick_get
();
send
=
DUMMY
;
/* initial message */
message
.
send_buf
=
&
send
;
message
.
recv_buf
=
&
recv
;
message
.
length
=
1
;
message
.
cs_take
=
message
.
cs_release
=
0
;
while
(
1
)
{
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
if
(
recv
==
DUMMY
)
{
return
RT_EOK
;
}
else
if
(
rt_tick_timeout
(
tick_start
,
rt_tick_from_millisecond
(
1000
)))
{
/* Set response value to failure */
rvalue
=
MSD_RESPONSE_FAILURE
;
MSD_DEBUG
(
"[err] wait ready timeout!
\r\n
"
);
return
RT_ETIMEOUT
;
}
}
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte
(
DUMMY
);
/* Returns the reponse */
return
rvalue
;
}
/*******************************************************************************
* Function Name : MSD_GetCSDRegister
* Description : Read the CSD card register.
* Reading the contents of the CSD register in SPI mode
* is a simple read-block transaction.
* Input : - MSD_csd: pointer on an SCD register structure
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8
MSD_GetCSDRegister
(
sMSD_CSD
*
MSD_csd
)
static
rt_err_t
_read_block
(
struct
rt_spi_device
*
device
,
void
*
buffer
,
uint32_t
block_size
)
{
u32
i
=
0
;
u8
rvalue
=
MSD_RESPONSE_FAILURE
;
u8
CSD_Tab
[
16
];
/* MSD chip select low */
MSD_CS_LOW
();
/* Send CMD9 (CSD register) or CMD10(CSD register) */
MSD_SendCmd
(
MSD_SEND_CSD
,
0
,
0xFF
);
/* Wait for response in the R1 format (0x00 is no errors) */
if
(
!
MSD_GetResponse
(
MSD_RESPONSE_NO_ERROR
))
{
if
(
!
MSD_GetResponse
(
MSD_START_DATA_SINGLE_BLOCK_READ
))
{
for
(
i
=
0
;
i
<
16
;
i
++
)
{
/* Store CSD register value on CSD_Tab */
CSD_Tab
[
i
]
=
MSD_ReadByte
();
}
}
/* Get CRC bytes (not really needed by us, but required by MSD) */
MSD_WriteByte
(
DUMMY
);
MSD_WriteByte
(
DUMMY
);
/* Set response value to success */
rvalue
=
MSD_RESPONSE_NO_ERROR
;
}
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte
(
DUMMY
);
/* Byte 0 */
MSD_csd
->
CSDStruct
=
(
CSD_Tab
[
0
]
&
0xC0
)
>>
6
;
MSD_csd
->
SysSpecVersion
=
(
CSD_Tab
[
0
]
&
0x3C
)
>>
2
;
MSD_csd
->
Reserved1
=
CSD_Tab
[
0
]
&
0x03
;
/* Byte 1 */
MSD_csd
->
TAAC
=
CSD_Tab
[
1
]
;
/* Byte 2 */
MSD_csd
->
NSAC
=
CSD_Tab
[
2
];
/* Byte 3 */
MSD_csd
->
MaxBusClkFrec
=
CSD_Tab
[
3
];
/* Byte 4 */
MSD_csd
->
CardComdClasses
=
CSD_Tab
[
4
]
<<
4
;
/* Byte 5 */
MSD_csd
->
CardComdClasses
|=
(
CSD_Tab
[
5
]
&
0xF0
)
>>
4
;
MSD_csd
->
RdBlockLen
=
CSD_Tab
[
5
]
&
0x0F
;
/* Byte 6 */
MSD_csd
->
PartBlockRead
=
(
CSD_Tab
[
6
]
&
0x80
)
>>
7
;
MSD_csd
->
WrBlockMisalign
=
(
CSD_Tab
[
6
]
&
0x40
)
>>
6
;
MSD_csd
->
RdBlockMisalign
=
(
CSD_Tab
[
6
]
&
0x20
)
>>
5
;
MSD_csd
->
DSRImpl
=
(
CSD_Tab
[
6
]
&
0x10
)
>>
4
;
MSD_csd
->
Reserved2
=
0
;
/* Reserved */
MSD_csd
->
DeviceSize
=
(
CSD_Tab
[
6
]
&
0x03
)
<<
10
;
/* Byte 7 */
MSD_csd
->
DeviceSize
|=
(
CSD_Tab
[
7
])
<<
2
;
/* Byte 8 */
MSD_csd
->
DeviceSize
|=
(
CSD_Tab
[
8
]
&
0xC0
)
>>
6
;
MSD_csd
->
MaxRdCurrentVDDMin
=
(
CSD_Tab
[
8
]
&
0x38
)
>>
3
;
MSD_csd
->
MaxRdCurrentVDDMax
=
(
CSD_Tab
[
8
]
&
0x07
);
/* Byte 9 */
MSD_csd
->
MaxWrCurrentVDDMin
=
(
CSD_Tab
[
9
]
&
0xE0
)
>>
5
;
MSD_csd
->
MaxWrCurrentVDDMax
=
(
CSD_Tab
[
9
]
&
0x1C
)
>>
2
;
MSD_csd
->
DeviceSizeMul
=
(
CSD_Tab
[
9
]
&
0x03
)
<<
1
;
/* Byte 10 */
MSD_csd
->
DeviceSizeMul
|=
(
CSD_Tab
[
10
]
&
0x80
)
>>
7
;
MSD_csd
->
EraseGrSize
=
(
CSD_Tab
[
10
]
&
0x7C
)
>>
2
;
MSD_csd
->
EraseGrMul
=
(
CSD_Tab
[
10
]
&
0x03
)
<<
3
;
/* Byte 11 */
MSD_csd
->
EraseGrMul
|=
(
CSD_Tab
[
11
]
&
0xE0
)
>>
5
;
MSD_csd
->
WrProtectGrSize
=
(
CSD_Tab
[
11
]
&
0x1F
);
/* Byte 12 */
MSD_csd
->
WrProtectGrEnable
=
(
CSD_Tab
[
12
]
&
0x80
)
>>
7
;
MSD_csd
->
ManDeflECC
=
(
CSD_Tab
[
12
]
&
0x60
)
>>
5
;
MSD_csd
->
WrSpeedFact
=
(
CSD_Tab
[
12
]
&
0x1C
)
>>
2
;
MSD_csd
->
MaxWrBlockLen
=
(
CSD_Tab
[
12
]
&
0x03
)
<<
2
;
/* Byte 13 */
MSD_csd
->
MaxWrBlockLen
|=
(
CSD_Tab
[
13
]
&
0xc0
)
>>
6
;
MSD_csd
->
WriteBlockPaPartial
=
(
CSD_Tab
[
13
]
&
0x20
)
>>
5
;
MSD_csd
->
Reserved3
=
0
;
MSD_csd
->
ContentProtectAppli
=
(
CSD_Tab
[
13
]
&
0x01
);
/* Byte 14 */
MSD_csd
->
FileFormatGrouop
=
(
CSD_Tab
[
14
]
&
0x80
)
>>
7
;
MSD_csd
->
CopyFlag
=
(
CSD_Tab
[
14
]
&
0x40
)
>>
6
;
MSD_csd
->
PermWrProtect
=
(
CSD_Tab
[
14
]
&
0x20
)
>>
5
;
MSD_csd
->
TempWrProtect
=
(
CSD_Tab
[
14
]
&
0x10
)
>>
4
;
MSD_csd
->
FileFormat
=
(
CSD_Tab
[
14
]
&
0x0C
)
>>
2
;
MSD_csd
->
ECC
=
(
CSD_Tab
[
14
]
&
0x03
);
/* Byte 15 */
MSD_csd
->
msd_CRC
=
(
CSD_Tab
[
15
]
&
0xFE
)
>>
1
;
MSD_csd
->
Reserved4
=
1
;
/* Return the reponse */
return
rvalue
;
}
struct
rt_spi_message
message
;
rt_err_t
result
;
/*******************************************************************************
* Function Name : MSD_GetCIDRegister
* Description : Read the CID card register.
* Reading the contents of the CID register in SPI mode
* is a simple read-block transaction.
* Input : - MSD_cid: pointer on an CID register structure
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8
MSD_GetCIDRegister
(
sMSD_CID
*
MSD_cid
)
{
u32
i
=
0
;
u8
rvalue
=
MSD_RESPONSE_FAILURE
;
u8
CID_Tab
[
16
];
/* MSD chip select low */
MSD_CS_LOW
();
/* Send CMD10 (CID register) */
MSD_SendCmd
(
MSD_SEND_CID
,
0
,
0xFF
);
/* Wait for response in the R1 format (0x00 is no errors) */
if
(
!
MSD_GetResponse
(
MSD_RESPONSE_NO_ERROR
))
{
if
(
!
MSD_GetResponse
(
MSD_START_DATA_SINGLE_BLOCK_READ
))
{
/* Store CID register value on CID_Tab */
for
(
i
=
0
;
i
<
16
;
i
++
)
{
CID_Tab
[
i
]
=
MSD_ReadByte
();
}
}
/* Get CRC bytes (not really needed by us, but required by MSD) */
MSD_WriteByte
(
DUMMY
);
MSD_WriteByte
(
DUMMY
);
/* Set response value to success */
rvalue
=
MSD_RESPONSE_NO_ERROR
;
}
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte
(
DUMMY
);
/* Byte 0 */
MSD_cid
->
ManufacturerID
=
CID_Tab
[
0
];
/* Byte 1 */
MSD_cid
->
OEM_AppliID
=
CID_Tab
[
1
]
<<
8
;
/* Byte 2 */
MSD_cid
->
OEM_AppliID
|=
CID_Tab
[
2
];
/* Byte 3 */
MSD_cid
->
ProdName1
=
CID_Tab
[
3
]
<<
24
;
/* Byte 4 */
MSD_cid
->
ProdName1
|=
CID_Tab
[
4
]
<<
16
;
/* Byte 5 */
MSD_cid
->
ProdName1
|=
CID_Tab
[
5
]
<<
8
;
/* Byte 6 */
MSD_cid
->
ProdName1
|=
CID_Tab
[
6
];
/* Byte 7 */
MSD_cid
->
ProdName2
=
CID_Tab
[
7
];
/* Byte 8 */
MSD_cid
->
ProdRev
=
CID_Tab
[
8
];
/* Byte 9 */
MSD_cid
->
ProdSN
=
CID_Tab
[
9
]
<<
24
;
/* Byte 10 */
MSD_cid
->
ProdSN
|=
CID_Tab
[
10
]
<<
16
;
/* Byte 11 */
MSD_cid
->
ProdSN
|=
CID_Tab
[
11
]
<<
8
;
/* Byte 12 */
MSD_cid
->
ProdSN
|=
CID_Tab
[
12
];
/* Byte 13 */
MSD_cid
->
Reserved1
|=
(
CID_Tab
[
13
]
&
0xF0
)
>>
4
;
/* Byte 14 */
MSD_cid
->
ManufactDate
=
(
CID_Tab
[
13
]
&
0x0F
)
<<
8
;
/* Byte 15 */
MSD_cid
->
ManufactDate
|=
CID_Tab
[
14
];
/* Byte 16 */
MSD_cid
->
msd_CRC
=
(
CID_Tab
[
15
]
&
0xFE
)
>>
1
;
MSD_cid
->
Reserved2
=
1
;
/* Return the reponse */
return
rvalue
;
/* wati token */
result
=
_wait_token
(
device
,
MSD_TOKEN_READ_START
);
if
(
result
!=
RT_EOK
)
{
return
result
;
}
/* read data */
{
/* initial message */
message
.
send_buf
=
RT_NULL
;
message
.
recv_buf
=
buffer
;
message
.
length
=
block_size
;
message
.
cs_take
=
message
.
cs_release
=
0
;
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
}
/* read data */
/* get crc */
{
uint8_t
recv_buffer
[
2
];
/* initial message */
message
.
send_buf
=
RT_NULL
;
message
.
recv_buf
=
recv_buffer
;
message
.
length
=
2
;
message
.
cs_take
=
message
.
cs_release
=
0
;
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
}
/* get crc */
return
RT_EOK
;
}
/*******************************************************************************
* Function Name : MSD_SendCmd
* Description : Send 5 bytes command to the MSD card.
* Input : - Cmd: the user expected command to send to MSD card
* - Arg: the command argument
* - Crc: the CRC
* Output : None
* Return : None
*******************************************************************************/
void
MSD_SendCmd
(
u8
Cmd
,
u32
Arg
,
u8
Crc
)
static
rt_err_t
_write_block
(
struct
rt_spi_device
*
device
,
const
void
*
buffer
,
uint32_t
block_size
,
uint8_t
token
)
{
u32
i
=
0x00
;
u8
Frame
[
6
];
/* Construct byte1 */
Frame
[
0
]
=
(
Cmd
|
0x40
);
/* Construct byte2 */
Frame
[
1
]
=
(
u8
)(
Arg
>>
24
);
/* Construct byte3 */
Frame
[
2
]
=
(
u8
)(
Arg
>>
16
);
/* Construct byte4 */
Frame
[
3
]
=
(
u8
)(
Arg
>>
8
);
/* Construct byte5 */
Frame
[
4
]
=
(
u8
)(
Arg
);
/* Construct CRC: byte6 */
Frame
[
5
]
=
(
Crc
);
/* Send the Cmd bytes */
for
(
i
=
0
;
i
<
6
;
i
++
)
{
MSD_WriteByte
(
Frame
[
i
]);
struct
rt_spi_message
message
;
uint8_t
send_buffer
[
16
];
rt_memset
(
send_buffer
,
DUMMY
,
sizeof
(
send_buffer
));
send_buffer
[
sizeof
(
send_buffer
)
-
1
]
=
token
;
/* send start block token */
{
/* initial message */
message
.
send_buf
=
send_buffer
;
message
.
recv_buf
=
RT_NULL
;
message
.
length
=
sizeof
(
send_buffer
);
message
.
cs_take
=
message
.
cs_release
=
0
;
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
}
/* send data */
{
/* initial message */
message
.
send_buf
=
buffer
;
message
.
recv_buf
=
RT_NULL
;
message
.
length
=
block_size
;
message
.
cs_take
=
message
.
cs_release
=
0
;
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
}
/* put crc and get data response */
{
uint8_t
recv_buffer
[
3
];
uint8_t
response
;
/* initial message */
message
.
send_buf
=
send_buffer
;
message
.
recv_buf
=
recv_buffer
;
message
.
length
=
sizeof
(
recv_buffer
);
message
.
cs_take
=
message
.
cs_release
=
0
;
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
// response = 0x0E & recv_buffer[2];
response
=
MSD_GET_DATA_RESPONSE
(
recv_buffer
[
2
]);
if
(
response
!=
MSD_DATA_OK
)
{
MSD_DEBUG
(
"[err] write block fail! data response : 0x%02X
\r\n
"
,
response
);
return
RT_ERROR
;
}
}
/* wati ready */
return
_wait_ready
(
device
);
}
/*******************************************************************************
* Function Name : MSD_GetDataResponse
* Description : Get MSD card data response.
* Input : None
* Output : None
* Return : The MSD status: Read data response xxx0<status>1
* - status 010: Data accecpted
* - status 101: Data rejected due to a crc error
* - status 110: Data rejected due to a Write error.
* - status 111: Data rejected due to other error.
*******************************************************************************/
u8
MSD_GetDataResponse
(
void
)
/* RT-Thread Device Driver Interface */
static
rt_err_t
rt_msd_init
(
rt_device_t
dev
)
{
u32
i
=
0
;
u8
response
,
rvalue
;
struct
msd_device
*
msd
=
(
struct
msd_device
*
)
dev
;
uint8_t
response
[
MSD_RESPONSE_MAX_LEN
];
rt_err_t
result
=
RT_EOK
;
rt_tick_t
tick_start
;
uint32_t
OCR
;
if
(
msd
->
spi_device
==
RT_NULL
)
{
MSD_DEBUG
(
"[err] the SPI SD device has no SPI!
\r\n
"
);
return
RT_EIO
;
}
while
(
i
<=
64
)
/* config spi */
{
/* Read resonse */
response
=
MSD_ReadByte
();
/* Mask unused bits */
response
&=
0x1F
;
struct
rt_spi_configuration
cfg
;
cfg
.
data_width
=
8
;
cfg
.
mode
=
RT_SPI_MODE_0
|
RT_SPI_MSB
;
/* SPI Compatible Modes 0 */
cfg
.
max_hz
=
1000
*
400
;
/* 400kbit/s */
rt_spi_configure
(
msd
->
spi_device
,
&
cfg
);
}
/* config spi */
/* init SD card */
{
struct
rt_spi_message
message
;
result
=
MSD_take_owner
(
msd
->
spi_device
);
if
(
result
!=
RT_EOK
)
{
goto
_exit
;
}
MSD_release_cs
(
msd
->
spi_device
);
/* The host shall supply power to the card so that the voltage is reached to Vdd_min within 250ms and
start to supply at least 74 SD clocks to the SD card with keeping CMD line to high.
In case of SPI mode, CS shall be held to high during 74 clock cycles. */
{
uint8_t
send_buffer
[
100
];
/* 100byte > 74 clock */
switch
(
response
)
/* initial message */
memset
(
send_buffer
,
DUMMY
,
sizeof
(
send_buffer
));
message
.
send_buf
=
send_buffer
;
message
.
recv_buf
=
RT_NULL
;
message
.
length
=
sizeof
(
send_buffer
);
message
.
cs_take
=
message
.
cs_release
=
0
;
/* transfer message */
msd
->
spi_device
->
bus
->
ops
->
xfer
(
msd
->
spi_device
,
&
message
);
}
/* send 74 clock */
/* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */
{
tick_start
=
rt_tick_get
();
while
(
1
)
{
case
MSD_DATA_OK
:
MSD_take_cs
(
msd
->
spi_device
);
result
=
_send_cmd
(
msd
->
spi_device
,
GO_IDLE_STATE
,
0x00
,
0x95
,
response_r1
,
response
);
MSD_release_cs
(
msd
->
spi_device
);
if
((
result
==
RT_EOK
)
&&
(
response
[
0
]
==
MSD_IN_IDLE_STATE
))
{
rvalue
=
MSD_DATA_OK
;
break
;
}
case
MSD_DATA_CRC_ERROR
:
return
MSD_DATA_CRC_ERROR
;
if
(
rt_tick_timeout
(
tick_start
,
rt_tick_from_millisecond
(
CARD_TRY_TIMES
)))
{
MSD_DEBUG
(
"[err] SD card goto IDLE mode timeout!
\r\n
"
);
result
=
RT_ETIMEOUT
;
goto
_exit
;
}
}
MSD_DEBUG
(
"[info] SD card goto IDLE mode OK!
\r\n
"
);
}
/* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */
/* CMD8 */
{
tick_start
=
rt_tick_get
();
do
{
MSD_take_cs
(
msd
->
spi_device
);
result
=
_send_cmd
(
msd
->
spi_device
,
SEND_IF_COND
,
0x01AA
,
0x87
,
response_r7
,
response
);
MSD_release_cs
(
msd
->
spi_device
);
case
MSD_DATA_WRITE_ERROR
:
return
MSD_DATA_WRITE_ERROR
;
if
(
result
==
RT_EOK
)
{
MSD_DEBUG
(
"[info] CMD8 response : 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X
\r\n
"
,
response
[
0
],
response
[
1
],
response
[
2
],
response
[
3
],
response
[
4
]);
default:
if
(
response
[
0
]
&
(
1
<<
2
))
{
rvalue
=
MSD_DATA_OTHER_ERROR
;
/* illegal command, SD V1.x or MMC card */
MSD_DEBUG
(
"[info] CMD8 is illegal command.
\r\n
"
);
MSD_DEBUG
(
"[info] maybe Ver1.X SD Memory Card or MMC card!
\r\n
"
);
msd
->
card_type
=
MSD_CARD_TYPE_SD_V1_X
;
break
;
}
else
{
/* SD V2.0 or later or SDHC or SDXC memory card! */
MSD_DEBUG
(
"[info] Ver2.00 or later or SDHC or SDXC memory card!
\r\n
"
);
msd
->
card_type
=
MSD_CARD_TYPE_SD_V2_X
;
}
if
((
0xAA
==
response
[
4
])
&&
(
0x00
==
response
[
3
]))
{
/* SD2.0 not support current voltage */
MSD_DEBUG
(
"[err] VCA = 0, SD2.0 not surpport current operation voltage range
\r\n
"
);
result
=
RT_ERROR
;
goto
_exit
;
}
}
/* Exit loop in case of data ok */
if
(
rvalue
==
MSD_DATA_OK
)
else
{
if
(
rt_tick_timeout
(
tick_start
,
rt_tick_from_millisecond
(
200
)))
{
MSD_DEBUG
(
"[err] CMD8 SEND_IF_COND timeout!
\r\n
"
);
result
=
RT_ETIMEOUT
;
goto
_exit
;
}
}
}
while
(
0xAA
!=
response
[
4
]);
}
/* CMD8 */
/* Ver1.X SD Memory Card or MMC card */
if
(
msd
->
card_type
==
MSD_CARD_TYPE_SD_V1_X
)
{
rt_bool_t
is_sd_v1_x
=
RT_FALSE
;
rt_tick_t
tick_start
;
/* try SD Ver1.x */
while
(
1
)
{
MSD_take_cs
(
msd
->
spi_device
);
result
=
_send_cmd
(
msd
->
spi_device
,
READ_OCR
,
0x00
,
0x00
,
response_r3
,
response
);
if
(
result
!=
RT_EOK
)
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[info] It maybe SD1.x or MMC But it is Not response to CMD58!
\r\n
"
);
goto
_exit
;
}
if
(
0
!=
(
response
[
0
]
&
0xFE
))
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[info] It look CMD58 as illegal command so it is not SD card!
\r\n
"
);
break
;
/* Increment loop counter */
i
++
;
}
/* Wait null data */
while
(
MSD_ReadByte
()
==
0
);
/* Return response */
return
response
;
}
MSD_release_cs
(
msd
->
spi_device
);
/*******************************************************************************
* Function Name : MSD_GetResponse
* Description : Returns the MSD response.
* Input : None
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8
MSD_GetResponse
(
u8
Response
)
{
u32
Count
=
0xFFF
;
OCR
=
response
[
1
];
OCR
=
(
OCR
<<
8
)
+
response
[
2
];
OCR
=
(
OCR
<<
8
)
+
response
[
3
];
OCR
=
(
OCR
<<
8
)
+
response
[
4
];
MSD_DEBUG
(
"[info] OCR is 0x%08X
\r\n
"
,
OCR
);
/* Check if response is got or a timeout is happen */
while
((
MSD_ReadByte
()
!=
Response
)
&&
Count
)
if
(
0
==
(
OCR
&
(
0x1
<<
15
)))
{
Count
--
;
MSD_DEBUG
((
"[err] SD 1.x But not surpport current voltage
\r\n
"
));
result
=
RT_ERROR
;
goto
_exit
;
}
if
(
Count
==
0
)
/* --Send ACMD41 to make card ready */
tick_start
=
rt_tick_get
();
/* try CMD55 + ACMD41 */
while
(
1
)
{
/* After time out */
return
MSD_RESPONSE_FAILURE
;
if
(
rt_tick_timeout
(
tick_start
,
rt_tick_from_millisecond
(
CARD_TRY_TIMES_ACMD41
)))
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[info] try CMD55 + ACMD41 timeout! mabey MMC card!
\r\n
"
);
break
;
}
else
MSD_take_cs
(
msd
->
spi_device
);
/* CMD55 APP_CMD */
result
=
_send_cmd
(
msd
->
spi_device
,
APP_CMD
,
0x00
,
0x00
,
response_r1
,
response
);
if
(
result
!=
RT_EOK
)
{
/* Right response got */
return
MSD_RESPONSE_NO_ERROR
;
MSD_release_cs
(
msd
->
spi_device
);
continue
;
}
}
/*******************************************************************************
* Function Name : MSD_GetStatus
* Description : Returns the MSD status.
* Input : None
* Output : None
* Return : The MSD status.
*******************************************************************************/
u16
MSD_GetStatus
(
void
)
{
u16
Status
=
0
;
if
(
0
!=
(
response
[
0
]
&
0xFE
))
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[info] Not SD card2 , may be MMC
\r\n
"
);
break
;
}
/* MSD chip select low */
MSD_CS_LOW
();
/* Send CMD13 (MSD_SEND_STATUS) to get MSD status */
MSD_SendCmd
(
MSD_SEND_STATUS
,
0
,
0xFF
);
/* ACMD41 SD_SEND_OP_COND */
result
=
_send_cmd
(
msd
->
spi_device
,
SD_SEND_OP_COND
,
0x00
,
0x00
,
response_r1
,
response
);
if
(
result
!=
RT_EOK
)
{
MSD_release_cs
(
msd
->
spi_device
);
continue
;
}
Status
=
MSD_ReadByte
();
Status
|=
(
u16
)(
MSD_ReadByte
()
<<
8
);
if
(
0
!=
(
response
[
0
]
&
0xFE
))
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[info] Not SD card4 , may be MMC
\r\n
"
);
break
;
}
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send dummy byte 0xFF */
MSD_WriteByte
(
DUMMY
);
if
(
0
==
(
response
[
0
]
&
0xFF
))
{
MSD_release_cs
(
msd
->
spi_device
);
is_sd_v1_x
=
RT_TRUE
;
MSD_DEBUG
(
"[info] It is Ver1.X SD Memory Card!!!
\r\n
"
);
break
;
}
}
/* try CMD55 + ACMD41 */
return
Status
;
}
break
;
}
/* try SD Ver1.x */
/*******************************************************************************
* Function Name : MSD_GoIdleState
* Description : Put MSD in Idle state.
* Input : None
* Output : None
* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*******************************************************************************/
u8
MSD_GoIdleState
(
void
)
{
int
i
;
/* MSD chip select low */
MSD_CS_LOW
();
/* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */
MSD_SendCmd
(
MSD_GO_IDLE_STATE
,
0
,
0x95
);
/* try MMC */
if
(
is_sd_v1_x
!=
RT_TRUE
)
{
uint32_t
i
;
MSD_DEBUG
(
"[info] try MMC card!
\r\n
"
);
MSD_release_cs
(
msd
->
spi_device
);
/* send dummy clock */
{
uint8_t
send_buffer
[
100
];
/* initial message */
memset
(
send_buffer
,
DUMMY
,
sizeof
(
send_buffer
));
message
.
send_buf
=
send_buffer
;
message
.
recv_buf
=
RT_NULL
;
message
.
length
=
sizeof
(
send_buffer
);
message
.
cs_take
=
message
.
cs_release
=
0
;
for
(
i
=
0
;
i
<
10
;
i
++
)
{
/* transfer message */
msd
->
spi_device
->
bus
->
ops
->
xfer
(
msd
->
spi_device
,
&
message
);
}
}
/* send dummy clock */
/* send CMD0 goto IDLE state */
tick_start
=
rt_tick_get
();
while
(
1
)
{
MSD_take_cs
(
msd
->
spi_device
);
result
=
_send_cmd
(
msd
->
spi_device
,
GO_IDLE_STATE
,
0x00
,
0x95
,
response_r1
,
response
);
MSD_release_cs
(
msd
->
spi_device
);
if
((
result
==
RT_EOK
)
&&
(
response
[
0
]
==
MSD_IN_IDLE_STATE
))
{
break
;
}
if
(
rt_tick_timeout
(
tick_start
,
rt_tick_from_millisecond
(
CARD_TRY_TIMES
)))
{
MSD_DEBUG
(
"[err] SD card goto IDLE mode timeout!
\r\n
"
);
result
=
RT_ETIMEOUT
;
goto
_exit
;
}
}
/* send CMD0 goto IDLE stat */
/* send CMD1 */
tick_start
=
rt_tick_get
();
while
(
1
)
{
MSD_take_cs
(
msd
->
spi_device
);
result
=
_send_cmd
(
msd
->
spi_device
,
SEND_OP_COND
,
0x00
,
0x00
,
response_r1
,
response
);
MSD_release_cs
(
msd
->
spi_device
);
if
((
result
==
RT_EOK
)
&&
(
response
[
0
]
==
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[info] It is MMC card!!!
\r\n
"
);
msd
->
card_type
=
MSD_CARD_TYPE_MMC
;
break
;
}
if
(
rt_tick_timeout
(
tick_start
,
rt_tick_from_millisecond
(
CARD_TRY_TIMES
)))
{
MSD_DEBUG
(
"[err] SD card goto IDLE mode timeout!
\r\n
"
);
result
=
RT_ETIMEOUT
;
goto
_exit
;
}
}
/* send CMD1 */
}
/* try MMC */
}
else
if
(
msd
->
card_type
==
MSD_CARD_TYPE_SD_V2_X
)
{
MSD_take_cs
(
msd
->
spi_device
);
result
=
_send_cmd
(
msd
->
spi_device
,
READ_OCR
,
0x00
,
0x00
,
response_r3
,
response
);
if
(
result
!=
RT_EOK
)
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[err] It maybe SD2.0 But it is Not response to CMD58!
\r\n
"
);
goto
_exit
;
}
if
((
response
[
0
]
&
0xFE
)
!=
0
)
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[err] It look CMD58 as illegal command so it is not SD card!
\r\n
"
);
result
=
RT_ERROR
;
goto
_exit
;
}
MSD_release_cs
(
msd
->
spi_device
);
OCR
=
response
[
1
];
OCR
=
(
OCR
<<
8
)
+
response
[
2
];
OCR
=
(
OCR
<<
8
)
+
response
[
3
];
OCR
=
(
OCR
<<
8
)
+
response
[
4
];
MSD_DEBUG
(
"[info] OCR is 0x%08X
\r\n
"
,
OCR
);
/* Wait for In Idle State Response (R1 Format) equal to 0x01 */
if
(
MSD_GetResponse
(
MSD_IN_IDLE_STATE
))
if
(
0
==
(
OCR
&
(
0x1
<<
15
)))
{
/* No Idle State Response: return response failue */
return
MSD_RESPONSE_FAILURE
;
MSD_DEBUG
((
"[err] SD 1.x But not surpport current voltage
\r\n
"
));
result
=
RT_ERROR
;
goto
_exit
;
}
/*----------Activates the card initialization process-----------*/
/* --Send ACMD41 to make card ready */
tick_start
=
rt_tick_get
();
/* try CMD55 + ACMD41 */
do
{
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send Dummy byte 0xFF */
MSD_WriteByte
(
DUMMY
);
for
(
i
=
0
;
i
<
0xfff
;
i
++
);
MSD_take_cs
(
msd
->
spi_device
);
if
(
rt_tick_timeout
(
tick_start
,
rt_tick_from_millisecond
(
CARD_TRY_TIMES_ACMD41
)))
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[err] SD Ver2.x or later try CMD55 + ACMD41 timeout!
\r\n
"
);
result
=
RT_ERROR
;
goto
_exit
;
}
/* MSD chip select low */
MSD_CS_LOW
();
for
(
i
=
0
;
i
<
0xfff
;
i
++
);
/* CMD55 APP_CMD */
result
=
_send_cmd
(
msd
->
spi_device
,
APP_CMD
,
0x00
,
0x65
,
response_r1
,
response
);
// if((result != RT_EOK) || (response[0] == 0x01))
if
(
result
!=
RT_EOK
)
{
MSD_release_cs
(
msd
->
spi_device
);
continue
;
}
/* Send CMD1 (Activates the card process) until response equal to 0x0 */
MSD_SendCmd
(
MSD_SEND_OP_COND
,
0
,
0xFF
);
/* Wait for no error Response (R1 Format) equal to 0x00 */
if
((
response
[
0
]
&
0xFE
)
!=
0
)
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[err] Not SD ready!
\r\n
"
);
result
=
RT_ERROR
;
goto
_exit
;
}
while
(
MSD_GetResponse
(
MSD_RESPONSE_NO_ERROR
));
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send dummy byte 0xFF */
MSD_WriteByte
(
DUMMY
);
/* ACMD41 SD_SEND_OP_COND */
result
=
_send_cmd
(
msd
->
spi_device
,
SD_SEND_OP_COND
,
0x40000000
,
0x77
,
response_r1
,
response
);
if
(
result
!=
RT_EOK
)
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[err] ACMD41 fail!
\r\n
"
);
result
=
RT_ERROR
;
goto
_exit
;
}
return
MSD_RESPONSE_NO_ERROR
;
}
if
((
response
[
0
]
&
0xFE
)
!=
0
)
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[info] Not SD card4 , response : 0x%02X
\r\n
"
,
response
[
0
]);
// break;
}
}
while
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
);
MSD_release_cs
(
msd
->
spi_device
);
/* try CMD55 + ACMD41 */
/* --Read OCR again */
MSD_take_cs
(
msd
->
spi_device
);
result
=
_send_cmd
(
msd
->
spi_device
,
READ_OCR
,
0x00
,
0x00
,
response_r3
,
response
);
if
(
result
!=
RT_EOK
)
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[err] It maybe SD2.0 But it is Not response to 2nd CMD58!
\r\n
"
);
goto
_exit
;
}
/*******************************************************************************
* Function Name : MSD_WriteByte
* Description : Write a byte on the MSD.
* Input : Data: byte to send.
* Output : None
* Return : None.
*******************************************************************************/
u8
MSD_WriteByte
(
u8
Data
)
{
/* Wait until the transmit buffer is empty */
while
(
SPI_I2S_GetFlagStatus
(
MSD_SPI
,
SPI_I2S_FLAG_TXE
)
==
RESET
);
/* Send the byte */
SPI_I2S_SendData
(
MSD_SPI
,
Data
);
if
((
response
[
0
]
&
0xFE
)
!=
0
)
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[err] It look 2nd CMD58 as illegal command so it is not SD card!
\r\n
"
);
result
=
RT_ERROR
;
goto
_exit
;
}
MSD_release_cs
(
msd
->
spi_device
);
/* Get the received data */
Data
=
SPI_I2S_ReceiveData
(
MSD_SPI
);
OCR
=
response
[
1
];
OCR
=
(
OCR
<<
8
)
+
response
[
2
];
OCR
=
(
OCR
<<
8
)
+
response
[
3
];
OCR
=
(
OCR
<<
8
)
+
response
[
4
];
MSD_DEBUG
(
"[info] OCR 2nd read is 0x%08X
\r\n
"
,
OCR
);
return
Data
;
}
if
((
OCR
&
0x40000000
)
!=
0
)
{
MSD_DEBUG
(
"[info] It is SD2.0 SDHC Card!!!
\r\n
"
);
msd
->
card_type
=
MSD_CARD_TYPE_SD_SDHC
;
}
else
{
MSD_DEBUG
(
"[info] It is SD2.0 standard capacity Card!!!
\r\n
"
);
}
}
/* MSD_CARD_TYPE_SD_V2_X */
else
{
MSD_DEBUG
(
"[err] SD card type unkonw!
\r\n
"
);
result
=
RT_ERROR
;
goto
_exit
;
}
}
/* init SD card */
/*******************************************************************************
* Function Name : MSD_ReadByte
* Description : Read a byte from the MSD.
* Input : None.
* Output : None
* Return : The received byte.
*******************************************************************************/
u8
MSD_ReadByte
(
void
)
{
u8
Data
=
0
;
if
(
msd
->
card_type
==
MSD_CARD_TYPE_SD_SDHC
)
{
dev
->
read
=
rt_msd_sdhc_read
;
dev
->
write
=
rt_msd_sdhc_write
;
}
else
{
dev
->
read
=
rt_msd_read
;
dev
->
write
=
rt_msd_write
;
}
/* Wait until the transmit buffer is empty */
while
(
SPI_I2S_GetFlagStatus
(
MSD_SPI
,
SPI_I2S_FLAG_TXE
)
==
RESET
);
/* Send the byte */
SPI_I2S_SendData
(
MSD_SPI
,
DUMMY
);
/* set CRC */
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_take_cs
(
msd
->
spi_device
);
#ifdef MSD_USE_CRC
result
=
_send_cmd
(
msd
->
spi_device
,
CRC_ON_OFF
,
0x01
,
0x83
,
response_r1
,
response
);
#else
result
=
_send_cmd
(
msd
->
spi_device
,
CRC_ON_OFF
,
0x00
,
0x91
,
response_r1
,
response
);
#endif
MSD_release_cs
(
msd
->
spi_device
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[err] CMD59 CRC_ON_OFF fail! response : 0x%02X
\r\n
"
,
response
[
0
]);
result
=
RT_ERROR
;
goto
_exit
;
}
}
/* set CRC */
/* Wait until a data is received */
while
(
SPI_I2S_GetFlagStatus
(
MSD_SPI
,
SPI_I2S_FLAG_RXNE
)
==
RESET
);
/* Get the received data */
Data
=
SPI_I2S_ReceiveData
(
MSD_SPI
);
/* CMD16 SET_BLOCKLEN */
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_take_cs
(
msd
->
spi_device
);
result
=
_send_cmd
(
msd
->
spi_device
,
SET_BLOCKLEN
,
SECTOR_SIZE
,
0x00
,
response_r1
,
response
);
MSD_release_cs
(
msd
->
spi_device
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[err] CMD16 SET_BLOCKLEN fail! response : 0x%02X
\r\n
"
,
response
[
0
]);
result
=
RT_ERROR
;
goto
_exit
;
}
msd
->
geometry
.
block_size
=
SECTOR_SIZE
;
msd
->
geometry
.
bytes_per_sector
=
SECTOR_SIZE
;
}
/* Return the shifted data
*/
return
Data
;
}
/* read CSD
*/
{
uint8_t
CSD_buffer
[
MSD_CSD_LEN
];
/*******************************************************************************
* Function Name : SPI_Config
* Description : Initializes the SPI and CS pins.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void
SPI_Config
(
void
)
{
uint32_t
delay
;
GPIO_InitTypeDef
GPIO_InitStructure
;
SPI_InitTypeDef
SPI_InitStructure
;
/* GPIOA and GPIOC Periph clock enable */
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_GPIOA
|
RCC_APB2Periph_GPIOC
|
RCC_APB2Periph_AFIO
,
ENABLE
);
/* SPI Periph clock enable */
RCC_APB2PeriphClockCmd
(
MSD_RCC_SPI
,
ENABLE
);
/* Configure SPI pins: SCK, MISO and MOSI */
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_5
|
GPIO_Pin_6
|
GPIO_Pin_7
;
GPIO_InitStructure
.
GPIO_Speed
=
GPIO_Speed_50MHz
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_AF_PP
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStructure
);
/* Configure PA4 pin: CS pin, PC4 : SD Power */
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_4
;
GPIO_InitStructure
.
GPIO_Speed
=
GPIO_Speed_50MHz
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_Out_PP
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStructure
);
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_4
;
GPIO_InitStructure
.
GPIO_Speed
=
GPIO_Speed_50MHz
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_Out_PP
;
GPIO_Init
(
GPIOC
,
&
GPIO_InitStructure
);
/* SPI Config */
SPI_InitStructure
.
SPI_Direction
=
SPI_Direction_2Lines_FullDuplex
;
SPI_InitStructure
.
SPI_Mode
=
SPI_Mode_Master
;
SPI_InitStructure
.
SPI_DataSize
=
SPI_DataSize_8b
;
SPI_InitStructure
.
SPI_CPOL
=
SPI_CPOL_High
;
SPI_InitStructure
.
SPI_CPHA
=
SPI_CPHA_2Edge
;
SPI_InitStructure
.
SPI_NSS
=
SPI_NSS_Soft
;
SPI_InitStructure
.
SPI_BaudRatePrescaler
=
SPI_BaudRatePrescaler_4
;
SPI_InitStructure
.
SPI_FirstBit
=
SPI_FirstBit_MSB
;
SPI_InitStructure
.
SPI_CRCPolynomial
=
7
;
SPI_Init
(
MSD_SPI
,
&
SPI_InitStructure
);
/* SPI enable */
SPI_Cmd
(
MSD_SPI
,
ENABLE
);
/* active SD card */
GPIO_ResetBits
(
GPIOC
,
GPIO_Pin_4
);
for
(
delay
=
0
;
delay
<
0xfffff
;
delay
++
);
}
MSD_take_cs
(
msd
->
spi_device
);
// result = _send_cmd(msd->spi_device, SEND_CSD, 0x00, 0xAF, response_r1, response);
result
=
_send_cmd
(
msd
->
spi_device
,
SEND_CSD
,
0x00
,
0x00
,
response_r1
,
response
);
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
if
(
result
!=
RT_EOK
)
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[err] CMD9 SEND_CSD timeout!
\r\n
"
);
goto
_exit
;
}
/*
* RT-Thread SD Card Driver
* 2009-04-17 Bernard first version
* 2010-07-15 Modify read/write according new block driver interface
*/
#include <rtthread.h>
#include <dfs_fs.h>
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[err] CMD9 SEND_CSD fail! response : 0x%02X
\r\n
"
,
response
[
0
]);
result
=
RT_ERROR
;
goto
_exit
;
}
static
struct
rt_device
sdcard_device
;
static
struct
dfs_partition
part
;
result
=
_read_block
(
msd
->
spi_device
,
CSD_buffer
,
MSD_CSD_LEN
);
MSD_release_cs
(
msd
->
spi_device
);
if
(
result
!=
RT_EOK
)
{
MSD_DEBUG
(
"[err] read CSD fail!
\r\n
"
);
goto
_exit
;
}
#define SECTOR_SIZE 512
/* Analyze CSD */
{
uint8_t
CSD_STRUCTURE
;
uint32_t
C_SIZE
;
uint32_t
card_capacity
;
/* RT-Thread Device Driver Interface */
static
rt_err_t
rt_msd_init
(
rt_device_t
dev
)
{
sMSD_CSD
MSD_csd
;
MSD_GetCSDRegister
(
&
MSD_csd
);
uint8_t
tmp8
;
uint16_t
tmp16
;
uint32_t
tmp32
;
return
RT_EOK
;
/* get CSD_STRUCTURE */
tmp8
=
CSD_buffer
[
0
]
&
0xC0
;
/* 0b11000000 */
CSD_STRUCTURE
=
tmp8
>>
6
;
/* MMC CSD Analyze. */
if
(
msd
->
card_type
==
MSD_CARD_TYPE_MMC
)
{
uint8_t
C_SIZE_MULT
;
uint8_t
READ_BL_LEN
;
if
(
CSD_STRUCTURE
>
2
)
{
MSD_DEBUG
(
"[err] bad CSD Version : %d
\r\n
"
,
CSD_STRUCTURE
);
result
=
RT_ERROR
;
goto
_exit
;
}
if
(
CSD_STRUCTURE
==
0
)
{
MSD_DEBUG
(
"[info] CSD version No. 1.0
\r\n
"
);
}
else
if
(
CSD_STRUCTURE
==
1
)
{
MSD_DEBUG
(
"[info] CSD version No. 1.1
\r\n
"
);
}
else
if
(
CSD_STRUCTURE
==
2
)
{
MSD_DEBUG
(
"[info] CSD version No. 1.2
\r\n
"
);
}
/* get TRAN_SPEED 8bit [103:96] */
tmp8
=
CSD_buffer
[
3
];
tmp8
&=
0x03
;
/* [2:0] transfer rate unit.*/
if
(
tmp8
==
0
)
{
msd
->
max_clock
=
100
*
1000
;
/* 0=100kbit/s. */
}
else
if
(
tmp8
==
1
)
{
msd
->
max_clock
=
1
*
1000
*
1000
;
/* 1=1Mbit/s. */
}
else
if
(
tmp8
==
2
)
{
msd
->
max_clock
=
10
*
1000
*
1000
;
/* 2=10Mbit/s. */
}
else
if
(
tmp8
==
3
)
{
msd
->
max_clock
=
100
*
1000
*
1000
;
/* 3=100Mbit/s. */
}
if
(
tmp8
==
0
)
{
MSD_DEBUG
(
"[info] TRAN_SPEED: 0x%02X, %dkbit/s.
\r\n
"
,
tmp8
,
msd
->
max_clock
/
1000
);
}
else
{
MSD_DEBUG
(
"[info] TRAN_SPEED: 0x%02X, %dMbit/s.
\r\n
"
,
tmp8
,
msd
->
max_clock
/
1000
/
1000
);
}
/* get READ_BL_LEN 4bit [83:80] */
tmp8
=
CSD_buffer
[
5
]
&
0x0F
;
/* 0b00001111; */
READ_BL_LEN
=
tmp8
;
/* 4 bit */
MSD_DEBUG
(
"[info] CSD : READ_BL_LEN : %d %dbyte
\r\n
"
,
READ_BL_LEN
,
(
1
<<
READ_BL_LEN
));
/* get C_SIZE 12bit [73:62] */
tmp16
=
CSD_buffer
[
6
]
&
0x03
;
/* get [73:72] 0b00000011 */
tmp16
=
tmp16
<<
8
;
tmp16
+=
CSD_buffer
[
7
];
/* get [71:64] */
tmp16
=
tmp16
<<
2
;
tmp8
=
CSD_buffer
[
8
]
&
0xC0
;
/* get [63:62] 0b11000000 */
tmp8
=
tmp8
>>
6
;
tmp16
=
tmp16
+
tmp8
;
C_SIZE
=
tmp16
;
//12 bit
MSD_DEBUG
(
"[info] CSD : C_SIZE : %d
\r\n
"
,
C_SIZE
);
/* get C_SIZE_MULT 3bit [49:47] */
tmp8
=
CSD_buffer
[
9
]
&
0x03
;
//0b00000011;
tmp8
=
tmp8
<<
1
;
tmp8
=
tmp8
+
((
CSD_buffer
[
10
]
&
0x80
/*0b10000000*/
)
>>
7
);
C_SIZE_MULT
=
tmp8
;
// 3 bit
MSD_DEBUG
(
"[info] CSD : C_SIZE_MULT : %d
\r\n
"
,
C_SIZE_MULT
);
/* memory capacity = BLOCKNR * BLOCK_LEN */
/* BLOCKNR = (C_SIZE+1) * MULT */
/* MULT = 2^(C_SIZE_MULT+2) */
/* BLOCK_LEN = 2^READ_BL_LEN */
card_capacity
=
(
1
<<
READ_BL_LEN
)
*
((
C_SIZE
+
1
)
*
(
1
<<
(
C_SIZE_MULT
+
2
)));
msd
->
geometry
.
sector_count
=
card_capacity
/
msd
->
geometry
.
bytes_per_sector
;
MSD_DEBUG
(
"[info] card capacity : %d Mbyte
\r\n
"
,
card_capacity
/
(
1024
*
1024
));
}
else
/* SD CSD Analyze. */
{
if
(
CSD_STRUCTURE
==
0
)
{
uint8_t
C_SIZE_MULT
;
uint8_t
READ_BL_LEN
;
MSD_DEBUG
(
"[info] CSD Version 1.0
\r\n
"
);
/* get TRAN_SPEED 8bit [103:96] */
tmp8
=
CSD_buffer
[
3
];
if
(
tmp8
==
0x32
)
{
msd
->
max_clock
=
1000
*
1000
*
10
;
/* 10Mbit/s. */
}
else
if
(
tmp8
==
0x5A
)
{
msd
->
max_clock
=
1000
*
1000
*
50
;
/* 50Mbit/s. */
}
else
{
msd
->
max_clock
=
1000
*
1000
*
1
;
/* 1Mbit/s default. */
}
MSD_DEBUG
(
"[info] TRAN_SPEED: 0x%02X, %dMbit/s.
\r\n
"
,
tmp8
,
msd
->
max_clock
/
1000
/
1000
);
/* get READ_BL_LEN 4bit [83:80] */
tmp8
=
CSD_buffer
[
5
]
&
0x0F
;
/* 0b00001111; */
READ_BL_LEN
=
tmp8
;
/* 4 bit */
MSD_DEBUG
(
"[info] CSD : READ_BL_LEN : %d %dbyte
\r\n
"
,
READ_BL_LEN
,
(
1
<<
READ_BL_LEN
));
/* get C_SIZE 12bit [73:62] */
tmp16
=
CSD_buffer
[
6
]
&
0x03
;
/* get [73:72] 0b00000011 */
tmp16
=
tmp16
<<
8
;
tmp16
+=
CSD_buffer
[
7
];
/* get [71:64] */
tmp16
=
tmp16
<<
2
;
tmp8
=
CSD_buffer
[
8
]
&
0xC0
;
/* get [63:62] 0b11000000 */
tmp8
=
tmp8
>>
6
;
tmp16
=
tmp16
+
tmp8
;
C_SIZE
=
tmp16
;
//12 bit
MSD_DEBUG
(
"[info] CSD : C_SIZE : %d
\r\n
"
,
C_SIZE
);
/* get C_SIZE_MULT 3bit [49:47] */
tmp8
=
CSD_buffer
[
9
]
&
0x03
;
//0b00000011;
tmp8
=
tmp8
<<
1
;
tmp8
=
tmp8
+
((
CSD_buffer
[
10
]
&
0x80
/*0b10000000*/
)
>>
7
);
C_SIZE_MULT
=
tmp8
;
// 3 bit
MSD_DEBUG
(
"[info] CSD : C_SIZE_MULT : %d
\r\n
"
,
C_SIZE_MULT
);
/* memory capacity = BLOCKNR * BLOCK_LEN */
/* BLOCKNR = (C_SIZE+1) * MULT */
/* MULT = 2^(C_SIZE_MULT+2) */
/* BLOCK_LEN = 2^READ_BL_LEN */
card_capacity
=
(
1
<<
READ_BL_LEN
)
*
((
C_SIZE
+
1
)
*
(
1
<<
(
C_SIZE_MULT
+
2
)));
msd
->
geometry
.
sector_count
=
card_capacity
/
msd
->
geometry
.
bytes_per_sector
;
MSD_DEBUG
(
"[info] card capacity : %d Mbyte
\r\n
"
,
card_capacity
/
(
1024
*
1024
));
}
else
if
(
CSD_STRUCTURE
==
1
)
{
MSD_DEBUG
(
"[info] CSD Version 2.0
\r\n
"
);
/* get TRAN_SPEED 8bit [103:96] */
tmp8
=
CSD_buffer
[
3
];
if
(
tmp8
==
0x32
)
{
msd
->
max_clock
=
1000
*
1000
*
10
;
/* 10Mbit/s. */
}
else
if
(
tmp8
==
0x5A
)
{
msd
->
max_clock
=
1000
*
1000
*
50
;
/* 50Mbit/s. */
}
else
if
(
tmp8
==
0x0B
)
{
msd
->
max_clock
=
1000
*
1000
*
100
;
/* 100Mbit/s. */
/* UHS50 Card sets TRAN_SPEED to 0Bh (100Mbit/sec), */
/* for both SDR50 and DDR50 modes. */
}
else
if
(
tmp8
==
0x2B
)
{
msd
->
max_clock
=
1000
*
1000
*
200
;
/* 200Mbit/s. */
/* UHS104 Card sets TRAN_SPEED to 2Bh (200Mbit/sec). */
}
else
{
msd
->
max_clock
=
1000
*
1000
*
1
;
/* 1Mbit/s default. */
}
MSD_DEBUG
(
"[info] TRAN_SPEED: 0x%02X, %dMbit/s.
\r\n
"
,
tmp8
,
msd
->
max_clock
/
1000
/
1000
);
/* get C_SIZE 22bit [69:48] */
tmp32
=
CSD_buffer
[
7
]
&
0x3F
;
/* 0b00111111 */
tmp32
=
tmp32
<<
8
;
tmp32
+=
CSD_buffer
[
8
];
tmp32
=
tmp32
<<
8
;
tmp32
+=
CSD_buffer
[
9
];
C_SIZE
=
tmp32
;
MSD_DEBUG
(
"[info] CSD : C_SIZE : %d
\r\n
"
,
C_SIZE
);
/* memory capacity = (C_SIZE+1) * 512K byte */
card_capacity
=
(
C_SIZE
+
1
)
/
2
;
/* unit : Mbyte */
msd
->
geometry
.
sector_count
=
card_capacity
*
1024
;
/* 1 Mbyte = 512 byte X 2048 */
MSD_DEBUG
(
"[info] card capacity : %d.%d Gbyte
\r\n
"
,
card_capacity
/
1024
,
(
card_capacity
%
1024
)
*
100
/
1024
);
}
else
{
MSD_DEBUG
(
"[err] bad CSD Version : %d
\r\n
"
,
CSD_STRUCTURE
);
result
=
RT_ERROR
;
goto
_exit
;
}
}
/* SD CSD Analyze. */
}
/* Analyze CSD */
}
/* read CSD */
/* config spi to high speed */
{
struct
rt_spi_configuration
cfg
;
cfg
.
data_width
=
8
;
cfg
.
mode
=
RT_SPI_MODE_0
|
RT_SPI_MSB
;
/* SPI Compatible Modes 0 */
cfg
.
max_hz
=
msd
->
max_clock
;
rt_spi_configure
(
msd
->
spi_device
,
&
cfg
);
}
/* config spi */
_exit:
MSD_release_cs
(
msd
->
spi_device
);
rt_mutex_release
(
&
(
msd
->
spi_device
->
bus
->
lock
));
return
result
;
}
static
rt_err_t
rt_msd_open
(
rt_device_t
dev
,
rt_uint16_t
oflag
)
{
// struct msd_device * msd = (struct msd_device *)dev;
return
RT_EOK
;
}
static
rt_err_t
rt_msd_close
(
rt_device_t
dev
)
{
// struct msd_device * msd = (struct msd_device *)dev;
return
RT_EOK
;
}
static
rt_size_t
rt_msd_read
(
rt_device_t
dev
,
rt_off_t
pos
,
void
*
buffer
,
rt_size_t
size
)
{
rt_uint8_t
status
;
rt_uint32_t
i
;
struct
msd_device
*
msd
=
(
struct
msd_device
*
)
dev
;
uint8_t
response
[
MSD_RESPONSE_MAX_LEN
];
rt_err_t
result
=
RT_EOK
;
result
=
MSD_take_owner
(
msd
->
spi_device
);
if
(
result
!=
RT_EOK
)
{
goto
_exit
;
}
status
=
MSD_RESPONSE_NO_ERROR
;
// rt_kprintf("read: 0x%x, size %d\n", pos, size);
/* config spi to high speed */
{
struct
rt_spi_configuration
cfg
;
cfg
.
data_width
=
8
;
cfg
.
mode
=
RT_SPI_MODE_0
|
RT_SPI_MSB
;
/* SPI Compatible Modes 0 */
cfg
.
max_hz
=
msd
->
max_clock
;
rt_spi_configure
(
msd
->
spi_device
,
&
cfg
);
}
/* config spi */
/* SINGLE_BLOCK? */
if
(
size
==
1
)
{
MSD_take_cs
(
msd
->
spi_device
);
/* read all sectors */
for
(
i
=
0
;
i
<
size
;
i
++
)
result
=
_send_cmd
(
msd
->
spi_device
,
READ_SINGLE_BLOCK
,
pos
*
msd
->
geometry
.
bytes_per_sector
,
0x00
,
response_r1
,
response
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
)
)
{
status
=
MSD_ReadBlock
((
rt_uint8_t
*
)((
rt_uint8_t
*
)
buffer
+
i
*
SECTOR_SIZE
),
(
part
.
offset
+
pos
+
i
)
*
SECTOR_SIZE
,
SECTOR_SIZE
);
if
(
status
!=
MSD_RESPONSE_NO_ERROR
)
MSD_DEBUG
(
"[err] read SINGLE_BLOCK #%d fail!
\r\n
"
,
pos
);
size
=
0
;
goto
_exit
;
}
result
=
_read_block
(
msd
->
spi_device
,
buffer
,
msd
->
geometry
.
bytes_per_sector
);
if
(
result
!=
RT_EOK
)
{
rt_kprintf
(
"sd card read failed
\n
"
);
return
0
;
MSD_DEBUG
(
"[err] read SINGLE_BLOCK #%d fail!
\r\n
"
,
pos
);
size
=
0
;
}
}
else
if
(
size
>
1
)
{
uint32_t
i
;
if
(
status
==
MSD_RESPONSE_NO_ERROR
)
return
size
;
MSD_take_cs
(
msd
->
spi_device
)
;
rt_kprintf
(
"read failed: %d
\n
"
,
status
);
return
0
;
result
=
_send_cmd
(
msd
->
spi_device
,
READ_MULTIPLE_BLOCK
,
pos
*
msd
->
geometry
.
bytes_per_sector
,
0x00
,
response_r1
,
response
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[err] read READ_MULTIPLE_BLOCK #%d fail!
\r\n
"
,
pos
);
size
=
0
;
goto
_exit
;
}
for
(
i
=
0
;
i
<
size
;
i
++
)
{
result
=
_read_block
(
msd
->
spi_device
,
(
uint8_t
*
)
buffer
+
msd
->
geometry
.
bytes_per_sector
*
i
,
msd
->
geometry
.
bytes_per_sector
);
if
(
result
!=
RT_EOK
)
{
MSD_DEBUG
(
"[err] read READ_MULTIPLE_BLOCK #%d fail!
\r\n
"
,
pos
);
size
=
i
;
break
;
}
}
/* send CMD12 stop transfer */
result
=
_send_cmd
(
msd
->
spi_device
,
STOP_TRANSMISSION
,
0x00
,
0x00
,
response_r1b
,
response
);
if
(
result
!=
RT_EOK
)
{
MSD_DEBUG
(
"[err] read READ_MULTIPLE_BLOCK, send stop token fail!
\r\n
"
);
}
}
/* READ_MULTIPLE_BLOCK */
_exit:
/* release and exit */
MSD_release_cs
(
msd
->
spi_device
);
rt_mutex_release
(
&
(
msd
->
spi_device
->
bus
->
lock
));
return
size
;
}
static
rt_size_t
rt_msd_
write
(
rt_device_t
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
static
rt_size_t
rt_msd_
sdhc_read
(
rt_device_t
dev
,
rt_off_t
pos
,
void
*
buffer
,
rt_size_t
size
)
{
rt_uint8_t
status
;
rt_uint32_t
i
;
struct
msd_device
*
msd
=
(
struct
msd_device
*
)
dev
;
uint8_t
response
[
MSD_RESPONSE_MAX_LEN
];
rt_err_t
result
=
RT_EOK
;
result
=
MSD_take_owner
(
msd
->
spi_device
);
if
(
result
!=
RT_EOK
)
{
goto
_exit
;
}
/* config spi to high speed */
{
struct
rt_spi_configuration
cfg
;
cfg
.
data_width
=
8
;
cfg
.
mode
=
RT_SPI_MODE_0
|
RT_SPI_MSB
;
/* SPI Compatible Modes 0 */
cfg
.
max_hz
=
msd
->
max_clock
;
rt_spi_configure
(
msd
->
spi_device
,
&
cfg
);
}
/* config spi */
/* SINGLE_BLOCK? */
if
(
size
==
1
)
{
MSD_take_cs
(
msd
->
spi_device
);
result
=
_send_cmd
(
msd
->
spi_device
,
READ_SINGLE_BLOCK
,
pos
,
0x00
,
response_r1
,
response
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[err] read SINGLE_BLOCK #%d fail!
\r\n
"
,
pos
);
size
=
0
;
goto
_exit
;
}
result
=
_read_block
(
msd
->
spi_device
,
buffer
,
msd
->
geometry
.
bytes_per_sector
);
if
(
result
!=
RT_EOK
)
{
MSD_DEBUG
(
"[err] read SINGLE_BLOCK #%d fail!
\r\n
"
,
pos
);
size
=
0
;
}
}
else
if
(
size
>
1
)
{
uint32_t
i
;
MSD_take_cs
(
msd
->
spi_device
);
status
=
MSD_RESPONSE_NO_ERROR
;
// rt_kprintf("write: 0x%x, size %d\n", pos, size);
result
=
_send_cmd
(
msd
->
spi_device
,
READ_MULTIPLE_BLOCK
,
pos
,
0x00
,
response_r1
,
response
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[err] read READ_MULTIPLE_BLOCK #%d fail!
\r\n
"
,
pos
);
size
=
0
;
goto
_exit
;
}
/* write all sectors */
for
(
i
=
0
;
i
<
size
;
i
++
)
for
(
i
=
0
;
i
<
size
;
i
++
)
{
status
=
MSD_WriteBuffer
((
rt_uint8_t
*
)((
rt_uint8_t
*
)
buffer
+
i
*
SECTOR_SIZE
),
(
part
.
offset
+
pos
+
i
)
*
SECTOR_SIZE
,
SECTOR_SIZE
);
if
(
status
!=
MSD_RESPONSE_NO_ERROR
)
result
=
_read_block
(
msd
->
spi_device
,
(
uint8_t
*
)
buffer
+
msd
->
geometry
.
bytes_per_sector
*
i
,
msd
->
geometry
.
bytes_per_sector
);
if
(
result
!=
RT_EOK
)
{
rt_kprintf
(
"sd card write failed
\n
"
);
return
0
;
MSD_DEBUG
(
"[err] read READ_MULTIPLE_BLOCK #%d fail!
\r\n
"
,
pos
);
size
=
i
;
break
;
}
}
/* send CMD12 stop transfer */
result
=
_send_cmd
(
msd
->
spi_device
,
STOP_TRANSMISSION
,
0x00
,
0x00
,
response_r1b
,
response
);
if
(
result
!=
RT_EOK
)
{
MSD_DEBUG
(
"[err] read READ_MULTIPLE_BLOCK, send stop token fail!
\r\n
"
);
}
}
/* READ_MULTIPLE_BLOCK */
if
(
status
==
MSD_RESPONSE_NO_ERROR
)
return
size
;
_exit:
/* release and exit */
MSD_release_cs
(
msd
->
spi_device
);
rt_mutex_release
(
&
(
msd
->
spi_device
->
bus
->
lock
));
rt_kprintf
(
"write failed: %d
\n
"
,
status
);
return
0
;
return
size
;
}
static
rt_
err_t
rt_msd_control
(
rt_device_t
dev
,
rt_uint8_t
cmd
,
void
*
args
)
static
rt_
size_t
rt_msd_write
(
rt_device_t
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
{
RT_ASSERT
(
dev
!=
RT_NULL
);
struct
msd_device
*
msd
=
(
struct
msd_device
*
)
dev
;
uint8_t
response
[
MSD_RESPONSE_MAX_LEN
];
rt_err_t
result
;
return
RT_EOK
;
result
=
MSD_take_owner
(
msd
->
spi_device
);
if
(
result
!=
RT_EOK
)
{
MSD_DEBUG
(
"[err] get SPI owner fail!
\r\n
"
);
goto
_exit
;
}
/* config spi to high speed */
{
struct
rt_spi_configuration
cfg
;
cfg
.
data_width
=
8
;
cfg
.
mode
=
RT_SPI_MODE_0
|
RT_SPI_MSB
;
/* SPI Compatible Modes 0 */
cfg
.
max_hz
=
msd
->
max_clock
;
rt_spi_configure
(
msd
->
spi_device
,
&
cfg
);
}
/* config spi */
/* SINGLE_BLOCK? */
if
(
size
==
1
)
{
MSD_take_cs
(
msd
->
spi_device
);
result
=
_send_cmd
(
msd
->
spi_device
,
WRITE_BLOCK
,
pos
*
msd
->
geometry
.
bytes_per_sector
,
0x00
,
response_r1
,
response
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[err] CMD WRITE_BLOCK fail!
\r\n
"
);
size
=
0
;
goto
_exit
;
}
result
=
_write_block
(
msd
->
spi_device
,
buffer
,
msd
->
geometry
.
bytes_per_sector
,
MSD_TOKEN_WRITE_SINGLE_START
);
if
(
result
!=
RT_EOK
)
{
MSD_DEBUG
(
"[err] write SINGLE_BLOCK #%d fail!
\r\n
"
,
pos
);
size
=
0
;
}
}
else
if
(
size
>
1
)
{
struct
rt_spi_message
message
;
uint32_t
i
;
MSD_take_cs
(
msd
->
spi_device
);
#ifdef MSD_USE_PRE_ERASED
if
(
msd
->
card_type
!=
MSD_CARD_TYPE_MMC
)
{
/* CMD55 APP_CMD */
result
=
_send_cmd
(
msd
->
spi_device
,
APP_CMD
,
0x00
,
0x00
,
response_r1
,
response
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[err] CMD55 APP_CMD fail!
\r\n
"
);
size
=
0
;
goto
_exit
;
}
/* ACMD23 Pre-erased */
result
=
_send_cmd
(
msd
->
spi_device
,
SET_WR_BLK_ERASE_COUNT
,
size
,
0x00
,
response_r1
,
response
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[err] ACMD23 SET_BLOCK_COUNT fail!
\r\n
"
);
size
=
0
;
goto
_exit
;
}
}
#endif
result
=
_send_cmd
(
msd
->
spi_device
,
WRITE_MULTIPLE_BLOCK
,
pos
*
msd
->
geometry
.
bytes_per_sector
,
0x00
,
response_r1
,
response
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[err] CMD WRITE_MULTIPLE_BLOCK fail!
\r\n
"
);
size
=
0
;
goto
_exit
;
}
/* write all block */
for
(
i
=
0
;
i
<
size
;
i
++
)
{
result
=
_write_block
(
msd
->
spi_device
,
(
const
uint8_t
*
)
buffer
+
msd
->
geometry
.
bytes_per_sector
*
i
,
msd
->
geometry
.
bytes_per_sector
,
MSD_TOKEN_WRITE_MULTIPLE_START
);
if
(
result
!=
RT_EOK
)
{
MSD_DEBUG
(
"[err] write SINGLE_BLOCK #%d fail!
\r\n
"
,
pos
);
size
=
i
;
break
;
}
}
/* write all block */
/* send stop token */
{
uint8_t
send_buffer
[
18
];
rt_memset
(
send_buffer
,
DUMMY
,
sizeof
(
send_buffer
));
send_buffer
[
sizeof
(
send_buffer
)
-
1
]
=
MSD_TOKEN_WRITE_MULTIPLE_STOP
;
/* initial message */
message
.
send_buf
=
send_buffer
;
message
.
recv_buf
=
RT_NULL
;
message
.
length
=
sizeof
(
send_buffer
);
message
.
cs_take
=
message
.
cs_release
=
0
;
/* transfer message */
msd
->
spi_device
->
bus
->
ops
->
xfer
(
msd
->
spi_device
,
&
message
);
}
/* wait ready */
result
=
_wait_ready
(
msd
->
spi_device
);
if
(
result
!=
RT_EOK
)
{
MSD_DEBUG
(
"[warning] wait WRITE_MULTIPLE_BLOCK stop token ready timeout!
\r\n
"
);
}
}
/* size > 1 */
_exit:
/* release and exit */
MSD_release_cs
(
msd
->
spi_device
);
rt_mutex_release
(
&
(
msd
->
spi_device
->
bus
->
lock
));
return
size
;
}
void
rt_hw_msd_init
(
)
static
rt_size_t
rt_msd_sdhc_write
(
rt_device_t
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
{
if
(
MSD_Init
()
==
MSD_RESPONSE_NO_ERROR
)
struct
msd_device
*
msd
=
(
struct
msd_device
*
)
dev
;
uint8_t
response
[
MSD_RESPONSE_MAX_LEN
];
rt_err_t
result
;
result
=
MSD_take_owner
(
msd
->
spi_device
);
if
(
result
!=
RT_EOK
)
{
rt_uint8_t
status
;
rt_uint8_t
*
sector
;
goto
_exit
;
}
/* register sdcard device */
sdcard_device
.
init
=
rt_msd_init
;
sdcard_device
.
open
=
rt_msd_open
;
sdcard_device
.
close
=
rt_msd_close
;
sdcard_device
.
read
=
rt_msd_read
;
sdcard_device
.
write
=
rt_msd_write
;
sdcard_device
.
control
=
rt_msd_control
;
/* config spi to high speed */
{
struct
rt_spi_configuration
cfg
;
cfg
.
data_width
=
8
;
cfg
.
mode
=
RT_SPI_MODE_0
|
RT_SPI_MSB
;
/* SPI Compatible Modes 0 */
cfg
.
max_hz
=
msd
->
max_clock
;
rt_spi_configure
(
msd
->
spi_device
,
&
cfg
);
}
/* config spi */
/* no private */
sdcard_device
.
user_data
=
RT_NULL
;
/* get the first sector to read partition table */
sector
=
(
rt_uint8_t
*
)
rt_malloc
(
512
);
if
(
sector
==
RT_NULL
)
/* SINGLE_BLOCK? */
if
(
size
==
1
)
{
rt_kprintf
(
"allocate partition sector buffer failed
\n
"
);
return
;
MSD_take_cs
(
msd
->
spi_device
);
result
=
_send_cmd
(
msd
->
spi_device
,
WRITE_BLOCK
,
pos
,
0x00
,
response_r1
,
response
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[err] CMD WRITE_BLOCK fail!
\r\n
"
);
size
=
0
;
goto
_exit
;
}
status
=
MSD_ReadBlock
(
sector
,
0
,
512
);
if
(
status
==
MSD_RESPONSE_NO_ERROR
)
result
=
_write_block
(
msd
->
spi_device
,
buffer
,
msd
->
geometry
.
bytes_per_sector
,
MSD_TOKEN_WRITE_SINGLE_START
);
if
(
result
!=
RT_EOK
)
{
/* get the first partition */
status
=
dfs_filesystem_get_partition
(
&
part
,
sector
,
0
);
if
(
status
!=
RT_EOK
)
MSD_DEBUG
(
"[err] write SINGLE_BLOCK #%d fail!
\r\n
"
,
pos
);
size
=
0
;
}
}
else
if
(
size
>
1
)
{
/* there is no partition table */
part
.
offset
=
0
;
part
.
size
=
0
;
struct
rt_spi_message
message
;
uint32_t
i
;
MSD_take_cs
(
msd
->
spi_device
);
#ifdef MSD_USE_PRE_ERASED
/* CMD55 APP_CMD */
result
=
_send_cmd
(
msd
->
spi_device
,
APP_CMD
,
0x00
,
0x00
,
response_r1
,
response
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[err] CMD55 APP_CMD fail!
\r\n
"
);
size
=
0
;
goto
_exit
;
}
/* ACMD23 Pre-erased */
result
=
_send_cmd
(
msd
->
spi_device
,
SET_WR_BLK_ERASE_COUNT
,
size
,
0x00
,
response_r1
,
response
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
MSD_DEBUG
(
"[err] ACMD23 SET_BLOCK_COUNT fail!
\r\n
"
);
size
=
0
;
goto
_exit
;
}
else
#endif
result
=
_send_cmd
(
msd
->
spi_device
,
WRITE_MULTIPLE_BLOCK
,
pos
,
0x00
,
response_r1
,
response
);
if
((
result
!=
RT_EOK
)
||
(
response
[
0
]
!=
MSD_RESPONSE_NO_ERROR
))
{
/* there is no partition table */
part
.
offset
=
0
;
part
.
size
=
0
;
MSD_DEBUG
(
"[err] CMD WRITE_MULTIPLE_BLOCK fail!
\r\n
"
);
size
=
0
;
goto
_exit
;
}
/* release sector buffer */
rt_free
(
sector
);
/* write all block */
for
(
i
=
0
;
i
<
size
;
i
++
)
{
result
=
_write_block
(
msd
->
spi_device
,
(
const
uint8_t
*
)
buffer
+
msd
->
geometry
.
bytes_per_sector
*
i
,
msd
->
geometry
.
bytes_per_sector
,
MSD_TOKEN_WRITE_MULTIPLE_START
);
if
(
result
!=
RT_EOK
)
{
MSD_DEBUG
(
"[err] write MULTIPLE_BLOCK #%d fail!
\r\n
"
,
pos
);
size
=
i
;
break
;
}
}
/* write all block */
rt_device_register
(
&
sdcard_device
,
"sd0"
,
RT_DEVICE_FLAG_RDWR
|
RT_DEVICE_FLAG_REMOVABLE
|
RT_DEVICE_FLAG_STANDALONE
);
/* send stop token */
{
uint8_t
send_buffer
[
18
];
rt_memset
(
send_buffer
,
DUMMY
,
sizeof
(
send_buffer
));
send_buffer
[
sizeof
(
send_buffer
)
-
1
]
=
MSD_TOKEN_WRITE_MULTIPLE_STOP
;
/* initial message */
message
.
send_buf
=
send_buffer
;
message
.
recv_buf
=
RT_NULL
;
message
.
length
=
sizeof
(
send_buffer
);
message
.
cs_take
=
message
.
cs_release
=
0
;
/* transfer message */
msd
->
spi_device
->
bus
->
ops
->
xfer
(
msd
->
spi_device
,
&
message
);
}
else
result
=
_wait_ready
(
msd
->
spi_device
);
if
(
result
!=
RT_EOK
)
{
MSD_DEBUG
(
"[warning] wait WRITE_MULTIPLE_BLOCK stop token ready timeout!
\r\n
"
);
}
}
/* size > 1 */
_exit:
/* release and exit */
MSD_release_cs
(
msd
->
spi_device
);
rt_mutex_release
(
&
(
msd
->
spi_device
->
bus
->
lock
));
return
size
;
}
static
rt_err_t
rt_msd_control
(
rt_device_t
dev
,
rt_uint8_t
cmd
,
void
*
args
)
{
struct
msd_device
*
msd
=
(
struct
msd_device
*
)
dev
;
RT_ASSERT
(
dev
!=
RT_NULL
);
if
(
cmd
==
RT_DEVICE_CTRL_BLK_GETGEOME
)
{
rt_kprintf
(
"sdcard init failed
\n
"
);
struct
rt_device_blk_geometry
*
geometry
;
geometry
=
(
struct
rt_device_blk_geometry
*
)
args
;
if
(
geometry
==
RT_NULL
)
return
-
RT_ERROR
;
geometry
->
bytes_per_sector
=
msd
->
geometry
.
bytes_per_sector
;
geometry
->
block_size
=
msd
->
geometry
.
block_size
;
geometry
->
sector_count
=
msd
->
geometry
.
sector_count
;
}
return
RT_EOK
;
}
rt_err_t
msd_init
(
const
char
*
sd_device_name
,
const
char
*
spi_device_name
)
{
rt_err_t
result
=
RT_EOK
;
struct
rt_spi_device
*
spi_device
;
spi_device
=
(
struct
rt_spi_device
*
)
rt_device_find
(
spi_device_name
);
if
(
spi_device
==
RT_NULL
)
{
MSD_DEBUG
(
"spi device %s not found!
\r\n
"
,
spi_device_name
);
return
-
RT_ENOSYS
;
}
rt_memset
(
&
_msd_device
,
0
,
sizeof
(
_msd_device
));
_msd_device
.
spi_device
=
spi_device
;
/* register sdcard device */
_msd_device
.
parent
.
type
=
RT_Device_Class_Block
;
_msd_device
.
geometry
.
bytes_per_sector
=
0
;
_msd_device
.
geometry
.
sector_count
=
0
;
_msd_device
.
geometry
.
block_size
=
0
;
_msd_device
.
parent
.
init
=
rt_msd_init
;
_msd_device
.
parent
.
open
=
rt_msd_open
;
_msd_device
.
parent
.
close
=
rt_msd_close
;
_msd_device
.
parent
.
read
=
RT_NULL
;
_msd_device
.
parent
.
write
=
RT_NULL
;
_msd_device
.
parent
.
control
=
rt_msd_control
;
/* no private, no callback */
_msd_device
.
parent
.
user_data
=
RT_NULL
;
_msd_device
.
parent
.
rx_indicate
=
RT_NULL
;
_msd_device
.
parent
.
tx_complete
=
RT_NULL
;
result
=
rt_device_register
(
&
_msd_device
.
parent
,
sd_device_name
,
RT_DEVICE_FLAG_RDWR
|
RT_DEVICE_FLAG_REMOVABLE
|
RT_DEVICE_FLAG_STANDALONE
);
return
result
;
}
bsp/stm32f107/drivers/msd.h
浏览文件 @
8421ecfa
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : msd.h
* Author : MCD Application Team
* Version : V2.1
* Date : 05/30/2008
* Description : Header for msd.c file.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
* FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED
* IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MSD_H
#define __MSD_H
/* Includes ------------------------------------------------------------------*/
#include <stm32f10x.h>
/* Private define ------------------------------------------------------------*/
/* Block Size */
#define BLOCK_SIZE 512
/* Dummy byte */
#define DUMMY 0xFF
/*
* File : msd.h
* SPI mode SD Card Driver
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-04-17 Bernard first version.
*/
#ifndef MSD_H_INCLUDED
#define MSD_H_INCLUDED
#include <stdint.h>
#include <drivers/spi.h>
/* SD command (SPI mode) */
#define GO_IDLE_STATE 0
/* CMD0 R1 */
#define SEND_OP_COND 1
/* CMD1 R1 */
#define SWITCH_FUNC 6
/* CMD6 R1 */
#define SEND_IF_COND 8
/* CMD8 R7 */
#define SEND_CSD 9
/* CMD9 R1 */
#define SEND_CID 10
/* CMD10 R1 */
#define STOP_TRANSMISSION 12
/* CMD12 R1B */
#define SEND_STATUS 13
/* CMD13 R2 */
#define SET_BLOCKLEN 16
/* CMD16 R1 */
#define READ_SINGLE_BLOCK 17
/* CMD17 R1 */
#define READ_MULTIPLE_BLOCK 18
/* CMD18 R1 */
#define WRITE_BLOCK 24
/* CMD24 R1 */
#define WRITE_MULTIPLE_BLOCK 25
/* CMD25 R1 */
#define PROGRAM_CSD 27
/* CMD27 R1 */
#define SET_WRITE_PROT 28
/* CMD28 R1B */
#define CLR_WRITE_PROT 29
/* CMD29 R1B */
#define SEND_WRITE_PROT 30
/* CMD30 R1 */
#define ERASE_WR_BLK_START_ADDR 32
/* CMD32 R1 */
#define ERASE_WR_BLK_END_ADDR 33
/* CMD33 R1 */
#define ERASE 38
/* CMD38 R1B */
#define LOCK_UNLOCK 42
/* CMD42 R1 */
#define APP_CMD 55
/* CMD55 R1 */
#define GEN_CMD 56
/* CMD56 R1 */
#define READ_OCR 58
/* CMD58 R3 */
#define CRC_ON_OFF 59
/* CMD59 R1 */
/* Application-Specific Command */
#define SD_STATUS 13
/* ACMD13 R2 */
#define SEND_NUM_WR_BLOCKS 22
/* ACMD22 R1 */
#define SET_WR_BLK_ERASE_COUNT 23
/* ACMD23 R1 */
#define SD_SEND_OP_COND 41
/* ACMD41 R1 */
#define SET_CLR_CARD_DETECT 42
/* ACMD42 R1 */
#define SEND_SCR 51
/* ACMD51 R1 */
/* Start Data tokens */
/* Tokens (necessary because at nop/idle (and CS active) only 0xff is on the data/command line) */
#define MSD_START_DATA_SINGLE_BLOCK_READ 0xFE
/* Data token start byte, Start Single Block Read */
#define MSD_START_DATA_MULTIPLE_BLOCK_READ 0xFE
/* Data token start byte, Start Multiple Block Read */
#define MSD_START_DATA_SINGLE_BLOCK_WRITE 0xFE
/* Data token start byte, Start Single Block Write */
#define MSD_START_DATA_MULTIPLE_BLOCK_WRITE 0xFD
/* Data token start byte, Start Multiple Block Write */
#define MSD_STOP_DATA_MULTIPLE_BLOCK_WRITE 0xFD
/* Data toke stop byte, Stop Multiple Block Write */
#define MSD_TOKEN_READ_START 0xFE
/* Data token start byte, Start Single Block Read */
#define MSD_TOKEN_WRITE_SINGLE_START 0xFE
/* Data token start byte, Start Single Block Write */
/* MSD functions return */
#define MSD_SUCCESS 0x00
#define MSD_FAIL 0xFF
#define MSD_TOKEN_WRITE_MULTIPLE_START 0xFC
/* Data token start byte, Start Multiple Block Write */
#define MSD_TOKEN_WRITE_MULTIPLE_STOP 0xFD
/* Data toke stop byte, Stop Multiple Block Write */
/* MSD reponses and error flags */
#define MSD_RESPONSE_NO_ERROR 0x00
...
...
@@ -57,117 +78,55 @@
#define MSD_DATA_CRC_ERROR 0x0B
#define MSD_DATA_WRITE_ERROR 0x0D
#define MSD_DATA_OTHER_ERROR 0xFF
#define MSD_DATA_RESPONSE_MASK 0x1F
#define MSD_GET_DATA_RESPONSE(res) (res & MSD_DATA_RESPONSE_MASK)
/* Commands: CMDxx = CMD-number | 0x40 */
#define MSD_GO_IDLE_STATE 0
/* CMD0=0x40 */
#define MSD_SEND_OP_COND 1
/* CMD1=0x41 */
#define MSD_SEND_CSD 9
/* CMD9=0x49 */
#define MSD_SEND_CID 10
/* CMD10=0x4A */
#define MSD_STOP_TRANSMISSION 12
/* CMD12=0x4C */
#define MSD_SEND_STATUS 13
/* CMD13=0x4D */
#define MSD_SET_BLOCKLEN 16
/* CMD16=0x50 */
#define MSD_READ_SINGLE_BLOCK 17
/* CMD17=0x51 */
#define MSD_READ_MULTIPLE_BLOCK 18
/* CMD18=0x52 */
#define MSD_SET_BLOCK_COUNT 23
/* CMD23=0x57 */
#define MSD_WRITE_BLOCK 24
/* CMD24=0x58 */
#define MSD_WRITE_MULTIPLE_BLOCK 25
/* CMD25=0x59 */
#define MSD_PROGRAM_CSD 27
/* CMD27=0x5B */
#define MSD_SET_WRITE_PROT 28
/* CMD28=0x5C */
#define MSD_CLR_WRITE_PROT 29
/* CMD29=0x5D */
#define MSD_SEND_WRITE_PROT 30
/* CMD30=0x5E */
#define MSD_TAG_SECTOR_START 32
/* CMD32=0x60 */
#define MSD_TAG_SECTOR_END 33
/* CMD33=0x61 */
#define MSD_UNTAG_SECTOR 34
/* CMD34=0x62 */
#define MSD_TAG_ERASE_GROUP_START 35
/* CMD35=0x63 */
#define MSD_TAG_ERASE_GROUP_END 36
/* CMD36=0x64 */
#define MSD_UNTAG_ERASE_GROUP 37
/* CMD37=0x65 */
#define MSD_ERASE 38
/* CMD38=0x66 */
#define MSD_READ_OCR 39
/* CMD39=0x67 */
#define MSD_CRC_ON_OFF 40
/* CMD40=0x68 */
/* Exported types ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
typedef
struct
_MSD_CSD
/*Card Specific Data*/
#define MSD_CMD_LEN 6
/**< command, arg and crc. */
#define MSD_RESPONSE_MAX_LEN 5
/**< response max len */
#define MSD_CSD_LEN 16
/**< SD crad CSD register len */
#define SECTOR_SIZE 512
/**< sector size, default 512byte */
/* card try timeout, unit: ms */
#define CARD_TRY_TIMES 3000
#define CARD_TRY_TIMES_ACMD41 800
#define CARD_WAIT_TOKEN_TIMES 800
#define MSD_USE_PRE_ERASED
/**< id define MSD_USE_PRE_ERASED, before CMD25, send ACMD23 */
/**
* SD/MMC card type
*/
typedef
enum
{
vu8
CSDStruct
;
/* CSD structure */
vu8
SysSpecVersion
;
/* System specification version */
vu8
Reserved1
;
/* Reserved */
vu8
TAAC
;
/* Data read access-time 1 */
vu8
NSAC
;
/* Data read access-time 2 in CLK cycles */
vu8
MaxBusClkFrec
;
/* Max. bus clock frequency */
vu16
CardComdClasses
;
/* Card command classes */
vu8
RdBlockLen
;
/* Max. read data block length */
vu8
PartBlockRead
;
/* Partial blocks for read allowed */
vu8
WrBlockMisalign
;
/* Write block misalignment */
vu8
RdBlockMisalign
;
/* Read block misalignment */
vu8
DSRImpl
;
/* DSR implemented */
vu8
Reserved2
;
/* Reserved */
vu16
DeviceSize
;
/* Device Size */
vu8
MaxRdCurrentVDDMin
;
/* Max. read current @ VDD min */
vu8
MaxRdCurrentVDDMax
;
/* Max. read current @ VDD max */
vu8
MaxWrCurrentVDDMin
;
/* Max. write current @ VDD min */
vu8
MaxWrCurrentVDDMax
;
/* Max. write current @ VDD max */
vu8
DeviceSizeMul
;
/* Device size multiplier */
vu8
EraseGrSize
;
/* Erase group size */
vu8
EraseGrMul
;
/* Erase group size multiplier */
vu8
WrProtectGrSize
;
/* Write protect group size */
vu8
WrProtectGrEnable
;
/* Write protect group enable */
vu8
ManDeflECC
;
/* Manufacturer default ECC */
vu8
WrSpeedFact
;
/* Write speed factor */
vu8
MaxWrBlockLen
;
/* Max. write data block length */
vu8
WriteBlockPaPartial
;
/* Partial blocks for write allowed */
vu8
Reserved3
;
/* Reserded */
vu8
ContentProtectAppli
;
/* Content protection application */
vu8
FileFormatGrouop
;
/* File format group */
vu8
CopyFlag
;
/* Copy flag (OTP) */
vu8
PermWrProtect
;
/* Permanent write protection */
vu8
TempWrProtect
;
/* Temporary write protection */
vu8
FileFormat
;
/* File Format */
vu8
ECC
;
/* ECC code */
vu8
msd_CRC
;
/* CRC */
vu8
Reserved4
;
/* always 1*/
}
sMSD_CSD
;
typedef
struct
_MSD_CID
/*Card Identification Data*/
MSD_CARD_TYPE_UNKNOWN
=
0
,
/**< unknown */
MSD_CARD_TYPE_MMC
,
/**< MultiMedia Card */
MSD_CARD_TYPE_SD_V1_X
,
/**< Ver 1.X Standard Capacity SD Memory Card */
MSD_CARD_TYPE_SD_V2_X
,
/**< Ver 2.00 or later Standard Capacity SD Memory Card */
MSD_CARD_TYPE_SD_SDHC
,
/**< High Capacity SD Memory Card */
MSD_CARD_TYPE_SD_SDXC
,
/**< later Extended Capacity SD Memory Card */
}
msd_card_type
;
typedef
enum
{
vu8
ManufacturerID
;
/* ManufacturerID */
vu16
OEM_AppliID
;
/* OEM/Application ID */
vu32
ProdName1
;
/* Product Name part1 */
vu8
ProdName2
;
/* Product Name part2*/
vu8
ProdRev
;
/* Product Revision */
vu32
ProdSN
;
/* Product Serial Number */
vu8
Reserved1
;
/* Reserved1 */
vu16
ManufactDate
;
/* Manufacturing Date */
vu8
msd_CRC
;
/* CRC */
vu8
Reserved2
;
/* always 1*/
}
sMSD_CID
;
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/*----- High layer function -----*/
u8
MSD_Init
(
void
);
u8
MSD_WriteBlock
(
u8
*
pBuffer
,
u32
WriteAddr
,
u16
NumByteToWrite
);
u8
MSD_ReadBlock
(
u8
*
pBuffer
,
u32
ReadAddr
,
u16
NumByteToRead
);
u8
MSD_WriteBuffer
(
u8
*
pBuffer
,
u32
WriteAddr
,
u32
NumByteToWrite
);
u8
MSD_ReadBuffer
(
u8
*
pBuffer
,
u32
ReadAddr
,
u32
NumByteToRead
);
u8
MSD_GetCSDRegister
(
sMSD_CSD
*
MSD_csd
);
u8
MSD_GetCIDRegister
(
sMSD_CID
*
MSD_cid
);
/*----- Medium layer function -----*/
void
MSD_SendCmd
(
u8
Cmd
,
u32
Arg
,
u8
Crc
);
u8
MSD_GetResponse
(
u8
Response
);
u8
MSD_GetDataResponse
(
void
);
u8
MSD_GoIdleState
(
void
);
u16
MSD_GetStatus
(
void
);
/*----- Low layer function -----*/
u8
MSD_WriteByte
(
u8
byte
);
u8
MSD_ReadByte
(
void
);
#endif
/* __MSD_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
response_type_unknown
=
0
,
response_r1
,
response_r1b
,
response_r2
,
response_r3
,
response_r4
,
response_r5
,
response_r7
,
}
response_type
;
struct
msd_device
{
struct
rt_device
parent
;
/**< RT-Thread device struct */
struct
rt_device_blk_geometry
geometry
;
/**< sector size, sector count */
struct
rt_spi_device
*
spi_device
;
/**< SPI interface */
msd_card_type
card_type
;
/**< card type: MMC SD1.x SD2.0 SDHC SDXC */
uint32_t
max_clock
;
/**< MAX SPI clock */
};
extern
rt_err_t
msd_init
(
const
char
*
sd_device_name
,
const
char
*
spi_device_name
);
#endif // MSD_H_INCLUDED
bsp/stm32f107/drivers/platform.c
浏览文件 @
8421ecfa
...
...
@@ -5,18 +5,98 @@
#include "stm32_eth.h"
#endif
/* RT_USING_LWIP */
#ifdef RT_USING_SPI
#include "rt_stm32f10x_spi.h"
#if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT)
#include "msd.h"
#endif
/* RT_USING_DFS */
/*
* SPI1_MOSI: PA7
* SPI1_MISO: PA6
* SPI1_SCK : PA5
*
* CS0: PA4 SD card.
*/
static
void
rt_hw_spi_init
(
void
)
{
#ifdef RT_USING_SPI1
/* register spi bus */
{
static
struct
stm32_spi_bus
stm32_spi
;
GPIO_InitTypeDef
GPIO_InitStructure
;
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_GPIOA
|
RCC_APB2Periph_AFIO
,
ENABLE
);
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_5
|
GPIO_Pin_6
|
GPIO_Pin_7
;
GPIO_InitStructure
.
GPIO_Speed
=
GPIO_Speed_50MHz
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_AF_PP
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStructure
);
stm32_spi_register
(
SPI1
,
&
stm32_spi
,
"spi1"
);
}
/* attach cs */
{
static
struct
rt_spi_device
spi_device
;
static
struct
stm32_spi_cs
spi_cs
;
GPIO_InitTypeDef
GPIO_InitStructure
;
GPIO_InitStructure
.
GPIO_Speed
=
GPIO_Speed_10MHz
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_Out_PP
;
/* spi21: PG10 */
spi_cs
.
GPIOx
=
GPIOA
;
spi_cs
.
GPIO_Pin
=
GPIO_Pin_4
;
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_GPIOA
,
ENABLE
);
GPIO_InitStructure
.
GPIO_Pin
=
spi_cs
.
GPIO_Pin
;
GPIO_SetBits
(
spi_cs
.
GPIOx
,
spi_cs
.
GPIO_Pin
);
GPIO_Init
(
spi_cs
.
GPIOx
,
&
GPIO_InitStructure
);
rt_spi_bus_attach_device
(
&
spi_device
,
"spi10"
,
"spi1"
,
(
void
*
)
&
spi_cs
);
}
#endif
/* RT_USING_SPI1 */
}
#endif
/* RT_USING_SPI */
void
rt_platform_init
(
void
)
{
#ifdef RT_USING_LWIP
/* initialize eth interface */
rt_hw_stm32_eth_init
();
#endif
/* RT_USING_LWIP */
#ifdef RT_USING_SPI
rt_hw_spi_init
();
#if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT)
/* init sdcard driver */
{
extern
void
rt_hw_msd_init
(
void
);
rt_hw_msd_init
();
GPIO_InitTypeDef
GPIO_InitStructure
;
/* PC4 : SD Power */
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_GPIOC
,
ENABLE
);
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_4
;
GPIO_InitStructure
.
GPIO_Speed
=
GPIO_Speed_10MHz
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_Out_PP
;
GPIO_Init
(
GPIOC
,
&
GPIO_InitStructure
);
/* SD card power on. */
GPIO_ResetBits
(
GPIOC
,
GPIO_Pin_4
);
rt_thread_delay
(
2
);
msd_init
(
"sd0"
,
"spi10"
);
}
#endif
/* RT_USING_DFS && RT_USING_DFS_ELMFAT */
#endif // RT_USING_SPI
#ifdef RT_USING_LWIP
/* initialize eth interface */
rt_hw_stm32_eth_init
();
#endif
/* RT_USING_LWIP */
}
bsp/stm32f107/drivers/rt_stm32f10x_spi.c
0 → 100644
浏览文件 @
8421ecfa
#include "rt_stm32f10x_spi.h"
static
rt_err_t
configure
(
struct
rt_spi_device
*
device
,
struct
rt_spi_configuration
*
configuration
);
static
rt_uint32_t
xfer
(
struct
rt_spi_device
*
device
,
struct
rt_spi_message
*
message
);
static
struct
rt_spi_ops
stm32_spi_ops
=
{
configure
,
xfer
};
#ifdef USING_SPI1
static
struct
stm32_spi_bus
stm32_spi_bus_1
;
#endif
/* #ifdef USING_SPI1 */
#ifdef USING_SPI2
static
struct
stm32_spi_bus
stm32_spi_bus_2
;
#endif
/* #ifdef USING_SPI2 */
#ifdef USING_SPI3
static
struct
stm32_spi_bus
stm32_spi_bus_3
;
#endif
/* #ifdef USING_SPI3 */
//------------------ DMA ------------------
#ifdef SPI_USE_DMA
static
uint8_t
dummy
=
0xFF
;
#endif
#ifdef SPI_USE_DMA
static
void
DMA_Configuration
(
struct
stm32_spi_bus
*
stm32_spi_bus
,
const
void
*
send_addr
,
void
*
recv_addr
,
rt_size_t
size
)
{
DMA_InitTypeDef
DMA_InitStructure
;
DMA_ClearFlag
(
stm32_spi_bus
->
DMA_Channel_RX_FLAG_TC
|
stm32_spi_bus
->
DMA_Channel_RX_FLAG_TE
|
stm32_spi_bus
->
DMA_Channel_TX_FLAG_TC
|
stm32_spi_bus
->
DMA_Channel_TX_FLAG_TE
);
/* RX channel configuration */
DMA_Cmd
(
stm32_spi_bus
->
DMA_Channel_RX
,
DISABLE
);
DMA_InitStructure
.
DMA_PeripheralBaseAddr
=
(
u32
)(
&
(
stm32_spi_bus
->
SPI
->
DR
));
DMA_InitStructure
.
DMA_DIR
=
DMA_DIR_PeripheralSRC
;
DMA_InitStructure
.
DMA_PeripheralInc
=
DMA_PeripheralInc_Disable
;
DMA_InitStructure
.
DMA_PeripheralDataSize
=
DMA_PeripheralDataSize_Byte
;
DMA_InitStructure
.
DMA_MemoryDataSize
=
DMA_MemoryDataSize_Byte
;
DMA_InitStructure
.
DMA_Priority
=
DMA_Priority_VeryHigh
;
DMA_InitStructure
.
DMA_Mode
=
DMA_Mode_Normal
;
DMA_InitStructure
.
DMA_M2M
=
DMA_M2M_Disable
;
DMA_InitStructure
.
DMA_BufferSize
=
size
;
if
(
recv_addr
!=
RT_NULL
)
{
DMA_InitStructure
.
DMA_MemoryBaseAddr
=
(
u32
)
recv_addr
;
DMA_InitStructure
.
DMA_MemoryInc
=
DMA_MemoryInc_Enable
;
}
else
{
DMA_InitStructure
.
DMA_MemoryBaseAddr
=
(
u32
)
(
&
dummy
);
DMA_InitStructure
.
DMA_MemoryInc
=
DMA_MemoryInc_Disable
;
}
DMA_Init
(
stm32_spi_bus
->
DMA_Channel_RX
,
&
DMA_InitStructure
);
DMA_Cmd
(
stm32_spi_bus
->
DMA_Channel_RX
,
ENABLE
);
/* TX channel configuration */
DMA_Cmd
(
stm32_spi_bus
->
DMA_Channel_TX
,
DISABLE
);
DMA_InitStructure
.
DMA_PeripheralBaseAddr
=
(
u32
)(
&
(
stm32_spi_bus
->
SPI
->
DR
));
DMA_InitStructure
.
DMA_DIR
=
DMA_DIR_PeripheralDST
;
DMA_InitStructure
.
DMA_PeripheralInc
=
DMA_PeripheralInc_Disable
;
DMA_InitStructure
.
DMA_PeripheralDataSize
=
DMA_PeripheralDataSize_Byte
;
DMA_InitStructure
.
DMA_MemoryDataSize
=
DMA_MemoryDataSize_Byte
;
DMA_InitStructure
.
DMA_Priority
=
DMA_Priority_Medium
;
DMA_InitStructure
.
DMA_Mode
=
DMA_Mode_Normal
;
DMA_InitStructure
.
DMA_M2M
=
DMA_M2M_Disable
;
DMA_InitStructure
.
DMA_BufferSize
=
size
;
if
(
send_addr
!=
RT_NULL
)
{
DMA_InitStructure
.
DMA_MemoryBaseAddr
=
(
u32
)
send_addr
;
DMA_InitStructure
.
DMA_MemoryInc
=
DMA_MemoryInc_Enable
;
}
else
{
DMA_InitStructure
.
DMA_MemoryBaseAddr
=
(
u32
)(
&
dummy
);;
DMA_InitStructure
.
DMA_MemoryInc
=
DMA_MemoryInc_Disable
;
}
DMA_Init
(
stm32_spi_bus
->
DMA_Channel_TX
,
&
DMA_InitStructure
);
DMA_Cmd
(
stm32_spi_bus
->
DMA_Channel_TX
,
ENABLE
);
}
#endif
rt_inline
uint16_t
get_spi_BaudRatePrescaler
(
rt_uint32_t
max_hz
)
{
uint16_t
SPI_BaudRatePrescaler
;
/* STM32F10x SPI MAX 18Mhz */
if
(
max_hz
>=
SystemCoreClock
/
2
&&
SystemCoreClock
/
2
<=
18000000
)
{
SPI_BaudRatePrescaler
=
SPI_BaudRatePrescaler_2
;
}
else
if
(
max_hz
>=
SystemCoreClock
/
4
)
{
SPI_BaudRatePrescaler
=
SPI_BaudRatePrescaler_4
;
}
else
if
(
max_hz
>=
SystemCoreClock
/
8
)
{
SPI_BaudRatePrescaler
=
SPI_BaudRatePrescaler_8
;
}
else
if
(
max_hz
>=
SystemCoreClock
/
16
)
{
SPI_BaudRatePrescaler
=
SPI_BaudRatePrescaler_16
;
}
else
if
(
max_hz
>=
SystemCoreClock
/
32
)
{
SPI_BaudRatePrescaler
=
SPI_BaudRatePrescaler_32
;
}
else
if
(
max_hz
>=
SystemCoreClock
/
64
)
{
SPI_BaudRatePrescaler
=
SPI_BaudRatePrescaler_64
;
}
else
if
(
max_hz
>=
SystemCoreClock
/
128
)
{
SPI_BaudRatePrescaler
=
SPI_BaudRatePrescaler_128
;
}
else
{
/* min prescaler 256 */
SPI_BaudRatePrescaler
=
SPI_BaudRatePrescaler_256
;
}
return
SPI_BaudRatePrescaler
;
}
static
rt_err_t
configure
(
struct
rt_spi_device
*
device
,
struct
rt_spi_configuration
*
configuration
)
{
struct
stm32_spi_bus
*
stm32_spi_bus
=
(
struct
stm32_spi_bus
*
)
device
->
bus
;
SPI_InitTypeDef
SPI_InitStructure
;
SPI_StructInit
(
&
SPI_InitStructure
);
/* data_width */
if
(
configuration
->
data_width
<=
8
)
{
SPI_InitStructure
.
SPI_DataSize
=
SPI_DataSize_8b
;
}
else
if
(
configuration
->
data_width
<=
16
)
{
SPI_InitStructure
.
SPI_DataSize
=
SPI_DataSize_16b
;
}
else
{
return
RT_EIO
;
}
/* baudrate */
SPI_InitStructure
.
SPI_BaudRatePrescaler
=
get_spi_BaudRatePrescaler
(
configuration
->
max_hz
);
/* CPOL */
if
(
configuration
->
mode
&
RT_SPI_CPOL
)
{
SPI_InitStructure
.
SPI_CPOL
=
SPI_CPOL_High
;
}
else
{
SPI_InitStructure
.
SPI_CPOL
=
SPI_CPOL_Low
;
}
/* CPHA */
if
(
configuration
->
mode
&
RT_SPI_CPHA
)
{
SPI_InitStructure
.
SPI_CPHA
=
SPI_CPHA_2Edge
;
}
else
{
SPI_InitStructure
.
SPI_CPHA
=
SPI_CPHA_1Edge
;
}
/* MSB or LSB */
if
(
configuration
->
mode
&
RT_SPI_MSB
)
{
SPI_InitStructure
.
SPI_FirstBit
=
SPI_FirstBit_MSB
;
}
else
{
SPI_InitStructure
.
SPI_FirstBit
=
SPI_FirstBit_LSB
;
}
SPI_InitStructure
.
SPI_Direction
=
SPI_Direction_2Lines_FullDuplex
;
SPI_InitStructure
.
SPI_Mode
=
SPI_Mode_Master
;
SPI_InitStructure
.
SPI_NSS
=
SPI_NSS_Soft
;
/* init SPI */
SPI_I2S_DeInit
(
stm32_spi_bus
->
SPI
);
SPI_Init
(
stm32_spi_bus
->
SPI
,
&
SPI_InitStructure
);
/* Enable SPI_MASTER */
SPI_Cmd
(
stm32_spi_bus
->
SPI
,
ENABLE
);
SPI_CalculateCRC
(
stm32_spi_bus
->
SPI
,
DISABLE
);
return
RT_EOK
;
};
static
rt_uint32_t
xfer
(
struct
rt_spi_device
*
device
,
struct
rt_spi_message
*
message
)
{
struct
stm32_spi_bus
*
stm32_spi_bus
=
(
struct
stm32_spi_bus
*
)
device
->
bus
;
struct
rt_spi_configuration
*
config
=
&
device
->
config
;
SPI_TypeDef
*
SPI
=
stm32_spi_bus
->
SPI
;
struct
stm32_spi_cs
*
stm32_spi_cs
=
device
->
parent
.
user_data
;
rt_uint32_t
size
=
message
->
length
;
/* take CS */
if
(
message
->
cs_take
)
{
GPIO_ResetBits
(
stm32_spi_cs
->
GPIOx
,
stm32_spi_cs
->
GPIO_Pin
);
}
#ifdef SPI_USE_DMA
if
(
message
->
length
>
32
)
{
if
(
config
->
data_width
<=
8
)
{
DMA_Configuration
(
stm32_spi_bus
,
message
->
send_buf
,
message
->
recv_buf
,
message
->
length
);
SPI_I2S_DMACmd
(
SPI
,
SPI_I2S_DMAReq_Tx
|
SPI_I2S_DMAReq_Rx
,
ENABLE
);
while
(
DMA_GetFlagStatus
(
stm32_spi_bus
->
DMA_Channel_RX_FLAG_TC
)
==
RESET
||
DMA_GetFlagStatus
(
stm32_spi_bus
->
DMA_Channel_TX_FLAG_TC
)
==
RESET
);
SPI_I2S_DMACmd
(
SPI
,
SPI_I2S_DMAReq_Tx
|
SPI_I2S_DMAReq_Rx
,
DISABLE
);
}
// rt_memcpy(buffer,_spi_flash_buffer,DMA_BUFFER_SIZE);
// buffer += DMA_BUFFER_SIZE;
}
else
#endif
{
if
(
config
->
data_width
<=
8
)
{
const
rt_uint8_t
*
send_ptr
=
message
->
send_buf
;
rt_uint8_t
*
recv_ptr
=
message
->
recv_buf
;
while
(
size
--
)
{
rt_uint8_t
data
=
0xFF
;
if
(
send_ptr
!=
RT_NULL
)
{
data
=
*
send_ptr
++
;
}
//Wait until the transmit buffer is empty
while
(
SPI_I2S_GetFlagStatus
(
SPI
,
SPI_I2S_FLAG_TXE
)
==
RESET
);
// Send the byte
SPI_I2S_SendData
(
SPI
,
data
);
//Wait until a data is received
while
(
SPI_I2S_GetFlagStatus
(
SPI
,
SPI_I2S_FLAG_RXNE
)
==
RESET
);
// Get the received data
data
=
SPI_I2S_ReceiveData
(
SPI
);
if
(
recv_ptr
!=
RT_NULL
)
{
*
recv_ptr
++
=
data
;
}
}
}
else
if
(
config
->
data_width
<=
16
)
{
const
rt_uint16_t
*
send_ptr
=
message
->
send_buf
;
rt_uint16_t
*
recv_ptr
=
message
->
recv_buf
;
while
(
size
--
)
{
rt_uint16_t
data
=
0xFF
;
if
(
send_ptr
!=
RT_NULL
)
{
data
=
*
send_ptr
++
;
}
//Wait until the transmit buffer is empty
while
(
SPI_I2S_GetFlagStatus
(
SPI
,
SPI_I2S_FLAG_TXE
)
==
RESET
);
// Send the byte
SPI_I2S_SendData
(
SPI
,
data
);
//Wait until a data is received
while
(
SPI_I2S_GetFlagStatus
(
SPI
,
SPI_I2S_FLAG_RXNE
)
==
RESET
);
// Get the received data
data
=
SPI_I2S_ReceiveData
(
SPI
);
if
(
recv_ptr
!=
RT_NULL
)
{
*
recv_ptr
++
=
data
;
}
}
}
}
/* release CS */
if
(
message
->
cs_release
)
{
GPIO_SetBits
(
stm32_spi_cs
->
GPIOx
,
stm32_spi_cs
->
GPIO_Pin
);
}
return
message
->
length
;
};
/** \brief init and register stm32 spi bus.
*
* \param SPI: STM32 SPI, e.g: SPI1,SPI2,SPI3.
* \param stm32_spi: stm32 spi bus struct.
* \param spi_bus_name: spi bus name, e.g: "spi1"
* \return
*
*/
rt_err_t
stm32_spi_register
(
SPI_TypeDef
*
SPI
,
struct
stm32_spi_bus
*
stm32_spi
,
const
char
*
spi_bus_name
)
{
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_AFIO
,
ENABLE
);
if
(
SPI
==
SPI1
)
{
stm32_spi
->
SPI
=
SPI1
;
#ifdef SPI_USE_DMA
/* Enable the DMA1 Clock */
RCC_AHBPeriphClockCmd
(
RCC_AHBPeriph_DMA1
,
ENABLE
);
stm32_spi
->
DMA_Channel_RX
=
DMA1_Channel2
;
stm32_spi
->
DMA_Channel_TX
=
DMA1_Channel3
;
stm32_spi
->
DMA_Channel_RX_FLAG_TC
=
DMA1_FLAG_TC2
;
stm32_spi
->
DMA_Channel_RX_FLAG_TE
=
DMA1_FLAG_TE2
;
stm32_spi
->
DMA_Channel_TX_FLAG_TC
=
DMA1_FLAG_TC3
;
stm32_spi
->
DMA_Channel_TX_FLAG_TE
=
DMA1_FLAG_TE3
;
#endif
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_SPI1
,
ENABLE
);
}
else
if
(
SPI
==
SPI2
)
{
stm32_spi
->
SPI
=
SPI2
;
#ifdef SPI_USE_DMA
/* Enable the DMA1 Clock */
RCC_AHBPeriphClockCmd
(
RCC_AHBPeriph_DMA1
,
ENABLE
);
stm32_spi
->
DMA_Channel_RX
=
DMA1_Channel4
;
stm32_spi
->
DMA_Channel_TX
=
DMA1_Channel5
;
stm32_spi
->
DMA_Channel_RX_FLAG_TC
=
DMA1_FLAG_TC4
;
stm32_spi
->
DMA_Channel_RX_FLAG_TE
=
DMA1_FLAG_TE4
;
stm32_spi
->
DMA_Channel_TX_FLAG_TC
=
DMA1_FLAG_TC5
;
stm32_spi
->
DMA_Channel_TX_FLAG_TE
=
DMA1_FLAG_TE5
;
#endif
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_SPI2
,
ENABLE
);
}
else
if
(
SPI
==
SPI3
)
{
stm32_spi
->
SPI
=
SPI3
;
#ifdef SPI_USE_DMA
/* Enable the DMA2 Clock */
RCC_AHBPeriphClockCmd
(
RCC_AHBPeriph_DMA2
,
ENABLE
);
stm32_spi
->
DMA_Channel_RX
=
DMA2_Channel1
;
stm32_spi
->
DMA_Channel_TX
=
DMA2_Channel2
;
stm32_spi
->
DMA_Channel_RX_FLAG_TC
=
DMA2_FLAG_TC1
;
stm32_spi
->
DMA_Channel_RX_FLAG_TE
=
DMA2_FLAG_TE1
;
stm32_spi
->
DMA_Channel_TX_FLAG_TC
=
DMA2_FLAG_TC2
;
stm32_spi
->
DMA_Channel_TX_FLAG_TE
=
DMA2_FLAG_TE2
;
#endif
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_SPI3
,
ENABLE
);
}
else
{
return
RT_ENOSYS
;
}
return
rt_spi_bus_register
(
&
stm32_spi
->
parent
,
spi_bus_name
,
&
stm32_spi_ops
);
}
bsp/stm32f107/drivers/rt_stm32f10x_spi.h
0 → 100644
浏览文件 @
8421ecfa
#ifndef STM32_SPI_H_INCLUDED
#define STM32_SPI_H_INCLUDED
#include <rtdevice.h>
#include "stm32f10x.h"
#include "stm32f10x_spi.h"
#include "board.h"
//#define SPI_USE_DMA
struct
stm32_spi_bus
{
struct
rt_spi_bus
parent
;
SPI_TypeDef
*
SPI
;
#ifdef SPI_USE_DMA
DMA_Channel_TypeDef
*
DMA_Channel_TX
;
DMA_Channel_TypeDef
*
DMA_Channel_RX
;
uint32_t
DMA_Channel_TX_FLAG_TC
;
uint32_t
DMA_Channel_TX_FLAG_TE
;
uint32_t
DMA_Channel_RX_FLAG_TC
;
uint32_t
DMA_Channel_RX_FLAG_TE
;
#endif
/* SPI_USE_DMA */
};
struct
stm32_spi_cs
{
GPIO_TypeDef
*
GPIOx
;
uint16_t
GPIO_Pin
;
};
/* public function list */
rt_err_t
stm32_spi_register
(
SPI_TypeDef
*
SPI
,
struct
stm32_spi_bus
*
stm32_spi
,
const
char
*
spi_bus_name
);
#endif // STM32_SPI_H_INCLUDED
bsp/stm32f107/drivers/stm32f10x_it.c
浏览文件 @
8421ecfa
...
...
@@ -107,12 +107,6 @@ void DebugMon_Handler(void)
{
}
void
SysTick_Handler
(
void
)
{
extern
void
rt_hw_timer_handler
(
void
);
rt_hw_timer_handler
();
}
/******************************************************************************/
/* STM32F10x Peripherals Interrupt Handlers */
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
...
...
bsp/stm32f107/drivers/usart.c
浏览文件 @
8421ecfa
...
...
@@ -13,6 +13,7 @@
* 2010-03-29 Bernard remove interrupt Tx and DMA Rx mode
*/
#include <board.h>
#include "usart.h"
#include <serial.h>
#include <stm32f10x_dma.h>
...
...
bsp/stm32f107/project.uvproj
浏览文件 @
8421ecfa
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Project
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"project_proj.xsd"
>
<SchemaVersion>
1.1
</SchemaVersion>
<Header>
### uVision Project, (C) Keil Software
</Header>
<Targets>
<Target>
<TargetName>
RT-Thread STM32
</TargetName>
...
...
@@ -12,25 +15,25 @@
<Device>
STM32F107VC
</Device>
<Vendor>
STMicroelectronics
</Vendor>
<Cpu>
IRAM(0x20000000-0x2000FFFF) IROM(0x8000000-0x803FFFF) CLOCK(25000000) CPUTYPE("Cortex-M3")
</Cpu>
<FlashUtilSpec
/
>
<FlashUtilSpec
></FlashUtilSpec
>
<StartupFile>
"STARTUP\ST\STM32F10x.s" ("STM32 Startup Code")
</StartupFile>
<FlashDriverDll>
UL2CM3(-O14 -S0 -C0 -N00("ARM Cortex-M3") -D00(1BA00477) -L00(4) -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F10x_CL -FS08000000 -FL040000)
</FlashDriverDll>
<DeviceId>
4889
</DeviceId>
<RegisterFile>
stm32f10x_lib.h
</RegisterFile>
<MemoryEnv
/
>
<Cmp
/
>
<Asm
/
>
<Linker
/
>
<OHString
/
>
<InfinionOptionDll
/
>
<SLE66CMisc
/
>
<SLE66AMisc
/
>
<SLE66LinkerMisc
/
>
<MemoryEnv
></MemoryEnv
>
<Cmp
></Cmp
>
<Asm
></Asm
>
<Linker
></Linker
>
<OHString
></OHString
>
<InfinionOptionDll
></InfinionOptionDll
>
<SLE66CMisc
></SLE66CMisc
>
<SLE66AMisc
></SLE66AMisc
>
<SLE66LinkerMisc
></SLE66LinkerMisc
>
<SFDFile>
SFD\ST\STM32F107x\STM32F107.sfr
</SFDFile>
<UseEnv>
0
</UseEnv>
<BinPath
/
>
<IncludePath
/
>
<LibPath
/
>
<BinPath
></BinPath
>
<IncludePath
></IncludePath
>
<LibPath
></LibPath
>
<RegisterFilePath>
ST\STM32F10x\
</RegisterFilePath>
<DBRegisterFilePath>
ST\STM32F10x\
</DBRegisterFilePath>
<TargetStatus>
...
...
@@ -54,16 +57,18 @@
<BeforeCompile>
<RunUserProg1>
0
</RunUserProg1>
<RunUserProg2>
0
</RunUserProg2>
<UserProg1Name
/
>
<UserProg2Name
/
>
<UserProg1Name
></UserProg1Name
>
<UserProg2Name
></UserProg2Name
>
<UserProg1Dos16Mode>
0
</UserProg1Dos16Mode>
<UserProg2Dos16Mode>
0
</UserProg2Dos16Mode>
<nStopU1X>
0
</nStopU1X>
<nStopU2X>
0
</nStopU2X>
</BeforeCompile>
<BeforeMake>
<RunUserProg1>
0
</RunUserProg1>
<RunUserProg2>
0
</RunUserProg2>
<UserProg1Name
/
>
<UserProg2Name
/
>
<UserProg1Name
></UserProg1Name
>
<UserProg2Name
></UserProg2Name
>
<UserProg1Dos16Mode>
0
</UserProg1Dos16Mode>
<UserProg2Dos16Mode>
0
</UserProg2Dos16Mode>
</BeforeMake>
...
...
@@ -71,12 +76,12 @@
<RunUserProg1>
1
</RunUserProg1>
<RunUserProg2>
0
</RunUserProg2>
<UserProg1Name>
fromelf --bin !L --output rtthread.bin
</UserProg1Name>
<UserProg2Name
/
>
<UserProg2Name
></UserProg2Name
>
<UserProg1Dos16Mode>
0
</UserProg1Dos16Mode>
<UserProg2Dos16Mode>
0
</UserProg2Dos16Mode>
</AfterMake>
<SelectedForBatchBuild>
0
</SelectedForBatchBuild>
<SVCSIdString
/
>
<SVCSIdString
></SVCSIdString
>
</TargetCommonOption>
<CommonProperty>
<UseCPPCompiler>
0
</UseCPPCompiler>
...
...
@@ -90,16 +95,16 @@
<AssembleAssemblyFile>
0
</AssembleAssemblyFile>
<PublicsOnly>
0
</PublicsOnly>
<StopOnExitCode>
3
</StopOnExitCode>
<CustomArgument
/
>
<IncludeLibraryModules
/
>
<CustomArgument
></CustomArgument
>
<IncludeLibraryModules
></IncludeLibraryModules
>
</CommonProperty>
<DllOption>
<SimDllName>
SARMCM3.DLL
</SimDllName>
<SimDllArguments
/
>
<SimDllArguments
></SimDllArguments
>
<SimDlgDll>
DARMSTM.DLL
</SimDlgDll>
<SimDlgDllArguments>
-pSTM32F107VC
</SimDlgDllArguments>
<TargetDllName>
SARMCM3.DLL
</TargetDllName>
<TargetDllArguments
/
>
<TargetDllArguments
></TargetDllArguments
>
<TargetDlgDll>
TARMSTM.DLL
</TargetDlgDll>
<TargetDlgDllArguments>
-pSTM32F107VC
</TargetDlgDllArguments>
</DllOption>
...
...
@@ -131,22 +136,23 @@
<RestoreMemoryDisplay>
1
</RestoreMemoryDisplay>
<RestoreFunctions>
0
</RestoreFunctions>
<RestoreToolbox>
1
</RestoreToolbox>
<RestoreTracepoints>
0
</RestoreTracepoints>
</Target>
<RunDebugAfterBuild>
0
</RunDebugAfterBuild>
<TargetSelection>
7
</TargetSelection>
<SimDlls>
<CpuDll
/
>
<CpuDllArguments
/
>
<PeripheralDll
/
>
<PeripheralDllArguments
/
>
<InitializationFile
/
>
<CpuDll
></CpuDll
>
<CpuDllArguments
></CpuDllArguments
>
<PeripheralDll
></PeripheralDll
>
<PeripheralDllArguments
></PeripheralDllArguments
>
<InitializationFile
></InitializationFile
>
</SimDlls>
<TargetDlls>
<CpuDll
/
>
<CpuDllArguments
/
>
<PeripheralDll
/
>
<PeripheralDllArguments
/
>
<InitializationFile
/
>
<CpuDll
></CpuDll
>
<CpuDllArguments
></CpuDllArguments
>
<PeripheralDll
></PeripheralDll
>
<PeripheralDllArguments
></PeripheralDllArguments
>
<InitializationFile
></InitializationFile
>
<Driver>
Segger\JL2CM3.dll
</Driver>
</TargetDlls>
</DebugOption>
...
...
@@ -160,8 +166,8 @@
<DriverSelection>
4099
</DriverSelection>
</Flash1>
<Flash2>
Segger\JL2CM3.dll
</Flash2>
<Flash3
/
>
<Flash4
/
>
<Flash3
>
"" ()
</Flash3
>
<Flash4
></Flash4
>
</Utilities>
<TargetArmAds>
<ArmAdsMisc>
...
...
@@ -193,7 +199,7 @@
<RvctClst>
0
</RvctClst>
<GenPPlst>
0
</GenPPlst>
<AdsCpuType>
"Cortex-M3"
</AdsCpuType>
<RvctDeviceName
/
>
<RvctDeviceName
></RvctDeviceName
>
<mOS>
0
</mOS>
<uocRom>
0
</uocRom>
<uocRam>
0
</uocRam>
...
...
@@ -324,7 +330,7 @@
<Size>
0x0
</Size>
</OCR_RVCT10>
</OnChipMemories>
<RvctStartVector
/
>
<RvctStartVector
></RvctStartVector
>
</ArmAdsMisc>
<Cads>
<interw>
1
</interw>
...
...
@@ -339,11 +345,12 @@
<Rwpi>
0
</Rwpi>
<wLevel>
0
</wLevel>
<uThumb>
0
</uThumb>
<uSurpInc>
0
</uSurpInc>
<VariousControls>
<MiscControls
/
>
<MiscControls
></MiscControls
>
<Define>
STM32F10X_CL, USE_STDPERIPH_DRIVER
</Define>
<Undefine
/
>
<IncludePath>
.;..\..\components\CMSIS\Include;..\..\components\dfs;..\..\components\dfs\include;..\..\components\finsh;..\..\components\init;..\..\components\net\lwip\src;..\..\components\net\lwip\src\arch\include;..\..\components\net\lwip\src\include;..\..\components\net\lwip\src\include\ipv4;..\..\components\net\lwip\src\include\netif;..\..\include;..\..\libcpu\arm\common;..\..\libcpu\arm\cortex-m3;Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x;Libraries\STM32F10x_StdPeriph_Driver\inc;applications;drivers
</IncludePath>
<Undefine
></Undefine
>
<IncludePath>
.;..\..\components\CMSIS\Include;..\..\components\dfs;..\..\components\dfs\include;..\..\components\
drivers\include;..\..\components\
finsh;..\..\components\init;..\..\components\net\lwip\src;..\..\components\net\lwip\src\arch\include;..\..\components\net\lwip\src\include;..\..\components\net\lwip\src\include\ipv4;..\..\components\net\lwip\src\include\netif;..\..\include;..\..\libcpu\arm\common;..\..\libcpu\arm\cortex-m3;Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x;Libraries\STM32F10x_StdPeriph_Driver\inc;applications;drivers
</IncludePath>
</VariousControls>
</Cads>
<Aads>
...
...
@@ -354,11 +361,12 @@
<SplitLS>
0
</SplitLS>
<SwStkChk>
0
</SwStkChk>
<NoWarn>
0
</NoWarn>
<uSurpInc>
0
</uSurpInc>
<VariousControls>
<MiscControls
/
>
<Define
/
>
<Undefine
/
>
<IncludePath
/
>
<MiscControls
></MiscControls
>
<Define
></Define
>
<Undefine
></Undefine
>
<IncludePath
></IncludePath
>
</VariousControls>
</Aads>
<LDads>
...
...
@@ -370,12 +378,12 @@
<useFile>
0
</useFile>
<TextAddressRange>
0x08000000
</TextAddressRange>
<DataAddressRange>
0x20000000
</DataAddressRange>
<ScatterFile
/
>
<IncludeLibs
/
>
<IncludeLibsPath
/
>
<ScatterFile
></ScatterFile
>
<IncludeLibs
></IncludeLibs
>
<IncludeLibsPath
></IncludeLibsPath
>
<Misc>
--keep __fsym_* --keep __vsym_*
</Misc>
<LinkerInputFile
/
>
<DisabledWarnings
/
>
<LinkerInputFile
></LinkerInputFile
>
<DisabledWarnings
></DisabledWarnings
>
</LDads>
</TargetArmAds>
</TargetOption>
...
...
@@ -388,8 +396,6 @@
<FileType>
1
</FileType>
<FilePath>
applications\application.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
startup.c
</FileName>
<FileType>
1
</FileType>
...
...
@@ -405,43 +411,36 @@
<FileType>
1
</FileType>
<FilePath>
drivers\board.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
msd.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
drivers\msd.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
platform.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
drivers\platform.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
rt_stm32f10x_spi.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
drivers\rt_stm32f10x_spi.c
</FilePath>
</File>
<File>
<FileName>
serial.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
drivers\serial.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32_eth.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
drivers\stm32_eth.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_it.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
drivers\stm32f10x_it.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
usart.c
</FileName>
<FileType>
1
</FileType>
...
...
@@ -457,169 +456,121 @@
<FileType>
1
</FileType>
<FilePath>
Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\system_stm32f10x.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_crc.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_crc.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_rcc.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_wwdg.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_wwdg.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_pwr.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_pwr.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_exti.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_exti.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_bkp.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_bkp.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_i2c.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_i2c.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_adc.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_adc.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_dac.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dac.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_rtc.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_rtc.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_fsmc.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_fsmc.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_tim.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_tim.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_iwdg.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_iwdg.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_spi.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_spi.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_flash.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_flash.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_sdio.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_sdio.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_gpio.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_usart.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_usart.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_dbgmcu.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dbgmcu.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_dma.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_dma.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_can.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_can.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stm32f10x_cec.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_cec.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
misc.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
Libraries\STM32F10x_StdPeriph_Driver\src\misc.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
startup_stm32f10x_cl.s
</FileName>
<FileType>
2
</FileType>
...
...
@@ -635,78 +586,56 @@
<FileType>
1
</FileType>
<FilePath>
..\..\src\clock.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
device.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\src\device.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
idle.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\src\idle.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
ipc.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\src\ipc.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
irq.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\src\irq.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
kservice.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\src\kservice.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
mem.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\src\mem.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
mempool.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\src\mempool.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
object.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\src\object.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
scheduler.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\src\scheduler.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
thread.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\src\thread.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
timer.c
</FileName>
<FileType>
1
</FileType>
...
...
@@ -722,29 +651,21 @@
<FileType>
1
</FileType>
<FilePath>
..\..\libcpu\arm\cortex-m3\cpuport.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
context_rvds.S
</FileName>
<FileType>
2
</FileType>
<FilePath>
..\..\libcpu\arm\cortex-m3\context_rvds.S
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
backtrace.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\libcpu\arm\common\backtrace.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
div0.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\libcpu\arm\common\div0.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
showmem.c
</FileName>
<FileType>
1
</FileType>
...
...
@@ -760,36 +681,26 @@
<FileType>
1
</FileType>
<FilePath>
..\..\components\dfs\src\dfs.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
dfs_fs.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\dfs\src\dfs_fs.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
dfs_file.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\dfs\src\dfs_file.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
dfs_posix.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\dfs\src\dfs_posix.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
dfs_elm.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\dfs\filesystems\elmfat\dfs_elm.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
ff.c
</FileName>
<FileType>
1
</FileType>
...
...
@@ -797,6 +708,21 @@
</File>
</Files>
</Group>
<Group>
<GroupName>
DeviceDrivers
</GroupName>
<Files>
<File>
<FileName>
spi_core.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\drivers\spi\spi_core.c
</FilePath>
</File>
<File>
<FileName>
spi_dev.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\drivers\spi\spi_dev.c
</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>
finsh
</GroupName>
<Files>
...
...
@@ -805,85 +731,61 @@
<FileType>
1
</FileType>
<FilePath>
..\..\components\finsh\cmd.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
finsh_compiler.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\finsh\finsh_compiler.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
finsh_error.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\finsh\finsh_error.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
finsh_heap.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\finsh\finsh_heap.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
finsh_init.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\finsh\finsh_init.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
finsh_node.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\finsh\finsh_node.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
finsh_ops.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\finsh\finsh_ops.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
finsh_parser.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\finsh\finsh_parser.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
finsh_token.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\finsh\finsh_token.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
finsh_var.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\finsh\finsh_var.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
finsh_vm.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\finsh\finsh_vm.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
shell.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\finsh\shell.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
symbol.c
</FileName>
<FileType>
1
</FileType>
...
...
@@ -909,239 +811,171 @@
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\api\api_lib.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
api_msg.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\api\api_msg.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
err.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\api\err.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
netbuf.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\api\netbuf.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
netdb.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\api\netdb.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
netifapi.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\api\netifapi.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
sockets.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\api\sockets.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
tcpip.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\api\tcpip.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
sys_arch.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\arch\sys_arch.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
def.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\def.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
dhcp.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\dhcp.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
dns.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\dns.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
init.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\init.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
memp.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\memp.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
netif.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\netif.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
pbuf.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\pbuf.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
raw.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\raw.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
stats.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\stats.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
sys.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\sys.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
tcp.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\tcp.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
tcp_in.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\tcp_in.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
tcp_out.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\tcp_out.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
timers.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\timers.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
udp.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\udp.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
autoip.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\ipv4\autoip.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
icmp.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\ipv4\icmp.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
igmp.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\ipv4\igmp.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
inet.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\ipv4\inet.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
inet_chksum.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\ipv4\inet_chksum.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
ip.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\ipv4\ip.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
ip_addr.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\ipv4\ip_addr.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
ip_frag.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\core\ipv4\ip_frag.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
etharp.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\netif\etharp.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
ethernetif.c
</FileName>
<FileType>
1
</FileType>
<FilePath>
..\..\components\net\lwip\src\netif\ethernetif.c
</FilePath>
</File>
</Files>
<Files>
<File>
<FileName>
slipif.c
</FileName>
<FileType>
1
</FileType>
...
...
@@ -1152,4 +986,5 @@
</Groups>
</Target>
</Targets>
</Project>
bsp/stm32f107/readme.txt
浏览文件 @
8421ecfa
...
...
@@ -2,4 +2,4 @@
# GoldBull debug board
- 10M/100M ethernet
- SPI SD Card
- LCD
SPI: SPI1 (PA5,PA6,PA7). CS:PA4
bsp/stm32f107/rtconfig.h
浏览文件 @
8421ecfa
...
...
@@ -58,7 +58,7 @@
/* SECTION: Device System */
/* Using Device System */
#define RT_USING_DEVICE
#define RT_USING_
UART1
#define RT_USING_
SPI
/* SECTION: Console options */
#define RT_USING_CONSOLE
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录