00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "pic24_all.h"
00030 #include <stdio.h>
00031
00042 void configBaudECAN1(void) {
00043
00044 #if FCY == 40000000L
00045
00046 C1CTRL1bits.CANCKS = ECAN_FCAN_IS_FCY;
00047
00048 C1CFG2 = ECAN_NO_WAKEUP |
00049 ECAN_SAMPLE_3TIMES |
00050 ECAN_SEG1PH_8TQ |
00051 ECAN_SEG2_PROGRAMMABLE |
00052 ECAN_SEG2PH_6TQ |
00053 ECAN_PRSEG_5TQ;
00054
00055 C1CFG1 = ECAN_SYNC_JUMP_4 |
00056 ECAN_PRE_2x1;
00057
00058 #else
00059 #warning ECAN module not configured! Edit function configECAN1()
00060 #endif
00061 }
00062
00063
00064 #define NUM_TX_BUFS 1 //reserve 1 for TX
00065 #define NUM_BUFS 2 //make this a power of 2 for the alignment to work or enter alignment manually
00066 ECANMSG msgBuf[NUM_BUFS] __attribute__((space(dma),aligned(NUM_BUFS*16)));
00067
00068
00069 #define MSG_ID 0x7A0 //arbitrary choice for 11-bit messsage ID
00070
00071
00072 void configDMA0(void) {
00073 DMACS0 = 0;
00074 _DMA0IF = 0;
00075 DMA0PAD = (unsigned int) &C1TXD;
00076 DMA0REQ = DMA_IRQ_ECAN1TX;
00077 DMA0STA = __builtin_dmaoffset(msgBuf);
00078 DMA0CNT = sizeof(ECANMSG)/2 -1;
00079 DMA0CON =
00080 (DMA_MODULE_ON |
00081 DMA_SIZE_WORD |
00082 DMA_DIR_WRITE_PERIPHERAL |
00083 DMA_INTERRUPT_FULL |
00084 DMA_NULLW_OFF |
00085 DMA_AMODE_PERIPHERAL_INDIRECT |
00086 DMA_MODE_CONTINUOUS);
00087 }
00088
00089
00090 void configDMA1(void) {
00091 _DMA1IF = 0;
00092 DMA1PAD = (unsigned int) &C1RXD;
00093 DMA1REQ = DMA_IRQ_ECAN1RX;
00094 DMA1STA = __builtin_dmaoffset(msgBuf);
00095 DMA1CNT = sizeof(ECANMSG)/2 -1;
00096 DMA1CON =
00097 (DMA_MODULE_ON |
00098 DMA_SIZE_WORD |
00099 DMA_DIR_READ_PERIPHERAL |
00100 DMA_INTERRUPT_FULL |
00101 DMA_NULLW_OFF |
00102 DMA_AMODE_PERIPHERAL_INDIRECT |
00103 DMA_MODE_CONTINUOUS);
00104
00105 }
00106
00107 #define RX_BUFFER_ID 1
00108
00109 void configECAN1() {
00110 uint8 u8_i;
00111 CHANGE_MODE_ECAN1(ECAN_MODE_CONFIGURE);
00112 configBaudECAN1();
00113
00114
00115 configRxFilterECAN1(0, MSG_ID, ECAN_MATCH_SID, RX_BUFFER_ID, 0);
00116 configRxMaskECAN1(0, 0x7FC, 0, 1);
00117 clrRxFullOvfFlagsECAN1();
00118
00119
00120 for (u8_i = 0; u8_i<8; u8_i++) {
00121 if (u8_i < NUM_TX_BUFS)
00122 configTxRxBufferECAN1(u8_i,ECAN_TX_BUFF,3);
00123 else
00124 configTxRxBufferECAN1(u8_i,ECAN_RX_BUFF,3);
00125 }
00126
00127 configDMA0();
00128 configDMA1();
00129 CHANGE_MODE_ECAN1(ECAN_MODE_NORMAL);
00130 }
00131
00132 uint32 rrot32(uint32 u32_x) {
00133 if (u32_x & 0x1) {
00134 u32_x = u32_x >> 1;
00135 u32_x = u32_x | 0x8000;
00136 } else u32_x = u32_x >> 1;
00137 return u32_x;
00138 }
00139
00140 int main (void) {
00141 uint32 u32_out0, u32_out1, u32_in0, u32_in1;
00142 uint8 rx_buff_id, u8_cnt;
00143
00144 configBasic(HELLO_MSG);
00145 configECAN1();
00146 CHANGE_MODE_ECAN1(ECAN_MODE_LOOPBACK);
00147 u32_out0 = 0xFEDCBA98;
00148 u32_out1 = 0x76543210;
00149 u8_cnt = 0;
00150 while (1) {
00151 DELAY_MS(500);
00152 msgBuf[0].data.u32[0] = u32_out0;
00153 msgBuf[0].data.u32[1] = u32_out1;
00154
00155 formatStandardDataFrameECAN(&msgBuf[0], MSG_ID+u8_cnt, 8);
00156 startTxECAN1(0);
00157 while (getTxInProgressECAN1(0)) {
00158 doHeartbeat();
00159 }
00160 _DMA0IF = 0;
00161 DELAY_MS(10);
00162 if (!_DMA1IF) {
00163 printf("Message ID 0x%X rejected by acceptance filter.\n",MSG_ID+u8_cnt);
00164 } else {
00165 _DMA1IF = 0;
00166 rx_buff_id = RX_BUFFER_ID;
00167 u32_in0 = msgBuf[rx_buff_id].data.u32[0];
00168 u32_in1 = msgBuf[rx_buff_id].data.u32[1];
00169 printf("Msg ID: 0x%X, Out: 0x%lx%lx, In: 0x%lx%lx\n",
00170 msgBuf[rx_buff_id].w0.SID,u32_out0, u32_out1, u32_in0, u32_in1 );
00171 clrRxFullFlagECAN1(rx_buff_id);
00172 }
00173 u32_out0 = rrot32(u32_out0);
00174 u32_out1 = rrot32(u32_out1);
00175 u8_cnt++;
00176 if (u8_cnt == 8) u8_cnt = 0;
00177 }
00178 }