📄 mupdd.c
字号:
//-----------------------------------------------------------------------------
//
// Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Copyright (C) 2004, Freescale Semiconductor, Inc. All Rights Reserved
// THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
// BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
// Freescale Semiconductor, Inc.
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// File: mupdd.c
//
// Implementation of Messaging Unit Driver
//
//-----------------------------------------------------------------------------
#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include "mxarm11.h"
#include "mu.h"
#include "mu_priv.h"
//-----------------------------------------------------------------------------
// External Functions
extern UINT32 BSPMUCalculateCompareVal(UINT32 period);
extern DWORD BSPMUGetMaxQueueSize();
extern DWORD MUGetPhysAddr(void);
extern MU_IRQ_STRUCT MUGetIRQs(void);
//-----------------------------------------------------------------------------
// External Variables
//-----------------------------------------------------------------------------
// Defines
#define MIN_MESSAGE_LENGTH 1 // in bytes
#define MAX_MESSAGE_LENGTH 16
#define MU_WRITE_TIMEOUT 250
#define MU_READ_TIMEOUT 250
#define MU_THREAD_PRIORITY_DEFAULT 250
#define NUM_MU_INTERRUPTS 13
#define MU_TRANSMIT_QUEUE_NAME L"MU transmit queue"
#define MU_RECEIVE_QUEUE_NAME L"MU receive queue"
#define MU_REG_PATH L"Drivers\\BuiltIn\\MGU"
#define MU_REG_GPI3_PRI_KEYWORD L"GPI3ThreadPriority"
#define MU_REG_GPI2_PRI_KEYWORD L"GPI2ThreadPriority"
#define MU_REG_GPI1_PRI_KEYWORD L"GPI1ThreadPriority"
#define MU_REG_GPI0_PRI_KEYWORD L"GPI0ThreadPriority"
#define MU_REG_RX_PRI_KEYWORD L"ReceiveThreadPriority"
#define MU_REG_TX_PRI_KEYWORD L"TransmitThreadPriority"
//-----------------------------------------------------------------------------
// Types
typedef struct MUShortMessage
{
UINT16 iLength; // number of 32-byte words comprising the message
DWORD dwChunk[4]; // up to 4 32-bit words
} MUShortMessage_c;
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
// Local Variables
static PCSP_MU_REGS g_pMU;
static CRITICAL_SECTION g_csMULock;
// System Interrupts
static DWORD g_MUTXIntr;
static DWORD g_MURXIntr;
static DWORD g_MUGPI3Intr;
static DWORD g_MUGPI2Intr;
static DWORD g_MUGPI1Intr;
static DWORD g_MUGPI0Intr;
// Hardware interrupt events, registered
// using InterruptInitialize
static HANDLE g_hMUTXIntrEvent = NULL;
static HANDLE g_hMURXIntrEvent = NULL;
static HANDLE g_hMUGPI3IntrEvent = NULL;
static HANDLE g_hMUGPI2IntrEvent = NULL;
static HANDLE g_hMUGPI1IntrEvent = NULL;
static HANDLE g_hMUGPI0IntrEvent = NULL;
// Interrupt events signalled to the application
static HANDLE g_hMUTransmit0EmptyEvent = NULL;
static HANDLE g_hMUTransmit1EmptyEvent = NULL;
static HANDLE g_hMUTransmit2EmptyEvent = NULL;
static HANDLE g_hMUTransmit3EmptyEvent = NULL;
static HANDLE g_hMUReceive0FullEvent = NULL;
static HANDLE g_hMUReceive1FullEvent = NULL;
static HANDLE g_hMUReceive2FullEvent = NULL;
static HANDLE g_hMUReceive3FullEvent = NULL;
static HANDLE g_hMUGPI3Event = NULL;
static HANDLE g_hMUGPI2Event = NULL;
static HANDLE g_hMUGPI1Event = NULL;
static HANDLE g_hMUGPI0Event = NULL;
// Thread handles
static HANDLE g_hMUReadThread = NULL;
static HANDLE g_hMUWriteThread = NULL;
static HANDLE g_hMUGPI3Thread = NULL;
static HANDLE g_hMUGPI2Thread = NULL;
static HANDLE g_hMUGPI1Thread = NULL;
static HANDLE g_hMUGPI0Thread = NULL;
// Variables for Transmit and Receive Queues
static HANDLE g_hReadTransmitQueue; // read-enabled handle to queue
static HANDLE g_hWriteTransmitQueue; // write-enabled handle to queue
static HANDLE g_hReadReceiveQueue;
static HANDLE g_hWriteReceiveQueue;
static CRITICAL_SECTION g_csWriteBufferLock;
static CRITICAL_SECTION g_csReadBufferLock;
//-----------------------------------------------------------------------------
// Local Functions
static void MUStatus(void);
static void MUReadIntrThread(void);
static void MUWriteIntrThread(void);
static void MUGPI3IntrThread(void);
static void MUGPI2IntrThread(void);
static void MUGPI1IntrThread(void);
static void MUGPI0IntrThread(void);
static void MUReadISRLoop(UINT32);
static void MUWriteISRLoop(UINT32);
static void MUGPI3ISRLoop(UINT32);
static void MUGPI2ISRLoop(UINT32);
static void MUGPI1ISRLoop(UINT32);
static void MUGPI0ISRLoop(UINT32);
//-----------------------------------------------------------------------------
//
// Function: MUInitialize
//
// This function will call the PMU function to enable the timer source
// clock and create the timer irq event and create the IST thread.
//
// Parameters:
// None
//
// Returns:
// TRUE - If success
//
// FALSE - If failure
//
//-----------------------------------------------------------------------------
BOOL MUInitialize(void)
{
PHYSICAL_ADDRESS phyAddr;
MU_IRQ_STRUCT muIRQs;
MSGQUEUEOPTIONS queueOptions;
UINT8 numIntrs = NUM_MU_INTERRUPTS;
DWORD maxNumMessages, dwAddr;
DWORD dwGPI3Priority, dwGPI2Priority, dwGPI1Priority,
dwGPI0Priority, dwRXPriority, dwTXPriority, dwSize;
HKEY hKey;
UINT32 error;
MU_FUNCTION_ENTRY();
// Map MU register address space
dwAddr = MUGetPhysAddr();
phyAddr.QuadPart = dwAddr;
g_pMU = (PCSP_MU_REGS) MmMapIoSpace(phyAddr, sizeof(CSP_MU_REGS), FALSE);
// check if Map Virtual Address failed
if (g_pMU == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: MmMapIoSpace failed!\r\n"), __WFUNCTION__));
return FALSE;
}
// Get SOC-specific IRQs
muIRQs = MUGetIRQs();
// Create interrupt events
DEBUGMSG(ZONE_INFO, (TEXT("%s: CreateEvent calls\r\n"), __WFUNCTION__));
g_hMUTXIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_hMUTXIntrEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMURXIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_hMURXIntrEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUGPI3IntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_hMUGPI3IntrEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUGPI2IntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_hMUGPI2IntrEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUGPI1IntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_hMUGPI1IntrEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUGPI0IntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_hMUGPI0IntrEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
// Create events to facilitate communication of
// interrupt status with applications.
// Event names are shared between the driver and application,
// and allow both sides to acquire a handle to the event
// without using an API.
g_hMUTransmit0EmptyEvent = CreateEvent(NULL, FALSE, FALSE, MU_TRANSMIT_0_EMPTY_EVENT);
if (g_hMUTransmit0EmptyEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUTransmit1EmptyEvent = CreateEvent(NULL, FALSE, FALSE, MU_TRANSMIT_1_EMPTY_EVENT);
if (g_hMUTransmit1EmptyEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUTransmit2EmptyEvent = CreateEvent(NULL, FALSE, FALSE, MU_TRANSMIT_2_EMPTY_EVENT);
if (g_hMUTransmit2EmptyEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUTransmit3EmptyEvent = CreateEvent(NULL, FALSE, FALSE, MU_TRANSMIT_3_EMPTY_EVENT);
if (g_hMUTransmit3EmptyEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUReceive0FullEvent = CreateEvent(NULL, FALSE, FALSE, MU_RECEIVE_0_FULL_EVENT);
if (g_hMUReceive0FullEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUReceive1FullEvent = CreateEvent(NULL, FALSE, FALSE, MU_RECEIVE_1_FULL_EVENT);
if (g_hMUReceive1FullEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUReceive2FullEvent = CreateEvent(NULL, FALSE, FALSE, MU_RECEIVE_2_FULL_EVENT);
if (g_hMUReceive2FullEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUReceive3FullEvent = CreateEvent(NULL, FALSE, FALSE, MU_RECEIVE_3_FULL_EVENT);
if (g_hMUReceive3FullEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
DEBUGMSG(ZONE_INFO, (TEXT("%s: CreateEvent calls\r\n"), __WFUNCTION__));
g_hMUGPI3Event = CreateEvent(NULL, FALSE, FALSE, MU_GPI3_EVENT);
if (g_hMUGPI3Event == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUGPI2Event = CreateEvent(NULL, FALSE, FALSE, MU_GPI2_EVENT);
if (g_hMUGPI2Event == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUGPI1Event = CreateEvent(NULL, FALSE, FALSE, MU_GPI1_EVENT);
if (g_hMUGPI1Event == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
g_hMUGPI0Event = CreateEvent(NULL, FALSE, FALSE, MU_GPI0_EVENT);
if (g_hMUGPI0Event == NULL)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: CreateEvent failed\r\n"), __WFUNCTION__));
goto Error;
}
// Translate IRQs to SYSINTRs
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &muIRQs.txIRQ,
sizeof(muIRQs.txIRQ), &g_MUTXIntr, sizeof(g_MUTXIntr), NULL))
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Request SYSINTR failed\r\n"), __WFUNCTION__));
goto Error;
}
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &muIRQs.rxIRQ,
sizeof(muIRQs.rxIRQ), &g_MURXIntr, sizeof(g_MURXIntr), NULL))
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Request SYSINTR failed\r\n"), __WFUNCTION__));
goto Error;
}
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &muIRQs.gpi3IRQ,
sizeof(muIRQs.gpi3IRQ), &g_MUGPI3Intr, sizeof(g_MUGPI3Intr), NULL))
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Request SYSINTR failed\r\n"), __WFUNCTION__));
goto Error;
}
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &muIRQs.gpi2IRQ,
sizeof(muIRQs.gpi2IRQ), &g_MUGPI2Intr, sizeof(g_MUGPI2Intr), NULL))
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Request SYSINTR failed\r\n"), __WFUNCTION__));
goto Error;
}
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &muIRQs.gpi1IRQ,
sizeof(muIRQs.gpi1IRQ), &g_MUGPI1Intr, sizeof(g_MUGPI1Intr), NULL))
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Request SYSINTR failed\r\n"), __WFUNCTION__));
goto Error;
}
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &muIRQs.gpi0IRQ,
sizeof(muIRQs.gpi0IRQ), &g_MUGPI0Intr, sizeof(g_MUGPI0Intr), NULL))
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Request SYSINTR failed\r\n"), __WFUNCTION__));
goto Error;
}
if(!InterruptInitialize(g_MUTXIntr, g_hMUTXIntrEvent, NULL, 0))
{
CloseHandle(g_hMUTXIntrEvent);
g_hMUTXIntrEvent = NULL;
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Interrupt initialization failed! \r\n"), __WFUNCTION__));
goto Error;
}
if(!InterruptInitialize(g_MURXIntr, g_hMURXIntrEvent, NULL, 0))
{
CloseHandle(g_hMURXIntrEvent);
g_hMURXIntrEvent = NULL;
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Interrupt initialization failed! \r\n"), __WFUNCTION__));
goto Error;
}
if(!InterruptInitialize(g_MUGPI3Intr, g_hMUGPI3IntrEvent, NULL, 0))
{
CloseHandle(g_hMUGPI3IntrEvent);
g_hMUGPI3IntrEvent = NULL;
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Interrupt initialization failed! \r\n"), __WFUNCTION__));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -