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 #define NUM_TX_BUFS 1 //reserve 1 for TX
00064 #define NUM_BUFS 8 //make this a power of 2 for the alignment to work or enter alignment manually
00065 ECANMSG msgBuf[NUM_BUFS] __attribute__((space(dma),aligned(NUM_BUFS*16)));
00066
00067 #define MSG_ID 0x10B2ABC0 //arbitrary choice for extended messsage ID
00068
00069
00070 void configDMA0(void) {
00071 _DMA0IF = 0;
00072 DMA0PAD = (unsigned int) &C1TXD;
00073 DMA0REQ = DMA_IRQ_ECAN1TX;
00074 DMA0STA = __builtin_dmaoffset(msgBuf);
00075 DMA0CNT = sizeof(ECANMSG)/2 -1;
00076 DMA0CON =
00077 (DMA_MODULE_ON |
00078 DMA_SIZE_WORD |
00079 DMA_DIR_WRITE_PERIPHERAL |
00080 DMA_INTERRUPT_FULL |
00081 DMA_NULLW_OFF |
00082 DMA_AMODE_PERIPHERAL_INDIRECT |
00083 DMA_MODE_CONTINUOUS);
00084 }
00085
00086
00087 void configDMA1(void) {
00088 _DMA1IF = 0;
00089 DMA1PAD = (unsigned int) &C1RXD;
00090 DMA1REQ = DMA_IRQ_ECAN1RX;
00091 DMA1STA = __builtin_dmaoffset(msgBuf);
00092 DMA1CNT = sizeof(ECANMSG)/2 -1;
00093 DMA1CON =
00094 (DMA_MODULE_ON |
00095 DMA_SIZE_WORD |
00096 DMA_DIR_READ_PERIPHERAL |
00097 DMA_INTERRUPT_FULL |
00098 DMA_NULLW_OFF |
00099 DMA_AMODE_PERIPHERAL_INDIRECT |
00100 DMA_MODE_CONTINUOUS);
00101
00102 }
00103
00104 #define RX_BUFFER_ID 15 //a value of 15 means to use a FIFO for RX
00105
00106 void configECAN1() {
00107 uint8 u8_i;
00108 CHANGE_MODE_ECAN1(ECAN_MODE_CONFIGURE);
00109 configBaudECAN1();
00110 C1FCTRL = ECAN_DMA_BUF_SIZE_8 | ECAN_FIFO_START_AREA_1;
00111
00112 configRxFilterECAN1(0, MSG_ID, ECAN_MATCH_EID, RX_BUFFER_ID, 0);
00113 configRxMaskECAN1(0, 0x1FFFFFFC, ECAN_MATCH_EID, 1);
00114 clrRxFullOvfFlagsECAN1();
00115
00116
00117 for (u8_i = 0; u8_i<8; u8_i++) {
00118 if (u8_i < NUM_TX_BUFS)
00119 configTxRxBufferECAN1(u8_i,ECAN_TX_BUFF,3);
00120 else
00121 configTxRxBufferECAN1(u8_i,ECAN_RX_BUFF,3);
00122 }
00123 configDMA0();
00124 configDMA1();
00125 CHANGE_MODE_ECAN1(ECAN_MODE_NORMAL);
00126 }
00127
00128 uint32 rrot32(uint32 u32_x) {
00129 if (u32_x & 0x1) {
00130 u32_x = u32_x >> 1;
00131 u32_x = u32_x | 0x8000;
00132 } else u32_x = u32_x >> 1;
00133 return u32_x;
00134 }
00135
00136 int main (void) {
00137 uint32 u32_out0, u32_out1, u32_in0, u32_in1;
00138 uint8 rx_buff_id, u8_cnt;
00139
00140 configBasic(HELLO_MSG);
00141 configECAN1();
00142 CHANGE_MODE_ECAN1(ECAN_MODE_LOOPBACK);
00143 u32_out0 = 0xFEDCBA98;
00144 u32_out1 = 0x76543210;
00145 u8_cnt = 0;
00146 while (1) {
00147 DELAY_MS(500);
00148 msgBuf[0].data.u32[0] = u32_out0;
00149 msgBuf[0].data.u32[1] = u32_out1;
00150
00151 formatExtendedDataFrameECAN(&msgBuf[0], MSG_ID+u8_cnt, 8);
00152 startTxECAN1(0);
00153 while (getTxInProgressECAN1(0)) {
00154 doHeartbeat();
00155 }
00156 _DMA0IF = 1;
00157 DELAY_MS(10);
00158 if (!_DMA1IF) {
00159 printf("Message ID 0x%lX rejected by acceptance filter.\n",MSG_ID+u8_cnt);
00160 } else {
00161 _DMA1IF = 0;
00162 rx_buff_id = GET_FIFO_READBUFFER_ECAN1();
00163 u32_in0 = msgBuf[rx_buff_id].data.u32[0];
00164 u32_in1 = msgBuf[rx_buff_id].data.u32[1];
00165 printf("Rx Buff: %d. Msg ID: 0x%lX, Out: 0x%lx%lx, In: 0x%lx%lx\n",
00166 rx_buff_id, getIdExtendedDataFrameECAN (&msgBuf[rx_buff_id]),u32_out0, u32_out1, u32_in0, u32_in1 );
00167 clrRxFullFlagECAN1(rx_buff_id);
00168 }
00169 u32_out0 = rrot32(u32_out0);
00170 u32_out1 = rrot32(u32_out1);
00171 u8_cnt++;
00172 if (u8_cnt == 8) u8_cnt = 0;
00173 }
00174 }