共2条
1/1 1 跳转至页
easyARM2200,eCos 在easyARM2200上成功移植eCos
问
答 1:
RE:如果乐意的话,你可以考虑将移植结果与大家交流
答 2:
能交流一下吗?
答 3:
移植中的问题现在移植过程中还有一个难题,就是8019的移植。找到的ecos下8019的补丁代码是在PC下的代码。虽然有人声称移植成功,但它给出的具体方法好像并不适用于ARM,特别好像不适用于ZLG平台。我正在研究,希望大家给点意见。
答 4:
请教楼主楼主有没有测试uart0,1的驱动?不是hal的串行驱动,是dev和io层的,
我测试下来uart0是ok的,uart1用中断方式驱动死活不行。后来查出是lpc
的bug在搞鬼,要改就要改dev中的16x5x通用驱动。没办法,只好uart0用上层
驱动,uart1用hal驱动,反正用起来也一样,等lpc修正了bug再说。
不知楼主是怎么解决这个问题的,希望可以多多交流:) 答 5: 我的信箱是slump@263.net 答 6: 还是不行看来不是硬件问题。
sgwu大哥能把变体抽象层(如果改动的话)和平台抽象层代码给我看看吗? 答 7: 用 NE2000 的驱动,稍微修改读写就可以了。晚上放44B0上移植参考。 答 8: 郁闷郁闷还是改驱动吧,和16x5x包脱离关系。
怎么这个问题就我碰到? 答 9: 问题找到了首先可以肯定,ecos源码(www.ecoscentric.com下载的最新snapshot)中的lpc2xxx串口驱动程序是绝对有问题的。该驱动基于16550标准驱动,lpc的uart寄存器位置也符合16550工业规范,不同在于THRE中断的产生。在不满足初始条件时THRE中断不置位,而所有数据发送都在中断处理例程中进行,造成根本不能发送数据。所以该驱动在联合hal串口驱动使用时比较正常,单独使用就不行。结果表现为至多有一个串口能正常工作。
这个问题以前在编写ucos的中断方式串口驱动就发现了,解决办法是在每次发送开始时,从队列取出第一个字节发送到UxTHR,其他数据在中断例程中传送。而现在要用这个方法解决问题势必要改动io层的串口驱动,这是不大规范的做法。
所以,希望在lpc上使用ecos的朋友能一起讨论讨论:) 答 10: 谢谢slump很好。我手上没有合适的串口线,雌雄不对。所以一直不知道又UART1的问题。谢谢! 答 11: 写了一个串口驱动,解决了问题半天赶工的,程序本身还很粗糙。但是能用(包括查询方式和中断方式)
#include <pkgconf/hal.h>
#include <pkgconf/infra.h>
#include <pkgconf/system.h>
#include <pkgconf/io_serial.h>
#include <pkgconf/io.h>
#include <pkgconf/kernel.h>
#include <cyg/io/io.h>
#include <cyg/hal/hal_io.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/io/devtab.h>
#include <cyg/io/serial.h>
#include <cyg/infra/diag.h>
#include <cyg/infra/cyg_type.h>
#ifdef CYGPKG_IO_SERIAL_ARM_LPC2XXX
const unsigned int select_baud[] = {
9999,
50,
75,
110,
134.5,
150,
200,
300,
600,
1200,
1800,
2400,
3600,
4800,
7200,
9600,
14400,
19200,
38400,
57600,
115200,
230400
};
typedef struct lpc2xxx_serial_info {
int int_num;
cyg_interrupt serial_interrupt;
cyg_handle_t serial_interrupt_handle;
} lpc2xxx_serial_info;
static bool lpc2xxx_serial_init(struct cyg_devtab_entry *tab);
static Cyg_ErrNo lpc2xxx_serial_lookup(struct cyg_devtab_entry **tab,
struct cyg_devtab_entry *sub_tab,
const char *name);
static Cyg_ErrNo lpc2xxx_serial_set_config(serial_channel *chan, cyg_uint32 key,
const void *xbuf, cyg_uint32 *len);
static void lpc2xxx_serial_start_xmit(serial_channel *chan);
static void lpc2xxx_serial_stop_xmit(serial_channel *chan);
static cyg_uint32 lpc2xxx_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
static void lpc2xxx_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
static bool lpc2xxx_serial_putc_interrupt(serial_channel *chan, unsigned char c);
static unsigned char lpc2xxx_serial_getc_interrupt(serial_channel *chan);
static bool lpc2xxx_serial_putc_polled(serial_channel *chan, unsigned char c);
static unsigned char lpc2xxx_serial_getc_polled(serial_channel *chan);
#if (CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE > 0)
static SERIAL_FUNS(lpc2xxx_serial_funs_interrupt,
lpc2xxx_serial_putc_interrupt,
lpc2xxx_serial_getc_interrupt,
lpc2xxx_serial_set_config,
lpc2xxx_serial_start_xmit,
lpc2xxx_serial_stop_xmit
);
#endif
#if (CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE == 0)
static SERIAL_FUNS(lpc2xxx_serial_funs_polled,
lpc2xxx_serial_putc_polled,
lpc2xxx_serial_getc_polled,
lpc2xxx_serial_set_config,
lpc2xxx_serial_start_xmit,
lpc2xxx_serial_stop_xmit
);
#endif
static lpc2xxx_serial_info lpc2xxx_serial_info0 = {
int_num : CYGNUM_HAL_INTERRUPT_UART1
};
#if CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE > 0
static unsigned char lpc2xxx_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE];
static unsigned char lpc2xxx_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE];
static SERIAL_CHANNEL_USING_INTERRUPTS(lpc2xxx_serial_channel0,
lpc2xxx_serial_funs_interrupt,
lpc2xxx_serial_info0,
CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BAUD),
CYG_SERIAL_STOP_DEFAULT,
CYG_SERIAL_PARITY_DEFAULT,
CYG_SERIAL_WORD_LENGTH_DEFAULT,
CYG_SERIAL_FLAGS_DEFAULT,
&lpc2xxx_serial_out_buf0[0], sizeof(lpc2xxx_serial_out_buf0),
&lpc2xxx_serial_in_buf0[0], sizeof(lpc2xxx_serial_in_buf0)
);
#else
static SERIAL_CHANNEL(lpc2xxx_serial_channel0,
lpc2xxx_serial_funs_polled,
lpc2xxx_serial_info0,
CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BAUD),
CYG_SERIAL_STOP_DEFAULT,
CYG_SERIAL_PARITY_DEFAULT,
CYG_SERIAL_WORD_LENGTH_DEFAULT,
CYG_SERIAL_FLAGS_DEFAULT
);
#endif
DEVTAB_ENTRY(lpc2xxx_serial_io0,
CYGDAT_IO_SERIAL_ARM_LPC2XXX_SERIAL0_NAME,
0,
&cyg_io_serial_devio,
lpc2xxx_serial_init,
lpc2xxx_serial_lookup,
&lpc2xxx_serial_channel0
);
static bool
lpc2xxx_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config)
{
unsigned int baud_rate = select_baud[new_config->baud];
unsigned short baud_divisor = CYG_HAL_ARM_LPC2XXX_BAUD_GENERATOR(baud_rate);
HAL_WRITE_UINT8(LPC2XXX_U1IER, 0x00);
HAL_WRITE_UINT8(LPC2XXX_U1LCR, 0x83);
HAL_WRITE_UINT8(LPC2XXX_U1DLM, baud_divisor >> 8);
HAL_WRITE_UINT8(LPC2XXX_U1DLL, baud_divisor & 0xFF);
HAL_WRITE_UINT8(LPC2XXX_U1LCR, 0x03);
HAL_WRITE_UINT8(LPC2XXX_U1FCR, 0x07);
HAL_WRITE_UINT8(LPC2XXX_U1IER, 0x01);
if (new_config != &chan->config) {
chan->config = *new_config;
}
return true;
}
static bool
lpc2xxx_serial_init(struct cyg_devtab_entry *tab)
{
serial_channel * const chan = (serial_channel *) tab->priv;
lpc2xxx_serial_info * const lpc2xxx_chan = (lpc2xxx_serial_info *) chan->dev_priv;
(chan->callbacks->serial_init)(chan);
if (chan->out_cbuf.len != 0) {
cyg_drv_interrupt_create(lpc2xxx_chan->int_num,
4,
(cyg_addrword_t)chan,
lpc2xxx_serial_ISR,
lpc2xxx_serial_DSR,
&lpc2xxx_chan->serial_interrupt_handle,
&lpc2xxx_chan->serial_interrupt);
cyg_drv_interrupt_attach(lpc2xxx_chan->serial_interrupt_handle);
cyg_drv_interrupt_unmask(lpc2xxx_chan->int_num);
}
lpc2xxx_serial_config_port(chan, &chan->config);
return true;
}
static Cyg_ErrNo
lpc2xxx_serial_lookup(struct cyg_devtab_entry **tab,
struct cyg_devtab_entry *sub_tab,
const char *name)
{
serial_channel * const chan = (serial_channel *) (*tab)->priv;
(chan->callbacks->serial_init)(chan);
return ENOERR;
}
static bool
lpc2xxx_serial_putc_interrupt(serial_channel *chan, unsigned char c)
{
cyg_uint8 uart_lsr;
HAL_READ_UINT8(LPC2XXX_U1LSR, uart_lsr);
if (uart_lsr & 0x20) {
HAL_WRITE_UINT8(LPC2XXX_U1THR, c);
return true;
}
return false;
}
static bool
lpc2xxx_serial_putc_polled(serial_channel *chan, unsigned char c)
{
cyg_uint8 uart_lsr;
HAL_WRITE_UINT8(LPC2XXX_U1THR, c);
while (1) {
HAL_READ_UINT8(LPC2XXX_U1LSR, uart_lsr);
if (uart_lsr & 0x40) break;
}
return true;
}
static unsigned char
lpc2xxx_serial_getc_interrupt(serial_channel *chan)
{
cyg_uint8 c;
HAL_READ_UINT8(LPC2XXX_U1RBR, c);
return (unsigned char) c;
}
static unsigned char
lpc2xxx_serial_getc_polled(serial_channel *chan)
{
cyg_uint8 c;
cyg_uint8 uart_lsr;
while (1) {
HAL_READ_UINT8(LPC2XXX_U1LSR, uart_lsr);
if (uart_lsr & 0x01) break;
}
HAL_READ_UINT8(LPC2XXX_U1RBR, c);
return (unsigned char) c;
}
static Cyg_ErrNo
lpc2xxx_serial_set_config(serial_channel *chan, cyg_uint32 key,
const void *xbuf, cyg_uint32 *len)
{
switch (key) {
case CYG_IO_SET_CONFIG_SERIAL_INFO:
{
cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
if ( *len < sizeof(cyg_serial_info_t) ) {
return -EINVAL;
}
*len = sizeof(cyg_serial_info_t);
if ( true != lpc2xxx_serial_config_port(chan, config) )
return -EINVAL;
}
break;
default:
return -EINVAL;
}
return ENOERR;
}
static void
lpc2xxx_serial_start_xmit(serial_channel *chan)
{
cbuf_t *cbuf = &chan->out_cbuf;
serial_funs *funs = chan->funs;
cyg_uint8 uart_lsr;
cyg_uint8 uart_ier;
cyg_uint8 c;
c = cbuf->data[cbuf->get];
HAL_WRITE_UINT8(LPC2XXX_U1THR, c);
while (1) {
HAL_READ_UINT8(LPC2XXX_U1LSR, uart_lsr);
if (uart_lsr & 0x20) break;
}
cbuf->get++;
if (cbuf->get == cbuf->len) cbuf->get = 0;
cbuf->nb--;
HAL_READ_UINT8(LPC2XXX_U1IER, uart_ier);
uart_ier |= 0x02;
HAL_WRITE_UINT8(LPC2XXX_U1IER, uart_ier);
}
static void
lpc2xxx_serial_stop_xmit(serial_channel *chan)
{
cyg_uint8 uart_ier;
HAL_READ_UINT8(LPC2XXX_U1IER, uart_ier);
uart_ier &= ~0x02;
HAL_WRITE_UINT8(LPC2XXX_U1IER, uart_ier);
}
static cyg_uint32
lpc2xxx_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
{
serial_channel *chan = (serial_channel *)data;
lpc2xxx_serial_info *lpc2xxx_chan = (lpc2xxx_serial_info *)chan->dev_priv;
cyg_drv_interrupt_mask(lpc2xxx_chan->int_num);
cyg_drv_interrupt_acknowledge(lpc2xxx_chan->int_num);
return CYG_ISR_CALL_DSR;
}
static void
lpc2xxx_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
serial_channel *chan = (serial_channel *)data;
lpc2xxx_serial_info *lpc2xxx_chan = (lpc2xxx_serial_info *)chan->dev_priv;
cyg_uint8 uart_iir;
HAL_READ_UINT8(LPC2XXX_U1IIR, uart_iir);
while ((uart_iir & 01) == 0) {
switch (uart_iir & 0x0E) {
case 0x04:
case 0x0C:
{
cyg_uint8 uart_lsr;
unsigned char c;
HAL_READ_UINT8(LPC2XXX_U1LSR, uart_lsr);
while(uart_lsr & 0x01) {
HAL_READ_UINT8(LPC2XXX_U1RBR, c);
(chan->callbacks->rcv_char)(chan, c);
HAL_READ_UINT8(LPC2XXX_U1LSR, uart_lsr);
}
break;
}
case 0x02:
(chan->callbacks->xmt_char)(chan);
break;
}
HAL_READ_UINT8(LPC2XXX_U1IIR, uart_iir);
}
cyg_drv_interrupt_unmask(lpc2xxx_chan->int_num);
}
#endif
答 12: 在2106 2132 2214上测试通过中断方式开始发送时使用了查询,浪费了一点cpu
继续完善ing:) 答 13: 驱动补完有兴趣的可以mail联系。
不过好象感兴趣的不多:) 答 14: 能参考一下吗我想用TCP做个数据传输,看周立功自带的相应太慢,能参考一下你移植的吗?
我的邮箱
calvinwx@163.com
我测试下来uart0是ok的,uart1用中断方式驱动死活不行。后来查出是lpc
的bug在搞鬼,要改就要改dev中的16x5x通用驱动。没办法,只好uart0用上层
驱动,uart1用hal驱动,反正用起来也一样,等lpc修正了bug再说。
不知楼主是怎么解决这个问题的,希望可以多多交流:) 答 5: 我的信箱是slump@263.net 答 6: 还是不行看来不是硬件问题。
sgwu大哥能把变体抽象层(如果改动的话)和平台抽象层代码给我看看吗? 答 7: 用 NE2000 的驱动,稍微修改读写就可以了。晚上放44B0上移植参考。 答 8: 郁闷郁闷还是改驱动吧,和16x5x包脱离关系。
怎么这个问题就我碰到? 答 9: 问题找到了首先可以肯定,ecos源码(www.ecoscentric.com下载的最新snapshot)中的lpc2xxx串口驱动程序是绝对有问题的。该驱动基于16550标准驱动,lpc的uart寄存器位置也符合16550工业规范,不同在于THRE中断的产生。在不满足初始条件时THRE中断不置位,而所有数据发送都在中断处理例程中进行,造成根本不能发送数据。所以该驱动在联合hal串口驱动使用时比较正常,单独使用就不行。结果表现为至多有一个串口能正常工作。
这个问题以前在编写ucos的中断方式串口驱动就发现了,解决办法是在每次发送开始时,从队列取出第一个字节发送到UxTHR,其他数据在中断例程中传送。而现在要用这个方法解决问题势必要改动io层的串口驱动,这是不大规范的做法。
所以,希望在lpc上使用ecos的朋友能一起讨论讨论:) 答 10: 谢谢slump很好。我手上没有合适的串口线,雌雄不对。所以一直不知道又UART1的问题。谢谢! 答 11: 写了一个串口驱动,解决了问题半天赶工的,程序本身还很粗糙。但是能用(包括查询方式和中断方式)
#include <pkgconf/hal.h>
#include <pkgconf/infra.h>
#include <pkgconf/system.h>
#include <pkgconf/io_serial.h>
#include <pkgconf/io.h>
#include <pkgconf/kernel.h>
#include <cyg/io/io.h>
#include <cyg/hal/hal_io.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/io/devtab.h>
#include <cyg/io/serial.h>
#include <cyg/infra/diag.h>
#include <cyg/infra/cyg_type.h>
#ifdef CYGPKG_IO_SERIAL_ARM_LPC2XXX
const unsigned int select_baud[] = {
9999,
50,
75,
110,
134.5,
150,
200,
300,
600,
1200,
1800,
2400,
3600,
4800,
7200,
9600,
14400,
19200,
38400,
57600,
115200,
230400
};
typedef struct lpc2xxx_serial_info {
int int_num;
cyg_interrupt serial_interrupt;
cyg_handle_t serial_interrupt_handle;
} lpc2xxx_serial_info;
static bool lpc2xxx_serial_init(struct cyg_devtab_entry *tab);
static Cyg_ErrNo lpc2xxx_serial_lookup(struct cyg_devtab_entry **tab,
struct cyg_devtab_entry *sub_tab,
const char *name);
static Cyg_ErrNo lpc2xxx_serial_set_config(serial_channel *chan, cyg_uint32 key,
const void *xbuf, cyg_uint32 *len);
static void lpc2xxx_serial_start_xmit(serial_channel *chan);
static void lpc2xxx_serial_stop_xmit(serial_channel *chan);
static cyg_uint32 lpc2xxx_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
static void lpc2xxx_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
static bool lpc2xxx_serial_putc_interrupt(serial_channel *chan, unsigned char c);
static unsigned char lpc2xxx_serial_getc_interrupt(serial_channel *chan);
static bool lpc2xxx_serial_putc_polled(serial_channel *chan, unsigned char c);
static unsigned char lpc2xxx_serial_getc_polled(serial_channel *chan);
#if (CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE > 0)
static SERIAL_FUNS(lpc2xxx_serial_funs_interrupt,
lpc2xxx_serial_putc_interrupt,
lpc2xxx_serial_getc_interrupt,
lpc2xxx_serial_set_config,
lpc2xxx_serial_start_xmit,
lpc2xxx_serial_stop_xmit
);
#endif
#if (CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE == 0)
static SERIAL_FUNS(lpc2xxx_serial_funs_polled,
lpc2xxx_serial_putc_polled,
lpc2xxx_serial_getc_polled,
lpc2xxx_serial_set_config,
lpc2xxx_serial_start_xmit,
lpc2xxx_serial_stop_xmit
);
#endif
static lpc2xxx_serial_info lpc2xxx_serial_info0 = {
int_num : CYGNUM_HAL_INTERRUPT_UART1
};
#if CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE > 0
static unsigned char lpc2xxx_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE];
static unsigned char lpc2xxx_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE];
static SERIAL_CHANNEL_USING_INTERRUPTS(lpc2xxx_serial_channel0,
lpc2xxx_serial_funs_interrupt,
lpc2xxx_serial_info0,
CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BAUD),
CYG_SERIAL_STOP_DEFAULT,
CYG_SERIAL_PARITY_DEFAULT,
CYG_SERIAL_WORD_LENGTH_DEFAULT,
CYG_SERIAL_FLAGS_DEFAULT,
&lpc2xxx_serial_out_buf0[0], sizeof(lpc2xxx_serial_out_buf0),
&lpc2xxx_serial_in_buf0[0], sizeof(lpc2xxx_serial_in_buf0)
);
#else
static SERIAL_CHANNEL(lpc2xxx_serial_channel0,
lpc2xxx_serial_funs_polled,
lpc2xxx_serial_info0,
CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BAUD),
CYG_SERIAL_STOP_DEFAULT,
CYG_SERIAL_PARITY_DEFAULT,
CYG_SERIAL_WORD_LENGTH_DEFAULT,
CYG_SERIAL_FLAGS_DEFAULT
);
#endif
DEVTAB_ENTRY(lpc2xxx_serial_io0,
CYGDAT_IO_SERIAL_ARM_LPC2XXX_SERIAL0_NAME,
0,
&cyg_io_serial_devio,
lpc2xxx_serial_init,
lpc2xxx_serial_lookup,
&lpc2xxx_serial_channel0
);
static bool
lpc2xxx_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config)
{
unsigned int baud_rate = select_baud[new_config->baud];
unsigned short baud_divisor = CYG_HAL_ARM_LPC2XXX_BAUD_GENERATOR(baud_rate);
HAL_WRITE_UINT8(LPC2XXX_U1IER, 0x00);
HAL_WRITE_UINT8(LPC2XXX_U1LCR, 0x83);
HAL_WRITE_UINT8(LPC2XXX_U1DLM, baud_divisor >> 8);
HAL_WRITE_UINT8(LPC2XXX_U1DLL, baud_divisor & 0xFF);
HAL_WRITE_UINT8(LPC2XXX_U1LCR, 0x03);
HAL_WRITE_UINT8(LPC2XXX_U1FCR, 0x07);
HAL_WRITE_UINT8(LPC2XXX_U1IER, 0x01);
if (new_config != &chan->config) {
chan->config = *new_config;
}
return true;
}
static bool
lpc2xxx_serial_init(struct cyg_devtab_entry *tab)
{
serial_channel * const chan = (serial_channel *) tab->priv;
lpc2xxx_serial_info * const lpc2xxx_chan = (lpc2xxx_serial_info *) chan->dev_priv;
(chan->callbacks->serial_init)(chan);
if (chan->out_cbuf.len != 0) {
cyg_drv_interrupt_create(lpc2xxx_chan->int_num,
4,
(cyg_addrword_t)chan,
lpc2xxx_serial_ISR,
lpc2xxx_serial_DSR,
&lpc2xxx_chan->serial_interrupt_handle,
&lpc2xxx_chan->serial_interrupt);
cyg_drv_interrupt_attach(lpc2xxx_chan->serial_interrupt_handle);
cyg_drv_interrupt_unmask(lpc2xxx_chan->int_num);
}
lpc2xxx_serial_config_port(chan, &chan->config);
return true;
}
static Cyg_ErrNo
lpc2xxx_serial_lookup(struct cyg_devtab_entry **tab,
struct cyg_devtab_entry *sub_tab,
const char *name)
{
serial_channel * const chan = (serial_channel *) (*tab)->priv;
(chan->callbacks->serial_init)(chan);
return ENOERR;
}
static bool
lpc2xxx_serial_putc_interrupt(serial_channel *chan, unsigned char c)
{
cyg_uint8 uart_lsr;
HAL_READ_UINT8(LPC2XXX_U1LSR, uart_lsr);
if (uart_lsr & 0x20) {
HAL_WRITE_UINT8(LPC2XXX_U1THR, c);
return true;
}
return false;
}
static bool
lpc2xxx_serial_putc_polled(serial_channel *chan, unsigned char c)
{
cyg_uint8 uart_lsr;
HAL_WRITE_UINT8(LPC2XXX_U1THR, c);
while (1) {
HAL_READ_UINT8(LPC2XXX_U1LSR, uart_lsr);
if (uart_lsr & 0x40) break;
}
return true;
}
static unsigned char
lpc2xxx_serial_getc_interrupt(serial_channel *chan)
{
cyg_uint8 c;
HAL_READ_UINT8(LPC2XXX_U1RBR, c);
return (unsigned char) c;
}
static unsigned char
lpc2xxx_serial_getc_polled(serial_channel *chan)
{
cyg_uint8 c;
cyg_uint8 uart_lsr;
while (1) {
HAL_READ_UINT8(LPC2XXX_U1LSR, uart_lsr);
if (uart_lsr & 0x01) break;
}
HAL_READ_UINT8(LPC2XXX_U1RBR, c);
return (unsigned char) c;
}
static Cyg_ErrNo
lpc2xxx_serial_set_config(serial_channel *chan, cyg_uint32 key,
const void *xbuf, cyg_uint32 *len)
{
switch (key) {
case CYG_IO_SET_CONFIG_SERIAL_INFO:
{
cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
if ( *len < sizeof(cyg_serial_info_t) ) {
return -EINVAL;
}
*len = sizeof(cyg_serial_info_t);
if ( true != lpc2xxx_serial_config_port(chan, config) )
return -EINVAL;
}
break;
default:
return -EINVAL;
}
return ENOERR;
}
static void
lpc2xxx_serial_start_xmit(serial_channel *chan)
{
cbuf_t *cbuf = &chan->out_cbuf;
serial_funs *funs = chan->funs;
cyg_uint8 uart_lsr;
cyg_uint8 uart_ier;
cyg_uint8 c;
c = cbuf->data[cbuf->get];
HAL_WRITE_UINT8(LPC2XXX_U1THR, c);
while (1) {
HAL_READ_UINT8(LPC2XXX_U1LSR, uart_lsr);
if (uart_lsr & 0x20) break;
}
cbuf->get++;
if (cbuf->get == cbuf->len) cbuf->get = 0;
cbuf->nb--;
HAL_READ_UINT8(LPC2XXX_U1IER, uart_ier);
uart_ier |= 0x02;
HAL_WRITE_UINT8(LPC2XXX_U1IER, uart_ier);
}
static void
lpc2xxx_serial_stop_xmit(serial_channel *chan)
{
cyg_uint8 uart_ier;
HAL_READ_UINT8(LPC2XXX_U1IER, uart_ier);
uart_ier &= ~0x02;
HAL_WRITE_UINT8(LPC2XXX_U1IER, uart_ier);
}
static cyg_uint32
lpc2xxx_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
{
serial_channel *chan = (serial_channel *)data;
lpc2xxx_serial_info *lpc2xxx_chan = (lpc2xxx_serial_info *)chan->dev_priv;
cyg_drv_interrupt_mask(lpc2xxx_chan->int_num);
cyg_drv_interrupt_acknowledge(lpc2xxx_chan->int_num);
return CYG_ISR_CALL_DSR;
}
static void
lpc2xxx_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
serial_channel *chan = (serial_channel *)data;
lpc2xxx_serial_info *lpc2xxx_chan = (lpc2xxx_serial_info *)chan->dev_priv;
cyg_uint8 uart_iir;
HAL_READ_UINT8(LPC2XXX_U1IIR, uart_iir);
while ((uart_iir & 01) == 0) {
switch (uart_iir & 0x0E) {
case 0x04:
case 0x0C:
{
cyg_uint8 uart_lsr;
unsigned char c;
HAL_READ_UINT8(LPC2XXX_U1LSR, uart_lsr);
while(uart_lsr & 0x01) {
HAL_READ_UINT8(LPC2XXX_U1RBR, c);
(chan->callbacks->rcv_char)(chan, c);
HAL_READ_UINT8(LPC2XXX_U1LSR, uart_lsr);
}
break;
}
case 0x02:
(chan->callbacks->xmt_char)(chan);
break;
}
HAL_READ_UINT8(LPC2XXX_U1IIR, uart_iir);
}
cyg_drv_interrupt_unmask(lpc2xxx_chan->int_num);
}
#endif
答 12: 在2106 2132 2214上测试通过中断方式开始发送时使用了查询,浪费了一点cpu
继续完善ing:) 答 13: 驱动补完有兴趣的可以mail联系。
不过好象感兴趣的不多:) 答 14: 能参考一下吗我想用TCP做个数据传输,看周立功自带的相应太慢,能参考一下你移植的吗?
我的邮箱
calvinwx@163.com
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |