提交 7ac09ece 编写于 作者: B bernard.xiong

add http mp3 file to play; add MMC card support in sdcard driver (by gzhuli)

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@100 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 0be4d1d5
......@@ -21,6 +21,7 @@
#include <finsh.h>
#include <stm32f10x.h>
#include "board.h"
#ifdef RT_USING_DFS
/* dfs init */
......@@ -140,6 +141,11 @@ void rt_init_thread_entry(void *parameter)
rt_kprintf("TCP/IP initialized!\n");
}
#endif
#if STM32_EXT_SRAM
/* init netbuf worker */
net_buf_init(320 * 1024);
#endif
}
int rt_application_init()
......
......@@ -24,7 +24,7 @@
/* whether use board external SRAM memory */
// <e>Use external SRAM memory on the board
// <i>Enable External SRAM memory
#define STM32_EXT_SRAM 0
#define STM32_EXT_SRAM 1
// <o>Begin Address of External SRAM
// <i>Default: 0x68000000
#define STM32_EXT_SRAM_BEGIN 0x68000000 /* the begining address of external SRAM */
......
......@@ -530,6 +530,8 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
if ((rx_status & 0xbf00) || (rx_len < 0x40)
|| (rx_len > DM9000_PKT_MAX))
{
rt_kprintf("rx error: status %04x\n", rx_status);
if (rx_status & 0x100)
{
rt_kprintf("rx fifo error\n");
......
/*
* http client for RT-Thread
*/
#include <rtthread.h>
#include "http.h"
#include <dfs_posix.h>
#include <lwip/sockets.h>
......@@ -13,19 +14,6 @@ const char _http_getend[] = " HTTP/1.0\r\n";
const char _http_user_agent[] = "User-Agent: RT-Thread HTTP Agent\r\n";
const char _http_endheader[] = "\r\n";
struct http_session
{
char* host;
int port;
char* user_agent;
int socket;
/* size of http file */
rt_size_t size;
rt_off_t position;
};
extern long int strtol(const char *nptr, char **endptr, int base);
//
......@@ -204,16 +192,50 @@ static int http_connect(struct http_session* session,
}
// Needs more error checking here.....
#if 0
rc = send( peer_handle, _http_get, sizeof( _http_get ) - 1, 0 );
rc = send( peer_handle, (void*) url, strlen( url ), 0 );
rc = send( peer_handle, _http_getend, sizeof( _http_getend ) - 1, 0 );
rc = send( peer_handle, _http_host, sizeof( _http_host ) - 1, 0 );
rc = send( peer_handle, host_addr, strlen( url ), 0 );
rc = send( peer_handle, host_addr, strlen( host_addr ), 0 );
rc = send( peer_handle, _http_endheader, sizeof( _http_endheader ) - 1, 0 ); // "\r\n"
rc = send( peer_handle, _http_user_agent, sizeof( _http_user_agent ) - 1, 0 );
rc = send( peer_handle, _http_endheader, sizeof( _http_endheader ) - 1, 0 );
#else
{
rt_uint8_t *ptr, *buf;
buf = rt_malloc (512);
ptr = buf;
rt_memcpy(ptr, _http_get, sizeof(_http_get) - 1);
ptr += sizeof(_http_get) - 1;
rt_memcpy(ptr, url, strlen(url));
ptr += strlen(url);
rt_memcpy(ptr, _http_getend, sizeof(_http_getend) - 1);
ptr += sizeof(_http_getend) - 1;
rt_memcpy(ptr, _http_host, sizeof(_http_host) - 1);
ptr += sizeof(_http_host) - 1;
rt_memcpy(ptr, host_addr, strlen(host_addr));
ptr += strlen(host_addr);
rt_memcpy(ptr, _http_endheader, sizeof(_http_endheader) - 1);
ptr += sizeof(_http_endheader) - 1;
rt_memcpy(ptr, _http_user_agent, sizeof(_http_user_agent) - 1);
ptr += sizeof(_http_user_agent) - 1;
rt_memcpy(ptr, _http_endheader, sizeof(_http_endheader) - 1);
ptr += sizeof(_http_endheader) - 1;
rc = send(peer_handle, buf,
(rt_uint32_t)ptr - (rt_uint32_t)buf, 0);
}
#endif
// We now need to read the header information
while ( 1 )
......@@ -356,7 +378,7 @@ void http_test(char* url)
return;
}
do
do
{
rt_memset(buffer, 0, sizeof(buffer));
length = http_session_read(session, buffer, sizeof(buffer));
......
#ifndef __HTTP_H__
#define __HTTP_H__
#include <rtthread.h>
struct http_session
{
char* host;
int port;
char* user_agent;
int socket;
/* size of http file */
rt_size_t size;
rt_off_t position;
};
struct http_session* http_session_open(char* url);
rt_size_t http_session_read(struct http_session* session, rt_uint8_t *buffer, rt_size_t length);
rt_off_t http_session_seek(struct http_session* session, rt_off_t offset, int mode);
int http_session_close(struct http_session* session);
#endif
......@@ -2,15 +2,12 @@
#include <dfs_posix.h>
#include <mp3/pub/mp3dec.h>
#include "board.h"
#include "netbuffer.h"
#define MP3_AUDIO_BUF_SZ 4096
#define MP3_DECODE_MP_CNT 2
#define MP3_DECODE_MP_SZ 2560
#define STATIC_MEMORY_POOL
#ifdef STATIC_MEMORY_POOL
static rt_uint8_t mempool[(MP3_DECODE_MP_SZ * 2 + 4)* 2]; // 5k x 2
static struct rt_mempool _mp;
#endif
rt_uint8_t mp3_fd_buffer[MP3_AUDIO_BUF_SZ];
struct mp3_decoder
{
......@@ -20,7 +17,8 @@ struct mp3_decoder
rt_uint32_t frames;
/* mp3 file descriptor */
int fd;
rt_size_t (*fetch_data)(void* parameter, rt_uint8_t *buffer, rt_size_t length);
void* fetch_parameter;
/* mp3 read session */
rt_uint8_t *read_buffer;
......@@ -28,22 +26,18 @@ struct mp3_decoder
rt_int32_t read_offset;
rt_uint32_t bytes_left, bytes_left_before_decoding;
/* mp3 decode memory pool */
rt_mp_t mp;
/* audio device */
rt_device_t snd_device;
};
static rt_err_t mp3_decoder_tx_done(rt_device_t dev, void *buffer)
{
/* release memory block to memory pool */
rt_mp_free(buffer);
/* release memory block */
sbuf_release(buffer);
return RT_EOK;
}
rt_uint8_t mp3_fd_buffer[MP3_AUDIO_BUF_SZ];
void mp3_decoder_init(struct mp3_decoder* decoder)
{
RT_ASSERT(decoder != RT_NULL);
......@@ -57,14 +51,6 @@ void mp3_decoder_init(struct mp3_decoder* decoder)
decoder->read_buffer = &mp3_fd_buffer[0];
if (decoder->read_buffer == RT_NULL) return;
/* create memory pool for decoding */
#ifdef STATIC_MEMORY_POOL
rt_mp_init(&_mp, "mp3", &mempool[0], sizeof(mempool), MP3_DECODE_MP_SZ * 2);
decoder->mp = &_mp;
#else
decoder->mp = rt_mp_create("mp3dec", MP3_DECODE_MP_CNT, MP3_DECODE_MP_SZ * 2);
#endif
decoder->decoder = MP3InitDecoder();
/* open audio device */
......@@ -84,16 +70,9 @@ void mp3_decoder_detach(struct mp3_decoder* decoder)
/* close audio device */
if (decoder->snd_device != RT_NULL)
rt_device_close(decoder->snd_device);
/* release mp3 decoder */
MP3FreeDecoder(decoder->decoder);
#ifdef STATIC_MEMORY_POOL
rt_mp_detach(decoder->mp);
#else
/* delete memory pool for decoding */
rt_mp_delete(decoder->mp);
#endif
}
struct mp3_decoder* mp3_decoder_create()
......@@ -136,11 +115,12 @@ static rt_int32_t mp3_decoder_fill_buffer(struct mp3_decoder* decoder)
bytes_to_read = (MP3_AUDIO_BUF_SZ - decoder->bytes_left) & ~(512 - 1);
// rt_kprintf("read bytes: %d\n", bytes_to_read);
if (is_first) is_first = 0;
else current_offset += MP3_AUDIO_BUF_SZ - decoder->bytes_left;
bytes_read = read(decoder->fd, (char *)(decoder->read_buffer + decoder->bytes_left),
bytes_read = decoder->fetch_data(decoder->fetch_parameter,
(rt_uint8_t *)(decoder->read_buffer + decoder->bytes_left),
bytes_to_read);
if (bytes_read == bytes_to_read)
......@@ -210,7 +190,7 @@ int mp3_decoder_run(struct mp3_decoder* decoder)
#endif
/* get a decoder buffer */
buffer = (rt_uint16_t*)rt_mp_alloc(decoder->mp, RT_WAITING_FOREVER);
buffer = (rt_uint16_t*)sbuf_alloc();
// rt_kprintf("bytes left before decode: %d\n", decoder->bytes_left);
......@@ -218,7 +198,7 @@ int mp3_decoder_run(struct mp3_decoder* decoder)
(int*)&decoder->bytes_left, (short*)buffer, 0);
// rt_kprintf("bytes left after decode: %d\n", decoder->bytes_left);
decoder->frames++;
if (err != ERR_MP3_NONE)
......@@ -278,7 +258,7 @@ int mp3_decoder_run(struct mp3_decoder* decoder)
}
/* release this memory block */
rt_mp_free(buffer);
sbuf_release(buffer);
}
else
{
......@@ -304,24 +284,82 @@ int mp3_decoder_run(struct mp3_decoder* decoder)
}
#include <finsh.h>
rt_size_t fd_fetch(void* parameter, rt_uint8_t *buffer, rt_size_t length)
{
int fd = (int)parameter;
return read(fd, (char*)buffer, length);
}
void mp3(char* filename)
{
int fd;
struct mp3_decoder* decoder;
fd = open(filename, O_RDONLY, 0);
if (fd >= 0)
{
decoder = mp3_decoder_create();
if (decoder != RT_NULL)
{
decoder->fd = fd;
decoder->fetch_data = fd_fetch;
decoder->fetch_parameter = (void*)fd;
while (mp3_decoder_run(decoder) != -1);
close(fd);
/* delete decoder object */
mp3_decoder_delete(decoder);
}
}
}
FINSH_FUNCTION_EXPORT(mp3, mp3 decode test)
FINSH_FUNCTION_EXPORT(mp3, mp3 decode test);
#if STM32_EXT_SRAM
/* http mp3 */
#include "http.h"
static rt_size_t http_fetch(rt_uint8_t* ptr, rt_size_t len, void* parameter)
{
struct http_session* session = (struct http_session*)parameter;
RT_ASSERT(session != RT_NULL);
return http_session_read(session, ptr, len);
}
static void http_close(void* parameter)
{
struct http_session* session = (struct http_session*)parameter;
RT_ASSERT(session != RT_NULL);
http_session_close(session);
}
rt_size_t http_data_fetch(void* parameter, rt_uint8_t *buffer, rt_size_t length)
{
return net_buf_read(buffer, length);
}
void http_mp3(char* url)
{
struct http_session* session;
struct mp3_decoder* decoder;
session = http_session_open(url);
if (session != RT_NULL)
{
/* add a job to netbuf worker */
net_buf_add_job(http_fetch, http_close, (void*)session);
decoder = mp3_decoder_create();
if (decoder != RT_NULL)
{
decoder->fetch_data = http_data_fetch;
decoder->fetch_parameter = RT_NULL;
while (mp3_decoder_run(decoder) != -1);
/* delete decoder object */
mp3_decoder_delete(decoder);
}
session = RT_NULL;
}
}
FINSH_FUNCTION_EXPORT(http_mp3, http mp3 decode test);
#endif
#include <rthw.h>
#include <rtthread.h>
#include "netbuffer.h"
#define MP3_DECODE_MP_CNT 2
#define MP3_DECODE_MP_SZ 2560
static rt_uint8_t mempool[(MP3_DECODE_MP_SZ * 2 + 4)* 2]; // 5k x 2
static struct rt_mempool _mp;
static rt_bool_t is_inited = RT_FALSE;
rt_size_t sbuf_get_size()
{
return MP3_DECODE_MP_SZ * 2;
}
void sbuf_init()
{
rt_mp_init(&_mp, "mp3", &mempool[0], sizeof(mempool), MP3_DECODE_MP_SZ * 2);
}
void* sbuf_alloc()
{
if (is_inited == RT_FALSE)
{
sbuf_init();
is_inited = RT_TRUE;
}
return (rt_uint16_t*)rt_mp_alloc(&_mp, RT_WAITING_FOREVER);
}
void sbuf_release(void* ptr)
{
rt_mp_free(ptr);
}
#if STM32_EXT_SRAM
/* netbuf worker stat */
#define NETBUF_STAT_FREE 0
#define NETBUF_STAT_BUFFERING 1
#define NETBUF_STAT_BUSY 2
#define NETBUF_STAT_STOPPING 3
#define NETBUF_STAT_STOPPED 4
/* net buffer module */
struct net_buffer
{
/* read index and save index in the buffer */
rt_size_t read_index, save_index;
/* buffer data and size of buffer */
rt_uint8_t* buffer_data;
rt_size_t data_length;
rt_size_t size;
/* buffer ready water mater */
rt_uint32_t ready_wm, resume_wm;
rt_bool_t is_wait_ready, is_wait_resume;
rt_sem_t wait_ready, wait_resume;
/* netbuf worker stat */
rt_uint8_t stat;
};
struct net_buffer_job
{
rt_size_t (*fetch)(rt_uint8_t* ptr, rt_size_t len, void* parameter);
void (*close)(void* parameter);
void* parameter;
};
static struct net_buffer _netbuf;
static rt_mq_t _netbuf_mq = RT_NULL;
rt_size_t net_buf_read(rt_uint8_t* buffer, rt_size_t length)
{
rt_size_t data_length, read_index;
rt_uint32_t level;
data_length = _netbuf.data_length;
if ((data_length == 0) &&
(_netbuf.stat != NETBUF_STAT_STOPPED && _netbuf.stat != NETBUF_STAT_STOPPING))
{
/* set stat */
_netbuf.stat = NETBUF_STAT_BUFFERING;
rt_kprintf("stat -> buffering\n");
/* buffer is not ready. */
_netbuf.is_wait_ready = RT_TRUE;
rt_kprintf("wait ready, data len: %d, stat %d\n", data_length, _netbuf.stat);
rt_sem_take(_netbuf.wait_ready, RT_WAITING_FOREVER);
}
if ((data_length <= _netbuf.ready_wm) &&
(_netbuf.stat == NETBUF_STAT_BUFFERING))
{
/* buffer is not ready. */
_netbuf.is_wait_ready = RT_TRUE;
rt_kprintf("wait ready, data len: %d, stat %d\n", data_length, _netbuf.stat);
rt_sem_take(_netbuf.wait_ready, RT_WAITING_FOREVER);
}
/* get read and save index */
read_index = _netbuf.read_index;
/* re-get data legnth */
data_length = _netbuf.data_length;
/* set the length */
if (length > data_length) length = data_length;
// rt_kprintf("data len: %d, read idx %d\n", data_length, read_index);
if (data_length > 0)
{
/* copy buffer */
if (_netbuf.size - read_index > length)
{
rt_memcpy(buffer, &_netbuf.buffer_data[read_index],
length);
_netbuf.read_index += length;
}
else
{
rt_memcpy(buffer, &_netbuf.buffer_data[read_index],
_netbuf.size - read_index);
rt_memcpy(&buffer[_netbuf.size - read_index],
&_netbuf.buffer_data[0],
length - (_netbuf.size - read_index));
_netbuf.read_index = length - (_netbuf.size - read_index);
}
level = rt_hw_interrupt_disable();
_netbuf.data_length -= length;
data_length = _netbuf.data_length;
if ((_netbuf.is_wait_resume == RT_TRUE) && data_length < _netbuf.resume_wm)
{
_netbuf.is_wait_resume = RT_FALSE;
rt_hw_interrupt_enable(level);
rt_kprintf("resume netbuf worker\n");
rt_sem_release(_netbuf.wait_resume);
}
else
{
rt_hw_interrupt_enable(level);
}
}
return length;
}
void net_buf_add_job(rt_size_t (*fetch)(rt_uint8_t* ptr, rt_size_t len, void* parameter),
void (*close)(void* parameter),
void* parameter)
{
struct net_buffer_job job;
job.fetch = fetch;
job.close = close;
job.parameter = parameter;
rt_mq_send(_netbuf_mq, (void*)&job, sizeof(struct net_buffer_job));
}
void net_buf_stop_job()
{
rt_uint32_t level;
level = rt_hw_interrupt_disable();
_netbuf.stat = NETBUF_STAT_STOPPING;
rt_kprintf("stat -> stopping\n");
rt_hw_interrupt_enable(level);
}
static void net_buf_do_stop(struct net_buffer_job* job)
{
/* source closed */
job->close(job->parameter);
_netbuf.stat = NETBUF_STAT_STOPPED;
rt_kprintf("stat -> stopped\n");
if (_netbuf.is_wait_ready == RT_TRUE)
{
/* resume the wait for buffer task */
_netbuf.is_wait_ready = RT_FALSE;
rt_sem_release(_netbuf.wait_ready);
}
rt_kprintf("job done, stat %d\n", _netbuf.stat);
}
#define NETBUF_BLOCK_SIZE 1024
static void net_buf_do_job(struct net_buffer_job* job)
{
rt_uint32_t level;
rt_size_t read_length, data_length;
rt_uint8_t *ptr;
ptr = rt_malloc(NETBUF_BLOCK_SIZE);
while (1)
{
if (_netbuf.stat == NETBUF_STAT_STOPPING)
{
net_buf_do_stop(job);
break;
}
/* fetch data buffer */
read_length = job->fetch(ptr, NETBUF_BLOCK_SIZE, job->parameter);
if (read_length <= 0)
{
net_buf_do_stop(job);
break;
}
else
{
/* got data length in the buffer */
data_length = _netbuf.data_length;
/* check avaible buffer to save */
if ((_netbuf.size - data_length) < read_length)
{
rt_err_t result;
_netbuf.is_wait_resume = RT_TRUE;
rt_kprintf("netbuf suspend, avaible room %d\n", data_length);
result = rt_sem_take(_netbuf.wait_resume, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
/* stop net buffer worker */
net_buf_do_stop(job);
break;
}
}
/* there are free space to fetch data */
if ((_netbuf.size - _netbuf.save_index) < read_length)
{
rt_memcpy(&_netbuf.buffer_data[_netbuf.save_index],
ptr, _netbuf.size - _netbuf.save_index);
rt_memcpy(&_netbuf.buffer_data[0],
ptr + (_netbuf.size - _netbuf.save_index),
read_length - (_netbuf.size - _netbuf.save_index));
/* move save index */
_netbuf.save_index = read_length - (_netbuf.size - _netbuf.save_index);
}
else
{
rt_memcpy(&_netbuf.buffer_data[_netbuf.save_index],
ptr, read_length);
/* move save index */
_netbuf.save_index += read_length;
if (_netbuf.save_index >= _netbuf.size) _netbuf.save_index = 0;
}
level = rt_hw_interrupt_disable();
_netbuf.data_length += read_length;
data_length = _netbuf.data_length;
rt_hw_interrupt_enable(level);
}
rt_kprintf("buffering ... %d %c\n", (data_length * 100) / _netbuf.size, '%');
if ((_netbuf.stat == NETBUF_STAT_BUFFERING) && (data_length >= _netbuf.ready_wm))
{
_netbuf.stat = NETBUF_STAT_BUSY;
rt_kprintf("stat -> busy\n");
/* notify the thread for waitting buffer ready */
rt_kprintf("resume wait buffer\n");
if (_netbuf.is_wait_ready == RT_TRUE)
{
_netbuf.is_wait_ready = RT_FALSE;
rt_sem_release(_netbuf.wait_ready);
}
}
}
/* release fetch buffer */
rt_free(ptr);
}
static void net_buf_thread_entry(void* parameter)
{
rt_err_t result;
struct net_buffer_job job;
while (1)
{
/* get a job */
result = rt_mq_recv(_netbuf_mq, (void*)&job, sizeof(struct net_buffer_job), RT_WAITING_FOREVER);
if (result == RT_EOK)
{
_netbuf.stat = NETBUF_STAT_BUFFERING;
rt_kprintf("stat -> buffering\n");
/* perform the job */
net_buf_do_job(&job);
}
}
}
void net_buf_init(rt_size_t size)
{
rt_thread_t tid;
/* init net buffer structure */
_netbuf.read_index = _netbuf.save_index = 0;
_netbuf.size = size; /* net buffer size */
/* allocate buffer */
_netbuf.buffer_data = rt_malloc(_netbuf.size);
_netbuf.data_length = 0;
/* set ready and resume water mater */
_netbuf.ready_wm = _netbuf.size * 90/100;
_netbuf.resume_wm = _netbuf.size * 80/100;
/* set init stat */
_netbuf.stat = NETBUF_STAT_FREE;
rt_kprintf("stat -> free\n");
_netbuf.wait_ready = rt_sem_create("nready", 0, RT_IPC_FLAG_FIFO);
_netbuf.wait_resume = rt_sem_create("nresum", 0, RT_IPC_FLAG_FIFO);
_netbuf.is_wait_ready = RT_FALSE;
_netbuf.is_wait_resume = RT_FALSE;
/* crate message queue */
_netbuf_mq = rt_mq_create("njob", sizeof(struct net_buffer_job),
4, RT_IPC_FLAG_FIFO);
/* create net buffer thread */
tid = rt_thread_create("nbuf",
net_buf_thread_entry, RT_NULL,
1024, 22, 5);
if (tid != RT_NULL)
rt_thread_startup(tid);
}
#endif
#ifndef __NET_BUF_H__
#define __NET_BUF_H__
#include <rtthread.h>
#include "board.h"
/* SRAM buffer pool routine */
rt_size_t sbuf_get_size(void);
void* sbuf_alloc(void);
void sbuf_release(void* ptr);
#if STM32_EXT_SRAM
/* net buffer routine */
void net_buf_init(rt_size_t size);
rt_size_t net_buf_read(rt_uint8_t* buffer, rt_size_t length);
void net_buf_add_job(rt_size_t (*fetch)(rt_uint8_t* ptr, rt_size_t len, void* parameter),
void (*close)(void* parameter),
void* parameter);
void net_buf_stop_job(void);
#endif
#endif
此差异已折叠。
......@@ -13,24 +13,28 @@ Group (Filesystem)
Group (LwIP)
Group (mp3)
File 1,5,<.\rtconfig.h><rtconfig.h>
File 1,5,<.\board.h><board.h>
File 1,5,<.\stm32f10x_conf.h><stm32f10x_conf.h>
File 1,1,<.\application.c><application.c>
File 1,1,<.\board.c><board.c>
File 1,1,<.\startup.c><startup.c>
File 1,1,<.\stm32f10x_it.c><stm32f10x_it.c>
File 1,5,<.\stm32f10x_conf.h><stm32f10x_conf.h>
File 1,5,<.\rtconfig.h><rtconfig.h>
File 1,1,<.\usart.c><usart.c>
File 1,1,<.\sdcard.c><sdcard.c>
File 1,1,<.\rtc.c><rtc.c>
File 1,1,<.\mp3.c><mp3.c>
File 1,1,<.\wm8753.c><wm8753.c>
File 1,1,<.\wav.c><wav.c>
File 1,1,<.\dm9000.c><dm9000.c>
File 1,1,<.\fsmc_nand.c><fsmc_nand.c>
File 1,1,<.\fsmc_sram.c><fsmc_sram.c>
File 1,1,<.\fmt0371\fmt0371.c><fmt0371.c>
File 1,1,<.\http.c><http.c>
File 1,1,<.\lcd.c><lcd.c>
File 1,1,<..\..\net\apps\tcpecho.c><tcpecho.c>
File 1,1,<..\..\net\apps\udpecho.c><udpecho.c>
File 1,1,<.\mp3.c><mp3.c>
File 1,1,<.\wav.c><wav.c>
File 1,1,<.\netbuffer.c><netbuffer.c>
File 2,1,<..\..\src\clock.c><clock.c>
File 2,1,<..\..\src\idle.c><idle.c>
File 2,1,<..\..\src\ipc.c><ipc.c>
......@@ -260,7 +264,7 @@ Options 1,9,0 // Group 'mp3'
StopCode=11
CustArgs ()
LibMods ()
ADSCCFLG { 6,84,85,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
ADSCCFLG { 18,84,85,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
ADSCMISC ()
ADSCDEFN ()
ADSCUDEF ()
......
......@@ -55,6 +55,7 @@
#define SD_HIGH_CAPACITY ((u32)0x40000000)
#define SD_STD_CAPACITY ((u32)0x00000000)
#define SD_CHECK_PATTERN ((u32)0x000001AA)
#define SD_VOLTAGE_WINDOW_MMC ((u32)0x80FF8000)
#define SD_MAX_VOLT_TRIAL ((u32)0x0000FFFF)
#define SD_ALLZERO ((u32)0x00000000)
......@@ -310,8 +311,40 @@ SD_Error SD_PowerON(void)
}
}/* else MMC Card */
else
{
CardType = SDIO_MULTIMEDIA_CARD;
return(errorstatus);
/* Send CMD1 SEND_OP_COND with Argument 0x80FF8000 */
while ((!validvoltage) && (count < SD_MAX_VOLT_TRIAL))
{
/* SEND CMD55 APP_CMD with RCA as 0 */
SDIO_CmdInitStructure.SDIO_Argument = SD_VOLTAGE_WINDOW_MMC;
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_OP_COND;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp3Error();
if (errorstatus != SD_OK)
{
return(errorstatus);
}
response = SDIO_GetResponse(SDIO_RESP1);
validvoltage = (bool) (((response >> 31) == 1) ? 1 : 0);
count++;
}
if (count >= SD_MAX_VOLT_TRIAL)
{
errorstatus = SD_INVALID_VOLTRANGE;
return(errorstatus);
}
}
return(SD_OK);
}
/*******************************************************************************
......@@ -343,6 +376,7 @@ SD_Error SD_InitializeCards(void)
{
SD_Error errorstatus = SD_OK;
u16 rca = 0x01;
// u32 count = 0;
if (SDIO_GetPowerState() == SDIO_PowerState_OFF)
{
......@@ -391,6 +425,24 @@ SD_Error SD_InitializeCards(void)
return(errorstatus);
}
}
if (SDIO_MULTIMEDIA_CARD == CardType)
{
/* Send CMD3 SET_REL_ADDR with argument 0 */
/* SD Card publishes its RCA. */
SDIO_CmdInitStructure.SDIO_Argument = (u32)(rca << 16);
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_REL_ADDR;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp2Error();
if (SD_OK != errorstatus)
{
return(errorstatus);
}
}
if (SDIO_SECURE_DIGITAL_IO_CARD != CardType)
{
......
#include <finsh.h>
#include <dfs_posix.h>
#include "netbuffer.h"
#include "stm32f10x.h"
rt_uint32_t wav_length;
rt_uint8_t* wav_buffer;
#define WAV_MP_NUM 2
#define WAV_MP_BUFSZ (1024 * 1)
#define STATIC_MEMPOOL
#ifdef STATIC_MEMPOOL
static rt_uint8_t mempool[(WAV_MP_BUFSZ + 4)* WAV_MP_NUM]; // 5k x 2
static struct rt_mempool _mp;
#endif
static rt_mp_t mp;
static rt_err_t wav_tx_done(rt_device_t dev, void *buffer)
{
/* release memory block to memory pool */
rt_mp_free(buffer);
/* release memory block */
sbuf_release(buffer);
return RT_EOK;
}
......@@ -25,13 +14,10 @@ static rt_err_t wav_tx_done(rt_device_t dev, void *buffer)
void wav(char* filename)
{
int fd;
rt_size_t block_size;
#ifdef STATIC_MEMPOOL
rt_mp_init(&_mp, "wav", &mempool[0], sizeof(mempool), WAV_MP_BUFSZ);
mp = &_mp;
#else
mp = rt_mp_create("wav", WAV_MP_NUM, WAV_MP_BUFSZ);
#endif
block_size = sbuf_get_size();
block_size = (block_size / 512) * 512;
fd = open(filename, O_RDONLY, 0);
if (fd >= 0)
......@@ -47,21 +33,15 @@ void wav(char* filename)
do
{
buf = rt_mp_alloc(mp, RT_WAITING_FOREVER);
len = read(fd, (char*)buf, WAV_MP_BUFSZ);
buf = sbuf_alloc();
len = read(fd, (char*)buf, block_size);
if (len > 0) rt_device_write(device, 0, buf, len);
} while (len != 0);
/* close device and file */
rt_device_close(device);
close(fd);
/* delete memory pool */
#ifdef STATIC_MEMPOOL
rt_mp_detach(mp);
#else
rt_mp_delete(mp);
#endif
}
}
FINSH_FUNCTION_EXPORT(wav, wav test)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册