Browse Source

update stm32 radio code; add backspace key support in finsh;

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@22 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 15 years ago
parent
commit
e00da562ed

+ 2 - 2
bsp/stm32_radio/application.c

@@ -69,8 +69,8 @@ void rt_init_thread_entry(void *parameter)
 
 int rt_application_init()
 {
-	rt_thread_t init_thread;
-
+	rt_thread_t init_thread;
+
 	init_thread = rt_thread_create("init",
 								rt_init_thread_entry, RT_NULL,
 								1024, 8, 20);

+ 135 - 161
bsp/stm32_radio/board.c

@@ -25,8 +25,6 @@ static void rt_hw_console_init(void);
 
 /*@{*/
 
-ErrorStatus HSEStartUpStatus;
-
 /*******************************************************************************
  * Function Name  : RCC_Configuration
  * Description    : Configures the different system clocks.
@@ -35,7 +33,9 @@ ErrorStatus HSEStartUpStatus;
  * Return         : None
  *******************************************************************************/
 void RCC_Configuration(void)
-{
+{
+	ErrorStatus HSEStartUpStatus;
+
 	/* RCC system reset(for debug purpose) */
 	RCC_DeInit();
 
@@ -133,6 +133,114 @@ void rt_hw_timer_handler(void)
 	rt_interrupt_leave();
 	rt_hw_interrupt_thread_switch();
 }
+
+
+/*******************************************************************************
+* Function Name  : LCD_CtrlLinesConfig
+* Description    : Configures LCD Control lines (FSMC Pins) in alternate function
+                   Push-Pull mode.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void LCD_CtrlLinesConfig(void)
+{
+	GPIO_InitTypeDef GPIO_InitStructure;
+	
+	/* Enable FSMC, GPIOD, GPIOE, GPIOF, GPIOG and AFIO clocks */
+	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
+	
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |
+		RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG |
+		RCC_APB2Periph_AFIO, ENABLE);
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+	// GPIO_Init(GPIOA, &GPIO_InitStructure);
+	// GPIO_ResetBits(GPIOA, GPIO_Pin_8);
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
+	GPIO_Init(GPIOC, &GPIO_InitStructure);
+	GPIO_SetBits(GPIOC, GPIO_Pin_6);
+
+	/* Set PD.00(D2), PD.01(D3), PD.04(NOE), PD.05(NWE), PD.08(D13), PD.09(D14),
+	 PD.10(D15), PD.14(D0), PD.15(D1) as alternate 
+	 function push pull */
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
+	                            GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | 
+	                            GPIO_Pin_15;
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+	GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+	/* Set PE.07(D4), PE.08(D5), PE.09(D6), PE.10(D7), PE.11(D8), PE.12(D9), PE.13(D10),
+	 PE.14(D11), PE.15(D12) as alternate function push pull */
+	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | 
+	                            GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | 
+	                            GPIO_Pin_15;
+	GPIO_Init(GPIOE, &GPIO_InitStructure);
+
+	// GPIO_WriteBit(GPIOE, GPIO_Pin_6, Bit_SET);
+	/* Set PF.00(A0 (RS)) as alternate function push pull */
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
+	GPIO_Init(GPIOF, &GPIO_InitStructure);
+	
+	/* Set PG.12(NE4 (LCD/CS)) as alternate function push pull - CE3(LCD /CS) */
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
+	GPIO_Init(GPIOG, &GPIO_InitStructure);
+}
+
+/*******************************************************************************
+* Function Name  : LCD_FSMCConfig
+* Description    : Configures the Parallel interface (FSMC) for LCD(Parallel mode)
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void LCD_FSMCConfig(void)
+{
+	FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
+	FSMC_NORSRAMTimingInitTypeDef  p;
+	
+	/*-- FSMC Configuration ------------------------------------------------------*/
+	/*----------------------- SRAM Bank 4 ----------------------------------------*/
+	/* FSMC_Bank1_NORSRAM4 configuration */
+	p.FSMC_AddressSetupTime = 0;
+	p.FSMC_AddressHoldTime = 0;
+	p.FSMC_DataSetupTime = 2;
+	p.FSMC_BusTurnAroundDuration = 0;
+	p.FSMC_CLKDivision = 0;
+	p.FSMC_DataLatency = 0;
+	p.FSMC_AccessMode = FSMC_AccessMode_A;
+	
+	/* Color LCD configuration ------------------------------------
+	 LCD configured as follow:
+	    - Data/Address MUX = Disable
+	    - Memory Type = SRAM
+	    - Data Width = 16bit
+	    - Write Operation = Enable
+	    - Extended Mode = Enable
+	    - Asynchronous Wait = Disable */
+	FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;
+	FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
+	FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
+	FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
+	FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
+	FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
+	FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
+	FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
+	FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
+	FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
+	FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
+	// FSMC_NORSRAMInitStructure.FSMC_AsyncWait = FSMC_AsyncWait_Disable;
+	FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
+	FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
+	FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
+	
+	FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);  
+	
+	/* BANK 4 (of NOR/SRAM Bank 1~4) is enabled */
+	FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);
+}
 
 /*******************************************************************************
 * Function Name  : FSMC_SRAM_Init
@@ -145,166 +253,32 @@ void rt_hw_timer_handler(void)
 *******************************************************************************/
 void FSMC_SRAM_Init(void)
 {
-  FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
-  FSMC_NORSRAMTimingInitTypeDef  p;
-  GPIO_InitTypeDef GPIO_InitStructure; 
-  
-  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOG | RCC_APB2Periph_GPIOE |
-                         RCC_APB2Periph_GPIOF, ENABLE);
-  
-/*-- GPIO Configuration ------------------------------------------------------*/
-  /* SRAM Data lines configuration */
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |
-                                GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-  GPIO_Init(GPIOD, &GPIO_InitStructure); 
-  
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
-                                GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | 
-                                GPIO_Pin_15;
-  GPIO_Init(GPIOE, &GPIO_InitStructure);
-  
-  /* SRAM Address lines configuration */
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | 
-                                GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 | 
-                                GPIO_Pin_14 | GPIO_Pin_15;
-  GPIO_Init(GPIOF, &GPIO_InitStructure);
-  
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | 
-                                GPIO_Pin_4 | GPIO_Pin_5;
-  GPIO_Init(GPIOG, &GPIO_InitStructure);
-  
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; 
-  GPIO_Init(GPIOD, &GPIO_InitStructure);
-   
-  /* NOE and NWE configuration */  
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5;
-  GPIO_Init(GPIOD, &GPIO_InitStructure);
-  
-  /* NE3 configuration */
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 
-  GPIO_Init(GPIOG, &GPIO_InitStructure);
-  
-  /* NBL0, NBL1 configuration */
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; 
-  GPIO_Init(GPIOE, &GPIO_InitStructure); 
-  
-/*-- FSMC Configuration ------------------------------------------------------*/
-  p.FSMC_AddressSetupTime = 0;
-  p.FSMC_AddressHoldTime = 0;
-  p.FSMC_DataSetupTime = 2;
-  p.FSMC_BusTurnAroundDuration = 0;
-  p.FSMC_CLKDivision = 0;
-  p.FSMC_DataLatency = 0;
-  p.FSMC_AccessMode = FSMC_AccessMode_A;
+#define REG32(x)	(*(volatile unsigned long*)(x))
 
-  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;
-  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
-  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
-  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
-  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
-  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
-  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
-  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
-  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
-  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
-  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
-  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
-  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
-  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
-
-  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); 
-
-  /* Enable FSMC Bank1_SRAM Bank */
-  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);  
+	/* enable FSMC clock */
+	REG32(0x40021014) = 0x114;
+	
+	/* enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
+	REG32(0x40021018) = 0x1e0;
+	
+	/* SRAM Data lines, NOE and NWE configuration */
+	REG32(0x40011400) = 0x44BB44BB;
+	REG32(0x40011404) = 0xBBBBBBBB;
+	REG32(0x40011800) = 0xB44444BB;
+	REG32(0x40011804) = 0xBBBBBBBB;
+	REG32(0x40011C00) = 0x44BBBBBB;
+	REG32(0x40011C04) = 0xBBBB4444;
+	REG32(0x40012000) = 0x44BBBBBB;
+	REG32(0x40012004) = 0x44444B44;
+	
+	/* FSMC Configuration (enable FSMC Bank1_SRAM Bank) */
+	REG32(0xA0000010) = 0x00001011;
+	REG32(0xA0000014) = 0x00000200;	
+	
+	LCD_CtrlLinesConfig();
+	LCD_FSMCConfig();
 }
 
-/*******************************************************************************
-* Function Name  : FSMC_NOR_Init
-* Description    : Configures the FSMC and GPIOs to interface with the NOR memory.
-*                  This function must be called before any write/read operation
-*                  on the NOR.
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void FSMC_NOR_Init(void)
-{
-  FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
-  FSMC_NORSRAMTimingInitTypeDef  p;
-  GPIO_InitTypeDef GPIO_InitStructure;
-
-  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | 
-                         RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
-
-  /*-- GPIO Configuration ------------------------------------------------------*/
-  /* NOR Data lines configuration */
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |
-                                GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-  GPIO_Init(GPIOD, &GPIO_InitStructure);
-
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
-                                GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 |
-                                GPIO_Pin_14 | GPIO_Pin_15;
-  GPIO_Init(GPIOE, &GPIO_InitStructure);
-
-  /* NOR Address lines configuration */
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
-                                GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 |
-                                GPIO_Pin_14 | GPIO_Pin_15;
-  GPIO_Init(GPIOF, &GPIO_InitStructure);
-
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 |
-                                GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;                            
-  GPIO_Init(GPIOG, &GPIO_InitStructure);
-
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
-  GPIO_Init(GPIOD, &GPIO_InitStructure);
-
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
-  GPIO_Init(GPIOE, &GPIO_InitStructure);
-
-  /* NOE and NWE configuration */
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
-  GPIO_Init(GPIOD, &GPIO_InitStructure);
-
-  /* NE2 configuration */
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
-  GPIO_Init(GPIOG, &GPIO_InitStructure);
-
-  /*-- FSMC Configuration ----------------------------------------------------*/
-  p.FSMC_AddressSetupTime = 0x03;
-  p.FSMC_AddressHoldTime = 0x00;
-  p.FSMC_DataSetupTime = 0x04;
-  p.FSMC_BusTurnAroundDuration = 0x00;
-  p.FSMC_CLKDivision = 0x00;
-  p.FSMC_DataLatency = 0x00;
-  p.FSMC_AccessMode = FSMC_AccessMode_B;
-
-  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
-  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
-  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
-  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
-  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
-  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
-  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
-  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
-  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
-  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
-  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
-  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
-  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
-  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
-
-  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
-
-  /* Enable FSMC Bank1_NOR Bank */
-  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE);
-}
-
 /**
  * This function will initial STM32 board.
  */
@@ -318,7 +292,7 @@ void rt_hw_board_init()
 	
 	/* SRAM init */
 	FSMC_SRAM_Init();
-	
+
 	/* Configure the SysTick */
 	SysTick_Configuration();
 	

+ 2 - 0
bsp/stm32_radio/board.h

@@ -14,6 +14,8 @@
 
 #ifndef __BOARD_H__
 #define __BOARD_H__
+
+#define RT_USING_SRAM
 
 void rt_hw_board_led_on(int n);
 void rt_hw_board_led_off(int n);

+ 242 - 128
bsp/stm32_radio/mp3.c

@@ -1,68 +1,153 @@
 #include <rtthread.h>
 #include <dfs_posix.h>
 #include <mp3/pub/mp3dec.h>
-#include "dac.h"
-
-static HMP3Decoder hMP3Decoder;
-static MP3FrameInfo mp3FrameInfo;
-static unsigned char *read_ptr;
-static int bytes_left=0, bytes_leftBeforeDecoding=0, err, offset;
-static int nFrames = 0;
-static unsigned char *mp3buf;
-static unsigned int mp3buf_size;
-static unsigned char allocated = 0;
-
-static void mp3_reset()
+
+#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
+
+struct mp3_decoder
+{
+    /* mp3 information */
+    HMP3Decoder decoder;
+    MP3FrameInfo frame_info;
+    rt_uint32_t frames;
+
+    /* mp3 file descriptor */
+    int fd;
+
+    /* mp3 read session */
+    rt_uint8_t *read_buffer;
+    rt_uint8_t* read_ptr;
+    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)
 {
-	read_ptr = RT_NULL;
-	bytes_leftBeforeDecoding = bytes_left = 0;
-	nFrames = 0;
+	/* release memory block to memory pool */
+	rt_mp_free(buffer);
+
+	return RT_EOK;
 }
 
-void mp3_init(rt_uint8_t *buffer, rt_uint32_t buffer_size)
+rt_uint8_t mp3_fd_buffer[MP3_AUDIO_BUF_SZ];
+void mp3_decoder_init(struct mp3_decoder* decoder)
 {
-	mp3buf = buffer;
-	mp3buf_size = buffer_size;
-	mp3_reset();
+    RT_ASSERT(decoder != RT_NULL);
+
+	/* init read session */
+	decoder->read_ptr = RT_NULL;
+	decoder->bytes_left_before_decoding = decoder->bytes_left = 0;
+	decoder->frames = 0;
+
+    // decoder->read_buffer = rt_malloc(MP3_AUDIO_BUF_SZ);
+    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 */
+	decoder->snd_device = rt_device_find("snd");
+	if (decoder->snd_device != RT_NULL)
+	{
+		/* set tx complete call back function */
+		rt_device_set_tx_complete(decoder->snd_device, mp3_decoder_tx_done);
+		rt_device_open(decoder->snd_device, RT_DEVICE_OFLAG_WRONLY);
+	}
 }
 
-void mp3_alloc()
+void mp3_decoder_detach(struct mp3_decoder* decoder)
 {
-	if (!allocated) hMP3Decoder = MP3InitDecoder();
-	allocated = 1;
+    RT_ASSERT(decoder != RT_NULL);
+
+	/* 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()
+{
+    struct mp3_decoder* decoder;
+
+	/* allocate object */
+    decoder = (struct mp3_decoder*) rt_malloc (sizeof(struct mp3_decoder));
+    if (decoder != RT_NULL)
+    {
+        mp3_decoder_init(decoder);
+    }
+
+    return decoder;
 }
 
-void mp3_free()
+void mp3_decoder_delete(struct mp3_decoder* decoder)
 {
-	if (allocated) MP3FreeDecoder(hMP3Decoder);
-	allocated = 0;
+    RT_ASSERT(decoder != RT_NULL);
+
+	/* de-init mp3 decoder object */
+	mp3_decoder_detach(decoder);
+	/* release this object */
+    rt_free(decoder);
 }
 
-int mp3_refill_inbuffer(int fd)
+rt_uint16_t is_first = 1;
+rt_uint32_t current_offset = 0;
+static rt_int32_t mp3_decoder_fill_buffer(struct mp3_decoder* decoder)
 {
-  rt_uint16_t bytes_read;
-  int bytes_to_read;
-  
-  // rt_kprintf("left: %d. refilling inbuffer...\n", bytes_left);
-  if (bytes_left > 0)
-  {
-    	// after fseeking backwards the FAT has to be read from the beginning -> S L O W
-		// assert(f_lseek(mp3file, mp3file->fptr - bytes_leftBeforeDecoding) == FR_OK);
+	rt_size_t bytes_read;
+	rt_size_t bytes_to_read;
+
+	// rt_kprintf("left: %d. refilling inbuffer...\n", decoder->bytes_left);
+	if (decoder->bytes_left > 0)
+	{
 		// better: move unused rest of buffer to the start
-		// no overlap as long as (1024 <= mp3buf_size/2), so no need to use memove
-		rt_memcpy(mp3buf, read_ptr, bytes_left);
-  }
-  
-  bytes_to_read = mp3buf_size - bytes_left;
-  
-	bytes_read = read(fd, (char *)mp3buf + bytes_left, bytes_to_read);
+		rt_memmove(decoder->read_buffer, decoder->read_ptr, decoder->bytes_left);
+	}
+
+	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_to_read);
+
 	if (bytes_read == bytes_to_read)
 	{
-		read_ptr = mp3buf;
-		offset = 0;
-		bytes_left = mp3buf_size;
-		// rt_kprintf("ok. read: %d. left: %d\n", bytes_read, bytes_left);
+		decoder->read_ptr = decoder->read_buffer;
+		decoder->read_offset = 0;
+		decoder->bytes_left = decoder->bytes_left + bytes_to_read;
 		return 0;
 	}
 	else
@@ -72,115 +157,147 @@ int mp3_refill_inbuffer(int fd)
 	}
 }
 
-int mp3_process(int fd)
+int mp3_decoder_run(struct mp3_decoder* decoder)
 {
-	int writeable_buffer;
-	
-	if (read_ptr == RT_NULL)
+	int err;
+	rt_uint16_t* buffer;
+
+    RT_ASSERT(decoder != RT_NULL);
+
+	if ((decoder->read_ptr == RT_NULL) || decoder->bytes_left < 2*MAINBUF_SIZE)
 	{
-		if(mp3_refill_inbuffer(fd) != 0)
-		  return -1;
+		if(mp3_decoder_fill_buffer(decoder) != 0)
+			return -1;
 	}
 
-	offset = MP3FindSyncWord(read_ptr, bytes_left);
-	if (offset < 0)
+	// rt_kprintf("read offset: 0x%08x\n", decoder->read_ptr - decoder->read_buffer);
+	decoder->read_offset = MP3FindSyncWord(decoder->read_ptr, decoder->bytes_left);
+	if (decoder->read_offset < 0)
 	{
 		rt_kprintf("Error: MP3FindSyncWord returned <0");
-		
-		if(mp3_refill_inbuffer(fd) != 0)
-		  return -1;
+
+		if(mp3_decoder_fill_buffer(decoder) != 0)
+			return -1;
 	}
+	// rt_kprintf("sync position: %x\n", decoder->read_offset);
 
-	read_ptr += offset;
-	bytes_left -= offset;
-	bytes_leftBeforeDecoding = bytes_left;
+	decoder->read_ptr += decoder->read_offset;
+	decoder->bytes_left -= decoder->read_offset;
+	decoder->bytes_left_before_decoding = decoder->bytes_left;
 
+#if 0
 	// check if this is really a valid frame
 	// (the decoder does not seem to calculate CRC, so make some plausibility checks)
-	if (MP3GetNextFrameInfo(hMP3Decoder, &mp3FrameInfo, read_ptr) == 0 &&
-		mp3FrameInfo.nChans == 2 &&
-		mp3FrameInfo.version == 0)
-	{
-		// rt_kprintf("Found a frame at offset %x\n", offset + read_ptr - mp3buf + mp3file->fptr);
-	}
-	else
+	if (!(MP3GetNextFrameInfo(decoder->decoder, &decoder->frame_info, decoder->read_ptr) == 0 &&
+			decoder->frame_info.nChans == 2 &&
+			decoder->frame_info.version == 0))
 	{
-		rt_kprintf("this is no valid frame\n");
+		rt_kprintf("this is an invalid frame\n");
 		// advance data pointer
 		// TODO: handle bytes_left == 0
-		RT_ASSERT(bytes_left > 0);
-		bytes_left -= 1;
-		read_ptr += 1;
+		RT_ASSERT(decoder->bytes_left > 0);
+
+		decoder->bytes_left --;
+		decoder->read_ptr ++;
 		return 0;
 	}
 
-	if (bytes_left < 1024) {
-		if(mp3_refill_inbuffer(fd) != 0)
-		  return -1;
+	if (decoder->bytes_left < 1024)
+	{
+		if(mp3_decoder_fill_buffer(decoder) != 0)
+			return -1;
 	}
+#endif
 
-	// rt_kprintf("bytes_leftBeforeDecoding: %i\n", bytes_leftBeforeDecoding);
-
-	writeable_buffer = dac_get_writeable_buffer();
-	if (writeable_buffer == -1) {
-		return 0;
-	}
+    /* get a decoder buffer */
+    buffer = (rt_uint16_t*)rt_mp_alloc(decoder->mp, RT_WAITING_FOREVER);
 
-	// rt_kprintf("wb %i\n", writeable_buffer);
+	// rt_kprintf("bytes left before decode: %d\n", decoder->bytes_left);
 
-	err = MP3Decode(hMP3Decoder, &read_ptr, &bytes_left, dac_buffer[writeable_buffer], 0);
+	err = MP3Decode(decoder->decoder, &decoder->read_ptr,
+        (int*)&decoder->bytes_left, (short*)buffer, 0);
 
-	nFrames++;
+	// rt_kprintf("bytes left after decode: %d\n", decoder->bytes_left);
 	
-	if (err)
+	decoder->frames++;
+
+	if (err != ERR_MP3_NONE)
 	{
- 		switch (err)
+		switch (err)
 		{
 		case ERR_MP3_INDATA_UNDERFLOW:
-			rt_kprintf("ERR_MP3_INDATA_UNDERFLOW");
-      		bytes_left = 0;
-			if(mp3_refill_inbuffer(fd) != 0)
-  		  return -1;
+			rt_kprintf("ERR_MP3_INDATA_UNDERFLOW\n");
+			decoder->bytes_left = 0;
+			if(mp3_decoder_fill_buffer(decoder) != 0)
+				return -1;
+			break;
+
+		case ERR_MP3_MAINDATA_UNDERFLOW:
+			/* do nothing - next call to decode will provide more mainData */
+			rt_kprintf("ERR_MP3_MAINDATA_UNDERFLOW\n");
 			break;
 
- 		case ERR_MP3_MAINDATA_UNDERFLOW:
- 			/* do nothing - next call to decode will provide more mainData */
- 			rt_kprintf("ERR_MP3_MAINDATA_UNDERFLOW");
- 			break;
+		case ERR_MP3_INVALID_FRAMEHEADER:
+			rt_kprintf("ERR_MP3_INVALID_FRAMEHEADER\n");
+			rt_kprintf("current offset: 0x%08x, frames: %d\n", current_offset, decoder->frames);
+			/* dump sector */
+			{
+				rt_uint8_t *ptr;
+				rt_size_t   size = 0, col = 0;
+
+				ptr = decoder->read_buffer;
+				rt_kprintf("   00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
+				rt_kprintf("00 ");
+				while (size ++ < 512)
+				{
+					rt_kprintf("%02x ", *ptr ++);
+					if (size % 16 == 0) rt_kprintf("\n%02x ", ++col);
+				}
+			}
+			RT_ASSERT(0);
+			// break;
+
+		case ERR_MP3_INVALID_HUFFCODES:
+			rt_kprintf("ERR_MP3_INVALID_HUFFCODES\n");
+			break;
 
- 		default:
- 			rt_kprintf("unknown error: %i\n", err);
- 			// skip this frame
- 			if (bytes_left > 0)
+		default:
+			rt_kprintf("unknown error: %i\n", err);
+			// skip this frame
+			if (decoder->bytes_left > 0)
 			{
- 				bytes_left --;
- 				read_ptr ++;
- 			}
+				decoder->bytes_left --;
+				decoder->read_ptr ++;
+			}
 			else
 			{
- 				// TODO
- 				RT_ASSERT(0);
- 			}
- 			break;
- 		}
+				// TODO
+				RT_ASSERT(0);
+			}
+			break;
+		}
 
-		dac_buffer_size[writeable_buffer] = 0;
+		/* release this memory block */
+		rt_mp_free(buffer);
 	}
 	else
 	{
 		/* no error */
-		MP3GetLastFrameInfo(hMP3Decoder, &mp3FrameInfo);
-		// rt_kprintf("Bitrate: %i\r\n", mp3FrameInfo.bitrate);
-		// rt_kprintf("%i samples\n", mp3FrameInfo.outputSamps);
+		MP3GetLastFrameInfo(decoder->decoder, &decoder->frame_info);
 
-		dac_buffer_size[writeable_buffer] = mp3FrameInfo.outputSamps;
+// #ifdef MP3_DECODER_TRACE
+		rt_kprintf("Bitrate: %i\n", decoder->frame_info.bitrate);
+		rt_kprintf("%i samples\n", decoder->frame_info.outputSamps);
 
-		// rt_kprintf("%lu Hz, %i kbps\n", mp3FrameInfo.samprate, mp3FrameInfo.bitrate/1000);
+		rt_kprintf("%lu Hz, %i kbps\n", decoder->frame_info.samprate,
+            decoder->frame_info.bitrate/1000);
+// #endif
 
-		if (dac_set_srate(mp3FrameInfo.samprate) != 0) {
-			rt_kprintf("unsupported sample rate: %lu\n", mp3FrameInfo.samprate);
-			return -1;
-		}
+        /* set sample rate */
+
+		/* write to sound device */
+		rt_device_write(decoder->snd_device, 0, buffer, decoder->frame_info.outputSamps * 2);
+		// rt_mp_free(buffer);
 	}
 
 	return 0;
@@ -190,24 +307,21 @@ int mp3_process(int fd)
 void mp3(char* filename)
 {
 	int fd;
-	rt_uint8_t *mp3_buffer;
-	
-	list_date();
-	
-	dac_init();
-	
-	mp3_buffer = rt_malloc(2048);
-	mp3_init(mp3_buffer, 2048);
-	mp3_alloc();
+	struct mp3_decoder* decoder;
 	
 	fd = open(filename, O_RDONLY, 0);
 	if (fd >= 0)
 	{
-		while (mp3_process(fd) == 0);
-		
-		close(fd);
+		decoder = mp3_decoder_create();
+		if (decoder != RT_NULL)
+		{
+			decoder->fd = fd;
+			while (mp3_decoder_run(decoder) != -1);
+			close(fd);
+			
+			/* delete decoder object */
+			mp3_decoder_delete(decoder);
+		}
 	}
-	
-	list_date();
 }
 FINSH_FUNCTION_EXPORT(mp3, mp3 decode test)

+ 4 - 3
bsp/stm32_radio/mp3/real/buffers.c

@@ -50,7 +50,7 @@
 
 #include "coder.h"
 
-#define static_buffers // KJ - Changes to Static buffers, Can run with dynamic buffers.
+#define static_buffers
 #ifdef static_buffers
 MP3DecInfo  mp3DecInfo;     //  0x7f0 =  2032 
 SubbandInfo sbi;            // 0x2204 =  8708
@@ -61,7 +61,9 @@ ScaleFactorInfo sfi;        //  0x124 =   292
 SideInfo si;                //  0x148 =   328
 FrameHeader fh;             //   0x38 =    56
 #else
-#include "stdlib.h" // J.Sz. 21/04/2006
+#include <rtthread.h>
+#define malloc rt_malloc
+#define free rt_free
 #endif
 
 /**************************************************************************************
@@ -179,7 +181,6 @@ MP3DecInfo *AllocateBuffers(void)
 
 #endif
 	return mp3DecInfo_pointer;
-
 }
 
 

+ 5 - 4
bsp/stm32_radio/project.Uv2

@@ -24,7 +24,8 @@ File 1,1,<.\sdcard.c><sdcard.c>
 File 1,1,<.\enc28j60.c><enc28j60.c>
 File 1,1,<.\rtc.c><rtc.c>
 File 1,1,<.\mp3.c><mp3.c>
-File 1,1,<.\dac.c><dac.c>
+File 1,1,<.\wm8753.c><wm8753.c>
+File 1,1,<.\wav.c><wav.c>
 File 2,1,<.\library\src\stm32f10x_adc.c><stm32f10x_adc.c>
 File 2,1,<.\library\src\stm32f10x_bkp.c><stm32f10x_bkp.c>
 File 2,1,<.\library\src\stm32f10x_can.c><stm32f10x_can.c>
@@ -208,7 +209,7 @@ Options 1,0,0  // Target 'RT-Thread/STM32-Radio'
  OCMADSXRAM { 0,0,0,0,0,0,0,0,0 }
  OCR_RVCT { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,8,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,1,0,0,0,0,0,0,0,0,0,0 }
  RV_STAVEC ()
- ADSCCFLG { 17,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+ ADSCCFLG { 5,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
  ADSCMISC ()
  ADSCDEFN ()
  ADSCUDEF ()
@@ -238,7 +239,7 @@ Options 1,0,0  // Target 'RT-Thread/STM32-Radio'
  ADSLDDW ()
   OPTDL (SARMCM3.DLL)()(DARMSTM.DLL)(-pSTM32F103ZE)(SARMCM3.DLL)()(TARMSTM.DLL)(-pSTM32F103ZE)
   OPTDBG 48118,7,()()()()()()()()()() (Segger\JL2CM3.dll)()()()
- FLASH1 { 9,0,0,0,1,0,0,0,5,16,0,0,0,0,0,0,0,0,0,0 }
+ FLASH1 { 1,0,0,0,1,0,0,0,5,16,0,0,0,0,0,0,0,0,0,0 }
  FLASH2 (Segger\JL2CM3.dll)
  FLASH3 ("" ())
  FLASH4 ()
@@ -254,7 +255,7 @@ Options 1,8,0  // Group 'mp3'
  StopCode=11
  CustArgs ()
  LibMods ()
- ADSCCFLG { 2,84,85,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+ ADSCCFLG { 6,84,85,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
  ADSCMISC ()
  ADSCDEFN ()
  ADSCUDEF ()

+ 5 - 5
bsp/stm32_radio/rtconfig.h

@@ -15,7 +15,7 @@
 #define RT_TICK_PER_SECOND	100
 
 /* SECTION: RT_DEBUG */
-/* Thread Debug*/
+/* Thread Debug*/
 #define RT_DEBUG
 /* #define RT_THREAD_DEBUG */
 
@@ -95,7 +95,7 @@
 
 /* SECTION: lwip, a lighwight TCP/IP protocol stack */
 /* Using lighweight TCP/IP protocol stack */
-#define RT_USING_LWIP
+/* #define RT_USING_LWIP */
 /* #define RT_USING_WEBSERVER */
 
 /* Trace LwIP protocol */
@@ -123,7 +123,7 @@
 /* #define RT_LWIP_SNMP */
 
 /* Using DHCP */
-#define RT_LWIP_DHCP
+#define RT_LWIP_DHCP
 
 /* Using DNS */
 #define RT_LWIP_DNS
@@ -154,8 +154,8 @@
 /* ethernet if thread options */
 #define RT_LWIP_ETHTHREAD_PRIORITY		12
 #define RT_LWIP_ETHTHREAD_MBOX_SIZE		4
-#define RT_LWIP_ETHTHREAD_STACKSIZE		512
+#define RT_LWIP_ETHTHREAD_STACKSIZE		512
 
-#define LWIP_NOASSERT
+#define LWIP_NOASSERT
 
 #endif

+ 9 - 2
bsp/stm32_radio/startup.c

@@ -41,7 +41,9 @@ extern int Image$$RW_IRAM1$$ZI$$Limit;
 #pragma section="HEAP"
 #else
 extern int __bss_end;
-#endif
+#endif
+
+extern rt_err_t wm8753_hw_init(void);
 
 #ifdef  DEBUG
 /*******************************************************************************
@@ -83,7 +85,10 @@ void rtthread_startup(void)
 	/* init timer system */
 	rt_system_timer_init();
 
-#ifdef RT_USING_HEAP
+#ifdef RT_USING_HEAP
+#ifdef RT_USING_SRAM
+	rt_system_heap_init((void*)0x68000000, (void*)0x68080000);
+#else
 #ifdef __CC_ARM
 	rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)0x20010000);
 #elif __ICCARM__
@@ -91,6 +96,7 @@ void rtthread_startup(void)
 #else
 	/* init memory system */
 	rt_system_heap_init((void*)&__bss_end, (void*)0x20010000);
+#endif
 #endif
 #endif
 
@@ -105,6 +111,7 @@ void rtthread_startup(void)
 #endif
 
 	rt_hw_rtc_init();
+	wm8753_hw_init();
 
 	/* init hardware serial device */
 	rt_hw_usart_init();

+ 29 - 0
bsp/stm32_radio/stm32f10x_it.c

@@ -361,6 +361,25 @@ void DMA1_Channel4_IRQHandler(void)
 *******************************************************************************/
 void DMA1_Channel5_IRQHandler(void)
 {
+	extern void wm8753_dma_isr(void);
+
+	/* enter interrupt */
+	rt_interrupt_enter();
+
+	if (DMA_GetITStatus(DMA1_IT_TC5))
+	{
+		/* clear DMA flag */
+		DMA_ClearFlag(DMA1_FLAG_TC5 | DMA1_FLAG_TE5);
+
+		// rt_kprintf("DMA\n");
+		/* transmission complete, invoke serial dma tx isr */
+		wm8753_dma_isr();
+	}
+	
+	/* leave interrupt */
+	rt_interrupt_leave();
+	rt_hw_interrupt_thread_switch();
+
 }
 
 /*******************************************************************************
@@ -610,6 +629,16 @@ void SPI1_IRQHandler(void)
 *******************************************************************************/
 void SPI2_IRQHandler(void)
 {
+	extern void wm8753_isr(void);
+
+	/* enter interrupt */
+	rt_interrupt_enter();
+
+	wm8753_isr();
+
+	/* leave interrupt */
+	rt_interrupt_leave();
+	rt_hw_interrupt_thread_switch();
 }
 
 /*******************************************************************************

+ 30 - 30
filesystem/dfs/filesystems/efsl/src/fs/vfat/file.c

@@ -61,40 +61,40 @@ euint32 file_fread(File *file,euint32 offset, euint32 size,euint8 *buf)
 	if( (offset+size > file->FileSize) && size_left!=0)
 		size_left=file->FileSize-offset;
 	
-	while(size_left>0)
+	while(size_left>0)
 	{
 		cclus = coffset/(512*file->fs->volumeId.SectorsPerCluster);
 		csec = (coffset/(512))%file->fs->volumeId.SectorsPerCluster;
 		cbyte = coffset%512;
-		
-		if ((size_left > 512 * file->fs->volumeId.SectorsPerCluster) &&
-			(csec == 0) && (cbyte == 0))
-		{
-			/* read whole cluster */
-			btr = 512 * file->fs->volumeId.SectorsPerCluster;
-		}
-		else if(cbyte!=0 || size_left<512)
-		{
+		
+		if ((size_left > 512 * file->fs->volumeId.SectorsPerCluster) &&
+			(csec == 0) && (cbyte == 0))
+		{
+			/* read whole cluster */
+			btr = 512 * file->fs->volumeId.SectorsPerCluster;
+		}
+		else if(cbyte!=0 || size_left<512)
+		{
 			btr = 512-(coffset%512) >= size_left? size_left:512-(coffset%512);
-		}
-		else
-		{
+		}
+		else
+		{
 			/* whole sector */
 			btr = 512;
 		}
 		
 		if((fat_LogicToDiscCluster(file->fs,&(file->Cache),cclus))!=0){
 			return(0);
-		}
+		}
 		
 		rclus = file->Cache.DiscCluster;
 		rsec  = fs_clusterToSector(file->fs,rclus);
 		
-		if(btr > 512)
+		if(btr > 512)
 		{
 			part_directSectorRead(file->fs->part, rsec + csec, buf + bytes_read, btr / 512);
-		}
-		else
+		}
+		else
 		{
 			tbuf = part_getSect(file->fs->part,rsec+csec,IOM_MODE_READONLY);
 			memCpy(tbuf+(coffset%512),buf+bytes_read,btr);
@@ -194,18 +194,18 @@ euint32 file_fwrite(File* file,euint32 offset,euint32 size,euint8* buf)
 		csec = (coffset/(512))%file->fs->volumeId.SectorsPerCluster;
 		cbyte = coffset%512;
 		
-		if ((size_left > 512 * file->fs->volumeId.SectorsPerCluster) &&
-			(csec == 0) && (cbyte == 0))
-		{
-			/* write whole cluster */
-			btr = 512 * file->fs->volumeId.SectorsPerCluster;
-		}
-		else if(cbyte!=0 || size_left<512)
+		if ((size_left > 512 * file->fs->volumeId.SectorsPerCluster) &&
+			(csec == 0) && (cbyte == 0))
+		{
+			/* write whole cluster */
+			btr = 512 * file->fs->volumeId.SectorsPerCluster;
+		}
+		else if(cbyte!=0 || size_left<512)
 		{
 			btr = 512- (coffset%512) >= size_left? size_left:512-(coffset%512);
-		}
-		else
-		{
+		}
+		else
+		{
 			/* whole sector */
 			btr = 512;
 		}
@@ -218,11 +218,11 @@ euint32 file_fwrite(File* file,euint32 offset,euint32 size,euint8* buf)
 		rclus=file->Cache.DiscCluster;
 		rsec=fs_clusterToSector(file->fs,rclus);
 		
-		if(btr > 512)
+		if(btr > 512)
 		{
 			part_directSectorWrite(file->fs->part, rsec + csec, buf + bytes_written, btr / 512);
-		}
-		else
+		}
+		else
 		{
 			tbuf = part_getSect(file->fs->part,rsec+csec,IOM_MODE_READWRITE);
 			memCpy(buf+bytes_written, tbuf+(coffset%512), btr);

+ 8 - 0
filesystem/dfs/src/dfs_raw.c

@@ -38,7 +38,11 @@ int fd_new(void)
 	rt_sem_take(fd_table_lock, RT_WAITING_FOREVER);
 
 	/* find an empty fd entry */
+#ifdef RT_USING_STDIO
 	for (idx = 3; idx < DFS_FD_MAX && fd_table[idx].ref_count > 0; idx++);
+#else
+	for (idx = 0; idx < DFS_FD_MAX && fd_table[idx].ref_count > 0; idx++);
+#endif
 
 	/* can't find an empty fd entry */
 	if (idx == DFS_FD_MAX)
@@ -69,7 +73,11 @@ struct dfs_fd* fd_get(int fd)
 {
 	struct dfs_fd* d;
 
+#ifdef RT_USING_STDIO
 	if ( fd < 3 || fd > DFS_FD_MAX ) return RT_NULL;
+#else
+	if ( fd < 0 || fd > DFS_FD_MAX ) return RT_NULL;
+#endif
 
 	d = &fd_table[fd];
 

+ 12 - 5
finsh/shell.c

@@ -27,12 +27,12 @@
     extern int VSymTab$$Base;
     extern int VSymTab$$Limit;
   #endif
-#elif defined(__ICCARM__)               /* for IAR compiler */
+#elif defined(__ICCARM__)               /* for IAR compiler */
   #ifdef FINSH_USING_SYMTAB
     #pragma section="FSymTab"
-    #pragma section="VSymTab"
+    #pragma section="VSymTab"
   #endif
-#endif
+#endif
 
 /* finsh thread */
 struct rt_thread finsh_thread;
@@ -58,7 +58,7 @@ void *memccpy(void *dst, const void *src, int c, size_t count)
 		b++;
 	}
 	return 0;
-}
+}
 
 int strcmp (const char *s1, const char *s2)
 {
@@ -133,7 +133,7 @@ void finsh_set_device(char* device_name)
 			rt_device_close(finsh_device);
 		}
 
-		finsh_device = dev;
+		finsh_device = dev;
 		rt_device_set_rx_indicate(dev, finsh_rx_ind);
 	}
 	else
@@ -189,6 +189,13 @@ void finsh_thread_entry(void* parameter)
 						line[pos] = ';';
 						break;
 					}
+					else if (line[pos] == 0x7f) /* backspace */
+					{
+						line[pos] = 0;
+						pos --;
+						if (pos < 0) pos = 0;
+						continue;
+					}
 					pos ++;
 				}
 			}