This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
lpc2xxx HAL and CAN driver patch
- From: Alexey Shusharin <mrfinch at mail dot ru>
- To: ecos-patches at ecos dot sourceware dot org
- Date: Fri, 23 May 2008 14:34:10 +0700
- Subject: lpc2xxx HAL and CAN driver patch
Hi,
New version of lpc2xxx (with suffix /01) has substantial changes in
contrast with previous versions. Mainly there are error corrections. But
i was surprised that it has other CAN controller numeration in LUT table
and so loses backward compatibility.
This patch adds suffix option to lpc2xxx HAL configuration and changes
CAN controller enumeration in compliance with this option.
Also this patch adds CAN interrupt priorities options. CAN driver
doesn't care about interrupt priority and set its value to 0 (highest
priority), but i think it's not correct. Moreover if ASSERT is enabled,
CAN initialisation is failed. I set number of priority to 16 by default,
which means non vectored IRQ (the lowest priority).
Best regards
Alexey Shusharin
diff -bur /opt/ecos-repo/cvs/ecos/packages/devs/can/arm/lpc2xxx/current/cdl/can_lpc2xxx.cdl ./devs/can/arm/lpc2xxx/current/cdl/can_lpc2xxx.cdl
--- /opt/ecos-repo/cvs/ecos/packages/devs/can/arm/lpc2xxx/current/cdl/can_lpc2xxx.cdl 2007-07-31 14:53:36.000000000 +0700
+++ ./devs/can/arm/lpc2xxx/current/cdl/can_lpc2xxx.cdl 2008-05-23 11:46:41.000000000 +0700
@@ -229,8 +229,49 @@
identifier."
}
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_CAN[set ::channel]_RX_INT_PRIORITY {
+ display "Priority level of CAN module [set ::channel] receive interrupt"
+ flavor data
+ default_value 16
+ legal_values 0 to 16
+ description "
+ This option sets CAN module [set ::channel] device receive interrupt priority level.
+ We support up to 17 interrupt levels. Interrupts 0 - 15
+ are vectored interrupt requests. Priority 16 indicates a
+ non vectored IRQ. Vectored IRQs have the higher priority
+ then non vectored IRQs and slot 0 has the highest priority
+ and slot 15 has the lowest."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_CAN[set ::channel]_TX_INT_PRIORITY {
+ display "Priority level of CAN module [set ::channel] transmit interrupt"
+ flavor data
+ default_value 16
+ legal_values 0 to 16
+ description "
+ This option sets CAN module [set ::channel] device transmit interrupt priority level.
+ We support up to 17 interrupt levels. Interrupts 0 - 15
+ are vectored interrupt requests. Priority 16 indicates a
+ non vectored IRQ. Vectored IRQs have the higher priority
+ then non vectored IRQs and slot 0 has the highest priority
+ and slot 15 has the lowest."
}
}
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_ERR_INT_PRIORITY {
+ display "Priority level of CAN error interrupt"
+ flavor data
+ default_value 16
+ legal_values 0 to 16
+ description "
+ This option sets CAN device error interrupt priority level.
+ We support up to 17 interrupt levels. Interrupts 0 - 15
+ are vectored interrupt requests. Priority 16 indicates a
+ non vectored IRQ. Vectored IRQs have the higher priority
+ then non vectored IRQs and slot 0 has the highest priority
+ and slot 15 has the lowest."
+ }
cdl_option CYGPKG_DEVS_CAN_LPC2XXX_TESTS {
display "CAN LPC2xxx device driver tests"
diff -bur /opt/ecos-repo/cvs/ecos/packages/devs/can/arm/lpc2xxx/current/ChangeLog ./devs/can/arm/lpc2xxx/current/ChangeLog
--- /opt/ecos-repo/cvs/ecos/packages/devs/can/arm/lpc2xxx/current/ChangeLog 2007-08-17 15:48:57.000000000 +0700
+++ ./devs/can/arm/lpc2xxx/current/ChangeLog 2008-05-23 13:34:56.000000000 +0700
@@ -1,3 +1,13 @@
+2008-05-23 Alexey Shusharin <mrfinch@mail.ru>
+
+ * cdl/can_lpc2xxx.cdl: add CAN interrupt priorities
+
+ * src/can_lpc2xxx.c: add CAN interrupt priorities,
+ repair "chan" definition missing in rx_ISR
+
+ * src/can_accfilt_lpc2xxx.c: add various types of CAN controllers
+ numbering (depends on LPC2XXX version)
+
2007-08-17 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
* src/can_lpc2xxx.c: The definition of "info" is missing when only
diff -bur /opt/ecos-repo/cvs/ecos/packages/devs/can/arm/lpc2xxx/current/src/can_accfilt_lpc2xxx.c ./devs/can/arm/lpc2xxx/current/src/can_accfilt_lpc2xxx.c
--- /opt/ecos-repo/cvs/ecos/packages/devs/can/arm/lpc2xxx/current/src/can_accfilt_lpc2xxx.c 2007-07-31 14:53:36.000000000 +0700
+++ ./devs/can/arm/lpc2xxx/current/src/can_accfilt_lpc2xxx.c 2008-05-23 12:08:25.000000000 +0700
@@ -72,6 +72,17 @@
// Declarations
//===========================================================================
//--------------------------------------------------------------------------
+// On no-suffix and /00 devices, the CAN controllers are numbered 1 to n
+// (n = 2 or 4) in the LUT tables. However, on /01 devices, the CAN controllers
+// are numbered 0 to nâ1 in the LUT tables.
+
+#ifdef CYGHWR_HAL_ARM_LPC2XXX_SUFFIX_01
+# define LPC2XXX_CAN_FIRST_IN_LUT (0)
+#else
+# define LPC2XXX_CAN_FIRST_IN_LUT (1)
+#endif
+
+//--------------------------------------------------------------------------
// Lowlevel acceptance filter access
//
#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
@@ -602,7 +613,7 @@
// Here we rely on the ISR vector ordering for calculaion of of channel number
// Maybe this is not the right way for newer LPC parts
//
- new_entry.channel_no = (CAN_ISRVEC(info) - CYGNUM_HAL_INTERRUPT_CAN1_TX) + 1;
+ new_entry.channel_no = (CAN_ISRVEC(info) - CYGNUM_HAL_INTERRUPT_CAN1_TX) + LPC2XXX_CAN_FIRST_IN_LUT;
//
// If lower_id == upper_id then we know that we have to setup a single message filter
@@ -686,7 +697,7 @@
cyg_uint16 entries;
cyg_uint32 TableStartAddress = CAN_ACCFILT_SFF_SA;
lpc2xxx_accfilt_entry_t Entry;
- cyg_uint8 channel_no = (CAN_ISRVEC(info) - CYGNUM_HAL_INTERRUPT_CAN1_TX) + 1;
+ cyg_uint8 channel_no = (CAN_ISRVEC(info) - CYGNUM_HAL_INTERRUPT_CAN1_TX) + LPC2XXX_CAN_FIRST_IN_LUT;
cyg_uint16 entry_idx;
//
@@ -778,7 +789,7 @@
while (lpc2xxx_global_can_info.active_channels[i])
{
lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)lpc2xxx_global_can_info.active_channels[i++]->dev_priv;
- cyg_uint8 channel_no = (CAN_ISRVEC(info) - CYGNUM_HAL_INTERRUPT_CAN1_TX) + 1;
+ cyg_uint8 channel_no = (CAN_ISRVEC(info) - CYGNUM_HAL_INTERRUPT_CAN1_TX) + LPC2XXX_CAN_FIRST_IN_LUT;
#ifdef CYGOPT_IO_CAN_STD_CAN_ID
accfilt_entry.column.lower = (channel_no << 13) | (0x000 & ACCFILT_STD_ID_MASK);
diff -bur /opt/ecos-repo/cvs/ecos/packages/devs/can/arm/lpc2xxx/current/src/can_lpc2xxx.c ./devs/can/arm/lpc2xxx/current/src/can_lpc2xxx.c
--- /opt/ecos-repo/cvs/ecos/packages/devs/can/arm/lpc2xxx/current/src/can_lpc2xxx.c 2008-04-25 12:43:07.000000000 +0700
+++ ./devs/can/arm/lpc2xxx/current/src/can_lpc2xxx.c 2008-05-23 13:07:43.000000000 +0700
@@ -416,8 +416,10 @@
{
cyg_interrupt tx_interrupt;
cyg_handle_t tx_interrupt_handle;
+ cyg_uint8 tx_interrupt_priority;
cyg_interrupt rx_interrupt;
cyg_handle_t rx_interrupt_handle;
+ cyg_uint8 rx_interrupt_priority;
cyg_can_state state; // state of CAN controller
cyg_uint32 icr; // buffers icr register
cyg_uint8 flags; // flags indicating several states
@@ -438,19 +440,23 @@
//
#define LPC2XXX_CTRL_NOT_INITIALIZED 0xFF
#if CYGINT_IO_CAN_CHANNELS > 1
-#define LPC2XXX_CAN_INFO(_l, _base, _isrvec, _flags) \
+#define LPC2XXX_CAN_INFO(_l, _base, _isrvec, _tx_priority, _rx_priority, _flags) \
lpc2xxx_can_info_t _l = { \
state : LPC2XXX_CTRL_NOT_INITIALIZED, \
base : (_base), \
isrvec : (_isrvec), \
+ tx_interrupt_priority : (_tx_priority), \
+ rx_interrupt_priority : (_rx_priority), \
flags : (_flags), \
icr : 0, \
LPC2XXX_CAN_INFO_LAST_TX_ID_INIT \
};
#else
-#define LPC2XXX_CAN_INFO(_l, _flags) \
+#define LPC2XXX_CAN_INFO(_l, _tx_priority, _rx_priority, _flags) \
lpc2xxx_can_info_t _l = { \
state : CYGNUM_CAN_STATE_STOPPED, \
+ tx_interrupt_priority : (_tx_priority), \
+ rx_interrupt_priority : (_rx_priority), \
flags : (_flags), \
icr : 0, \
LPC2XXX_CAN_INFO_LAST_TX_ID_INIT \
@@ -517,6 +523,8 @@
LPC2XXX_CAN_INFO(lpc2xxx_can0_info,
CAN_CTRL_1_REG_BASE,
CYGNUM_HAL_INTERRUPT_CAN1_TX,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN0_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN0_RX_INT_PRIORITY,
CAN0_FLAG_STARTUP_ACCFILT_SETUP);
#endif
@@ -524,6 +532,8 @@
LPC2XXX_CAN_INFO(lpc2xxx_can1_info,
CAN_CTRL_2_REG_BASE,
CYGNUM_HAL_INTERRUPT_CAN2_TX,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN1_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN1_RX_INT_PRIORITY,
CAN1_FLAG_STARTUP_ACCFILT_SETUP);
#endif
@@ -531,6 +541,8 @@
LPC2XXX_CAN_INFO(lpc2xxx_can2_info,
CAN_CTRL_3_REG_BASE,
CYGNUM_HAL_INTERRUPT_CAN3_TX,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN2_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN2_RX_INT_PRIORITY,
CAN2_FLAG_STARTUP_ACCFILT_SETUP);
#endif
@@ -538,29 +550,43 @@
LPC2XXX_CAN_INFO(lpc2xxx_can3_info,
CAN_CTRL_4_REG_BASE,
CYGNUM_HAL_INTERRUPT_CAN4_TX,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN3_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN3_RX_INT_PRIORITY,
CAN3_FLAG_STARTUP_ACCFILT_SETUP);
#endif
#else // CYGINT_IO_CAN_CHANNELS == 1
#ifdef CYGINT_DEVS_CAN_LPC2XXX_CAN0
-LPC2XXX_CAN_INFO(lpc2xxx_can0_info, CAN0_FLAG_STARTUP_ACCFILT_SETUP);
+LPC2XXX_CAN_INFO(lpc2xxx_can0_info,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN0_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN0_RX_INT_PRIORITY,
+ CAN0_FLAG_STARTUP_ACCFILT_SETUP);
#define CAN_CTRL_SINGLETON_BASE CAN_CTRL_1_REG_BASE
#define CAN_SINGLETON_ISRVEC CYGNUM_HAL_INTERRUPT_CAN1_TX
#endif
#ifdef CYGINT_DEVS_CAN_LPC2XXX_CAN1
-LPC2XXX_CAN_INFO(lpc2xxx_can1_info, CAN1_FLAG_STARTUP_ACCFILT_SETUP);
+LPC2XXX_CAN_INFO(lpc2xxx_can1_info,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN1_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN1_RX_INT_PRIORITY,
+ CAN1_FLAG_STARTUP_ACCFILT_SETUP);
#define CAN_CTRL_SINGLETON_BASE CAN_CTRL_2_REG_BASE
#define CAN_SINGLETON_ISRVEC CYGNUM_HAL_INTERRUPT_CAN2_TX
#endif
#ifdef CYGINT_DEVS_CAN_LPC2XXX_CAN2
-LPC2XXX_CAN_INFO(lpc2xxx_can2_info, CAN2_FLAG_STARTUP_ACCFILT_SETUP);
+LPC2XXX_CAN_INFO(lpc2xxx_can2_info,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN2_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN2_RX_INT_PRIORITY,
+ CAN2_FLAG_STARTUP_ACCFILT_SETUP);
#define CAN_CTRL_SINGLETON_BASE CAN_CTRL_3_REG_BASE
#define CAN_SINGLETON_ISRVEC CYGNUM_HAL_INTERRUPT_CAN3_TX
#endif
#ifdef CYGINT_DEVS_CAN_LPC2XXX_CAN3
-LPC2XXX_CAN_INFO(lpc2xxx_can3_info, CAN3_FLAG_STARTUP_ACCFILT_SETUP);
+LPC2XXX_CAN_INFO(lpc2xxx_can3_info,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN3_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN3_RX_INT_PRIORITY,
+ CAN3_FLAG_STARTUP_ACCFILT_SETUP);
#define CAN_CTRL_SINGLETON_BASE CAN_CTRL_4_REG_BASE
#define CAN_SINGLETON_ISRVEC CYGNUM_HAL_INTERRUPT_CAN4_TX
#endif
@@ -767,7 +793,7 @@
// Create TX interrupt
//
cyg_drv_interrupt_create(CAN_ISRVEC(info),
- 0, // Priority does not matter LPC2xxx
+ info->tx_interrupt_priority,
(cyg_addrword_t)chan, // Data item passed to interrupt handler
lpc2xxx_can_tx_ISR,
lpc2xxx_can_tx_DSR,
@@ -780,7 +806,7 @@
// Create RX interrupt
//
cyg_drv_interrupt_create(CAN_ISRVEC(info) + 6,
- 0, // Priority does not matter for LPC2xxx
+ info->rx_interrupt_priority,
(cyg_addrword_t)chan, // Data item passed to interrupt handler
lpc2xxx_can_rx_ISR,
lpc2xxx_can_rx_DSR,
@@ -800,7 +826,7 @@
// Create err interrupt
//
cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_CAN,
- 0, // Priority does not matter for LPX2xxx
+ CYGNUM_DEVS_CAN_LPC2XXX_ERR_INT_PRIORITY,
0, // Data item passed to interrupt handler
lpc2xxx_can_err_ISR,
lpc2xxx_can_err_DSR,
@@ -1768,9 +1794,9 @@
static cyg_uint32 lpc2xxx_can_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
{
cyg_uint32 regval;
- CAN_DECLARE_CHAN(data); // declares chan pointer if required
#ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
+ can_channel* chan = (can_channel*)data;
lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *) chan->dev_priv;
cyg_uint32 id;
cyg_uint32 index;
@@ -1800,6 +1826,7 @@
}
}
#else
+ CAN_DECLARE_CHAN(data); // declares chan pointer if requred
CAN_DECLARE_INFO(info); // declares info pointer if reuired
#endif
diff -bur /opt/ecos-repo/cvs/ecos/packages/hal/arm/lpc2xxx/var/current/cdl/hal_arm_lpc2xxx.cdl ./hal/arm/lpc2xxx/var/current/cdl/hal_arm_lpc2xxx.cdl
--- /opt/ecos-repo/cvs/ecos/packages/hal/arm/lpc2xxx/var/current/cdl/hal_arm_lpc2xxx.cdl 2007-07-31 01:09:47.000000000 +0700
+++ ./hal/arm/lpc2xxx/var/current/cdl/hal_arm_lpc2xxx.cdl 2008-05-23 12:43:01.000000000 +0700
@@ -110,6 +110,18 @@
lpc214x has USB) which affect which features should be
available in the HAL."
}
+
+ cdl_option CYGHWR_HAL_ARM_LPC2XXX_SUFFIX {
+ display "Suffix of LPC2XXX device"
+ flavor data
+ legal_values { "no_suffix" "00" "01" }
+ default_value { "no_suffix" }
+ description "
+ This option sets the version number of LPC2XXX microcontroller.
+ To denote different version of LPC2XXX the following suffixes
+ are used: no suffix, /00, /01. All /01 version contain
+ enhanced features."
+ }
}
# Important! Be very careful changing this value. That will always
@@ -185,7 +197,7 @@
cdl_option CYGHWR_HAL_ARM_LPC2XXX_EXTINT_ERRATA {
display "EXTINT.1 errata workaround"
flavor bool
- default_value 1
+ default_value { CYGHWR_HAL_ARM_LPC2XXX_SUFFIX != "01" }
description "
On some chips writing to the EXTPOLAR or EXTMODE registers
diff -bur /opt/ecos-repo/cvs/ecos/packages/hal/arm/lpc2xxx/var/current/ChangeLog ./hal/arm/lpc2xxx/var/current/ChangeLog
--- /opt/ecos-repo/cvs/ecos/packages/hal/arm/lpc2xxx/var/current/ChangeLog 2007-09-15 21:43:22.000000000 +0700
+++ ./hal/arm/lpc2xxx/var/current/ChangeLog 2008-05-23 13:29:37.000000000 +0700
@@ -1,3 +1,8 @@
+2008-05-23 Alexey Shusharin <mrfinch@mail.ru>
+
+ * cdl/hal_arm_lpc2xxx.cdl: add suffix option to denote
+ different versions of LPC2XXX
+
2007-08-23 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
* include/hal_var_ints.h: use interrupt priority 16 for