forked from Imagelibrary/rtems
applied patches for PR1117/1118/1119/1120
This commit is contained in:
@@ -25,6 +25,7 @@ AC_DEFUN([_RTEMS_BSP_ALIAS],
|
|||||||
pc586) $2=pc386 ;; # i386 - PC with Pentium
|
pc586) $2=pc386 ;; # i386 - PC with Pentium
|
||||||
pc686) $2=pc386 ;; # i386 - PC with PentiumPro
|
pc686) $2=pc386 ;; # i386 - PC with PentiumPro
|
||||||
pck6) $2=pc386 ;; # i386 - PC with K6
|
pck6) $2=pc386 ;; # i386 - PC with K6
|
||||||
|
brs5l*) $2=gen5200 ;; # MPC5200 based board
|
||||||
pm520*) $2=gen5200 ;; # MPC5200 based board
|
pm520*) $2=gen5200 ;; # MPC5200 based board
|
||||||
simcpu32) $2=sim68000 ;; # BSVC CPU32 variant
|
simcpu32) $2=sim68000 ;; # BSVC CPU32 variant
|
||||||
simsh7032) $2=shsim ;; # SH7032 simulator
|
simsh7032) $2=shsim ;; # SH7032 simulator
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ AC_MSG_CHECKING([for available BSPs])
|
|||||||
bsps="$bsps mbx860_002"
|
bsps="$bsps mbx860_002"
|
||||||
bsps="$bsps mbx860_005b"
|
bsps="$bsps mbx860_005b"
|
||||||
;;
|
;;
|
||||||
gen5200) bsps="pm520_cr825 pm520_ze30";;
|
gen5200) bsps="pm520_cr825 pm520_ze30 brs5l";;
|
||||||
motorola_powerpc) bsps="mvme2307 mcp750 mtx603e mvme2100";;
|
motorola_powerpc) bsps="mvme2307 mcp750 mtx603e mvme2100";;
|
||||||
pc386) bsps="pc386 pc386dx pc486 pc586 pc686 pck6";;
|
pc386) bsps="pc386 pc386dx pc486 pc586 pc686 pck6";;
|
||||||
erc32) bsps="erc32 erc32nfp sis";;
|
erc32) bsps="erc32 erc32nfp sis";;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ start.$(OBJEXT): start/start.S
|
|||||||
$(CPPASCOMPILE) -DASM -o $@ -c $<
|
$(CPPASCOMPILE) -DASM -o $@ -c $<
|
||||||
project_lib_DATA = start.$(OBJEXT)
|
project_lib_DATA = start.$(OBJEXT)
|
||||||
|
|
||||||
dist_project_lib_DATA += startup/linkcmds startup/linkcmds.pm520
|
dist_project_lib_DATA += startup/linkcmds.brs5l startup/linkcmds.pm520
|
||||||
|
|
||||||
noinst_PROGRAMS += bestcomm.rel
|
noinst_PROGRAMS += bestcomm.rel
|
||||||
bestcomm_rel_SOURCES = bestcomm/include/ppctypes.h \
|
bestcomm_rel_SOURCES = bestcomm/include/ppctypes.h \
|
||||||
@@ -90,11 +90,13 @@ noinst_PROGRAMS += nvram.rel
|
|||||||
nvram_rel_SOURCES = nvram/nvram.c nvram/nvram.h nvram/m93cxx.h
|
nvram_rel_SOURCES = nvram/nvram.c nvram/nvram.h nvram/m93cxx.h
|
||||||
nvram_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
nvram_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
nvram_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
nvram_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
include_bsp_HEADERS += nvram/nvram.h
|
||||||
|
|
||||||
noinst_PROGRAMS += slicetimer.rel
|
noinst_PROGRAMS += slicetimer.rel
|
||||||
slicetimer_rel_SOURCES = slicetimer/slicetimer.c slicetimer/slicetimer.h
|
slicetimer_rel_SOURCES = slicetimer/slicetimer.c slicetimer/slicetimer.h
|
||||||
slicetimer_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
slicetimer_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
slicetimer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
slicetimer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
include_bsp_HEADERS += slicetimer/slicetimer.h
|
||||||
|
|
||||||
noinst_PROGRAMS += tod.rel
|
noinst_PROGRAMS += tod.rel
|
||||||
tod_rel_SOURCES = tod/todcfg.c tod/pcf8563.c tod/pcf8563.h \
|
tod_rel_SOURCES = tod/todcfg.c tod/pcf8563.c tod/pcf8563.h \
|
||||||
@@ -108,7 +110,7 @@ noinst_PROGRAMS += startup.rel
|
|||||||
startup_rel_SOURCES = ../../shared/bspclean.c ../../shared/bsplibc.c \
|
startup_rel_SOURCES = ../../shared/bspclean.c ../../shared/bsplibc.c \
|
||||||
../../shared/bsppost.c startup/bspstart.c ../../shared/bootcard.c \
|
../../shared/bsppost.c startup/bspstart.c ../../shared/bootcard.c \
|
||||||
../../shared/main.c ../../shared/sbrk.c \
|
../../shared/main.c ../../shared/sbrk.c \
|
||||||
../../shared/gnatinstallhandler.c startup/cpuinit.c
|
../../shared/gnatinstallhandler.c startup/cpuinit.c start/start.S
|
||||||
startup_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
startup_rel_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
|
||||||
|
|
||||||
|
|||||||
@@ -46,12 +46,15 @@ void bestcomm_glue_irq_enable
|
|||||||
| none |
|
| none |
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
{
|
{
|
||||||
|
rtems_interrupt_level level;
|
||||||
if (0 != ((1UL<<bestcomm_taskno) & SDMA_INT_BIT_IMPL)) {
|
if (0 != ((1UL<<bestcomm_taskno) & SDMA_INT_BIT_IMPL)) {
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
/*
|
/*
|
||||||
* valid task number
|
* valid task number
|
||||||
* enable interrupt in bestcomm mask
|
* enable interrupt in bestcomm mask
|
||||||
*/
|
*/
|
||||||
SDMA_INT_ENABLE(&mpc5200.IntMask,bestcomm_taskno);
|
SDMA_INT_ENABLE(&mpc5200.IntMask,bestcomm_taskno);
|
||||||
|
rtems_interrupt_enable(level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,12 +76,15 @@ void bestcomm_glue_irq_disable
|
|||||||
| none |
|
| none |
|
||||||
\*=========================================================================*/
|
\*=========================================================================*/
|
||||||
{
|
{
|
||||||
|
rtems_interrupt_level level;
|
||||||
if (0 != ((1UL<<bestcomm_taskno) & SDMA_INT_BIT_IMPL)) {
|
if (0 != ((1UL<<bestcomm_taskno) & SDMA_INT_BIT_IMPL)) {
|
||||||
|
rtems_interrupt_disable(level);
|
||||||
/*
|
/*
|
||||||
* valid task number
|
* valid task number
|
||||||
* disable interrupt in bestcomm mask
|
* disable interrupt in bestcomm mask
|
||||||
*/
|
*/
|
||||||
SDMA_INT_DISABLE(&mpc5200.IntMask,bestcomm_taskno);
|
SDMA_INT_DISABLE(&mpc5200.IntMask,bestcomm_taskno);
|
||||||
|
rtems_interrupt_enable(level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,7 +251,7 @@ void bestcomm_glue_init
|
|||||||
TasksLoadImage( (void *)&(mpc5200.taskBar));
|
TasksLoadImage( (void *)&(mpc5200.taskBar));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: initialize interrupt dispatcher
|
* initialize interrupt dispatcher
|
||||||
*/
|
*/
|
||||||
if(!BSP_install_rtems_irq_handler (&bestcomm_glue_irq_data)) {
|
if(!BSP_install_rtems_irq_handler (&bestcomm_glue_irq_data)) {
|
||||||
rtems_panic ("Can't attach MPC5x00 BestComm interrupt handler\n");
|
rtems_panic ("Can't attach MPC5x00 BestComm interrupt handler\n");
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
%{!qnolinkcmds: -T linkcmds%s}}}
|
%{!qnolinkcmds: -T linkcmds%s}}}
|
||||||
|
|
||||||
*startfile:
|
*startfile:
|
||||||
%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems: ecrti%O%s \
|
%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems: \
|
||||||
%{!qrtems_debug: start.o%s} \
|
%{!qrtems_debug: } \
|
||||||
%{qrtems_debug: start_g.o%s}}}
|
%{qrtems_debug: } ecrti%O%s}}
|
||||||
|
|
||||||
*endfile:
|
*endfile:
|
||||||
%{!qrtems: %(old_endfile)} %{qrtems: ecrtn%O%s}
|
%{!qrtems: %(old_endfile)} %{qrtems: ecrtn%O%s}
|
||||||
|
|||||||
@@ -212,8 +212,9 @@ int mpc5200_psc_setAttributes(int minor, const struct termios *t)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate baud rate
|
* Calculate baud rate
|
||||||
|
* round divider to nearest!
|
||||||
*/
|
*/
|
||||||
baud = IPB_CLOCK / (baud * 32);
|
baud = (IPB_CLOCK + baud *16) / (baud * 32);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,9 +342,10 @@ static void mpc5200_psc_interrupt_handler(rtems_irq_hdl_param handle)
|
|||||||
*/
|
*/
|
||||||
c = (psc->rb_tb >> 24);
|
c = (psc->rb_tb >> 24);
|
||||||
|
|
||||||
|
if (ttyp[minor] != NULL) {
|
||||||
nb_overflow = rtems_termios_enqueue_raw_characters((void *)ttyp[minor], (char *)&c, (int)1);
|
nb_overflow = rtems_termios_enqueue_raw_characters((void *)ttyp[minor], (char *)&c, (int)1);
|
||||||
|
|
||||||
channel_info[minor].rx_characters++;
|
channel_info[minor].rx_characters++;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef SINGLE_CHAR_MODE
|
#ifndef SINGLE_CHAR_MODE
|
||||||
}
|
}
|
||||||
@@ -364,6 +366,7 @@ static void mpc5200_psc_interrupt_handler(rtems_irq_hdl_param handle)
|
|||||||
*/
|
*/
|
||||||
psc->isr_imr = channel_info[minor].shadow_imr &= ~(IMR_TX_RDY);
|
psc->isr_imr = channel_info[minor].shadow_imr &= ~(IMR_TX_RDY);
|
||||||
|
|
||||||
|
if (ttyp[minor] != NULL) {
|
||||||
#ifndef SINGLE_CHAR_MODE
|
#ifndef SINGLE_CHAR_MODE
|
||||||
rtems_termios_dequeue_characters((void *)ttyp[minor], channel_info[minor].cur_tx_len);
|
rtems_termios_dequeue_characters((void *)ttyp[minor], channel_info[minor].cur_tx_len);
|
||||||
|
|
||||||
@@ -373,7 +376,7 @@ static void mpc5200_psc_interrupt_handler(rtems_irq_hdl_param handle)
|
|||||||
|
|
||||||
channel_info[minor].tx_characters++;
|
channel_info[minor].tx_characters++;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isr & ISR_ERROR)
|
if(isr & ISR_ERROR)
|
||||||
@@ -684,6 +687,8 @@ rtems_device_driver console_initialize(rtems_device_major_number major, rtems_de
|
|||||||
rtems_status_code status;
|
rtems_status_code status;
|
||||||
rtems_device_minor_number console_minor;
|
rtems_device_minor_number console_minor;
|
||||||
char dev_name[] = "/dev/ttyx";
|
char dev_name[] = "/dev/ttyx";
|
||||||
|
uint32_t tty_num = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Always use and set up TERMIOS
|
* Always use and set up TERMIOS
|
||||||
*/
|
*/
|
||||||
@@ -701,13 +706,18 @@ rtems_device_driver console_initialize(rtems_device_major_number major, rtems_de
|
|||||||
* Do device-specific initialization and registration for Motorola IceCube
|
* Do device-specific initialization and registration for Motorola IceCube
|
||||||
*/
|
*/
|
||||||
mpc5200_uart_psc_initialize(console_minor); /* /dev/tty0 */
|
mpc5200_uart_psc_initialize(console_minor); /* /dev/tty0 */
|
||||||
dev_name[8] = '0' + console_minor - PSC1_MINOR;
|
dev_name[8] = '0' + tty_num;
|
||||||
status = rtems_io_register_name (dev_name, major, console_minor);
|
status = rtems_io_register_name (dev_name, major, console_minor);
|
||||||
|
|
||||||
if(status != RTEMS_SUCCESSFUL)
|
if(status != RTEMS_SUCCESSFUL)
|
||||||
|
{
|
||||||
rtems_fatal_error_occurred(status);
|
rtems_fatal_error_occurred(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tty_num++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Now register the RTEMS console */
|
/* Now register the RTEMS console */
|
||||||
status = rtems_io_register_name ("/dev/console", major, PSC1_MINOR);
|
status = rtems_io_register_name ("/dev/console", major, PSC1_MINOR);
|
||||||
|
|
||||||
@@ -780,8 +790,9 @@ rtems_device_driver console_close(rtems_device_major_number major, rtems_device_
|
|||||||
if ( minor > NUM_PORTS-1 )
|
if ( minor > NUM_PORTS-1 )
|
||||||
return RTEMS_INVALID_NUMBER;
|
return RTEMS_INVALID_NUMBER;
|
||||||
|
|
||||||
return rtems_termios_close( arg );
|
ttyp[minor] = NULL; /* mark for int handler: tty no longer open */
|
||||||
|
|
||||||
|
return rtems_termios_close( arg );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,13 +61,15 @@
|
|||||||
*/
|
*/
|
||||||
/* ROM definitions (2 MB) */
|
/* ROM definitions (2 MB) */
|
||||||
#define ROM_START 0xFFE00000
|
#define ROM_START 0xFFE00000
|
||||||
#define ROM_END 0xFFFFFFFF
|
#define ROM_SIZE 0x00200000
|
||||||
|
#define ROM_END (ROM_START+ROM_SIZE-1)
|
||||||
#define BOOT_START ROM_START
|
#define BOOT_START ROM_START
|
||||||
#define BOOT_END ROM_END
|
#define BOOT_END ROM_END
|
||||||
|
|
||||||
/* SDRAM definitions (256 MB) */
|
/* SDRAM definitions (256 MB) */
|
||||||
#define RAM_START 0x00000000
|
#define RAM_START 0x00000000
|
||||||
#define RAM_END 0x0FFFFFFF
|
#define RAM_SIZE 0x10000000
|
||||||
|
#define RAM_END (RAM_START+RAM_SIZE-1)
|
||||||
|
|
||||||
/* DPRAM definitions (64 KB) */
|
/* DPRAM definitions (64 KB) */
|
||||||
#define DPRAM_START 0xFF000000
|
#define DPRAM_START 0xFF000000
|
||||||
@@ -198,7 +200,8 @@ void bsp_cleanup(void);
|
|||||||
#define UARTS_USE_TERMIOS_INT 1
|
#define UARTS_USE_TERMIOS_INT 1
|
||||||
|
|
||||||
/* ata modes */
|
/* ata modes */
|
||||||
#undef ATA_USE_INT
|
/* #undef ATA_USE_INT */
|
||||||
|
#define ATA_USE_INT
|
||||||
|
|
||||||
/* clock settings */
|
/* clock settings */
|
||||||
#if defined(HAS_UBOOT)
|
#if defined(HAS_UBOOT)
|
||||||
@@ -211,6 +214,21 @@ void bsp_cleanup(void);
|
|||||||
#define G2_CLOCK 231000000 /* 231 MHz */
|
#define G2_CLOCK 231000000 /* 231 MHz */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert decrement value to tenths of microsecnds (used by
|
||||||
|
* shared timer driver).
|
||||||
|
*
|
||||||
|
* + CPU has a XLB_CLOCK bus,
|
||||||
|
* + There are 4 bus cycles per click
|
||||||
|
* + We return value in 1/10 microsecond units.
|
||||||
|
* Modified following equation to integer equation to remove
|
||||||
|
* floating point math.
|
||||||
|
* (int) ((float)(_value) / ((XLB_CLOCK/1000000 * 0.1) / 4.0))
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BSP_Convert_decrementer( _value ) \
|
||||||
|
(int) (((_value) * 4000) / (XLB_CLOCK/10000))
|
||||||
|
|
||||||
/* slicetimer settings */
|
/* slicetimer settings */
|
||||||
#define USE_SLICETIMER_0 TRUE
|
#define USE_SLICETIMER_0 TRUE
|
||||||
#define USE_SLICETIMER_1 FALSE
|
#define USE_SLICETIMER_1 FALSE
|
||||||
|
|||||||
@@ -300,12 +300,15 @@ typedef struct mpc5200_
|
|||||||
#define GPT_STATUS_RESET 0x0000000F
|
#define GPT_STATUS_RESET 0x0000000F
|
||||||
#define GPT_STATUS_TEXP (1 << 3)
|
#define GPT_STATUS_TEXP (1 << 3)
|
||||||
#define GPT_STATUS_PIN (1 << 8)
|
#define GPT_STATUS_PIN (1 << 8)
|
||||||
|
#define GPT_EMSEL_GPIO_DIR (2 << 4)
|
||||||
|
#define GPT_EMSEL_GPIO_OUT (1 << 4)
|
||||||
#define GPT_EMSEL_GPIO_OUT_HIGH (3 << 4)
|
#define GPT_EMSEL_GPIO_OUT_HIGH (3 << 4)
|
||||||
#define GPT_EMSEL_TIMER_MS_GPIO (4 << 0)
|
#define GPT_EMSEL_TIMER_MS_GPIO (4 << 0)
|
||||||
#define GPT_EMSEL_GPIO_IN (0 << 0)
|
#define GPT_EMSEL_GPIO_IN (0 << 0)
|
||||||
#define GPT_EMSEL_CE (1 << 12)
|
#define GPT_EMSEL_CE (1 << 12)
|
||||||
#define GPT_EMSEL_ST_CONT (1 << 10)
|
#define GPT_EMSEL_ST_CONT (1 << 10)
|
||||||
#define GPT_EMSEL_INTEN (1 << 8)
|
#define GPT_EMSEL_INTEN (1 << 8)
|
||||||
|
#define GPT_EMSEL_WDEN (1 << 15)
|
||||||
|
|
||||||
#define GPT0 0
|
#define GPT0 0
|
||||||
#define GPT1 1
|
#define GPT1 1
|
||||||
|
|||||||
@@ -15,28 +15,49 @@
|
|||||||
#ifndef __tm27_h
|
#ifndef __tm27_h
|
||||||
#define __tm27_h
|
#define __tm27_h
|
||||||
|
|
||||||
|
#include <bsp/irq.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stuff for Time Test 27
|
* Stuff for Time Test 27
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MUST_WAIT_FOR_INTERRUPT 0
|
#define MUST_WAIT_FOR_INTERRUPT 1
|
||||||
|
|
||||||
#define Install_tm27_vector( handler ) \
|
void nullFunc() {}
|
||||||
|
|
||||||
|
static rtems_irq_connect_data clockIrqData = {BSP_DECREMENTER,
|
||||||
|
0,
|
||||||
|
(rtems_irq_enable)nullFunc,
|
||||||
|
(rtems_irq_disable)nullFunc,
|
||||||
|
(rtems_irq_is_enabled) nullFunc};
|
||||||
|
void Install_tm27_vector(void (*_handler)())
|
||||||
|
{
|
||||||
|
clockIrqData.hdl = _handler;
|
||||||
|
if (!BSP_install_rtems_irq_handler (&clockIrqData)) {
|
||||||
|
printk("Error installing clock interrupt handler!\n");
|
||||||
|
rtems_fatal_error_occurred(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Cause_tm27_intr() \
|
||||||
do { \
|
do { \
|
||||||
static rtems_irq_connect_data scIrqData = { \
|
uint32_t _clicks = 8; \
|
||||||
PPC_IRQ_SCALL, \
|
asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
|
||||||
(rtems_irq_hdl) handler, \
|
|
||||||
NULL, \
|
|
||||||
NULL, \
|
|
||||||
NULL \
|
|
||||||
}; \
|
|
||||||
BSP_install_rtems_irq_handler (&scIrqData); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define Cause_tm27_intr() asm volatile ("sc")
|
#define Clear_tm27_intr() \
|
||||||
|
do { \
|
||||||
|
uint32_t _clicks = 0xffffffff; \
|
||||||
|
asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define Clear_tm27_intr() /* empty */
|
#define Lower_tm27_intr() \
|
||||||
|
do { \
|
||||||
#define Lower_tm27_intr() /* empty */
|
uint32_t _msr = 0; \
|
||||||
|
_ISR_Set_level( 0 ); \
|
||||||
|
asm volatile( "mfmsr %0 ;" : "=r" (_msr) : "r" (_msr) ); \
|
||||||
|
_msr |= 0x8002; \
|
||||||
|
asm volatile( "mtmsr %0 ;" : "=r" (_msr) : "r" (_msr) ); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -30,8 +30,107 @@
|
|||||||
|
|
||||||
/* #define MSCAN_LOOPBACK */
|
/* #define MSCAN_LOOPBACK */
|
||||||
|
|
||||||
|
volatile uint32_t tx_int_wr_count = 0;
|
||||||
|
|
||||||
struct mpc5200_rx_cntrl mpc5200_mscan_rx_cntrl[MPC5200_CAN_NO];
|
struct mpc5200_rx_cntrl mpc5200_mscan_rx_cntrl[MPC5200_CAN_NO];
|
||||||
static struct mscan_channel_info chan_info[MPC5200_CAN_NO];
|
volatile static struct mscan_channel_info chan_info[MPC5200_CAN_NO];
|
||||||
|
|
||||||
|
/* time segmant table */
|
||||||
|
uint8_t can_time_segment_table[CAN_MAX_NO_OF_TQ - MIN_NO_OF_TQ + 1][NO_OF_TABLE_ENTRIES] = {
|
||||||
|
|
||||||
|
/* Total no. of time quantas */ /* Time Segment 1*/ /* Time Segment 2 */ /* Sync: Jump width */
|
||||||
|
{ 7, 4, 2, 1 },
|
||||||
|
{ 8, 5, 2, 1 },
|
||||||
|
{ 9, 6, 2, 2 },
|
||||||
|
{ 10, 6, 3, 2 },
|
||||||
|
{ 11, 7, 3, 2 },
|
||||||
|
{ 12, 8, 3, 2 },
|
||||||
|
{ 13, 8, 4, 2 },
|
||||||
|
{ 14, 9, 4, 2 },
|
||||||
|
{ 15, 10, 4, 2 },
|
||||||
|
{ 16, 10, 5, 2 },
|
||||||
|
{ 17, 11, 5, 2 },
|
||||||
|
{ 18, 12, 5, 2 },
|
||||||
|
{ 19, 12, 6, 2 },
|
||||||
|
{ 20, 13, 6, 2 },
|
||||||
|
{ 21, 14, 6, 2 },
|
||||||
|
{ 22, 14, 7, 2 },
|
||||||
|
{ 23, 15, 7, 2 },
|
||||||
|
{ 24, 15, 8, 2 },
|
||||||
|
{ 25, 16, 8, 2 }};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPC5x00 MSCAN tx ring buffer function to get a can message buffer from the head of the tx ring buffer
|
||||||
|
*/
|
||||||
|
volatile static struct can_message * get_tx_buffer(struct mscan_channel_info *chan)
|
||||||
|
{
|
||||||
|
/* define a temp. mess ptr. */
|
||||||
|
volatile struct can_message * tmp_mess_ptr = NULL, *temp_head_ptr;
|
||||||
|
|
||||||
|
/* set temp. head pointer */
|
||||||
|
temp_head_ptr = chan->tx_ring_buf.head_ptr;
|
||||||
|
|
||||||
|
/* check buffer empty condition */
|
||||||
|
if(temp_head_ptr != chan->tx_ring_buf.tail_ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* current buffer head. ptr. */
|
||||||
|
tmp_mess_ptr = temp_head_ptr;
|
||||||
|
|
||||||
|
/* increment the head pointer */
|
||||||
|
temp_head_ptr++;
|
||||||
|
|
||||||
|
/* check for wrap around condition */
|
||||||
|
if(temp_head_ptr > chan->tx_ring_buf.buf_ptr + NO_OF_MSCAN_TX_BUFF)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* set head ptr. to the begin of the ring buffer */
|
||||||
|
temp_head_ptr = chan->tx_ring_buf.buf_ptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of crtical section restore head ptr. */
|
||||||
|
chan->tx_ring_buf.head_ptr = temp_head_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the current head pointer */
|
||||||
|
return tmp_mess_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPC5x00 MSCAN tx ring buffer function to write a can message buffer to the tail of the tx ring buffer
|
||||||
|
*/
|
||||||
|
volatile static struct can_message * fill_tx_buffer(struct mscan_channel_info *chan, struct can_message * mess_ptr)
|
||||||
|
{
|
||||||
|
/* define a temp. mess ptr. to the entry which follows the current tail entry */
|
||||||
|
struct can_message * tmp_mess_ptr = chan->tx_ring_buf.tail_ptr + 1;
|
||||||
|
|
||||||
|
/* check for the wrap around condition */
|
||||||
|
if(tmp_mess_ptr > chan->tx_ring_buf.buf_ptr + NO_OF_MSCAN_TX_BUFF)
|
||||||
|
{
|
||||||
|
/* set temp. mess. ptr to the begin of the ring buffer */
|
||||||
|
tmp_mess_ptr = chan->tx_ring_buf.buf_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check buffer full condition */
|
||||||
|
if(tmp_mess_ptr == chan->tx_ring_buf.head_ptr)
|
||||||
|
{
|
||||||
|
/* return NULL in case buffer is full */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* copy the can mess. to the tail of the buffer */
|
||||||
|
memcpy((void *)chan->tx_ring_buf.tail_ptr, (void *)mess_ptr, sizeof(struct can_message));
|
||||||
|
|
||||||
|
/* set new tail equal to temp. mess. ptr. */
|
||||||
|
chan->tx_ring_buf.tail_ptr = tmp_mess_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the actual tail ptr. (next free entry) */
|
||||||
|
return chan->tx_ring_buf.tail_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MPC5x00 MSCAN interrupt handler
|
* MPC5x00 MSCAN interrupt handler
|
||||||
@@ -41,24 +140,110 @@ static void mpc5200_mscan_interrupt_handler(rtems_irq_hdl_param handle)
|
|||||||
rtems_status_code status;
|
rtems_status_code status;
|
||||||
mscan_handle *mscan_hdl = (mscan_handle *)handle;
|
mscan_handle *mscan_hdl = (mscan_handle *)handle;
|
||||||
struct mscan_channel_info *chan = &chan_info[mscan_hdl->mscan_channel];
|
struct mscan_channel_info *chan = &chan_info[mscan_hdl->mscan_channel];
|
||||||
struct can_message rx_mess, *rx_mess_ptr;
|
struct can_message rx_mess, *rx_mess_ptr, *tx_mess_ptr;
|
||||||
volatile struct mpc5200_mscan *mscan = chan->regs;
|
volatile struct mpc5200_mscan *mscan = chan->regs;
|
||||||
|
register uint8_t idx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
handle tx interrupts
|
handle tx ring buffer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* check and disable tx interrupt for message buffer 0 */
|
/* loop over all 3 tx buffers */
|
||||||
if(mscan->tier & MSCAN_TX_BUFF0)
|
for(idx = TFLG_TXE0; idx <= TFLG_TXE2; idx=idx<<1)
|
||||||
mscan->tier &= ~(MSCAN_TX_BUFF0);
|
{
|
||||||
|
|
||||||
/* check and disable tx interrupt for message buffer 1 */
|
/* check for tx buffer vacation */
|
||||||
if(mscan->tier & MSCAN_TX_BUFF1)
|
if((mscan->tflg) & idx)
|
||||||
mscan->tier &= ~(MSCAN_TX_BUFF1);
|
{
|
||||||
|
|
||||||
/* check and disable tx interrupt for message buffer 2 */
|
/* try to get a message */
|
||||||
if(mscan->tier & MSCAN_TX_BUFF2)
|
tx_mess_ptr = get_tx_buffer(chan);
|
||||||
mscan->tier &= ~(MSCAN_TX_BUFF2);
|
|
||||||
|
/* check for new tx message */
|
||||||
|
if(tx_mess_ptr != NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* select the tx buffer */
|
||||||
|
mscan->bsel = idx;
|
||||||
|
|
||||||
|
/* check for toucan interface */
|
||||||
|
if((mscan_hdl->toucan_callback) == NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* set tx id */
|
||||||
|
mscan->txidr0 = SET_IDR0(tx_mess_ptr->mess_id);
|
||||||
|
mscan->txidr1 = SET_IDR1(tx_mess_ptr->mess_id);
|
||||||
|
mscan->txidr2 = 0;
|
||||||
|
mscan->txidr3 = 0;
|
||||||
|
|
||||||
|
/* insert dlc into mscan register */
|
||||||
|
mscan->txdlr = (uint8_t)((tx_mess_ptr->mess_len) & 0x000F);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* select one free tx buffer if TOUCAN not registered) */
|
||||||
|
if(((mscan_hdl->toucan_callback) == NULL) || (((mscan_hdl->toucan_callback) != NULL) && ((tx_mess_ptr->toucan_tx_id) == idx)))
|
||||||
|
{
|
||||||
|
|
||||||
|
/* set tx id */
|
||||||
|
mscan->txidr0 = SET_IDR0(tx_mess_ptr->mess_id);
|
||||||
|
mscan->txidr1 = SET_IDR1(tx_mess_ptr->mess_id);
|
||||||
|
mscan->txidr2 = 0;
|
||||||
|
mscan->txidr3 = 0;
|
||||||
|
|
||||||
|
/* insert dlc into mscan register */
|
||||||
|
mscan->txdlr = (uint8_t)((tx_mess_ptr->mess_len) & 0x000F);
|
||||||
|
|
||||||
|
/* copy tx data to MSCAN registers */
|
||||||
|
switch(mscan->txdlr)
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
mscan->txdsr7 = tx_mess_ptr->mess_data[7];
|
||||||
|
case 7:
|
||||||
|
mscan->txdsr6 = tx_mess_ptr->mess_data[6];
|
||||||
|
case 6:
|
||||||
|
mscan->txdsr5 = tx_mess_ptr->mess_data[5];
|
||||||
|
case 5:
|
||||||
|
mscan->txdsr4 = tx_mess_ptr->mess_data[4];
|
||||||
|
case 4:
|
||||||
|
mscan->txdsr3 = tx_mess_ptr->mess_data[3];
|
||||||
|
case 3:
|
||||||
|
mscan->txdsr2 = tx_mess_ptr->mess_data[2];
|
||||||
|
case 2:
|
||||||
|
mscan->txdsr1 = tx_mess_ptr->mess_data[1];
|
||||||
|
case 1:
|
||||||
|
mscan->txdsr0 = tx_mess_ptr->mess_data[0];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable message buffer specific interrupt */
|
||||||
|
mscan->tier |= mscan->bsel;
|
||||||
|
|
||||||
|
/* start transfer */
|
||||||
|
mscan->tflg = mscan->bsel;
|
||||||
|
|
||||||
|
/* release counting semaphore of tx ring buffer */
|
||||||
|
rtems_semaphore_release((rtems_id)(chan->tx_rb_sid));
|
||||||
|
|
||||||
|
tx_int_wr_count++;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
/* refill the tx ring buffer with the message */
|
||||||
|
fill_tx_buffer(chan, tx_mess_ptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* reset interrupt enable bit */
|
||||||
|
mscan->tier &= ~(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
handle rx interrupts
|
handle rx interrupts
|
||||||
@@ -84,23 +269,16 @@ static void mpc5200_mscan_interrupt_handler(rtems_irq_hdl_param handle)
|
|||||||
|
|
||||||
/* check the rx fliter-match indicators (16-bit filter mode) */
|
/* check the rx fliter-match indicators (16-bit filter mode) */
|
||||||
/* in case of more than one hit, lower hit has priority */
|
/* in case of more than one hit, lower hit has priority */
|
||||||
switch((mscan->idac) & 0x7)
|
idx = (mscan->idac) & 0x7;
|
||||||
|
switch(idx)
|
||||||
{
|
{
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
rx_mess_ptr = (struct can_message *)&(mpc5200_mscan_rx_cntrl[MSCAN_A].can_rx_message[0]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
rx_mess_ptr = (struct can_message *)&(mpc5200_mscan_rx_cntrl[MSCAN_A].can_rx_message[1]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
rx_mess_ptr = (struct can_message *)&(mpc5200_mscan_rx_cntrl[MSCAN_A].can_rx_message[2]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
rx_mess_ptr = (struct can_message *)&(mpc5200_mscan_rx_cntrl[MSCAN_A].can_rx_message[3]);
|
rx_mess_ptr =
|
||||||
|
(struct can_message *)&(mpc5200_mscan_rx_cntrl[mscan_hdl->mscan_channel].can_rx_message[idx]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* this case should never happen */
|
/* this case should never happen */
|
||||||
@@ -530,34 +708,71 @@ void mpc5200_mscan_wait_sync(volatile struct mpc5200_mscan *mscan)
|
|||||||
/* [01]:SLPRQ 0 : No Sleep Mode Request */
|
/* [01]:SLPRQ 0 : No Sleep Mode Request */
|
||||||
/* [00]:INITRQ 0 : No init. Mode Request */
|
/* [00]:INITRQ 0 : No init. Mode Request */
|
||||||
/* wait for MSCAN A_/_B bus synch. */
|
/* wait for MSCAN A_/_B bus synch. */
|
||||||
while(!((mscan->ctl0) & CTL0_SYNCH));
|
|
||||||
|
|
||||||
|
#if 0 /* we don't have a need to wait for sync. */
|
||||||
|
while(!((mscan->ctl0) & CTL0_SYNCH));
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* calculate the can clock prescaler value */
|
||||||
|
uint8_t prescaler_calculation(uint32_t can_bit_rate, uint32_t can_clock_frq, uint8_t *tq_no) {
|
||||||
|
|
||||||
|
/* local variables */
|
||||||
|
uint8_t tq_no_min_dev = 0;
|
||||||
|
uint32_t frq_tq, frq_dev, frq_dev_min = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
/* loop through all values of time quantas */
|
||||||
|
for(*tq_no = CAN_MAX_NO_OF_TQ; *tq_no >= MIN_NO_OF_TQ; (*tq_no)--) {
|
||||||
|
|
||||||
|
/* calculate time quanta freq. */
|
||||||
|
frq_tq = *tq_no * can_bit_rate;
|
||||||
|
|
||||||
|
/* calculate the deviation from requested tq freq. */
|
||||||
|
frq_dev = can_clock_frq%frq_tq;
|
||||||
|
|
||||||
|
/* check the deviation freq. */
|
||||||
|
if(frq_dev == 0) {
|
||||||
|
|
||||||
|
/* return if best match (zero deviation) */
|
||||||
|
return (uint8_t)(can_clock_frq/frq_tq);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
/* check for minimum of freq. deviation */
|
||||||
|
if(frq_dev < frq_dev_min) {
|
||||||
|
|
||||||
|
/* recognize the minimum freq. deviation */
|
||||||
|
frq_dev_min = frq_dev;
|
||||||
|
|
||||||
|
/* recognize the no. of time quantas */
|
||||||
|
tq_no_min_dev = *tq_no;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the optimized prescaler value */
|
||||||
|
*tq_no = tq_no_min_dev;
|
||||||
|
return (uint8_t)(can_clock_frq/(tq_no_min_dev * can_bit_rate));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MPC5x00 MSCAN set up the bit timing
|
* MPC5x00 MSCAN set up the bit timing
|
||||||
*/
|
*/
|
||||||
void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *mscan)
|
void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *mscan, uint32_t can_bit_rate, uint32_t can_clock_frq)
|
||||||
{
|
{
|
||||||
uint32_t prescale_val = 0;
|
uint32_t prescale_val = 0;
|
||||||
uint32_t tq_num;
|
uint8_t tq_no, tseg_1, tseg_2, sseg;
|
||||||
uint32_t sync_seg,tseg1,tseg2;
|
|
||||||
|
|
||||||
if(IPB_CLOCK%(CAN_BIT_RATE * CAN_MAX_NO_OF_TQ))
|
/* get optimized prescaler value */
|
||||||
prescale_val = (IPB_CLOCK/(CAN_BIT_RATE * (CAN_MAX_NO_OF_TQ*2/3))) + 1;
|
prescale_val = prescaler_calculation(can_bit_rate, can_clock_frq, &tq_no);
|
||||||
else
|
|
||||||
prescale_val = IPB_CLOCK/(CAN_BIT_RATE* (CAN_MAX_NO_OF_TQ*2/3));
|
|
||||||
|
|
||||||
tq_num = ((IPB_CLOCK/prescale_val)+CAN_BIT_RATE/2)/CAN_BIT_RATE;
|
/* get time segment length from time segment table */
|
||||||
/*
|
tseg_1 = can_time_segment_table[tq_no - MIN_NO_OF_TQ][TSEG_1];
|
||||||
* XXX: make this table controlled according to MPC5200UM/Rev.3,Table 19-34
|
tseg_2 = can_time_segment_table[tq_no - MIN_NO_OF_TQ][TSEG_2];
|
||||||
*/
|
sseg = can_time_segment_table[tq_no - MIN_NO_OF_TQ][SJW];
|
||||||
sync_seg = 2;
|
|
||||||
tseg2 = (tq_num-sync_seg)/6;
|
|
||||||
tseg1 = tq_num - sync_seg - tseg2;
|
|
||||||
|
|
||||||
/* Bus Timing Register 0 MSCAN_A/_B ------------------------------*/
|
/* Bus Timing Register 0 MSCAN_A/_B ------------------------------*/
|
||||||
/* [07]:SJW1 1 : Synchronization jump width, Bit1 */
|
/* [07]:SJW1 1 : Synchronization jump width, Bit1 */
|
||||||
@@ -569,7 +784,7 @@ void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *msca
|
|||||||
/* [02]:BRP2 1 : Baud Rate Prescaler, Bit 2 */
|
/* [02]:BRP2 1 : Baud Rate Prescaler, Bit 2 */
|
||||||
/* [01]:BRP1 0 : Baud Rate Prescaler, Bit 1 */
|
/* [01]:BRP1 0 : Baud Rate Prescaler, Bit 1 */
|
||||||
/* [00]:BRP0 1 : Baud Rate Prescaler, Bit 0 */
|
/* [00]:BRP0 1 : Baud Rate Prescaler, Bit 0 */
|
||||||
mscan->btr0 |= (BTR0_SJW(sync_seg-1) | BTR0_BRP(prescale_val - 1));
|
mscan->btr0 = (BTR0_SJW(sseg-1) | BTR0_BRP(prescale_val-1));
|
||||||
|
|
||||||
/* Bus Timing Register 1 MSCAN_A/_B ------------------------------*/
|
/* Bus Timing Register 1 MSCAN_A/_B ------------------------------*/
|
||||||
/* [07]:SAMP 0 : One Sample per bit */
|
/* [07]:SAMP 0 : One Sample per bit */
|
||||||
@@ -581,8 +796,7 @@ void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *msca
|
|||||||
/* [02]:TSEG12 1 : Time Segment 1, Bit 2 */
|
/* [02]:TSEG12 1 : Time Segment 1, Bit 2 */
|
||||||
/* [01]:TSEG11 1 : Time Segment 1, Bit 1 */
|
/* [01]:TSEG11 1 : Time Segment 1, Bit 1 */
|
||||||
/* [00]:TSEG10 0 : Time Segment 1, Bit 0 */
|
/* [00]:TSEG10 0 : Time Segment 1, Bit 0 */
|
||||||
mscan->btr1 &= ~(BTR1_SAMP);
|
mscan->btr1 = (BTR1_TSEG_22_20(tseg_2-1) | BTR1_TSEG_13_10(tseg_1-1));
|
||||||
mscan->btr1 |= (BTR1_TSEG_22_20(tseg2-1) | BTR1_TSEG_13_10(tseg1-1));
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -594,7 +808,10 @@ void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *msca
|
|||||||
*/
|
*/
|
||||||
void mpc5200_mscan_perform_init_mode_settings(volatile struct mpc5200_mscan *mscan)
|
void mpc5200_mscan_perform_init_mode_settings(volatile struct mpc5200_mscan *mscan)
|
||||||
{
|
{
|
||||||
mpc5200_mscan_perform_bit_time_settings(mscan);
|
|
||||||
|
/* perform all can bit time settings */
|
||||||
|
mpc5200_mscan_perform_bit_time_settings(mscan,CAN_BIT_RATE,IPB_CLOCK);
|
||||||
|
|
||||||
/* Control Register 1 --------------------------------------------*/
|
/* Control Register 1 --------------------------------------------*/
|
||||||
/* [07]:CANE 0 : MSCAN Module is disabled */
|
/* [07]:CANE 0 : MSCAN Module is disabled */
|
||||||
/* [06]:CLKSRC 0 : Clock Source -> IPB_CLOCK (bsp.h) */
|
/* [06]:CLKSRC 0 : Clock Source -> IPB_CLOCK (bsp.h) */
|
||||||
@@ -634,25 +851,15 @@ void mpc5200_mscan_perform_init_mode_settings(volatile struct mpc5200_mscan *msc
|
|||||||
mscan->idac &= ~(IDAC_IDAM1);
|
mscan->idac &= ~(IDAC_IDAM1);
|
||||||
mscan->idac |= (IDAC_IDAM0);
|
mscan->idac |= (IDAC_IDAM0);
|
||||||
|
|
||||||
/* initialize rx filter masks: only accept exact matches */
|
/* initialize rx filter masks (16 bit) */
|
||||||
mscan->idmr0 = 0x00;
|
mscan->idmr0 = SET_IDMR0(0x07FF);
|
||||||
mscan->idmr1 = 0x00;
|
mscan->idmr1 = SET_IDMR1(0x07FF);
|
||||||
mscan->idmr2 = 0x00;
|
mscan->idmr2 = SET_IDMR2(0x07FF);
|
||||||
mscan->idmr3 = 0x00;
|
mscan->idmr3 = SET_IDMR3(0x07FF);
|
||||||
mscan->idmr4 = 0x00;
|
mscan->idmr4 = SET_IDMR4(0x07FF);
|
||||||
mscan->idmr5 = 0x00;
|
mscan->idmr5 = SET_IDMR5(0x07FF);
|
||||||
mscan->idmr6 = 0x00;
|
mscan->idmr6 = SET_IDMR6(0x07FF);
|
||||||
mscan->idmr7 = 0x00;
|
mscan->idmr7 = SET_IDMR7(0x07FF);
|
||||||
|
|
||||||
/* initialize rx filters: set to illegal values, so no matches occure */
|
|
||||||
mscan->idar0 = 0xff;
|
|
||||||
mscan->idar1 = 0xff;
|
|
||||||
mscan->idar2 = 0xff;
|
|
||||||
mscan->idar3 = 0xff;
|
|
||||||
mscan->idar4 = 0xff;
|
|
||||||
mscan->idar5 = 0xff;
|
|
||||||
mscan->idar6 = 0xff;
|
|
||||||
mscan->idar7 = 0xff;
|
|
||||||
|
|
||||||
/* Control Register 1 --------------------------------------------*/
|
/* Control Register 1 --------------------------------------------*/
|
||||||
/* [07]:CANE 0->1 : MSCAN Module is enabled */
|
/* [07]:CANE 0->1 : MSCAN Module is enabled */
|
||||||
@@ -719,16 +926,30 @@ rtems_status_code mpc5200_mscan_set_mode(rtems_device_minor_number minor, uint8_
|
|||||||
switch(mode)
|
switch(mode)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
case MSCAN_INIT_NORMAL_MODE:
|
||||||
|
/* if not already set enter init mode */
|
||||||
|
mpc5200_mscan_enter_init_mode(mscan);
|
||||||
|
/* perform initialization which has to be done in init mode */
|
||||||
|
mpc5200_mscan_perform_init_mode_settings(mscan);
|
||||||
|
break;
|
||||||
|
|
||||||
case MSCAN_NORMAL_MODE:
|
case MSCAN_NORMAL_MODE:
|
||||||
/* if not already set enter init mode */
|
/* if not already set enter init mode */
|
||||||
mpc5200_mscan_enter_init_mode(mscan);
|
mpc5200_mscan_enter_init_mode(mscan);
|
||||||
|
|
||||||
if((chan->mode) == MSCAN_INITIALIZED_MODE)
|
if((chan->mode) == MSCAN_INITIALIZED_MODE)
|
||||||
|
{
|
||||||
|
|
||||||
/* perform initialization which has to be done in init mode */
|
/* perform initialization which has to be done in init mode */
|
||||||
mpc5200_mscan_perform_init_mode_settings(mscan);
|
mpc5200_mscan_perform_init_mode_settings(mscan);
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if((chan->mode) == MSCAN_SLEEP_MODE)
|
||||||
|
{
|
||||||
|
|
||||||
/* exit sleep mode */
|
/* exit sleep mode */
|
||||||
mpc5200_mscan_exit_sleep_mode(mscan);
|
mpc5200_mscan_exit_sleep_mode(mscan);
|
||||||
|
}
|
||||||
|
|
||||||
/* exit init mode */
|
/* exit init mode */
|
||||||
mpc5200_mscan_exit_init_mode(mscan);
|
mpc5200_mscan_exit_init_mode(mscan);
|
||||||
@@ -736,19 +957,13 @@ rtems_status_code mpc5200_mscan_set_mode(rtems_device_minor_number minor, uint8_
|
|||||||
mpc5200_mscan_int_enable(mscan);
|
mpc5200_mscan_int_enable(mscan);
|
||||||
/* wait for bus sync. */
|
/* wait for bus sync. */
|
||||||
mpc5200_mscan_wait_sync(mscan);
|
mpc5200_mscan_wait_sync(mscan);
|
||||||
return RTEMS_SUCCESSFUL;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSCAN_SLEEP_MODE:
|
case MSCAN_SLEEP_MODE:
|
||||||
/* enable ints. */
|
/* disable ints. */
|
||||||
mpc5200_mscan_int_disable(mscan);
|
mpc5200_mscan_int_disable(mscan);
|
||||||
/* if not already set enter init mode */
|
|
||||||
mpc5200_mscan_enter_init_mode(mscan);
|
|
||||||
/* exit sleep mode */
|
/* exit sleep mode */
|
||||||
mpc5200_mscan_enter_sleep_mode(mscan);
|
mpc5200_mscan_enter_sleep_mode(mscan);
|
||||||
/* exit init mode */
|
|
||||||
mpc5200_mscan_exit_init_mode(mscan);
|
|
||||||
return RTEMS_SUCCESSFUL;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -773,26 +988,55 @@ rtems_status_code mscan_channel_initialize(rtems_device_major_number major, rtem
|
|||||||
rtems_status_code status;
|
rtems_status_code status;
|
||||||
struct mscan_channel_info *chan = &chan_info[minor];
|
struct mscan_channel_info *chan = &chan_info[minor];
|
||||||
|
|
||||||
|
|
||||||
/* set registers according to MSCAN channel information */
|
/* set registers according to MSCAN channel information */
|
||||||
switch(minor)
|
switch(minor)
|
||||||
{
|
{
|
||||||
|
|
||||||
case MSCAN_A:
|
case MSCAN_A:
|
||||||
chan->rx_qname = rtems_build_name ('C', 'N', 'A', 'Q');
|
chan->rx_qname = rtems_build_name ('C', 'N', 'A', 'Q');
|
||||||
|
chan->tx_rb_sname = rtems_build_name ('C', 'N', 'A', 'S');
|
||||||
|
|
||||||
/* register RTEMS device names for MSCAN A */
|
/* register RTEMS device names for MSCAN A */
|
||||||
if((status = rtems_io_register_name (MSCAN_A_DEV_NAME, major, MSCAN_A)) != RTEMS_SUCCESSFUL)
|
if((status = rtems_io_register_name (MSCAN_A_DEV_NAME, major, MSCAN_A)) != RTEMS_SUCCESSFUL)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
/* register RTEMS device names for MSCAN 0 */
|
||||||
|
if((status = rtems_io_register_name (MSCAN_0_DEV_NAME, major, MSCAN_A)) != RTEMS_SUCCESSFUL)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
/* allocate the space for MSCAN A tx ring buffer */
|
||||||
|
if(((chan->tx_ring_buf.buf_ptr) = malloc(sizeof(struct can_message)*(NO_OF_MSCAN_TX_BUFF+1))) != NULL)
|
||||||
|
{
|
||||||
|
chan->tx_ring_buf.head_ptr = chan->tx_ring_buf.tail_ptr = chan->tx_ring_buf.buf_ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RTEMS_UNSATISFIED;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSCAN_B:
|
case MSCAN_B:
|
||||||
chan->rx_qname = rtems_build_name ('C', 'N', 'B', 'Q');
|
chan->rx_qname = rtems_build_name ('C', 'N', 'B', 'Q');
|
||||||
|
chan->tx_rb_sname = rtems_build_name ('C', 'N', 'B', 'S');
|
||||||
|
|
||||||
/* register RTEMS device names for MSCAN B */
|
/* register RTEMS device names for MSCAN B */
|
||||||
if((status = rtems_io_register_name (MSCAN_B_DEV_NAME, major, MSCAN_B)) != RTEMS_SUCCESSFUL)
|
if((status = rtems_io_register_name (MSCAN_B_DEV_NAME, major, MSCAN_B)) != RTEMS_SUCCESSFUL)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
/* register RTEMS device names for MSCAN 1 */
|
||||||
|
if((status = rtems_io_register_name (MSCAN_1_DEV_NAME, major, MSCAN_B)) != RTEMS_SUCCESSFUL)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
/* allocate the space for MSCAN B tx ring buffer */
|
||||||
|
if(((chan->tx_ring_buf.buf_ptr) = malloc(sizeof(struct can_message)*(NO_OF_MSCAN_TX_BUFF+1))) != NULL)
|
||||||
|
{
|
||||||
|
chan->tx_ring_buf.head_ptr = chan->tx_ring_buf.tail_ptr = chan->tx_ring_buf.buf_ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RTEMS_UNSATISFIED;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -800,19 +1044,21 @@ rtems_status_code mscan_channel_initialize(rtems_device_major_number major, rtem
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create RTEMS rx message queue for MSCAN A */
|
/* create RTEMS rx message queue */
|
||||||
if((status = rtems_message_queue_create(chan->rx_qname,
|
status = rtems_message_queue_create(chan->rx_qname,
|
||||||
(uint32_t) NO_OF_MSCAN_A_RX_BUFF,
|
(uint32_t) NO_OF_MSCAN_RX_BUFF,
|
||||||
(uint32_t) MSCAN_MESSAGE_SIZE(sizeof(struct can_message)),
|
(uint32_t) MSCAN_MESSAGE_SIZE(sizeof(struct can_message)),
|
||||||
(rtems_attribute) RTEMS_LOCAL | RTEMS_FIFO,
|
(rtems_attribute) RTEMS_LOCAL | RTEMS_FIFO,
|
||||||
(rtems_id *)&(chan->rx_qid)))
|
(rtems_id *)&(chan->rx_qid));
|
||||||
!= RTEMS_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
return status;
|
|
||||||
|
|
||||||
}
|
/* create counting RTEMS tx ring buffer semaphore */
|
||||||
|
status = rtems_semaphore_create(chan->tx_rb_sname,
|
||||||
|
(uint32_t)(NO_OF_MSCAN_TX_BUFF),
|
||||||
|
RTEMS_COUNTING_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL,
|
||||||
|
(rtems_task_priority)0,
|
||||||
|
(rtems_id *)&(chan->tx_rb_sid));
|
||||||
|
|
||||||
/* Set up interrupts MSCAN A */
|
/* Set up interrupts */
|
||||||
if(!BSP_install_rtems_irq_handler(&(mpc5200_mscan_irq_data[minor])))
|
if(!BSP_install_rtems_irq_handler(&(mpc5200_mscan_irq_data[minor])))
|
||||||
rtems_panic("Can't attach MPC5x00 MSCAN interrupt handler %d\n", minor);
|
rtems_panic("Can't attach MPC5x00 MSCAN interrupt handler %d\n", minor);
|
||||||
|
|
||||||
@@ -821,6 +1067,7 @@ rtems_status_code mscan_channel_initialize(rtems_device_major_number major, rtem
|
|||||||
chan->int_rx_err = 0;
|
chan->int_rx_err = 0;
|
||||||
chan->id_extended = FALSE;
|
chan->id_extended = FALSE;
|
||||||
chan->mode = MSCAN_INITIALIZED_MODE;
|
chan->mode = MSCAN_INITIALIZED_MODE;
|
||||||
|
chan->tx_buf_no = NO_OF_MSCAN_TX_BUFF;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -844,10 +1091,10 @@ rtems_device_driver mscan_initialize(rtems_device_major_number major,
|
|||||||
if((status = mscan_channel_initialize(major,MSCAN_B)) != RTEMS_SUCCESSFUL)
|
if((status = mscan_channel_initialize(major,MSCAN_B)) != RTEMS_SUCCESSFUL)
|
||||||
rtems_fatal_error_occurred(status);
|
rtems_fatal_error_occurred(status);
|
||||||
|
|
||||||
if((status = mpc5200_mscan_set_mode(MSCAN_A, MSCAN_NORMAL_MODE)) != RTEMS_SUCCESSFUL)
|
if((status = mpc5200_mscan_set_mode(MSCAN_A, MSCAN_INIT_NORMAL_MODE)) != RTEMS_SUCCESSFUL)
|
||||||
rtems_fatal_error_occurred(status);
|
rtems_fatal_error_occurred(status);
|
||||||
|
|
||||||
if((status = mpc5200_mscan_set_mode(MSCAN_B, MSCAN_NORMAL_MODE)) != RTEMS_SUCCESSFUL)
|
if((status = mpc5200_mscan_set_mode(MSCAN_B, MSCAN_INIT_NORMAL_MODE)) != RTEMS_SUCCESSFUL)
|
||||||
rtems_fatal_error_occurred(status);
|
rtems_fatal_error_occurred(status);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -863,7 +1110,7 @@ rtems_device_driver mscan_open( rtems_device_major_number major,
|
|||||||
void * arg
|
void * arg
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
rtems_status_code status;
|
rtems_status_code status = RTEMS_SUCCESSFUL;
|
||||||
struct mscan_channel_info *chan = NULL;
|
struct mscan_channel_info *chan = NULL;
|
||||||
|
|
||||||
switch(minor)
|
switch(minor)
|
||||||
@@ -879,8 +1126,14 @@ rtems_device_driver mscan_open( rtems_device_major_number major,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* check mode */
|
||||||
|
if((chan->mode) == MSCAN_SLEEP_MODE)
|
||||||
|
{
|
||||||
|
|
||||||
/* if not already set enter init mode */
|
/* if not already set enter init mode */
|
||||||
status = mpc5200_mscan_set_mode(minor, MSCAN_NORMAL_MODE);
|
status = mpc5200_mscan_set_mode(minor, MSCAN_NORMAL_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -947,6 +1200,15 @@ rtems_device_driver mscan_read( rtems_device_major_number major,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* end init mode if it is first read */
|
||||||
|
if((chan->mode) == MSCAN_INIT_NORMAL_MODE)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* if not already set enter init mode */
|
||||||
|
mpc5200_mscan_set_mode(minor, MSCAN_NORMAL_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
if((status = rtems_message_queue_receive(chan->rx_qid,
|
if((status = rtems_message_queue_receive(chan->rx_qid,
|
||||||
(void *)(rx_mess),
|
(void *)(rx_mess),
|
||||||
(uint32_t *)&message_size,
|
(uint32_t *)&message_size,
|
||||||
@@ -978,6 +1240,7 @@ rtems_device_driver mscan_write( rtems_device_major_number major,
|
|||||||
void * arg
|
void * arg
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
rtems_status_code status;
|
||||||
rtems_libio_rw_args_t *parms = (rtems_libio_rw_args_t *)arg;
|
rtems_libio_rw_args_t *parms = (rtems_libio_rw_args_t *)arg;
|
||||||
struct mscan_tx_parms *tx_parms = (struct mscan_tx_parms *)(parms->buffer);
|
struct mscan_tx_parms *tx_parms = (struct mscan_tx_parms *)(parms->buffer);
|
||||||
struct can_message *tx_mess = (struct can_message *)(tx_parms->tx_mess);
|
struct can_message *tx_mess = (struct can_message *)(tx_parms->tx_mess);
|
||||||
@@ -987,7 +1250,6 @@ rtems_device_driver mscan_write( rtems_device_major_number major,
|
|||||||
|
|
||||||
switch(minor)
|
switch(minor)
|
||||||
{
|
{
|
||||||
|
|
||||||
case MSCAN_A:
|
case MSCAN_A:
|
||||||
case MSCAN_B:
|
case MSCAN_B:
|
||||||
chan = &chan_info[minor];
|
chan = &chan_info[minor];
|
||||||
@@ -1000,118 +1262,39 @@ rtems_device_driver mscan_write( rtems_device_major_number major,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* select one free tx buffer (TOUCAN not registered) */
|
/* end init mode if it is first write */
|
||||||
if((mscan_hdl->toucan_callback) == NULL)
|
if((chan->mode) == MSCAN_INIT_NORMAL_MODE)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(mscan->tflg & MSCAN_TX_BUFF2)
|
/* if not already set enter init mode */
|
||||||
mscan->bsel = MSCAN_TX_BUFF2;
|
mpc5200_mscan_set_mode(minor, MSCAN_NORMAL_MODE);
|
||||||
|
|
||||||
if(mscan->tflg & MSCAN_TX_BUFF1)
|
|
||||||
mscan->bsel = MSCAN_TX_BUFF1;
|
|
||||||
|
|
||||||
if(mscan->tflg & MSCAN_TX_BUFF0)
|
|
||||||
mscan->bsel = MSCAN_TX_BUFF0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
/* select a specific, preconfigured tx buffer (TOUCAN registered) */
|
|
||||||
switch(tx_parms->tx_id)
|
|
||||||
{
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
if(mscan->tflg & MSCAN_TX_BUFF0)
|
|
||||||
mscan->bsel = MSCAN_TX_BUFF0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
if(mscan->tflg & MSCAN_TX_BUFF1)
|
|
||||||
mscan->bsel = MSCAN_TX_BUFF1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
if(mscan->tflg & MSCAN_TX_BUFF2)
|
|
||||||
mscan->bsel = MSCAN_TX_BUFF2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
/* preset moved bytes */
|
||||||
|
|
||||||
/* if no tx buffer is available, teminate the write request */
|
|
||||||
if(!(mscan->bsel))
|
|
||||||
{
|
|
||||||
|
|
||||||
parms->bytes_moved = 0;
|
parms->bytes_moved = 0;
|
||||||
return RTEMS_UNSATISFIED;
|
|
||||||
|
|
||||||
}
|
/* obtain counting semaphore of tx ring buffer */
|
||||||
|
if((status = rtems_semaphore_obtain((rtems_id)(chan->tx_rb_sid),
|
||||||
/* prepare tx id and dlc (TOUCAN not initialized) */
|
RTEMS_NO_WAIT,
|
||||||
if((mscan_hdl->toucan_callback) == NULL)
|
(rtems_interval)0))
|
||||||
|
== RTEMS_SUCCESSFUL)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* check for tx length */
|
/* append the TOUCAN tx_id to the mess. due to interrupt handling */
|
||||||
if((tx_mess->mess_len) & 0x000F)
|
tx_mess->toucan_tx_id = tx_parms->tx_id;
|
||||||
{
|
|
||||||
|
|
||||||
/* set tx id */
|
/* fill the tx ring buffer with the message */
|
||||||
mscan->txidr0 = SET_IDR0(tx_mess->mess_id);
|
fill_tx_buffer(chan, tx_mess);
|
||||||
mscan->txidr1 = SET_IDR1(tx_mess->mess_id);
|
|
||||||
mscan->txidr2 = 0;
|
|
||||||
mscan->txidr3 = 0;
|
|
||||||
|
|
||||||
/* insert dlc into mscan register */
|
|
||||||
mscan->txdlr = (uint8_t)((tx_mess->mess_len) & 0x000F);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
parms->bytes_moved = 0;
|
|
||||||
return RTEMS_UNSATISFIED;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy tx data to MSCAN registers */
|
|
||||||
switch(mscan->txdlr)
|
|
||||||
{
|
|
||||||
|
|
||||||
case 8:
|
|
||||||
mscan->txdsr7 = tx_mess->mess_data[7];
|
|
||||||
case 7:
|
|
||||||
mscan->txdsr6 = tx_mess->mess_data[6];
|
|
||||||
case 6:
|
|
||||||
mscan->txdsr5 = tx_mess->mess_data[5];
|
|
||||||
case 5:
|
|
||||||
mscan->txdsr4 = tx_mess->mess_data[4];
|
|
||||||
case 4:
|
|
||||||
mscan->txdsr3 = tx_mess->mess_data[3];
|
|
||||||
case 3:
|
|
||||||
mscan->txdsr2 = tx_mess->mess_data[2];
|
|
||||||
case 2:
|
|
||||||
mscan->txdsr1 = tx_mess->mess_data[1];
|
|
||||||
case 1:
|
|
||||||
mscan->txdsr0 = tx_mess->mess_data[0];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* enable message buffer specific interrupt */
|
/* enable message buffer specific interrupt */
|
||||||
mscan->tier |= mscan->bsel;
|
mscan->tier |= (TIER_TXEI0 | TIER_TXEI1 | TIER_TXEI2);
|
||||||
|
|
||||||
/* start transfer */
|
/* calculate moved bytes */
|
||||||
mscan->tflg = mscan->bsel;
|
parms->bytes_moved = (tx_mess->mess_len) & 0x000F;
|
||||||
|
|
||||||
return RTEMS_SUCCESSFUL;
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1124,12 +1307,14 @@ rtems_device_driver mscan_control( rtems_device_major_number major,
|
|||||||
void * arg
|
void * arg
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
rtems_status_code status;
|
||||||
uint16_t tx_id;
|
uint16_t tx_id;
|
||||||
rtems_libio_ioctl_args_t *parms = (rtems_libio_ioctl_args_t *)arg;
|
rtems_libio_ioctl_args_t *parms = (rtems_libio_ioctl_args_t *)arg;
|
||||||
struct mscan_ctrl_parms *ctrl_parms = (struct mscan_ctrl_parms *)(parms->buffer);
|
struct mscan_ctrl_parms *ctrl_parms = (struct mscan_ctrl_parms *)(parms->buffer);
|
||||||
struct mscan_channel_info *chan = NULL;
|
struct mscan_channel_info *chan = NULL;
|
||||||
mscan_handle *mscan_hdl = NULL;
|
mscan_handle *mscan_hdl = NULL;
|
||||||
volatile struct mpc5200_mscan *mscan = NULL;
|
volatile struct mpc5200_mscan *mscan = NULL;
|
||||||
|
uint8_t tx_buf_count = 0;
|
||||||
|
|
||||||
switch(minor)
|
switch(minor)
|
||||||
{
|
{
|
||||||
@@ -1239,23 +1424,23 @@ rtems_device_driver mscan_control( rtems_device_major_number major,
|
|||||||
{
|
{
|
||||||
|
|
||||||
case RX_BUFFER_0:
|
case RX_BUFFER_0:
|
||||||
mscan->idmr0 = SET_IDR0(ctrl_parms->ctrl_id_mask);
|
mscan->idmr0 = SET_IDMR0(ctrl_parms->ctrl_id_mask);
|
||||||
mscan->idmr1 = SET_IDR1(ctrl_parms->ctrl_id_mask);
|
mscan->idmr1 = SET_IDMR1(ctrl_parms->ctrl_id_mask);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RX_BUFFER_1:
|
case RX_BUFFER_1:
|
||||||
mscan->idmr2 = SET_IDR2(ctrl_parms->ctrl_id_mask);
|
mscan->idmr2 = SET_IDMR2(ctrl_parms->ctrl_id_mask);
|
||||||
mscan->idmr3 = SET_IDR3(ctrl_parms->ctrl_id_mask);
|
mscan->idmr3 = SET_IDMR3(ctrl_parms->ctrl_id_mask);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RX_BUFFER_2:
|
case RX_BUFFER_2:
|
||||||
mscan->idmr4 = SET_IDR4(ctrl_parms->ctrl_id_mask);
|
mscan->idmr4 = SET_IDMR4(ctrl_parms->ctrl_id_mask);
|
||||||
mscan->idmr5 = SET_IDR5(ctrl_parms->ctrl_id_mask);
|
mscan->idmr5 = SET_IDMR5(ctrl_parms->ctrl_id_mask);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RX_BUFFER_3:
|
case RX_BUFFER_3:
|
||||||
mscan->idmr6 = SET_IDR6(ctrl_parms->ctrl_id_mask);
|
mscan->idmr6 = SET_IDMR6(ctrl_parms->ctrl_id_mask);
|
||||||
mscan->idmr7 = SET_IDR7(ctrl_parms->ctrl_id_mask);
|
mscan->idmr7 = SET_IDMR7(ctrl_parms->ctrl_id_mask);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1281,19 +1466,19 @@ rtems_device_driver mscan_control( rtems_device_major_number major,
|
|||||||
{
|
{
|
||||||
|
|
||||||
case RX_BUFFER_0:
|
case RX_BUFFER_0:
|
||||||
ctrl_parms->ctrl_id_mask = GET_IDR0(mscan->idmr0) | GET_IDR1(mscan->idmr1);
|
ctrl_parms->ctrl_id_mask = GET_IDMR0(mscan->idmr0) | GET_IDMR1(mscan->idmr1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RX_BUFFER_1:
|
case RX_BUFFER_1:
|
||||||
ctrl_parms->ctrl_id_mask = GET_IDR2(mscan->idmr2) | GET_IDR3(mscan->idmr3);
|
ctrl_parms->ctrl_id_mask = GET_IDMR2(mscan->idmr2) | GET_IDMR3(mscan->idmr3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RX_BUFFER_2:
|
case RX_BUFFER_2:
|
||||||
ctrl_parms->ctrl_id_mask = GET_IDR4(mscan->idmr4) | GET_IDR5(mscan->idmr5);
|
ctrl_parms->ctrl_id_mask = GET_IDMR4(mscan->idmr4) | GET_IDMR5(mscan->idmr5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RX_BUFFER_3:
|
case RX_BUFFER_3:
|
||||||
ctrl_parms->ctrl_id_mask = GET_IDR6(mscan->idmr6) | GET_IDR7(mscan->idmr7);
|
ctrl_parms->ctrl_id_mask = GET_IDMR6(mscan->idmr6) | GET_IDMR7(mscan->idmr7);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1339,6 +1524,98 @@ rtems_device_driver mscan_control( rtems_device_major_number major,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* set can bitrate */
|
||||||
|
case MSCAN_SET_BAUDRATE:
|
||||||
|
|
||||||
|
/* check bitrate settings */
|
||||||
|
if(((ctrl_parms->ctrl_can_bitrate) >= CAN_BIT_RATE_MIN) && ((ctrl_parms->ctrl_can_bitrate) <= CAN_BIT_RATE_MAX)) {
|
||||||
|
|
||||||
|
/* enter init mode */
|
||||||
|
mpc5200_mscan_enter_init_mode(mscan);
|
||||||
|
|
||||||
|
/* perform all can bit time settings */
|
||||||
|
mpc5200_mscan_perform_bit_time_settings(mscan,(uint32_t)(ctrl_parms->ctrl_can_bitrate),IPB_CLOCK);
|
||||||
|
|
||||||
|
/* exit init mode and perform further initialization which is required in the normal mode */
|
||||||
|
mpc5200_mscan_exit_init_mode(mscan);
|
||||||
|
|
||||||
|
/* enable ints. */
|
||||||
|
mpc5200_mscan_int_enable(mscan);
|
||||||
|
|
||||||
|
/* wait for bus sync. */
|
||||||
|
mpc5200_mscan_wait_sync(mscan);
|
||||||
|
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
return RTEMS_UNSATISFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SET_TX_BUF_NO:
|
||||||
|
|
||||||
|
/* check for different settings of tx ring buffer */
|
||||||
|
if((tx_buf_count = chan->tx_buf_no) != (uint8_t)(ctrl_parms->ctrl_tx_buf_no))
|
||||||
|
{
|
||||||
|
|
||||||
|
/* preset the channel specific no of messages in the tx ring buffer */
|
||||||
|
tx_buf_count = chan->tx_buf_no;
|
||||||
|
|
||||||
|
/* try to obtain all of the tx ring buffers */
|
||||||
|
while(tx_buf_count > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* obtain semaphore of all tx ring buffers */
|
||||||
|
if((status = rtems_semaphore_obtain((rtems_id)(chan->tx_rb_sid),
|
||||||
|
RTEMS_WAIT,
|
||||||
|
(rtems_interval)10))
|
||||||
|
== RTEMS_SUCCESSFUL)
|
||||||
|
{
|
||||||
|
|
||||||
|
tx_buf_count--;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free the former tx ring buffer */
|
||||||
|
free((void *)chan->tx_ring_buf.buf_ptr);
|
||||||
|
|
||||||
|
/* allocate the tx ring buffer with new size */
|
||||||
|
if(((chan->tx_ring_buf.buf_ptr) = malloc(sizeof(struct can_message)*((uint8_t)(ctrl_parms->ctrl_tx_buf_no)+1))) != NULL)
|
||||||
|
{
|
||||||
|
chan->tx_ring_buf.head_ptr = chan->tx_ring_buf.tail_ptr = chan->tx_ring_buf.buf_ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RTEMS_UNSATISFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the new amount of tx buffers */
|
||||||
|
chan->tx_buf_no = (uint8_t)(ctrl_parms->ctrl_tx_buf_no);
|
||||||
|
|
||||||
|
/* release the semaphore of all tx ring buffers */
|
||||||
|
while(tx_buf_count < chan->tx_buf_no)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* obtain semaphore of all tx ring buffers */
|
||||||
|
rtems_semaphore_release((rtems_id)(chan->tx_rb_sid));
|
||||||
|
|
||||||
|
tx_buf_count++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,11 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MIN_NO_OF_TQ 7
|
||||||
|
#define NO_OF_TABLE_ENTRIES 4
|
||||||
|
#define TSEG_1 1
|
||||||
|
#define TSEG_2 2
|
||||||
|
#define SJW 3
|
||||||
|
|
||||||
#define MSCAN_MAX_DATA_BYTES 8
|
#define MSCAN_MAX_DATA_BYTES 8
|
||||||
#define MSCAN_RX_BUFF_NUM 4
|
#define MSCAN_RX_BUFF_NUM 4
|
||||||
@@ -34,13 +39,19 @@ extern "C" {
|
|||||||
|
|
||||||
#define MSCAN_A_DEV_NAME "/dev/mscana"
|
#define MSCAN_A_DEV_NAME "/dev/mscana"
|
||||||
#define MSCAN_B_DEV_NAME "/dev/mscanb"
|
#define MSCAN_B_DEV_NAME "/dev/mscanb"
|
||||||
|
#define MSCAN_0_DEV_NAME "/dev/mscan0"
|
||||||
|
#define MSCAN_1_DEV_NAME "/dev/mscan1"
|
||||||
#define MSCAN_A 0
|
#define MSCAN_A 0
|
||||||
#define MSCAN_B 1
|
#define MSCAN_B 1
|
||||||
|
|
||||||
#define MSCAN_INITIALIZED_MODE 0
|
#define MSCAN_NON_INITIALIZED_MODE 0
|
||||||
#define MSCAN_INIT_NORMAL_MODE 1
|
#define MSCAN_INITIALIZED_MODE 1
|
||||||
#define MSCAN_NORMAL_MODE 2
|
#define MSCAN_INIT_NORMAL_MODE 2
|
||||||
#define MSCAN_SLEEP_MODE 4
|
#define MSCAN_NORMAL_MODE 4
|
||||||
|
#define MSCAN_SLEEP_MODE 8
|
||||||
|
|
||||||
|
#define CAN_BIT_RATE_MAX 1000000
|
||||||
|
#define CAN_BIT_RATE_MIN 100000
|
||||||
|
|
||||||
#define CAN_BIT_RATE 100000
|
#define CAN_BIT_RATE 100000
|
||||||
#define CAN_MAX_NO_OF_TQ 25
|
#define CAN_MAX_NO_OF_TQ 25
|
||||||
@@ -54,7 +65,10 @@ extern "C" {
|
|||||||
#define MSCAN_GET_RX_ID_MASK 4
|
#define MSCAN_GET_RX_ID_MASK 4
|
||||||
#define MSCAN_SET_TX_ID 5
|
#define MSCAN_SET_TX_ID 5
|
||||||
#define MSCAN_GET_TX_ID 6
|
#define MSCAN_GET_TX_ID 6
|
||||||
|
|
||||||
#define TOUCAN_MSCAN_INIT 7
|
#define TOUCAN_MSCAN_INIT 7
|
||||||
|
#define MSCAN_SET_BAUDRATE 8
|
||||||
|
#define SET_TX_BUF_NO 9
|
||||||
|
|
||||||
#define MSCAN_RX_BUFF_NOACTIVE (0 << 4)
|
#define MSCAN_RX_BUFF_NOACTIVE (0 << 4)
|
||||||
#define MSCAN_RX_BUFF_EMPTY (1 << 6)
|
#define MSCAN_RX_BUFF_EMPTY (1 << 6)
|
||||||
@@ -62,8 +76,7 @@ extern "C" {
|
|||||||
#define MSCAN_RX_BUFF_OVERRUN ((MSCAN_RX_BUFF_EMPTY) | (MSCAN_RX_BUFF_FULL))
|
#define MSCAN_RX_BUFF_OVERRUN ((MSCAN_RX_BUFF_EMPTY) | (MSCAN_RX_BUFF_FULL))
|
||||||
#define MSCAN_RX_BUFF_BUSY (1 << 4)
|
#define MSCAN_RX_BUFF_BUSY (1 << 4)
|
||||||
|
|
||||||
#define MSCAN_A_MBUFF_MASK 0x07
|
#define MSCAN_MBUFF_MASK 0x07
|
||||||
#define MSCAN_B_MBUFF_MASK 0x07
|
|
||||||
|
|
||||||
#define MSCAN_TX_BUFF0 (1 << 0)
|
#define MSCAN_TX_BUFF0 (1 << 0)
|
||||||
#define MSCAN_TX_BUFF1 (1 << 1)
|
#define MSCAN_TX_BUFF1 (1 << 1)
|
||||||
@@ -175,7 +188,7 @@ extern "C" {
|
|||||||
#define SET_IDR7(u16) SET_IDR1(u16)
|
#define SET_IDR7(u16) SET_IDR1(u16)
|
||||||
|
|
||||||
#define GET_IDR0(u16) ((uint16_t) ((u16) << 3))
|
#define GET_IDR0(u16) ((uint16_t) ((u16) << 3))
|
||||||
#define GET_IDR1(u16) ((uint16_t)((u16) >> 5))
|
#define GET_IDR1(u16) ((uint16_t)(((u16) >> 5)&0x0007))
|
||||||
|
|
||||||
#define GET_IDR2(u16) GET_IDR0(u16)
|
#define GET_IDR2(u16) GET_IDR0(u16)
|
||||||
#define GET_IDR3(u16) GET_IDR1(u16)
|
#define GET_IDR3(u16) GET_IDR1(u16)
|
||||||
@@ -186,8 +199,31 @@ extern "C" {
|
|||||||
#define GET_IDR6(u16) GET_IDR0(u16)
|
#define GET_IDR6(u16) GET_IDR0(u16)
|
||||||
#define GET_IDR7(u16) GET_IDR1(u16)
|
#define GET_IDR7(u16) GET_IDR1(u16)
|
||||||
|
|
||||||
#define NO_OF_MSCAN_A_RX_BUFF 20
|
#define SET_IDMR0(u16) ((uint8_t)((u16) >> 3))
|
||||||
#define NO_OF_MSCAN_B_RX_BUFF 20
|
#define SET_IDMR1(u16) ((uint8_t)((((u16) & 0x0007) << 5))|0x001F)
|
||||||
|
|
||||||
|
#define SET_IDMR2(u16) SET_IDMR0(u16)
|
||||||
|
#define SET_IDMR3(u16) SET_IDMR1(u16)
|
||||||
|
|
||||||
|
#define SET_IDMR4(u16) SET_IDMR0(u16)
|
||||||
|
#define SET_IDMR5(u16) SET_IDMR1(u16)
|
||||||
|
|
||||||
|
#define SET_IDMR6(u16) SET_IDMR0(u16)
|
||||||
|
#define SET_IDMR7(u16) SET_IDMR1(u16)
|
||||||
|
|
||||||
|
#define GET_IDMR0(u16) ((uint16_t) ((u16) << 3))
|
||||||
|
#define GET_IDMR1(u16) ((uint16_t)(((u16) >> 5)&0x0007))
|
||||||
|
|
||||||
|
#define GET_IDMR2(u16) GET_IDMR0(u16)
|
||||||
|
#define GET_IDMR3(u16) GET_IDMR1(u16)
|
||||||
|
|
||||||
|
#define GET_IDMR4(u16) GET_IDMR0(u16)
|
||||||
|
#define GET_IDMR5(u16) GET_IDMR1(u16)
|
||||||
|
|
||||||
|
#define GET_IDMR6(u16) GET_IDMR0(u16)
|
||||||
|
#define GET_IDMR7(u16) GET_IDMR1(u16)
|
||||||
|
|
||||||
|
#define NO_OF_MSCAN_RX_BUFF 20
|
||||||
#define MSCAN_MESSAGE_SIZE(size) (((size)%CPU_ALIGNMENT) ? (((size) + CPU_ALIGNMENT)-((size) + CPU_ALIGNMENT)%CPU_ALIGNMENT) : (size))
|
#define MSCAN_MESSAGE_SIZE(size) (((size)%CPU_ALIGNMENT) ? (((size) + CPU_ALIGNMENT)-((size) + CPU_ALIGNMENT)%CPU_ALIGNMENT) : (size))
|
||||||
|
|
||||||
#define TX_BUFFER_0 0
|
#define TX_BUFFER_0 0
|
||||||
@@ -199,6 +235,11 @@ extern "C" {
|
|||||||
#define RX_BUFFER_2 2
|
#define RX_BUFFER_2 2
|
||||||
#define RX_BUFFER_3 3
|
#define RX_BUFFER_3 3
|
||||||
|
|
||||||
|
#define NO_OF_MSCAN_TX_BUFF 20
|
||||||
|
#define RING_BUFFER_EMPTY(rbuff) ((((rbuff)->head) == ((rbuff)->tail)) ? TRUE : FALSE)
|
||||||
|
#define RING_BUFFER_FULL(rbuff) ((((rbuff)->head) == ((rbuff)->tail)) ? TRUE : FALSE)
|
||||||
|
|
||||||
|
|
||||||
typedef struct _mscan_handle
|
typedef struct _mscan_handle
|
||||||
{
|
{
|
||||||
uint8_t mscan_channel;
|
uint8_t mscan_channel;
|
||||||
@@ -212,6 +253,14 @@ struct can_message
|
|||||||
uint16_t mess_time_stamp;
|
uint16_t mess_time_stamp;
|
||||||
uint8_t mess_data[MSCAN_MAX_DATA_BYTES];
|
uint8_t mess_data[MSCAN_MAX_DATA_BYTES];
|
||||||
uint8_t mess_len;
|
uint8_t mess_len;
|
||||||
|
uint32_t toucan_tx_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
volatile struct ring_buf
|
||||||
|
{
|
||||||
|
volatile struct can_message *buf_ptr;
|
||||||
|
volatile struct can_message *head_ptr;
|
||||||
|
volatile struct can_message *tail_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mpc5200_rx_cntrl
|
struct mpc5200_rx_cntrl
|
||||||
@@ -219,15 +268,18 @@ struct mpc5200_rx_cntrl
|
|||||||
struct can_message can_rx_message[MSCAN_RX_BUFF_NUM];
|
struct can_message can_rx_message[MSCAN_RX_BUFF_NUM];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct mscan_channel_info
|
struct mscan_channel_info
|
||||||
{
|
{
|
||||||
volatile struct mpc5200_mscan *regs;
|
volatile struct mpc5200_mscan *regs;
|
||||||
uint32_t int_rx_err;
|
uint32_t int_rx_err;
|
||||||
rtems_id rx_qid;
|
rtems_id rx_qid;
|
||||||
uint32_t rx_qname;
|
uint32_t rx_qname;
|
||||||
|
rtems_id tx_rb_sid;
|
||||||
|
uint32_t tx_rb_sname;
|
||||||
uint8_t id_extended;
|
uint8_t id_extended;
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
|
uint8_t tx_buf_no;
|
||||||
|
volatile struct ring_buf tx_ring_buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mscan_rx_parms
|
struct mscan_rx_parms
|
||||||
@@ -248,6 +300,8 @@ struct mscan_ctrl_parms
|
|||||||
uint32_t ctrl_id;
|
uint32_t ctrl_id;
|
||||||
uint32_t ctrl_id_mask;
|
uint32_t ctrl_id_mask;
|
||||||
uint8_t ctrl_reg_no;
|
uint8_t ctrl_reg_no;
|
||||||
|
uint8_t ctrl_tx_buf_no;
|
||||||
|
uint32_t ctrl_can_bitrate;
|
||||||
void (*toucan_cb_fnc)(int16_t);
|
void (*toucan_cb_fnc)(int16_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -304,6 +358,8 @@ void mpc5200_mscan_perform_init_mode_settings(volatile struct mpc5200_mscan *);
|
|||||||
void mpc5200_mscan_perform_normal_mode_settings(volatile struct mpc5200_mscan *);
|
void mpc5200_mscan_perform_normal_mode_settings(volatile struct mpc5200_mscan *);
|
||||||
rtems_status_code mpc5200_mscan_set_mode(rtems_device_minor_number, uint8_t);
|
rtems_status_code mpc5200_mscan_set_mode(rtems_device_minor_number, uint8_t);
|
||||||
rtems_status_code mscan_channel_initialize(rtems_device_major_number, rtems_device_minor_number);
|
rtems_status_code mscan_channel_initialize(rtems_device_major_number, rtems_device_minor_number);
|
||||||
|
uint8_t prescaler_calculation(uint32_t, uint32_t, uint8_t *);
|
||||||
|
void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *, uint32_t, uint32_t);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -78,8 +78,8 @@
|
|||||||
|
|
||||||
#define SDMA_BD_TFD 0x08000000 /*< Transmit Frame Done */
|
#define SDMA_BD_TFD 0x08000000 /*< Transmit Frame Done */
|
||||||
#define SDMA_BD_INT 0x04000000 /*< Interrupt on frame done */
|
#define SDMA_BD_INT 0x04000000 /*< Interrupt on frame done */
|
||||||
#define SDMA_BD_RX_NUM 32 /* Number of receive buffer descriptors */
|
#define SDMA_BD_RX_NUM 64 /* Number of receive buffer descriptors */
|
||||||
#define SDMA_BD_TX_NUM 48 /* Number of transmit buffer descriptors */
|
#define SDMA_BD_TX_NUM 64 /* Number of transmit buffer descriptors */
|
||||||
|
|
||||||
#define SET_BD_STATUS(bd, stat) { \
|
#define SET_BD_STATUS(bd, stat) { \
|
||||||
(bd)->Status &= 0x0000ffff; \
|
(bd)->Status &= 0x0000ffff; \
|
||||||
@@ -127,6 +127,7 @@ static TaskId txTaskId; /* SDMA TX task ID */
|
|||||||
* This must *not* be the same event used by the TCP/IP task synchronization.
|
* This must *not* be the same event used by the TCP/IP task synchronization.
|
||||||
*/
|
*/
|
||||||
#define INTERRUPT_EVENT RTEMS_EVENT_1
|
#define INTERRUPT_EVENT RTEMS_EVENT_1
|
||||||
|
#define FATAL_INT_EVENT RTEMS_EVENT_3
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RTEMS event used to start transmit daemon.
|
* RTEMS event used to start transmit daemon.
|
||||||
@@ -197,6 +198,10 @@ typedef struct mpc5200_buffer_desc_
|
|||||||
} mpc5200_buffer_desc_t;
|
} mpc5200_buffer_desc_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define FEC_INTR_MASK_USED \
|
||||||
|
(FEC_INTR_LCEN |FEC_INTR_CRLEN |\
|
||||||
|
FEC_INTR_XFUNEN|FEC_INTR_XFERREN|FEC_INTR_RFERREN)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Device data
|
* Device data
|
||||||
*/
|
*/
|
||||||
@@ -235,11 +240,10 @@ struct mpc5200_enet_struct {
|
|||||||
unsigned long txRetryLimit;
|
unsigned long txRetryLimit;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t tx_shadow_buffer[TX_BUF_COUNT][(ETHER_MAX_LEN+3)&~3];
|
|
||||||
|
|
||||||
static struct mpc5200_enet_struct enet_driver[NIFACES];
|
static struct mpc5200_enet_struct enet_driver[NIFACES];
|
||||||
|
|
||||||
extern int taskTable;
|
extern int taskTable;
|
||||||
|
static void mpc5200_fec_restart(struct mpc5200_enet_struct *sc);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -279,6 +283,30 @@ static void mpc5200_fec_rx_bd_init(struct mpc5200_enet_struct *sc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function: mpc5200_fec_rx_bd_cleanup
|
||||||
|
*
|
||||||
|
* Description: put all mbufs pending in rx BDs back to buffer pool
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void mpc5200_fec_rx_bd_cleanup(struct mpc5200_enet_struct *sc) {
|
||||||
|
int rxBdIndex;
|
||||||
|
struct mbuf *m,*n;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Drain RX buffer descriptor ring.
|
||||||
|
*/
|
||||||
|
for( rxBdIndex = 0; rxBdIndex < sc->rxBdCount; rxBdIndex++ ) {
|
||||||
|
n = sc->rxMbuf[rxBdIndex];
|
||||||
|
while (n != NULL) {
|
||||||
|
m = n;
|
||||||
|
MFREE(m,n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: MPC5200_eth_addr_filter_set
|
* Function: MPC5200_eth_addr_filter_set
|
||||||
*
|
*
|
||||||
@@ -492,6 +520,7 @@ static int mpc5200_eth_mii_write(struct mpc5200_enet_struct *sc, unsigned char p
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int mpc5200_fec_reset(struct mpc5200_enet_struct *sc) {
|
static int mpc5200_fec_reset(struct mpc5200_enet_struct *sc) {
|
||||||
|
volatile int delay;
|
||||||
/*
|
/*
|
||||||
* Clear FIFO status registers
|
* Clear FIFO status registers
|
||||||
*/
|
*/
|
||||||
@@ -499,8 +528,12 @@ static int mpc5200_fec_reset(struct mpc5200_enet_struct *sc) {
|
|||||||
mpc5200.tfifo_status &= FEC_FIFO_STAT_ERROR;
|
mpc5200.tfifo_status &= FEC_FIFO_STAT_ERROR;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
* reset the FIFOs
|
||||||
*/
|
*/
|
||||||
|
mpc5200.reset_cntrl = 0x03000000;
|
||||||
|
|
||||||
|
for (delay = 0;delay < 16*4;delay++) {};
|
||||||
|
|
||||||
mpc5200.reset_cntrl = 0x01000000;
|
mpc5200.reset_cntrl = 0x01000000;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -511,7 +544,7 @@ static int mpc5200_fec_reset(struct mpc5200_enet_struct *sc) {
|
|||||||
/*
|
/*
|
||||||
* wait at least 16 clock cycles
|
* wait at least 16 clock cycles
|
||||||
*/
|
*/
|
||||||
rtems_task_wake_after(2);
|
for (delay = 0;delay < 16*4;delay++) {};
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -554,9 +587,9 @@ void mpc5200_fec_off(struct mpc5200_enet_struct *sc)
|
|||||||
#endif /* ETH_DEBUG */
|
#endif /* ETH_DEBUG */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mask FEC chip interrupts
|
* block FEC chip interrupts
|
||||||
*/
|
*/
|
||||||
mpc5200.imask = FEC_INTR_MASK_ALL;
|
mpc5200.imask = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* issue graceful stop command to the FEC transmitter if necessary
|
* issue graceful stop command to the FEC transmitter if necessary
|
||||||
@@ -565,6 +598,7 @@ void mpc5200_fec_off(struct mpc5200_enet_struct *sc)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* wait for graceful stop to register
|
* wait for graceful stop to register
|
||||||
|
* FIXME: add rtems_task_wake_after here, if it takes to long
|
||||||
*/
|
*/
|
||||||
while((counter--) && (!(mpc5200.ievent & FEC_INTR_GRA)));
|
while((counter--) && (!(mpc5200.ievent & FEC_INTR_GRA)));
|
||||||
|
|
||||||
@@ -584,19 +618,56 @@ void mpc5200_fec_off(struct mpc5200_enet_struct *sc)
|
|||||||
*/
|
*/
|
||||||
mpc5200.ecntrl &= ~(FEC_ECNTRL_OE | FEC_ECNTRL_EN);
|
mpc5200.ecntrl &= ~(FEC_ECNTRL_OE | FEC_ECNTRL_EN);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cleanup all buffers
|
||||||
|
*/
|
||||||
|
mpc5200_fec_rx_bd_cleanup(sc);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MPC5200 FEC interrupt handler
|
||||||
|
*/
|
||||||
|
void mpc5200_fec_irq_handler(rtems_irq_hdl_param handle)
|
||||||
|
{
|
||||||
|
struct mpc5200_enet_struct *sc = (struct mpc5200_enet_struct *) handle;
|
||||||
|
volatile uint32_t ievent;
|
||||||
|
|
||||||
|
ievent = mpc5200.ievent;
|
||||||
|
|
||||||
|
mpc5200.ievent = ievent;
|
||||||
|
/*
|
||||||
|
* check errors, update statistics
|
||||||
|
*/
|
||||||
|
if (ievent & FEC_INTR_LATE_COL) {
|
||||||
|
sc->txLateCollision++;
|
||||||
|
}
|
||||||
|
if (ievent & FEC_INTR_COL_RETRY) {
|
||||||
|
sc->txRetryLimit++;
|
||||||
|
}
|
||||||
|
if (ievent & FEC_INTR_XFIFO_UN) {
|
||||||
|
sc->txUnderrun++;
|
||||||
|
}
|
||||||
|
if (ievent & FEC_INTR_XFIFO_ERR) {
|
||||||
|
sc->txUnderrun++;
|
||||||
|
}
|
||||||
|
if (ievent & FEC_INTR_RFIFO_ERR) {
|
||||||
|
sc->rxOverrun++;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* fatal error ocurred?
|
||||||
|
*/
|
||||||
|
if (ievent & (FEC_INTR_XFIFO_ERR | FEC_INTR_RFIFO_ERR)) {
|
||||||
|
mpc5200.imask &= ~(FEC_INTR_XFERREN | FEC_INTR_RFERREN);
|
||||||
|
rtems_event_send(enet_driver[0].rxDaemonTid, FATAL_INT_EVENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MPC5200 SmartComm ethernet interrupt handler
|
* MPC5200 SmartComm ethernet interrupt handler
|
||||||
*/
|
*/
|
||||||
void mpc5200_smartcomm_rx_irq_handler(rtems_irq_hdl_param unused)
|
void mpc5200_smartcomm_rx_irq_handler(rtems_irq_hdl_param unused)
|
||||||
{
|
{
|
||||||
volatile uint32_t ievent;
|
|
||||||
|
|
||||||
ievent = mpc5200.ievent;
|
|
||||||
|
|
||||||
|
|
||||||
/* Frame received? */
|
/* Frame received? */
|
||||||
if(GET_SDMA_PENDINGBIT(FEC_RECV_TASK_NO))
|
if(GET_SDMA_PENDINGBIT(FEC_RECV_TASK_NO))
|
||||||
{
|
{
|
||||||
@@ -617,11 +688,6 @@ void mpc5200_smartcomm_rx_irq_handler(rtems_irq_hdl_param unused)
|
|||||||
*/
|
*/
|
||||||
void mpc5200_smartcomm_tx_irq_handler(rtems_irq_hdl_param unused)
|
void mpc5200_smartcomm_tx_irq_handler(rtems_irq_hdl_param unused)
|
||||||
{
|
{
|
||||||
volatile uint32_t ievent;
|
|
||||||
|
|
||||||
ievent = mpc5200.ievent;
|
|
||||||
|
|
||||||
|
|
||||||
/* Buffer transmitted or transmitter error? */
|
/* Buffer transmitted or transmitter error? */
|
||||||
if(GET_SDMA_PENDINGBIT(FEC_XMIT_TASK_NO))
|
if(GET_SDMA_PENDINGBIT(FEC_XMIT_TASK_NO))
|
||||||
{
|
{
|
||||||
@@ -652,7 +718,8 @@ void mpc5200_smartcomm_tx_irq_handler(rtems_irq_hdl_param unused)
|
|||||||
* Notes:
|
* Notes:
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void mpc5200_fec_retire_tbd(struct mpc5200_enet_struct *sc)
|
static void mpc5200_fec_retire_tbd(struct mpc5200_enet_struct *sc,
|
||||||
|
boolean force)
|
||||||
{
|
{
|
||||||
struct mbuf *n;
|
struct mbuf *n;
|
||||||
TaskBD1_t *bdRing = (TaskBD1_t *)TaskGetBDRing( txTaskId );;
|
TaskBD1_t *bdRing = (TaskBD1_t *)TaskGetBDRing( txTaskId );;
|
||||||
@@ -662,7 +729,7 @@ static void mpc5200_fec_retire_tbd(struct mpc5200_enet_struct *sc)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
while ((sc->txBdActiveCount > 0) &&
|
while ((sc->txBdActiveCount > 0) &&
|
||||||
(bdRing[sc->txBdTail].Status == 0x0)) {
|
(force || (bdRing[sc->txBdTail].Status == 0x0))) {
|
||||||
if (sc->txMbuf[sc->txBdTail] != NULL) {
|
if (sc->txMbuf[sc->txBdTail] != NULL) {
|
||||||
/*
|
/*
|
||||||
* NOTE: txMbuf can be NULL, if mbuf has been split into different BDs
|
* NOTE: txMbuf can be NULL, if mbuf has been split into different BDs
|
||||||
@@ -677,6 +744,37 @@ static void mpc5200_fec_retire_tbd(struct mpc5200_enet_struct *sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function: mpc5200_fec_tx_bd_requeue
|
||||||
|
*
|
||||||
|
* Description: put buffers back to interface output queue
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void mpc5200_fec_tx_bd_requeue(struct mpc5200_enet_struct *sc)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Clear already transmitted BDs first. Will not work calling same
|
||||||
|
* from fecExceptionHandler(TFINT).
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (sc->txBdActiveCount > 0) {
|
||||||
|
if (sc->txMbuf[sc->txBdHead] != NULL) {
|
||||||
|
/*
|
||||||
|
* NOTE: txMbuf can be NULL, if mbuf has been split into different BDs
|
||||||
|
*/
|
||||||
|
IF_PREPEND(&(sc->arpcom.ac_if.if_snd),sc->txMbuf[sc->txBdHead]);
|
||||||
|
sc->txMbuf[sc->txBdHead] = NULL;
|
||||||
|
}
|
||||||
|
sc->txBdActiveCount--;
|
||||||
|
if(--sc->txBdHead < 0) {
|
||||||
|
sc->txBdHead = sc->txBdCount-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void mpc5200_fec_sendpacket(struct ifnet *ifp,struct mbuf *m) {
|
static void mpc5200_fec_sendpacket(struct ifnet *ifp,struct mbuf *m) {
|
||||||
struct mpc5200_enet_struct *sc = ifp->if_softc;
|
struct mpc5200_enet_struct *sc = ifp->if_softc;
|
||||||
@@ -693,7 +791,7 @@ static void mpc5200_fec_sendpacket(struct ifnet *ifp,struct mbuf *m) {
|
|||||||
/*
|
/*
|
||||||
* Free up buffer descriptors
|
* Free up buffer descriptors
|
||||||
*/
|
*/
|
||||||
mpc5200_fec_retire_tbd(sc);
|
mpc5200_fec_retire_tbd(sc,FALSE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the transmit buffer descriptors.
|
* Set up the transmit buffer descriptors.
|
||||||
@@ -728,14 +826,14 @@ static void mpc5200_fec_sendpacket(struct ifnet *ifp,struct mbuf *m) {
|
|||||||
* last buffer descriptor in a frame can generate
|
* last buffer descriptor in a frame can generate
|
||||||
* an interrupt.
|
* an interrupt.
|
||||||
*/
|
*/
|
||||||
mpc5200_fec_retire_tbd(sc);
|
mpc5200_fec_retire_tbd(sc,FALSE);
|
||||||
|
|
||||||
while((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
|
while((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
|
||||||
bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO);
|
bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO);
|
||||||
rtems_bsdnet_event_receive(INTERRUPT_EVENT,
|
rtems_bsdnet_event_receive(INTERRUPT_EVENT,
|
||||||
RTEMS_WAIT | RTEMS_EVENT_ANY,
|
RTEMS_WAIT | RTEMS_EVENT_ANY,
|
||||||
RTEMS_NO_TIMEOUT, &events);
|
RTEMS_NO_TIMEOUT, &events);
|
||||||
mpc5200_fec_retire_tbd(sc);
|
mpc5200_fec_retire_tbd(sc,FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -821,11 +919,11 @@ void mpc5200_fec_txDaemon(void *arg)
|
|||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
rtems_event_set events;
|
rtems_event_set events;
|
||||||
|
|
||||||
for(;;)
|
for(;;) {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Wait for packet
|
* Wait for packet
|
||||||
*/
|
*/
|
||||||
|
bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO);
|
||||||
rtems_bsdnet_event_receive(START_TRANSMIT_EVENT|INTERRUPT_EVENT,
|
rtems_bsdnet_event_receive(START_TRANSMIT_EVENT|INTERRUPT_EVENT,
|
||||||
RTEMS_EVENT_ANY | RTEMS_WAIT,
|
RTEMS_EVENT_ANY | RTEMS_WAIT,
|
||||||
RTEMS_NO_TIMEOUT,
|
RTEMS_NO_TIMEOUT,
|
||||||
@@ -944,10 +1042,16 @@ static void mpc5200_fec_rxDaemon(void *arg){
|
|||||||
*/
|
*/
|
||||||
bestcomm_glue_irq_enable(FEC_RECV_TASK_NO);
|
bestcomm_glue_irq_enable(FEC_RECV_TASK_NO);
|
||||||
|
|
||||||
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
|
rtems_bsdnet_event_receive (INTERRUPT_EVENT | FATAL_INT_EVENT,
|
||||||
RTEMS_WAIT | RTEMS_EVENT_ANY,
|
RTEMS_WAIT | RTEMS_EVENT_ANY,
|
||||||
RTEMS_NO_TIMEOUT, &events);
|
RTEMS_NO_TIMEOUT, &events);
|
||||||
|
if (events & FATAL_INT_EVENT) {
|
||||||
|
/*
|
||||||
|
* fatal interrupt ocurred, so reinit fec and restart bestcomm tasks
|
||||||
|
*/
|
||||||
|
mpc5200_fec_restart(sc);
|
||||||
|
rxBdIndex = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -965,8 +1069,6 @@ static void mpc5200_fec_rxDaemon(void *arg){
|
|||||||
*/
|
*/
|
||||||
static void mpc5200_fec_initialize_hardware(struct mpc5200_enet_struct *sc)
|
static void mpc5200_fec_initialize_hardware(struct mpc5200_enet_struct *sc)
|
||||||
{
|
{
|
||||||
int timeout;
|
|
||||||
unsigned short phyAddr = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset mpc5200 FEC
|
* Reset mpc5200 FEC
|
||||||
@@ -981,17 +1083,7 @@ static void mpc5200_fec_initialize_hardware(struct mpc5200_enet_struct *sc)
|
|||||||
/*
|
/*
|
||||||
* Set interrupt mask register
|
* Set interrupt mask register
|
||||||
*/
|
*/
|
||||||
mpc5200.imask = (FEC_INTR_HBEEN
|
mpc5200.imask = FEC_INTR_MASK_USED;
|
||||||
| FEC_INTR_BREN
|
|
||||||
| FEC_INTR_BTEN
|
|
||||||
| FEC_INTR_GRAEN
|
|
||||||
| FEC_INTR_LATE_COL
|
|
||||||
| FEC_INTR_COL_RETRY
|
|
||||||
| FEC_INTR_XFIFO_UN
|
|
||||||
| FEC_INTR_XFIFO_ERR
|
|
||||||
| FEC_INTR_RFIFO_ERR
|
|
||||||
| FEC_INTR_TFINT
|
|
||||||
);
|
|
||||||
/*
|
/*
|
||||||
* Set FEC-Lite receive control register (R_CNTRL)
|
* Set FEC-Lite receive control register (R_CNTRL)
|
||||||
* frame length=1518, MII mode for 18-wire-transceiver
|
* frame length=1518, MII mode for 18-wire-transceiver
|
||||||
@@ -1054,6 +1146,7 @@ static void mpc5200_fec_initialize_hardware(struct mpc5200_enet_struct *sc)
|
|||||||
* enable CRC in finite state machine register
|
* enable CRC in finite state machine register
|
||||||
*/
|
*/
|
||||||
mpc5200.xmit_fsm = FEC_FSM_CRC | FEC_FSM_ENFSM;
|
mpc5200.xmit_fsm = FEC_FSM_CRC | FEC_FSM_ENFSM;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize PHY(LXT971A):
|
* Initialize PHY(LXT971A):
|
||||||
@@ -1075,7 +1168,16 @@ static void mpc5200_fec_initialize_hardware(struct mpc5200_enet_struct *sc)
|
|||||||
* Note:
|
* Note:
|
||||||
* The physical address is dependent on hardware configuration.
|
* The physical address is dependent on hardware configuration.
|
||||||
*
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
static void mpc5200_fec_initialize_phy(struct mpc5200_enet_struct *sc)
|
||||||
|
{
|
||||||
|
int timeout;
|
||||||
|
unsigned short phyAddr = 0;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset PHY, then delay 300ns
|
* Reset PHY, then delay 300ns
|
||||||
@@ -1180,14 +1282,14 @@ static void mpc5200_fec_tx_start(struct ifnet *ifp)
|
|||||||
/*
|
/*
|
||||||
* set up sdma tasks for ethernet
|
* set up sdma tasks for ethernet
|
||||||
*/
|
*/
|
||||||
static void mpc5200_sdma_task_setup(void) {
|
static void mpc5200_sdma_task_setup(struct mpc5200_enet_struct *sc) {
|
||||||
TaskSetupParamSet_t rxParam; /* RX task setup parameters */
|
TaskSetupParamSet_t rxParam; /* RX task setup parameters */
|
||||||
TaskSetupParamSet_t txParam; /* TX task setup parameters */
|
TaskSetupParamSet_t txParam; /* TX task setup parameters */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the SDMA RX task.
|
* Setup the SDMA RX task.
|
||||||
*/
|
*/
|
||||||
rxParam.NumBD = SDMA_BD_RX_NUM;
|
rxParam.NumBD = sc->rxBdCount;
|
||||||
rxParam.Size.MaxBuf = ETHER_MAX_LEN;
|
rxParam.Size.MaxBuf = ETHER_MAX_LEN;
|
||||||
rxParam.Initiator = 0;
|
rxParam.Initiator = 0;
|
||||||
rxParam.StartAddrSrc = (uint32)&(mpc5200.rfifo_data);
|
rxParam.StartAddrSrc = (uint32)&(mpc5200.rfifo_data);
|
||||||
@@ -1201,7 +1303,7 @@ static void mpc5200_sdma_task_setup(void) {
|
|||||||
/*
|
/*
|
||||||
* Setup the TX task.
|
* Setup the TX task.
|
||||||
*/
|
*/
|
||||||
txParam.NumBD = SDMA_BD_TX_NUM;
|
txParam.NumBD = sc->txBdCount;
|
||||||
txParam.Size.MaxBuf = ETHER_MAX_LEN;
|
txParam.Size.MaxBuf = ETHER_MAX_LEN;
|
||||||
txParam.Initiator = 0;
|
txParam.Initiator = 0;
|
||||||
txParam.StartAddrSrc = (uint32)NULL;
|
txParam.StartAddrSrc = (uint32)NULL;
|
||||||
@@ -1215,6 +1317,23 @@ static void mpc5200_sdma_task_setup(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mpc5200_fec_irq_on(const rtems_irq_connect_data* ptr)
|
||||||
|
{
|
||||||
|
mpc5200.imask = FEC_INTR_MASK_USED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int mpc5200_fec_irq_isOn(const rtems_irq_connect_data* ptr)
|
||||||
|
{
|
||||||
|
return mpc5200.imask != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mpc5200_fec_irq_off(const rtems_irq_connect_data* ptr)
|
||||||
|
{
|
||||||
|
mpc5200.imask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize and start the device
|
* Initialize and start the device
|
||||||
@@ -1223,6 +1342,15 @@ static void mpc5200_fec_init(void *arg)
|
|||||||
{
|
{
|
||||||
struct mpc5200_enet_struct *sc = (struct mpc5200_enet_struct *)arg;
|
struct mpc5200_enet_struct *sc = (struct mpc5200_enet_struct *)arg;
|
||||||
struct ifnet *ifp = &sc->arpcom.ac_if;
|
struct ifnet *ifp = &sc->arpcom.ac_if;
|
||||||
|
rtems_irq_connect_data fec_irq_data = {
|
||||||
|
BSP_SIU_IRQ_ETH,
|
||||||
|
mpc5200_fec_irq_handler, /* rtems_irq_hdl */
|
||||||
|
(rtems_irq_hdl_param)sc, /* (rtems_irq_hdl_param) */
|
||||||
|
mpc5200_fec_irq_on, /* (rtems_irq_enable) */
|
||||||
|
mpc5200_fec_irq_off, /* (rtems_irq_disable) */
|
||||||
|
mpc5200_fec_irq_isOn /* (rtems_irq_is_enabled) */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
if(sc->txDaemonTid == 0)
|
if(sc->txDaemonTid == 0)
|
||||||
{
|
{
|
||||||
@@ -1239,7 +1367,7 @@ static void mpc5200_fec_init(void *arg)
|
|||||||
|
|
||||||
bestcomm_glue_init();
|
bestcomm_glue_init();
|
||||||
|
|
||||||
mpc5200_sdma_task_setup();
|
mpc5200_sdma_task_setup(sc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up interrupts
|
* Set up interrupts
|
||||||
@@ -1250,6 +1378,10 @@ static void mpc5200_fec_init(void *arg)
|
|||||||
bestcomm_glue_irq_install(FEC_XMIT_TASK_NO,
|
bestcomm_glue_irq_install(FEC_XMIT_TASK_NO,
|
||||||
mpc5200_smartcomm_tx_irq_handler,
|
mpc5200_smartcomm_tx_irq_handler,
|
||||||
NULL);
|
NULL);
|
||||||
|
if(!BSP_install_rtems_irq_handler (&fec_irq_data)) {
|
||||||
|
rtems_panic ("Can't attach MPC5x00 FEX interrupt handler\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* mpc5200_fec_tx_bd_init(sc); */
|
/* mpc5200_fec_tx_bd_init(sc); */
|
||||||
mpc5200_fec_rx_bd_init(sc);
|
mpc5200_fec_rx_bd_init(sc);
|
||||||
|
|
||||||
@@ -1257,6 +1389,10 @@ static void mpc5200_fec_init(void *arg)
|
|||||||
* reset and Set up mpc5200 FEC hardware
|
* reset and Set up mpc5200 FEC hardware
|
||||||
*/
|
*/
|
||||||
mpc5200_fec_initialize_hardware(sc);
|
mpc5200_fec_initialize_hardware(sc);
|
||||||
|
/*
|
||||||
|
* Set up the phy
|
||||||
|
*/
|
||||||
|
mpc5200_fec_initialize_phy(sc);
|
||||||
/*
|
/*
|
||||||
* Set priority of different initiators
|
* Set priority of different initiators
|
||||||
*/
|
*/
|
||||||
@@ -1322,6 +1458,99 @@ static void enet_stats (struct mpc5200_enet_struct *sc)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* restart the driver, reinit the fec
|
||||||
|
* this function is responsible to reinitialize the FEC in case a fatal
|
||||||
|
* error has ocurred. This is needed, wen a RxFIFO Overrun or a TxFIFO underrun
|
||||||
|
* has ocurred. In these cases, the FEC is automatically disabled, and
|
||||||
|
* both FIFOs must be reset and the BestComm tasks must be restarted
|
||||||
|
*
|
||||||
|
* Note: the daemon tasks will continue to run
|
||||||
|
* (in fact this function will be called in the context of the rx daemon task)
|
||||||
|
*/
|
||||||
|
#define NEW_SDMA_SETUP
|
||||||
|
|
||||||
|
static void mpc5200_fec_restart(struct mpc5200_enet_struct *sc)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* FIXME: bring Tx Daemon into idle state
|
||||||
|
*/
|
||||||
|
#ifdef NEW_SDMA_SETUP
|
||||||
|
/*
|
||||||
|
* cleanup remaining receive mbufs
|
||||||
|
*/
|
||||||
|
mpc5200_fec_rx_bd_cleanup(sc);
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Stop SDMA tasks
|
||||||
|
*/
|
||||||
|
TaskStop( rxTaskId);
|
||||||
|
TaskStop( txTaskId);
|
||||||
|
/*
|
||||||
|
* FIXME: wait, until Tx Daemon is in idle state
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable transmit / receive interrupts
|
||||||
|
*/
|
||||||
|
bestcomm_glue_irq_disable(FEC_XMIT_TASK_NO);
|
||||||
|
bestcomm_glue_irq_disable(FEC_RECV_TASK_NO);
|
||||||
|
#ifdef NEW_SDMA_SETUP
|
||||||
|
/*
|
||||||
|
* recycle pending tx buffers
|
||||||
|
* FIXME: try to extract pending Tx buffers
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
mpc5200_fec_tx_bd_requeue(sc);
|
||||||
|
#else
|
||||||
|
mpc5200_fec_retire_tbd(sc,TRUE);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* re-initialize the FEC hardware
|
||||||
|
*/
|
||||||
|
mpc5200_fec_initialize_hardware(sc);
|
||||||
|
|
||||||
|
#ifdef NEW_SDMA_SETUP
|
||||||
|
/*
|
||||||
|
* completely reinitialize Bestcomm tasks
|
||||||
|
*/
|
||||||
|
mpc5200_sdma_task_setup(sc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reinit receive mbufs
|
||||||
|
*/
|
||||||
|
mpc5200_fec_rx_bd_init(sc);
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Clear SmartDMA task interrupt pending bits.
|
||||||
|
*/
|
||||||
|
TaskIntClear( rxTaskId );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable the SmartDMA receive/transmit task.
|
||||||
|
*/
|
||||||
|
TaskStart( rxTaskId, 1, rxTaskId, 1 );
|
||||||
|
TaskStart( txTaskId, 1, txTaskId, 1 );
|
||||||
|
/*
|
||||||
|
* reenable rx/tx interrupts
|
||||||
|
*/
|
||||||
|
bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO);
|
||||||
|
bestcomm_glue_irq_enable(FEC_RECV_TASK_NO);
|
||||||
|
/*
|
||||||
|
* (re-)init fec hardware
|
||||||
|
*/
|
||||||
|
mpc5200_fec_initialize_hardware(sc);
|
||||||
|
/*
|
||||||
|
* reenable fec FIFO error interrupts
|
||||||
|
*/
|
||||||
|
mpc5200.imask = FEC_INTR_MASK_USED;
|
||||||
|
/*
|
||||||
|
* Enable FEC-Lite controller
|
||||||
|
*/
|
||||||
|
mpc5200.ecntrl |= (FEC_ECNTRL_OE | FEC_ECNTRL_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Driver ioctl handler
|
* Driver ioctl handler
|
||||||
|
|||||||
@@ -77,9 +77,13 @@ $(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
|
|||||||
$(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT)
|
$(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT)
|
||||||
TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT)
|
TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT)
|
||||||
|
|
||||||
$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
|
$(PROJECT_LIB)/linkcmds.brs5l: startup/linkcmds.brs5l $(PROJECT_LIB)/$(dirstamp)
|
||||||
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
|
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.brs5l
|
||||||
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds
|
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.brs5l
|
||||||
|
|
||||||
|
$(PROJECT_LIB)/linkcmds.pm520: startup/linkcmds.pm520 $(PROJECT_LIB)/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.pm520
|
||||||
|
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.pm520
|
||||||
|
|
||||||
$(PROJECT_LIB)/linkcmds.pm520: startup/linkcmds.pm520 $(PROJECT_LIB)/$(dirstamp)
|
$(PROJECT_LIB)/linkcmds.pm520: startup/linkcmds.pm520 $(PROJECT_LIB)/$(dirstamp)
|
||||||
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.pm520
|
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.pm520
|
||||||
|
|||||||
@@ -111,8 +111,8 @@
|
|||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro LWI reg, value
|
.macro LWI reg, value
|
||||||
lis \reg , \value@h
|
lis \reg , (\value)@h
|
||||||
ori \reg , \reg, \value@l
|
ori \reg , \reg, (\value)@l
|
||||||
sync
|
sync
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@@ -286,7 +286,7 @@ start:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef RSM5LOG
|
#ifdef BRS5L
|
||||||
LWI r30, CSBOOTROM_VAL
|
LWI r30, CSBOOTROM_VAL
|
||||||
stw r30, CSBOOTROM(r31) /* Set CSBOOTROM */
|
stw r30, CSBOOTROM(r31) /* Set CSBOOTROM */
|
||||||
|
|
||||||
@@ -299,7 +299,9 @@ start:
|
|||||||
rlwinm r30, r30,17,15,31
|
rlwinm r30, r30,17,15,31
|
||||||
stw r30, CS0STR(r31) /* Set CS0STR */
|
stw r30, CS0STR(r31) /* Set CS0STR */
|
||||||
|
|
||||||
LWI r30, ROM_END
|
lis r30, ROM_END@h
|
||||||
|
ori r30, r30, ROM_END@l
|
||||||
|
|
||||||
rlwinm r30, r30,17,15,31
|
rlwinm r30, r30,17,15,31
|
||||||
stw r30, CS0STP(r31) /* Set CS0STP */
|
stw r30, CS0STP(r31) /* Set CS0STP */
|
||||||
|
|
||||||
@@ -327,7 +329,7 @@ reloc_in_CS0:
|
|||||||
ori r30,r30,0x1a /* size code: bank is 128MByte */
|
ori r30,r30,0x1a /* size code: bank is 128MByte */
|
||||||
stw r30,SDRAMCS0(r31) /* Set SDRAMCS0 */
|
stw r30,SDRAMCS0(r31) /* Set SDRAMCS0 */
|
||||||
|
|
||||||
LWI r30,(RAM_END+1-RAM_START)/2
|
LWI r30,(RAM_SIZE)>>1
|
||||||
ori r30,r30,0x1a /* size code: bank is 128MByte */
|
ori r30,r30,0x1a /* size code: bank is 128MByte */
|
||||||
stw r30, SDRAMCS1(r31) /* Set SDRAMCS1 */
|
stw r30, SDRAMCS1(r31) /* Set SDRAMCS1 */
|
||||||
|
|
||||||
@@ -441,12 +443,13 @@ skip_ROM_start:
|
|||||||
stw r30,ADREN(r31) /* enable CS1 */
|
stw r30,ADREN(r31) /* enable CS1 */
|
||||||
|
|
||||||
/* clear entire on chip SRAM (unique for ROM startup) */
|
/* clear entire on chip SRAM (unique for ROM startup) */
|
||||||
LWI r30, (MBAR+ONCHIP_SRAM_OFFSET) /* get start address of onchip SRAM */
|
lis r30, (MBAR+ONCHIP_SRAM_OFFSET)@h /* get start address of onchip SRAM */
|
||||||
|
ori r30,r30,(MBAR+ONCHIP_SRAM_OFFSET)@l
|
||||||
LWI r29, ONCHIP_SRAM_SIZE /* get size of onchip SRAM */
|
LWI r29, ONCHIP_SRAM_SIZE /* get size of onchip SRAM */
|
||||||
|
|
||||||
bl clr_mem /* Clear onchip SRAM */
|
bl clr_mem /* Clear onchip SRAM */
|
||||||
|
|
||||||
#endif /* defined(RSM5LOG) */
|
#endif /* defined(BRS5L) */
|
||||||
/* clear .bss section (unique for ROM startup) */
|
/* clear .bss section (unique for ROM startup) */
|
||||||
LWI r30, _bss_start /* get start address of bss section */
|
LWI r30, _bss_start /* get start address of bss section */
|
||||||
LWI r29, _bss_size /* get size of bss section */
|
LWI r29, _bss_size /* get size of bss section */
|
||||||
@@ -522,7 +525,7 @@ SDRAM_init:
|
|||||||
LWI r30, 0xCCC70004 /* Burst2Read Prec.delay=0x8, Burst Write delay=0x8 */
|
LWI r30, 0xCCC70004 /* Burst2Read Prec.delay=0x8, Burst Write delay=0x8 */
|
||||||
stw r30, CFG2(r31) /* Burst Read2Write delay=0xB, Burst length=0x7, Read Tap=0x4 */
|
stw r30, CFG2(r31) /* Burst Read2Write delay=0xB, Burst length=0x7, Read Tap=0x4 */
|
||||||
|
|
||||||
#ifdef RSM5LOG
|
#ifdef BRS5L
|
||||||
LWI r30, 0xD1470000 /* Mode Set enabled, Clock enabled, Auto refresh enabled, Mem. data drv */
|
LWI r30, 0xD1470000 /* Mode Set enabled, Clock enabled, Auto refresh enabled, Mem. data drv */
|
||||||
stw r30, CTRL(r31) /* Refresh counter=0xFFFF */
|
stw r30, CTRL(r31) /* Refresh counter=0xFFFF */
|
||||||
|
|
||||||
@@ -608,7 +611,7 @@ copy_image_byte:
|
|||||||
|
|
||||||
copy_image_end:
|
copy_image_end:
|
||||||
blr
|
blr
|
||||||
#endif /* defined(RSM5LOG) */
|
#endif /* defined(BRS5L) */
|
||||||
|
|
||||||
FID_DCache:
|
FID_DCache:
|
||||||
mflr r26
|
mflr r26
|
||||||
@@ -740,10 +743,6 @@ FPU_init:
|
|||||||
mtfsfi 6, 0
|
mtfsfi 6, 0
|
||||||
mtfsfi 7, 0
|
mtfsfi 7, 0
|
||||||
|
|
||||||
|
|
||||||
CLRBITS r30, r29, MSR_FP /* disable FPU and FPU exceptions */
|
|
||||||
mtmsr r30
|
|
||||||
|
|
||||||
blr
|
blr
|
||||||
|
|
||||||
SPRG_init: /* initialize registers */
|
SPRG_init: /* initialize registers */
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ pcf8563_get_time(int minor, rtems_time_of_day *time)
|
|||||||
v1 = info[PCF8563_DAY_ADR-PCF8563_SECOND_ADR] & PCF8563_DAY_MASK;
|
v1 = info[PCF8563_DAY_ADR-PCF8563_SECOND_ADR] & PCF8563_DAY_MASK;
|
||||||
time->day = From_BCD(v1);
|
time->day = From_BCD(v1);
|
||||||
|
|
||||||
v1 = info[PCF8563_HOUR_ADR-PCF8563_SECOND_ADR] & PCF8563_HOUR_ADR;
|
v1 = info[PCF8563_HOUR_ADR-PCF8563_SECOND_ADR] & PCF8563_HOUR_MASK;
|
||||||
time->hour = From_BCD(v1);
|
time->hour = From_BCD(v1);
|
||||||
|
|
||||||
v1 = info[PCF8563_MINUTE_ADR-PCF8563_SECOND_ADR] & PCF8563_MINUTE_MASK;
|
v1 = info[PCF8563_MINUTE_ADR-PCF8563_SECOND_ADR] & PCF8563_MINUTE_MASK;
|
||||||
@@ -211,7 +211,7 @@ pcf8563_set_time(int minor, rtems_time_of_day *time)
|
|||||||
*/
|
*/
|
||||||
try = 0;
|
try = 0;
|
||||||
do {
|
do {
|
||||||
status = i2c_write(bus, addr, info, 8);
|
status = i2c_write(bus, addr, info,sizeof(info));
|
||||||
try++;
|
try++;
|
||||||
} while ((status != I2C_SUCCESSFUL) && (try < 10));
|
} while ((status != I2C_SUCCESSFUL) && (try < 10));
|
||||||
|
|
||||||
|
|||||||
@@ -1012,6 +1012,7 @@ ata_initialize(rtems_device_major_number major,
|
|||||||
char name[ATA_MAX_NAME_LENGTH];
|
char name[ATA_MAX_NAME_LENGTH];
|
||||||
dev_t device;
|
dev_t device;
|
||||||
ata_int_st_t *int_st;
|
ata_int_st_t *int_st;
|
||||||
|
|
||||||
#if defined(ATA_USE_OLD_EXCEPTIONS)
|
#if defined(ATA_USE_OLD_EXCEPTIONS)
|
||||||
rtems_isr_entry old_isr;
|
rtems_isr_entry old_isr;
|
||||||
#else
|
#else
|
||||||
@@ -1045,7 +1046,9 @@ ata_initialize(rtems_device_major_number major,
|
|||||||
*/
|
*/
|
||||||
status = rtems_task_create(
|
status = rtems_task_create(
|
||||||
rtems_build_name ('A', 'T', 'A', 'T'),
|
rtems_build_name ('A', 'T', 'A', 'T'),
|
||||||
ATA_DRIVER_TASK_PRIORITY,
|
((ata_driver_task_priority > 0)
|
||||||
|
? ata_driver_task_priority
|
||||||
|
: ATA_DRIVER_TASK_DEFAULT_PRIORITY),
|
||||||
ATA_DRIVER_TASK_STACK_SIZE,
|
ATA_DRIVER_TASK_STACK_SIZE,
|
||||||
RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_ASR |
|
RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_ASR |
|
||||||
RTEMS_INTERRUPT_LEVEL(0),
|
RTEMS_INTERRUPT_LEVEL(0),
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ rtems_device_driver ata_initialize(
|
|||||||
* FIXME: should be configured more easy...
|
* FIXME: should be configured more easy...
|
||||||
*/
|
*/
|
||||||
#define ATA_DRIVER_MESSAGE_QUEUE_SIZE 50
|
#define ATA_DRIVER_MESSAGE_QUEUE_SIZE 50
|
||||||
#define ATA_DRIVER_TASK_PRIORITY 140
|
|
||||||
#define ATA_DRIVER_TASK_STACK_SIZE 16*1024
|
#define ATA_DRIVER_TASK_STACK_SIZE 16*1024
|
||||||
|
#define ATA_DRIVER_TASK_DEFAULT_PRIORITY 140
|
||||||
|
extern rtems_task_priority ata_driver_task_priority;
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -91,6 +91,9 @@ typedef struct rtems_bdbuf_config {
|
|||||||
extern rtems_bdbuf_config rtems_bdbuf_configuration[];
|
extern rtems_bdbuf_config rtems_bdbuf_configuration[];
|
||||||
extern int rtems_bdbuf_configuration_size;
|
extern int rtems_bdbuf_configuration_size;
|
||||||
|
|
||||||
|
#define SWAPOUT_TASK_DEFAULT_PRIORITY 15
|
||||||
|
extern rtems_task_priority swapout_task_priority;
|
||||||
|
|
||||||
/* rtems_bdbuf_init --
|
/* rtems_bdbuf_init --
|
||||||
* Prepare buffering layer to work - initialize buffer descritors
|
* Prepare buffering layer to work - initialize buffer descritors
|
||||||
* and (if it is neccessary) buffers. Buffers will be allocated accoriding
|
* and (if it is neccessary) buffers. Buffers will be allocated accoriding
|
||||||
|
|||||||
@@ -28,8 +28,7 @@
|
|||||||
#define BLKDEV_FATAL_BDBUF_SWAPOUT BLKDEV_FATAL_ERROR(2)
|
#define BLKDEV_FATAL_BDBUF_SWAPOUT BLKDEV_FATAL_ERROR(2)
|
||||||
|
|
||||||
|
|
||||||
#define SWAPOUT_PRIORITY 15
|
#define SWAPOUT_TASK_STACK_SIZE (RTEMS_MINIMUM_STACK_SIZE * 2)
|
||||||
#define SWAPOUT_STACK_SIZE (RTEMS_MINIMUM_STACK_SIZE * 2)
|
|
||||||
|
|
||||||
#define READ_MULTIPLE
|
#define READ_MULTIPLE
|
||||||
|
|
||||||
@@ -864,8 +863,10 @@ rtems_bdbuf_init(rtems_bdbuf_config *conf_table, int size)
|
|||||||
/* Create and start swapout task */
|
/* Create and start swapout task */
|
||||||
rc = rtems_task_create(
|
rc = rtems_task_create(
|
||||||
rtems_build_name('B', 'S', 'W', 'P'),
|
rtems_build_name('B', 'S', 'W', 'P'),
|
||||||
SWAPOUT_PRIORITY,
|
((swapout_task_priority > 0)
|
||||||
SWAPOUT_STACK_SIZE,
|
? swapout_task_priority
|
||||||
|
: SWAPOUT_TASK_DEFAULT_PRIORITY),
|
||||||
|
SWAPOUT_TASK_STACK_SIZE,
|
||||||
RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
|
RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
|
||||||
RTEMS_DEFAULT_ATTRIBUTES,
|
RTEMS_DEFAULT_ATTRIBUTES,
|
||||||
&bd_ctx.swapout_task);
|
&bd_ctx.swapout_task);
|
||||||
|
|||||||
@@ -116,6 +116,7 @@
|
|||||||
#define __pure
|
#define __pure
|
||||||
#define __pure2
|
#define __pure2
|
||||||
#define __unused
|
#define __unused
|
||||||
|
#define __used
|
||||||
#define __attribute__(x)
|
#define __attribute__(x)
|
||||||
#endif
|
#endif
|
||||||
#if __GNUC__ == 2 && __GNUC_MINOR__ < 5
|
#if __GNUC__ == 2 && __GNUC_MINOR__ < 5
|
||||||
@@ -124,6 +125,7 @@
|
|||||||
#define __pure __const
|
#define __pure __const
|
||||||
#define __pure2
|
#define __pure2
|
||||||
#define __unused
|
#define __unused
|
||||||
|
#define __used
|
||||||
#endif
|
#endif
|
||||||
#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7
|
#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7
|
||||||
#define __dead
|
#define __dead
|
||||||
@@ -131,6 +133,7 @@
|
|||||||
#define __pure
|
#define __pure
|
||||||
#define __pure2 __attribute__((__const__))
|
#define __pure2 __attribute__((__const__))
|
||||||
#define __unused
|
#define __unused
|
||||||
|
#define __used
|
||||||
#endif
|
#endif
|
||||||
#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ >= 3
|
#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ >= 3
|
||||||
#define __dead
|
#define __dead
|
||||||
@@ -138,6 +141,7 @@
|
|||||||
#define __pure
|
#define __pure
|
||||||
#define __pure2 __attribute__((__const__))
|
#define __pure2 __attribute__((__const__))
|
||||||
#define __unused __attribute__((__unused__))
|
#define __unused __attribute__((__unused__))
|
||||||
|
#define __used __attribute__((__used__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|||||||
@@ -80,7 +80,15 @@ typedef struct {
|
|||||||
* max_filesize with blocks of 512 is 1,082,195,456
|
* max_filesize with blocks of 512 is 1,082,195,456
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define IMFS_MEMFILE_BYTES_PER_BLOCK 128
|
#define IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK 128
|
||||||
|
extern int imfs_rq_memfile_bytes_per_block;
|
||||||
|
/*
|
||||||
|
* FIXME: make and use derivates from this,
|
||||||
|
* a shift count and a mask
|
||||||
|
*/
|
||||||
|
extern int imfs_memfile_bytes_per_block;
|
||||||
|
|
||||||
|
#define IMFS_MEMFILE_BYTES_PER_BLOCK imfs_memfile_bytes_per_block
|
||||||
#define IMFS_MEMFILE_BLOCK_SLOTS \
|
#define IMFS_MEMFILE_BLOCK_SLOTS \
|
||||||
(IMFS_MEMFILE_BYTES_PER_BLOCK / sizeof(void *))
|
(IMFS_MEMFILE_BYTES_PER_BLOCK / sizeof(void *))
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,37 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IMFS_determine_bytes_per_block
|
||||||
|
*/
|
||||||
|
int imfs_memfile_bytes_per_block = 0;
|
||||||
|
|
||||||
|
static int IMFS_determine_bytes_per_block(
|
||||||
|
int *dest_bytes_per_block,
|
||||||
|
int requested_bytes_per_block,
|
||||||
|
int default_bytes_per_block
|
||||||
|
)
|
||||||
|
{
|
||||||
|
rtems_boolean is_valid = FALSE;
|
||||||
|
int bit_mask;
|
||||||
|
/*
|
||||||
|
* check, whether requested bytes per block is valid
|
||||||
|
*/
|
||||||
|
for (bit_mask = 16;
|
||||||
|
!is_valid && (bit_mask <= 512);
|
||||||
|
bit_mask <<= 1) {
|
||||||
|
if (bit_mask == requested_bytes_per_block) {
|
||||||
|
is_valid = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*dest_bytes_per_block = ((is_valid)
|
||||||
|
? requested_bytes_per_block
|
||||||
|
: default_bytes_per_block);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IMFS_initialize
|
* IMFS_initialize
|
||||||
*/
|
*/
|
||||||
@@ -44,6 +75,13 @@ int IMFS_initialize_support(
|
|||||||
IMFS_fs_info_t *fs_info;
|
IMFS_fs_info_t *fs_info;
|
||||||
IMFS_jnode_t *jnode;
|
IMFS_jnode_t *jnode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* determine/check value for imfs_memfile_bytes_per_block
|
||||||
|
*/
|
||||||
|
IMFS_determine_bytes_per_block(&imfs_memfile_bytes_per_block,
|
||||||
|
imfs_rq_memfile_bytes_per_block,
|
||||||
|
IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the root node
|
* Create the root node
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -543,6 +543,15 @@ rtems_task shell_shell(rtems_task_argument task_argument) {
|
|||||||
rtems_current_user_env->euid=
|
rtems_current_user_env->euid=
|
||||||
rtems_current_user_env->egid=0;
|
rtems_current_user_env->egid=0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* newlib delays the creation of default stdio 'til the
|
||||||
|
* first I/O operation, therefore we must perform dummy
|
||||||
|
* operations before we redirect stdio
|
||||||
|
*/
|
||||||
|
ftell(stdin);
|
||||||
|
ftell(stdout);
|
||||||
|
ftell(stderr);
|
||||||
|
|
||||||
stdin =fopen(devname,"r+");
|
stdin =fopen(devname,"r+");
|
||||||
|
|
||||||
if (!stdin) {
|
if (!stdin) {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
* Kernel variables for tcp.
|
* Kernel variables for tcp.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef __BSD_VISIBLE
|
||||||
/*
|
/*
|
||||||
* Tcp control block, one per tcp; fields:
|
* Tcp control block, one per tcp; fields:
|
||||||
*/
|
*/
|
||||||
@@ -196,6 +197,7 @@ struct rmxp_tao {
|
|||||||
#define intotcpcb(ip) ((struct tcpcb *)(ip)->inp_ppcb)
|
#define intotcpcb(ip) ((struct tcpcb *)(ip)->inp_ppcb)
|
||||||
#define intotw(ip) ((struct tcptw *)(ip)->inp_ppcb)
|
#define intotw(ip) ((struct tcptw *)(ip)->inp_ppcb)
|
||||||
#define sototcpcb(so) (intotcpcb(sotoinpcb(so)))
|
#define sototcpcb(so) (intotcpcb(sotoinpcb(so)))
|
||||||
|
#endif /* __BSD_VISIBLE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The smoothed round-trip time and estimated variance
|
* The smoothed round-trip time and estimated variance
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define __MAKE_SET(set, sym) \
|
#define __MAKE_SET(set, sym) \
|
||||||
static void const * const __set_##set##_sym_##sym \
|
static void const * const __set_##set##_sym_##sym \
|
||||||
__attribute((section("set_" #set))) __unused = &sym
|
__attribute((section("set_" #set))) __used = &sym
|
||||||
#else /* !__GNUC__ */
|
#else /* !__GNUC__ */
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#error "This file needs to be compiled by GCC or lint"
|
#error "This file needs to be compiled by GCC or lint"
|
||||||
|
|||||||
@@ -123,8 +123,15 @@ extern int rtems_telnetd_maximum_ptys;
|
|||||||
|
|
||||||
#include <rtems/imfs.h>
|
#include <rtems/imfs.h>
|
||||||
|
|
||||||
|
#ifndef CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK
|
||||||
|
#define CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK \
|
||||||
|
IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK
|
||||||
|
#endif
|
||||||
#ifdef CONFIGURE_INIT
|
#ifdef CONFIGURE_INIT
|
||||||
|
int imfs_rq_memfile_bytes_per_block = CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK;
|
||||||
|
#endif /* CONFIGURE_INIT */
|
||||||
|
|
||||||
|
#ifdef CONFIGURE_INIT
|
||||||
#ifndef CONFIGURE_HAS_OWN_MOUNT_TABLE
|
#ifndef CONFIGURE_HAS_OWN_MOUNT_TABLE
|
||||||
rtems_filesystem_mount_table_t configuration_mount_table = {
|
rtems_filesystem_mount_table_t configuration_mount_table = {
|
||||||
#ifdef CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
|
#ifdef CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
|
||||||
@@ -296,6 +303,18 @@ rtems_initialization_tasks_table Initialization_tasks[] = {
|
|||||||
#include <rtems/devnull.h>
|
#include <rtems/devnull.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER
|
||||||
|
/* the ide driver needs the ATA driver */
|
||||||
|
# ifndef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
|
||||||
|
# define CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
|
||||||
|
# endif
|
||||||
|
#include <libchip/ide_ctrl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
|
||||||
|
#include <libchip/ata.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE
|
#ifndef CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE
|
||||||
|
|
||||||
#ifdef CONFIGURE_INIT
|
#ifdef CONFIGURE_INIT
|
||||||
@@ -312,12 +331,20 @@ rtems_driver_address_table Device_drivers[] = {
|
|||||||
#ifdef CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
|
#ifdef CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
|
||||||
DEVNULL_DRIVER_TABLE_ENTRY,
|
DEVNULL_DRIVER_TABLE_ENTRY,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER
|
||||||
|
IDE_CONTROLLER_DRIVER_TABLE_ENTRY,
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
|
||||||
|
ATA_DRIVER_TABLE_ENTRY,
|
||||||
|
#endif
|
||||||
#ifdef CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER
|
#ifdef CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER
|
||||||
NULL_DRIVER_TABLE_ENTRY
|
NULL_DRIVER_TABLE_ENTRY
|
||||||
#elif !defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) && \
|
#elif !defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) && \
|
||||||
!defined(CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER) && \
|
!defined(CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER) && \
|
||||||
!defined(CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER) && \
|
!defined(CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER) && \
|
||||||
!defined(CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER)
|
!defined(CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER) && \
|
||||||
|
!defined(CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER) && \
|
||||||
|
!defined(CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER)
|
||||||
NULL_DRIVER_TABLE_ENTRY
|
NULL_DRIVER_TABLE_ENTRY
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -346,6 +373,52 @@ rtems_driver_address_table Device_drivers[] = {
|
|||||||
#define CONFIGURE_MAXIMUM_DEVICES 20
|
#define CONFIGURE_MAXIMUM_DEVICES 20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
|
||||||
|
/*
|
||||||
|
* configure the priority of the ATA driver task
|
||||||
|
*/
|
||||||
|
# ifndef CONFIGURE_ATA_DRIVER_TASK_PRIORITY
|
||||||
|
# define CONFIGURE_ATA_DRIVER_TASK_PRIORITY ATA_DRIVER_TASK_DEFAULT_PRIORITY
|
||||||
|
# endif
|
||||||
|
# ifdef CONFIGURE_INIT
|
||||||
|
rtems_task_priority ata_driver_task_priority
|
||||||
|
= CONFIGURE_ATA_DRIVER_TASK_PRIORITY;
|
||||||
|
# endif /* CONFIGURE_INIT */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add bdbuf configuration and values for swapout task priority
|
||||||
|
*/
|
||||||
|
#ifdef CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
|
||||||
|
#include <rtems/bdbuf.h>
|
||||||
|
/*
|
||||||
|
* configure the priority of the bdbuf swapout task
|
||||||
|
*/
|
||||||
|
#ifndef CONFIGURE_SWAPOUT_TASK_PRIORITY
|
||||||
|
#define CONFIGURE_SWAPOUT_TASK_PRIORITY SWAPOUT_TASK_DEFAULT_PRIORITY
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIGURE_INIT
|
||||||
|
rtems_task_priority swapout_task_priority
|
||||||
|
= CONFIGURE_SWAPOUT_TASK_PRIORITY;
|
||||||
|
#endif /* CONFIGURE_INIT */
|
||||||
|
#ifndef CONFIGURE_HAS_OWN_BDBUF_TABLE
|
||||||
|
|
||||||
|
#ifndef CONFIGURE_BDBUF_BUFFER_COUNT
|
||||||
|
#define CONFIGURE_BDBUF_BUFFER_COUNT 64
|
||||||
|
#endif /* CONFIGURE_BDBUF_BUFFER_COUNT */
|
||||||
|
|
||||||
|
#ifndef CONFIGURE_BDBUF_BUFFER_SIZE
|
||||||
|
#define CONFIGURE_BDBUF_BUFFER_SIZE 512
|
||||||
|
#endif /* CONFIGURE_BDBUF_BUFFER_SIZE */
|
||||||
|
#ifdef CONFIGURE_INIT
|
||||||
|
rtems_bdbuf_config rtems_bdbuf_configuration[] = {
|
||||||
|
{CONFIGURE_BDBUF_BUFFER_SIZE,CONFIGURE_BDBUF_BUFFER_COUNT,NULL}
|
||||||
|
};
|
||||||
|
int rtems_bdbuf_configuration_size =( sizeof(rtems_bdbuf_configuration)
|
||||||
|
/sizeof(rtems_bdbuf_configuration[0]));
|
||||||
|
#endif /* CONFIGURE_INIT */
|
||||||
|
#endif /* CONFIGURE_HAS_OWN_BDBUF_TABLE */
|
||||||
|
#endif /* CONFIGURE_APPLICATION_NEEDS_LIBBLOCK */
|
||||||
/*
|
/*
|
||||||
* Default Multiprocessing Configuration Table. The defaults are
|
* Default Multiprocessing Configuration Table. The defaults are
|
||||||
* appropriate for most of the RTEMS Multiprocessor Test Suite. Each
|
* appropriate for most of the RTEMS Multiprocessor Test Suite. Each
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ CPU_CFLAGS = -mcpu=603e -mstrict-align -Dmpc8260
|
|||||||
# optimize flag: typically -0, could use -O4 or -fast
|
# optimize flag: typically -0, could use -O4 or -fast
|
||||||
# -O4 is ok for RTEMS
|
# -O4 is ok for RTEMS
|
||||||
# NOTE: some level of -O may be actually required by inline assembler
|
# NOTE: some level of -O may be actually required by inline assembler
|
||||||
CFLAGS_OPTIMIZE_V=-O4 -fno-keep-inline-functions
|
CFLAGS_OPTIMIZE_V=-O4 -fno-keep-inline-functions -g
|
||||||
|
|
||||||
# The following are definitions of make-exe which will work using ld as
|
# The following are definitions of make-exe which will work using ld as
|
||||||
# is currently required. It is expected that as of gcc 2.8, the end user
|
# is currently required. It is expected that as of gcc 2.8, the end user
|
||||||
|
|||||||
@@ -32,31 +32,10 @@ rtems_task Init(
|
|||||||
|
|
||||||
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
||||||
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
|
||||||
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
|
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
|
||||||
|
|
||||||
#define CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE
|
|
||||||
|
|
||||||
#ifdef CONFIGURE_INIT
|
|
||||||
rtems_driver_address_table Device_drivers[] =
|
|
||||||
{
|
|
||||||
CONSOLE_DRIVER_TABLE_ENTRY
|
|
||||||
,CLOCK_DRIVER_TABLE_ENTRY
|
|
||||||
#ifdef RTEMS_BSP_HAS_IDE_DRIVER
|
|
||||||
,IDE_CONTROLLER_DRIVER_TABLE_ENTRY
|
|
||||||
/* important: ATA driver must be after ide drivers */
|
|
||||||
,ATA_DRIVER_TABLE_ENTRY
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#include <rtems/bdbuf.h>
|
|
||||||
rtems_bdbuf_config rtems_bdbuf_configuration[] = {
|
|
||||||
{512,128,NULL}
|
|
||||||
};
|
|
||||||
int rtems_bdbuf_configuration_size =( sizeof(rtems_bdbuf_configuration)
|
|
||||||
/sizeof(rtems_bdbuf_configuration[0]));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX: these values are higher than needed...
|
* XXX: these values are higher than needed...
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user