mirror of
https://github.com/elua/elua.git
synced 2025-01-25 01:02:54 +08:00
added timers support for STM32 (and enabled XMODEM) plus a few more minor changes
This commit is contained in:
parent
947379c750
commit
41641f657a
@ -35,7 +35,6 @@ pre {
|
|||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
float: left;
|
|
||||||
}
|
}
|
||||||
p.info {
|
p.info {
|
||||||
margin-left: 3em;
|
margin-left: 3em;
|
||||||
|
@ -24,7 +24,7 @@ cdefs = cdefs + " -Dgcc"
|
|||||||
# Toolset data
|
# Toolset data
|
||||||
tools[ 'stm32' ] = {}
|
tools[ 'stm32' ] = {}
|
||||||
tools[ 'stm32' ][ 'cccom' ] = "%s -mcpu=cortex-m3 -mthumb -mlittle-endian %s %s -ffunction-sections -fdata-sections -fno-strict-aliasing %s -Wall -c $SOURCE -o $TARGET" % ( toolset[ 'compile' ], opt, local_include, cdefs )
|
tools[ 'stm32' ][ 'cccom' ] = "%s -mcpu=cortex-m3 -mthumb -mlittle-endian %s %s -ffunction-sections -fdata-sections -fno-strict-aliasing %s -Wall -c $SOURCE -o $TARGET" % ( toolset[ 'compile' ], opt, local_include, cdefs )
|
||||||
tools[ 'stm32' ][ 'linkcom' ] = "%s -mcpu=cortex-m3 -mthumb -Wl,-T -Xlinker %s -u _start -Wl,-e,Reset_Handler -Wl,-static -Wl,--gc-sections -nostartfiles -nostdlib -Wl,-Map -Xlinker project.map -Wl,--allow-multiple-definition -o $TARGET $SOURCES -lc -lgcc -lm %s" % ( toolset[ 'compile' ], ldscript, local_libs )
|
tools[ 'stm32' ][ 'linkcom' ] = "%s -mcpu=cortex-m3 -mthumb -Wl,-T -Xlinker %s -u _start -Wl,-e,Reset_Handler -Wl,-static -Wl,--gc-sections -nostartfiles -nostdlib -Wl,--allow-multiple-definition -o $TARGET $SOURCES -lc -lgcc -lm %s" % ( toolset[ 'compile' ], ldscript, local_libs )
|
||||||
tools[ 'stm32' ][ 'ascom' ] = "%s -x assembler-with-cpp %s -mcpu=cortex-m3 -mthumb %s -Wall -c $SOURCE -o $TARGET" % ( toolset[ 'compile' ], local_include, cdefs )
|
tools[ 'stm32' ][ 'ascom' ] = "%s -x assembler-with-cpp %s -mcpu=cortex-m3 -mthumb %s -Wall -c $SOURCE -o $TARGET" % ( toolset[ 'compile' ], local_include, cdefs )
|
||||||
|
|
||||||
# Programming function
|
# Programming function
|
||||||
|
@ -29,16 +29,14 @@
|
|||||||
#include "stm32f10x_spi.h"
|
#include "stm32f10x_spi.h"
|
||||||
#include "stm32f10x_systick.h"
|
#include "stm32f10x_systick.h"
|
||||||
#include "stm32f10x_flash.h"
|
#include "stm32f10x_flash.h"
|
||||||
|
#include "stm32f10x_conf.h"
|
||||||
#include "systick.h"
|
#include "systick.h"
|
||||||
|
|
||||||
#define STM32_USE_PIO
|
// Clock data
|
||||||
#define STM32_USE_USART
|
// IMPORTANT: if you change these, make sure to modify RCC_Configuration() too!
|
||||||
|
#define HCLK ( HSE_Value * 9 )
|
||||||
void exit(int ret)
|
#define PCLK1_DIV 2
|
||||||
{
|
#define PCLK2_DIV 1
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
// Platform initialization
|
// Platform initialization
|
||||||
@ -49,10 +47,7 @@ static void NVIC_Configuration(void);
|
|||||||
|
|
||||||
static void timers_init();
|
static void timers_init();
|
||||||
static void uarts_init();
|
static void uarts_init();
|
||||||
static void spis_init();
|
|
||||||
static void pios_init();
|
static void pios_init();
|
||||||
static void pwms_init();
|
|
||||||
static void eth_init();
|
|
||||||
|
|
||||||
int platform_init()
|
int platform_init()
|
||||||
{
|
{
|
||||||
@ -65,29 +60,14 @@ int platform_init()
|
|||||||
// Enable SysTick timer.
|
// Enable SysTick timer.
|
||||||
SysTick_Config();
|
SysTick_Config();
|
||||||
|
|
||||||
#ifdef STM32_USE_PIO
|
|
||||||
// Setup PIO
|
// Setup PIO
|
||||||
pios_init();
|
pios_init();
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STM32_USE_SPI
|
|
||||||
// Setup SPIs
|
|
||||||
//spis_init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STM32_USE_USART
|
|
||||||
// Setup UARTs
|
// Setup UARTs
|
||||||
uarts_init();
|
uarts_init();
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup timers
|
// Setup timers
|
||||||
//timers_init();
|
timers_init();
|
||||||
|
|
||||||
// Setup PWMs
|
|
||||||
//pwms_init();
|
|
||||||
|
|
||||||
// Setup ethernet (TCP/IP)
|
|
||||||
//eth_init();
|
|
||||||
|
|
||||||
cmn_platform_init();
|
cmn_platform_init();
|
||||||
|
|
||||||
@ -172,8 +152,6 @@ static void RCC_Configuration(void)
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
static void NVIC_Configuration(void)
|
static void NVIC_Configuration(void)
|
||||||
{
|
{
|
||||||
NVIC_InitTypeDef NVIC_InitStructure;
|
|
||||||
|
|
||||||
NVIC_DeInit();
|
NVIC_DeInit();
|
||||||
|
|
||||||
#ifdef VECT_TAB_RAM
|
#ifdef VECT_TAB_RAM
|
||||||
@ -195,7 +173,6 @@ static void NVIC_Configuration(void)
|
|||||||
// PIO
|
// PIO
|
||||||
// This is pretty much common code to all STM32 devices.
|
// This is pretty much common code to all STM32 devices.
|
||||||
// todo: Needs updates to support different processor lines.
|
// todo: Needs updates to support different processor lines.
|
||||||
#ifdef STM32_USE_PIO
|
|
||||||
static GPIO_TypeDef * const pio_port[] = { GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG };
|
static GPIO_TypeDef * const pio_port[] = { GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG };
|
||||||
static const u32 pio_port_clk[] = { RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB, RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE, RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG };
|
static const u32 pio_port_clk[] = { RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB, RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE, RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG };
|
||||||
|
|
||||||
@ -291,86 +268,17 @@ pio_type platform_pio_op( unsigned port, pio_type pinmask, int op )
|
|||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STM32_USE_SPI
|
|
||||||
// ****************************************************************************
|
|
||||||
// SPI
|
|
||||||
// TODO: Just about everything.
|
|
||||||
|
|
||||||
static const u32 spi_base[] = { SSI0_BASE, SSI1_BASE };
|
|
||||||
static const u32 spi_sysctl[] = { SYSCTL_PERIPH_SSI0, SYSCTL_PERIPH_SSI1 };
|
|
||||||
static const u32 spi_gpio_base[] = { GPIO_PORTA_BASE | GPIO_PORTE_BASE };
|
|
||||||
static const u8 spi_gpio_pins[] = { GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5,
|
|
||||||
GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 };
|
|
||||||
// SSIxClk SSIxFss SSIxRx SSIxTx
|
|
||||||
static const u8 spi_gpio_clk_pin[] = { GPIO_PIN_2, GPIO_PIN_0 };
|
|
||||||
#define SPIS_COUNT 1
|
|
||||||
|
|
||||||
static void spis_init()
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for( i = 0; i < SPIS_COUNT; i ++ )
|
|
||||||
{
|
|
||||||
SysCtlPeripheralEnable(spi_sysctl[ i ]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int platform_spi_exists( unsigned id )
|
|
||||||
{
|
|
||||||
return id < SPIS_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 platform_spi_setup( unsigned id, int mode, u32 clock, unsigned cpol, unsigned cpha, unsigned databits )
|
|
||||||
{
|
|
||||||
unsigned protocol;
|
|
||||||
|
|
||||||
if( cpol == 0 )
|
|
||||||
protocol = cpha ? SSI_FRF_MOTO_MODE_1 : SSI_FRF_MOTO_MODE_0;
|
|
||||||
else
|
|
||||||
protocol = cpha ? SSI_FRF_MOTO_MODE_3 : SSI_FRF_MOTO_MODE_2;
|
|
||||||
mode = mode == PLATFORM_SPI_MASTER ? SSI_MODE_MASTER : SSI_MODE_SLAVE;
|
|
||||||
SSIDisable( spi_base[ id ] );
|
|
||||||
|
|
||||||
GPIOPinTypeSSI( spi_gpio_base[ id ], spi_gpio_pins[ id ] );
|
|
||||||
|
|
||||||
// FIXME: not sure this is always "right"
|
|
||||||
GPIOPadConfigSet(spi_gpio_base[ id ], spi_gpio_clk_pin[ id ], GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD_WPU);
|
|
||||||
|
|
||||||
SSIConfigSetExpClk( spi_base[ id ], SysCtlClockGet(), protocol, mode, clock, databits );
|
|
||||||
SSIEnable( spi_base[ id ] );
|
|
||||||
return clock;
|
|
||||||
}
|
|
||||||
|
|
||||||
spi_data_type platform_spi_send_recv( unsigned id, spi_data_type data )
|
|
||||||
{
|
|
||||||
SSIDataPut( spi_base[ id ], data );
|
|
||||||
SSIDataGet( spi_base[ id ], &data );
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void platform_spi_select( unsigned id, int is_select )
|
|
||||||
{
|
|
||||||
// This platform doesn't have a hardware SS pin, so there's nothing to do here
|
|
||||||
id = id;
|
|
||||||
is_select = is_select;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STM32_USE_USART
|
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
// UART
|
// UART
|
||||||
// TODO: Support timeouts.
|
// TODO: Support timeouts.
|
||||||
|
|
||||||
// All possible STM32 uarts defs
|
// All possible STM32 uarts defs
|
||||||
static USART_TypeDef * usart[] = { USART1, USART2, USART3, UART4 };
|
static USART_TypeDef *const usart[] = { USART1, USART2, USART3, UART4, UART5 };
|
||||||
static GPIO_TypeDef * usart_gpio_port[] = { GPIOA, GPIOA, GPIOB, GPIOC };
|
static GPIO_TypeDef *const usart_gpio_rx_port[] = { GPIOA, GPIOA, GPIOB, GPIOC, GPIOD };
|
||||||
static const u16 usart_gpio_tx_pin[] = { GPIO_Pin_9, GPIO_Pin_2, GPIO_Pin_10, GPIO_Pin_10 };
|
static GPIO_TypeDef *const usart_gpio_tx_port[] = { GPIOA, GPIOA, GPIOB, GPIOC, GPIOC };
|
||||||
static const u16 usart_gpio_rx_pin[] = { GPIO_Pin_10, GPIO_Pin_3, GPIO_Pin_11, GPIO_Pin_11 };
|
static const u16 usart_gpio_rx_pin[] = { GPIO_Pin_10, GPIO_Pin_3, GPIO_Pin_11, GPIO_Pin_11, GPIO_Pin_2 };
|
||||||
//static const u32 uart_sysctl[] = { SYSCTL_PERIPH_UART0, SYSCTL_PERIPH_UART1, SYSCTL_PERIPH_UART2 };
|
static const u16 usart_gpio_tx_pin[] = { GPIO_Pin_9, GPIO_Pin_2, GPIO_Pin_10, GPIO_Pin_10, GPIO_Pin_12 };
|
||||||
//static const u32 uart_gpio_base[] = { _BASE, GPIO_PORTD_BASE, GPIO_PORTG_BASE };
|
|
||||||
//static const u8 uart_gpio_pins[] = { GPIO_PIN_0 | GPIO_PIN_1, GPIO_PIN_2 | GPIO_PIN_3, GPIO_PIN_0 | GPIO_PIN_1 };
|
|
||||||
|
|
||||||
static void usart_init(u32 id, USART_InitTypeDef * initVals)
|
static void usart_init(u32 id, USART_InitTypeDef * initVals)
|
||||||
{
|
{
|
||||||
@ -381,12 +289,12 @@ static void usart_init(u32 id, USART_InitTypeDef * initVals)
|
|||||||
GPIO_InitStructure.GPIO_Pin = usart_gpio_tx_pin[id];
|
GPIO_InitStructure.GPIO_Pin = usart_gpio_tx_pin[id];
|
||||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||||
GPIO_Init(usart_gpio_port[id], &GPIO_InitStructure);
|
GPIO_Init(usart_gpio_tx_port[id], &GPIO_InitStructure);
|
||||||
|
|
||||||
/* Configure USART Rx Pin as input floating */
|
/* Configure USART Rx Pin as input floating */
|
||||||
GPIO_InitStructure.GPIO_Pin = usart_gpio_rx_pin[id];
|
GPIO_InitStructure.GPIO_Pin = usart_gpio_rx_pin[id];
|
||||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||||
GPIO_Init(usart_gpio_port[id], &GPIO_InitStructure);
|
GPIO_Init(usart_gpio_rx_port[id], &GPIO_InitStructure);
|
||||||
|
|
||||||
/* Configure USART */
|
/* Configure USART */
|
||||||
USART_Init(usart[id], initVals);
|
USART_Init(usart[id], initVals);
|
||||||
@ -395,7 +303,7 @@ static void usart_init(u32 id, USART_InitTypeDef * initVals)
|
|||||||
//USART_ITConfig(usart[id], USART_IT_RXNE, ENABLE);
|
//USART_ITConfig(usart[id], USART_IT_RXNE, ENABLE);
|
||||||
//USART_ITConfig(usart[id], USART_IT_TXE, ENABLE);
|
//USART_ITConfig(usart[id], USART_IT_TXE, ENABLE);
|
||||||
|
|
||||||
/* Enable the USART1 */
|
/* Enable USART */
|
||||||
USART_Cmd(usart[id], ENABLE);
|
USART_Cmd(usart[id], ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,7 +317,7 @@ static void uarts_init()
|
|||||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
|
||||||
|
|
||||||
// Configure the U(S)ART for 115,200, 8-N-1 operation.
|
// Configure the U(S)ART
|
||||||
|
|
||||||
USART_InitStructure.USART_BaudRate = CON_UART_SPEED;
|
USART_InitStructure.USART_BaudRate = CON_UART_SPEED;
|
||||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||||
@ -498,86 +406,90 @@ int platform_s_uart_recv( unsigned id, s32 timeout )
|
|||||||
while(USART_GetFlagStatus(usart[id], USART_FLAG_RXNE) == RESET);
|
while(USART_GetFlagStatus(usart[id], USART_FLAG_RXNE) == RESET);
|
||||||
return USART_ReceiveData(usart[id]);
|
return USART_ReceiveData(usart[id]);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STM32_USE_TIMERS
|
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
// Timers
|
// Timers
|
||||||
|
|
||||||
// All possible LM3S timers defs
|
// We leave out TIM6/TIM for now, as they are dedicated
|
||||||
static TIM_TypeDef * timer[] = { TIM2, TIM3, TIM4, TIM5};
|
static TIM_TypeDef * const timer[] = { TIM1, TIM2, TIM3, TIM4, TIM5, TIM8 };
|
||||||
|
#define TIM_GET_BASE_CLK( id ) ( ( id ) == 0 || ( id ) == 5 ? ( HCLK / PCLK2_DIV ) : ( HCLK / PCLK1_DIV ) )
|
||||||
|
#define TIM_STARTUP_CLOCK 50000
|
||||||
|
|
||||||
static void timers_init()
|
static void timers_init()
|
||||||
{
|
{
|
||||||
#if 0
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
|
// Enable clocks.
|
||||||
|
RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE );
|
||||||
|
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2, ENABLE );
|
||||||
|
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE );
|
||||||
|
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM4, ENABLE );
|
||||||
|
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM5, ENABLE );
|
||||||
|
RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM8, ENABLE );
|
||||||
|
|
||||||
|
// Configure timers
|
||||||
for( i = 0; i < NUM_TIMER; i ++ )
|
for( i = 0; i < NUM_TIMER; i ++ )
|
||||||
{
|
{
|
||||||
SysCtlPeripheralEnable(timer_sysctl[ i ]);
|
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
|
||||||
TimerConfigure(timer_base[ i ], TIMER_CFG_32_BIT_PER);
|
TIM_TimeBaseStructure.TIM_Prescaler = TIM_GET_BASE_CLK( i ) / TIM_STARTUP_CLOCK;
|
||||||
TimerEnable(timer_base[ i ], TIMER_A);
|
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||||||
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
|
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0000;
|
||||||
|
TIM_TimeBaseInit( timer[ i ], &TIM_TimeBaseStructure );
|
||||||
|
TIM_Cmd( timer[ i ], ENABLE );
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 platform_timer_get_clock(unsigned id)
|
static u32 timer_get_clock( unsigned id )
|
||||||
{
|
{
|
||||||
RCC_ClocksTypeDef Clocks;
|
TIM_TypeDef* ptimer = timer[ id ];
|
||||||
|
|
||||||
RCC_GetClocksFreq(&Clocks);
|
return TIM_GET_BASE_CLK( id ) / ( TIM_GetPrescaler( ptimer ) + 1 );
|
||||||
|
|
||||||
return Clocks.PCLK1_Frequency / (TIM_GetPrescaler(timer[id]) + 1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 platform_timer_set_clock(unsigned id, u32 clock)
|
static u32 timer_set_clock( unsigned id, u32 clock )
|
||||||
{
|
{
|
||||||
RCC_ClocksTypeDef Clocks;
|
TIM_TypeDef *ptimer = timer[ id ];
|
||||||
u32 pclk, clkdiv;
|
u16 pre;
|
||||||
u64 tmp;
|
|
||||||
|
pre = TIM_GET_BASE_CLK( id ) / clock;
|
||||||
RCC_GetClocksFreq(&Clocks);
|
TIM_PrescalerConfig( ptimer, pre, TIM_PSCReloadMode_Immediate );
|
||||||
|
return TIM_GET_BASE_CLK( id ) / pre;
|
||||||
pclk = Clocks.PCLK1_Frequency; // Get peripheral bus clock frequency.
|
|
||||||
tmp = ((u64)pclk << 16) / clock; // Convert to u32.16 fixed point and calculate prescaler divisor
|
|
||||||
clkdiv = ((tmp & 0x8000) ? (tmp + 0x10000) : tmp) >> 16; // Round up or down and convert back to u32.0
|
|
||||||
if (clkdiv > 0x10000) // Saturate to u16 (+1 for a clkdiv value of 1 is a reg value of 0)
|
|
||||||
clkdiv = 0x10000;
|
|
||||||
|
|
||||||
TIM_PrescalerConfig(timer[id], clkdiv - 1, TIM_PSCReloadMode_Immediate); // Update timer prescaler immediately
|
|
||||||
|
|
||||||
return pclk / clkdiv; // Return actual clock rate used.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void platform_s_timer_delay( unsigned id, u32 delay_us )
|
void platform_s_timer_delay( unsigned id, u32 delay_us )
|
||||||
{
|
{
|
||||||
|
TIM_TypeDef *ptimer = timer[ id ];
|
||||||
|
volatile unsigned dummy;
|
||||||
timer_data_type final;
|
timer_data_type final;
|
||||||
u32 base = timer_base[ id ];
|
|
||||||
|
|
||||||
final = 0xFFFFFFFF - ( ( ( u64 )delay_us * SysCtlClockGet() ) / 1000000 );
|
final = ( ( u64 )delay_us * timer_get_clock( id ) ) / 1000000;
|
||||||
TimerLoadSet( base, TIMER_A, 0xFFFFFFFF );
|
TIM_SetCounter( ptimer, 0 );
|
||||||
while( TimerValueGet( base, TIMER_A ) > final );
|
for( dummy = 0; dummy < 200; dummy ++ );
|
||||||
|
while( TIM_GetCounter( ptimer ) < final );
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 platform_s_timer_op( unsigned id, int op, u32 data )
|
u32 platform_s_timer_op( unsigned id, int op, u32 data )
|
||||||
{
|
{
|
||||||
u32 res = 0;
|
u32 res = 0;
|
||||||
u32 base = timer_base[ id ];
|
TIM_TypeDef *ptimer = timer[ id ];
|
||||||
|
volatile unsigned dummy;
|
||||||
|
|
||||||
data = data;
|
data = data;
|
||||||
switch( op )
|
switch( op )
|
||||||
{
|
{
|
||||||
case PLATFORM_TIMER_OP_START:
|
case PLATFORM_TIMER_OP_START:
|
||||||
res = 0xFFFFFFFF;
|
TIM_SetCounter( ptimer, 0 );
|
||||||
TimerLoadSet( base, TIMER_A, 0xFFFFFFFF );
|
for( dummy = 0; dummy < 200; dummy ++ );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLATFORM_TIMER_OP_READ:
|
case PLATFORM_TIMER_OP_READ:
|
||||||
res = TimerValueGet( base, TIMER_A );
|
res = TIM_GetCounter( ptimer );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLATFORM_TIMER_OP_GET_MAX_DELAY:
|
case PLATFORM_TIMER_OP_GET_MAX_DELAY:
|
||||||
res = platform_timer_get_diff_us( id, 0, 0xFFFFFFFF );
|
res = platform_timer_get_diff_us( id, 0, 0xFFFF );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLATFORM_TIMER_OP_GET_MIN_DELAY:
|
case PLATFORM_TIMER_OP_GET_MIN_DELAY:
|
||||||
@ -585,122 +497,16 @@ u32 platform_s_timer_op( unsigned id, int op, u32 data )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PLATFORM_TIMER_OP_SET_CLOCK:
|
case PLATFORM_TIMER_OP_SET_CLOCK:
|
||||||
|
res = timer_set_clock( id, data );
|
||||||
|
break;
|
||||||
|
|
||||||
case PLATFORM_TIMER_OP_GET_CLOCK:
|
case PLATFORM_TIMER_OP_GET_CLOCK:
|
||||||
res = SysCtlClockGet();
|
res = timer_get_clock( id );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
u32 platform_s_timer_op( unsigned id, int op, u32 data )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STM32_USE_PWM
|
|
||||||
// ****************************************************************************
|
|
||||||
// PWMs
|
|
||||||
// TODO: Everything.
|
|
||||||
|
|
||||||
#define PLATFORM_NUM_PWMS 6
|
|
||||||
|
|
||||||
// SYSCTL div data and actual div factors
|
|
||||||
const static u32 pwm_div_ctl[] = { SYSCTL_PWMDIV_1, SYSCTL_PWMDIV_2, SYSCTL_PWMDIV_4, SYSCTL_PWMDIV_8, SYSCTL_PWMDIV_16, SYSCTL_PWMDIV_32, SYSCTL_PWMDIV_64 };
|
|
||||||
const static u8 pwm_div_data[] = { 1, 2, 4, 8, 16, 32, 64 };
|
|
||||||
// Port/pin information for all channels
|
|
||||||
const static u32 pwm_ports[] = { GPIO_PORTF_BASE, GPIO_PORTG_BASE, GPIO_PORTB_BASE, GPIO_PORTB_BASE, GPIO_PORTE_BASE, GPIO_PORTE_BASE };
|
|
||||||
const static u8 pwm_pins[] = { GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_0, GPIO_PIN_1 };
|
|
||||||
// PWM generators
|
|
||||||
const static u16 pwm_gens[] = { PWM_GEN_0, PWM_GEN_1, PWM_GEN_2 };
|
|
||||||
// PWM outputs
|
|
||||||
const static u16 pwm_outs[] = { PWM_OUT_0, PWM_OUT_1, PWM_OUT_2, PWM_OUT_3, PWM_OUT_4, PWM_OUT_5 };
|
|
||||||
|
|
||||||
static void pwms_init()
|
|
||||||
{
|
|
||||||
SysCtlPeripheralEnable( SYSCTL_PERIPH_PWM );
|
|
||||||
SysCtlPWMClockSet( SYSCTL_PWMDIV_1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function: return the PWM clock
|
|
||||||
static u32 platform_pwm_get_clock()
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
u32 clk;
|
|
||||||
|
|
||||||
clk = SysCtlPWMClockGet();
|
|
||||||
for( i = 0; i < sizeof( pwm_div_ctl ) / sizeof( u32 ); i ++ )
|
|
||||||
if( clk == pwm_div_ctl[ i ] )
|
|
||||||
break;
|
|
||||||
return SysCtlClockGet() / pwm_div_data[ i ];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function: set the PWM clock
|
|
||||||
static u32 platform_pwm_set_clock( u32 clock )
|
|
||||||
{
|
|
||||||
unsigned i, min_i;
|
|
||||||
u32 sysclk;
|
|
||||||
|
|
||||||
sysclk = SysCtlClockGet();
|
|
||||||
for( i = min_i = 0; i < sizeof( pwm_div_data ) / sizeof( u8 ); i ++ )
|
|
||||||
if( ABSDIFF( clock, sysclk / pwm_div_data[ i ] ) < ABSDIFF( clock, sysclk / pwm_div_data[ min_i ] ) )
|
|
||||||
min_i = i;
|
|
||||||
SysCtlPWMClockSet( pwm_div_ctl[ min_i ] );
|
|
||||||
return sysclk / pwm_div_data[ min_i ];
|
|
||||||
}
|
|
||||||
|
|
||||||
int platform_pwm_exists( unsigned id )
|
|
||||||
{
|
|
||||||
return id < PLATFORM_NUM_PWMS;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 platform_pwm_setup( unsigned id, u32 frequency, unsigned duty )
|
|
||||||
{
|
|
||||||
u32 pwmclk = platform_pwm_get_clock();
|
|
||||||
u32 period;
|
|
||||||
|
|
||||||
// Set pin as PWM
|
|
||||||
GPIOPinTypePWM( pwm_ports[ id ], pwm_pins[ id ] );
|
|
||||||
// Compute period
|
|
||||||
period = pwmclk / frequency;
|
|
||||||
// Set the period
|
|
||||||
PWMGenConfigure( PWM_BASE, pwm_gens[ id >> 1 ], PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC );
|
|
||||||
PWMGenPeriodSet( PWM_BASE, pwm_gens[ id >> 1 ], period );
|
|
||||||
// Set duty cycle
|
|
||||||
PWMPulseWidthSet( PWM_BASE, pwm_outs[ id ], ( period * duty ) / 100 );
|
|
||||||
// Return actual frequency
|
|
||||||
return pwmclk / period;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 platform_pwm_op( unsigned id, int op, u32 data )
|
|
||||||
{
|
|
||||||
u32 res = 0;
|
|
||||||
|
|
||||||
switch( op )
|
|
||||||
{
|
|
||||||
case PLATFORM_PWM_OP_SET_CLOCK:
|
|
||||||
res = platform_pwm_set_clock( data );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PLATFORM_PWM_OP_GET_CLOCK:
|
|
||||||
res = platform_pwm_get_clock();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PLATFORM_PWM_OP_START:
|
|
||||||
PWMOutputState( PWM_BASE, 1 << id, true );
|
|
||||||
PWMGenEnable( PWM_BASE, pwm_gens[ id >> 1 ] );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PLATFORM_PWM_OP_STOP:
|
|
||||||
PWMOutputState( PWM_BASE, 1 << id, false );
|
|
||||||
PWMGenDisable( PWM_BASE, pwm_gens[ id >> 1 ] );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// CPU specific functions
|
// CPU specific functions
|
||||||
@ -717,169 +523,6 @@ void platform_cpu_disable_interrupts()
|
|||||||
|
|
||||||
u32 platform_s_cpu_get_frequency()
|
u32 platform_s_cpu_get_frequency()
|
||||||
{
|
{
|
||||||
RCC_ClocksTypeDef clocks;
|
return HCLK;
|
||||||
|
|
||||||
RCC_GetClocksFreq(&clocks);
|
|
||||||
|
|
||||||
return clocks.HCLK_Frequency;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 platform_pclk1_get_frequency()
|
|
||||||
{
|
|
||||||
RCC_ClocksTypeDef clocks;
|
|
||||||
|
|
||||||
RCC_GetClocksFreq(&clocks);
|
|
||||||
|
|
||||||
return clocks.PCLK1_Frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 platform_pclk2_get_frequency()
|
|
||||||
{
|
|
||||||
RCC_ClocksTypeDef clocks;
|
|
||||||
|
|
||||||
RCC_GetClocksFreq(&clocks);
|
|
||||||
|
|
||||||
return clocks.PCLK2_Frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ****************************************************************************
|
|
||||||
// Ethernet functions
|
|
||||||
|
|
||||||
static void eth_init()
|
|
||||||
{
|
|
||||||
#ifdef BUILD_UIP
|
|
||||||
u32 user0, user1, temp;
|
|
||||||
static struct uip_eth_addr sTempAddr;
|
|
||||||
|
|
||||||
// Enable and reset the controller
|
|
||||||
SysCtlPeripheralEnable( SYSCTL_PERIPH_ETH );
|
|
||||||
SysCtlPeripheralReset( SYSCTL_PERIPH_ETH );
|
|
||||||
|
|
||||||
// Enable Ethernet LEDs
|
|
||||||
GPIODirModeSet( GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3, GPIO_DIR_MODE_HW );
|
|
||||||
GPIOPadConfigSet( GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD );
|
|
||||||
|
|
||||||
// Configure SysTick for a periodic interrupt.
|
|
||||||
SysTickPeriodSet(SysCtlClockGet() / SYSTICKHZ);
|
|
||||||
SysTickEnable();
|
|
||||||
SysTickIntEnable();
|
|
||||||
|
|
||||||
// Intialize the Ethernet Controller and disable all Ethernet Controller interrupt sources.
|
|
||||||
EthernetIntDisable(ETH_BASE, (ETH_INT_PHY | ETH_INT_MDIO | ETH_INT_RXER |
|
|
||||||
ETH_INT_RXOF | ETH_INT_TX | ETH_INT_TXER | ETH_INT_RX));
|
|
||||||
temp = EthernetIntStatus(ETH_BASE, false);
|
|
||||||
EthernetIntClear(ETH_BASE, temp);
|
|
||||||
|
|
||||||
// Initialize the Ethernet Controller for operation.
|
|
||||||
EthernetInitExpClk(ETH_BASE, SysCtlClockGet());
|
|
||||||
|
|
||||||
// Configure the Ethernet Controller for normal operation.
|
|
||||||
// - Full Duplex
|
|
||||||
// - TX CRC Auto Generation
|
|
||||||
// - TX Padding Enabled
|
|
||||||
EthernetConfigSet(ETH_BASE, (ETH_CFG_TX_DPLXEN | ETH_CFG_TX_CRCEN |
|
|
||||||
ETH_CFG_TX_PADEN));
|
|
||||||
|
|
||||||
// Enable the Ethernet Controller.
|
|
||||||
EthernetEnable(ETH_BASE);
|
|
||||||
|
|
||||||
// Enable the Ethernet interrupt.
|
|
||||||
IntEnable(INT_ETH);
|
|
||||||
|
|
||||||
// Enable the Ethernet RX Packet interrupt source.
|
|
||||||
EthernetIntEnable(ETH_BASE, ETH_INT_RX);
|
|
||||||
|
|
||||||
// Enable all processor interrupts.
|
|
||||||
IntMasterEnable();
|
|
||||||
|
|
||||||
// Configure the hardware MAC address for Ethernet Controller filtering of
|
|
||||||
// incoming packets.
|
|
||||||
//
|
|
||||||
// For the Ethernet Eval Kits, the MAC address will be stored in the
|
|
||||||
// non-volatile USER0 and USER1 registers. These registers can be read
|
|
||||||
// using the FlashUserGet function, as illustrated below.
|
|
||||||
FlashUserGet(&user0, &user1);
|
|
||||||
|
|
||||||
// Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC
|
|
||||||
// address needed to program the hardware registers, then program the MAC
|
|
||||||
// address into the Ethernet Controller registers.
|
|
||||||
sTempAddr.addr[0] = ((user0 >> 0) & 0xff);
|
|
||||||
sTempAddr.addr[1] = ((user0 >> 8) & 0xff);
|
|
||||||
sTempAddr.addr[2] = ((user0 >> 16) & 0xff);
|
|
||||||
sTempAddr.addr[3] = ((user1 >> 0) & 0xff);
|
|
||||||
sTempAddr.addr[4] = ((user1 >> 8) & 0xff);
|
|
||||||
sTempAddr.addr[5] = ((user1 >> 16) & 0xff);
|
|
||||||
|
|
||||||
// Program the hardware with it's MAC address (for filtering).
|
|
||||||
EthernetMACAddrSet(ETH_BASE, (unsigned char *)&sTempAddr);
|
|
||||||
|
|
||||||
// Initialize the eLua uIP layer
|
|
||||||
elua_uip_init( &sTempAddr );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef BUILD_UIP
|
|
||||||
static int eth_timer_fired;
|
|
||||||
|
|
||||||
void platform_eth_send_packet( const void* src, u32 size )
|
|
||||||
{
|
|
||||||
EthernetPacketPut( ETH_BASE, uip_buf, uip_len );
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 platform_eth_get_packet_nb( void* buf, u32 maxlen )
|
|
||||||
{
|
|
||||||
return EthernetPacketGetNonBlocking( ETH_BASE, uip_buf, sizeof( uip_buf ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void platform_eth_force_interrupt()
|
|
||||||
{
|
|
||||||
HWREG( NVIC_SW_TRIG) |= INT_ETH - 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 platform_eth_get_elapsed_time()
|
|
||||||
{
|
|
||||||
if( eth_timer_fired )
|
|
||||||
{
|
|
||||||
eth_timer_fired = 0;
|
|
||||||
return SYSTICKMS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void SysTickHandler(void)
|
|
||||||
{
|
|
||||||
// Indicate that a SysTick interrupt has occurred.
|
|
||||||
eth_timer_fired = 1;
|
|
||||||
|
|
||||||
// Generate a fake Ethernet interrupt. This will perform the actual work
|
|
||||||
// of incrementing the timers and taking the appropriate actions.
|
|
||||||
platform_eth_force_interrupt();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void EthernetIntHandler()
|
|
||||||
{
|
|
||||||
u32 temp;
|
|
||||||
|
|
||||||
// Read and Clear the interrupt.
|
|
||||||
temp = EthernetIntStatus( ETH_BASE, false );
|
|
||||||
EthernetIntClear( ETH_BASE, temp );
|
|
||||||
|
|
||||||
// Call the UIP main loop
|
|
||||||
elua_uip_mainloop();
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // #ifdef ELUA_UIP
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void SysTickHandler()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void EthernetIntHandler()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif // #ifdef ELUA_UIP
|
|
||||||
|
@ -6,11 +6,12 @@
|
|||||||
#include "auxmods.h"
|
#include "auxmods.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "stacks.h"
|
#include "stacks.h"
|
||||||
|
#include "stm32f10x_lib.h"
|
||||||
|
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// Define here what components you want for this platform
|
// Define here what components you want for this platform
|
||||||
|
|
||||||
//#define BUILD_XMODEM
|
#define BUILD_XMODEM
|
||||||
#define BUILD_SHELL
|
#define BUILD_SHELL
|
||||||
#define BUILD_ROMFS
|
#define BUILD_ROMFS
|
||||||
#define BUILD_TERM
|
#define BUILD_TERM
|
||||||
@ -50,6 +51,7 @@ LUALIB_API int ( luaopen_lcd )( lua_State* L );
|
|||||||
_ROM( AUXLIB_PACK, luaopen_pack, pack_map )\
|
_ROM( AUXLIB_PACK, luaopen_pack, pack_map )\
|
||||||
_ROM( AUXLIB_BIT, luaopen_bit, bit_map )\
|
_ROM( AUXLIB_BIT, luaopen_bit, bit_map )\
|
||||||
_ROM( AUXLIB_CPU, luaopen_cpu, cpu_map )\
|
_ROM( AUXLIB_CPU, luaopen_cpu, cpu_map )\
|
||||||
|
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
|
||||||
LCDLINE\
|
LCDLINE\
|
||||||
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )
|
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )
|
||||||
|
|
||||||
@ -87,8 +89,8 @@ LUALIB_API int ( luaopen_lcd )( lua_State* L );
|
|||||||
// Number of resources (0 if not available/not implemented)
|
// Number of resources (0 if not available/not implemented)
|
||||||
#define NUM_PIO 7
|
#define NUM_PIO 7
|
||||||
#define NUM_SPI 0
|
#define NUM_SPI 0
|
||||||
#define NUM_UART 4
|
#define NUM_UART 5
|
||||||
#define NUM_TIMER 0
|
#define NUM_TIMER 6
|
||||||
#define NUM_PWM 0
|
#define NUM_PWM 0
|
||||||
#define NUM_ADC 0
|
#define NUM_ADC 0
|
||||||
|
|
||||||
@ -102,7 +104,7 @@ u32 platform_s_cpu_get_frequency();
|
|||||||
// #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
|
// #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
|
||||||
// #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
|
// #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
|
||||||
// Use #define PIO_PINS_PER_PORT 0 if this isn't needed
|
// Use #define PIO_PINS_PER_PORT 0 if this isn't needed
|
||||||
#define PIO_PIN_ARRAY { 16, 16, 16, 16, 16, 16, 16 }
|
#define PIO_PINS_PER_PORT 16
|
||||||
|
|
||||||
// Allocator data: define your free memory zones here in two arrays
|
// Allocator data: define your free memory zones here in two arrays
|
||||||
// (start address and end address)
|
// (start address and end address)
|
||||||
@ -110,61 +112,5 @@ u32 platform_s_cpu_get_frequency();
|
|||||||
#define MEM_START_ADDRESS { ( void* )end }
|
#define MEM_START_ADDRESS { ( void* )end }
|
||||||
#define MEM_END_ADDRESS { ( void* )( SRAM_BASE + SRAM_SIZE - STACK_SIZE_TOTAL - 1 ) }
|
#define MEM_END_ADDRESS { ( void* )( SRAM_BASE + SRAM_SIZE - STACK_SIZE_TOTAL - 1 ) }
|
||||||
|
|
||||||
// *****************************************************************************
|
|
||||||
// CPU constants that should be exposed to the eLua "cpu" module
|
|
||||||
|
|
||||||
#include "stm32f10x_gpio.h"
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define PLATFORM_CPU_CONSTANTS\
|
|
||||||
_C( INT_GPIOA ),\
|
|
||||||
_C( INT_GPIOB ),\
|
|
||||||
_C( INT_GPIOC ),\
|
|
||||||
_C( INT_GPIOD ),\
|
|
||||||
_C( INT_GPIOE ),\
|
|
||||||
_C( INT_UART0 ),\
|
|
||||||
_C( INT_UART1 ),\
|
|
||||||
_C( INT_SSI0 ),\
|
|
||||||
_C( INT_I2C0 ),\
|
|
||||||
_C( INT_PWM_FAULT ),\
|
|
||||||
_C( INT_PWM0 ),\
|
|
||||||
_C( INT_PWM1 ),\
|
|
||||||
_C( INT_PWM2 ),\
|
|
||||||
_C( INT_QEI0 ),\
|
|
||||||
_C( INT_ADC0 ),\
|
|
||||||
_C( INT_ADC1 ),\
|
|
||||||
_C( INT_ADC2 ),\
|
|
||||||
_C( INT_ADC3 ),\
|
|
||||||
_C( INT_WATCHDOG ),\
|
|
||||||
_C( INT_TIMER0A ),\
|
|
||||||
_C( INT_TIMER0B ),\
|
|
||||||
_C( INT_TIMER1A ),\
|
|
||||||
_C( INT_TIMER1B ),\
|
|
||||||
_C( INT_TIMER2A ),\
|
|
||||||
_C( INT_TIMER2B ),\
|
|
||||||
_C( INT_COMP0 ),\
|
|
||||||
_C( INT_COMP1 ),\
|
|
||||||
_C( INT_COMP2 ),\
|
|
||||||
_C( INT_SYSCTL ),\
|
|
||||||
_C( INT_FLASH ),\
|
|
||||||
_C( INT_GPIOF ),\
|
|
||||||
_C( INT_GPIOG ),\
|
|
||||||
_C( INT_GPIOH ),\
|
|
||||||
_C( INT_UART2 ),\
|
|
||||||
_C( INT_SSI1 ),\
|
|
||||||
_C( INT_TIMER3A ),\
|
|
||||||
_C( INT_TIMER3B ),\
|
|
||||||
_C( INT_I2C1 ),\
|
|
||||||
_C( INT_QEI1 ),\
|
|
||||||
_C( INT_CAN0 ),\
|
|
||||||
_C( INT_CAN1 ),\
|
|
||||||
_C( INT_CAN2 ),\
|
|
||||||
_C( INT_ETH ),\
|
|
||||||
_C( INT_HIBERNATE ),\
|
|
||||||
_C( INT_USB0 ),\
|
|
||||||
_C( INT_PWM3 ),\
|
|
||||||
_C( INT_UDMA ),\
|
|
||||||
_C( INT_UDMAERR )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // #ifndef __PLATFORM_CONF_H__
|
#endif // #ifndef __PLATFORM_CONF_H__
|
||||||
|
|
||||||
|
56
src/xmodem.c
56
src/xmodem.c
@ -38,23 +38,23 @@
|
|||||||
#include "platform_conf.h"
|
#include "platform_conf.h"
|
||||||
#ifdef BUILD_XMODEM
|
#ifdef BUILD_XMODEM
|
||||||
|
|
||||||
#define PACKET_SIZE 128
|
#define PXM_ACKET_SIZE 128
|
||||||
static p_xm_send_func xmodem_out_func;
|
static p_xm_send_func xmodem_out_func;
|
||||||
static p_xm_recv_func xmodem_in_func;
|
static p_xm_recv_func xmodem_in_func;
|
||||||
|
|
||||||
// Line control codes
|
// Line control codes
|
||||||
#define SOH 0x01
|
#define XM_SOH 0x01
|
||||||
#define ACK 0x06
|
#define XM_ACK 0x06
|
||||||
#define NAK 0x15
|
#define XM_NAK 0x15
|
||||||
#define CAN 0x18
|
#define XM_CAN 0x18
|
||||||
#define EOT 0x04
|
#define XM_EOT 0x04
|
||||||
|
|
||||||
// Arguments to xmodem_flush
|
// Arguments to xmodem_flush
|
||||||
#define XMODEM_FLUSH_ONLY 0
|
#define XMODEM_FLUSH_ONLY 0
|
||||||
#define XMODEM_FLUSH_AND_CAN 1
|
#define XMODEM_FLUSH_AND_XM_CAN 1
|
||||||
|
|
||||||
// Delay in "flush packet" mode
|
// Delay in "flush packet" mode
|
||||||
#define XMODEM_PACKET_DELAY 10000UL
|
#define XMODEM_PXM_ACKET_DELAY 10000UL
|
||||||
|
|
||||||
void xmodem_init( p_xm_send_func send_func, p_xm_recv_func recv_func )
|
void xmodem_init( p_xm_send_func send_func, p_xm_recv_func recv_func )
|
||||||
{
|
{
|
||||||
@ -65,12 +65,12 @@ void xmodem_init( p_xm_send_func send_func, p_xm_recv_func recv_func )
|
|||||||
// Utility function: flush the receive buffer
|
// Utility function: flush the receive buffer
|
||||||
static void xmodem_flush( int how )
|
static void xmodem_flush( int how )
|
||||||
{
|
{
|
||||||
while( xmodem_in_func( XMODEM_PACKET_DELAY ) != -1 );
|
while( xmodem_in_func( XMODEM_PXM_ACKET_DELAY ) != -1 );
|
||||||
if( how == XMODEM_FLUSH_AND_CAN )
|
if( how == XMODEM_FLUSH_AND_XM_CAN )
|
||||||
{
|
{
|
||||||
xmodem_out_func( CAN );
|
xmodem_out_func( XM_CAN );
|
||||||
xmodem_out_func( CAN );
|
xmodem_out_func( XM_CAN );
|
||||||
xmodem_out_func( CAN );
|
xmodem_out_func( XM_CAN );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ static int xmodem_get_record( unsigned char blocknum, unsigned char *pbuf )
|
|||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
// Read packet
|
// Read packet
|
||||||
for( j = 0; j < PACKET_SIZE + 4; j ++ )
|
for( j = 0; j < PXM_ACKET_SIZE + 4; j ++ )
|
||||||
{
|
{
|
||||||
if( ( ch = xmodem_in_func( XMODEM_TIMEOUT ) ) == -1 )
|
if( ( ch = xmodem_in_func( XMODEM_TIMEOUT ) ) == -1 )
|
||||||
goto err;
|
goto err;
|
||||||
@ -95,7 +95,7 @@ static int xmodem_get_record( unsigned char blocknum, unsigned char *pbuf )
|
|||||||
if( *pbuf ++ != ( unsigned char )~blocknum )
|
if( *pbuf ++ != ( unsigned char )~blocknum )
|
||||||
goto err;
|
goto err;
|
||||||
// Check CRC
|
// Check CRC
|
||||||
for( size = chk = 0; size < PACKET_SIZE; size++, pbuf ++ )
|
for( size = chk = 0; size < PXM_ACKET_SIZE; size++, pbuf ++ )
|
||||||
{
|
{
|
||||||
chk = chk ^ *pbuf << 8;
|
chk = chk ^ *pbuf << 8;
|
||||||
for( j = 0; j < 8; j ++ )
|
for( j = 0; j < 8; j ++ )
|
||||||
@ -114,7 +114,7 @@ static int xmodem_get_record( unsigned char blocknum, unsigned char *pbuf )
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
xmodem_out_func( NAK );
|
xmodem_out_func( XM_NAK );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ err:
|
|||||||
long xmodem_receive( char **dest )
|
long xmodem_receive( char **dest )
|
||||||
{
|
{
|
||||||
int starting = 1, ch;
|
int starting = 1, ch;
|
||||||
unsigned char packnum = 1, buf[ PACKET_SIZE + 4 ];
|
unsigned char packnum = 1, buf[ PXM_ACKET_SIZE + 4 ];
|
||||||
unsigned retries = XMODEM_RETRY_LIMIT;
|
unsigned retries = XMODEM_RETRY_LIMIT;
|
||||||
u32 limit = XMODEM_INITIAL_BUFFER_SIZE, size = 0;
|
u32 limit = XMODEM_INITIAL_BUFFER_SIZE, size = 0;
|
||||||
void *p;
|
void *p;
|
||||||
@ -133,19 +133,19 @@ long xmodem_receive( char **dest )
|
|||||||
{
|
{
|
||||||
if( starting )
|
if( starting )
|
||||||
xmodem_out_func( 'C' );
|
xmodem_out_func( 'C' );
|
||||||
if( ( ( ch = xmodem_in_func( XMODEM_TIMEOUT ) ) == -1 ) || ( ch != SOH && ch != EOT && ch != CAN ) )
|
if( ( ( ch = xmodem_in_func( XMODEM_TIMEOUT ) ) == -1 ) || ( ch != XM_SOH && ch != XM_EOT && ch != XM_CAN ) )
|
||||||
continue;
|
continue;
|
||||||
if( ch == EOT )
|
if( ch == XM_EOT )
|
||||||
{
|
{
|
||||||
// End of transmission
|
// End of transmission
|
||||||
xmodem_out_func( ACK );
|
xmodem_out_func( XM_ACK );
|
||||||
xmodem_flush( XMODEM_FLUSH_ONLY );
|
xmodem_flush( XMODEM_FLUSH_ONLY );
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
else if( ch == CAN )
|
else if( ch == XM_CAN )
|
||||||
{
|
{
|
||||||
// The remote part ended the transmission
|
// The remote part ended the transmission
|
||||||
xmodem_out_func( ACK );
|
xmodem_out_func( XM_ACK );
|
||||||
xmodem_flush( XMODEM_FLUSH_ONLY );
|
xmodem_flush( XMODEM_FLUSH_ONLY );
|
||||||
return XMODEM_ERROR_REMOTECANCEL;
|
return XMODEM_ERROR_REMOTECANCEL;
|
||||||
}
|
}
|
||||||
@ -159,25 +159,25 @@ long xmodem_receive( char **dest )
|
|||||||
packnum ++;
|
packnum ++;
|
||||||
|
|
||||||
// Got a valid packet
|
// Got a valid packet
|
||||||
if( size + PACKET_SIZE > limit )
|
if( size + PXM_ACKET_SIZE > limit )
|
||||||
{
|
{
|
||||||
limit += XMODEM_INCREMENT_AMMOUNT;
|
limit += XMODEM_INCREMENT_AMMOUNT;
|
||||||
if( ( p = realloc( *dest, limit ) ) == NULL )
|
if( ( p = realloc( *dest, limit ) ) == NULL )
|
||||||
{
|
{
|
||||||
// Not enough memory, force cancel and return
|
// Not enough memory, force cancel and return
|
||||||
xmodem_flush( XMODEM_FLUSH_AND_CAN );
|
xmodem_flush( XMODEM_FLUSH_AND_XM_CAN );
|
||||||
return XMODEM_ERROR_OUTOFMEM;
|
return XMODEM_ERROR_OUTOFMEM;
|
||||||
}
|
}
|
||||||
*dest = ( char* )p;
|
*dest = ( char* )p;
|
||||||
}
|
}
|
||||||
// Acknowledge and consume packet
|
// Acknowledge and consume packet
|
||||||
xmodem_out_func( ACK );
|
xmodem_out_func( XM_ACK );
|
||||||
memcpy( *dest + size, buf + 2, PACKET_SIZE );
|
memcpy( *dest + size, buf + 2, PXM_ACKET_SIZE );
|
||||||
size += PACKET_SIZE;
|
size += PXM_ACKET_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exceeded retry count
|
// Exceeded retry count
|
||||||
xmodem_flush( XMODEM_FLUSH_AND_CAN );
|
xmodem_flush( XMODEM_FLUSH_AND_XM_CAN );
|
||||||
return XMODEM_ERROR_RETRYEXCEED;
|
return XMODEM_ERROR_RETRYEXCEED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user