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,15 +44,15 @@ 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
();
/* enter interrupt */
rt_interrupt_enter
();
rt_tick_increase
();
rt_tick_increase
();
/* leave interrupt */
rt_interrupt_leave
();
/* leave interrupt */
rt_interrupt_leave
();
}
/**
...
...
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
)
{
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
());
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
)
{
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
;
/* MSD chip select low */
MSD_CS_LOW
();
/* Send CMD24 (MSD_WRITE_BLOCK) to write multiple block */
MSD_SendCmd
(
MSD_WRITE_BLOCK
,
WriteAddr
,
0xFF
);
/* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */
if
(
!
MSD_GetResponse
(
MSD_RESPONSE_NO_ERROR
))
{
/* 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
++
)
{
/* Send the pointed byte */
MSD_WriteByte
(
*
pBuffer
);
/* Point to the next location where the byte read will be saved */
pBuffer
++
;
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
);
}
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
;
if
(
tick_end
>=
tick_start
)
{
if
(
tick_now
>=
tick_end
)
{
result
=
RT_TRUE
;
}
else
{
result
=
RT_FALSE
;
}
}
/* 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
;
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
;
/* 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
);
/* Check if the MSD acknowledged the read block command: R1 response (0x00: no errors) */
if
(
!
MSD_GetResponse
(
MSD_RESPONSE_NO_ERROR
))
{
/* 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
<
NumByteToRead
;
i
++
)
{
/* Save the received data */
*
pBuffer
=
MSD_ReadByte
();
/* Point to the next location where the byte read will be saved */
pBuffer
++
;
}
/* 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
;
unsigned
char
i
,
j
,
crc
,
ch
,
ch2
,
ch3
;
crc
=
0
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
ch
=
buf
[
i
];
for
(
j
=
0
;
j
<
8
;
j
++
,
ch
<<=
1
)
{
ch2
=
(
crc
&
0x40
)
?
1
:
0
;
ch3
=
(
ch
&
0x80
)
?
1
:
0
;
if
(
ch2
^
ch3
)
{
crc
^=
0x04
;
crc
<<=
1
;
crc
|=
0x01
;
}
else
{
crc
<<=
1
;
}
}
}
}
/* 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
;
/* Calculate number of blocks to write */
NbrOfBlock
=
NumByteToWrite
/
BLOCK_SIZE
;
/* MSD chip select low */
MSD_CS_LOW
();
/* initial message */
message
.
send_buf
=
cmd_buffer
;
message
.
recv_buf
=
recv_buffer
;
message
.
length
=
sizeof
(
cmd_buffer
);
message
.
cs_take
=
message
.
cs_release
=
0
;
/* Data transfer */
while
(
NbrOfBlock
--
)
{
/* Send CMD24 (MSD_WRITE_BLOCK) to write blocks */
MSD_SendCmd
(
MSD_WRITE_BLOCK
,
WriteAddr
+
Offset
,
0xFF
);
_wait_ready
(
device
);
/* 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
);
for
(
i
=
CARD_NCR
;
i
<
(
CARD_NCR_MAX
+
1
);
i
++
)
{
return
MSD_RESPONSE_FAILURE
;
}
/* 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
++
)
{
/* Send the pointed byte */
MSD_WriteByte
(
*
pBuffer
);
/* Point to the next location where the byte read will be saved */
pBuffer
++
;
uint8_t
send
=
DUMMY
;
/* initial message */
message
.
send_buf
=
&
send
;
message
.
recv_buf
=
response
;
message
.
length
=
1
;
message
.
cs_take
=
message
.
cs_release
=
0
;
/* transfer message */
device
->
bus
->
ops
->
xfer
(
device
,
&
message
);
if
(
0
==
(
response
[
0
]
&
0x80
))
{
break
;
}
}
/* wait response */
if
((
CARD_NCR_MAX
+
1
)
==
i
)
{
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
)
{
/* Set response value to success */
rvalue
=
MSD_RESPONSE_NO_ERROR
;
//recieve other byte
if
(
type
==
response_r1
)
{
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
;
}
}
}
}
/* 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_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
)
{
u32
i
=
0
,
NbrOfBlock
=
0
,
Offset
=
0
;
u8
rvalue
=
MSD_RESPONSE_FAILURE
;
/* Calculate number of blocks to read */
NbrOfBlock
=
NumByteToRead
/
BLOCK_SIZE
;
/* MSD chip select low */
MSD_CS_LOW
();
/* Data transfer */
while
(
NbrOfBlock
--
)
{
/* 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
))
{
return
MSD_RESPONSE_FAILURE
;
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
);
}
/* 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
++
)
{
/* Read the pointed data */
*
pBuffer
=
MSD_ReadByte
();
/* Point to the next location where the byte read will be saved */
pBuffer
++
;
}
/* 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
;
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
{
/* Set response value to failure */
rvalue
=
MSD_RESPONSE_FAILURE
;
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_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
_wait_token
(
struct
rt_spi_device
*
device
,
uint8_t
token
)
{
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_tick_t
tick_start
;
uint8_t
send
,
recv
;
tick_start
=
rt_tick_get
();
/* wati token */
/* initial message */
send
=
DUMMY
;
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
==
token
)
{
return
RT_EOK
;
}
if
(
rt_tick_timeout
(
tick_start
,
rt_tick_from_millisecond
(
CARD_WAIT_TOKEN_TIMES
)))
{
MSD_DEBUG
(
"[err] wait data start token timeout!
\r\n
"
);
return
RT_ETIMEOUT
;
}
}
/* wati token */
}
/*******************************************************************************
* 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
)
static
rt_err_t
_wait_ready
(
struct
rt_spi_device
*
device
)
{
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
();
}
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
;
}
if
(
rt_tick_timeout
(
tick_start
,
rt_tick_from_millisecond
(
1000
)))
{
MSD_DEBUG
(
"[err] wait ready timeout!
\r\n
"
);
return
RT_ETIMEOUT
;
}
}
/* 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
;
}
/*******************************************************************************
* 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
_read_block
(
struct
rt_spi_device
*
device
,
void
*
buffer
,
uint32_t
block_size
)
{
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
;
rt_err_t
result
;
/*******************************************************************************
* 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
)
{
u32
i
=
0
;
u8
response
,
rvalue
;
while
(
i
<=
64
)
{
/* Read resonse */
response
=
MSD_ReadByte
();
/* Mask unused bits */
response
&=
0x1F
;
switch
(
response
)
{
case
MSD_DATA_OK
:
{
rvalue
=
MSD_DATA_OK
;
break
;
}
case
MSD_DATA_CRC_ERROR
:
return
MSD_DATA_CRC_ERROR
;
case
MSD_DATA_WRITE_ERROR
:
return
MSD_DATA_WRITE_ERROR
;
default:
{
rvalue
=
MSD_DATA_OTHER_ERROR
;
break
;
}
/* wati token */
result
=
_wait_token
(
device
,
MSD_TOKEN_READ_START
);
if
(
result
!=
RT_EOK
)
{
return
result
;
}
/* Exit loop in case of data ok */
if
(
rvalue
==
MSD_DATA_OK
)
break
;
/* Increment loop counter */
i
++
;
}
/* Wait null data */
while
(
MSD_ReadByte
()
==
0
);
/* Return response */
return
response
;
/* 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_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
)
static
rt_err_t
_write_block
(
struct
rt_spi_device
*
device
,
const
void
*
buffer
,
uint32_t
block_size
,
uint8_t
token
)
{
u32
Count
=
0xFFF
;
/* Check if response is got or a timeout is happen */
while
((
MSD_ReadByte
()
!=
Response
)
&&
Count
)
{
Count
--
;
}
if
(
Count
==
0
)
{
/* After time out */
return
MSD_RESPONSE_FAILURE
;
}
else
{
/* Right response got */
return
MSD_RESPONSE_NO_ERROR
;
}
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_GetStatus
* Description : Returns the MSD status.
* Input : None
* Output : None
* Return : The MSD status.
*******************************************************************************/
u16
MSD_GetStatus
(
void
)
/* RT-Thread Device Driver Interface */
static
rt_err_t
rt_msd_init
(
rt_device_t
dev
)
{
u16
Status
=
0
;
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
;
/* MSD chip select low */
MSD_CS_LOW
();
/* Send CMD13 (MSD_SEND_STATUS) to get MSD status */
MSD_SendCmd
(
MSD_SEND_STATUS
,
0
,
0xFF
);
if
(
msd
->
spi_device
==
RT_NULL
)
{
MSD_DEBUG
(
"[err] the SPI SD device has no SPI!
\r\n
"
);
return
RT_EIO
;
}
Status
=
MSD_ReadByte
();
Status
|=
(
u16
)(
MSD_ReadByte
()
<<
8
);
/* config spi */
{
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 */
/* 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
)
{
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
;
}
}
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
);
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
]);
if
(
response
[
0
]
&
(
1
<<
2
))
{
/* 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
;
}
}
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
;
}
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
);
if
(
0
==
(
OCR
&
(
0x1
<<
15
)))
{
MSD_DEBUG
((
"[err] SD 1.x But not surpport current voltage
\r\n
"
));
result
=
RT_ERROR
;
goto
_exit
;
}
/* --Send ACMD41 to make card ready */
tick_start
=
rt_tick_get
();
/* try CMD55 + ACMD41 */
while
(
1
)
{
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
;
}
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
)
{
MSD_release_cs
(
msd
->
spi_device
);
continue
;
}
if
(
0
!=
(
response
[
0
]
&
0xFE
))
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[info] Not SD card2 , may be MMC
\r\n
"
);
break
;
}
/* 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
;
}
if
(
0
!=
(
response
[
0
]
&
0xFE
))
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[info] Not SD card4 , may be MMC
\r\n
"
);
break
;
}
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 */
break
;
}
/* try SD Ver1.x */
/* 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
);
if
(
0
==
(
OCR
&
(
0x1
<<
15
)))
{
MSD_DEBUG
((
"[err] SD 1.x But not surpport current voltage
\r\n
"
));
result
=
RT_ERROR
;
goto
_exit
;
}
/* --Send ACMD41 to make card ready */
tick_start
=
rt_tick_get
();
/* try CMD55 + ACMD41 */
do
{
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
;
}
/* 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
;
}
if
((
response
[
0
]
&
0xFE
)
!=
0
)
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[err] Not SD ready!
\r\n
"
);
result
=
RT_ERROR
;
goto
_exit
;
}
/* 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
;
}
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
;
}
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
);
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
);
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 */
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
;
}
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send dummy byte 0xFF */
MSD_WriteByte
(
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 */
/* 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
Status
;
/* read CSD */
{
uint8_t
CSD_buffer
[
MSD_CSD_LEN
];
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
);
if
(
result
!=
RT_EOK
)
{
MSD_release_cs
(
msd
->
spi_device
);
MSD_DEBUG
(
"[err] CMD9 SEND_CSD timeout!
\r\n
"
);
goto
_exit
;
}
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
;
}
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
;
}
/* Analyze CSD */
{
uint8_t
CSD_STRUCTURE
;
uint32_t
C_SIZE
;
uint32_t
card_capacity
;
uint8_t
tmp8
;
uint16_t
tmp16
;
uint32_t
tmp32
;
/* 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
;
}
/*******************************************************************************
* 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
)
static
rt_err_t
rt_msd_open
(
rt_device_t
dev
,
rt_uint16_t
oflag
)
{
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
);
/* Wait for In Idle State Response (R1 Format) equal to 0x01 */
if
(
MSD_GetResponse
(
MSD_IN_IDLE_STATE
))
{
/* No Idle State Response: return response failue */
return
MSD_RESPONSE_FAILURE
;
}
/*----------Activates the card initialization process-----------*/
do
{
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send Dummy byte 0xFF */
MSD_WriteByte
(
DUMMY
);
for
(
i
=
0
;
i
<
0xfff
;
i
++
);
/* MSD chip select low */
MSD_CS_LOW
();
for
(
i
=
0
;
i
<
0xfff
;
i
++
);
/* 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 */
}
while
(
MSD_GetResponse
(
MSD_RESPONSE_NO_ERROR
));
/* MSD chip select high */
MSD_CS_HIGH
();
/* Send dummy byte 0xFF */
MSD_WriteByte
(
DUMMY
);
return
MSD_RESPONSE_NO_ERROR
;
// struct msd_device * msd = (struct msd_device *)dev;
return
RT_EOK
;
}
/*******************************************************************************
* 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
)
static
rt_err_t
rt_msd_close
(
rt_device_t
dev
)
{
/* 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
);
/* Get the received data */
Data
=
SPI_I2S_ReceiveData
(
MSD_SPI
);
return
Data
;
// struct msd_device * msd = (struct msd_device *)dev;
return
RT_EOK
;
}
/*******************************************************************************
* Function Name : MSD_ReadByte
* Description : Read a byte from the MSD.
* Input : None.
* Output : None
* Return : The received byte.
*******************************************************************************/
u8
MSD_ReadByte
(
void
)
static
rt_size_t
rt_msd_read
(
rt_device_t
dev
,
rt_off_t
pos
,
void
*
buffer
,
rt_size_t
size
)
{
u8
Data
=
0
;
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
;
}
/* 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
);
/* 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
;
/* 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
);
rt_spi_configure
(
msd
->
spi_device
,
&
cfg
);
}
/* config spi */
/* Return the shifted data */
return
Data
;
/* SINGLE_BLOCK? */
if
(
size
==
1
)
{
MSD_take_cs
(
msd
->
spi_device
);
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
))
{
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
);
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
;
}
/*******************************************************************************
* Function Name : SPI_Config
* Description : Initializes the SPI and CS pins.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void
SPI_Config
(
void
)
static
rt_size_t
rt_msd_sdhc_read
(
rt_device_t
dev
,
rt_off_t
pos
,
void
*
buffer
,
rt_size_t
size
)
{
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
++
);
}
struct
msd_device
*
msd
=
(
struct
msd_device
*
)
dev
;
uint8_t
response
[
MSD_RESPONSE_MAX_LEN
];
rt_err_t
result
=
RT_EOK
;
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
result
=
MSD_take_owner
(
msd
->
spi_device
);
/*
* 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>
static
struct
rt_device
sdcard_device
;
static
struct
dfs_partition
part
;
if
(
result
!=
RT_EOK
)
{
goto
_exit
;
}
#define SECTOR_SIZE 512
/* 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-Thread Device Driver Interface */
static
rt_err_t
rt_msd_init
(
rt_device_t
dev
)
{
sMSD_CSD
MSD_csd
;
MSD_GetCSDRegister
(
&
MSD_csd
);
rt_spi_configure
(
msd
->
spi_device
,
&
cfg
);
}
/* config spi */
return
RT_EOK
;
/* 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
);
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
;
}
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_
err_t
rt_msd_open
(
rt_device_t
dev
,
rt_uint16_t
oflag
)
static
rt_
size_t
rt_msd_write
(
rt_device_t
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
{
return
RT_EOK
;
}
struct
msd_device
*
msd
=
(
struct
msd_device
*
)
dev
;
uint8_t
response
[
MSD_RESPONSE_MAX_LEN
];
rt_err_t
result
;
static
rt_err_t
rt_msd_close
(
rt_device_t
dev
)
{
return
RT_EOK
;
}
result
=
MSD_take_owner
(
msd
->
spi_device
);
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
;
status
=
MSD_RESPONSE_NO_ERROR
;
// rt_kprintf("read: 0x%x, size %d\n", pos, size);
/* read all sectors */
for
(
i
=
0
;
i
<
size
;
i
++
)
{
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
)
{
rt_kprintf
(
"sd card read failed
\n
"
);
return
0
;
}
}
if
(
status
==
MSD_RESPONSE_NO_ERROR
)
return
size
;
rt_kprintf
(
"read failed: %d
\n
"
,
status
);
return
0
;
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
;
}
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_
write
(
rt_device_t
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
{
rt_uint8_t
status
;
rt_uint32_t
i
;
status
=
MSD_RESPONSE_NO_ERROR
;
// rt_kprintf("write: 0x%x, size %d\n", pos, size);
/* write all sectors */
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
)
{
rt_kprintf
(
"sd card write failed
\n
"
);
return
0
;
}
}
if
(
status
==
MSD_RESPONSE_NO_ERROR
)
return
size
;
rt_kprintf
(
"write failed: %d
\n
"
,
status
);
return
0
;
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
)
{
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
,
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
/* 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
,
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 MULTIPLE_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
);
}
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
);
return
RT_EOK
;
if
(
cmd
==
RT_DEVICE_CTRL_BLK_GETGEOME
)
{
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
;
}
void
rt_hw_msd_init
(
)
rt_err_t
msd_init
(
const
char
*
sd_device_name
,
const
char
*
spi_device_name
)
{
if
(
MSD_Init
()
==
MSD_RESPONSE_NO_ERROR
)
{
rt_uint8_t
status
;
rt_uint8_t
*
sector
;
/* 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
;
/* 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
)
{
rt_kprintf
(
"allocate partition sector buffer failed
\n
"
);
return
;
}
status
=
MSD_ReadBlock
(
sector
,
0
,
512
);
if
(
status
==
MSD_RESPONSE_NO_ERROR
)
{
/* get the first partition */
status
=
dfs_filesystem_get_partition
(
&
part
,
sector
,
0
);
if
(
status
!=
RT_EOK
)
{
/* there is no partition table */
part
.
offset
=
0
;
part
.
size
=
0
;
}
}
else
{
/* there is no partition table */
part
.
offset
=
0
;
part
.
size
=
0
;
}
/* release sector buffer */
rt_free
(
sector
);
rt_device_register
(
&
sdcard_device
,
"sd0"
,
RT_DEVICE_FLAG_RDWR
|
RT_DEVICE_FLAG_REMOVABLE
|
RT_DEVICE_FLAG_STANDALONE
);
}
else
{
rt_kprintf
(
"sdcard init failed
\n
"
);
}
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
#define MSD_IN_IDLE_STATE 0x01
#define MSD_ERASE_RESET 0x02
#define MSD_ILLEGAL_COMMAND 0x04
#define MSD_COM_CRC_ERROR 0x08
#define MSD_ERASE_SEQUENCE_ERROR 0x10
#define MSD_ADDRESS_ERROR 0x20
#define MSD_PARAMETER_ERROR 0x40
#define MSD_RESPONSE_FAILURE 0xFF
#define MSD_RESPONSE_NO_ERROR
0x00
#define MSD_IN_IDLE_STATE
0x01
#define MSD_ERASE_RESET
0x02
#define MSD_ILLEGAL_COMMAND
0x04
#define MSD_COM_CRC_ERROR
0x08
#define MSD_ERASE_SEQUENCE_ERROR
0x10
#define MSD_ADDRESS_ERROR
0x20
#define MSD_PARAMETER_ERROR
0x40
#define MSD_RESPONSE_FAILURE
0xFF
/* Data response error */
#define MSD_DATA_OK 0x05
#define MSD_DATA_CRC_ERROR 0x0B
#define MSD_DATA_WRITE_ERROR 0x0D
#define MSD_DATA_OTHER_ERROR 0xFF
/* 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_DATA_OK 0x05
#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)
#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
...
...
@@ -5,7 +5,7 @@
* @version V3.5.0
* @date 08-April-2011
* @brief Main Interrupt Service Routines.
* This file provides template for all exceptions handler and
* This file provides template for all exceptions handler and
* peripherals interrupt service routine.
******************************************************************************
* @attention
...
...
@@ -19,7 +19,7 @@
*
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
...
...
@@ -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 */
...
...
@@ -132,7 +126,7 @@ void USART1_IRQHandler(void)
#ifdef RT_USING_UART1
extern
struct
rt_device
uart1_device
;
extern
void
rt_hw_serial_isr
(
struct
rt_device
*
device
);
/* enter interrupt */
rt_interrupt_enter
();
...
...
@@ -191,7 +185,7 @@ void USART3_IRQHandler(void)
/**
* @}
*/
*/
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录