Mercurial > ecos-v3_0-branch
annotate packages/devs/can/arm/lpc2xxx/current/src/can_accfilt_lpc2xxx.c @ 2509:a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
arbitration lost interrupt optional. Added option
CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY to configure the interrupt
priority for global CAN interrupt in LPC24xx variants.
* include/can_lpc2xxx_baudrates.h: Replaced CYGNUM_CAN_LPC2XXX_VPB_CLK
by CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK because newer variants like LPC24xx
do not have a global VPB_CLK.
* src/can_accfilt_lpc2xxx.c: Adjusted LPC2XXX_CAN_FIRST_IN_LUT to
be 0 for LPC24xxx variants. Added macro CAN_CHAN_NO_LUT(_info_) to
abstract channel numbering from acceptance filter code.
* src/can_lpc2xxx.c: Removed icr data field from lpc2xxx_can_info_st
structure because it is not required any longer. A lot of small
modifications to make the driver usable with newer LPC2xxx variants like
LPC24xx. ISR and DSR code changed - instead of disabling interrupts in
IER register they are disabled in VIC by using cyg_drv_interrupt_mask()
function calls. Added global CAN ISR and DSR for LPC24xx variants
(they do not support individual interrupt vectors for RX and TX
interrupts). Moved LUT error checking code from ISR into DSR to keep
ISR as short as possible and made LUT error checking code optional.
* 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)
| author | asl |
|---|---|
| date | Tue, 22 Jul 2008 19:40:02 +0000 |
| parents | e8eaf852a606 |
| children | 74dbf4c3f2e1 |
| rev | line source |
|---|---|
| 2409 | 1 //========================================================================== |
| 2 // | |
| 3 // devs/can/arm/lpc2xxx/current/src/can_accfilt_lpc2xxx.c | |
| 4 // | |
| 5 // Acceptance filter management for LPC2xxx CAN driver | |
| 6 // | |
| 7 //========================================================================== | |
| 8 //####ECOSGPLCOPYRIGHTBEGIN#### | |
| 9 // ------------------------------------------- | |
| 10 // This file is part of eCos, the Embedded Configurable Operating System. | |
| 11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. | |
| 12 // Copyright (C) 2003 Gary Thomas | |
| 13 // | |
| 14 // eCos is free software; you can redistribute it and/or modify it under | |
| 15 // the terms of the GNU General Public License as published by the Free | |
| 16 // Software Foundation; either version 2 or (at your option) any later version. | |
| 17 // | |
| 18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY | |
| 19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 21 // for more details. | |
| 22 // | |
| 23 // You should have received a copy of the GNU General Public License along | |
| 24 // with eCos; if not, write to the Free Software Foundation, Inc., | |
| 25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | |
| 26 // | |
| 27 // As a special exception, if other files instantiate templates or use macros | |
| 28 // or inline functions from this file, or you compile this file and link it | |
| 29 // with other works to produce a work based on this file, this file does not | |
| 30 // by itself cause the resulting work to be covered by the GNU General Public | |
| 31 // License. However the source code for this file must still be made available | |
| 32 // in accordance with section (3) of the GNU General Public License. | |
| 33 // | |
| 34 // This exception does not invalidate any other reasons why a work based on | |
| 35 // this file might be covered by the GNU General Public License. | |
| 36 // | |
| 37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. | |
| 38 // at http://sources.redhat.com/ecos/ecos-license/ | |
| 39 // ------------------------------------------- | |
| 40 //####ECOSGPLCOPYRIGHTEND#### | |
| 41 //========================================================================== | |
| 42 //#####DESCRIPTIONBEGIN#### | |
| 43 // | |
| 44 // Author(s): Uwe Kindler | |
| 45 // Contributors: Uwe Kindler | |
| 46 // Date: 2007-05-28 | |
| 47 // Purpose: Support LPC2xxx on-chip CAN acceptance filters | |
| 48 // Description: | |
| 49 // | |
| 50 //####DESCRIPTIONEND#### | |
| 51 // | |
| 52 //========================================================================== | |
| 53 | |
| 54 | |
| 55 //=========================================================================== | |
| 56 // Data types | |
| 57 //=========================================================================== | |
| 58 // | |
| 59 // Acceptance filter entry | |
| 60 // | |
| 61 typedef struct lpc2xxx_accfilt_entry | |
| 62 { | |
| 63 cyg_uint32 data; // the value inclusive channel number | |
| 64 cyg_uint32 id; | |
| 65 cyg_uint32 lower_id_bound; | |
| 66 cyg_uint32 upper_id_bound; | |
| 67 cyg_uint8 channel_no; | |
| 68 } lpc2xxx_accfilt_entry_t; | |
| 69 | |
| 70 | |
| 71 //=========================================================================== | |
| 72 // Declarations | |
| 73 //=========================================================================== | |
| 74 //-------------------------------------------------------------------------- | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
75 // On no-suffix and /00 devices, the CAN controllers are numbered 1 to n |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
76 // (n = 2 or 4) in the LUT tables. However, on /01 devices, the CAN controllers |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
77 // are numbered 0 to n�1 in the LUT tables. |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
78 // |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
79 // On the LPC2468 the LUT channel numbers are also numbered from 0 - 4. |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
80 // |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
81 #if defined(CYGHWR_HAL_ARM_LPC2XXX_SUFFIX_01) || (CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION == 4) |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
82 # define LPC2XXX_CAN_FIRST_IN_LUT (0) |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
83 #else |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
84 # define LPC2XXX_CAN_FIRST_IN_LUT (1) |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
85 #endif |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
86 |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
87 // |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
88 // This macro calculates the chanel number from the channel info. The channel |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
89 // number is numbered from 0 - 3 but in the LUT the channel number may differ |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
90 // depending on the device suffix. For some devices the channel number in |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
91 // LUT are numbered 0 - 3 and for other devices the channels in LUT are |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
92 // numbered 1 - 4. This macro abstrats this fact from the acceptance filter |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
93 // code |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
94 // |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
95 #define CAN_CHAN_NO_LUT(_info_) (CAN_CHAN_NO(_info_) + LPC2XXX_CAN_FIRST_IN_LUT) |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
96 |
|
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
97 //-------------------------------------------------------------------------- |
| 2409 | 98 // Lowlevel acceptance filter access |
| 99 // | |
| 100 #ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG | |
| 101 static bool lpc2xxx_can_accfilt_add(lpc2xxx_can_info_t *info, | |
| 102 cyg_uint32 lower_id, | |
| 103 cyg_uint32 upper_id, | |
| 104 cyg_can_id_type ext); | |
| 105 void lpc2xxx_can_accfilt_ram_insert_entry(cyg_uint32 TableAddress, cyg_uint16 EntryNo); | |
| 106 void lpc2xxx_can_accfilt_ram_remove_entry(cyg_uint32 TableAddress, cyg_uint16 EntryNo); | |
| 107 void lpc2xxx_can_accfilt_remove_all_ctrl_entries(lpc2xxx_can_info_t *info); | |
| 108 #else | |
| 109 static void lpc2xxx_can_accfilt_simple_rx_all(void); | |
| 110 #endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG | |
| 111 void lpc2xxx_can_accfilt_reset(void); | |
| 112 | |
| 113 #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG | |
| 114 void lpc2xxx_can_accfilt_dbg_dump(void); | |
| 115 void lpc2xxx_can_reg_dump(struct cyg_devtab_entry* devtab_entry); | |
| 116 #endif | |
| 117 | |
| 118 | |
| 119 #ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG | |
| 120 //=========================================================================== | |
| 121 // Calculate address of entry in certain table | |
| 122 //=========================================================================== | |
| 123 static cyg_uint32 lpc2xxx_can_accfilt_calc_entry_address(cyg_uint32 TableAddressRegister, cyg_uint16 EntryNo) | |
| 124 { | |
| 125 cyg_uint32 EntryAddress = 0xFFFFFFFF; | |
| 126 cyg_uint32 TableAddress; | |
| 127 | |
| 128 HAL_READ_UINT32(TableAddressRegister, TableAddress); | |
| 129 switch (TableAddressRegister) | |
| 130 { | |
| 131 #ifdef CYGOPT_IO_CAN_STD_CAN_ID | |
| 132 case CAN_ACCFILT_SFF_SA: | |
| 133 EntryAddress = ((EntryNo / 2) << 2) + TableAddress; | |
| 134 break; | |
| 135 | |
| 136 case CAN_ACCFILT_SFF_GRP_SA: | |
| 137 EntryAddress = TableAddress + (EntryNo << 2); | |
| 138 break; | |
| 139 #endif // CYGOPT_IO_CAN_STD_CAN_ID | |
| 140 | |
| 141 #ifdef CYGOPT_IO_CAN_EXT_CAN_ID | |
| 142 case CAN_ACCFILT_EFF_SA: | |
| 143 EntryAddress = TableAddress + (EntryNo << 2); | |
| 144 break; | |
| 145 | |
| 146 case CAN_ACCFILT_EFF_GRP_SA: | |
| 147 EntryAddress = TableAddress + (EntryNo << 3); | |
| 148 break; | |
| 149 #endif // CYGOPT_IO_CAN_EXT_CAN_ID | |
| 150 default: | |
| 151 CYG_ASSERT(0, "Wrong TableAddressRegister"); | |
| 152 } | |
| 153 | |
| 154 return EntryAddress; | |
| 155 } | |
| 156 | |
| 157 | |
| 158 //=========================================================================== | |
| 159 // Remove one single entry from acceptance filter table | |
| 160 //=========================================================================== | |
| 161 void lpc2xxx_can_accfilt_ram_remove_entry(cyg_uint32 Table, cyg_uint16 EntryNo) | |
| 162 { | |
| 163 cyg_int32 remove_address = lpc2xxx_can_accfilt_calc_entry_address(Table, EntryNo); | |
| 164 cyg_int32 entry_address; | |
| 165 lsc_buf_t lsc_val; | |
| 166 cyg_uint8 entry_size = sizeof(cyg_uint32); | |
| 167 cyg_uint32 sff_sa; | |
| 168 cyg_uint32 sff_grp_sa; | |
| 169 cyg_uint32 eff_sa; | |
| 170 cyg_uint32 eff_grp_sa; | |
| 171 cyg_int32 end_of_table; | |
| 172 | |
| 173 HAL_READ_UINT32(CAN_ACCFILT_SFF_SA, sff_sa); | |
| 174 HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa); | |
| 175 HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa); | |
| 176 HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa); | |
| 177 HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table); | |
| 178 | |
| 179 // | |
| 180 // Do not try to remove from an empty table | |
| 181 // | |
| 182 if (!end_of_table) | |
| 183 { | |
| 184 return; | |
| 185 } | |
| 186 | |
| 187 entry_address = remove_address; | |
| 188 | |
| 189 if ((remove_address < eff_grp_sa) && (CAN_ACCFILT_EFF_GRP_SA != Table)) | |
| 190 { | |
| 191 if ((remove_address < eff_sa) && (CAN_ACCFILT_EFF_SA != Table)) | |
| 192 { | |
| 193 if ((remove_address < sff_grp_sa) && (CAN_ACCFILT_SFF_GRP_SA != Table)) | |
| 194 { | |
| 195 lsc_buf_t nextval; | |
| 196 | |
| 197 if (EntryNo % 2) | |
| 198 { | |
| 199 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + remove_address, lsc_val.dword); | |
| 200 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + remove_address + sizeof(cyg_uint32), nextval.dword); | |
| 201 lsc_val.column.upper = nextval.column.lower; | |
| 202 entry_address += sizeof(cyg_uint32); | |
| 203 } | |
| 204 | |
| 205 // | |
| 206 // Start copy immediatelly after removed entry | |
| 207 // | |
| 208 while (entry_address < sff_grp_sa) | |
| 209 { | |
| 210 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, lsc_val.dword); | |
| 211 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address + sizeof(cyg_uint32), nextval.dword); | |
| 212 lsc_val.column.lower = lsc_val.column.upper; | |
| 213 lsc_val.column.upper = nextval.column.lower; | |
| 214 HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, lsc_val.dword); | |
| 215 entry_address += sizeof(cyg_uint32); | |
| 216 } | |
| 217 | |
| 218 // | |
| 219 // now check if the lower identifier is disabled - if it is disabled, then | |
| 220 // also the upper identifier is invalid and we can remove the entry completely | |
| 221 // if the lower identifier is not disabled, then it is valid and we need | |
| 222 // to disable the upper identifier because it contains an invalid entry | |
| 223 // | |
| 224 if (lsc_val.column.lower & ACCFILT_STD_DIS) | |
| 225 { | |
| 226 sff_grp_sa -= sizeof(cyg_uint32); | |
| 227 entry_address = sff_grp_sa; | |
| 228 } | |
| 229 else | |
| 230 { | |
| 231 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32), lsc_val.dword); | |
| 232 lsc_val.column.upper = 0xffff; | |
| 233 HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32), lsc_val.dword); | |
| 234 entry_size = 0; // we do not need to remove anything | |
| 235 } | |
| 236 } // if (pLine < pStdGrpStart) | |
| 237 | |
| 238 eff_sa -= entry_size; | |
| 239 } // if (pLine < pExtIdStart) | |
| 240 | |
| 241 eff_grp_sa -= entry_size; | |
| 242 } // if (pLine < pExtGrpStart) | |
| 243 | |
| 244 // | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
245 // If no entry was removed then we can leave immediately without changing any |
| 2409 | 246 // table pointers because we only did a change inside the sff table |
| 247 // | |
| 248 if (!entry_size) | |
| 249 { | |
| 250 #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG | |
| 251 lpc2xxx_can_accfilt_dbg_dump(); | |
| 252 #endif | |
| 253 return; | |
| 254 } | |
| 255 | |
| 256 if (CAN_ACCFILT_EFF_GRP_SA == Table) | |
| 257 { | |
| 258 // | |
| 259 // If we are in the area of extended groups then we need to remove | |
| 260 // 2 lines because lower and upper identifier need 1 line each | |
| 261 // | |
| 262 entry_size += sizeof(cyg_uint32); | |
| 263 } | |
| 264 | |
| 265 end_of_table -= entry_size; | |
| 266 | |
| 267 // | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
268 // Move all entries one or two dword downwards - that means we remove a line |
| 2409 | 269 // |
| 270 while (entry_address < end_of_table) | |
| 271 { | |
| 272 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address + entry_size, lsc_val.dword); | |
| 273 HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, lsc_val.dword); | |
| 274 entry_address += sizeof(cyg_uint32); | |
| 275 } | |
| 276 | |
| 277 HAL_WRITE_UINT32(CAN_ACCFILT_SFF_SA, sff_sa); | |
| 278 HAL_WRITE_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa); | |
| 279 HAL_WRITE_UINT32(CAN_ACCFILT_EFF_SA, eff_sa); | |
| 280 HAL_WRITE_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa); | |
| 281 HAL_WRITE_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table); | |
| 282 | |
| 283 #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG | |
| 284 lpc2xxx_can_accfilt_dbg_dump(); | |
| 285 #endif | |
| 286 } | |
| 287 | |
| 288 //=========================================================================== | |
| 289 // Insert one empty line into ram - all entries behind this line will be | |
| 290 // moved one entry upwards | |
| 291 //=========================================================================== | |
| 292 void lpc2xxx_can_accfilt_ram_insert_entry(cyg_uint32 Table, cyg_uint16 EntryNo) | |
| 293 { | |
| 294 cyg_int16 insert_address = lpc2xxx_can_accfilt_calc_entry_address(Table, EntryNo); | |
| 295 cyg_int16 entry_address; | |
| 296 cyg_int16 copy_start = insert_address; | |
| 297 lsc_buf_t lsc_val; | |
| 298 cyg_uint8 entry_size = sizeof(cyg_uint32); | |
| 299 cyg_uint32 sff_sa; | |
| 300 cyg_uint32 sff_grp_sa; | |
| 301 cyg_uint32 eff_sa; | |
| 302 cyg_uint32 eff_grp_sa; | |
| 303 cyg_uint32 end_of_table; | |
| 304 | |
| 305 | |
| 306 HAL_READ_UINT32(CAN_ACCFILT_SFF_SA, sff_sa); | |
| 307 HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa); | |
| 308 HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa); | |
| 309 HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa); | |
| 310 HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table); | |
| 311 | |
| 312 if ((insert_address <= eff_grp_sa) && (CAN_ACCFILT_EFF_GRP_SA != Table)) | |
| 313 { | |
| 314 if ((insert_address <= eff_sa) && (CAN_ACCFILT_EFF_SA != Table)) | |
| 315 { | |
| 316 if ((insert_address <= sff_grp_sa) && (CAN_ACCFILT_SFF_GRP_SA != Table)) | |
| 317 { | |
| 318 // | |
| 319 // If we are in the range of standard identifiers then we need to | |
| 320 // do some special copy procedure for this area because a standard entry | |
| 321 // is only 2 byte long. Copy only til start of area with standard groups | |
| 322 // | |
| 323 if (sff_grp_sa) | |
| 324 { | |
| 325 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32), lsc_val.dword); // read last entry | |
| 326 // | |
| 327 // now check if the upper identifier is disabled - if it is disabled, then | |
| 328 // we have an odd number of std ids in the list. Then we do not need to | |
| 329 // insert a new line - we simply need to copy all entries 2 bytes upwards | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
330 // that means we only need to change the std id area and do not need to touch |
| 2409 | 331 // any other filter id area. |
| 332 // If the last entry is not disabled, then we have a valid filter here. | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
333 // Then we need to insert a complete new line, that means we also have to move |
| 2409 | 334 // all following entries and filter tables one dword upwards. |
| 335 // | |
| 336 if (lsc_val.words.low & ACCFILT_STD_DIS) | |
| 337 { | |
| 338 copy_start = end_of_table + sizeof(cyg_uint32); // we do not need to insert a new line and do not copy anything | |
| 339 entry_size = 0; | |
| 340 } | |
| 341 } | |
| 342 | |
| 343 if (entry_size) | |
| 344 { | |
| 345 copy_start = sff_grp_sa; // copy everything behind std id group | |
| 346 sff_grp_sa += entry_size; | |
| 347 } | |
| 348 } // if (pLine < pStdGrpStart) | |
| 349 | |
| 350 eff_sa += entry_size; | |
| 351 } // if (pLine < pExtIdStart) | |
| 352 | |
| 353 eff_grp_sa += entry_size; | |
| 354 } // if (pLine < pExtGrpStart) | |
| 355 | |
| 356 if (CAN_ACCFILT_EFF_GRP_SA == Table) | |
| 357 { | |
| 358 // | |
| 359 // If we are in the area of extended groups then we need to insert | |
| 360 // 2 lines because lower and upper identifier need 1 line each | |
| 361 // | |
| 362 entry_size += sizeof(cyg_uint32); // one entry is 2 dword long | |
| 363 } | |
| 364 | |
| 365 entry_address = end_of_table - sizeof(cyg_uint32); | |
| 366 end_of_table += entry_size; // add one additional entry | |
| 367 | |
| 368 // | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
369 // Move all entries one or two dwords upwards - that means we insert a new empty line |
| 2409 | 370 // |
| 371 while (entry_address >= copy_start) | |
| 372 { | |
| 373 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address, lsc_val.dword); | |
| 374 HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address + entry_size, lsc_val.dword); | |
| 375 entry_address -= sizeof(cyg_uint32); | |
| 376 } | |
| 377 | |
| 378 // | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
379 // For the std ID area we need a special procedure |
| 2409 | 380 // |
| 381 if (CAN_ACCFILT_SFF_SA == Table) | |
| 382 { | |
| 383 lsc_buf_t preval; | |
| 384 // | |
| 385 // Start copy with last entry of std id table | |
| 386 // | |
| 387 entry_address = sff_grp_sa - sizeof(cyg_uint32); | |
| 388 | |
| 389 while (entry_address > insert_address) | |
| 390 { | |
| 391 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address, lsc_val.dword); | |
| 392 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address - sizeof(cyg_uint32), preval.dword); | |
| 393 lsc_val.column.upper = lsc_val.column.lower; | |
| 394 lsc_val.column.lower = preval.column.upper; | |
| 395 HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address, lsc_val.dword); | |
| 396 entry_address -= sizeof(cyg_uint32); | |
| 397 } | |
| 398 | |
| 399 // | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
400 // If we insert an entry into the lower column, then we need to move the |
| 2409 | 401 // content of the lower column into the upper column |
| 402 // | |
| 403 if (!(EntryNo % 2)) | |
| 404 { | |
| 405 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)insert_address, lsc_val.dword); | |
| 406 lsc_val.column.upper = lsc_val.column.lower; | |
| 407 HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)insert_address, lsc_val.dword); | |
| 408 } | |
| 409 | |
| 410 // | |
| 411 // If we inserted a new line, then we have an odd number of identifiers now | |
| 412 // and need to disable the last (the upper) entry | |
| 413 // | |
| 414 if (entry_size) | |
| 415 { | |
| 416 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32) , lsc_val.dword); | |
| 417 lsc_val.column.upper = 0xFFFF; // disable the entry | |
| 418 HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32) , lsc_val.dword); | |
| 419 } | |
| 420 } | |
| 421 | |
| 422 HAL_WRITE_UINT32(CAN_ACCFILT_SFF_SA, sff_sa); | |
| 423 HAL_WRITE_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa); | |
| 424 HAL_WRITE_UINT32(CAN_ACCFILT_EFF_SA, eff_sa); | |
| 425 HAL_WRITE_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa); | |
| 426 HAL_WRITE_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table); | |
| 427 } | |
| 428 | |
| 429 | |
| 430 //=========================================================================== | |
| 431 // Query number of entries in a certain table | |
| 432 //=========================================================================== | |
| 433 static cyg_uint16 lpc2xxx_can_accfilt_get_table_entries(cyg_uint32 TableStartAddress) | |
| 434 { | |
| 435 cyg_uint32 start; | |
| 436 cyg_uint32 end; | |
| 437 | |
| 438 switch (TableStartAddress) | |
| 439 { | |
| 440 #ifdef CYGOPT_IO_CAN_STD_CAN_ID | |
| 441 case CAN_ACCFILT_SFF_SA: | |
| 442 HAL_READ_UINT32(CAN_ACCFILT_SFF_SA, start); | |
| 443 HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, end); | |
| 444 if (end - start) | |
| 445 { | |
| 446 lsc_buf_t data; | |
| 447 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + end - sizeof(cyg_uint32), data.dword); | |
| 448 if (data.column.upper & ACCFILT_STD_DIS) | |
| 449 { | |
| 450 return (((end - start) >> 1) - 1); | |
| 451 } | |
| 452 } | |
| 453 return (end - start) >> 1; | |
| 454 | |
| 455 case CAN_ACCFILT_SFF_GRP_SA: | |
| 456 HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, start); | |
| 457 HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, end); | |
| 458 return (end - start) >> 2; | |
| 459 #endif // CYGOPT_IO_CAN_STD_CAN_ID | |
| 460 | |
| 461 #ifdef CYGOPT_IO_CAN_EXT_CAN_ID | |
| 462 case CAN_ACCFILT_EFF_SA: | |
| 463 HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, start); | |
| 464 HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, end); | |
| 465 return (end - start) >> 2; | |
| 466 | |
| 467 case CAN_ACCFILT_EFF_GRP_SA: | |
| 468 HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, start); | |
| 469 HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end); | |
| 470 return (end - start) >> 3; | |
| 471 #endif // CYGOPT_IO_CAN_EXT_CAN_ID | |
| 472 default: | |
| 473 CYG_FAIL("Invalid identifier table address"); | |
| 474 return 0; | |
| 475 } // switch (TableStartAddress) | |
| 476 } | |
| 477 | |
| 478 //=========================================================================== | |
| 479 // Query certain entry from table | |
| 480 //=========================================================================== | |
| 481 static void lpc2xxx_can_accfilt_get_entry(cyg_uint32 TableStartAddress, cyg_uint16 EntryNo, lpc2xxx_accfilt_entry_t *pEntry) | |
| 482 { | |
| 483 cyg_uint32 EntryAddress = lpc2xxx_can_accfilt_calc_entry_address(TableStartAddress, EntryNo); | |
| 484 lsc_buf_t Data; | |
| 485 | |
| 486 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + EntryAddress, Data.dword); | |
| 487 pEntry->data = Data.dword; | |
| 488 switch (TableStartAddress) | |
| 489 { | |
| 490 #ifdef CYGOPT_IO_CAN_STD_CAN_ID | |
| 491 case CAN_ACCFILT_SFF_SA: | |
| 492 { | |
| 493 cyg_uint16 column; | |
| 494 if (EntryNo % 2) | |
| 495 { | |
| 496 column = Data.column.upper; | |
| 497 } | |
| 498 else | |
| 499 { | |
| 500 column = Data.column.lower; | |
| 501 } | |
| 502 pEntry->id = ACCFILT_STD_GET_ID(column); | |
| 503 pEntry->channel_no = ACCFILT_STD_GET_CTRL(column); | |
| 504 } | |
| 505 break; | |
| 506 | |
| 507 case CAN_ACCFILT_SFF_GRP_SA: | |
| 508 pEntry->lower_id_bound = ACCFILT_STD_GET_ID(Data.column.lower); | |
| 509 pEntry->upper_id_bound = ACCFILT_STD_GET_ID(Data.column.upper); | |
| 510 pEntry->channel_no = ACCFILT_STD_GET_CTRL(Data.column.lower); | |
| 511 break; | |
| 512 #endif // #ifdef CYGOPT_IO_CAN_STD_CAN_ID | |
| 513 | |
| 514 #ifdef CYGOPT_IO_CAN_EXT_CAN_ID | |
| 515 case CAN_ACCFILT_EFF_SA: | |
| 516 pEntry->id = ACCFILT_EXT_GET_ID(Data.dword); | |
| 517 pEntry->channel_no = ACCFILT_EXT_GET_CTRL(Data.dword); | |
| 518 break; | |
| 519 | |
| 520 case CAN_ACCFILT_EFF_GRP_SA: | |
| 521 pEntry->lower_id_bound = ACCFILT_EXT_GET_ID(Data.dword); | |
| 522 pEntry->channel_no = ACCFILT_EXT_GET_CTRL(Data.dword); | |
| 523 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE+ EntryAddress + sizeof(cyg_uint32), Data.dword); | |
| 524 pEntry->upper_id_bound = ACCFILT_EXT_GET_ID(Data.dword); | |
| 525 break; | |
| 526 #endif // #ifedf CYGOPT_IO_CAN_EXT_CAN_ID | |
| 527 default: | |
| 528 CYG_FAIL("Invalid identifier table address"); | |
| 529 } // switch () | |
| 530 } | |
| 531 | |
| 532 | |
| 533 //=========================================================================== | |
| 534 // Set certain entry in table | |
| 535 //=========================================================================== | |
| 536 static void lpc2xxx_can_accfilt_set_entry(cyg_uint32 TableStartAddress, cyg_uint16 EntryNo, lpc2xxx_accfilt_entry_t *pEntry) | |
| 537 { | |
| 538 cyg_uint32 EntryAddress = lpc2xxx_can_accfilt_calc_entry_address(TableStartAddress, EntryNo); | |
| 539 lsc_buf_t Data; | |
| 540 | |
| 541 switch (TableStartAddress) | |
| 542 { | |
| 543 #ifdef CYGOPT_IO_CAN_STD_CAN_ID | |
| 544 case CAN_ACCFILT_SFF_SA: | |
| 545 { | |
| 546 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + EntryAddress, Data.dword); | |
| 547 if (EntryNo % 2) | |
| 548 { | |
| 549 Data.column.upper = (pEntry->channel_no << 13) | (pEntry->id & ACCFILT_STD_ID_MASK); | |
| 550 } | |
| 551 else | |
| 552 { | |
| 553 Data.column.lower = (pEntry->channel_no << 13) | (pEntry->id & ACCFILT_STD_ID_MASK); | |
| 554 } | |
| 555 } | |
| 556 break; | |
| 557 | |
| 558 case CAN_ACCFILT_SFF_GRP_SA: | |
| 559 Data.column.lower = (pEntry->channel_no << 13) | (pEntry->lower_id_bound & ACCFILT_STD_ID_MASK); | |
| 560 Data.column.upper = (pEntry->channel_no << 13) | (pEntry->upper_id_bound & ACCFILT_STD_ID_MASK); | |
| 561 break; | |
| 562 #endif // #ifdef CYGOPT_IO_CAN_STD_CAN_ID | |
| 563 | |
| 564 #ifdef CYGOPT_IO_CAN_EXT_CAN_ID | |
| 565 case CAN_ACCFILT_EFF_SA: | |
| 566 Data.dword = (pEntry->channel_no << 29) | (pEntry->id & ACCFILT_EXT_ID_MASK); | |
| 567 break; | |
| 568 | |
| 569 case CAN_ACCFILT_EFF_GRP_SA: | |
| 570 { | |
| 571 lsc_buf_t Data2; | |
| 572 | |
| 573 Data.dword = (pEntry->channel_no << 29) | (pEntry->lower_id_bound & ACCFILT_EXT_ID_MASK); | |
| 574 Data2.dword = (pEntry->channel_no << 29) | (pEntry->upper_id_bound & ACCFILT_EXT_ID_MASK); | |
| 575 HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + EntryAddress + sizeof(cyg_uint32), Data2.dword); | |
| 576 } | |
| 577 break; | |
| 578 #endif // #ifdef CYGOPT_IO_CAN_EXT_CAN_ID | |
| 579 | |
| 580 default: | |
| 581 CYG_FAIL("Invalid identifier table address"); | |
| 582 } // switch () | |
| 583 | |
| 584 HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + EntryAddress, Data.dword); | |
| 585 } | |
| 586 | |
| 587 | |
| 588 //=========================================================================== | |
| 589 // Add one entry to acceptance filter RAM | |
| 590 // If upper ID is > lower ID then we have to add a group filter - else we | |
| 591 // have to add a single message filter here | |
| 592 //=========================================================================== | |
| 593 static bool lpc2xxx_can_accfilt_add(lpc2xxx_can_info_t *info, | |
| 594 cyg_uint32 lower_id, | |
| 595 cyg_uint32 upper_id, | |
| 596 cyg_can_id_type ext) | |
| 597 { | |
| 598 cyg_uint32 accfilt_bck; // acceptance filter backup | |
| 599 cyg_uint32 end_of_table; | |
| 600 cyg_uint32 table; | |
| 601 lpc2xxx_accfilt_entry_t entry; | |
| 602 lpc2xxx_accfilt_entry_t new_entry; | |
| 603 | |
| 604 | |
| 605 // | |
| 606 // first step: disable acceptance filter and prepare it for modification | |
| 607 // | |
| 608 HAL_READ_UINT32(CAN_ACCFILT_AFMR, accfilt_bck); | |
| 609 HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF | AFMR_BYPASS); | |
| 610 | |
| 611 // | |
| 612 // Check if table is full | |
| 613 // | |
| 614 HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table); | |
| 615 if (end_of_table >= ACCFILT_RAM_SIZE) | |
| 616 { | |
| 617 return false; | |
| 618 } | |
| 619 | |
| 620 new_entry.id = lower_id; | |
| 621 new_entry.lower_id_bound = lower_id; | |
| 622 new_entry.upper_id_bound = upper_id; | |
| 623 | |
| 624 // | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
625 // Here we rely on the ISR vector ordering for calculation of channel number |
| 2409 | 626 // Maybe this is not the right way for newer LPC parts |
| 627 // | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
628 new_entry.channel_no = CAN_CHAN_NO_LUT(info); |
| 2409 | 629 |
| 630 // | |
| 631 // If lower_id == upper_id then we know that we have to setup a single message filter | |
| 632 // here. If it is not equal the it is group of identifiers to receive | |
| 633 // | |
| 634 if ((lower_id == upper_id) || (lower_id > upper_id)) | |
| 635 { | |
| 636 // | |
| 637 // setup single message filter (standard or extended) here | |
| 638 // | |
| 639 #ifdef CYGOPT_IO_CAN_EXT_CAN_ID | |
| 640 if (ext) | |
| 641 { | |
| 642 table = CAN_ACCFILT_EFF_SA; | |
| 643 } | |
| 644 else | |
| 645 #endif // #ifdef CYGOPT_IO_CAN_EXT_CAN_ID | |
| 646 { | |
| 647 #ifdef CYGOPT_IO_CAN_STD_CAN_ID | |
| 648 table = CAN_ACCFILT_SFF_SA; | |
| 649 #endif // CYGOPT_IO_CAN_STD_CAN_ID | |
| 650 } | |
| 651 } | |
| 652 else | |
| 653 { | |
| 654 // | |
| 655 // setup single message filter (standard or extended) here | |
| 656 // | |
| 657 #ifdef CYGOPT_IO_CAN_EXT_CAN_ID | |
| 658 if (ext) | |
| 659 { | |
| 660 table = CAN_ACCFILT_EFF_GRP_SA; | |
| 661 } | |
| 662 else | |
| 663 #endif // #ifdef CYGOPT_IO_CAN_EXT_CAN_ID | |
| 664 { | |
| 665 #ifdef CYGOPT_IO_CAN_STD_CAN_ID | |
| 666 table = CAN_ACCFILT_SFF_GRP_SA; | |
| 667 #endif // #ifdef CYGOPT_IO_CAN_STD_CAN_ID | |
| 668 } | |
| 669 } | |
| 670 | |
| 671 cyg_uint16 entries = lpc2xxx_can_accfilt_get_table_entries(table); | |
| 672 cyg_uint16 i; | |
| 673 | |
| 674 | |
| 675 for (i = 0; i < entries; ++i) | |
| 676 { | |
| 677 lpc2xxx_can_accfilt_get_entry(table, i, &entry); | |
| 678 | |
| 679 if (entry.channel_no > new_entry.channel_no) | |
| 680 { | |
| 681 break; | |
| 682 } | |
| 683 | |
| 684 if ((entry.channel_no == new_entry.channel_no) | |
| 685 && (entry.id > new_entry.id)) | |
| 686 { | |
| 687 break; | |
| 688 } | |
| 689 } // for (i = 0; i < entries; ++i) | |
| 690 | |
| 691 lpc2xxx_can_accfilt_ram_insert_entry(table, i); | |
| 692 lpc2xxx_can_accfilt_set_entry(table, i, &new_entry); | |
| 693 | |
| 694 // | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
695 // finally restore the previous state of the acceptance filter |
| 2409 | 696 // |
| 697 HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, accfilt_bck); | |
| 698 return true; | |
| 699 } | |
| 700 | |
| 701 | |
| 702 //=========================================================================== | |
| 703 // Remove all entries from a certain controller | |
| 704 //=========================================================================== | |
| 705 void lpc2xxx_can_accfilt_remove_all_ctrl_entries(lpc2xxx_can_info_t *info) | |
| 706 { | |
| 707 cyg_uint32 accfilt_bck; // acceptance filter backup | |
| 708 cyg_uint16 i; | |
| 709 cyg_uint16 entries; | |
| 710 cyg_uint32 TableStartAddress = CAN_ACCFILT_SFF_SA; | |
| 711 lpc2xxx_accfilt_entry_t Entry; | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
712 cyg_uint8 channel_no = CAN_CHAN_NO_LUT(info); |
| 2409 | 713 cyg_uint16 entry_idx; |
| 714 | |
| 715 // | |
| 716 // first step: disable acceptance filter and prepare it for modification | |
| 717 // | |
| 718 HAL_READ_UINT32(CAN_ACCFILT_AFMR, accfilt_bck); | |
| 719 HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF | AFMR_BYPASS); | |
| 720 | |
| 721 // | |
| 722 // now remove all entries for a certain controller | |
| 723 // | |
| 724 for (TableStartAddress = CAN_ACCFILT_SFF_SA; TableStartAddress < CAN_ACCFILT_ENDOFTABLE; TableStartAddress += 4) | |
| 725 { | |
| 726 entries = lpc2xxx_can_accfilt_get_table_entries(TableStartAddress); | |
| 727 entry_idx = 0; | |
| 728 for (i = 0; i < entries; ++i) | |
| 729 { | |
| 730 lpc2xxx_can_accfilt_get_entry(TableStartAddress, entry_idx, &Entry); | |
| 731 if (Entry.channel_no == channel_no) | |
| 732 { | |
| 733 lpc2xxx_can_accfilt_ram_remove_entry(TableStartAddress, entry_idx); | |
| 734 } | |
| 735 else | |
| 736 { | |
| 737 entry_idx++; | |
| 738 } | |
| 739 } // for (i = 0; i < entries; ++i) | |
| 740 } // for (TableStartAddress = CAN_ACCFILT_SFF_SA ... | |
| 741 | |
| 742 // | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
743 // finally restore the previous state of the acceptance filter |
| 2409 | 744 // |
| 745 HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, accfilt_bck); | |
| 746 } | |
| 747 #endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG | |
| 748 | |
| 749 | |
| 750 #ifndef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG | |
| 751 //=========================================================================== | |
| 752 // Setup reception of all CAN identifiers | |
| 753 // If runtime acceptance filter configuration is not required then we simply | |
| 754 // setup the acceptance filter here to receive all CAN identifiers | |
| 755 //=========================================================================== | |
| 756 static void lpc2xxx_can_accfilt_simple_rx_all(void) | |
| 757 { | |
| 758 cyg_uint32 regval; | |
| 759 | |
| 760 // | |
| 761 // First check if it is really necessary to setup filters. If end of table is | |
| 762 // != 0 then the acceptance filter is already setup properly | |
| 763 // | |
| 764 HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, regval); | |
| 765 if (regval) | |
| 766 { | |
| 767 return; | |
| 768 } | |
| 769 | |
| 770 cyg_uint32 accfilt_bck; // acceptance filter backup | |
| 771 cyg_uint8 i = 0; // loop counter | |
| 772 lsc_buf_t accfilt_entry; // std group entry | |
| 773 #ifdef CYGOPT_IO_CAN_STD_CAN_ID | |
| 774 cyg_uint8 std_address = 0; // std group entry address | |
| 775 #ifdef CYGOPT_IO_CAN_EXT_CAN_ID | |
| 776 cyg_uint8 ext_address = lpc2xxx_global_can_info.init_cnt << 2; | |
| 777 #endif | |
| 778 #else | |
| 779 cyg_uint8 ext_address = 0; | |
| 780 #endif | |
| 781 | |
| 782 // | |
| 783 // first step: disable acceptance filter and prepare it for modification | |
| 784 // | |
| 785 HAL_READ_UINT32(CAN_ACCFILT_AFMR, accfilt_bck); | |
| 786 HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF | AFMR_BYPASS); | |
| 787 | |
| 788 // | |
| 789 // Write table start adresses - we use only standard group and extended filter | |
| 790 // group | |
| 791 // | |
| 792 HAL_WRITE_UINT32(CAN_ACCFILT_SFF_SA, 0); | |
| 793 HAL_WRITE_UINT32(CAN_ACCFILT_SFF_GRP_SA, 0); | |
| 794 HAL_WRITE_UINT32(CAN_ACCFILT_EFF_SA, ext_address); | |
| 795 HAL_WRITE_UINT32(CAN_ACCFILT_EFF_GRP_SA, ext_address); | |
| 796 | |
| 797 // | |
| 798 // Now loop through all active CAN channels and setup the acceptance filter for | |
| 799 // each channel to receive all standard and extended CAN identifiers | |
| 800 // | |
| 801 while (lpc2xxx_global_can_info.active_channels[i]) | |
| 802 { | |
| 803 lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)lpc2xxx_global_can_info.active_channels[i++]->dev_priv; | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
804 cyg_uint8 channel_no = CAN_CHAN_NO_LUT(info); |
| 2409 | 805 |
| 806 #ifdef CYGOPT_IO_CAN_STD_CAN_ID | |
| 807 accfilt_entry.column.lower = (channel_no << 13) | (0x000 & ACCFILT_STD_ID_MASK); | |
| 808 accfilt_entry.column.upper = (channel_no << 13) | (0x7FF & ACCFILT_STD_ID_MASK); | |
| 809 HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + std_address, accfilt_entry.dword); | |
| 810 std_address += sizeof(cyg_uint32); | |
| 811 #endif // CYGOPT_IO_CAN_STD_CAN_ID | |
| 812 | |
| 813 #ifdef CYGOPT_IO_CAN_EXT_CAN_ID | |
| 814 accfilt_entry.dword = (channel_no << 29) | (0x00000000 & ACCFILT_EXT_ID_MASK); | |
| 815 HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + ext_address, accfilt_entry.dword); | |
| 816 ext_address += sizeof(cyg_uint32); | |
| 817 accfilt_entry.dword = (channel_no << 29) | (0x1FFFFFFF & ACCFILT_EXT_ID_MASK); | |
| 818 HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + ext_address, accfilt_entry.dword); | |
| 819 ext_address += sizeof(cyg_uint32); | |
| 820 #endif // CYGOPT_IO_CAN_EXT_CAN_ID | |
| 821 } // while (lpc2xxx_global_can_info.active_channels[i]) | |
| 822 | |
| 823 // | |
| 824 // finally store end of table value and restore the previous state of the | |
| 825 // acceptance filter | |
| 826 // | |
| 827 HAL_WRITE_UINT32(CAN_ACCFILT_ENDOFTABLE, ext_address); | |
| 828 HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, accfilt_bck); | |
| 829 } | |
| 830 #endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG | |
| 831 | |
| 832 | |
| 833 //=========================================================================== | |
| 834 // Reset acceptance filter to poweron defaults | |
| 835 //=========================================================================== | |
| 836 void lpc2xxx_can_accfilt_reset(void) | |
| 837 { | |
| 838 cyg_uint32 accfilt_bck; // acceptance filter backup | |
| 839 // | |
| 840 // first step: disable acceptance filter and prepare it for modification | |
| 841 // | |
| 842 HAL_READ_UINT32(CAN_ACCFILT_AFMR, accfilt_bck); | |
| 843 HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF | AFMR_BYPASS); | |
| 844 | |
| 845 // | |
| 846 // Now write zero to all addresses of acceptance filter table | |
| 847 // | |
| 848 HAL_WRITE_UINT32(CAN_ACCFILT_SFF_SA, 0); | |
| 849 HAL_WRITE_UINT32(CAN_ACCFILT_SFF_GRP_SA, 0); | |
| 850 HAL_WRITE_UINT32(CAN_ACCFILT_EFF_SA, 0); | |
| 851 HAL_WRITE_UINT32(CAN_ACCFILT_EFF_GRP_SA, 0); | |
| 852 HAL_WRITE_UINT32(CAN_ACCFILT_ENDOFTABLE, 0); | |
| 853 | |
| 854 // | |
|
2509
a52d470bc691
* cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
asl
parents:
2409
diff
changeset
|
855 // finally restore the previous state of the acceptance filter |
| 2409 | 856 // |
| 857 HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, accfilt_bck); | |
| 858 } | |
| 859 | |
| 860 | |
| 861 //=========================================================================== | |
| 862 // Dump content of acceptance filter lookup table | |
| 863 //=========================================================================== | |
| 864 #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG | |
| 865 void lpc2xxx_can_accfilt_dbg_dump(void) | |
| 866 { | |
| 867 cyg_uint32 sff_sa; | |
| 868 cyg_uint32 sff_grp_sa; | |
| 869 cyg_uint32 eff_sa; | |
| 870 cyg_uint32 eff_grp_sa; | |
| 871 cyg_uint32 end_of_table; | |
| 872 cyg_uint32 entry_address; | |
| 873 lsc_buf_t data; | |
| 874 | |
| 875 | |
| 876 HAL_READ_UINT32(CAN_ACCFILT_SFF_SA, sff_sa); | |
| 877 HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa); | |
| 878 HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa); | |
| 879 HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa); | |
| 880 HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table); | |
| 881 | |
| 882 entry_address = sff_sa; | |
| 883 | |
| 884 // | |
| 885 // Print lookup table registers | |
| 886 // | |
| 887 diag_printf("\n\nDUMP CAN ACCEPTANCE FILTER REGISTERS\n"); | |
| 888 diag_printf("----------------------------------------\n"); | |
| 889 diag_printf("SFF_sa:\t\t0x%08x\n", sff_sa); | |
| 890 diag_printf("SFF_GRP_sa:\t0x%08x\n", sff_grp_sa); | |
| 891 diag_printf("EFF_sa:\t\t0x%08x\n", eff_sa); | |
| 892 diag_printf("EFF_GRP_sa:\t0x%08x\n", eff_grp_sa); | |
| 893 diag_printf("EOT:\t\t0x%08x\n", end_of_table); | |
| 894 | |
| 895 // | |
| 896 // Print table of standard identifiers | |
| 897 // | |
| 898 diag_printf("\n\nDUMP CAN LOOKUP TABLE RAM"); | |
| 899 diag_printf("\nSFF_sa\t\tcolumn_lower\tcolumn_upper\traw_data\n"); | |
| 900 diag_printf("----------------------------------------------------------\n"); | |
| 901 while (entry_address < sff_grp_sa) | |
| 902 { | |
| 903 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, data.dword); | |
| 904 diag_printf("0x%04x:\t\t0x%x\t\t0x%x\t\t0x%x\n", entry_address, data.column.lower, data.column.upper, data.dword); | |
| 905 entry_address += sizeof(cyg_uint32); | |
| 906 } | |
| 907 | |
| 908 // | |
| 909 // Print table of standard identifier groups | |
| 910 // | |
| 911 diag_printf("\nSFF_GRP_sa\tcolumn_lower\tcolumn_upper\traw_data\n"); | |
| 912 diag_printf("----------------------------------------------------------\n"); | |
| 913 while (entry_address < eff_sa) | |
| 914 { | |
| 915 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, data.dword); | |
| 916 diag_printf("0x%04x:\t\t0x%x\t\t0x%x\t\t0x%x\n", entry_address, data.column.lower, data.column.upper, data.dword); | |
| 917 entry_address += sizeof(cyg_uint32); | |
| 918 } | |
| 919 | |
| 920 // | |
| 921 // Print table of extended identifiers | |
| 922 // | |
| 923 diag_printf("\nEFF_sa\t\t-\t\t-\t\traw_data\n"); | |
| 924 diag_printf("----------------------------------------------------------\n"); | |
| 925 while (entry_address < eff_grp_sa) | |
| 926 { | |
| 927 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, data.dword); | |
| 928 diag_printf("0x%04x:\t\t\t\t\t\t0x%x\n", entry_address, data.dword); | |
| 929 entry_address += sizeof(cyg_uint32); | |
| 930 } | |
| 931 | |
| 932 // | |
| 933 // Print table of extended identifier groups | |
| 934 // | |
| 935 diag_printf("\nEFF_GRP_sa\t-\t\t-\t\traw_data\n"); | |
| 936 diag_printf("----------------------------------------------------------\n"); | |
| 937 while (entry_address < end_of_table) | |
| 938 { | |
| 939 HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, data.dword); | |
| 940 diag_printf("0x%04x:\t\t\t\t\t\t0x%x\n", entry_address, data.dword); | |
| 941 entry_address += sizeof(cyg_uint32); | |
| 942 } | |
| 943 } | |
| 944 #endif // CYGDBG_DEVS_CAN_LPC2XXX_DEBUG | |
| 945 | |
| 946 //=========================================================================== | |
| 947 // Dump content of acceptance filter lookup table | |
| 948 //=========================================================================== | |
| 949 #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG | |
| 950 void lpc2xxx_can_reg_dump(struct cyg_devtab_entry* devtab_entry) | |
| 951 { | |
| 952 can_channel *chan = (can_channel*)devtab_entry->priv; | |
| 953 cyg_uint32 reg_val; | |
| 954 CAN_DECLARE_INFO(chan); | |
| 955 | |
| 956 chan = chan; // avoid compiler warnings for unused variables | |
| 957 // | |
| 958 // Print table of extended identifier groups | |
| 959 // | |
| 960 diag_printf("\n\nCAN REGISTER DUMP\n"); | |
| 961 diag_printf("\nRegister\tValue\n"); | |
| 962 diag_printf("----------------------------------------------------------\n"); | |
| 963 HAL_READ_UINT32(CAN_CTRL_MOD(info), reg_val); | |
| 964 diag_printf("CANMOD\t\t0x%08x\n", reg_val); | |
| 965 HAL_READ_UINT32(CAN_CTRL_CMR(info), reg_val); | |
| 966 diag_printf("CANCMR\t\t0x%08x\n", reg_val); | |
| 967 HAL_READ_UINT32(CAN_CTRL_GSR(info), reg_val); | |
| 968 diag_printf("CANGSR\t\t0x%08x\n", reg_val); | |
| 969 HAL_READ_UINT32(CAN_CTRL_ICR(info), reg_val); | |
| 970 diag_printf("CANICR\t\t0x%08x\n", reg_val); | |
| 971 HAL_READ_UINT32(CAN_CTRL_IER(info), reg_val); | |
| 972 diag_printf("CANIER\t\t0x%08x\n", reg_val); | |
| 973 HAL_READ_UINT32(CAN_CTRL_BTR(info), reg_val); | |
| 974 diag_printf("CANBTR\t\t0x%08x\n", reg_val); | |
| 975 HAL_READ_UINT32(CAN_CTRL_EWL(info), reg_val); | |
| 976 diag_printf("CANEWL\t\t0x%08x\n", reg_val); | |
| 977 HAL_READ_UINT32(CAN_CTRL_SR(info), reg_val); | |
| 978 diag_printf("CANSR\t\t0x%08x\n", reg_val); | |
| 979 HAL_READ_UINT32(CAN_CTRL_RFS(info), reg_val); | |
| 980 diag_printf("CANRFS\t\t0x%08x\n", reg_val); | |
| 981 HAL_READ_UINT32(CAN_CTRL_RID(info), reg_val); | |
| 982 diag_printf("CANRID\t\t0x%08x\n", reg_val); | |
| 983 HAL_READ_UINT32(CAN_CTRL_RDA(info), reg_val); | |
| 984 diag_printf("CANRDA\t\t0x%08x\n", reg_val); | |
| 985 HAL_READ_UINT32(CAN_CTRL_RDB(info), reg_val); | |
| 986 diag_printf("CANRDB\t\t0x%08x\n", reg_val); | |
| 987 | |
| 988 diag_printf("\n\nCAN CENTRAL REGISTER DUMP\n"); | |
| 989 diag_printf("\nRegister\tValue\n"); | |
| 990 diag_printf("----------------------------------------------------------\n"); | |
| 991 HAL_READ_UINT32(CAN_CENTRAL_TXSR, reg_val); | |
| 992 diag_printf("CANTxSR\t\t0x%08x\n", reg_val); | |
| 993 HAL_READ_UINT32(CAN_CENTRAL_RXSR, reg_val); | |
| 994 diag_printf("CANRxSR\t\t0x%08x\n", reg_val); | |
| 995 HAL_READ_UINT32(CAN_CENTRAL_MSR, reg_val); | |
| 996 diag_printf("CANMSR\t\t0x%08x\n", reg_val); | |
| 997 | |
| 998 diag_printf("\n\nCAN ACCEPTANCE FILTER REGISTER DUMP\n"); | |
| 999 diag_printf("\nRegister\tValue\n"); | |
| 1000 diag_printf("----------------------------------------------------------\n"); | |
| 1001 HAL_READ_UINT32(CAN_ACCFILT_AFMR, reg_val); | |
| 1002 diag_printf("AFMR\t\t0x%08x\n", reg_val); | |
| 1003 HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR, reg_val); | |
| 1004 diag_printf("LUTERR\t\t0x%08x\n", reg_val); | |
| 1005 HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR_ADDR, reg_val); | |
| 1006 diag_printf("LUTERRADDR\t0x%08x\n", reg_val); | |
| 1007 } | |
| 1008 #endif // #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG | |
| 1009 | |
| 1010 //--------------------------------------------------------------------------- | |
| 1011 // EOF can_accfilt_lpc2xxx.c |
