Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
fwatch
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
8
Issues
8
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
fwatch
Commits
380335f4
Commit
380335f4
authored
Jul 28, 2014
by
Xavier Piroux
Committed by
Matthieu Cattin
Sep 26, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SD protocol on SPI have a first implementation
parent
d2dea84b
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
229 additions
and
59 deletions
+229
-59
config_mdriver_sd.h
...n/freertos_blink_fat/src/media-drv/sd/config_mdriver_sd.h
+1
-1
sd_driver_f.c
...parison/freertos_blink_fat/src/media-drv/sd/sd_driver_f.c
+145
-30
spi.c
sw/os-comparison/freertos_blink_fat/src/media-drv/sd/spi.c
+28
-25
spi.h
sw/os-comparison/freertos_blink_fat/src/media-drv/sd/spi.h
+5
-2
usart.c
sw/os-comparison/freertos_blink_fat/src/media-drv/sd/usart.c
+49
-1
usart.h
sw/os-comparison/freertos_blink_fat/src/media-drv/sd/usart.h
+1
-0
No files found.
sw/os-comparison/freertos_blink_fat/src/media-drv/sd/config_mdriver_sd.h
View file @
380335f4
...
...
@@ -29,6 +29,6 @@
#define MDRIVER_SD_SECTOR_SIZE 512
/* Sector size */
#define MDRIVER_SD_VOLUME0_SIZE (
32 * 1024)
/* definition for size of sddrive0
*/
#define MDRIVER_SD_VOLUME0_SIZE (
2 * 1024 * 1024)
/* definition for size of sddrive0 : we assume working with a 2GB micro SD card
*/
#endif
/* _CONFIG_MDRIVER_SD_H_ */
sw/os-comparison/freertos_blink_fat/src/media-drv/sd/sd_driver_f.c
View file @
380335f4
...
...
@@ -6,6 +6,7 @@
#include "../../api/api_mdriver_sd.h"
#include "config_mdriver_sd.h"
#include "../../psp/include/psp_string.h"
#include "spi.h"
#include "em_gpio.h"
#include "em_cmu.h"
...
...
@@ -15,38 +16,99 @@
//TODO: use those CMD to send it through SPI interface
/* MMC/SD command (in SPI) */
#define
MICROSD_CMD0
(0x40+0)
/* GO_IDLE_STATE */
#define
MICROSD_CMD1
(0x40+1)
/* SEND_OP_COND (MMC) */
#define
MICRO
SD_ACMD41 (0xC0+41)
/* SEND_OP_COND (SDC) */
#define
MICROSD_CMD8
(0x40+8)
/* SEND_IF_COND */
#define
MICROSD_CMD9
(0x40+9)
/* SEND_CSD */
#define
MICRO
SD_CMD10 (0x40+10)
/* SEND_CID */
#define
MICRO
SD_CMD12 (0x40+12)
/* STOP_TRANSMISSION */
#define
MICRO
SD_ACMD13 (0xC0+13)
/* SD_STATUS (SDC) */
#define
MICRO
SD_CMD16 (0x40+16)
/* SET_BLOCKLEN */
#define
MICRO
SD_CMD17 (0x40+17)
/* READ_SINGLE_BLOCK */
#define
MICRO
SD_CMD18 (0x40+18)
/* READ_MULTIPLE_BLOCK */
#define
MICRO
SD_CMD23 (0x40+23)
/* SET_BLOCK_COUNT (MMC) */
#define
MICRO
SD_ACMD23 (0xC0+23)
/* SET_WR_BLK_ERASE_COUNT (SDC) */
#define
MICRO
SD_CMD24 (0x40+24)
/* WRITE_BLOCK */
#define
MICRO
SD_CMD25 (0x40+25)
/* WRITE_MULTIPLE_BLOCK */
#define
MICRO
SD_CMD55 (0x40+55)
/* APP_CMD */
#define
MICRO
SD_CMD58 (0x40+58)
/* READ_OCR */
#define
SD_CMD0
(0x40+0)
/* GO_IDLE_STATE */
#define
SD_CMD1
(0x40+1)
/* SEND_OP_COND (MMC) */
#define SD_ACMD41 (0xC0+41)
/* SEND_OP_COND (SDC) */
#define
SD_CMD8
(0x40+8)
/* SEND_IF_COND */
#define
SD_CMD9
(0x40+9)
/* SEND_CSD */
#define SD_CMD10 (0x40+10)
/* SEND_CID */
#define SD_CMD12 (0x40+12)
/* STOP_TRANSMISSION */
#define SD_ACMD13 (0xC0+13)
/* SD_STATUS (SDC) */
#define SD_CMD16 (0x40+16)
/* SET_BLOCKLEN */
#define SD_CMD17 (0x40+17)
/* READ_SINGLE_BLOCK */
#define SD_CMD18 (0x40+18)
/* READ_MULTIPLE_BLOCK */
#define SD_CMD23 (0x40+23)
/* SET_BLOCK_COUNT (MMC) */
#define SD_ACMD23 (0xC0+23)
/* SET_WR_BLK_ERASE_COUNT (SDC) */
#define SD_CMD24 (0x40+24)
/* WRITE_BLOCK */
#define SD_CMD25 (0x40+25)
/* WRITE_MULTIPLE_BLOCK */
#define SD_CMD55 (0x40+55)
/* APP_CMD */
#define SD_CMD58 (0x40+58)
/* READ_OCR */
/*
Command Argument Type Description
CMD0 None R1 Tell the card to reset and enter its idle state.
CMD16 32-bit Block Length R1 Select the block length.
CMD17 32-bit Block Address R1 Read a single block.
CMD24 32-bit Block Address R1 Write a single block.
CMD55 None R1 Next command will be application-specific (ACMDXX).
CMD58 None R3 Read OCR (Operating Conditions Register).
ACMD41 None R1 Initialize the card.
3 types of reply:
R1 : 1 byte :
bit
7 : always 0
6 : parameter error
5 : adress error
4 : erase seq num
3 : crc error
2 : illegal command
1 : erase resed
0 : in idle state
R2 : 2 byte (not interrested)
R3 : 5 bytes :
bit (byte 1) :
7 : always 0
6 : parameter error
5 : adress error
4 : erase seq num
3 : crc error
2 : illegal command
1 : erase resed
0 : in idle state
bytes 2-5 : operating condition register, MSB first
*/
#include "../../version/ver_mdriver_ram.h"
#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2
#error Incompatible MDRIVER_RAM version number!
#endif
typedef
enum
{
SD_RESPONSE_R1
=
1
,
SD_RESPONSE_R2
=
1
,
SD_RESPONSE_R3
=
3
}
sd_response_type
;
static
int
sd_card_present
(
F_DRIVER
*
driver
);
static
int
sd_vol0_card_present
(
void
)
{
return
(
GPIO_PortInGet
(
gpioPortC
)
&
0x8
);
//pin = PC3
}
/*
* transform a 32 bit value into a 4 bytes array
*/
static
void
sd_packarg
(
unsigned
char
*
argument
,
unsigned
long
value
)
{
argument
[
3
]
=
(
unsigned
char
)(
value
>>
24
);
argument
[
2
]
=
(
unsigned
char
)(
value
>>
16
);
argument
[
1
]
=
(
unsigned
char
)(
value
>>
8
);
argument
[
0
]
=
(
unsigned
char
)(
value
);
}
typedef
struct
{
//TODO: we can improve and add the USART number here
unsigned
long
maxsector
;
int
use
;
struct
{
uint8_t
spiNumber
;
uint8_t
location
;
int
(
*
is_sd_card_present
)
(
void
);
void
(
*
spi_setupRXInt
)
(
char
*
receiveBuffer
,
int
bytesToReceive
);
void
(
*
spi_setupTXInt
)
(
char
*
transmitBuffer
,
int
transmitBufferSize
);
void
(
*
usart_wait_TX_finished
)
(
void
);
void
(
*
usart_wait_RX_finished
)
(
void
);
}
usart_data
;
F_DRIVER
*
driver
;
}
t_SdDrv
;
...
...
@@ -54,21 +116,68 @@ static F_DRIVER t_drivers[1];
static
t_SdDrv
SdDrv
[
1
]
=
{
{
(
MDRIVER_SD_VOLUME0_SIZE
/
MDRIVER_SD_SECTOR_SIZE
),
0
,
&
t_drivers
[
0
]
}
{
(
MDRIVER_SD_VOLUME0_SIZE
/
MDRIVER_SD_SECTOR_SIZE
),
0
,
{
1
,
1
,
sd_vol0_card_present
,
SPI1_setupRXInt
,
SPI1_setupTXInt
,
USART1_Wait_TX_finished
,
USART1_Wait_RX_finished
},
&
t_drivers
[
0
]
}
};
static
int
sd_card_send_command
(
F_DRIVER
*
driver
,
unsigned
char
command
,
unsigned
char
response_type
,
unsigned
char
*
argument
,
unsigned
char
*
response
)
{
t_SdDrv
*
pSdDrv
=
(
t_SdDrv
*
)
driver
->
user_ptr
;
char
txBuffer
[
5
];
char
rxBuffer
[
5
];
int
txSize
;
int
rxSize
;
int
i
;
if
(
response_type
==
SD_RESPONSE_R1
)
{
rxSize
=
1
;
}
else
if
(
response_type
==
SD_RESPONSE_R2
)
{
rxSize
=
2
;
}
else
{
rxSize
=
5
;
}
if
(
argument
==
NULL
)
{
txSize
=
1
;
}
else
{
txSize
=
5
;
}
txBuffer
[
0
]
=
command
;
for
(
i
=
1
;
i
<
txSize
;
i
++
)
{
txBuffer
[
i
]
=
argument
[
i
-
1
];
}
pSdDrv
->
usart_data
.
spi_setupRXInt
(
rxBuffer
,
rxSize
);
pSdDrv
->
usart_data
.
spi_setupTXInt
(
txBuffer
,
txSize
);
pSdDrv
->
usart_data
.
usart_wait_TX_finished
();
pSdDrv
->
usart_data
.
usart_wait_RX_finished
();
if
(
response
!=
NULL
)
{
for
(
i
=
1
;
i
<
rxSize
;
i
++
)
{
response
[
i
-
1
]
=
rxBuffer
[
i
];
}
}
return
1
;
//TODO: we could do check on bit 7 of 1st rx byte at least....
}
static
int
sd_readsector
(
F_DRIVER
*
driver
,
void
*
data
,
unsigned
long
sector
)
{
//TODO:implement sd_readsector
return
-
1
;
char
arg_sector_adress
[
4
];
sd_packarg
((
unsigned
char
*
)
arg_sector_adress
,
sector
);
return
sd_card_send_command
(
driver
,
SD_CMD17
,
SD_RESPONSE_R3
,
(
unsigned
char
*
)
arg_sector_adress
,
(
unsigned
char
*
)
data
);
}
static
int
sd_writesector
(
F_DRIVER
*
driver
,
void
*
data
,
unsigned
long
sector
)
{
//TODO:implement sd_writesector
return
-
1
;
t_SdDrv
*
pSdDrv
=
(
t_SdDrv
*
)
driver
->
user_ptr
;
char
arg_sector_adress
[
4
];
//first, transmit the adress where to write
sd_packarg
((
unsigned
char
*
)
arg_sector_adress
,
sector
);
if
(
sd_card_send_command
(
driver
,
SD_CMD17
,
SD_RESPONSE_R3
,
(
unsigned
char
*
)
arg_sector_adress
,
NULL
)
!=
0
)
{
return
-
1
;
}
//now, transmit the data to write
pSdDrv
->
usart_data
.
spi_setupTXInt
(
data
,
4
);
pSdDrv
->
usart_data
.
usart_wait_RX_finished
();
return
1
;
}
static
int
sd_getphy
(
F_DRIVER
*
driver
,
F_PHY
*
phy
)
{
t_SdDrv
*
p
=
(
t_SdDrv
*
)(
driver
->
user_ptr
);
if
(
sd_card_present
(
driver
)
!=
0
)
{
if
(
p
->
usart_data
.
is_sd_card_present
(
)
!=
0
)
{
return
MDRIVER_SD_ERR_NOTAVAILABLE
;
}
...
...
@@ -85,9 +194,6 @@ static void sd_release ( F_DRIVER * driver ) {
p
->
use
=
0
;
}
}
static
int
sd_card_present
(
F_DRIVER
*
driver
)
{
return
(
GPIO_PortInGet
(
gpioPortC
)
&
0x8
);
//pin = PC3
}
F_DRIVER
*
sd_initfunc
(
unsigned
long
driver_param
)
{
t_SdDrv
*
p
;
...
...
@@ -100,13 +206,22 @@ F_DRIVER * sd_initfunc ( unsigned long driver_param ) {
return
0
;
}
{
char
commandCRC
=
0x95
;
char
arg_block_length
[
4
];
GPIO_Mode_TypeDef
gpioModeSD_EN
=
gpioModeInput
;
GPIO_PinModeSet
(
gpioPortC
,
3
,
gpioModeSD_EN
,
0
);
/* init pin SD_EN to check if SD is plugged */
//TODO: check specif of SPI protocol and init SD through SPI protocol
/* Enabling clock to USART 1*/
CMU_ClockEnable
(
cmuClock_USART1
,
true
);
SPI_setup
(
1
,
1
,
1
);
//init SD SPI
//TODO: check specif of SD protocol and init SD through SPI + SD protocol
//TODO: check specif of SD protocol and init SD through SD protocol
//TODO: goto to IDLE state?
SPI1_setupTXInt
(
&
commandCRC
,
1
);
//no reply to answer from the CRC command
USART1_Wait_TX_finished
();
sd_packarg
((
unsigned
char
*
)
arg_block_length
,
MDRIVER_SD_SECTOR_SIZE
);
//set sector size
sd_card_send_command
(
p
,
SD_CMD16
,
SD_RESPONSE_R1
,
arg_block_length
,
NULL
);
(
void
)
psp_memset
(
p
->
driver
,
0
,
sizeof
(
F_DRIVER
)
);
...
...
sw/os-comparison/freertos_blink_fat/src/media-drv/sd/spi.c
View file @
380335f4
...
...
@@ -64,7 +64,7 @@ void SPI_setup(uint8_t spiNumber, uint8_t location, bool master)
switch
(
spiNumber
)
{
case
0
:
spi
=
USART
0
;
spi
=
USART
1
;
break
;
case
1
:
spi
=
USART1
;
...
...
@@ -183,13 +183,13 @@ void SPI_setup(uint8_t spiNumber, uint8_t location, bool master)
/**************************************************************************//**
* @brief USART
0
RX IRQ Handler Setup
* @brief USART
1
RX IRQ Handler Setup
* @param receiveBuffer points to where to place recieved data
* @param receiveBufferSize indicates the number of bytes to receive
*****************************************************************************/
void
SPI
0
_setupRXInt
(
char
*
receiveBuffer
,
int
receiveBufferSize
)
void
SPI
1
_setupRXInt
(
char
*
receiveBuffer
,
int
receiveBufferSize
)
{
USART_TypeDef
*
spi
=
USART
0
;
USART_TypeDef
*
spi
=
USART
1
;
/* Setting up pointer and indexes */
slaveRxBuffer
=
receiveBuffer
;
...
...
@@ -200,21 +200,21 @@ void SPI0_setupRXInt(char* receiveBuffer, int receiveBufferSize)
spi
->
CMD
=
USART_CMD_CLEARRX
;
/* Enable interrupts */
NVIC_ClearPendingIRQ
(
USART
0
_RX_IRQn
);
NVIC_EnableIRQ
(
USART
0
_RX_IRQn
);
NVIC_ClearPendingIRQ
(
USART
1
_RX_IRQn
);
NVIC_EnableIRQ
(
USART
1
_RX_IRQn
);
spi
->
IEN
|=
USART_IEN_RXDATAV
;
}
/**************************************************************************//**
* @brief USART
0
TX IRQ Handler Setup
* @brief USART
1
TX IRQ Handler Setup
* @param transmitBuffer points to the data to send
* @param transmitBufferSize indicates the number of bytes to send
*****************************************************************************/
void
SPI
0
_setupTXInt
(
char
*
transmitBuffer
,
int
transmitBufferSize
)
void
SPI
1
_setupTXInt
(
char
*
transmitBuffer
,
int
transmitBufferSize
)
{
USART_TypeDef
*
spi
=
USART
0
;
USART_TypeDef
*
spi
=
USART
1
;
/* Setting up pointer and indexes */
slaveTxBuffer
=
transmitBuffer
;
...
...
@@ -225,34 +225,34 @@ void SPI0_setupTXInt(char* transmitBuffer, int transmitBufferSize)
spi
->
CMD
=
USART_CMD_CLEARTX
;
/* Enable interrupts */
NVIC_ClearPendingIRQ
(
USART
0
_TX_IRQn
);
NVIC_EnableIRQ
(
USART
0
_TX_IRQn
);
NVIC_ClearPendingIRQ
(
USART
1
_TX_IRQn
);
NVIC_EnableIRQ
(
USART
1
_TX_IRQn
);
spi
->
IEN
|=
USART_IEN_TXBL
;
}
/**************************************************************************//**
* @brief USART
0
IRQ Handler Setup
* @brief USART
1
IRQ Handler Setup
* @param receiveBuffer points to where received data is to be stored
* @param receiveBufferSize indicates the number of bytes to receive
* @param transmitBuffer points to the data to send
* @param transmitBufferSize indicates the number of bytes to send
*****************************************************************************/
void
SPI
0
_setupSlaveInt
(
char
*
receiveBuffer
,
int
receiveBufferSize
,
char
*
transmitBuffer
,
int
transmitBufferSize
)
void
SPI
1
_setupSlaveInt
(
char
*
receiveBuffer
,
int
receiveBufferSize
,
char
*
transmitBuffer
,
int
transmitBufferSize
)
{
SPI
0
_setupRXInt
(
receiveBuffer
,
receiveBufferSize
);
SPI
0
_setupTXInt
(
transmitBuffer
,
transmitBufferSize
);
SPI
1
_setupRXInt
(
receiveBuffer
,
receiveBufferSize
);
SPI
1
_setupTXInt
(
transmitBuffer
,
transmitBufferSize
);
}
/**************************************************************************//**
* @brief USART
0
RX IRQ Handler
* @brief USART
1
RX IRQ Handler
*****************************************************************************/
void
USART
0
_RX_IRQHandler
(
void
)
void
USART
1
_RX_IRQHandler
(
void
)
{
USART_TypeDef
*
spi
=
USART
0
;
USART_TypeDef
*
spi
=
USART
1
;
uint8_t
rxdata
;
if
(
spi
->
STATUS
&
USART_STATUS_RXDATAV
)
...
...
@@ -272,11 +272,11 @@ void USART0_RX_IRQHandler(void)
/**************************************************************************//**
* @brief USART
0
TX IRQ Handler
* @brief USART
1
TX IRQ Handler
*****************************************************************************/
void
USART
0
_TX_IRQHandler
(
void
)
void
USART
1
_TX_IRQHandler
(
void
)
{
USART_TypeDef
*
spi
=
USART
0
;
USART_TypeDef
*
spi
=
USART
1
;
if
(
spi
->
STATUS
&
USART_STATUS_TXBL
)
{
...
...
@@ -300,11 +300,14 @@ void USART0_TX_IRQHandler(void)
}
}
#if 0
void USART0_Wait_TX_finished(void) {
USART_TypeDef *spi = USART0;
void
USART1_Wait_TX_finished
(
void
)
{
USART_TypeDef
*
spi
=
USART1
;
while
(
!
(
spi
->
STATUS
&
USART_STATUS_TXC
));
}
#endif
void
USART1_Wait_RX_finished
(
void
)
{
USART_TypeDef
*
spi
=
USART1
;
while
(
!
(
spi
->
STATUS
&
USART_STATUS_RXDATAV
));
}
sw/os-comparison/freertos_blink_fat/src/media-drv/sd/spi.h
View file @
380335f4
...
...
@@ -40,8 +40,11 @@
void
SPI_setup
(
uint8_t
spiNumber
,
uint8_t
location
,
bool
master
);
void
SPI0_setupRXInt
(
char
*
receiveBuffer
,
int
bytesToReceive
);
void
SPI0_setupSlaveInt
(
char
*
receiveBuffer
,
int
receiveBufferSize
,
char
*
transmitBuffer
,
int
transmitBufferSize
);
void
SPI1_setupRXInt
(
char
*
receiveBuffer
,
int
bytesToReceive
);
void
SPI1_setupTXInt
(
char
*
transmitBuffer
,
int
transmitBufferSize
);
void
SPI1_setupSlaveInt
(
char
*
receiveBuffer
,
int
receiveBufferSize
,
char
*
transmitBuffer
,
int
transmitBufferSize
);
void
USART1_Wait_TX_finished
(
void
);
void
USART1_Wait_RX_finished
(
void
);
#endif
sw/os-comparison/freertos_blink_fat/src/media-drv/sd/usart.c
View file @
380335f4
...
...
@@ -37,7 +37,7 @@
#include "em_gpio.h"
/******************************************************************************
* @brief sends data using USART
0
* @brief sends data using USART
1
* @param txBuffer points to data to transmit
* @param bytesToSend bytes will be sent
*****************************************************************************/
...
...
@@ -68,5 +68,53 @@ void USART1_sendBuffer(char* txBuffer, int bytesToSend)
while
(
!
(
uart
->
STATUS
&
USART_STATUS_TXC
))
;
}
//TODO:this function is implemented by Xavier and might not be correct, to be tested
/******************************************************************************
* @brief sends and receives data using USART1
* @param txBuffer points to data to transmit
* @param rxBuffer points to data to receive
* @param bytesToSend bytes will be sent and receive
*****************************************************************************/
void
USART1_sendreceiveBuffer
(
char
*
txBuffer
,
char
*
rxBuffer
,
int
bytesToSend
)
{
USART_TypeDef
*
uart
=
USART1
;
int
ii
;
char
dummyRx
;
/* Sending and receiving the data */
for
(
ii
=
0
;
ii
<=
bytesToSend
;
ii
++
)
{
/* Waiting for the usart to be ready */
while
(
!
(
uart
->
STATUS
&
USART_STATUS_TXBL
))
;
if
(
txBuffer
==
0
||
ii
>=
bytesToSend
)
//don't write last byte of data to send, it's only for reception
{
uart
->
TXDATA
=
0
;
}
else
{
/* Writing next byte to USART */
uart
->
TXDATA
=
*
txBuffer
;
txBuffer
++
;
}
if
(
rxBuffer
==
0
||
ii
==
0
)
//don't read first bit of reception: it's only for transmission
{
dummyRx
=
uart
->
RXDATA
;
}
else
{
/* wait byte to read being available */
while
(
!
(
uart
->
STATUS
&
USART_STATUS_RXDATAV
))
;
*
rxBuffer
=
uart
->
RXDATA
;
rxBuffer
++
;
}
}
/*Waiting for transmission of last byte */
while
(
!
(
uart
->
STATUS
&
USART_STATUS_TXC
))
;
}
sw/os-comparison/freertos_blink_fat/src/media-drv/sd/usart.h
View file @
380335f4
...
...
@@ -51,6 +51,7 @@
void
USART1_sendBuffer
(
char
*
,
int
);
void
USART1_sendreceiveBuffer
(
char
*
,
char
*
,
int
);
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment