can_tx.c
00001 #include <includes.h>
00002
00003 CAN_TX_CHAN_CFG can_tx_chan_cfgs[5];
00004
00005 extern unsigned long can_elapsed_ms;
00006
00007
00008 extern volatile unsigned long can_error_1;
00009 extern volatile unsigned long can_error_2;
00010 extern volatile unsigned long can_error_3;
00011 extern volatile unsigned long can_error_4;
00012
00013
00014 volatile unsigned short can_tx_frame_count_1 = 0;
00015 volatile unsigned short can_tx_frame_count_2 = 0;
00016 volatile unsigned short can_tx_frame_count_3 = 0;
00017 volatile unsigned short can_tx_frame_count_4 = 0;
00018
00019 unsigned short can_tx_get_frame_count_1(CAN_FRAME * frame)
00020 {
00021 frame->payload.w.w1 = can_tx_frame_count_1;
00022 can_tx_frame_count_1 = 0;
00023 frame->payload.w.w2 = can_elapsed_ms;
00024 return 0;
00025 }
00026
00027 unsigned short can_tx_get_frame_count_2(CAN_FRAME * frame)
00028 {
00029 frame->payload.w.w1 = can_tx_frame_count_2;
00030 can_tx_frame_count_2 = 0;
00031 frame->payload.w.w2 = can_elapsed_ms;
00032 return 0;
00033 }
00034
00035 unsigned short can_tx_get_frame_count_3(CAN_FRAME * frame)
00036 {
00037 frame->payload.w.w1 = can_tx_frame_count_3;
00038 can_tx_frame_count_3 = 0;
00039 frame->payload.w.w2 = can_elapsed_ms;
00040 return 0;
00041 }
00042
00043 unsigned short can_tx_get_frame_count_4(CAN_FRAME * frame)
00044 {
00045 frame->payload.w.w1 = can_tx_frame_count_4;
00046 can_tx_frame_count_4 = 0;
00047 frame->payload.w.w2 = can_elapsed_ms;
00048 return 0;
00049 }
00050
00051
00052 void can_tx_set_chan_cfg(CAN_CHANNEL chan,volatile unsigned long * base_addr, CAN_RING * tx_ring){
00053 can_tx_chan_cfgs[chan].base_addr = base_addr;
00054 can_tx_chan_cfgs[chan].ring = tx_ring;
00055 can_tx_chan_cfgs[chan].stalled = 1;
00056 }
00057
00058
00059 int can_transmit(CAN_FRAME_DESC * frame_desc){
00060 return can_transmit_alt(frame_desc,frame_desc->chan, frame_desc->rtr);
00061 }
00062
00063
00064 int can_transmit_alt(CAN_FRAME_DESC * frame_desc, CAN_CHANNEL chan, char rtr){
00065 CAN_LAYOUT layout = frame_desc->frame_layout;
00066 CAN_FRAME frame;
00067 int dlc;
00068
00069
00070 if(rtr){
00071 dlc = 0;
00072 }else{
00073 switch(layout){
00074 case CAN_LAYOUT_D:
00075 case CAN_LAYOUT_FF:
00076 case CAN_LAYOUT_II:
00077 case CAN_LAYOUT_FI:
00078 case CAN_LAYOUT_ISS:
00079 dlc = 8;
00080 break;
00081 default:
00082
00083 return 1;
00084 }
00085 }
00086
00087
00088
00089 if(rtr) {
00090 dlc = 0;
00091 } else {
00092 switch(layout){
00093
00094
00095
00096 case CAN_LAYOUT_D:
00097 frame.payload.d.d1 = ((CAN_TX_GETTER_DOUBLE)frame_desc->ptr1)();
00098 dlc = 8;
00099 break;
00100 case CAN_LAYOUT_FF:
00101 frame.payload.f.f1 = ((CAN_TX_GETTER_FLOAT)frame_desc->ptr1)();
00102 frame.payload.f.f2 = ((CAN_TX_GETTER_FLOAT)frame_desc->ptr2)();
00103 dlc = 8;
00104 break;
00105 case CAN_LAYOUT_II:
00106 frame.payload.i.i1 = ((CAN_TX_GETTER_INT)frame_desc->ptr1)();
00107 frame.payload.i.i2 = ((CAN_TX_GETTER_INT)frame_desc->ptr2)();
00108 dlc = 8;
00109 break;
00110 case CAN_LAYOUT_FI:
00111 frame.payload.f.f1 = ((CAN_TX_GETTER_FLOAT)frame_desc->ptr1)();
00112 frame.payload.i.i2 = ((CAN_TX_GETTER_INT)frame_desc->ptr2)();
00113 dlc = 8;
00114 break;
00115 case CAN_LAYOUT_ISS:
00116 frame.payload.i.i1 = ((CAN_TX_GETTER_INT )frame_desc->ptr1)();
00117 frame.payload.s.s3 = ((CAN_TX_GETTER_SHORT)frame_desc->ptr2)();
00118 frame.payload.s.s4 = ((CAN_TX_GETTER_SHORT)frame_desc->ptr3)();
00119 dlc = 8;
00120 break;
00121 default:
00122
00123 return 1;
00124 }
00125 }
00126
00127
00128
00129
00130
00131 frame.addr = frame_desc->addr;
00132 frame.chan = frame_desc->chan;
00133 frame.dlc = dlc;
00134 frame.rtr = rtr;
00135
00136
00137
00138 return can_transmit_frame(&frame);
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 int can_transmit_frame(CAN_FRAME * frame){
00204 CAN_CHANNEL chan = frame->chan;
00205 CAN_RING * ring = can_tx_chan_cfgs[chan].ring;
00206 int * p_stalled = &(can_tx_chan_cfgs[chan].stalled);
00207 int ret;
00208
00209
00210 ret = can_ring_push(ring,frame);
00211 if(ret) {
00212 return 1;
00213 }
00214
00215
00216 if(*p_stalled) {
00217 can_tx_send_next_frame(chan);
00218 }
00219 return 0;
00220 }
00221
00222 void can_tx_send_next_frame(CAN_CHANNEL chan){
00223 volatile unsigned long * base = can_tx_chan_cfgs[chan].base_addr;
00224 CAN_RING * ring = can_tx_chan_cfgs[chan].ring;
00225 int * p_stalled = &(can_tx_chan_cfgs[chan].stalled);
00226 CAN_FRAME frame;
00227 int ret;
00228
00229
00230 ret = can_ring_pop(ring,&frame);
00231
00232 if(ret)
00233 {
00234
00235 *p_stalled = 1;
00236 }
00237 else
00238 {
00239 *p_stalled = 0;
00240
00241 if (chan == CHAN_CAN1) {can_tx_frame_count_1++;}
00242 else if (chan == CHAN_CAN2) {can_tx_frame_count_2++;}
00243 else if (chan == CHAN_CAN3) {can_tx_frame_count_3++;}
00244 else if (chan == CHAN_CAN4) {can_tx_frame_count_4++;}
00245
00246
00247 CAN_REG(base,CAN_TFI1) = (frame.dlc&0xF)<<16 | (frame.rtr&0x1) << 30;
00248 CAN_REG(base,CAN_TID1) = frame.addr;
00249 CAN_REG(base,CAN_TDA1) = frame.payload.w.w1;
00250 CAN_REG(base,CAN_TDB1) = frame.payload.w.w2;
00251 CAN_REG(base,CAN_CMR ) = (1<<0) | (1<<5);
00252
00253 }
00254 }
00255
00256
00257
00258
00259
00260 void can_subscribe(CAN_FRAME_DESC * fd){
00261 CAN_FRAME frame;
00262 frame.chan = fd->chan;
00263 frame.addr = fd->addr;
00264 frame.rtr = 1;
00265 can_transmit_frame(&frame);
00266 }
00267