Added Software projects
git-svn-id: file:///srv/dev-disk-by-uuid-17e88007-4d0c-45e0-8757-cacfcc458630/repositories/svn/Diplomarbeit@55 9fe90eed-be63-e94b-8204-d34ff4c2ff93
This commit is contained in:
@@ -0,0 +1,460 @@
|
||||
/* ---------------------------------------------------------------------------
|
||||
* can.c (c) 2008 Micro-key bv
|
||||
* ---------------------------------------------------------------------------
|
||||
* Micro-key bv
|
||||
* Industrieweg 28, 9804 TG Noordhorn
|
||||
* Postbus 92, 9800 AB Zuidhorn
|
||||
* The Netherlands
|
||||
* Tel: +31 594 503020
|
||||
* Fax: +31 594 505825
|
||||
* Email: support@microkey.nl
|
||||
* Web: www.microkey.nl
|
||||
* ---------------------------------------------------------------------------
|
||||
* Description:
|
||||
* ---------------------------------------------------------------------------
|
||||
* Version(s): 0.1, Feb 11, 2008, MMi
|
||||
* Creation.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* System include files
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
/* Hardware Includes */
|
||||
#include "LPC23xx.h"
|
||||
#include "types.h"
|
||||
|
||||
/* FreeRTOS includes */
|
||||
#include "FreeRTOS.h"
|
||||
#include "Task.h"
|
||||
#include "queue.h"
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Application include files
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
#include "can.h"
|
||||
#include "SerOut.h"
|
||||
#include "armVIC.h"
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Local constant and macro definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
#define CAN_PORT 2
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Global variable definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
static UINT32 debugVar = 0;
|
||||
static UINT32 debugCnt = 0;
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Local variable definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
UINT16 volatile gCANFilter = 0; /* Number of global set filters */
|
||||
|
||||
CAN_MSG volatile gCANList[MAX_FILTERS]; /* CAN message list */
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Local function definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
UINT16 CANInit (UINT32 can_btr)
|
||||
{
|
||||
|
||||
PCONP |= (1 << 14); /* power on CAN2 */
|
||||
|
||||
|
||||
/* Enable Pins for CAN interface */
|
||||
/* Set P0.4 to function 10 (RD2) */
|
||||
PINSEL0 &=~(1 << 8); /* Clear Bit 8 in PINSEL0 */
|
||||
PINSEL0 |= (1 << 9); /* set bit 9 in PINSEL0 */
|
||||
/* Set P0.5 to function 10 (TD2) */
|
||||
PINSEL0 &=~(1 << 10); /* Clear bit 10 in PINSEL0 */
|
||||
PINSEL0 |= (1 << 11); /* Set bit 11 in PINSEL0 */
|
||||
|
||||
gCANFilter = 0; /* Reset previous Filters */
|
||||
// CAN_AFMR = 0x00000001L; /* Switch off Aceptance Filter */
|
||||
|
||||
CAN2MOD = 0x00000001; /* Set Mode to Reset (Bit 0) */
|
||||
CAN2IER = 0x00000000; /* Disable all CAN2 Interrupts */
|
||||
CAN2GSR = 0x00000000; /* Clear all status bits */
|
||||
CAN2BTR = can_btr; /* Set bus timing */
|
||||
|
||||
/* Set Address of CAN ISR to Vectored Interrupt Address 23 */
|
||||
VICVectAddr23 = (unsigned long) CAN_IRS_Handler;
|
||||
VICVectCntl23 = 1; /* Set a low interrupt priority */
|
||||
VICIntEnable |= (1 << 23); /* Enable CAN interrupt */
|
||||
|
||||
// CAN2IER = 0x00000081; /* Enable all RX and Err IRQs */
|
||||
CAN2IER = 0x00000001; /* Enable all RX IRQs */
|
||||
CAN2MOD = 0x00000000; /* Set Mode to Normal (Bit 0) */
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
UINT16 CANSetFilter (UINT32 CANID)
|
||||
{
|
||||
UINT32 loopcnt = 0;
|
||||
UINT32 regbuffer = 0;
|
||||
UINT32 buf0;
|
||||
UINT32 buf1;
|
||||
UINT32 ID_lower;
|
||||
UINT32 ID_upper;
|
||||
UINT32 *pAddr;
|
||||
|
||||
CAN_AFMR = 0x00000001L; /* Switch off Acceptance filter */
|
||||
|
||||
if (gCANFilter == 0)
|
||||
{
|
||||
/* First filter set - Init Entry of position Zero */
|
||||
/* Make first array entry for CAN device 1
|
||||
* This is necessary due to the following sort algorithm
|
||||
*/
|
||||
gCANList[0].Dat1 = 0x000037FFL;
|
||||
}
|
||||
|
||||
if (gCANFilter >= MAX_FILTERS)
|
||||
{
|
||||
/* If Array index exceeds the limit, return with error */
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
CANID &= 0x000007FFL; /* Mask the 11-bit ID */
|
||||
CANID |= ((CAN_PORT - 1) << 13); /* Add PORT# to ID */
|
||||
|
||||
/* Filters must be sorted by interface, then by priority */
|
||||
|
||||
/* Algorithm to sort new entry into excisting array */
|
||||
while (loopcnt < gCANFilter) /* Look through all entries */
|
||||
{
|
||||
if ((gCANList[loopcnt].Dat1 & 0x0000FFFFL)> CANID)
|
||||
{
|
||||
/* Found position to insert new entry */
|
||||
break;
|
||||
}
|
||||
loopcnt++;
|
||||
}
|
||||
|
||||
buf0 = gCANList[loopcnt].Dat1; /* Buffer old array entry */
|
||||
gCANList[loopcnt].Dat1 = CANID; /* Insert the new entry */
|
||||
|
||||
/* move all remaining entries one position up */
|
||||
gCANFilter++; /* Increase Filter counter */
|
||||
while (loopcnt < gCANFilter)
|
||||
{
|
||||
loopcnt++;
|
||||
buf1 = gCANList[loopcnt].Dat1;
|
||||
gCANList[loopcnt].Dat1 = buf0;
|
||||
buf0 = buf1;
|
||||
}
|
||||
|
||||
|
||||
CAN_SFF_SA = regbuffer; /* Set Std Frame Start Address */
|
||||
/* Set pointer to the Filter RAM base Address */
|
||||
pAddr = ( UINT32 *) ACCEPTANCE_FILTER_RAM_BASE;
|
||||
|
||||
for (loopcnt = 0; loopcnt < ((gCANFilter + 1) / 2); loopcnt++)
|
||||
{
|
||||
ID_lower = gCANList[loopcnt * 2].Dat1 & 0x0000FFFFL;
|
||||
ID_upper = gCANList[loopcnt * 2 + 1].Dat1 & 0x0000FFFFL;
|
||||
// candata = (ID_lower << 16) + ID_upper; // \TODO IS THIS WORKING?
|
||||
// *pAddr = candata;
|
||||
*pAddr = (ID_lower << 16) + ID_upper;
|
||||
regbuffer += 4;
|
||||
pAddr++;
|
||||
}
|
||||
|
||||
/* regbuffer points to the End of the Table */
|
||||
|
||||
CAN_SFF_GRP_SA = regbuffer; /* Set Std Group Start Address */
|
||||
|
||||
// Set pointer for Extended Frame Individual
|
||||
// Extended Frame Start Address Register
|
||||
CAN_EFF_SA = regbuffer; /* Set Extd. Frame Start Address*/
|
||||
|
||||
CAN_EFF_GRP_SA = regbuffer; /* Set Extd. Group Start Address*/
|
||||
|
||||
CAN_EOT = regbuffer; /* Set End of Table */
|
||||
|
||||
CAN_AFMR = 0; /* enable Acception Filter */
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
UINT16 CANPushMessage (CAN_MSG *pTransmitBuf)
|
||||
{
|
||||
UINT32 *pAddr;
|
||||
UINT32 *pCandata;
|
||||
UINT8 TXBufOffset;
|
||||
|
||||
pAddr = (UINT32 *) &CAN2SR; // CANSR
|
||||
|
||||
/* Check if one of the three transmit buffers are available, use first */
|
||||
if (!(*pAddr & 0x00000004L))
|
||||
{
|
||||
/* First Buffer is not available */
|
||||
if (!(*pAddr & 0x00000400L))
|
||||
{
|
||||
/* Second Buffer is not available */
|
||||
if (!(*pAddr & 0x00040000L))
|
||||
{
|
||||
/* Third Buffer is not available -> No Buffer available */
|
||||
return (FALSE); /* Abort transmission, Error */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Third Buffer is available, set Buffer offset */
|
||||
TXBufOffset = 0x08;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Second Buffer is available, set Buffer offset */
|
||||
TXBufOffset = 0x04;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* First Buffer is available, set Buffer offset */
|
||||
TXBufOffset = 0x00;
|
||||
}
|
||||
|
||||
/* Write Data to Transmit Frame Information Register */
|
||||
pAddr = (UINT32 *) &CAN2TFI1 + TXBufOffset; /* Set pointer to CAN2TFIx */ // \TODO WATCH HERE (had offset)!!!
|
||||
*pAddr = (pTransmitBuf->Dat1 & 0x000F0000L);
|
||||
|
||||
/* Write CAN ID to Transmit Identifier Register */
|
||||
pAddr++; /* Increase pointer to CAN2TIDx */
|
||||
*pAddr = pTransmitBuf->Dat1 & 0x000007FFL;
|
||||
|
||||
/* Write first four Bytes to Transmit Data Register A */
|
||||
pCandata = (UINT32 *) &(pTransmitBuf->DatA); /* Get first 4 bytes */
|
||||
pAddr++; /* Set pointer to DataA register*/
|
||||
*pAddr = *pCandata; /* Write first 4 bytes to DataA */
|
||||
|
||||
/* Write second four Bytes to Transmit Data Register B */
|
||||
pCandata++; /* Get second four bytes */
|
||||
pAddr++; /* Point to DataB register */
|
||||
*pAddr = *pCandata; /* Write second 4 Bytes to DataB*/
|
||||
|
||||
|
||||
/* Write Transmission Request to CAN2 Command Register
|
||||
* This Action is depending on the chosen transmission buffer (1-3)
|
||||
* Two bits must be written - Bit (0): (TR) Transmission Request
|
||||
* Bit (5|6|7): (STBx) Select Buffer (1|2|3)
|
||||
*/
|
||||
if (TXBufOffset == 0x00)
|
||||
{
|
||||
/* First buffer was chosen. Write TR and STB1 */
|
||||
CAN2CMR = 0x21;
|
||||
}
|
||||
else if (TXBufOffset == 0x04)
|
||||
{
|
||||
/* Second buffer was chosen. Write TR and STB2 */
|
||||
CAN2CMR = 0x41;
|
||||
}
|
||||
else if (TXBufOffset == 0x08)
|
||||
{
|
||||
/* Third buffer was chosen. Write TR and STB3 */
|
||||
CAN2CMR = 0x81;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No Buffer was chosen, return with error (should not come here) */
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
UINT16 CANPullMessage (CAN_MSG *pReceiveBuf)
|
||||
{
|
||||
UINT32 loopcnt = 0;
|
||||
UINT32 *pSrc;
|
||||
UINT32 *pDst;
|
||||
UINT32 match;
|
||||
|
||||
|
||||
/* Initialise Source and Destination Pointer */
|
||||
pSrc = (UINT32 *) &(gCANList[0].Dat1);
|
||||
pDst = (UINT32 *) &(pReceiveBuf->Dat1);
|
||||
|
||||
/* Prepare match value for CAN interface */
|
||||
match = CAN_PORT << 13;
|
||||
match |= 0x03000000L; /* Semaphore bits are 11b */
|
||||
|
||||
while (loopcnt < gCANFilter)
|
||||
{
|
||||
/* Scan for every set Filter */
|
||||
if ((*pSrc & 0x0300E000L) == match)
|
||||
{
|
||||
/* A new Message is detected in Source Array */
|
||||
*pSrc &= 0xFCFFFFFFL; /* clear Semaphore */
|
||||
|
||||
*pDst = *pSrc; /* Copy Dat1 from SRC to DST */
|
||||
|
||||
pSrc++; /* Set SRC-Pointer to SRC.DataA */
|
||||
pDst++; /* Set DST-Pointer to DST.DataA */
|
||||
|
||||
*pDst = *pSrc; /* Copy DatA from SRC to DST */
|
||||
|
||||
pSrc++; /* Set SRC-Pointer to SRC.DataB */
|
||||
pDst++; /* Set DST-Pointer to DST.DataB */
|
||||
|
||||
*pDst = *pSrc; /* Copy DatB from SRC to DST */
|
||||
|
||||
pSrc -= 2; // Reset SRC-Pointer to Dat1 */
|
||||
pDst -= 2; // Reset DST-Pointer to Dat1 */
|
||||
|
||||
if ((*pSrc & 0x03000000L) == 0)
|
||||
{
|
||||
/* If actual SRC was updated while reading, return to caller
|
||||
* This is to prevent of ignoring the message that came in while
|
||||
* reading, which would not be noticed if the message counter
|
||||
* will be increased like the loop will do in the next step
|
||||
*/
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
loopcnt++; /* Go to next Message in Buffer */
|
||||
pSrc += 3; /* Increase SRC-Pointer to next */
|
||||
}
|
||||
return (FALSE); /* Return False if no Message in*/
|
||||
}
|
||||
|
||||
|
||||
void CAN_IRS_Handler()
|
||||
{
|
||||
UINT32 CANStatus;
|
||||
|
||||
ISR_ENTRY();
|
||||
CANStatus = CAN_RX_SR;
|
||||
if (CANStatus & (1 << 8))
|
||||
{
|
||||
/* A received Message is available in CAN1 controller */
|
||||
CAN_CANISR_Rx1();
|
||||
}
|
||||
if (CANStatus & (1 << 9))
|
||||
{
|
||||
/* A received Message is available in CAN2 controller */
|
||||
CAN_CANISR_Rx2();
|
||||
}
|
||||
|
||||
/* Error Interrupts are currently disabled due to purpose of CAN driver */
|
||||
if (CAN_MSR & (1 << 1))
|
||||
{
|
||||
/* At least one Error-Counter of CAN2 has reached the limit */
|
||||
CAN_CANISR_Err();
|
||||
}
|
||||
if (CAN1GSR & (1 << 6 ))
|
||||
{
|
||||
/* The error count includes both TX and RX */
|
||||
}
|
||||
if (CAN2GSR & (1 << 6 ))
|
||||
{
|
||||
/* The error count includes both TX and RX */
|
||||
}
|
||||
if (CAN2ICR & (1 << 7))
|
||||
{
|
||||
/* Error-on-Bus Interrupt detected */
|
||||
CAN_ERRORBUS();
|
||||
}
|
||||
|
||||
VICVectAddr = 0; /* Acknowledge Interrupt */
|
||||
|
||||
ISR_EXIT();
|
||||
}
|
||||
|
||||
|
||||
void CAN_CANISR_Rx1 (void)
|
||||
{
|
||||
UINT32 buf;
|
||||
UINT32 *pDest;
|
||||
|
||||
if (!(CAN1RFS & 0xC0000400L))
|
||||
{ // 11-bit ID, no RTR, matched a filter
|
||||
|
||||
// initialize destination pointer
|
||||
// filter number is in lower 10 bits of C1RFS
|
||||
pDest = (UINT32 *) &(gCANList[(CAN1RFS & 0x000003FFL)].Dat1);
|
||||
|
||||
// calculate contents for first entry into CAN list
|
||||
buf = CAN1RFS & 0xC00F0000L; // mask FF, RTR and DLC
|
||||
buf |= 0x01002000L; // set semaphore to 01b and CAN port to 1
|
||||
buf |= CAN1RID & 0x000007FFL; // get CAN message ID
|
||||
|
||||
// now copy entire message to CAN list
|
||||
*pDest = buf;
|
||||
pDest++; // set to gCANList[(C1RFS & 0x000003FFL)].DatA
|
||||
*pDest = CAN1RDA;
|
||||
pDest++; // set to gCANList[(C1RFS & 0x000003FFL)].DatB
|
||||
*pDest = CAN1RDB;
|
||||
|
||||
// now set the sempahore to complete
|
||||
buf |= 0x03000000L; // set semaphore to 11b
|
||||
pDest -= 2; // set to gCANList[(C1RFS & 0x000003FFL)].Dat1
|
||||
*pDest = buf;
|
||||
}
|
||||
|
||||
CAN1CMR = 0x04; // release receive buffer
|
||||
}
|
||||
|
||||
|
||||
void CAN_CANISR_Rx2(void)
|
||||
{
|
||||
UINT32 buf;
|
||||
UINT32 *pDest;
|
||||
|
||||
debugVar = 0x00000001;
|
||||
|
||||
if (!(CAN2RFS & 0xC0000400L))
|
||||
{
|
||||
/* 11-bit ID, no RTR */
|
||||
debugVar = 0x00000011;
|
||||
/* initialize Destination Pointer */
|
||||
/* Filter Nmber is in bit 0-9 of CAN2RFS */
|
||||
pDest = (UINT32 *) &(gCANList[(CAN2RFS & 0x000003FFL)].Dat1);
|
||||
// pDest = (UINT32 *) &(gCANList[(1)].Dat1);
|
||||
|
||||
/* Calculate contents for first entry into CAN list */
|
||||
buf = CAN2RFS & 0xC00F0000L; /* Mask FF, RTR and DLC */
|
||||
buf |= 0x01004000L; /* set sema to 01b and port to 2*/
|
||||
buf |= CAN2RID & 0x000007FFL; /* get CAN message ID */
|
||||
|
||||
/* Copy entire message to CAN list */
|
||||
*pDest = buf; /* Copy Dat1 to DST */
|
||||
pDest++; /* Set Pointer to DataA */
|
||||
*pDest = CAN2RDA; /* copy DataA */
|
||||
pDest++; /* Set Pointer to DataB */
|
||||
*pDest = CAN2RDB; /* Copy DataB */
|
||||
|
||||
|
||||
buf |= 0x03000000L; /* semaphore to 11b (complete) */
|
||||
pDest -= 2; /* Set back to Dat1 */
|
||||
*pDest = buf; /* update semaphore in DST */
|
||||
}
|
||||
|
||||
debugCnt++;
|
||||
CAN2CMR = 0x04; /* Release Receive Buffer */
|
||||
}
|
||||
|
||||
|
||||
void CAN_CANISR_Err (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CAN_ERRORBUS (void)
|
||||
{
|
||||
volatile UINT32 regRead;
|
||||
|
||||
regRead = CAN2ICR;
|
||||
|
||||
debugPrint("released");
|
||||
}
|
||||
Reference in New Issue
Block a user