00001
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "avr32/io.h"
00050 #include "can.h"
00051 #include "compiler.h"
00052 #include "preprocessor.h"
00053 #include "intc.h"
00054 #include "canif.h"
00055
00056
00057
00058
00060 U32 can_mob_alloc_vector0 = 0;
00061
00063 U32 can_mob_alloc_vector1 = 0;
00064
00066 static struct
00067 {
00068 void (*can_msg_callback_channel0) (U8,U8);
00069 void (*can_msg_callback_channel1) (U8,U8);
00070 } can_lib_params =
00071 {
00072 .can_msg_callback_channel0 = NULL,
00073 .can_msg_callback_channel1 = NULL
00074 };
00075
00076 #if defined (__GNUC__)
00077 __attribute__((__interrupt__))
00078 #elif defined (__ICCAVR32__)
00079 __interrupt
00080 #endif
00081 static void can0_int_tx_handler(void)
00082 {
00083 U8 handle;
00084 handle = CANIF_mob_get_mob_txok(0);
00085 if (handle != 0x20)
00086 {
00087 CANIF_mob_clear_txok_status(0,handle);
00088 CANIF_mob_clear_status(0,handle);
00089 }
00090 can_lib_params.can_msg_callback_channel0(handle,CAN_STATUS_COMPLETED);
00091 }
00092
00093 #if defined (__GNUC__)
00094 __attribute__((__interrupt__))
00095 #elif defined (__ICCAVR32__)
00096 __interrupt
00097 #endif
00098 static void can0_int_rx_handler(void)
00099 {
00100 U8 handle;
00101 handle = CANIF_mob_get_mob_rxok(0) ;
00102 if (handle != 0x20)
00103 {
00104 CANIF_mob_clear_rxok_status(0,handle);
00105 CANIF_mob_clear_status(0,handle);
00106 }
00107 can_lib_params.can_msg_callback_channel0(handle,CAN_STATUS_COMPLETED);
00108 }
00109
00110 #if defined (__GNUC__)
00111 __attribute__((__interrupt__))
00112 #elif defined (__ICCAVR32__)
00113 __interrupt
00114 #endif
00115 static void can0_int_busoff_handler(void)
00116 {
00117 CANIF_clr_interrupt_status(0);
00118 can_lib_params.can_msg_callback_channel0(0xFF,CAN_STATUS_BUSOFF);
00119 }
00120
00121 #if defined (__GNUC__)
00122 __attribute__((__interrupt__))
00123 #elif defined (__ICCAVR32__)
00124 __interrupt
00125 #endif
00126 static void can0_int_cerr_handler(void)
00127 {
00128 CANIF_clr_interrupt_status(0);
00129 can_lib_params.can_msg_callback_channel0(0xFF,CAN_STATUS_ERROR);
00130 }
00131
00132 #if defined (__GNUC__)
00133 __attribute__((__interrupt__))
00134 #elif defined (__ICCAVR32__)
00135 __interrupt
00136 #endif
00137 static void can0_int_wakeup_handler(void)
00138 {
00139 CANIF_clr_interrupt_status(0);
00140 can_lib_params.can_msg_callback_channel0(0xFF,CAN_STATUS_WAKEUP);
00141 }
00142
00143 #if defined (__GNUC__)
00144 __attribute__((__interrupt__))
00145 #elif defined (__ICCAVR32__)
00146 __interrupt
00147 #endif
00148 static void can1_int_tx_handler(void)
00149 {
00150 U8 handle;
00151 handle = CANIF_mob_get_mob_txok(1) ;
00152 if (handle != 0x20)
00153 {
00154 CANIF_mob_clear_txok_status(1,handle);
00155 CANIF_mob_clear_status(1,handle);
00156 }
00157 can_lib_params.can_msg_callback_channel1(handle,CAN_STATUS_COMPLETED);
00158 }
00159
00160 #if defined (__GNUC__)
00161 __attribute__((__interrupt__))
00162 #elif defined (__ICCAVR32__)
00163 __interrupt
00164 #endif
00165 static void can1_int_rx_handler(void)
00166 {
00167 U8 handle;
00168 handle = CANIF_mob_get_mob_rxok(1) ;
00169 if (handle != 0x20)
00170 {
00171 CANIF_mob_clear_rxok_status(1,handle);
00172 CANIF_mob_clear_status(1,handle);
00173 }
00174 can_lib_params.can_msg_callback_channel1(handle,CAN_STATUS_COMPLETED);
00175 }
00176
00177 #if defined (__GNUC__)
00178 __attribute__((__interrupt__))
00179 #elif defined (__ICCAVR32__)
00180 __interrupt
00181 #endif
00182 static void can1_int_busoff_handler(void)
00183 {
00184 CANIF_clr_interrupt_status(1);
00185 can_lib_params.can_msg_callback_channel1(0xFF,CAN_STATUS_BUSOFF);
00186 }
00187
00188 #if defined (__GNUC__)
00189 __attribute__((__interrupt__))
00190 #elif defined (__ICCAVR32__)
00191 __interrupt
00192 #endif
00193 static void can1_int_cerr_handler(void)
00194 {
00195 CANIF_clr_interrupt_status(1);
00196 can_lib_params.can_msg_callback_channel1(0xFF,CAN_STATUS_ERROR);
00197 }
00198
00199 #if defined (__GNUC__)
00200 __attribute__((__interrupt__))
00201 #elif defined (__ICCAVR32__)
00202 __interrupt
00203 #endif
00204 static void can1_int_wakeup_handler(void)
00205 {
00206 CANIF_clr_interrupt_status(1);
00207 can_lib_params.can_msg_callback_channel1(0xFF,CAN_STATUS_WAKEUP);
00208 }
00209
00210 U8 can_enable_interrupt(U8 ch)
00211 {
00212 if ((ch > 1))
00213 return CAN_CMD_REFUSED;
00214
00215 if (ch==0)
00216 {
00217 INTC_register_interrupt(&can0_int_tx_handler, AVR32_CANIF_TXOK_IRQ_0, CAN0_INT_TX_LEVEL);
00218 INTC_register_interrupt(&can0_int_rx_handler, AVR32_CANIF_RXOK_IRQ_0, CAN0_INT_RX_LEVEL);
00219 INTC_register_interrupt(&can0_int_busoff_handler, AVR32_CANIF_BUS_OFF_IRQ_0, CAN0_INT_BOFF_LEVEL);
00220 INTC_register_interrupt(&can0_int_cerr_handler, AVR32_CANIF_ERROR_IRQ_0, CAN0_INT_ERR_LEVEL);
00221 INTC_register_interrupt(&can0_int_wakeup_handler, AVR32_CANIF_WAKE_UP_IRQ_0, CAN0_INT_WAKE_UP_LEVEL);
00222 CANIF_enable_interrupt(ch);
00223 }
00224 else if (ch == 1)
00225 {
00226 INTC_register_interrupt(&can1_int_tx_handler, AVR32_CANIF_TXOK_IRQ_1, CAN1_INT_TX_LEVEL);
00227 INTC_register_interrupt(&can1_int_rx_handler, AVR32_CANIF_RXOK_IRQ_1, CAN1_INT_RX_LEVEL);
00228 INTC_register_interrupt(&can1_int_busoff_handler, AVR32_CANIF_BUS_OFF_IRQ_1, CAN1_INT_BOFF_LEVEL);
00229 INTC_register_interrupt(&can1_int_cerr_handler, AVR32_CANIF_ERROR_IRQ_1, CAN1_INT_ERR_LEVEL);
00230 INTC_register_interrupt(&can1_int_wakeup_handler, AVR32_CANIF_WAKE_UP_IRQ_1, CAN1_INT_WAKE_UP_LEVEL);
00231 CANIF_enable_interrupt(ch);
00232 }
00233
00234 return CAN_CMD_ACCEPTED;
00235 }
00236
00237 U8 can_init(U8 ch,
00238 U32 can_msg_ram_add,
00239 U8 operating_mode,
00240 void (*can_msg_callback_channel) (U8 handle, U8 event))
00241 {
00242 if ( ch > 1)
00243 return CAN_CMD_REFUSED;
00244
00245
00246 CANIF_set_reset(ch);
00247 while(CANIF_channel_enable_status(ch));
00248 CANIF_clr_reset(ch);
00249
00250 CANIF_set_ram_add(ch,(unsigned long) can_msg_ram_add);
00251 if ((CANIF_bit_timing(ch))==0) return (0);
00252 switch(operating_mode)
00253 {
00254 case CANIF_CHANNEL_MODE_NORMAL:
00255 CANIF_set_channel_mode(ch,0);
00256 CANIF_clr_overrun_mode(ch);
00257 break;
00258 case CANIF_CHANNEL_MODE_LISTENING:
00259 CANIF_set_channel_mode(ch,1);
00260 CANIF_set_overrun_mode(ch);
00261 break;
00262 case CANIF_CHANNEL_MODE_LOOPBACK:
00263 CANIF_set_channel_mode(ch,2);
00264 CANIF_clr_overrun_mode(ch);
00265 break;
00266 }
00267 canif_clear_all_mob(ch,NB_MOB_CHANNEL);
00268 CANIF_enable(ch);
00269 while(!CANIF_channel_enable_status(ch));
00270
00271 #ifdef CAN_LIB_UNDER_INTERRUPT
00272 switch(ch)
00273 {
00274 case 0:
00275 can_lib_params.can_msg_callback_channel0 = can_msg_callback_channel;
00276 break;
00277 case 1:
00278 can_lib_params.can_msg_callback_channel1 = can_msg_callback_channel;
00279 break;
00280 }
00281 can_enable_interrupt(ch);
00282 #endif
00283
00284 return CAN_CMD_ACCEPTED;
00285 }
00286
00287
00288 U8 can_mob_alloc(U8 ch)
00289 {
00290 if ((ch > 1))
00291 return CAN_CMD_REFUSED;
00292
00293 if(ch==0)
00294 {
00295 int i;
00296 for (i=0;i<NB_MOB_CHANNEL;i++)
00297 {
00298 if (!((can_mob_alloc_vector0>>i)&0x01))
00299 {
00300 can_mob_alloc_vector0|=(1<<i);
00301 CANIF_clr_mob(0,i);
00302 return i;
00303 }
00304 }
00305 return CAN_CMD_REFUSED;
00306 }
00307 else{
00308 int i;
00309 for (i=0;i<NB_MOB_CHANNEL;i++)
00310 {
00311 if (!((can_mob_alloc_vector1>>i)&0x01))
00312 {
00313 can_mob_alloc_vector1|=(1<<i);
00314 CANIF_clr_mob(1,i);
00315 return i;
00316 }
00317 }
00318 return CAN_CMD_REFUSED;
00319 }
00320 }
00321
00322 U8 can_mob_free(U8 ch, U8 handle)
00323 {
00324 if ((ch > 1)||
00325 (handle > (NB_MOB_CHANNEL-1)))
00326 return CAN_CMD_REFUSED;
00327 switch(ch)
00328 {
00329 case 0:
00330 can_mob_alloc_vector0 &= (~(1<<handle));
00331 break;
00332 case 1:
00333 can_mob_alloc_vector1 &= (~(1<<handle));
00334 break;
00335 }
00336 return CAN_CMD_ACCEPTED;
00337 }
00338
00339 U8 can_tx( U8 ch,
00340 U8 handle,
00341 U8 dlc,
00342 U8 req_type,
00343 const can_msg_t *can_msg)
00344 {
00345 if ((ch > 1) ||
00346 (handle > (NB_MOB_CHANNEL-1)) ||
00347 (dlc > 8))
00348 return CAN_CMD_REFUSED;
00349
00350 if (can_msg->ide_bit){
00351 CANIF_set_ext_id(ch,
00352 handle,
00353 can_msg->id);
00354
00355 CANIF_set_ext_idmask(ch,
00356 handle,
00357 can_msg->id_mask);
00358 }
00359 else {
00360 CANIF_set_std_id(ch,
00361 handle,
00362 can_msg->id);
00363 CANIF_set_std_idmask(ch,
00364 handle,
00365 can_msg->id_mask);
00366 }
00367 CANIF_mob_set_dlc(ch,handle,dlc);
00368 if (req_type == CAN_REMOTE_FRAME){
00369 CANIF_set_rtr(ch,handle);
00370 CANIF_set_rtrmask(ch,handle);
00371 CANIF_mob_set_automode(ch,handle);
00372 }
00373 CANIF_set_data(ch,handle,((can_msg_t *)can_msg)->data.u64);
00374 CANIF_config_tx(ch,handle);
00375 CANIF_mob_enable(ch,handle);
00376 #ifdef CAN_LIB_UNDER_INTERRUPT
00377 CANIF_mob_enable_interrupt(ch,handle);
00378 #endif
00379 return CAN_CMD_ACCEPTED;
00380 }
00381
00382 U8 can_rx( U8 ch,
00383 U8 handle,
00384 U8 req_type,
00385 const can_msg_t *can_msg)
00386 {
00387 if ((ch > 1) ||
00388 (handle > (NB_MOB_CHANNEL-1)))
00389 return CAN_CMD_REFUSED;
00390 if (can_msg->ide_bit){
00391 CANIF_set_ext_id(ch,
00392 handle,
00393 can_msg->id);
00394 CANIF_set_ext_idmask(ch,
00395 handle,
00396 can_msg->id_mask);
00397 }
00398 else {
00399 CANIF_set_std_id(ch,
00400 handle,
00401 can_msg->id);
00402 CANIF_set_std_idmask(ch,
00403 handle,
00404 can_msg->id_mask);
00405 }
00406 if (req_type == CAN_REMOTE_FRAME){
00407 CANIF_set_rtr(ch,handle);
00408 CANIF_set_rtrmask(ch,handle);
00409 CANIF_mob_set_automode(ch,handle);
00410 CANIF_set_data(ch,handle,((can_msg_t *)can_msg)->data.u64);
00411 }
00412 CANIF_config_rx(ch,handle);
00413 CANIF_mob_enable(ch,handle);
00414 #ifdef CAN_LIB_UNDER_INTERRUPT
00415 CANIF_mob_enable_interrupt(ch,handle);
00416 #endif
00417 return CAN_CMD_ACCEPTED;
00418 }
00419
00420 Union64 can_get_mob_data( U8 ch ,
00421 U8 handle)
00422 {
00423 return ((CANIF_mob_get_ptr_data(ch,handle)->data));
00424 }
00425
00426 U8 can_get_mob_dlc( U8 ch ,
00427 U8 handle)
00428 {
00429 return (CANIF_mob_get_dlc(ch,handle));
00430 }
00431
00432 U32 can_get_mob_id( U8 ch ,
00433 U8 handle)
00434 {
00435 return (CANIF_get_ext_id(ch,handle));
00436 }
00437
00438 U8 can_mob_get_status( U8 ch,
00439 U8 handle)
00440 {
00441 U8 status;
00442 if ((ch > 1)||
00443 (handle > (NB_MOB_CHANNEL-1)) )
00444 return CAN_CMD_REFUSED;
00445
00446 status = CANIF_get_interrupt_error_status(ch);
00447 if (status!=0)
00448 return CAN_STATUS_ERROR;
00449
00450 status = CANIF_mob_get_status(ch,handle);
00451 if ( (status & MOB_RX_COMPLETED) ||
00452 (status & MOB_TX_COMPLETED) ||
00453 (status & MOB_RX_COMPLETED_DLCW) )
00454 return CAN_STATUS_COMPLETED;
00455
00456 return CAN_STATUS_NOT_COMPLETED;
00457 }
00458
00459 void can_clear_status (U8 ch,
00460 U8 mob)
00461 {
00462 CANIF_mob_clear_status(ch,mob);
00463 }