1
0
mirror of https://github.com/elua/elua.git synced 2025-01-25 01:02:54 +08:00

LPC2888 port mostly functional, still working on it

This commit is contained in:
Bogdan Marinescu 2008-08-12 20:00:05 +00:00
parent 5efc3cb2ac
commit 3406a06f4d
7 changed files with 207 additions and 293 deletions

View File

@ -6,6 +6,6 @@
//#define BUILD_XMODEM
#define BUILD_SHELL
#define BUILD_ROMFS
//#define BUILD_TERM
#define BUILD_TERM
#endif

View File

@ -2,7 +2,7 @@
cpumode = ARGUMENTS.get( 'cpumode', 'arm' ).lower()
specific_files = "lpc28xx.s platform.c target.c"
specific_files = "lpc28xx.s platform.c target.c uart.c"
# Check CPU
if cputype == 'lpc2888':

View File

@ -12,17 +12,19 @@
#include <stdio.h>
#include "lpc288x.h"
#include "target.h"
#include "uart.h"
// *****************************************************************************
// std functions
static void uart_send( int fd, char c )
{
uart_write( c );
}
static int uart_recv()
{
return 0;
return uart_read();
}
// ****************************************************************************
@ -33,35 +35,95 @@ int platform_init()
// Initialize CPU
lpc288x_init();
// Initialize UART
// Initialize UART
uart_init( 115200, 8, PLATFORM_UART_PARITY_NONE, PLATFORM_UART_STOPBITS_1 );
// Set the send/recv functions
std_set_send_func( uart_send );
std_set_get_func( uart_recv );
return PLATFORM_OK;
}
// ****************************************************************************
// PIO functions
// Array with register addresses
typedef volatile unsigned int* vu_ptr;
static const vu_ptr pio_m0s_regs[] = { &MODE0S_0, &MODE0S_1, &MODE0S_2, &MODE0S_3, &MODE0S_4, &MODE0S_5, &MODE0S_6, &MODE0S_7 };
static const vu_ptr pio_m0c_regs[] = { &MODE0C_0, &MODE0C_1, &MODE0C_2, &MODE0C_3, &MODE0C_4, &MODE0C_5, &MODE0C_6, &MODE0C_7 };
static const vu_ptr pio_m1s_regs[] = { &MODE1S_0, &MODE1S_1, &MODE1S_2, &MODE1S_3, &MODE1S_4, &MODE1S_5, &MODE1S_6, &MODE1S_7 };
static const vu_ptr pio_m1c_regs[] = { &MODE1C_0, &MODE1C_1, &MODE1C_2, &MODE1C_3, &MODE1C_4, &MODE1C_5, &MODE1C_6, &MODE1C_7 };
static const vu_ptr pio_m0_regs[] = { &MODE0_0, &MODE0_1, &MODE0_2, &MODE0_3, &MODE0_4, &MODE0_5, &MODE0_6, &MODE0_7 };
static const vu_ptr pio_m1_regs[] = { &MODE1_0, &MODE1_1, &MODE1_2, &MODE1_3, &MODE1_4, &MODE1_5, &MODE1_6, &MODE1_7 };
static const vu_ptr pio_pin_regs[] = { &PINS_0, &PINS_1, &PINS_2, &PINS_3, &PINS_4, &PINS_5, &PINS_6, &PINS_7 };
int platform_pio_has_port( unsigned port )
{
return 0;
return port < 8;
}
const char* platform_pio_get_prefix( unsigned port )
{
return NULL;
static char c[ 3 ];
sprintf( c, "P%d", port );
return c;
}
// Maximum number of pins per port
static const unsigned pins_per_port[] = { 32, 20, 4, 6, 12, 6, 4, 1 };
int platform_pio_has_pin( unsigned port, unsigned pin )
{
return 0;
return port < 8 && pins_per_port[ port ] < pin;
}
pio_type platform_pio_op( unsigned port, pio_type pinmask, int op )
{
return 0;
pio_type retval = 0;
switch( op )
{
case PLATFORM_IO_PORT_SET_VALUE:
*pio_m0_regs[ port ] = pinmask;
break;
case PLATFORM_IO_PIN_SET:
*pio_m0s_regs[ port ] = pinmask;
break;
case PLATFORM_IO_PIN_CLEAR:
*pio_m0c_regs[ port ] = pinmask;
break;
case PLATFORM_IO_PORT_DIR_OUTPUT:
*pio_m1_regs[ port ] = 0xFFFFFFFF;
break;
case PLATFORM_IO_PIN_DIR_OUTPUT:
*pio_m1s_regs[ port ] = pinmask;
break;
case PLATFORM_IO_PORT_DIR_INPUT:
*pio_m1_regs[ port ] = 0;
*pio_m0_regs[ port ] = 0;
break;
case PLATFORM_IO_PIN_DIR_INPUT:
*pio_m1c_regs[ port ] = pinmask;
*pio_m0c_regs[ port ] = pinmask;
break;
case PLATFORM_IO_PORT_GET_VALUE:
retval = *pio_pin_regs[ port ];
break;
case PLATFORM_IO_PIN_GET:
retval = *pio_pin_regs[ port ] & pinmask ? 1 : 0;
break;
}
return retval;
}
// ****************************************************************************
@ -69,21 +131,48 @@ pio_type platform_pio_op( unsigned port, pio_type pinmask, int op )
int platform_uart_exists( unsigned id )
{
return 0;
return id < 1;
}
u32 platform_uart_setup( unsigned id, u32 baud, int databits, int parity, int stopbits )
{
return 0;
return uart_init( baud, databits, parity, stopbits );
}
void platform_uart_send( unsigned id, u8 data )
{
uart_write( data );
}
int platform_uart_recv( unsigned id, unsigned timer_id, int timeout )
{
return -1;
timer_data_type tmr_start, tmr_crt;
int res;
if( timeout == 0 )
{
// Return data only if already available
return uart_read_nb();
}
else if( timeout == PLATFORM_UART_INFINITE_TIMEOUT )
{
// Wait for data
return uart_read();
}
else
{
// Receive char with the specified timeout
tmr_start = platform_timer_op( timer_id, PLATFORM_TIMER_OP_START,0 );
while( 1 )
{
if( ( res = uart_read_nb() ) > 0 )
break;
tmr_crt = platform_timer_op( timer_id, PLATFORM_TIMER_OP_READ, 0 );
if( platform_timer_get_diff_us( timer_id, tmr_crt, tmr_start ) >= timeout )
break;
}
return res;
}
}
// ****************************************************************************
@ -94,18 +183,6 @@ int platform_timer_exists( unsigned id )
return 0;
}
// Helper: get timer clock
static u32 platform_timer_get_clock( unsigned id )
{
return 0;
}
// Helper: set timer clock
static u32 platform_timer_set_clock( unsigned id, u32 clock )
{
return 0;
}
void platform_timer_delay( unsigned id, u32 delay_us )
{
}
@ -135,7 +212,7 @@ const char* platform_pd_get_cpu_name()
u32 platform_pd_get_cpu_frequency()
{
return 0;
return Fcclk;
}
// ****************************************************************************

View File

@ -3,4 +3,12 @@
#ifndef __PLATFORM_LIBS_H__
#define __PLATFORM_LIBS_H__
#include "auxmods.h"
#define LUA_PLATFORM_LIBS\
{ AUXLIB_PIO, luaopen_pio},\
{ AUXLIB_PD, luaopen_pd },\
{ AUXLIB_UART, luaopen_uart },\
{ AUXLIB_TERM, luaopen_term }
#endif

View File

@ -15,17 +15,6 @@ typedef enum _SectionInClockSelect_t
HighPLL = 7, MainPLL,
} SectionInClockSelect_t;
static void Dly_us(u32 Dly)
{
INT_REQ5 = 0x04010000; // enable interrupt
T0CTRL = 0; // stop counting
T0LOAD = 12 * Dly; // load period
T0CLR = 0; // clear timer pendig interrupt
T0CTRL |= ( 1 << 7 ); // enable counting
while( !( INT_PENDING & ( 1 << 5 ) ) );
T0CTRL &= ~( 1 << 7 );
}
static void LPC288x_SectionClockSelect(volatile unsigned int * pReg, u32 Mode)
{
#define ST_OFFSET ((unsigned long *)&SYSSSR - (unsigned long *)&SYSSCR)
@ -84,7 +73,7 @@ static void InitSDRAMCtrl(void)
// DELAY to allow power and clocks to stabilize ~100 us
// NOP
EMC_DYN_CTRL = 0x4183;
Dly_us(200);
for( i = 0; i < 1000; i ++ );
// PALL
EMC_DYN_CTRL = ( EMC_DYN_CTRL & ~0x180 ) | ( 2 << 7 );

View File

@ -1,274 +1,100 @@
/*****************************************************************************
* uart.c: UART API file for NXP LPC288x Family Microprocessors
*
* Copyright(C) 2006, NXP Semiconductor
* All rights reserved.
*
* History
* 2006.07.12 ver 1.00 Prelimnary version, first Release
*
******************************************************************************/
#include "LPC288x.h" /* LPC288x definitions */
// UART driver for LPC2888
#include "lpc288x.h" /* LPC288x definitions */
#include "type.h"
#include "target.h"
#include "irq.h"
#include "uart.h"
#include <reent.h>
#include <errno.h>
#include <string.h>
static char uart_rx_buf[ UART_BUFSIZE ];
volatile static int uart_rx_in, uart_rx_out;
int uart_tx_count;
#define LABS( x ) ( ( x ) < 0 ? -( x ) : ( x ) )
// Structure with UART baud/parameters
// Computed used Philip's "baud rate calculator" XLS file
// Pre-computed values for different baud rates, using Philip's 'baud rate calculator' XLS file
typedef struct
{
int udlm, udll, divaddval, mulval;
} BAUDDATA;
unsigned baud;
unsigned udlm, udll, divaddval, mulval;
} UART_BAUDDATA;
static const BAUDDATA baudinfo[] =
static const UART_BAUDDATA uart_baudinfo[] =
{
{ 12, 53, 0, 2 },
{ 4, 226, 1, 4 },
{ 2, 113, 1, 4 },
{ 0, 217, 4, 5 },
{ 0, 217, 1, 5 },
{ 0, 71, 3, 8 },
{ 0, 47, 5, 13 },
{ 0, 24, 5, 14 },
};
// Local state information
static struct uart_data uartdata;
static void uart_isr(void)
{
u8 IIRValue, LSRValue;
u8 dummy;
IIRValue = UART_IIR;
IIRValue >>= 1; /* skip pending bit in IIR */
IIRValue &= 0x07; /* check bit 1~3, interrupt identification */
if ( IIRValue == IIR_RLS ) /* Receive Line Status */
{
LSRValue = UART_LSR;
/* Receive Line Status */
if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
{
/* There are errors or break interrupt */
/* Read LSR will clear the interrupt */
dummy = UART_RBR;
return;
}
if( LSRValue & LSR_RDR ) /* Receive Data Ready */
{
dummy = UART_RBR;
if( dummy != '\r' )
{
uart_rx_buf[ uart_rx_in ] = dummy;
UART_INC_OP( uart_rx_in );
}
}
}
else if ( IIRValue == IIR_RDA ) /* Receive Data Available */
{
dummy = UART_RBR;
if( dummy != '\r' )
{
uart_rx_buf[ uart_rx_in ] = dummy;
UART_INC_OP( uart_rx_in );
}
}
else if ( IIRValue == IIR_CTI ) /* Character timeout indicator */
{
dummy = UART_RBR;
}
}
// Utility function: write a char to the UART
static void uart_putchar( char c )
{
if( uart_tx_count == TXBUFSIZE )
{
while( ( UART_LSR & LSR_THRE ) == 0 );
uart_tx_count = 0;
}
UART_THR = c;
uart_tx_count ++;
}
// Utility function: return the number of bytes in the UART RX buffer
static int uart_bytes_received()
{
return ( uart_rx_in + UART_BUFSIZE - uart_rx_out ) & UART_BUF_MASK;
}
// Utility function: read a char from the UART. This is a BLOCKING function.
static char uart_getchar()
{
char c;
while( uart_bytes_received() == 0 );
c = uart_rx_buf[ uart_rx_out ];
UART_INC_OP( uart_rx_out );
return c;
}
// 'read' function for UART
static long uart_read( struct _reent *r, int fd, char *ptr, int len )
{
int i, c;
// Check file number
if( ( fd < DM_STDIN_NUM ) || ( fd > DM_STDERR_NUM ) )
{
r->_errno = EBADF;
return -1;
}
if( fd != DM_STDIN_NUM )
{
r->_errno = EINVAL;
return -1;
}
for( i = 0; i < len; i ++ )
{
c = uart_getchar();
ptr[ i ] = c;
if( c == '\n' )
return i + 1;
}
return len;
}
// 'write' function for UART
static long uart_write( struct _reent *r, int fd, const char *ptr, int len )
{
int i;
// Check file number
if( ( fd < DM_STDIN_NUM ) || ( fd > DM_STDERR_NUM ) )
{
r->_errno = EBADF;
return -1;
}
if( ( fd != DM_STDOUT_NUM ) && ( fd != DM_STDERR_NUM ) )
{
r->_errno = EINVAL;
return -1;
}
for( i = 0; i < len; i ++ )
uart_putchar( ptr[ i ] );
return len;
}
// 'ioctl' function for UART
static int uart_ioctl( struct _reent *r, int file, unsigned long request, void *ptr )
{
struct uart_data *pdata;
int temp, oldint;
const BAUDDATA* pbaud;
// Check file number
if( ( file < DM_STDIN_NUM ) || ( file > DM_STDERR_NUM ) )
{
r->_errno = EBADF;
return -1;
}
// Check request
if( ( request < IOCTL_UART_FIRST ) || ( request > IOCTL_UART_LAST ) )
{
r->_errno = EINVAL;
return -1;
}
// Serve request
switch( request )
{
case IOCTL_UART_SET:
// Set UART data
pdata = ( struct uart_data* )ptr;
if( pdata->baud < 0 || pdata->baud > UART_BAUD_115200 )
{
r->_errno = EINVAL;
return -1;
}
memcpy( &uartdata, pdata, sizeof( struct uart_data ) );
// Disable all interrupts and initialize FIFOs
temp = UART_IIR;
oldint = UART_IER;
UART_IER = 0;
UART_FCR = 0x0F;
// Setup format and enable access to divisor latches
temp = pdata->databits == UART_8_DATABITS ? 3 : 2;
temp |= ( pdata->parity == UART_ODD_PARITY ) ? 0x08 : ( ( pdata->parity == UART_EVEN_PARITY ) ? 0x18 : 0 );
UART_LCR = temp | 0x80;
// Write divisor latches and fractional data
pbaud = baudinfo + pdata->baud;
UART_DLM = pbaud->udlm;
UART_DLL = pbaud->udll;
UART_FDR = ( pbaud->mulval << 4 ) + pbaud->divaddval;
// Re-enable UART and its interrupts
UART_LCR = temp;
UART_IER = oldint;
break;
case IOCTL_UART_GET:
memcpy( ptr, &uartdata, sizeof( struct uart_data ) );
break;
case IOCTL_UART_FLUSH_IN:
while( uart_rx_in != uart_rx_out )
uart_getchar();
break;
case IOCTL_UART_FLUSH_OUT:
while( ( UART_LSR & LSR_THRE ) == 0 );
uart_tx_count = 0;
break;
}
return 0;
}
// Our UART device descriptor structure
static DM_DEVICE uart_device =
{
UART_DEV_NAME,
NULL, // we don't have 'open' on UART
NULL, // we don't hace 'close' on UART
uart_write,
uart_read,
uart_ioctl
{ 1200, 12, 53, 0, 2 },
{ 2400, 4, 226, 1, 4 },
{ 4800, 2, 113, 1, 4 },
{ 9600, 0, 217, 4, 5 },
{ 14400, 0, 217, 1, 5 },
{ 38400, 0, 71, 3, 8 },
{ 57600, 0, 47, 5, 13 },
{ 115200, 0, 24, 5, 14 }
};
// Initialize the UART device with the data found in the 'pdata' structure
// Returns a pointer to the UART's 'device' structure if OK, NULL for error
DM_DEVICE* uart_init( struct uart_data* pdata )
{
// Call the IOCTL function directly to set UART parameters
if( uart_ioctl( _REENT, DM_STDIN_NUM, IOCTL_UART_SET, pdata ) != 0 )
return NULL;
// Install UART interrupt handler
if ( install_IRQ( 12, 1, uart_isr ) == FALSE )
return NULL;
INT_REQ12 = ( 1<<28 ) | ( 1<<27 ) | ( 1<<26 ) | ( 1<<16 ) | 0x1;
UART_IER = IER_RBR | IER_RLS;
return &uart_device;
// Write a character to the UART
void uart_write( u8 data )
{
while( ( UART_LSR & LSR_THRE ) == 0 );
UART_THR = data;
}
// Return UART's descriptor
DM_DEVICE* platform_get_uart_desc()
// Read a character from the UART (blocking)
u8 uart_read()
{
return &uart_device;
while( ( UART_LSR & LSR_RDR ) == 0 );
return UART_RBR & 0xFF;
}
// Read a character from the UART (non-blocking)
int uart_read_nb()
{
if( ( UART_LSR & LSR_RDR ) == 0 )
return -1;
else
return UART_RBR & 0xFF;
}
// Initialize UART
u32 uart_init( u32 baud, int databits, int parity, int stopbits )
{
unsigned i, minpos;
const UART_BAUDDATA* pdata;
u32 temp;
// Setup I/O ports
// RXD is P6.0, TXD is P6.1
MODE0S_6 = 3;
MODE1C_6 = 3;
// Find correct baud
for( i = minpos = 0; i < sizeof( uart_baudinfo ) / sizeof( UART_BAUDDATA ); i ++ )
if( LABS( baud - uart_baudinfo[ i ].baud ) < LABS( baud - uart_baudinfo[ minpos ].baud ) )
minpos = i;
pdata = uart_baudinfo + minpos;
// Disable all interrupts and initialize FIFOs
UART_IER = 0;
UART_FCR = 0x0F;
// Setup format and enable access to divisor latches
temp = databits - 5;
if( stopbits == PLATFORM_UART_STOPBITS_2 || stopbits == PLATFORM_UART_STOPBITS_1_5 )
temp |= 1 << 2;
if( parity != PLATFORM_UART_PARITY_NONE )
{
temp |= 1 << 3;
if( parity == PLATFORM_UART_PARITY_EVEN )
temp |= 1 << 4;
}
UART_LCR = temp | 0x80;
// Write divisor latches and fractional data
UART_DLM = pdata->udlm;
UART_DLL = pdata->udll;
UART_FDR = ( pdata->mulval << 4 ) + pdata->divaddval;
// Re-enable UART and its interrupts
UART_LCR = temp;
return pdata->baud;
}

View File

@ -0,0 +1,14 @@
// UART driver for LPC2888
#ifndef __UART_H__
#define __UART_H__
#include "platform.h"
#include "type.h"
u32 uart_init( u32 baud, int databits, int parity, int stopbits );
void uart_write( u8 data );
u8 uart_read();
int uart_read_nb();
#endif