Moved remotely

git-svn-id: file:///srv/dev-disk-by-uuid-17e88007-4d0c-45e0-8757-cacfcc458630/repositories/svn/Diplomarbeit@113 9fe90eed-be63-e94b-8204-d34ff4c2ff93
This commit is contained in:
Matthias
2009-01-12 08:38:14 +00:00
parent 4e45654a5f
commit 6cc948eef8
204 changed files with 0 additions and 0 deletions
+460
View File
@@ -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");
}