mcf5206 libcpu and mcf5206elite: Fix warnings

This commit is contained in:
Joel Sherrill
2014-10-15 18:34:36 -05:00
parent 46dad9d465
commit a94fb39198
9 changed files with 1089 additions and 1203 deletions

View File

@@ -1,6 +1,8 @@
/* /*
* Console driver for Motorola MCF5206E UART modules * Console driver for Motorola MCF5206E UART modules
* */
/*
* Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
* Author: Victor V. Vengerov <vvv@oktet.ru> * Author: Victor V. Vengerov <vvv@oktet.ru>
* *
@@ -46,7 +48,7 @@ int console_mode = 2;
static int static int
console_poll_read(int minor) console_poll_read(int minor)
{ {
return mcfuart_poll_read(&uart[minor]); return mcfuart_poll_read(&uart[minor]);
} }
/* console_interrupt_write -- /* console_interrupt_write --
@@ -63,7 +65,7 @@ console_poll_read(int minor)
static ssize_t static ssize_t
console_interrupt_write(int minor, const char *buf, size_t len) console_interrupt_write(int minor, const char *buf, size_t len)
{ {
return mcfuart_interrupt_write(&uart[minor], buf, len); return mcfuart_interrupt_write(&uart[minor], buf, len);
} }
/* console_poll_write -- /* console_poll_write --
@@ -80,7 +82,7 @@ console_interrupt_write(int minor, const char *buf, size_t len)
static ssize_t static ssize_t
console_poll_write(int minor, const char *buf, size_t len) console_poll_write(int minor, const char *buf, size_t len)
{ {
return mcfuart_poll_write(&uart[minor], buf, len); return mcfuart_poll_write(&uart[minor], buf, len);
} }
/* console_set_attributes -- /* console_set_attributes --
@@ -96,7 +98,7 @@ console_poll_write(int minor, const char *buf, size_t len)
static int static int
console_set_attributes(int minor, const struct termios *t) console_set_attributes(int minor, const struct termios *t)
{ {
return mcfuart_set_attributes(&uart[minor], t); return mcfuart_set_attributes(&uart[minor], t);
} }
/* console_stop_remote_tx -- /* console_stop_remote_tx --
@@ -111,10 +113,10 @@ console_set_attributes(int minor, const struct termios *t)
static int static int
console_stop_remote_tx(int minor) console_stop_remote_tx(int minor)
{ {
if (minor < sizeof(uart)/sizeof(uart[0])) if (minor < sizeof(uart)/sizeof(uart[0]))
return mcfuart_stop_remote_tx(&uart[minor]); return mcfuart_stop_remote_tx(&uart[minor]);
else else
return RTEMS_INVALID_NUMBER; return RTEMS_INVALID_NUMBER;
} }
/* console_start_remote_tx -- /* console_start_remote_tx --
@@ -127,10 +129,10 @@ console_stop_remote_tx(int minor)
static int static int
console_start_remote_tx(int minor) console_start_remote_tx(int minor)
{ {
if (minor < sizeof(uart)/sizeof(uart[0])) if (minor < sizeof(uart)/sizeof(uart[0]))
return mcfuart_start_remote_tx(&uart[minor]); return mcfuart_start_remote_tx(&uart[minor]);
else else
return RTEMS_INVALID_NUMBER; return RTEMS_INVALID_NUMBER;
} }
/* console_first_open -- /* console_first_open --
@@ -147,32 +149,31 @@ console_start_remote_tx(int minor)
static int static int
console_first_open(int major, int minor, void *arg) console_first_open(int major, int minor, void *arg)
{ {
rtems_libio_open_close_args_t *args = arg; rtems_libio_open_close_args_t *args = arg;
rtems_status_code sc; rtems_status_code sc;
uint8_t intvec; uint8_t intvec;
switch (minor) switch (minor) {
{ case 0: intvec = BSP_INTVEC_UART1; break;
case 0: intvec = BSP_INTVEC_UART1; break; case 1: intvec = BSP_INTVEC_UART2; break;
case 1: intvec = BSP_INTVEC_UART2; break; default:
default: return RTEMS_INVALID_NUMBER;
return RTEMS_INVALID_NUMBER; }
}
if (console_mode != CONSOLE_MODE_INT) if (console_mode != CONSOLE_MODE_INT) {
{ intvec = 0;
intvec = 0; }
}
sc = mcfuart_init(&uart[minor], /* uart */ sc = mcfuart_init(
args->iop->data1, /* tty */ &uart[minor], /* uart */
intvec, /* interrupt vector number */ args->iop->data1, /* tty */
minor+1); intvec, /* interrupt vector number */
minor+1);
if (sc == RTEMS_SUCCESSFUL) if (sc == RTEMS_SUCCESSFUL)
sc = mcfuart_reset(&uart[minor]); sc = mcfuart_reset(&uart[minor]);
return sc; return sc;
} }
/* console_last_close -- /* console_last_close --
@@ -189,7 +190,7 @@ console_first_open(int major, int minor, void *arg)
static int static int
console_last_close(int major, int minor, void *arg) console_last_close(int major, int minor, void *arg)
{ {
return mcfuart_disable(&uart[minor]); return mcfuart_disable(&uart[minor]);
} }
/* console_initialize -- /* console_initialize --
@@ -204,51 +205,51 @@ console_last_close(int major, int minor, void *arg)
* RETURNS: * RETURNS:
* RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly) * RTEMS error code (RTEMS_SUCCESSFUL if device initialized successfuly)
*/ */
rtems_device_driver rtems_device_driver console_initialize(
console_initialize(rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *arg) void *arg)
{ {
rtems_status_code status; rtems_status_code status;
/* /*
* Set up TERMIOS * Set up TERMIOS
*/ */
if (console_mode != CONSOLE_MODE_RAW) if (console_mode != CONSOLE_MODE_RAW)
rtems_termios_initialize (); rtems_termios_initialize ();
/* /*
* Register the devices * Register the devices
*/ */
status = rtems_io_register_name ("/dev/console", major, 0); status = rtems_io_register_name ("/dev/console", major, 0);
if (status != RTEMS_SUCCESSFUL) if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status); rtems_fatal_error_occurred (status);
status = rtems_io_register_name ("/dev/aux", major, 1);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
if (console_mode == CONSOLE_MODE_RAW) status = rtems_io_register_name ("/dev/aux", major, 1);
{ if (status != RTEMS_SUCCESSFUL)
rtems_status_code sc; rtems_fatal_error_occurred (status);
sc = mcfuart_init(&uart[0], /* uart */
NULL, /* tty */
0, /* interrupt vector number */
1); /* UART channel number */
if (sc == RTEMS_SUCCESSFUL) if (console_mode == CONSOLE_MODE_RAW) {
sc = mcfuart_reset(&uart[0]); rtems_status_code sc;
sc = mcfuart_init(&uart[0], /* uart */
NULL, /* tty */
0, /* interrupt vector number */
1); /* UART channel number */
sc = mcfuart_init(&uart[1], /* uart */ if (sc == RTEMS_SUCCESSFUL)
NULL, /* tty */ sc = mcfuart_reset(&uart[0]);
0, /* interrupt vector number */
2); /* UART channel number */
if (sc == RTEMS_SUCCESSFUL) sc = mcfuart_init(&uart[1], /* uart */
sc = mcfuart_reset(&uart[1]); NULL, /* tty */
return sc; 0, /* interrupt vector number */
} 2); /* UART channel number */
return RTEMS_SUCCESSFUL; if (sc == RTEMS_SUCCESSFUL)
sc = mcfuart_reset(&uart[1]);
return sc;
}
return RTEMS_SUCCESSFUL;
} }
/* console_open -- /* console_open --
@@ -268,42 +269,41 @@ console_open(rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *arg) void *arg)
{ {
static const rtems_termios_callbacks intr_callbacks = { static const rtems_termios_callbacks intr_callbacks = {
console_first_open, /* firstOpen */ console_first_open, /* firstOpen */
console_last_close, /* lastClose */ console_last_close, /* lastClose */
NULL, /* pollRead */ NULL, /* pollRead */
console_interrupt_write, /* write */ console_interrupt_write, /* write */
console_set_attributes, /* setAttributes */ console_set_attributes, /* setAttributes */
console_stop_remote_tx, /* stopRemoteTx */ console_stop_remote_tx, /* stopRemoteTx */
console_start_remote_tx, /* startRemoteTx */ console_start_remote_tx, /* startRemoteTx */
1 /* outputUsesInterrupts */ 1 /* outputUsesInterrupts */
}; };
static const rtems_termios_callbacks poll_callbacks = { static const rtems_termios_callbacks poll_callbacks = {
console_first_open, /* firstOpen */ console_first_open, /* firstOpen */
console_last_close, /* lastClose */ console_last_close, /* lastClose */
console_poll_read, /* pollRead */ console_poll_read, /* pollRead */
console_poll_write, /* write */ console_poll_write, /* write */
console_set_attributes, /* setAttributes */ console_set_attributes, /* setAttributes */
console_stop_remote_tx, /* stopRemoteTx */ console_stop_remote_tx, /* stopRemoteTx */
console_start_remote_tx, /* startRemoteTx */ console_start_remote_tx, /* startRemoteTx */
0 /* outputUsesInterrupts */ 0 /* outputUsesInterrupts */
}; };
switch (console_mode) switch (console_mode) {
{ case CONSOLE_MODE_RAW:
case CONSOLE_MODE_RAW: return RTEMS_SUCCESSFUL;
return RTEMS_SUCCESSFUL;
case CONSOLE_MODE_INT: case CONSOLE_MODE_INT:
return rtems_termios_open(major, minor, arg, &intr_callbacks); return rtems_termios_open(major, minor, arg, &intr_callbacks);
case CONSOLE_MODE_POLL: case CONSOLE_MODE_POLL:
return rtems_termios_open(major, minor, arg, &poll_callbacks); return rtems_termios_open(major, minor, arg, &poll_callbacks);
default: default:
rtems_fatal_error_occurred(0xC07A1310); rtems_fatal_error_occurred(0xC07A1310);
} }
return RTEMS_INTERNAL_ERROR; return RTEMS_INTERNAL_ERROR;
} }
/* console_close -- /* console_close --
@@ -322,10 +322,10 @@ console_close(rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *arg) void *arg)
{ {
if (console_mode != CONSOLE_MODE_RAW) if (console_mode != CONSOLE_MODE_RAW)
return rtems_termios_close (arg); return rtems_termios_close (arg);
else else
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
/* console_read -- /* console_read --
@@ -344,32 +344,29 @@ console_read(rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *arg) void *arg)
{ {
if (console_mode != CONSOLE_MODE_RAW) if (console_mode != CONSOLE_MODE_RAW) {
{ return rtems_termios_read (arg);
return rtems_termios_read (arg); } else {
} rtems_libio_rw_args_t *argp = arg;
else char *buf = argp->buffer;
{ int count = argp->count;
rtems_libio_rw_args_t *argp = arg; int n = 0;
char *buf = argp->buffer; int c;
int count = argp->count;
int n = 0; while (n < count) {
int c; do {
while (n < count) c = mcfuart_poll_read(&uart[minor]);
{ } while (c == -1);
do { if (c == '\r')
c = mcfuart_poll_read(&uart[minor]); c = '\n';
} while (c == -1); *(buf++) = c;
if (c == '\r') n++;
c = '\n'; if (c == '\n')
*(buf++) = c; break;
n++;
if (c == '\n')
break;
}
argp->bytes_moved = n;
return RTEMS_SUCCESSFUL;
} }
argp->bytes_moved = n;
return RTEMS_SUCCESSFUL;
}
} }
/* console_write -- /* console_write --
@@ -389,27 +386,24 @@ console_write(rtems_device_major_number major,
void *arg void *arg
) )
{ {
if (console_mode != CONSOLE_MODE_RAW) if (console_mode != CONSOLE_MODE_RAW) {
{ return rtems_termios_write (arg);
return rtems_termios_write (arg); } else {
} rtems_libio_rw_args_t *argp = arg;
else char cr = '\r';
{ char *buf = argp->buffer;
rtems_libio_rw_args_t *argp = arg; int count = argp->count;
char cr = '\r'; int i;
char *buf = argp->buffer;
int count = argp->count; for (i = 0; i < count; i++) {
int i; if (*buf == '\n')
for (i = 0; i < count; i++) mcfuart_poll_write(&uart[minor], &cr, 1);
{ mcfuart_poll_write(&uart[minor], buf, 1);
if (*buf == '\n') buf++;
mcfuart_poll_write(&uart[minor], &cr, 1);
mcfuart_poll_write(&uart[minor], buf, 1);
buf++;
}
argp->bytes_moved = count;
return RTEMS_SUCCESSFUL;
} }
argp->bytes_moved = count;
return RTEMS_SUCCESSFUL;
}
} }
/* console_control -- /* console_control --
@@ -428,12 +422,9 @@ console_control(rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *arg) void *arg)
{ {
if (console_mode != CONSOLE_MODE_RAW) if (console_mode != CONSOLE_MODE_RAW) {
{ return rtems_termios_ioctl (arg);
return rtems_termios_ioctl (arg); } else {
} return RTEMS_SUCCESSFUL;
else }
{
return RTEMS_SUCCESSFUL;
}
} }

View File

@@ -173,6 +173,11 @@ rtems_isr_entry set_vector(
int type int type
); );
/*
* Prototypes for BSP methods that cross file boundaries
*/
void Init5206e(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -5,7 +5,9 @@
* The name of this entry point is compiler dependent. * The name of this entry point is compiler dependent.
* It jumps to the BSP which is responsible for performing * It jumps to the BSP which is responsible for performing
* all initialization. * all initialization.
* */
/*
* Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
* Author: Victor V. Vengerov <vvv@oktet.ru> * Author: Victor V. Vengerov <vvv@oktet.ru>
* *

View File

@@ -8,7 +8,9 @@
* This initialization code based on hardware settings of dBUG * This initialization code based on hardware settings of dBUG
* monitor. This must be changed if you like to run it immediately * monitor. This must be changed if you like to run it immediately
* after reset. * after reset.
* */
/*
* Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
* Author: Victor V. Vengerov <vvv@oktet.ru> * Author: Victor V. Vengerov <vvv@oktet.ru>
* *
@@ -53,180 +55,172 @@ extern void INTERRUPT_VECTOR(void);
"nop\n\t" \ "nop\n\t" \
: : "d" (MCF5206E_CACR_CINV) ) : : "d" (MCF5206E_CACR_CINV) )
/* Init5206e -- /*
* Initialize MCF5206e on-chip modules * Initialize MCF5206e on-chip modules
*
* PARAMETERS:
* none
*
* RETURNS:
* none
*/ */
void void Init5206e(void)
Init5206e(void)
{ {
/* Set Module Base Address register */
m68k_set_mbar((MBAR & MCF5206E_MBAR_BA) | MCF5206E_MBAR_V);
/* Set Module Base Address register */ /* Set System Protection Control Register (SYPCR):
m68k_set_mbar((MBAR & MCF5206E_MBAR_BA) | MCF5206E_MBAR_V); * Bus Monitor Enable, Bus Monitor Timing = 1024 clocks,
* Software watchdog disabled
*/
*MCF5206E_SYPCR(MBAR) = MCF5206E_SYPCR_BME |
MCF5206E_SYPCR_BMT_1024;
/* Set System Protection Control Register (SYPCR): /* Set Pin Assignment Register (PAR):
* Bus Monitor Enable, Bus Monitor Timing = 1024 clocks, * Output Timer 0 (not DREQ) on *TOUT[0] / *DREQ[1]
* Software watchdog disabled * Input Timer 0 (not DREQ) on *TIN[0] / *DREQ[0]
*/ * IRQ, not IPL
*MCF5206E_SYPCR(MBAR) = MCF5206E_SYPCR_BME | * UART2 RTS signal (not \RSTO)
MCF5206E_SYPCR_BMT_1024; * PST/DDATA (not PPIO)
* *WE (not CS/A)
*/
*MCF5206E_PAR(MBAR) = MCF5206E_PAR_PAR9_TOUT |
MCF5206E_PAR_PAR8_TIN0 |
MCF5206E_PAR_PAR7_UART2 |
MCF5206E_PAR_PAR6_IRQ |
MCF5206E_PAR_PAR5_PST |
MCF5206E_PAR_PAR4_DDATA |
MCF5206E_PAR_WE0_WE1_WE2_WE3;
/* Set Pin Assignment Register (PAR): /* Set SIM Configuration Register (SIMR):
* Output Timer 0 (not DREQ) on *TOUT[0] / *DREQ[1] * Disable software watchdog timer and bus timeout monitor when
* Input Timer 0 (not DREQ) on *TIN[0] / *DREQ[0] * internal freeze signal is asserted.
* IRQ, not IPL */
* UART2 RTS signal (not \RSTO) *MCF5206E_SIMR(MBAR) = MCF5206E_SIMR_FRZ0 | MCF5206E_SIMR_FRZ1;
* PST/DDATA (not PPIO)
* *WE (not CS/A)
*/
*MCF5206E_PAR(MBAR) = MCF5206E_PAR_PAR9_TOUT |
MCF5206E_PAR_PAR8_TIN0 |
MCF5206E_PAR_PAR7_UART2 |
MCF5206E_PAR_PAR6_IRQ |
MCF5206E_PAR_PAR5_PST |
MCF5206E_PAR_PAR4_DDATA |
MCF5206E_PAR_WE0_WE1_WE2_WE3;
/* Set SIM Configuration Register (SIMR): /* Set Interrupt Mask Register: Disable all interrupts */
* Disable software watchdog timer and bus timeout monitor when *MCF5206E_IMR(MBAR) = 0xFFFF;
* internal freeze signal is asserted.
*/
*MCF5206E_SIMR(MBAR) = MCF5206E_SIMR_FRZ0 | MCF5206E_SIMR_FRZ1;
/* Set Interrupt Mask Register: Disable all interrupts */ /* Assign Interrupt Control Registers as it is defined in bsp.h */
*MCF5206E_IMR(MBAR) = 0xFFFF; *MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL1) =
(BSP_INTLVL_AVEC1 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC1 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL2) =
(BSP_INTLVL_AVEC2 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC2 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL3) =
(BSP_INTLVL_AVEC3 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC3 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL4) =
(BSP_INTLVL_AVEC4 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC4 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL5) =
(BSP_INTLVL_AVEC5 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC5 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL6) =
(BSP_INTLVL_AVEC6 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC6 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL7) =
(BSP_INTLVL_AVEC7 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC7 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_TIMER_1) =
(BSP_INTLVL_TIMER1 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_TIMER1 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_TIMER_2) =
(BSP_INTLVL_TIMER2 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_TIMER2 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_MBUS) =
(BSP_INTLVL_MBUS << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_MBUS << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_UART_1) =
(BSP_INTLVL_UART1 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_UART1 << MCF5206E_ICR_IP_S);
*MCF5206E_ICR(MBAR,MCF5206E_INTR_UART_2) =
(BSP_INTLVL_UART2 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_UART2 << MCF5206E_ICR_IP_S);
*MCF5206E_ICR(MBAR,MCF5206E_INTR_DMA_0) =
(BSP_INTLVL_DMA0 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_DMA0 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_DMA_1) =
(BSP_INTLVL_DMA1 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_DMA1 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
/* Assign Interrupt Control Registers as it is defined in bsp.h */ /* Software Watchdog timer (not used now) */
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL1) = *MCF5206E_SWIVR(MBAR) = 0x0F; /* Uninitialized interrupt */
(BSP_INTLVL_AVEC1 << MCF5206E_ICR_IL_S) | *MCF5206E_SWSR(MBAR) = MCF5206E_SWSR_KEY1;
(BSP_INTPRIO_AVEC1 << MCF5206E_ICR_IP_S) | *MCF5206E_SWSR(MBAR) = MCF5206E_SWSR_KEY2;
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL2) =
(BSP_INTLVL_AVEC2 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC2 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL3) =
(BSP_INTLVL_AVEC3 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC3 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL4) =
(BSP_INTLVL_AVEC4 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC4 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL5) =
(BSP_INTLVL_AVEC5 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC5 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL6) =
(BSP_INTLVL_AVEC6 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC6 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_EXT_IPL7) =
(BSP_INTLVL_AVEC7 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_AVEC7 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_TIMER_1) =
(BSP_INTLVL_TIMER1 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_TIMER1 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_TIMER_2) =
(BSP_INTLVL_TIMER2 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_TIMER2 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_MBUS) =
(BSP_INTLVL_MBUS << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_MBUS << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_UART_1) =
(BSP_INTLVL_UART1 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_UART1 << MCF5206E_ICR_IP_S);
*MCF5206E_ICR(MBAR,MCF5206E_INTR_UART_2) =
(BSP_INTLVL_UART2 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_UART2 << MCF5206E_ICR_IP_S);
*MCF5206E_ICR(MBAR,MCF5206E_INTR_DMA_0) =
(BSP_INTLVL_DMA0 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_DMA0 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
*MCF5206E_ICR(MBAR,MCF5206E_INTR_DMA_1) =
(BSP_INTLVL_DMA1 << MCF5206E_ICR_IL_S) |
(BSP_INTPRIO_DMA1 << MCF5206E_ICR_IP_S) |
MCF5206E_ICR_AVEC;
/* Software Watchdog timer (not used now) */ /* Configuring Chip Selects */
*MCF5206E_SWIVR(MBAR) = 0x0F; /* Uninitialized interrupt */ /* CS2: SRAM memory */
*MCF5206E_SWSR(MBAR) = MCF5206E_SWSR_KEY1; *MCF5206E_CSAR(MBAR,2) = BSP_MEM_ADDR_ESRAM >> 16;
*MCF5206E_SWSR(MBAR) = MCF5206E_SWSR_KEY2; *MCF5206E_CSMR(MBAR,2) = BSP_MEM_MASK_ESRAM;
*MCF5206E_CSCR(MBAR,2) = MCF5206E_CSCR_WS1 |
MCF5206E_CSCR_PS_32 |
MCF5206E_CSCR_AA |
MCF5206E_CSCR_EMAA |
MCF5206E_CSCR_WR |
MCF5206E_CSCR_RD;
/* Configuring Chip Selects */ /* CS3: GPIO on eLITE board */
/* CS2: SRAM memory */ *MCF5206E_CSAR(MBAR,3) = BSP_MEM_ADDR_GPIO >> 16;
*MCF5206E_CSAR(MBAR,2) = BSP_MEM_ADDR_ESRAM >> 16; *MCF5206E_CSMR(MBAR,3) = BSP_MEM_MASK_GPIO;
*MCF5206E_CSMR(MBAR,2) = BSP_MEM_MASK_ESRAM; *MCF5206E_CSCR(MBAR,3) = MCF5206E_CSCR_WS15 |
*MCF5206E_CSCR(MBAR,2) = MCF5206E_CSCR_WS1 | MCF5206E_CSCR_PS_16 |
MCF5206E_CSCR_PS_32 | MCF5206E_CSCR_AA |
MCF5206E_CSCR_AA | MCF5206E_CSCR_EMAA |
MCF5206E_CSCR_EMAA | MCF5206E_CSCR_WR |
MCF5206E_CSCR_WR | MCF5206E_CSCR_RD;
MCF5206E_CSCR_RD;
/* CS3: GPIO on eLITE board */ {
*MCF5206E_CSAR(MBAR,3) = BSP_MEM_ADDR_GPIO >> 16; uint32_t *inttab = (uint32_t*)&INTERRUPT_VECTOR;
*MCF5206E_CSMR(MBAR,3) = BSP_MEM_MASK_GPIO; uint32_t *intvec = (uint32_t*)BSP_MEM_ADDR_ESRAM;
*MCF5206E_CSCR(MBAR,3) = MCF5206E_CSCR_WS15 | register int i;
MCF5206E_CSCR_PS_16 |
MCF5206E_CSCR_AA |
MCF5206E_CSCR_EMAA |
MCF5206E_CSCR_WR |
MCF5206E_CSCR_RD;
{ for (i = 0; i < 256; i++) {
uint32_t *inttab = (uint32_t*)&INTERRUPT_VECTOR; *(intvec++) = *(inttab++);
uint32_t *intvec = (uint32_t*)BSP_MEM_ADDR_ESRAM;
register int i;
for (i = 0; i < 256; i++)
{
*(intvec++) = *(inttab++);
}
} }
m68k_set_vbr(BSP_MEM_ADDR_ESRAM); }
m68k_set_vbr(BSP_MEM_ADDR_ESRAM);
/* CS0: Flash EEPROM */ /* CS0: Flash EEPROM */
*MCF5206E_CSAR(MBAR,0) = BSP_MEM_ADDR_FLASH >> 16; *MCF5206E_CSAR(MBAR,0) = BSP_MEM_ADDR_FLASH >> 16;
*MCF5206E_CSCR(MBAR,0) = MCF5206E_CSCR_WS3 | *MCF5206E_CSCR(MBAR,0) = MCF5206E_CSCR_WS3 |
MCF5206E_CSCR_AA | MCF5206E_CSCR_AA |
MCF5206E_CSCR_PS_16 | MCF5206E_CSCR_PS_16 |
MCF5206E_CSCR_EMAA | MCF5206E_CSCR_EMAA |
MCF5206E_CSCR_WR | MCF5206E_CSCR_WR |
MCF5206E_CSCR_RD; MCF5206E_CSCR_RD;
*MCF5206E_CSMR(MBAR,0) = BSP_MEM_MASK_FLASH; *MCF5206E_CSMR(MBAR,0) = BSP_MEM_MASK_FLASH;
/* /*
* Invalidate the cache and disable it * Invalidate the cache and disable it
*/ */
mcf5206e_disable_cache(); mcf5206e_disable_cache();
/* /*
* Setup ACRs so that if cache turned on, periphal accesses * Setup ACRs so that if cache turned on, periphal accesses
* are not messed up. (Non-cacheable, serialized) * are not messed up. (Non-cacheable, serialized)
*/ */
m68k_set_acr0 ( 0 m68k_set_acr0 ( 0
| MCF5206E_ACR_BASE(BSP_MEM_ADDR_ESRAM) | MCF5206E_ACR_BASE(BSP_MEM_ADDR_ESRAM)
| MCF5206E_ACR_MASK(BSP_MEM_MASK_ESRAM) | MCF5206E_ACR_MASK(BSP_MEM_MASK_ESRAM)
| MCF5206E_ACR_EN | MCF5206E_ACR_EN
| MCF5206E_ACR_SM_ANY | MCF5206E_ACR_SM_ANY
); );
m68k_set_acr1 ( 0 m68k_set_acr1 ( 0
| MCF5206E_ACR_BASE(BSP_MEM_ADDR_FLASH) | MCF5206E_ACR_BASE(BSP_MEM_ADDR_FLASH)
| MCF5206E_ACR_MASK(BSP_MEM_MASK_FLASH) | MCF5206E_ACR_MASK(BSP_MEM_MASK_FLASH)
| MCF5206E_ACR_EN | MCF5206E_ACR_EN
| MCF5206E_ACR_SM_ANY | MCF5206E_ACR_SM_ANY
); );
mcf5206e_enable_cache(); mcf5206e_enable_cache();
/* /*
* Copy data, clear BSS, switch stacks and call boot_card() * Copy data, clear BSS, switch stacks and call boot_card()

View File

@@ -16,13 +16,14 @@
* *
* + two digit years 00-87 are mapped to 2000-2087 * + two digit years 00-87 are mapped to 2000-2087
* + two digit years 88-99 are mapped to 1988-1999 * + two digit years 88-99 are mapped to 1988-1999
* */
/*
* Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
* Author: Victor V. Vengerov <vvv@oktet.ru> * Author: Victor V. Vengerov <vvv@oktet.ru>
* *
* The license and distribution terms for this file may be * The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at * found in the file LICENSE in this distribution or at
*
* http://www.rtems.org/license/LICENSE. * http://www.rtems.org/license/LICENSE.
*/ */
@@ -43,36 +44,34 @@
* PARAMETERS: * PARAMETERS:
* minor -- minor RTC device number * minor -- minor RTC device number
*/ */
void static void ds1307_initialize(int minor)
ds1307_initialize(int minor)
{ {
i2c_message_status status; i2c_message_status status;
int try; int try;
uint8_t sec; uint8_t sec;
i2c_bus_number bus; i2c_bus_number bus;
i2c_address addr; i2c_address addr;
bus = RTC_Table[minor].ulCtrlPort1; bus = RTC_Table[minor].ulCtrlPort1;
addr = RTC_Table[minor].ulDataPort; addr = RTC_Table[minor].ulDataPort;
/* Read SECONDS register */ /* Read SECONDS register */
try = 0; try = 0;
do { do {
status = i2c_wbrd(bus, addr, 0, &sec, sizeof(sec)); status = i2c_wbrd(bus, addr, 0, &sec, sizeof(sec));
try++; try++;
} while ((status != I2C_SUCCESSFUL) && (try < 15)); } while ((status != I2C_SUCCESSFUL) && (try < 15));
/* If clock is halted, reset and start the clock */ /* If clock is halted, reset and start the clock */
if ((sec & DS1307_SECOND_HALT) != 0) if ((sec & DS1307_SECOND_HALT) != 0) {
{ uint8_t start[8];
uint8_t start[8]; memset(start, 0, sizeof(start));
memset(start, 0, sizeof(start)); start[0] = DS1307_SECOND;
start[0] = DS1307_SECOND; try = 0;
try = 0; do {
do { status = i2c_write(bus, addr, start, 2);
status = i2c_write(bus, addr, start, 2); } while ((status != I2C_SUCCESSFUL) && (try < 15));
} while ((status != I2C_SUCCESSFUL) && (try < 15)); }
}
} }
/* ds1307_get_time -- /* ds1307_get_time --
@@ -87,74 +86,66 @@ ds1307_initialize(int minor)
* 0, if time obtained successfully * 0, if time obtained successfully
* -1, if error occured * -1, if error occured
*/ */
int static int ds1307_get_time(int minor, rtems_time_of_day *time)
ds1307_get_time(int minor, rtems_time_of_day *time)
{ {
i2c_bus_number bus; i2c_bus_number bus;
i2c_address addr; i2c_address addr;
uint8_t info[8]; uint8_t info[8];
uint32_t v1, v2; uint32_t v1, v2;
i2c_message_status status; i2c_message_status status;
int try; int try;
if (time == NULL) if (time == NULL)
return -1; return -1;
bus = RTC_Table[minor].ulCtrlPort1; bus = RTC_Table[minor].ulCtrlPort1;
addr = RTC_Table[minor].ulDataPort; addr = RTC_Table[minor].ulDataPort;
memset(time, 0, sizeof(rtems_time_of_day)); memset(time, 0, sizeof(rtems_time_of_day));
try = 0; try = 0;
do { do {
status = i2c_wbrd(bus, addr, 0, info, sizeof(info)); status = i2c_wbrd(bus, addr, 0, info, sizeof(info));
try++; try++;
} while ((status != I2C_SUCCESSFUL) && (try < 10)); } while ((status != I2C_SUCCESSFUL) && (try < 10));
if (status != I2C_SUCCESSFUL) if (status != I2C_SUCCESSFUL) {
{ return -1;
return -1; }
v1 = info[DS1307_YEAR];
v2 = From_BCD(v1);
if (v2 < 88)
time->year = 2000 + v2;
else
time->year = 1900 + v2;
v1 = info[DS1307_MONTH] & ~0xE0;
time->month = From_BCD(v1);
v1 = info[DS1307_DAY] & ~0xC0;
time->day = From_BCD(v1);
v1 = info[DS1307_HOUR];
if (v1 & DS1307_HOUR_12) {
v2 = v1 & ~0xE0;
if (v1 & DS1307_HOUR_PM) {
time->hour = From_BCD(v2) + 12;
} else {
time->hour = From_BCD(v2);
} }
} else {
v2 = v1 & ~0xC0;
time->hour = From_BCD(v2);
}
v1 = info[DS1307_YEAR]; v1 = info[DS1307_MINUTE] & ~0x80;
v2 = From_BCD(v1); time->minute = From_BCD(v1);
if (v2 < 88)
time->year = 2000 + v2;
else
time->year = 1900 + v2;
v1 = info[DS1307_MONTH] & ~0xE0; v1 = info[DS1307_SECOND];
time->month = From_BCD(v1); v2 = v1 & ~0x80;
time->second = From_BCD(v2);
v1 = info[DS1307_DAY] & ~0xC0; return 0;
time->day = From_BCD(v1);
v1 = info[DS1307_HOUR];
if (v1 & DS1307_HOUR_12)
{
v2 = v1 & ~0xE0;
if (v1 & DS1307_HOUR_PM)
{
time->hour = From_BCD(v2) + 12;
}
else
{
time->hour = From_BCD(v2);
}
}
else
{
v2 = v1 & ~0xC0;
time->hour = From_BCD(v2);
}
v1 = info[DS1307_MINUTE] & ~0x80;
time->minute = From_BCD(v1);
v1 = info[DS1307_SECOND];
v2 = v1 & ~0x80;
time->second = From_BCD(v2);
return 0;
} }
/* ds1307_set_time -- /* ds1307_set_time --
@@ -168,49 +159,48 @@ ds1307_get_time(int minor, rtems_time_of_day *time)
* 0, if time obtained successfully * 0, if time obtained successfully
* -1, if error occured * -1, if error occured
*/ */
int static int ds1307_set_time(int minor, const rtems_time_of_day *time)
ds1307_set_time(int minor, const rtems_time_of_day *time)
{ {
i2c_bus_number bus; i2c_bus_number bus;
i2c_address addr; i2c_address addr;
uint8_t info[8]; uint8_t info[8];
i2c_message_status status; i2c_message_status status;
int try; int try;
if (time == NULL) if (time == NULL)
return -1; return -1;
bus = RTC_Table[minor].ulCtrlPort1; bus = RTC_Table[minor].ulCtrlPort1;
addr = RTC_Table[minor].ulDataPort; addr = RTC_Table[minor].ulDataPort;
if (time->year >= 2088) if (time->year >= 2088)
rtems_fatal_error_occurred(RTEMS_INVALID_NUMBER); rtems_fatal_error_occurred(RTEMS_INVALID_NUMBER);
info[0] = DS1307_SECOND; info[0] = DS1307_SECOND;
info[1 + DS1307_YEAR] = To_BCD(time->year % 100); info[1 + DS1307_YEAR] = To_BCD(time->year % 100);
info[1 + DS1307_MONTH] = To_BCD(time->month); info[1 + DS1307_MONTH] = To_BCD(time->month);
info[1 + DS1307_DAY] = To_BCD(time->day); info[1 + DS1307_DAY] = To_BCD(time->day);
info[1 + DS1307_HOUR] = To_BCD(time->hour); info[1 + DS1307_HOUR] = To_BCD(time->hour);
info[1 + DS1307_MINUTE] = To_BCD(time->minute); info[1 + DS1307_MINUTE] = To_BCD(time->minute);
info[1 + DS1307_SECOND] = To_BCD(time->second); info[1 + DS1307_SECOND] = To_BCD(time->second);
info[1 + DS1307_DAY_OF_WEEK] = 1; /* Do not set day of week */ info[1 + DS1307_DAY_OF_WEEK] = 1; /* Do not set day of week */
try = 0; try = 0;
do { do {
status = i2c_write(bus, addr, info, 8); status = i2c_write(bus, addr, info, 8);
try++; try++;
} while ((status != I2C_SUCCESSFUL) && (try < 10)); } while ((status != I2C_SUCCESSFUL) && (try < 10));
if (status != I2C_SUCCESSFUL) if (status != I2C_SUCCESSFUL)
return -1; return -1;
else else
return 0; return 0;
} }
/* Driver function table */ /* Driver function table */
rtc_fns ds1307_fns = { rtc_fns ds1307_fns = {
ds1307_initialize, ds1307_initialize,
ds1307_get_time, ds1307_get_time,
ds1307_set_time ds1307_set_time
}; };

View File

@@ -1,6 +1,8 @@
/* /*
* Generic UART Serial driver for Motorola Coldfire processors * Generic UART Serial driver for Motorola Coldfire processors
* */
/*
* Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russian Fed. * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russian Fed.
* Author: Victor V. Vengerov <vvv@oktet.ru> * Author: Victor V. Vengerov <vvv@oktet.ru>
* *
@@ -10,7 +12,6 @@
* The license and distribution terms for this file may be * The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at * found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE. * http://www.rtems.org/license/LICENSE.
*
*/ */
#include <rtems.h> #include <rtems.h>
@@ -23,8 +24,8 @@
* UART descriptor structures * UART descriptor structures
*/ */
static struct { static struct {
mcfuart *uart; mcfuart *uart;
int vec; int vec;
} int_driven_uart[2]; } int_driven_uart[2];
/* Forward function declarations */ /* Forward function declarations */
@@ -48,20 +49,24 @@ mcfuart_interrupt_handler(rtems_vector_number vec);
* RTEMS_SUCCESSFUL if all parameters are valid, or error code * RTEMS_SUCCESSFUL if all parameters are valid, or error code
*/ */
rtems_status_code rtems_status_code
mcfuart_init(mcfuart *uart, void *tty, uint8_t intvec, mcfuart_init(
uint32_t chn) mcfuart *uart,
void *tty,
uint8_t intvec,
uint32_t chn
)
{ {
if (uart == NULL) if (uart == NULL)
return RTEMS_INVALID_ADDRESS; return RTEMS_INVALID_ADDRESS;
if ((chn <= 0) || (chn > MCF5206E_UART_CHANNELS)) if ((chn <= 0) || (chn > MCF5206E_UART_CHANNELS))
return RTEMS_INVALID_NUMBER; return RTEMS_INVALID_NUMBER;
uart->chn = chn; uart->chn = chn;
uart->intvec = intvec; uart->intvec = intvec;
uart->tty = tty; uart->tty = tty;
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
/* mcfuart_set_baudrate -- /* mcfuart_set_baudrate --
@@ -77,38 +82,38 @@ mcfuart_init(mcfuart *uart, void *tty, uint8_t intvec,
static void static void
mcfuart_set_baudrate(mcfuart *uart, speed_t baud) mcfuart_set_baudrate(mcfuart *uart, speed_t baud)
{ {
uint32_t div; uint32_t div;
uint32_t rate; uint32_t rate;
switch (baud)
{ switch (baud) {
case B50: rate = 50; break; case B50: rate = 50; break;
case B75: rate = 75; break; case B75: rate = 75; break;
case B110: rate = 110; break; case B110: rate = 110; break;
case B134: rate = 134; break; case B134: rate = 134; break;
case B150: rate = 150; break; case B150: rate = 150; break;
case B200: rate = 200; break; case B200: rate = 200; break;
case B300: rate = 300; break; case B300: rate = 300; break;
case B600: rate = 600; break; case B600: rate = 600; break;
case B1200: rate = 1200; break; case B1200: rate = 1200; break;
case B2400: rate = 2400; break; case B2400: rate = 2400; break;
case B4800: rate = 4800; break; case B4800: rate = 4800; break;
case B9600: rate = 9600; break; case B9600: rate = 9600; break;
case B19200: rate = 19200; break; case B19200: rate = 19200; break;
case B38400: rate = 38400; break; case B38400: rate = 38400; break;
case B57600: rate = 57600; break; case B57600: rate = 57600; break;
#ifdef B115200 #ifdef B115200
case B115200: rate = 115200; break; case B115200: rate = 115200; break;
#endif #endif
#ifdef B230400 #ifdef B230400
case B230400: rate = 230400; break; case B230400: rate = 230400; break;
#endif #endif
default: rate = 9600; break; default: rate = 9600; break;
} }
div = SYSTEM_CLOCK_FREQUENCY / (rate * 32); div = SYSTEM_CLOCK_FREQUENCY / (rate * 32);
*MCF5206E_UBG1(MBAR,uart->chn) = (uint8_t)((div >> 8) & 0xff); *MCF5206E_UBG1(MBAR,uart->chn) = (uint8_t)((div >> 8) & 0xff);
*MCF5206E_UBG2(MBAR,uart->chn) = (uint8_t)(div & 0xff); *MCF5206E_UBG2(MBAR,uart->chn) = (uint8_t)(div & 0xff);
} }
/* /*
@@ -128,69 +133,64 @@ mcfuart_set_baudrate(mcfuart *uart, speed_t baud)
* This function in general follows to algorith described in MCF5206e * This function in general follows to algorith described in MCF5206e
* User's Manual, 12.5 UART Module Initialization Sequence * User's Manual, 12.5 UART Module Initialization Sequence
*/ */
rtems_status_code rtems_status_code mcfuart_reset(mcfuart *uart)
mcfuart_reset(mcfuart *uart)
{ {
register uint32_t chn; register uint32_t chn;
rtems_status_code rc; rtems_status_code rc;
if (uart == NULL) if (uart == NULL)
return RTEMS_INVALID_ADDRESS; return RTEMS_INVALID_ADDRESS;
chn = uart->chn; chn = uart->chn;
/* Reset the receiver and transmitter */ /* Reset the receiver and transmitter */
*MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_RX; *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_RX;
*MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_TX; *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_TX;
/* /*
* Program the vector number for a UART module interrupt, or * Program the vector number for a UART module interrupt, or
* disable UART interrupts if polled I/O. Enable the desired * disable UART interrupts if polled I/O. Enable the desired
* interrupt sources. * interrupt sources.
*/ */
if (uart->intvec != 0) if (uart->intvec != 0) {
{ int_driven_uart[chn - 1].uart = uart;
int_driven_uart[chn - 1].uart = uart; int_driven_uart[chn - 1].vec = uart->intvec;
int_driven_uart[chn - 1].vec = uart->intvec; rc = rtems_interrupt_catch(mcfuart_interrupt_handler, uart->intvec,
rc = rtems_interrupt_catch(mcfuart_interrupt_handler, uart->intvec, &uart->old_handler);
&uart->old_handler); if (rc != RTEMS_SUCCESSFUL)
if (rc != RTEMS_SUCCESSFUL) return rc;
return rc; *MCF5206E_UIVR(MBAR,chn) = uart->intvec;
*MCF5206E_UIVR(MBAR,chn) = uart->intvec; *MCF5206E_UIMR(MBAR,chn) = MCF5206E_UIMR_FFULL;
*MCF5206E_UIMR(MBAR,chn) = MCF5206E_UIMR_FFULL; *MCF5206E_UACR(MBAR,chn) = MCF5206E_UACR_IEC;
*MCF5206E_UACR(MBAR,chn) = MCF5206E_UACR_IEC; *MCF5206E_IMR(MBAR) &= ~MCF5206E_INTR_BIT(uart->chn == 1 ?
*MCF5206E_IMR(MBAR) &= ~MCF5206E_INTR_BIT(uart->chn == 1 ? MCF5206E_INTR_UART_1 :
MCF5206E_INTR_UART_1 : MCF5206E_INTR_UART_2);
MCF5206E_INTR_UART_2); } else {
} *MCF5206E_UIMR(MBAR,chn) = 0;
else }
{
*MCF5206E_UIMR(MBAR,chn) = 0;
}
/* Select the receiver and transmitter clock. */ /* Select the receiver and transmitter clock. */
mcfuart_set_baudrate(uart, B19200); /* dBUG defaults (unfortunately, mcfuart_set_baudrate(uart, B19200); /* dBUG defaults (unfortunately,
it is differ to termios default */ it is differ to termios default */
*MCF5206E_UCSR(MBAR,chn) = *MCF5206E_UCSR(MBAR,chn) = MCF5206E_UCSR_RCS_TIMER | MCF5206E_UCSR_TCS_TIMER;
MCF5206E_UCSR_RCS_TIMER | MCF5206E_UCSR_TCS_TIMER;
/* Mode Registers 1,2 - set termios defaults (8N1) */ /* Mode Registers 1,2 - set termios defaults (8N1) */
*MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_MR; *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_MR;
*MCF5206E_UMR(MBAR,chn) = *MCF5206E_UMR(MBAR,chn) =
/* MCF5206E_UMR1_RXRTS | */ /* MCF5206E_UMR1_RXRTS | */
MCF5206E_UMR1_PM_NO_PARITY | MCF5206E_UMR1_PM_NO_PARITY |
MCF5206E_UMR1_BC_8; MCF5206E_UMR1_BC_8;
*MCF5206E_UMR(MBAR,chn) = *MCF5206E_UMR(MBAR,chn) =
MCF5206E_UMR2_CM_NORMAL | MCF5206E_UMR2_CM_NORMAL |
/* MCF5206E_UMR2_TXCTS | */ /* MCF5206E_UMR2_TXCTS | */
MCF5206E_UMR2_SB_1; MCF5206E_UMR2_SB_1;
/* Enable Receiver and Transmitter */ /* Enable Receiver and Transmitter */
*MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_ERR; *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_MISC_RESET_ERR;
*MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_TC_ENABLE; *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_TC_ENABLE;
*MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_RC_ENABLE; *MCF5206E_UCR(MBAR,chn) = MCF5206E_UCR_RC_ENABLE;
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
/* /*
@@ -205,25 +205,24 @@ mcfuart_reset(mcfuart *uart)
* RTEMS_SUCCESSFUL if UART closed successfuly, or error code in * RTEMS_SUCCESSFUL if UART closed successfuly, or error code in
* other case * other case
*/ */
rtems_status_code rtems_status_code mcfuart_disable(mcfuart *uart)
mcfuart_disable(mcfuart *uart)
{ {
rtems_status_code rc; rtems_status_code rc;
*MCF5206E_UCR(MBAR,uart->chn) =
MCF5206E_UCR_TC_DISABLE | *MCF5206E_UCR(MBAR,uart->chn) =
MCF5206E_UCR_RC_DISABLE; MCF5206E_UCR_TC_DISABLE |
if (uart->intvec != 0) MCF5206E_UCR_RC_DISABLE;
{ if (uart->intvec != 0) {
*MCF5206E_IMR(MBAR) |= MCF5206E_INTR_BIT(uart->chn == 1 ? *MCF5206E_IMR(MBAR) |= MCF5206E_INTR_BIT(uart->chn == 1 ?
MCF5206E_INTR_UART_1 : MCF5206E_INTR_UART_1 :
MCF5206E_INTR_UART_2); MCF5206E_INTR_UART_2);
rc = rtems_interrupt_catch(uart->old_handler, uart->intvec, NULL); rc = rtems_interrupt_catch(uart->old_handler, uart->intvec, NULL);
int_driven_uart[uart->chn - 1].uart = NULL; int_driven_uart[uart->chn - 1].uart = NULL;
int_driven_uart[uart->chn - 1].vec = 0; int_driven_uart[uart->chn - 1].vec = 0;
if (rc != RTEMS_SUCCESSFUL) if (rc != RTEMS_SUCCESSFUL)
return rc; return rc;
} }
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
/* /*
@@ -238,93 +237,72 @@ mcfuart_disable(mcfuart *uart)
* RETURNS: * RETURNS:
* RTEMS_SUCCESSFUL * RTEMS_SUCCESSFUL
*/ */
int int mcfuart_set_attributes(mcfuart *uart, const struct termios *t)
mcfuart_set_attributes(mcfuart *uart, const struct termios *t)
{ {
int level; int level;
speed_t baud; speed_t baud;
uint8_t umr1, umr2; uint8_t umr1, umr2;
baud = cfgetospeed(t); baud = cfgetospeed(t);
umr1 = 0; umr1 = 0;
umr2 = MCF5206E_UMR2_CM_NORMAL; umr2 = MCF5206E_UMR2_CM_NORMAL;
/* Set flow control */ /* Set flow control */
if ((t->c_cflag & CRTSCTS) != 0) if ((t->c_cflag & CRTSCTS) != 0) {
{ umr1 |= MCF5206E_UMR1_RXRTS;
umr1 |= MCF5206E_UMR1_RXRTS; umr2 |= MCF5206E_UMR2_TXCTS;
umr2 |= MCF5206E_UMR2_TXCTS; }
}
/* Set character size */ /* Set character size */
switch (t->c_cflag & CSIZE) switch (t->c_cflag & CSIZE) {
{ case CS5: umr1 |= MCF5206E_UMR1_BC_5; break;
case CS5: umr1 |= MCF5206E_UMR1_BC_5; break; case CS6: umr1 |= MCF5206E_UMR1_BC_6; break;
case CS6: umr1 |= MCF5206E_UMR1_BC_6; break; case CS7: umr1 |= MCF5206E_UMR1_BC_7; break;
case CS7: umr1 |= MCF5206E_UMR1_BC_7; break; case CS8: umr1 |= MCF5206E_UMR1_BC_8; break;
case CS8: umr1 |= MCF5206E_UMR1_BC_8; break; }
}
/* Set number of stop bits */ /* Set number of stop bits */
if ((t->c_cflag & CSTOPB) != 0) if ((t->c_cflag & CSTOPB) != 0) {
{ if ((t->c_cflag & CSIZE) == CS5) {
if ((t->c_cflag & CSIZE) == CS5) umr2 |= MCF5206E_UMR2_SB5_2;
{ } else {
umr2 |= MCF5206E_UMR2_SB5_2; umr2 |= MCF5206E_UMR2_SB_2;
}
else
{
umr2 |= MCF5206E_UMR2_SB_2;
}
} }
else } else {
{ if ((t->c_cflag & CSIZE) == CS5) {
if ((t->c_cflag & CSIZE) == CS5) umr2 |= MCF5206E_UMR2_SB5_1;
{ } else {
umr2 |= MCF5206E_UMR2_SB5_1; umr2 |= MCF5206E_UMR2_SB_1;
}
else
{
umr2 |= MCF5206E_UMR2_SB_1;
}
} }
}
/* Set parity mode */ /* Set parity mode */
if ((t->c_cflag & PARENB) != 0) if ((t->c_cflag & PARENB) != 0) {
{ if ((t->c_cflag & PARODD) != 0) {
if ((t->c_cflag & PARODD) != 0) umr1 |= MCF5206E_UMR1_PM_ODD;
{ } else {
umr1 |= MCF5206E_UMR1_PM_ODD; umr1 |= MCF5206E_UMR1_PM_EVEN;
}
else
{
umr1 |= MCF5206E_UMR1_PM_EVEN;
}
}
else
{
umr1 |= MCF5206E_UMR1_PM_NO_PARITY;
} }
} else {
umr1 |= MCF5206E_UMR1_PM_NO_PARITY;
}
rtems_interrupt_disable(level); rtems_interrupt_disable(level);
*MCF5206E_UCR(MBAR,uart->chn) =
MCF5206E_UCR_TC_DISABLE | MCF5206E_UCR_RC_DISABLE;
mcfuart_set_baudrate(uart, baud);
*MCF5206E_UCR(MBAR,uart->chn) = MCF5206E_UCR_MISC_RESET_MR;
*MCF5206E_UMR(MBAR,uart->chn) = umr1;
*MCF5206E_UMR(MBAR,uart->chn) = umr2;
if ((t->c_cflag & CREAD) != 0) {
*MCF5206E_UCR(MBAR,uart->chn) = *MCF5206E_UCR(MBAR,uart->chn) =
MCF5206E_UCR_TC_DISABLE | MCF5206E_UCR_RC_DISABLE; MCF5206E_UCR_TC_ENABLE | MCF5206E_UCR_RC_ENABLE;
mcfuart_set_baudrate(uart, baud); } else {
*MCF5206E_UCR(MBAR,uart->chn) = MCF5206E_UCR_MISC_RESET_MR; *MCF5206E_UCR(MBAR,uart->chn) = MCF5206E_UCR_TC_ENABLE;
*MCF5206E_UMR(MBAR,uart->chn) = umr1; }
*MCF5206E_UMR(MBAR,uart->chn) = umr2; rtems_interrupt_enable(level);
if ((t->c_cflag & CREAD) != 0)
{
*MCF5206E_UCR(MBAR,uart->chn) =
MCF5206E_UCR_TC_ENABLE | MCF5206E_UCR_RC_ENABLE;
}
else
{
*MCF5206E_UCR(MBAR,uart->chn) = MCF5206E_UCR_TC_ENABLE;
}
rtems_interrupt_enable(level);
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
/* /*
@@ -343,41 +321,33 @@ mcfuart_set_attributes(mcfuart *uart, const struct termios *t)
* RETURNS: * RETURNS:
* code of received character or -1 if no characters received. * code of received character or -1 if no characters received.
*/ */
int int mcfuart_poll_read(mcfuart *uart)
mcfuart_poll_read(mcfuart *uart)
{ {
uint8_t usr; uint8_t usr;
int ch; int ch;
if (uart->parerr_mark_flag == true)
{ if (uart->parerr_mark_flag == true) {
uart->parerr_mark_flag = false; uart->parerr_mark_flag = false;
return 0; return 0;
}
usr = *MCF5206E_USR(MBAR,uart->chn);
if ((usr & MCF5206E_USR_RXRDY) != 0) {
if (((usr & (MCF5206E_USR_FE | MCF5206E_USR_PE)) != 0) &&
!(uart->c_iflag & IGNPAR)) {
ch = *MCF5206E_URB(MBAR,uart->chn); /* Clear error bits */
if (uart->c_iflag & PARMRK) {
uart->parerr_mark_flag = true;
ch = 0xff;
} else {
ch = 0;
}
} else {
ch = *MCF5206E_URB(MBAR,uart->chn);
} }
usr = *MCF5206E_USR(MBAR,uart->chn); } else
if ((usr & MCF5206E_USR_RXRDY) != 0) ch = -1;
{ return ch;
if (((usr & (MCF5206E_USR_FE | MCF5206E_USR_PE)) != 0) &&
!(uart->c_iflag & IGNPAR))
{
ch = *MCF5206E_URB(MBAR,uart->chn); /* Clear error bits */
if (uart->c_iflag & PARMRK)
{
uart->parerr_mark_flag = true;
ch = 0xff;
}
else
{
ch = 0;
}
}
else
{
ch = *MCF5206E_URB(MBAR,uart->chn);
}
}
else
ch = -1;
return ch;
} }
/* /*
@@ -392,17 +362,15 @@ mcfuart_poll_read(mcfuart *uart)
* RETURNS: * RETURNS:
* 0 * 0
*/ */
ssize_t ssize_t mcfuart_poll_write(mcfuart *uart, const char *buf, size_t len)
mcfuart_poll_write(mcfuart *uart, const char *buf, size_t len)
{ {
size_t retval = len; size_t retval = len;
while (len--) while (len--) {
{ while ((*MCF5206E_USR(MBAR, uart->chn) & MCF5206E_USR_TXRDY) == 0);
while ((*MCF5206E_USR(MBAR, uart->chn) & MCF5206E_USR_TXRDY) == 0); *MCF5206E_UTB(MBAR, uart->chn) = *buf++;
*MCF5206E_UTB(MBAR, uart->chn) = *buf++; }
} return retval;
return retval;
} }
/* mcfuart_interrupt_handler -- /* mcfuart_interrupt_handler --
@@ -414,95 +382,78 @@ mcfuart_poll_write(mcfuart *uart, const char *buf, size_t len)
* RETURNS: * RETURNS:
* none * none
*/ */
static rtems_isr static rtems_isr mcfuart_interrupt_handler(rtems_vector_number vec)
mcfuart_interrupt_handler(rtems_vector_number vec)
{ {
mcfuart *uart; mcfuart *uart;
register uint8_t usr; register uint8_t usr;
register uint8_t uisr; register uint8_t uisr;
register int chn; register int chn;
register int bp = 0; register int bp = 0;
/* Find UART descriptor from vector number */ /* Find UART descriptor from vector number */
if (int_driven_uart[0].vec == vec) if (int_driven_uart[0].vec == vec)
uart = int_driven_uart[0].uart; uart = int_driven_uart[0].uart;
else if (int_driven_uart[1].vec == vec) else if (int_driven_uart[1].vec == vec)
uart = int_driven_uart[1].uart; uart = int_driven_uart[1].uart;
else
return;
chn = uart->chn;
uisr = *MCF5206E_UISR(MBAR, chn);
if (uisr & MCF5206E_UISR_DB) {
*MCF5206E_UCR(MBAR, chn) = MCF5206E_UCR_MISC_RESET_BRK;
}
/* Receiving */
while (1) {
char buf[32];
usr = *MCF5206E_USR(MBAR,chn);
if ((bp < sizeof(buf) - 1) && ((usr & MCF5206E_USR_RXRDY) != 0)) {
/* Receive character and handle frame/parity errors */
if (((usr & (MCF5206E_USR_FE | MCF5206E_USR_PE)) != 0) &&
!(uart->c_iflag & IGNPAR)) {
if (uart->c_iflag & PARMRK) {
buf[bp++] = 0xff;
buf[bp++] = 0x00;
} else {
buf[bp++] = 0x00;
}
} else {
buf[bp++] = *MCF5206E_URB(MBAR, chn);
}
/* Reset error condition if any errors has been detected */
if (usr & (MCF5206E_USR_RB | MCF5206E_USR_FE |
MCF5206E_USR_PE | MCF5206E_USR_OE)) {
*MCF5206E_UCR(MBAR, chn) = MCF5206E_UCR_MISC_RESET_ERR;
}
} else {
if (bp != 0)
rtems_termios_enqueue_raw_characters(uart->tty, buf, bp);
break;
}
}
/* Transmitting */
while (1) {
if ((*MCF5206E_USR(MBAR, chn) & MCF5206E_USR_TXRDY) == 0)
break;
if (uart->tx_buf != NULL) {
if (uart->tx_ptr >= uart->tx_buf_len) {
register int dequeue = uart->tx_buf_len;
*MCF5206E_UIMR(MBAR, uart->chn) = MCF5206E_UIMR_FFULL;
uart->tx_buf = NULL;
uart->tx_ptr = uart->tx_buf_len = 0;
rtems_termios_dequeue_characters(uart->tty, dequeue);
} else {
*MCF5206E_UTB(MBAR, chn) = uart->tx_buf[uart->tx_ptr++];
}
}
else else
return; break;
}
chn = uart->chn;
uisr = *MCF5206E_UISR(MBAR, chn);
if (uisr & MCF5206E_UISR_DB)
{
*MCF5206E_UCR(MBAR, chn) = MCF5206E_UCR_MISC_RESET_BRK;
}
/* Receiving */
while (1)
{
char buf[32];
usr = *MCF5206E_USR(MBAR,chn);
if ((bp < sizeof(buf) - 1) && ((usr & MCF5206E_USR_RXRDY) != 0))
{
/* Receive character and handle frame/parity errors */
if (((usr & (MCF5206E_USR_FE | MCF5206E_USR_PE)) != 0) &&
!(uart->c_iflag & IGNPAR))
{
if (uart->c_iflag & PARMRK)
{
buf[bp++] = 0xff;
buf[bp++] = 0x00;
}
else
{
buf[bp++] = 0x00;
}
}
else
{
buf[bp++] = *MCF5206E_URB(MBAR, chn);
}
/* Reset error condition if any errors has been detected */
if (usr & (MCF5206E_USR_RB | MCF5206E_USR_FE |
MCF5206E_USR_PE | MCF5206E_USR_OE))
{
*MCF5206E_UCR(MBAR, chn) = MCF5206E_UCR_MISC_RESET_ERR;
}
}
else
{
if (bp != 0)
rtems_termios_enqueue_raw_characters(uart->tty, buf, bp);
break;
}
}
/* Transmitting */
while (1)
{
if ((*MCF5206E_USR(MBAR, chn) & MCF5206E_USR_TXRDY) == 0)
break;
if (uart->tx_buf != NULL)
{
if (uart->tx_ptr >= uart->tx_buf_len)
{
register int dequeue = uart->tx_buf_len;
*MCF5206E_UIMR(MBAR, uart->chn) = MCF5206E_UIMR_FFULL;
uart->tx_buf = NULL;
uart->tx_ptr = uart->tx_buf_len = 0;
rtems_termios_dequeue_characters(uart->tty, dequeue);
}
else
{
*MCF5206E_UTB(MBAR, chn) = uart->tx_buf[uart->tx_ptr++];
}
}
else
break;
}
} }
/* mcfuart_interrupt_write -- /* mcfuart_interrupt_write --
@@ -516,24 +467,25 @@ mcfuart_interrupt_handler(rtems_vector_number vec)
* RETURNS: * RETURNS:
* 0 * 0
*/ */
ssize_t ssize_t mcfuart_interrupt_write(
mcfuart_interrupt_write(mcfuart *uart, const char *buf, size_t len) mcfuart *uart,
const char *buf,
size_t len
)
{ {
if (len > 0) if (len > 0) {
{ uart->tx_buf = buf;
uart->tx_buf = buf; uart->tx_buf_len = len;
uart->tx_buf_len = len; uart->tx_ptr = 0;
uart->tx_ptr = 0; *MCF5206E_UIMR(MBAR, uart->chn) =
*MCF5206E_UIMR(MBAR, uart->chn) = MCF5206E_UIMR_FFULL | MCF5206E_UIMR_TXRDY;
MCF5206E_UIMR_FFULL | MCF5206E_UIMR_TXRDY; while (((*MCF5206E_USR(MBAR,uart->chn) & MCF5206E_USR_TXRDY) != 0) &&
while (((*MCF5206E_USR(MBAR,uart->chn) & MCF5206E_USR_TXRDY) != 0) && (uart->tx_ptr < uart->tx_buf_len)) {
(uart->tx_ptr < uart->tx_buf_len)) *MCF5206E_UTB(MBAR,uart->chn) = uart->tx_buf[uart->tx_ptr++];
{
*MCF5206E_UTB(MBAR,uart->chn) = uart->tx_buf[uart->tx_ptr++];
}
} }
}
return 0; return 0;
} }
/* mcfuart_stop_remote_tx -- /* mcfuart_stop_remote_tx --
@@ -545,11 +497,10 @@ mcfuart_interrupt_write(mcfuart *uart, const char *buf, size_t len)
* RETURNS: * RETURNS:
* RTEMS_SUCCESSFUL * RTEMS_SUCCESSFUL
*/ */
int int mcfuart_stop_remote_tx(mcfuart *uart)
mcfuart_stop_remote_tx(mcfuart *uart)
{ {
*MCF5206E_UOP0(MBAR, uart->chn) = 1; *MCF5206E_UOP0(MBAR, uart->chn) = 1;
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
/* mcfuart_start_remote_tx -- /* mcfuart_start_remote_tx --
@@ -561,9 +512,8 @@ mcfuart_stop_remote_tx(mcfuart *uart)
* RETURNS: * RETURNS:
* RTEMS_SUCCESSFUL * RTEMS_SUCCESSFUL
*/ */
int int mcfuart_start_remote_tx(mcfuart *uart)
mcfuart_start_remote_tx(mcfuart *uart)
{ {
*MCF5206E_UOP1(MBAR, uart->chn) = 1; *MCF5206E_UOP1(MBAR, uart->chn) = 1;
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }

View File

@@ -36,7 +36,7 @@ typedef struct mcfmbus {
rtems_isr_entry oldisr; /* Old interrupt handler */ rtems_isr_entry oldisr; /* Old interrupt handler */
rtems_id sema; /* MBUS semaphore */ rtems_id sema; /* MBUS semaphore */
i2c_transfer_done done; /* Transfer done function */ i2c_transfer_done done; /* Transfer done function */
uint32_t done_arg_ptr; /* Done function argument ptr */ uintptr_t done_arg_ptr; /* Done function argument ptr */
} mcfmbus; } mcfmbus;
/* mcfmbus_initialize -- /* mcfmbus_initialize --

View File

@@ -34,7 +34,7 @@ typedef struct mcfuart {
0 if polled I/O */ 0 if polled I/O */
void *tty; /* termios channel descriptor */ void *tty; /* termios channel descriptor */
volatile const uint8_t *tx_buf; /* Transmit buffer from termios */ volatile const char *tx_buf; /* Transmit buffer from termios */
volatile uint32_t tx_buf_len; /* Transmit buffer length */ volatile uint32_t tx_buf_len; /* Transmit buffer length */
volatile uint32_t tx_ptr; /* Index of next char to transmit*/ volatile uint32_t tx_ptr; /* Index of next char to transmit*/
rtems_isr_entry old_handler; /* Saved interrupt handler */ rtems_isr_entry old_handler; /* Saved interrupt handler */

View File

@@ -1,6 +1,8 @@
/* /*
* MCF5206e MBUS module (I2C bus) driver * MCF5206e MBUS module (I2C bus) driver
* */
/*
* Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
* Author: Victor V. Vengerov <vvv@oktet.ru> * Author: Victor V. Vengerov <vvv@oktet.ru>
* *
@@ -15,15 +17,15 @@
/* Events of I2C machine */ /* Events of I2C machine */
typedef enum i2c_event { typedef enum i2c_event {
EVENT_NONE, /* Spurious event */ EVENT_NONE, /* Spurious event */
EVENT_TRANSFER, /* Start new transfer */ EVENT_TRANSFER, /* Start new transfer */
EVENT_NEXTMSG, /* Start processing of next message in transfer */ EVENT_NEXTMSG, /* Start processing of next message in transfer */
EVENT_ACK, /* Sending finished with ACK */ EVENT_ACK, /* Sending finished with ACK */
EVENT_NACK, /* Sending finished with NACK */ EVENT_NACK, /* Sending finished with NACK */
EVENT_TIMEOUT, /* Timeout occured */ EVENT_TIMEOUT, /* Timeout occured */
EVENT_DATA_RECV, /* Data received */ EVENT_DATA_RECV, /* Data received */
EVENT_ARB_LOST, /* Arbitration lost */ EVENT_ARB_LOST, /* Arbitration lost */
EVENT_SLAVE /* Addressed as a slave */ EVENT_SLAVE /* Addressed as a slave */
} i2c_event; } i2c_event;
static mcfmbus *mbus; static mcfmbus *mbus;
@@ -109,52 +111,42 @@ static mcfmbus *mbus;
static i2c_event static i2c_event
mcfmbus_get_event(mcfmbus *bus) mcfmbus_get_event(mcfmbus *bus)
{ {
i2c_event event; i2c_event event;
uint8_t status, control; uint8_t status, control;
rtems_interrupt_level level; rtems_interrupt_level level;
rtems_interrupt_disable(level); rtems_interrupt_disable(level);
status = *MCF5206E_MBSR(bus->base); status = *MCF5206E_MBSR(bus->base);
control = *MCF5206E_MBCR(bus->base); control = *MCF5206E_MBCR(bus->base);
if (status & MCF5206E_MBSR_MIF) /* Interrupt occured */
{
if (status & MCF5206E_MBSR_MAAS)
{
event = EVENT_SLAVE;
*MCF5206E_MBCR(bus->base) = control; /* To clear Addressed As Slave
condition */
}
else if (status & MCF5206E_MBSR_MAL) /* Arbitration lost */
{
*MCF5206E_MBSR(bus->base) = status & ~MCF5206E_MBSR_MAL;
event = EVENT_ARB_LOST;
}
else if (control & MCF5206E_MBCR_MTX) /* Trasmit mode */
{
if (status & MCF5206E_MBSR_RXAK)
event = EVENT_NACK;
else
event = EVENT_ACK;
}
else /* Received */
{
event = EVENT_DATA_RECV;
}
/* Clear interrupt condition */ if (status & MCF5206E_MBSR_MIF) { /* Interrupt occured */
*MCF5206E_MBSR(bus->base) &= ~MCF5206E_MBSR_MIF; if (status & MCF5206E_MBSR_MAAS) {
event = EVENT_SLAVE;
*MCF5206E_MBCR(bus->base) = control; /* To clear Addressed As Slave
condition */
} else if (status & MCF5206E_MBSR_MAL) { /* Arbitration lost */
*MCF5206E_MBSR(bus->base) = status & ~MCF5206E_MBSR_MAL;
event = EVENT_ARB_LOST;
} }
else else if (control & MCF5206E_MBCR_MTX) { /* Trasmit mode */
{ if (status & MCF5206E_MBSR_RXAK)
event = EVENT_NONE; event = EVENT_NACK;
else
event = EVENT_ACK;
} else { /* Received */
event = EVENT_DATA_RECV;
} }
rtems_interrupt_enable(level);
return event; /* Clear interrupt condition */
*MCF5206E_MBSR(bus->base) &= ~MCF5206E_MBSR_MIF;
} else {
event = EVENT_NONE;
}
rtems_interrupt_enable(level);
return event;
} }
static void static void mcfmbus_machine_error(mcfmbus *bus, i2c_event event)
mcfmbus_machine_error(mcfmbus *bus, i2c_event event)
{ {
return;
} }
/* mcfmbus_machine -- /* mcfmbus_machine --
@@ -167,445 +159,407 @@ mcfmbus_machine_error(mcfmbus *bus, i2c_event event)
* RETURNS: * RETURNS:
* none * none
*/ */
static void static void mcfmbus_machine(mcfmbus *bus, i2c_event event)
mcfmbus_machine(mcfmbus *bus, i2c_event event)
{ {
uint8_t b; uint8_t b;
switch (bus->state)
{
case STATE_IDLE:
switch (event)
{
case EVENT_NEXTMSG: /* Start new message processing */
bus->cmsg++;
/* FALLTHRU */
case EVENT_TRANSFER: /* Initiate new transfer */ switch (bus->state) {
if (bus->cmsg - bus->msg >= bus->nmsg) case STATE_IDLE:
{ switch (event) {
mcfmbus_stop(bus); case EVENT_NEXTMSG: /* Start new message processing */
next_state(bus, STATE_IDLE); bus->cmsg++;
bus->msg = bus->cmsg = NULL; /* FALLTHRU */
bus->nmsg = bus->byte = 0;
bus->done(bus->done_arg_ptr);
break;
}
/* Initiate START or REPEATED START condition on the bus */ case EVENT_TRANSFER: /* Initiate new transfer */
if (event == EVENT_TRANSFER) if (bus->cmsg - bus->msg >= bus->nmsg) {
{ mcfmbus_stop(bus);
mcfmbus_start(bus); next_state(bus, STATE_IDLE);
} bus->msg = bus->cmsg = NULL;
else /* (event == EVENT_NEXTMSG) */ bus->nmsg = bus->byte = 0;
{ bus->done((void *)bus->done_arg_ptr);
mcfmbus_rstart(bus);
}
bus->byte = 0;
mcfmbus_tx_mode(bus);
/* Initiate slave address sending */
if (bus->cmsg->flags & I2C_MSG_ADDR_10)
{
i2c_address a = bus->cmsg->addr;
b = 0xf0 | (((a >> 8) & 0x03) << 1);
if (bus->cmsg->flags & I2C_MSG_WR)
{
mcfmbus_send(bus, b);
next_state(bus, STATE_ADDR_1_W);
}
else
{
mcfmbus_send(bus, b | 1);
next_state(bus, STATE_ADDR_1_R);
}
}
else
{
b = (bus->cmsg->addr & ~0x01);
if (bus->cmsg->flags & I2C_MSG_WR)
{
next_state(bus, STATE_SENDING);
}
else
{
next_state(bus, STATE_ADDR_7);
b |= 1;
}
mcfmbus_send(bus, b);
}
break;
default:
mcfmbus_machine_error(bus, event);
break;
}
break; break;
}
case STATE_ADDR_7: /* Initiate START or REPEATED START condition on the bus */
switch (event) if (event == EVENT_TRANSFER) {
{ mcfmbus_start(bus);
case EVENT_ACK: } else { /* (event == EVENT_NEXTMSG) */
mcfmbus_rx_mode(bus); mcfmbus_rstart(bus);
if (bus->cmsg->len <= 1) }
mcfmbus_send_nack(bus);
else
mcfmbus_send_ack(bus);
next_state(bus, STATE_RECEIVING);
break;
case EVENT_NACK: bus->byte = 0;
mcfmbus_error(bus, I2C_NO_DEVICE); mcfmbus_tx_mode(bus);
next_state(bus, STATE_IDLE);
mcfmbus_machine(bus, EVENT_NEXTMSG);
break;
case EVENT_ARB_LOST: /* Initiate slave address sending */
mcfmbus_error(bus, I2C_ARBITRATION_LOST); if (bus->cmsg->flags & I2C_MSG_ADDR_10) {
next_state(bus, STATE_IDLE); i2c_address a = bus->cmsg->addr;
mcfmbus_machine(bus, EVENT_NEXTMSG); b = 0xf0 | (((a >> 8) & 0x03) << 1);
break; if (bus->cmsg->flags & I2C_MSG_WR) {
mcfmbus_send(bus, b);
default: next_state(bus, STATE_ADDR_1_W);
mcfmbus_machine_error(bus, event); } else {
break; mcfmbus_send(bus, b | 1);
next_state(bus, STATE_ADDR_1_R);
} }
break; } else {
b = (bus->cmsg->addr & ~0x01);
case STATE_ADDR_1_R: if (bus->cmsg->flags & I2C_MSG_WR) {
case STATE_ADDR_1_W: next_state(bus, STATE_SENDING);
switch (event) } else {
{ next_state(bus, STATE_ADDR_7);
case EVENT_ACK: b |= 1;
{
uint8_t b = (bus->cmsg->addr & 0xff);
mcfmbus_send(bus, b);
if (bus->state == STATE_ADDR_1_W)
{
next_state(bus, STATE_SENDING);
}
else
{
i2c_address a;
mcfmbus_rstart(bus);
mcfmbus_tx_mode(bus);
a = bus->cmsg->addr;
b = 0xf0 | (((a >> 8) & 0x03) << 1) | 1;
mcfmbus_send(bus, b);
next_state(bus, STATE_ADDR_7);
}
break;
}
case EVENT_NACK:
mcfmbus_error(bus, I2C_NO_DEVICE);
next_state(bus, STATE_IDLE);
mcfmbus_machine(bus, EVENT_NEXTMSG);
break;
case EVENT_ARB_LOST:
mcfmbus_error(bus, I2C_ARBITRATION_LOST);
next_state(bus, STATE_IDLE);
mcfmbus_machine(bus, EVENT_NEXTMSG);
break;
default:
mcfmbus_machine_error(bus, event);
break;
} }
mcfmbus_send(bus, b);
}
break;
default:
mcfmbus_machine_error(bus, event);
break; break;
}
break;
case STATE_SENDING: case STATE_ADDR_7:
switch (event) switch (event) {
{ case EVENT_ACK:
case EVENT_ACK: mcfmbus_rx_mode(bus);
if (bus->byte == bus->cmsg->len) if (bus->cmsg->len <= 1)
{ mcfmbus_send_nack(bus);
next_state(bus, STATE_IDLE); else
mcfmbus_machine(bus, EVENT_NEXTMSG); mcfmbus_send_ack(bus);
} next_state(bus, STATE_RECEIVING);
else break;
{
mcfmbus_send(bus, bus->cmsg->buf[bus->byte++]);
next_state(bus, STATE_SENDING);
}
break;
case EVENT_NACK: case EVENT_NACK:
if (bus->byte == 0) mcfmbus_error(bus, I2C_NO_DEVICE);
{ next_state(bus, STATE_IDLE);
mcfmbus_error(bus, I2C_NO_DEVICE); mcfmbus_machine(bus, EVENT_NEXTMSG);
} break;
else
{
mcfmbus_error(bus, I2C_NO_ACKNOWLEDGE);
}
next_state(bus, STATE_IDLE);
mcfmbus_machine(bus, EVENT_NEXTMSG);
break;
case EVENT_ARB_LOST: case EVENT_ARB_LOST:
mcfmbus_error(bus, I2C_ARBITRATION_LOST); mcfmbus_error(bus, I2C_ARBITRATION_LOST);
next_state(bus, STATE_IDLE); next_state(bus, STATE_IDLE);
mcfmbus_machine(bus, EVENT_NEXTMSG); mcfmbus_machine(bus, EVENT_NEXTMSG);
break; break;
default: default:
mcfmbus_machine_error(bus, event); mcfmbus_machine_error(bus, event);
break; break;
}
break;
} case STATE_ADDR_1_R:
break; case STATE_ADDR_1_W:
switch (event) {
case EVENT_ACK: {
uint8_t b = (bus->cmsg->addr & 0xff);
mcfmbus_send(bus, b);
if (bus->state == STATE_ADDR_1_W) {
next_state(bus, STATE_SENDING);
} else {
i2c_address a;
mcfmbus_rstart(bus);
mcfmbus_tx_mode(bus);
a = bus->cmsg->addr;
b = 0xf0 | (((a >> 8) & 0x03) << 1) | 1;
mcfmbus_send(bus, b);
next_state(bus, STATE_ADDR_7);
}
break;
}
case STATE_RECEIVING: case EVENT_NACK:
switch (event) mcfmbus_error(bus, I2C_NO_DEVICE);
{ next_state(bus, STATE_IDLE);
case EVENT_DATA_RECV: mcfmbus_machine(bus, EVENT_NEXTMSG);
if (bus->cmsg->len - bus->byte <= 2) break;
{
mcfmbus_send_nack(bus);
if (bus->cmsg->len - bus->byte <= 1)
{
if (bus->cmsg - bus->msg + 1 == bus->nmsg)
mcfmbus_stop(bus);
else
mcfmbus_rstart(bus);
}
}
else
{
mcfmbus_send_ack(bus);
}
bus->cmsg->buf[bus->byte++] = *MCF5206E_MBDR(bus->base);
if (bus->cmsg->len == bus->byte)
{
next_state(bus,STATE_IDLE);
mcfmbus_machine(bus, EVENT_NEXTMSG);
}
else
{
next_state(bus,STATE_RECEIVING);
}
break;
case EVENT_ARB_LOST: case EVENT_ARB_LOST:
mcfmbus_error(bus, I2C_ARBITRATION_LOST); mcfmbus_error(bus, I2C_ARBITRATION_LOST);
next_state(bus, STATE_IDLE); next_state(bus, STATE_IDLE);
mcfmbus_machine(bus, EVENT_NEXTMSG); mcfmbus_machine(bus, EVENT_NEXTMSG);
break; break;
default: default:
mcfmbus_machine_error(bus, event); mcfmbus_machine_error(bus, event);
break; break;
}
break;
} }
break;
case STATE_SENDING:
switch (event) {
case EVENT_ACK:
if (bus->byte == bus->cmsg->len) {
next_state(bus, STATE_IDLE);
mcfmbus_machine(bus, EVENT_NEXTMSG);
} else {
mcfmbus_send(bus, bus->cmsg->buf[bus->byte++]);
next_state(bus, STATE_SENDING);
}
break;
case EVENT_NACK:
if (bus->byte == 0) {
mcfmbus_error(bus, I2C_NO_DEVICE);
} else {
mcfmbus_error(bus, I2C_NO_ACKNOWLEDGE);
}
next_state(bus, STATE_IDLE);
mcfmbus_machine(bus, EVENT_NEXTMSG);
break;
case EVENT_ARB_LOST:
mcfmbus_error(bus, I2C_ARBITRATION_LOST);
next_state(bus, STATE_IDLE);
mcfmbus_machine(bus, EVENT_NEXTMSG);
break;
default:
mcfmbus_machine_error(bus, event);
break;
}
break;
case STATE_RECEIVING:
switch (event) {
case EVENT_DATA_RECV:
if (bus->cmsg->len - bus->byte <= 2) {
mcfmbus_send_nack(bus);
if (bus->cmsg->len - bus->byte <= 1) {
if (bus->cmsg - bus->msg + 1 == bus->nmsg)
mcfmbus_stop(bus);
else
mcfmbus_rstart(bus);
}
} else {
mcfmbus_send_ack(bus);
}
bus->cmsg->buf[bus->byte++] = *MCF5206E_MBDR(bus->base);
if (bus->cmsg->len == bus->byte) {
next_state(bus,STATE_IDLE);
mcfmbus_machine(bus, EVENT_NEXTMSG);
} else {
next_state(bus,STATE_RECEIVING);
}
break;
case EVENT_ARB_LOST:
mcfmbus_error(bus, I2C_ARBITRATION_LOST);
next_state(bus, STATE_IDLE);
mcfmbus_machine(bus, EVENT_NEXTMSG);
break;
default:
mcfmbus_machine_error(bus, event);
break;
}
break;
}
} }
/* mcfmbus_interrupt_handler -- /* mcfmbus_interrupt_handler --
* MBUS module interrupt handler routine * MBUS module interrupt handler routine
* *
* PARAMETERS: * PARAMETERS:
* vector - interrupt vector number (not used) * vector - interrupt vector number (not used)
* *
* RETURNS: * RETURNS:
* none * none
*/ */
rtems_isr static rtems_isr mcfmbus_interrupt_handler(rtems_vector_number vector)
mcfmbus_interrupt_handler(rtems_vector_number vector)
{ {
i2c_event event; i2c_event event;
event = mcfmbus_get_event(mbus); event = mcfmbus_get_event(mbus);
mcfmbus_machine(mbus, event); mcfmbus_machine(mbus, event);
} }
/* mcfmbus_poll -- /* mcfmbus_poll --
* MBUS module poll routine; used to poll events when I2C driver * MBUS module poll routine; used to poll events when I2C driver
* operates in poll-driven mode. * operates in poll-driven mode.
* *
* PARAMETERS: * PARAMETERS:
* none * none
* *
* RETURNS: * RETURNS:
* none * none
*/ */
void void
mcfmbus_poll(mcfmbus *bus) mcfmbus_poll(mcfmbus *bus)
{ {
i2c_event event; i2c_event event;
event = mcfmbus_get_event(bus); event = mcfmbus_get_event(bus);
if (event != EVENT_NONE) if (event != EVENT_NONE)
mcfmbus_machine(bus, event); mcfmbus_machine(bus, event);
} }
/* mcfmbus_select_clock_divider -- /* mcfmbus_select_clock_divider --
* Select divider for system clock which is used for I2C bus clock * Select divider for system clock which is used for I2C bus clock
* generation. Not each divider can be selected for I2C bus; this * generation. Not each divider can be selected for I2C bus; this
* function select nearest larger or equal divider. * function select nearest larger or equal divider.
* *
* PARAMETERS: * PARAMETERS:
* i2c_bus - pointer to the bus descriptor structure * i2c_bus - pointer to the bus descriptor structure
* divider - system frequency divider for I2C serial clock. * divider - system frequency divider for I2C serial clock.
* RETURNS: * RETURNS:
* RTEMS_SUCCESSFUL, if operation performed successfully, or * RTEMS_SUCCESSFUL, if operation performed successfully, or
* RTEMS error code when failed. * RTEMS error code when failed.
*/ */
rtems_status_code rtems_status_code
mcfmbus_select_clock_divider(mcfmbus *i2c_bus, int divider) mcfmbus_select_clock_divider(mcfmbus *i2c_bus, int divider)
{ {
int i; int i;
int mbc; int mbc;
struct { struct {
int divider; int divider;
int mbc; int mbc;
} dividers[] ={ } dividers[] ={
{ 20, 0x20 }, { 22, 0x21 }, { 24, 0x22 }, { 26, 0x23 }, { 20, 0x20 }, { 22, 0x21 }, { 24, 0x22 }, { 26, 0x23 },
{ 28, 0x00 }, { 30, 0x01 }, { 32, 0x25 }, { 34, 0x02 }, { 28, 0x00 }, { 30, 0x01 }, { 32, 0x25 }, { 34, 0x02 },
{ 36, 0x26 }, { 40, 0x03 }, { 44, 0x04 }, { 48, 0x05 }, { 36, 0x26 }, { 40, 0x03 }, { 44, 0x04 }, { 48, 0x05 },
{ 56, 0x06 }, { 64, 0x2a }, { 68, 0x07 }, { 72, 0x2B }, { 56, 0x06 }, { 64, 0x2a }, { 68, 0x07 }, { 72, 0x2B },
{ 80, 0x08 }, { 88, 0x09 }, { 96, 0x2D }, { 104, 0x0A }, { 80, 0x08 }, { 88, 0x09 }, { 96, 0x2D }, { 104, 0x0A },
{ 112, 0x2E }, { 128, 0x0B }, { 144, 0x0C }, { 160, 0x0D }, { 112, 0x2E }, { 128, 0x0B }, { 144, 0x0C }, { 160, 0x0D },
{ 192, 0x0E }, { 224, 0x32 }, { 240, 0x0F }, { 256, 0x33 }, { 192, 0x0E }, { 224, 0x32 }, { 240, 0x0F }, { 256, 0x33 },
{ 288, 0x10 }, { 320, 0x11 }, { 384, 0x12 }, { 448, 0x36 }, { 288, 0x10 }, { 320, 0x11 }, { 384, 0x12 }, { 448, 0x36 },
{ 480, 0x13 }, { 512, 0x37 }, { 576, 0x14 }, { 640, 0x15 }, { 480, 0x13 }, { 512, 0x37 }, { 576, 0x14 }, { 640, 0x15 },
{ 768, 0x16 }, { 896, 0x3A }, { 960, 0x17 }, { 1024, 0x3B }, { 768, 0x16 }, { 896, 0x3A }, { 960, 0x17 }, { 1024, 0x3B },
{ 1152, 0x18 }, { 1280, 0x19 }, { 1536, 0x1A }, { 1792, 0x3E }, { 1152, 0x18 }, { 1280, 0x19 }, { 1536, 0x1A }, { 1792, 0x3E },
{ 1920, 0x1B }, { 2048, 0x3F }, { 2304, 0x1C }, { 2560, 0x1D }, { 1920, 0x1B }, { 2048, 0x3F }, { 2304, 0x1C }, { 2560, 0x1D },
{ 3072, 0x1E }, { 3840, 0x1F } { 3072, 0x1E }, { 3840, 0x1F }
}; };
if (i2c_bus == NULL) if (i2c_bus == NULL)
return RTEMS_INVALID_ADDRESS; return RTEMS_INVALID_ADDRESS;
for (i = 0, mbc = -1; i < sizeof(dividers)/sizeof(dividers[0]); i++) for (i = 0, mbc = -1; i < sizeof(dividers)/sizeof(dividers[0]); i++) {
{ mbc = dividers[i].mbc;
mbc = dividers[i].mbc; if (dividers[i].divider >= divider) {
if (dividers[i].divider >= divider) break;
{
break;
}
} }
*MCF5206E_MFDR(i2c_bus->base) = mbc; }
return RTEMS_SUCCESSFUL; *MCF5206E_MFDR(i2c_bus->base) = mbc;
return RTEMS_SUCCESSFUL;
} }
/* mcfmbus_initialize -- /* mcfmbus_initialize --
* Initialize ColdFire MBUS I2C bus controller. * Initialize ColdFire MBUS I2C bus controller.
* *
* PARAMETERS: * PARAMETERS:
* i2c_bus - pointer to the bus descriptor structure * i2c_bus - pointer to the bus descriptor structure
* base - ColdFire internal peripherial base address * base - ColdFire internal peripherial base address
* *
* RETURNS: * RETURNS:
* RTEMS_SUCCESSFUL, or RTEMS error code when initialization failed. * RTEMS_SUCCESSFUL, or RTEMS error code when initialization failed.
*/ */
rtems_status_code rtems_status_code mcfmbus_initialize(mcfmbus *i2c_bus, uint32_t base)
mcfmbus_initialize(mcfmbus *i2c_bus, uint32_t base)
{ {
rtems_interrupt_level level; rtems_interrupt_level level;
rtems_status_code sc; rtems_status_code sc;
if (mbus != NULL) /* Check if already initialized */ if (mbus != NULL) /* Check if already initialized */
return RTEMS_RESOURCE_IN_USE; return RTEMS_RESOURCE_IN_USE;
if (i2c_bus == NULL) if (i2c_bus == NULL)
return RTEMS_INVALID_ADDRESS; return RTEMS_INVALID_ADDRESS;
i2c_bus->base = base; i2c_bus->base = base;
i2c_bus->state = STATE_IDLE; i2c_bus->state = STATE_IDLE;
i2c_bus->msg = NULL; i2c_bus->msg = NULL;
i2c_bus->cmsg = NULL; i2c_bus->cmsg = NULL;
i2c_bus->nmsg = 0; i2c_bus->nmsg = 0;
i2c_bus->byte = 0; i2c_bus->byte = 0;
sc = rtems_interrupt_catch( sc = rtems_interrupt_catch(
mcfmbus_interrupt_handler, mcfmbus_interrupt_handler,
24 + ((*MCF5206E_ICR(base, MCF5206E_INTR_MBUS) & MCF5206E_ICR_IL) >> 24 + ((*MCF5206E_ICR(base, MCF5206E_INTR_MBUS) & MCF5206E_ICR_IL) >>
MCF5206E_ICR_IL_S), MCF5206E_ICR_IL_S),
&i2c_bus->oldisr &i2c_bus->oldisr
); );
if (sc != RTEMS_SUCCESSFUL) if (sc != RTEMS_SUCCESSFUL)
return sc; return sc;
mbus = i2c_bus; mbus = i2c_bus;
rtems_interrupt_disable(level); rtems_interrupt_disable(level);
*MCF5206E_IMR(base) &= ~MCF5206E_INTR_BIT(MCF5206E_INTR_MBUS); *MCF5206E_IMR(base) &= ~MCF5206E_INTR_BIT(MCF5206E_INTR_MBUS);
*MCF5206E_MBCR(base) = 0; *MCF5206E_MBCR(base) = 0;
*MCF5206E_MBSR(base) = 0; *MCF5206E_MBSR(base) = 0;
*MCF5206E_MBDR(base) = 0x1F; /* Maximum possible divider is 3840 */ *MCF5206E_MBDR(base) = 0x1F; /* Maximum possible divider is 3840 */
*MCF5206E_MBCR(base) = MCF5206E_MBCR_MEN | MCF5206E_MBCR_MIEN; *MCF5206E_MBCR(base) = MCF5206E_MBCR_MEN | MCF5206E_MBCR_MIEN;
rtems_interrupt_enable(level); rtems_interrupt_enable(level);
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
/* mcfmbus_i2c_transfer -- /* mcfmbus_i2c_transfer --
* Initiate multiple-messages transfer over I2C bus via ColdFire MBUS * Initiate multiple-messages transfer over I2C bus via ColdFire MBUS
* controller. * controller.
* *
* PARAMETERS: * PARAMETERS:
* bus - pointer to MBUS controller descriptor * bus - pointer to MBUS controller descriptor
* nmsg - number of messages * nmsg - number of messages
* msg - pointer to messages array * msg - pointer to messages array
* done - function which is called when transfer is finished * done - function which is called when transfer is finished
* done_arg_ptr - arbitrary argument ptr passed to done funciton * done_arg_ptr - arbitrary argument ptr passed to done funciton
* *
* RETURNS: * RETURNS:
* RTEMS_SUCCESSFUL if transfer initiated successfully, or error * RTEMS_SUCCESSFUL if transfer initiated successfully, or error
* code when failed. * code when failed.
*/ */
rtems_status_code rtems_status_code mcfmbus_i2c_transfer(
mcfmbus_i2c_transfer(mcfmbus *bus, int nmsg, i2c_message *msg, mcfmbus *bus,
i2c_transfer_done done, void *done_arg_ptr) int nmsg,
i2c_message *msg,
i2c_transfer_done done,
void *done_arg_ptr
)
{ {
if (bus != mbus) if (bus != mbus)
return RTEMS_NOT_CONFIGURED; return RTEMS_NOT_CONFIGURED;
bus->done = done; bus->done = done;
bus->done_arg_ptr = done_arg_ptr; bus->done_arg_ptr = (uintptr_t) done_arg_ptr;
bus->cmsg = bus->msg = msg; bus->cmsg = bus->msg = msg;
bus->nmsg = nmsg; bus->nmsg = nmsg;
bus->byte = 0; bus->byte = 0;
bus->state = STATE_IDLE; bus->state = STATE_IDLE;
mcfmbus_machine(bus, EVENT_TRANSFER); mcfmbus_machine(bus, EVENT_TRANSFER);
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
/* mcfmbus_i2c_done -- /* mcfmbus_i2c_done --
* Close ColdFire MBUS I2C bus controller and release all resources. * Close ColdFire MBUS I2C bus controller and release all resources.
* *
* PARAMETERS: * PARAMETERS:
* bus - pointer to MBUS controller descriptor * bus - pointer to MBUS controller descriptor
* *
* RETURNS: * RETURNS:
* RTEMS_SUCCESSFUL, if transfer initiated successfully, or error * RTEMS_SUCCESSFUL, if transfer initiated successfully, or error
* code when failed. * code when failed.
*/ */
rtems_status_code rtems_status_code mcfmbus_i2c_done(mcfmbus *i2c_bus)
mcfmbus_i2c_done(mcfmbus *i2c_bus)
{ {
rtems_status_code sc; rtems_status_code sc;
uint32_t base; uint32_t base;
if (mbus == NULL) if (mbus == NULL)
return RTEMS_NOT_CONFIGURED; return RTEMS_NOT_CONFIGURED;
if (mbus != i2c_bus) if (mbus != i2c_bus)
return RTEMS_INVALID_ADDRESS; return RTEMS_INVALID_ADDRESS;
base = i2c_bus->base; base = i2c_bus->base;
*MCF5206E_IMR(base) |= MCF5206E_INTR_BIT(MCF5206E_INTR_MBUS); *MCF5206E_IMR(base) |= MCF5206E_INTR_BIT(MCF5206E_INTR_MBUS);
*MCF5206E_MBCR(base) = 0; *MCF5206E_MBCR(base) = 0;
sc = rtems_interrupt_catch( sc = rtems_interrupt_catch(
i2c_bus->oldisr, i2c_bus->oldisr,
24 + ((*MCF5206E_ICR(base, MCF5206E_INTR_MBUS) & MCF5206E_ICR_IL) >> 24 + ((*MCF5206E_ICR(base, MCF5206E_INTR_MBUS) & MCF5206E_ICR_IL) >>
MCF5206E_ICR_IL_S), MCF5206E_ICR_IL_S),
NULL NULL
); );
return sc; return sc;
} }