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
This commit is contained in:
parent
9eed317daf
commit
e00da562ed
|
@ -69,8 +69,8 @@ void rt_init_thread_entry(void *parameter)
|
||||||
|
|
||||||
int rt_application_init()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
rt_thread_t init_thread;
|
rt_thread_t init_thread;
|
||||||
|
|
||||||
init_thread = rt_thread_create("init",
|
init_thread = rt_thread_create("init",
|
||||||
rt_init_thread_entry, RT_NULL,
|
rt_init_thread_entry, RT_NULL,
|
||||||
1024, 8, 20);
|
1024, 8, 20);
|
||||||
|
|
|
@ -25,8 +25,6 @@ static void rt_hw_console_init(void);
|
||||||
|
|
||||||
/*@{*/
|
/*@{*/
|
||||||
|
|
||||||
ErrorStatus HSEStartUpStatus;
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Function Name : RCC_Configuration
|
* Function Name : RCC_Configuration
|
||||||
* Description : Configures the different system clocks.
|
* Description : Configures the different system clocks.
|
||||||
|
@ -35,7 +33,9 @@ ErrorStatus HSEStartUpStatus;
|
||||||
* Return : None
|
* Return : None
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
void RCC_Configuration(void)
|
void RCC_Configuration(void)
|
||||||
{
|
{
|
||||||
|
ErrorStatus HSEStartUpStatus;
|
||||||
|
|
||||||
/* RCC system reset(for debug purpose) */
|
/* RCC system reset(for debug purpose) */
|
||||||
RCC_DeInit();
|
RCC_DeInit();
|
||||||
|
|
||||||
|
@ -133,6 +133,114 @@ void rt_hw_timer_handler(void)
|
||||||
rt_interrupt_leave();
|
rt_interrupt_leave();
|
||||||
rt_hw_interrupt_thread_switch();
|
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
|
* Function Name : FSMC_SRAM_Init
|
||||||
|
@ -145,166 +253,32 @@ void rt_hw_timer_handler(void)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
void FSMC_SRAM_Init(void)
|
void FSMC_SRAM_Init(void)
|
||||||
{
|
{
|
||||||
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
|
#define REG32(x) (*(volatile unsigned long*)(x))
|
||||||
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;
|
|
||||||
|
|
||||||
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;
|
/* enable FSMC clock */
|
||||||
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
|
REG32(0x40021014) = 0x114;
|
||||||
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
|
|
||||||
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
|
/* enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
|
||||||
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
|
REG32(0x40021018) = 0x1e0;
|
||||||
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
|
|
||||||
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
|
/* SRAM Data lines, NOE and NWE configuration */
|
||||||
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
|
REG32(0x40011400) = 0x44BB44BB;
|
||||||
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
|
REG32(0x40011404) = 0xBBBBBBBB;
|
||||||
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
|
REG32(0x40011800) = 0xB44444BB;
|
||||||
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
|
REG32(0x40011804) = 0xBBBBBBBB;
|
||||||
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
|
REG32(0x40011C00) = 0x44BBBBBB;
|
||||||
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
|
REG32(0x40011C04) = 0xBBBB4444;
|
||||||
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
|
REG32(0x40012000) = 0x44BBBBBB;
|
||||||
|
REG32(0x40012004) = 0x44444B44;
|
||||||
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
|
|
||||||
|
/* FSMC Configuration (enable FSMC Bank1_SRAM Bank) */
|
||||||
/* Enable FSMC Bank1_SRAM Bank */
|
REG32(0xA0000010) = 0x00001011;
|
||||||
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);
|
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.
|
* This function will initial STM32 board.
|
||||||
*/
|
*/
|
||||||
|
@ -318,7 +292,7 @@ void rt_hw_board_init()
|
||||||
|
|
||||||
/* SRAM init */
|
/* SRAM init */
|
||||||
FSMC_SRAM_Init();
|
FSMC_SRAM_Init();
|
||||||
|
|
||||||
/* Configure the SysTick */
|
/* Configure the SysTick */
|
||||||
SysTick_Configuration();
|
SysTick_Configuration();
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#ifndef __BOARD_H__
|
#ifndef __BOARD_H__
|
||||||
#define __BOARD_H__
|
#define __BOARD_H__
|
||||||
|
|
||||||
|
#define RT_USING_SRAM
|
||||||
|
|
||||||
void rt_hw_board_led_on(int n);
|
void rt_hw_board_led_on(int n);
|
||||||
void rt_hw_board_led_off(int n);
|
void rt_hw_board_led_off(int n);
|
||||||
|
|
|
@ -1,68 +1,153 @@
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#include <dfs_posix.h>
|
#include <dfs_posix.h>
|
||||||
#include <mp3/pub/mp3dec.h>
|
#include <mp3/pub/mp3dec.h>
|
||||||
#include "dac.h"
|
|
||||||
|
|
||||||
static HMP3Decoder hMP3Decoder;
|
#define MP3_AUDIO_BUF_SZ 4096
|
||||||
static MP3FrameInfo mp3FrameInfo;
|
#define MP3_DECODE_MP_CNT 2
|
||||||
static unsigned char *read_ptr;
|
#define MP3_DECODE_MP_SZ 2560
|
||||||
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 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
|
||||||
{
|
{
|
||||||
read_ptr = RT_NULL;
|
/* mp3 information */
|
||||||
bytes_leftBeforeDecoding = bytes_left = 0;
|
HMP3Decoder decoder;
|
||||||
nFrames = 0;
|
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)
|
||||||
|
{
|
||||||
|
/* 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;
|
RT_ASSERT(decoder != RT_NULL);
|
||||||
mp3buf_size = buffer_size;
|
|
||||||
mp3_reset();
|
/* 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();
|
RT_ASSERT(decoder != RT_NULL);
|
||||||
allocated = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mp3_free()
|
/* close audio device */
|
||||||
{
|
if (decoder->snd_device != RT_NULL)
|
||||||
if (allocated) MP3FreeDecoder(hMP3Decoder);
|
rt_device_close(decoder->snd_device);
|
||||||
allocated = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mp3_refill_inbuffer(int fd)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
|
/* 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_decoder_delete(struct mp3_decoder* decoder)
|
||||||
|
{
|
||||||
|
RT_ASSERT(decoder != RT_NULL);
|
||||||
|
|
||||||
|
/* de-init mp3 decoder object */
|
||||||
|
mp3_decoder_detach(decoder);
|
||||||
|
/* release this object */
|
||||||
|
rt_free(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
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_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
|
||||||
|
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)
|
if (bytes_read == bytes_to_read)
|
||||||
{
|
{
|
||||||
read_ptr = mp3buf;
|
decoder->read_ptr = decoder->read_buffer;
|
||||||
offset = 0;
|
decoder->read_offset = 0;
|
||||||
bytes_left = mp3buf_size;
|
decoder->bytes_left = decoder->bytes_left + bytes_to_read;
|
||||||
// rt_kprintf("ok. read: %d. left: %d\n", bytes_read, bytes_left);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
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;
|
int err;
|
||||||
|
rt_uint16_t* buffer;
|
||||||
if (read_ptr == RT_NULL)
|
|
||||||
|
RT_ASSERT(decoder != RT_NULL);
|
||||||
|
|
||||||
|
if ((decoder->read_ptr == RT_NULL) || decoder->bytes_left < 2*MAINBUF_SIZE)
|
||||||
{
|
{
|
||||||
if(mp3_refill_inbuffer(fd) != 0)
|
if(mp3_decoder_fill_buffer(decoder) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = MP3FindSyncWord(read_ptr, bytes_left);
|
// rt_kprintf("read offset: 0x%08x\n", decoder->read_ptr - decoder->read_buffer);
|
||||||
if (offset < 0)
|
decoder->read_offset = MP3FindSyncWord(decoder->read_ptr, decoder->bytes_left);
|
||||||
|
if (decoder->read_offset < 0)
|
||||||
{
|
{
|
||||||
rt_kprintf("Error: MP3FindSyncWord returned <0");
|
rt_kprintf("Error: MP3FindSyncWord returned <0");
|
||||||
|
|
||||||
if(mp3_refill_inbuffer(fd) != 0)
|
if(mp3_decoder_fill_buffer(decoder) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
// rt_kprintf("sync position: %x\n", decoder->read_offset);
|
||||||
|
|
||||||
read_ptr += offset;
|
decoder->read_ptr += decoder->read_offset;
|
||||||
bytes_left -= offset;
|
decoder->bytes_left -= decoder->read_offset;
|
||||||
bytes_leftBeforeDecoding = bytes_left;
|
decoder->bytes_left_before_decoding = decoder->bytes_left;
|
||||||
|
|
||||||
|
#if 0
|
||||||
// check if this is really a valid frame
|
// check if this is really a valid frame
|
||||||
// (the decoder does not seem to calculate CRC, so make some plausibility checks)
|
// (the decoder does not seem to calculate CRC, so make some plausibility checks)
|
||||||
if (MP3GetNextFrameInfo(hMP3Decoder, &mp3FrameInfo, read_ptr) == 0 &&
|
if (!(MP3GetNextFrameInfo(decoder->decoder, &decoder->frame_info, decoder->read_ptr) == 0 &&
|
||||||
mp3FrameInfo.nChans == 2 &&
|
decoder->frame_info.nChans == 2 &&
|
||||||
mp3FrameInfo.version == 0)
|
decoder->frame_info.version == 0))
|
||||||
{
|
{
|
||||||
// rt_kprintf("Found a frame at offset %x\n", offset + read_ptr - mp3buf + mp3file->fptr);
|
rt_kprintf("this is an invalid frame\n");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rt_kprintf("this is no valid frame\n");
|
|
||||||
// advance data pointer
|
// advance data pointer
|
||||||
// TODO: handle bytes_left == 0
|
// TODO: handle bytes_left == 0
|
||||||
RT_ASSERT(bytes_left > 0);
|
RT_ASSERT(decoder->bytes_left > 0);
|
||||||
bytes_left -= 1;
|
|
||||||
read_ptr += 1;
|
decoder->bytes_left --;
|
||||||
|
decoder->read_ptr ++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes_left < 1024) {
|
if (decoder->bytes_left < 1024)
|
||||||
if(mp3_refill_inbuffer(fd) != 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rt_kprintf("bytes_leftBeforeDecoding: %i\n", bytes_leftBeforeDecoding);
|
|
||||||
|
|
||||||
writeable_buffer = dac_get_writeable_buffer();
|
|
||||||
if (writeable_buffer == -1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rt_kprintf("wb %i\n", writeable_buffer);
|
|
||||||
|
|
||||||
err = MP3Decode(hMP3Decoder, &read_ptr, &bytes_left, dac_buffer[writeable_buffer], 0);
|
|
||||||
|
|
||||||
nFrames++;
|
|
||||||
|
|
||||||
if (err)
|
|
||||||
{
|
{
|
||||||
switch (err)
|
if(mp3_decoder_fill_buffer(decoder) != 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* get a decoder buffer */
|
||||||
|
buffer = (rt_uint16_t*)rt_mp_alloc(decoder->mp, RT_WAITING_FOREVER);
|
||||||
|
|
||||||
|
// rt_kprintf("bytes left before decode: %d\n", decoder->bytes_left);
|
||||||
|
|
||||||
|
err = MP3Decode(decoder->decoder, &decoder->read_ptr,
|
||||||
|
(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)
|
||||||
|
{
|
||||||
|
switch (err)
|
||||||
{
|
{
|
||||||
case ERR_MP3_INDATA_UNDERFLOW:
|
case ERR_MP3_INDATA_UNDERFLOW:
|
||||||
rt_kprintf("ERR_MP3_INDATA_UNDERFLOW");
|
rt_kprintf("ERR_MP3_INDATA_UNDERFLOW\n");
|
||||||
bytes_left = 0;
|
decoder->bytes_left = 0;
|
||||||
if(mp3_refill_inbuffer(fd) != 0)
|
if(mp3_decoder_fill_buffer(decoder) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ERR_MP3_MAINDATA_UNDERFLOW:
|
case ERR_MP3_MAINDATA_UNDERFLOW:
|
||||||
/* do nothing - next call to decode will provide more mainData */
|
/* do nothing - next call to decode will provide more mainData */
|
||||||
rt_kprintf("ERR_MP3_MAINDATA_UNDERFLOW");
|
rt_kprintf("ERR_MP3_MAINDATA_UNDERFLOW\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case ERR_MP3_INVALID_FRAMEHEADER:
|
||||||
rt_kprintf("unknown error: %i\n", err);
|
rt_kprintf("ERR_MP3_INVALID_FRAMEHEADER\n");
|
||||||
// skip this frame
|
rt_kprintf("current offset: 0x%08x, frames: %d\n", current_offset, decoder->frames);
|
||||||
if (bytes_left > 0)
|
/* dump sector */
|
||||||
{
|
{
|
||||||
bytes_left --;
|
rt_uint8_t *ptr;
|
||||||
read_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 (decoder->bytes_left > 0)
|
||||||
|
{
|
||||||
|
decoder->bytes_left --;
|
||||||
|
decoder->read_ptr ++;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
RT_ASSERT(0);
|
RT_ASSERT(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dac_buffer_size[writeable_buffer] = 0;
|
/* release this memory block */
|
||||||
|
rt_mp_free(buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* no error */
|
/* no error */
|
||||||
MP3GetLastFrameInfo(hMP3Decoder, &mp3FrameInfo);
|
MP3GetLastFrameInfo(decoder->decoder, &decoder->frame_info);
|
||||||
// rt_kprintf("Bitrate: %i\r\n", mp3FrameInfo.bitrate);
|
|
||||||
// rt_kprintf("%i samples\n", mp3FrameInfo.outputSamps);
|
|
||||||
|
|
||||||
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) {
|
/* set sample rate */
|
||||||
rt_kprintf("unsupported sample rate: %lu\n", mp3FrameInfo.samprate);
|
|
||||||
return -1;
|
/* write to sound device */
|
||||||
}
|
rt_device_write(decoder->snd_device, 0, buffer, decoder->frame_info.outputSamps * 2);
|
||||||
|
// rt_mp_free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -190,24 +307,21 @@ int mp3_process(int fd)
|
||||||
void mp3(char* filename)
|
void mp3(char* filename)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
rt_uint8_t *mp3_buffer;
|
struct mp3_decoder* decoder;
|
||||||
|
|
||||||
list_date();
|
|
||||||
|
|
||||||
dac_init();
|
|
||||||
|
|
||||||
mp3_buffer = rt_malloc(2048);
|
|
||||||
mp3_init(mp3_buffer, 2048);
|
|
||||||
mp3_alloc();
|
|
||||||
|
|
||||||
fd = open(filename, O_RDONLY, 0);
|
fd = open(filename, O_RDONLY, 0);
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
{
|
{
|
||||||
while (mp3_process(fd) == 0);
|
decoder = mp3_decoder_create();
|
||||||
|
if (decoder != RT_NULL)
|
||||||
close(fd);
|
{
|
||||||
|
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)
|
FINSH_FUNCTION_EXPORT(mp3, mp3 decode test)
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
|
|
||||||
#include "coder.h"
|
#include "coder.h"
|
||||||
|
|
||||||
#define static_buffers // KJ - Changes to Static buffers, Can run with dynamic buffers.
|
#define static_buffers
|
||||||
#ifdef static_buffers
|
#ifdef static_buffers
|
||||||
MP3DecInfo mp3DecInfo; // 0x7f0 = 2032
|
MP3DecInfo mp3DecInfo; // 0x7f0 = 2032
|
||||||
SubbandInfo sbi; // 0x2204 = 8708
|
SubbandInfo sbi; // 0x2204 = 8708
|
||||||
|
@ -61,7 +61,9 @@ ScaleFactorInfo sfi; // 0x124 = 292
|
||||||
SideInfo si; // 0x148 = 328
|
SideInfo si; // 0x148 = 328
|
||||||
FrameHeader fh; // 0x38 = 56
|
FrameHeader fh; // 0x38 = 56
|
||||||
#else
|
#else
|
||||||
#include "stdlib.h" // J.Sz. 21/04/2006
|
#include <rtthread.h>
|
||||||
|
#define malloc rt_malloc
|
||||||
|
#define free rt_free
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**************************************************************************************
|
/**************************************************************************************
|
||||||
|
@ -179,7 +181,6 @@ MP3DecInfo *AllocateBuffers(void)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return mp3DecInfo_pointer;
|
return mp3DecInfo_pointer;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,8 @@ File 1,1,<.\sdcard.c><sdcard.c>
|
||||||
File 1,1,<.\enc28j60.c><enc28j60.c>
|
File 1,1,<.\enc28j60.c><enc28j60.c>
|
||||||
File 1,1,<.\rtc.c><rtc.c>
|
File 1,1,<.\rtc.c><rtc.c>
|
||||||
File 1,1,<.\mp3.c><mp3.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_adc.c><stm32f10x_adc.c>
|
||||||
File 2,1,<.\library\src\stm32f10x_bkp.c><stm32f10x_bkp.c>
|
File 2,1,<.\library\src\stm32f10x_bkp.c><stm32f10x_bkp.c>
|
||||||
File 2,1,<.\library\src\stm32f10x_can.c><stm32f10x_can.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 }
|
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 }
|
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 ()
|
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 ()
|
ADSCMISC ()
|
||||||
ADSCDEFN ()
|
ADSCDEFN ()
|
||||||
ADSCUDEF ()
|
ADSCUDEF ()
|
||||||
|
@ -238,7 +239,7 @@ Options 1,0,0 // Target 'RT-Thread/STM32-Radio'
|
||||||
ADSLDDW ()
|
ADSLDDW ()
|
||||||
OPTDL (SARMCM3.DLL)()(DARMSTM.DLL)(-pSTM32F103ZE)(SARMCM3.DLL)()(TARMSTM.DLL)(-pSTM32F103ZE)
|
OPTDL (SARMCM3.DLL)()(DARMSTM.DLL)(-pSTM32F103ZE)(SARMCM3.DLL)()(TARMSTM.DLL)(-pSTM32F103ZE)
|
||||||
OPTDBG 48118,7,()()()()()()()()()() (Segger\JL2CM3.dll)()()()
|
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)
|
FLASH2 (Segger\JL2CM3.dll)
|
||||||
FLASH3 ("" ())
|
FLASH3 ("" ())
|
||||||
FLASH4 ()
|
FLASH4 ()
|
||||||
|
@ -254,7 +255,7 @@ Options 1,8,0 // Group 'mp3'
|
||||||
StopCode=11
|
StopCode=11
|
||||||
CustArgs ()
|
CustArgs ()
|
||||||
LibMods ()
|
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 ()
|
ADSCMISC ()
|
||||||
ADSCDEFN ()
|
ADSCDEFN ()
|
||||||
ADSCUDEF ()
|
ADSCUDEF ()
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#define RT_TICK_PER_SECOND 100
|
#define RT_TICK_PER_SECOND 100
|
||||||
|
|
||||||
/* SECTION: RT_DEBUG */
|
/* SECTION: RT_DEBUG */
|
||||||
/* Thread Debug*/
|
/* Thread Debug*/
|
||||||
#define RT_DEBUG
|
#define RT_DEBUG
|
||||||
/* #define RT_THREAD_DEBUG */
|
/* #define RT_THREAD_DEBUG */
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
|
|
||||||
/* SECTION: lwip, a lighwight TCP/IP protocol stack */
|
/* SECTION: lwip, a lighwight TCP/IP protocol stack */
|
||||||
/* Using lighweight TCP/IP protocol stack */
|
/* Using lighweight TCP/IP protocol stack */
|
||||||
#define RT_USING_LWIP
|
/* #define RT_USING_LWIP */
|
||||||
/* #define RT_USING_WEBSERVER */
|
/* #define RT_USING_WEBSERVER */
|
||||||
|
|
||||||
/* Trace LwIP protocol */
|
/* Trace LwIP protocol */
|
||||||
|
@ -123,7 +123,7 @@
|
||||||
/* #define RT_LWIP_SNMP */
|
/* #define RT_LWIP_SNMP */
|
||||||
|
|
||||||
/* Using DHCP */
|
/* Using DHCP */
|
||||||
#define RT_LWIP_DHCP
|
#define RT_LWIP_DHCP
|
||||||
|
|
||||||
/* Using DNS */
|
/* Using DNS */
|
||||||
#define RT_LWIP_DNS
|
#define RT_LWIP_DNS
|
||||||
|
@ -154,8 +154,8 @@
|
||||||
/* ethernet if thread options */
|
/* ethernet if thread options */
|
||||||
#define RT_LWIP_ETHTHREAD_PRIORITY 12
|
#define RT_LWIP_ETHTHREAD_PRIORITY 12
|
||||||
#define RT_LWIP_ETHTHREAD_MBOX_SIZE 4
|
#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
|
#endif
|
||||||
|
|
|
@ -41,7 +41,9 @@ extern int Image$$RW_IRAM1$$ZI$$Limit;
|
||||||
#pragma section="HEAP"
|
#pragma section="HEAP"
|
||||||
#else
|
#else
|
||||||
extern int __bss_end;
|
extern int __bss_end;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern rt_err_t wm8753_hw_init(void);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -83,7 +85,10 @@ void rtthread_startup(void)
|
||||||
/* init timer system */
|
/* init timer system */
|
||||||
rt_system_timer_init();
|
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
|
#ifdef __CC_ARM
|
||||||
rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)0x20010000);
|
rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)0x20010000);
|
||||||
#elif __ICCARM__
|
#elif __ICCARM__
|
||||||
|
@ -91,6 +96,7 @@ void rtthread_startup(void)
|
||||||
#else
|
#else
|
||||||
/* init memory system */
|
/* init memory system */
|
||||||
rt_system_heap_init((void*)&__bss_end, (void*)0x20010000);
|
rt_system_heap_init((void*)&__bss_end, (void*)0x20010000);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -105,6 +111,7 @@ void rtthread_startup(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rt_hw_rtc_init();
|
rt_hw_rtc_init();
|
||||||
|
wm8753_hw_init();
|
||||||
|
|
||||||
/* init hardware serial device */
|
/* init hardware serial device */
|
||||||
rt_hw_usart_init();
|
rt_hw_usart_init();
|
||||||
|
|
|
@ -361,6 +361,25 @@ void DMA1_Channel4_IRQHandler(void)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
void DMA1_Channel5_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)
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
|
@ -61,40 +61,40 @@ euint32 file_fread(File *file,euint32 offset, euint32 size,euint8 *buf)
|
||||||
if( (offset+size > file->FileSize) && size_left!=0)
|
if( (offset+size > file->FileSize) && size_left!=0)
|
||||||
size_left=file->FileSize-offset;
|
size_left=file->FileSize-offset;
|
||||||
|
|
||||||
while(size_left>0)
|
while(size_left>0)
|
||||||
{
|
{
|
||||||
cclus = coffset/(512*file->fs->volumeId.SectorsPerCluster);
|
cclus = coffset/(512*file->fs->volumeId.SectorsPerCluster);
|
||||||
csec = (coffset/(512))%file->fs->volumeId.SectorsPerCluster;
|
csec = (coffset/(512))%file->fs->volumeId.SectorsPerCluster;
|
||||||
cbyte = coffset%512;
|
cbyte = coffset%512;
|
||||||
|
|
||||||
if ((size_left > 512 * file->fs->volumeId.SectorsPerCluster) &&
|
if ((size_left > 512 * file->fs->volumeId.SectorsPerCluster) &&
|
||||||
(csec == 0) && (cbyte == 0))
|
(csec == 0) && (cbyte == 0))
|
||||||
{
|
{
|
||||||
/* read whole cluster */
|
/* read whole cluster */
|
||||||
btr = 512 * file->fs->volumeId.SectorsPerCluster;
|
btr = 512 * file->fs->volumeId.SectorsPerCluster;
|
||||||
}
|
}
|
||||||
else if(cbyte!=0 || size_left<512)
|
else if(cbyte!=0 || size_left<512)
|
||||||
{
|
{
|
||||||
btr = 512-(coffset%512) >= size_left? size_left:512-(coffset%512);
|
btr = 512-(coffset%512) >= size_left? size_left:512-(coffset%512);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* whole sector */
|
/* whole sector */
|
||||||
btr = 512;
|
btr = 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((fat_LogicToDiscCluster(file->fs,&(file->Cache),cclus))!=0){
|
if((fat_LogicToDiscCluster(file->fs,&(file->Cache),cclus))!=0){
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
rclus = file->Cache.DiscCluster;
|
rclus = file->Cache.DiscCluster;
|
||||||
rsec = fs_clusterToSector(file->fs,rclus);
|
rsec = fs_clusterToSector(file->fs,rclus);
|
||||||
|
|
||||||
if(btr > 512)
|
if(btr > 512)
|
||||||
{
|
{
|
||||||
part_directSectorRead(file->fs->part, rsec + csec, buf + bytes_read, 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);
|
tbuf = part_getSect(file->fs->part,rsec+csec,IOM_MODE_READONLY);
|
||||||
memCpy(tbuf+(coffset%512),buf+bytes_read,btr);
|
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;
|
csec = (coffset/(512))%file->fs->volumeId.SectorsPerCluster;
|
||||||
cbyte = coffset%512;
|
cbyte = coffset%512;
|
||||||
|
|
||||||
if ((size_left > 512 * file->fs->volumeId.SectorsPerCluster) &&
|
if ((size_left > 512 * file->fs->volumeId.SectorsPerCluster) &&
|
||||||
(csec == 0) && (cbyte == 0))
|
(csec == 0) && (cbyte == 0))
|
||||||
{
|
{
|
||||||
/* write whole cluster */
|
/* write whole cluster */
|
||||||
btr = 512 * file->fs->volumeId.SectorsPerCluster;
|
btr = 512 * file->fs->volumeId.SectorsPerCluster;
|
||||||
}
|
}
|
||||||
else if(cbyte!=0 || size_left<512)
|
else if(cbyte!=0 || size_left<512)
|
||||||
{
|
{
|
||||||
btr = 512- (coffset%512) >= size_left? size_left:512-(coffset%512);
|
btr = 512- (coffset%512) >= size_left? size_left:512-(coffset%512);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* whole sector */
|
/* whole sector */
|
||||||
btr = 512;
|
btr = 512;
|
||||||
}
|
}
|
||||||
|
@ -218,11 +218,11 @@ euint32 file_fwrite(File* file,euint32 offset,euint32 size,euint8* buf)
|
||||||
rclus=file->Cache.DiscCluster;
|
rclus=file->Cache.DiscCluster;
|
||||||
rsec=fs_clusterToSector(file->fs,rclus);
|
rsec=fs_clusterToSector(file->fs,rclus);
|
||||||
|
|
||||||
if(btr > 512)
|
if(btr > 512)
|
||||||
{
|
{
|
||||||
part_directSectorWrite(file->fs->part, rsec + csec, buf + bytes_written, 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);
|
tbuf = part_getSect(file->fs->part,rsec+csec,IOM_MODE_READWRITE);
|
||||||
memCpy(buf+bytes_written, tbuf+(coffset%512), btr);
|
memCpy(buf+bytes_written, tbuf+(coffset%512), btr);
|
||||||
|
|
|
@ -38,7 +38,11 @@ int fd_new(void)
|
||||||
rt_sem_take(fd_table_lock, RT_WAITING_FOREVER);
|
rt_sem_take(fd_table_lock, RT_WAITING_FOREVER);
|
||||||
|
|
||||||
/* find an empty fd entry */
|
/* find an empty fd entry */
|
||||||
|
#ifdef RT_USING_STDIO
|
||||||
for (idx = 3; idx < DFS_FD_MAX && fd_table[idx].ref_count > 0; idx++);
|
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 */
|
/* can't find an empty fd entry */
|
||||||
if (idx == DFS_FD_MAX)
|
if (idx == DFS_FD_MAX)
|
||||||
|
@ -69,7 +73,11 @@ struct dfs_fd* fd_get(int fd)
|
||||||
{
|
{
|
||||||
struct dfs_fd* d;
|
struct dfs_fd* d;
|
||||||
|
|
||||||
|
#ifdef RT_USING_STDIO
|
||||||
if ( fd < 3 || fd > DFS_FD_MAX ) return RT_NULL;
|
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];
|
d = &fd_table[fd];
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,12 @@
|
||||||
extern int VSymTab$$Base;
|
extern int VSymTab$$Base;
|
||||||
extern int VSymTab$$Limit;
|
extern int VSymTab$$Limit;
|
||||||
#endif
|
#endif
|
||||||
#elif defined(__ICCARM__) /* for IAR compiler */
|
#elif defined(__ICCARM__) /* for IAR compiler */
|
||||||
#ifdef FINSH_USING_SYMTAB
|
#ifdef FINSH_USING_SYMTAB
|
||||||
#pragma section="FSymTab"
|
#pragma section="FSymTab"
|
||||||
#pragma section="VSymTab"
|
#pragma section="VSymTab"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* finsh thread */
|
/* finsh thread */
|
||||||
struct rt_thread finsh_thread;
|
struct rt_thread finsh_thread;
|
||||||
|
@ -58,7 +58,7 @@ void *memccpy(void *dst, const void *src, int c, size_t count)
|
||||||
b++;
|
b++;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strcmp (const char *s1, const char *s2)
|
int strcmp (const char *s1, const char *s2)
|
||||||
{
|
{
|
||||||
|
@ -133,7 +133,7 @@ void finsh_set_device(char* device_name)
|
||||||
rt_device_close(finsh_device);
|
rt_device_close(finsh_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
finsh_device = dev;
|
finsh_device = dev;
|
||||||
rt_device_set_rx_indicate(dev, finsh_rx_ind);
|
rt_device_set_rx_indicate(dev, finsh_rx_ind);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -189,6 +189,13 @@ void finsh_thread_entry(void* parameter)
|
||||||
line[pos] = ';';
|
line[pos] = ';';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (line[pos] == 0x7f) /* backspace */
|
||||||
|
{
|
||||||
|
line[pos] = 0;
|
||||||
|
pos --;
|
||||||
|
if (pos < 0) pos = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
pos ++;
|
pos ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue