1. #include "includes.h"
  2. #include <yfuns.h>
  3.  
  4. #define CAN1          0x1
  5. #define CAN2          0x2
  6. #define BAUD_RATE     115200
  7. #define LPC_APB0_BASE 0x40000000UL
  8. #define LPC_CAN1      (LPC_APB0_BASE + 0x44000)
  9. #define AFRAM         0x40038000
  10.  
  11. #define STD_ID_FORMAT 0
  12. #define EXT_ID_FORMAT 1
  13.  
  14. #define DATA_FRAME   0
  15. #define REMOTE_FRAME 1
  16.  
  17. #define RECEIVING    0
  18. #define TRANSMITTING 1
  19.  
  20. typedef struct
  21. {
  22.     uint32_t id;
  23.     uint8_t dataA[4];
  24.     uint8_t dataB[4];
  25.     uint8_t len;       
  26.     uint8_t format;
  27.     uint8_t type;
  28. } CAN_MSG_Type;
  29.  
  30. CAN_MSG_Type transMessage, recMessage;
  31.  
  32. void initCAN();
  33. void setCANBaudRate();
  34. void testCAN();
  35. void configCANMessage(uint32_t id, uint8_t dataA[4], uint8_t dataB[4],
  36.                       uint8_t len, uint8_t format, uint8_t type, uint8_t dir);
  37. void CAN_IRQHandler(void);
  38. uint8_t checkMessage(CAN_MSG_Type* transMessage, CAN_MSG_Type* recMessage);
  39. void receiveCANMessage(CAN_MSG_Type* recMessage);
  40. void sendCANMessage(CAN_MSG_Type* transMessage);
  41.  
  42. /** external data **/
  43. #pragma section=".intvec"
  44. /** public functions **/
  45. /*************************************************************************
  46.  * Function Name: InitClock
  47.  * Parameters: void
  48.  * Return: void
  49.  *
  50.   * Description: Initialize PLL0 and clocks' dividers. PLL = 96MHz,
  51.  *               CPU - 96MHz, PCLK - 48 MHz
  52.  *
  53.  *************************************************************************/
  54. void InitClock(void)
  55. {
  56.   /*Sys Clock Select as CPU clock
  57.     divider 1:1*/
  58.   CLK_SetCpuClk(CPUSEL_CLKSYS,1);
  59.   /*Select IRC oscilator as Sys clock*/
  60.   CLK_SetSysClk(SYSSEL_IRCOSC);
  61.   /*Enable Main oscilator*/
  62.   CLK_MainOscSet(CLK_ENABLE,MOSCRNG_1_20MHZ);
  63.   /*Select Main oscilator as Sys clock*/
  64.   CLK_SetSysClk(SYSSEL_MOSC);
  65.   /*Enable set PLL 96Hz (M = 8; P = 1)*/
  66.   CLK_SetMainPll(CLK_ENABLE, 8-1, 0);
  67.   /*Set peripheral divider 1:2. Peripheral clock 48MHz*/
  68.   CLK_SetPeriphClk(2);
  69.   /*PLL0 out is used as the input to the CPU clock divider
  70.   divider 1:1. CPU runs at 96MHz*/
  71.   CLK_SetCpuClk(CPUSEL_CLKPLL,1);
  72. }
  73.  
  74. /*************************************************************************
  75.  * Function Name: __low_level_init
  76.  * Parameters: void
  77.  * Return:
  78.  *
  79.  * Description: Low level system init (clock, flash accelerator,
  80.  *              SDRAM and vector table address)
  81.  *              
  82.  *
  83.  *************************************************************************/
  84. int __low_level_init (void)
  85. {
  86.   /*if debug is in SDRAM
  87.     clock and SDRAM initialization is made
  88.     in mac file*/
  89. #ifndef SDRAM_DEBUG
  90.   int cpuclk;
  91.   /* Flash accelerator save value*/
  92.   FLASHCFG = (6UL<<12) | 0x3AUL;
  93.   /*Clock Init*/
  94.   InitClock();
  95.   /*Flash accelerator init*/
  96.   cpuclk = CLK_GetClock(CLK_CPU);
  97.  
  98.   if( cpuclk < 20000000 ){
  99.     FLASHCFG = (0x0UL<<12) | 0x3AUL;
  100.   } else if( cpuclk < 40000000 ){
  101.     FLASHCFG = (0x1UL<<12) | 0x3AUL;
  102.   } else if( cpuclk< 60000000 ){
  103.     FLASHCFG = (0x2UL<<12) | 0x3AUL;
  104.   } else if( cpuclk < 80000000 ){
  105.     FLASHCFG = (0x3UL<<12) | 0x3AUL;
  106.   } else if( cpuclk < 100000000 ){
  107.     FLASHCFG = (0x4UL<<12) | 0x3AUL;
  108.   }
  109.   /*SDRAM init*/
  110.   SDRAM_Init();
  111. #endif
  112.   /*Set vector table location*/
  113.   VTOR  = (unsigned int)__segment_begin(".intvec");
  114.  
  115.   return  1;
  116. }
  117.  
  118. // LOW-LEVEL INITIALISATION - END
  119.  
  120.  
  121.  
  122. // Params: baudrate - the baud rate of the CAN peripheral.
  123. // Returns: None
  124. // Description: Sets the baud rate for the CAN
  125. void setCANBaudRate(int baudrate)
  126. {
  127.   uint32_t result = 0;
  128.   uint8_t NT, TSEG1, TSEG2;
  129.   uint32_t CANPclk = 0;
  130.   uint32_t BRP;
  131.  
  132.   CANPclk = CLK_GetClock(CLK_PERIPH);
  133.  
  134.   result = CANPclk / baudrate;
  135.  
  136.   // Calculate suitable nominal time value.
  137.   // NT = TSEG1 + TSEG2 + 3
  138.   // NTEG <= 24
  139.   // TSEG1 >= TSEG2*3
  140.   for(NT=24; NT > 0; NT -= 2)
  141.   {
  142.     if(!(result % NT))
  143.     {
  144.       BRP = result / NT - 1;
  145.       NT--;
  146.       TSEG2 = NT/3 - 1;
  147.       TSEG1 = NT - NT/3 - 1;
  148.       break;
  149.     }
  150.   }
  151.  
  152.   // Enter reset mode.
  153.   CAN1MOD = 0x01;
  154.  
  155.   // Set bit timing.
  156.   // Default: SAM = 0x00;
  157.   //          SJW = 0x03;
  158.   CAN1BTR = (TSEG2 << 20) | (TSEG1 << 16) | (3 << 14) | BRP;
  159.  
  160.   // Enter normal operating mode.
  161.   CAN1MOD = 0;
  162. }
  163.  
  164. // Params: None
  165. // Returns: None
  166. // Description: Initialises the CAN peripheral.
  167. void initCAN()
  168. {
  169.   // Enable power and clock.
  170.   PCONP_bit.PCAN1 = 1;
  171.  
  172.   // Configure pins.
  173.   IOCON_P0_00 &= ~0x7; IOCON_P0_00 |= 0x1;
  174.   IOCON_P0_01 &= ~0x7; IOCON_P0_01 |= 0x1;
  175.  
  176.   IOCON_P0_04 &= ~0x7; IOCON_P0_04 |= 0x2;
  177.   IOCON_P0_05 &= ~0x7; IOCON_P0_05 |= 0x2;
  178.  
  179.   IOCON_P0_21 &= ~0x7; IOCON_P0_21 |= 0x4;
  180.   IOCON_P0_22 &= ~0x7; IOCON_P0_22 |= 0x4;
  181.  
  182.   IOCON_P2_07 &= ~0x7; IOCON_P2_07 |= 0x1;
  183.   IOCON_P0_08 &= ~0x7; IOCON_P2_08 |= 0x1;
  184.  
  185.   // Triggers reset mode - all (writable) registers can be written to.
  186.   CAN1MOD = 1;
  187.   CAN1IER = 0;
  188.   CAN1GSR = 0;
  189.  
  190.   // Aborts transmissions, releases receive buffer and clears data overrun.
  191.   CAN1CMR_bit.AT  = 1;
  192.   CAN1CMR_bit.RRB = 1;
  193.   CAN1CMR_bit.CDO = 1;
  194.  
  195.   // Read to clear register.
  196.   uint16_t i = CAN1ICR;
  197.  
  198.   AFMR = 0x01;
  199.  
  200.   SFF_SA     = 0;
  201.   SFF_GRP_SA = 0;
  202.   EFF_SA     = 0;
  203.   EFF_GRP_SA = 0;
  204.   ENDOFTABLE = 0;
  205.  
  206.   AFMR  = 0;
  207.  
  208.   // Set baud rate.
  209.   setCANBaudRate(BAUD_RATE);
  210. }
  211.  
  212. // Params: None
  213. // Returns: None
  214. // Description: Performs a self-test on the CAN peripheral.
  215. void testCAN()
  216. {
  217.   uint32_t *ptr;
  218.  
  219.   // Enter reset mode.
  220.   CAN1MOD_bit.RM  = 1;
  221.  
  222.   // Enable bypassing.
  223.   AFMR_bit.ACCBP = 1;
  224.  
  225.   // Clear acceptance filter RAM.
  226.   for(uint32_t i=0; i < 512; i++)
  227.   {
  228.     ptr  = (uint32_t*)(AFRAM+i);
  229.     *ptr = 0;
  230.   }
  231.  
  232.   /*
  233.   // Set up acceptance filter values; reserve space in SFF_sa for one
  234.   // standard format group id.
  235.   SFF_SA     = (0x00 << 1);
  236.   SFF_GRP_SA = (0x00 << 1);
  237.   EFF_SA     = (0x20 << 1);
  238.   EFF_GRP_SA = (0x20 << 1);
  239.   ENDOFTABLE = (0x20 << 1);
  240.  
  241.   ptr = (uint32_t*)AFRAM;
  242.   // [    Valid ID 1   ] [    Valid ID 2   ]
  243.   // 0010 0111 1111 1111 0010 0000 0000 0000
  244.   // *ptr = 0x2EFF2000;
  245.  
  246.   // 0010 0000 0000 0000 0010 0111 1111 1111
  247.   *ptr = 0x20002EFF;
  248.   */
  249.  
  250.   // Enable self-testing mode.
  251.   CAN1MOD_bit.STM = 1;
  252.   CAN1CMR_bit.SRR = 1;
  253.  
  254.   // Re-enter normal operational mode.
  255.   CAN1MOD_bit.RM  = 0;
  256.  
  257.   // Enable interrupts on transmitting and receiving messages.
  258.   CAN1IER_bit.RIE      = 1;
  259.   CAN1IER_bit.TIE1     = 1;
  260.   CAN1IER_bit.IDIE     = 1;
  261.   SETENA0_bit.SETENA25 = 1;
  262.  
  263.   // [(En)/Dis]able AF bypassing.
  264.   AFMR_bit.ACCBP  = 1;
  265.   //AFMR_bit.ACCOFF = 0;
  266.   //AFMR_bit.EFCAN  = 1;
  267.  
  268.  
  269.   uint8_t dataA[] = { 0x12, 0x12, 0x12, 0x12 };
  270.   uint8_t dataB[] = { 0x34, 0x34, 0x34, 0x34 };
  271.   uint8_t dataZ[] = { 0, 0, 0, 0};
  272.   configCANMessage(0xEFF, dataA, dataB, 8, STD_ID_FORMAT, DATA_FRAME,
  273.                    TRANSMITTING);
  274.  
  275.   configCANMessage(0, dataZ, dataZ, 0, 0, 0, RECEIVING);
  276.  
  277.   printf("Sending message...\n");
  278.  
  279.   sendCANMessage(&transMessage);
  280. }
  281.  
  282. // Params: id       - the id of the message (if format = STD_ID_FORMAT, then id
  283. //                    should be 11 bits long, else if format = EXT_ID_FORMAT,
  284. //                    then id should be 29 bits long).
  285. //         dataA[4] - data field A.
  286. //         dataB[4] - data field B.
  287. //         len      - the length of the data field in bytes
  288. //                    (0000b - 0111b: 0-7 bytes, 1xxxb - 8 bytes).
  289. //         format   - the format of the id
  290. //                    (STD_ID_FORMAT - 11 bit format,
  291. //                    EXT_ID_FORMAT - 29 bit format).
  292. //         type     - remote transmission request
  293. //                  - (DATA_FRAME - the number of data bytes called out by the
  294. //                    DLC field are sent from the CANxTDA and CANxTDB
  295. //                    registers,
  296. //                    REMOTE FRAME - a remote frame is sent).
  297. //         dir      - specifies if the message format is for messages being
  298. //                    sent or received (0 - receiving, 1 - transmitting).
  299. // Returns: None
  300. // Description: Configures the format for transmitting and receiving messages.
  301. void configCANMessage(uint32_t id, uint8_t dataA[4], uint8_t dataB[4],
  302.                                uint8_t len, uint8_t format, uint8_t type,
  303.                                uint8_t dir)
  304. {
  305.   if(dir)
  306.   {
  307.     transMessage.id     = id;
  308.    
  309.     for(int i=0; i < 4; i++)
  310.     {
  311.       transMessage.dataA[i]  = dataA[i];
  312.       transMessage.dataB[i]  = dataB[i];
  313.     }
  314.    
  315.     transMessage.len    = len;
  316.     transMessage.format = format;
  317.     transMessage.type   = type;
  318.   }
  319.   else
  320.   {
  321.     recMessage.id     = id;
  322.    
  323.     for(int i=0; i < 4; i++)
  324.     {
  325.       recMessage.dataA[i]  = dataA[i];
  326.       recMessage.dataB[i]  = dataB[i];
  327.     }
  328.    
  329.     recMessage.len    = len;
  330.     recMessage.format = format;
  331.     recMessage.type   = type;
  332.   }
  333. }
  334.  
  335. // Params: None
  336. // Returns: None
  337. // Description: Handles messages received over CAN.
  338. void CAN_IRQHandler(void)
  339. {  
  340.   printf("IRQ\n");
  341.  
  342.   /*
  343.   // Check receive buffer status.
  344.   if(CAN1GSR_bit.RBS)
  345.   {
  346.     printf("You have mail\n");
  347.   }
  348.   else
  349.   {
  350.     printf("You don't have mail\n");
  351.   }
  352.   */
  353.   CAN1ICR_bit;
  354.  
  355.   if(CAN1SR_bit.RBS)
  356.   {
  357.     receiveCANMessage(&recMessage);
  358.  
  359.     // Validate received and transmitted information.
  360.     if(checkMessage(&transMessage, &recMessage))
  361.     {
  362.       printf("Self test is successful\n");
  363.     }
  364.     else
  365.     {
  366.       printf("Self test is not successful\n");
  367.     }
  368.   }
  369. }
  370.  
  371. // Params: transMessage - the message being transmitted.
  372. //         recMessage - the message being received.
  373. // Returns: Whether the two messages are the same (0 - false, 1 - true).
  374. // Description: Compares the two messages to each other and determines if
  375. //              they are identical
  376. uint8_t checkMessage(CAN_MSG_Type* transMessage, CAN_MSG_Type* recMessage)
  377. {
  378.   if(transMessage->format != recMessage->format) return FALSE;
  379.   if(transMessage->id != recMessage->id) return FALSE;
  380.   if(transMessage->len != recMessage->len) return FALSE;
  381.   if(transMessage->type != recMessage->type) return FALSE;
  382.  
  383.   for(int i=0; i < 4; i++)
  384.   {
  385.     if(transMessage->dataA[i] != recMessage->dataA[i]
  386.        || transMessage->dataB[i] != recMessage->dataB[i]) return FALSE;
  387.   }
  388.  
  389.   return TRUE;
  390. }
  391.  
  392. // Params: recMessage - a message loaded with the information of the incoming
  393. //         data.
  394. // Returns: None
  395. // Description: loads data received over CAN into a message format.
  396. void receiveCANMessage(CAN_MSG_Type* recMessage)
  397. {
  398.   uint32_t data;
  399.  
  400.   // Check status of receive buffer.
  401.   if(CAN1SR_bit.RBS)
  402.   {
  403.     recMessage->format = CAN1RFS_bit.FF;
  404.     recMessage->type   = CAN1RFS_bit.RTR;
  405.     recMessage->len    = CAN1RFS_bit.DLC;
  406.     recMessage->id     = CAN1RID;
  407.    
  408.     if(recMessage->type == DATA_FRAME)
  409.     {
  410.       // Read first four bytes of data.
  411.       data = CAN1RDA;
  412.      
  413.       recMessage->dataA[0] = (data & 0x000000FF) >> 0;
  414.       recMessage->dataA[1] = (data & 0x0000FF00) >> 8;
  415.       recMessage->dataA[2] = (data & 0x00FF0000) >> 16;
  416.       recMessage->dataA[3] = (data & 0xFF000000) >> 24;
  417.      
  418.       // Read second four bytes of data.
  419.       data = CAN1RDB;
  420.      
  421.       recMessage->dataB[0] = (data & 0x000000FF) >> 0;
  422.       recMessage->dataB[1] = (data & 0x0000FF00) >> 8;
  423.       recMessage->dataB[2] = (data & 0x00FF0000) >> 16;
  424.       recMessage->dataB[3] = (data & 0xFF000000) >> 24;
  425.      
  426.       // Release receive buffer.
  427.       CAN1CMR_bit.RRB = 1;
  428.     }
  429.     // If the received frame is just a Remote Frame, then we do not have data
  430.     // and we release the receive buffer.
  431.     else
  432.     {
  433.       CAN1CMR_bit.RRB = 1;
  434.     }
  435.   }
  436. }
  437.  
  438. // Params: transMessage - the message to be transmitted.
  439. // Returns: None
  440. // Description: Prepares a message to be transmitted over CAN.
  441. void sendCANMessage(CAN_MSG_Type* transMessage)
  442. {
  443.   uint32_t data;
  444.  
  445.   // Check status of transmit buffer 1.
  446.   if(CAN1SR_bit.TBS1)
  447.   {
  448.     CAN1TFI1_bit.DLC = transMessage->len;
  449.    
  450.     if(transMessage->type == REMOTE_FRAME)
  451.     {
  452.       CAN1TFI1_bit.RTR = 1;
  453.     }
  454.     else
  455.     {
  456.       CAN1TFI1_bit.RTR = 0;
  457.     }
  458.    
  459.     if(transMessage->format == EXT_ID_FORMAT)
  460.     {
  461.       CAN1TFI1_bit.FF = 1;
  462.     }
  463.     else
  464.     {
  465.       CAN1TFI1_bit.FF = 0;
  466.     }
  467.    
  468.     // Write CAN ID.
  469.     CAN1TID1 = transMessage->id;
  470.    
  471.     data = ((transMessage->dataA[0]) << 0)
  472.          | ((transMessage->dataA[1]) << 8)
  473.          | ((transMessage->dataA[2]) << 16)
  474.          | ((transMessage->dataA[3]) << 24);
  475.    
  476.     // Write first four bytes of data.
  477.     CAN1TDA1 = data;
  478.    
  479.     data = ((transMessage->dataB[0]) << 0)
  480.          | ((transMessage->dataB[1]) << 8)
  481.          | ((transMessage->dataB[2]) << 16)
  482.          | ((transMessage->dataB[3]) << 24);
  483.    
  484.     // Write second four bytes of data.
  485.     CAN1TDB1 = data;
  486.    
  487.     // Select transfer buffer 1.
  488.     CAN1CMR_bit.STB1 = 1;
  489.    
  490.     // Write transmission request.
  491.     CAN1CMR_bit.TR = 1;
  492.    
  493.     while(!CAN1SR_bit.TCS1)
  494.     {
  495.       printf("Waiting...\n");
  496.     };
  497.    
  498.     //printf("Got this far\n");
  499.   }
  500. }
  501.  
  502. int main()
  503. {
  504.   // Initialise CAN.
  505.   initCAN();
  506.  
  507.   // Enter self-test mode.
  508.   testCAN();
  509.  
  510.   printf("In main\n");
  511.  
  512.   while(1);
  513.  
  514.   return 0;
  515. }