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,716 @@
|
||||
/* ---------------------------------------------------------------------------
|
||||
* dio.c - v0.1 (c) 2007 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: Digital inputs/outputs interface.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Version(s): 0.1, 28-11-2007, fvds.
|
||||
* Creation.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* System include files
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
/* Compiler includes */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Hardware Includes */
|
||||
#include "LPC23xx.h"
|
||||
#include "types.h"
|
||||
|
||||
/* FreeRTOS includes */
|
||||
#include "FreeRTOS.h"
|
||||
#include "Task.h"
|
||||
#include "queue.h"
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Application include files
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
#include "dio.h"
|
||||
#include "dioISR.h"
|
||||
#include "armVIC.h"
|
||||
#include "ElecStatusCache.h"
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Local constant and macro definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
#define PORT0_BASE_ADDR FIO_BASE_ADDR
|
||||
#define PORT1_BASE_ADDR (FIO_BASE_ADDR + 0x20)
|
||||
#define PORT2_BASE_ADDR (FIO_BASE_ADDR + 0x40)
|
||||
#define PORT3_BASE_ADDR (FIO_BASE_ADDR + 0x60)
|
||||
#define PORT4_BASE_ADDR (FIO_BASE_ADDR + 0x80)
|
||||
|
||||
#define DIR_OFFSET (0x00)
|
||||
#define MASK_OFFSET (0x10)
|
||||
#define PIN_OFFSET (0x14)
|
||||
#define SET_OFFSET (0x18)
|
||||
#define CLR_OFFSET (0x1C)
|
||||
|
||||
// \MARK NEW PINSETTINGS FOR TESTER (2)
|
||||
#if (PINSET_TESTER == 2)
|
||||
#define DIO_MUX_DIR FIO3DIR
|
||||
#define DIO_MUX_SET FIO3SET
|
||||
#define DIO_MUX_CLR FIO3CLR
|
||||
|
||||
#define DIN_MUX_BIT BIT(25)
|
||||
#define DIN_MUX_SET (DIO_MUX_SET = DIN_MUX_BIT)
|
||||
#define DIN_MUX_CLR (DIO_MUX_CLR = DIN_MUX_BIT)
|
||||
|
||||
|
||||
#define DOUT_MUX_BIT BIT(26)
|
||||
#define DOUT_MUX_SET (DIO_MUX_SET = DOUT_MUX_BIT)
|
||||
#define DOUT_MUX_CLR (DIO_MUX_CLR = DOUT_MUX_BIT)
|
||||
#endif
|
||||
|
||||
#define DISPATCH_TASK_PRIO (tskIDLE_PRIORITY + 5)
|
||||
#define DISPATCH_QUEUE_SIZE 10
|
||||
|
||||
#define Int_queue_time 3 /* In Miliseconds */
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Global variable definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Local variable definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
portTickType dechatterStopTime[maxDI_Channels]; /* Contains tickcount Value, where*/
|
||||
/* dechattering timeout occours */
|
||||
|
||||
UINT8 dechatterLockFlag[maxDI_Channels] = /* Channel Lock Flag */
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
UINT32 dechatterTime[maxDI_Channels] = /* TimeDelay until dechatter timeout*/
|
||||
{
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10
|
||||
};
|
||||
|
||||
// \MARK NEW PINSETTINGS FOR TESTER (2)
|
||||
#if (PINSET_TESTER == 2)
|
||||
t_output outputPins[maxDO_Channels] =
|
||||
{
|
||||
{ PORT4_BASE_ADDR, BIT(8) }, // DOUT0
|
||||
{ PORT4_BASE_ADDR, BIT(9) }, // DOUT1
|
||||
{ PORT4_BASE_ADDR, BIT(10) }, // DOUT2
|
||||
{ PORT4_BASE_ADDR, BIT(11) }, // DOUT3
|
||||
{ PORT4_BASE_ADDR, BIT(12) }, // DOUT4
|
||||
{ PORT4_BASE_ADDR, BIT(13) }, // DOUT5
|
||||
{ PORT4_BASE_ADDR, BIT(14) }, // DOUT6
|
||||
{ PORT4_BASE_ADDR, BIT(15) } // DOUT7
|
||||
};
|
||||
#else
|
||||
t_output outputPins[maxDO_Channels] =
|
||||
{
|
||||
{ PORT1_BASE_ADDR, BIT(0) }, // DOUT0
|
||||
{ PORT1_BASE_ADDR, BIT(1) }, // DOUT1
|
||||
{ PORT1_BASE_ADDR, BIT(4) }, // DOUT2
|
||||
{ PORT1_BASE_ADDR, BIT(8) }, // DOUT3
|
||||
{ PORT1_BASE_ADDR, BIT(9) }, // DOUT4
|
||||
{ PORT1_BASE_ADDR, BIT(10) }, // DOUT5
|
||||
{ PORT1_BASE_ADDR, BIT(14) }, // DOUT6
|
||||
{ PORT1_BASE_ADDR, BIT(15) } // DOUT7
|
||||
};
|
||||
#endif
|
||||
|
||||
t_input inputPins[maxDI_Channels] =
|
||||
{
|
||||
{ PORT0_BASE_ADDR, BIT(15), NULL }, // DIN0
|
||||
{ PORT0_BASE_ADDR, BIT(16), NULL }, // DIN1
|
||||
{ PORT0_BASE_ADDR, BIT(17), NULL }, // DIN2
|
||||
{ PORT0_BASE_ADDR, BIT(18), NULL }, // DIN3
|
||||
{ PORT0_BASE_ADDR, BIT(24), NULL }, // DIN4
|
||||
{ PORT0_BASE_ADDR, BIT(25), NULL }, // DIN5
|
||||
{ PORT0_BASE_ADDR, BIT(26), NULL }, // DIN6
|
||||
{ PORT0_BASE_ADDR, BIT(27), NULL }, // DIN7
|
||||
{ PORT0_BASE_ADDR, BIT(28), NULL }, // DIN8
|
||||
{ PORT0_BASE_ADDR, BIT(29), NULL }, // DIN9
|
||||
{ PORT0_BASE_ADDR, BIT(30), NULL } // DIN10
|
||||
};
|
||||
|
||||
BOOLEAN dioActive = FALSE;
|
||||
xQueueHandle dispatchedIsrQueue= 0;
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Local function definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
static void setMaskDirRegisters(void);
|
||||
static void enableChannelInterrupt(UINT8 channel);
|
||||
static void disableChannelInterrupt(UINT8 channel);
|
||||
static void isrDispatchTask(void *pvParameters);
|
||||
static BOOLEAN hasTimeoutPast( UINT32 endTick );
|
||||
static void startDechatterInput (UINT8 ChannelNumber, t_di_mode Edge);
|
||||
static void endDechatterInput (void);
|
||||
static void callAllCallbacks(t_callbackListItem *pCallbackList, t_di_mode detectedEdge);
|
||||
|
||||
|
||||
|
||||
void dioInit(void)
|
||||
{
|
||||
SCS |= (1UL<<0); /* GPIOM in SCS to fast IO */
|
||||
|
||||
setMaskDirRegisters(); /* Init channel Registers */
|
||||
dioActive= TRUE; /* Set global dioAcitve */
|
||||
|
||||
/* Create queue and Task for ISR-displatching */
|
||||
dispatchedIsrQueue = xQueueCreate( DISPATCH_QUEUE_SIZE, sizeof(t_IsrDispatchQueueItem));
|
||||
xTaskCreate(isrDispatchTask, ( signed portCHAR * ) "dioIsrDispatcher",
|
||||
configMINIMAL_STACK_SIZE, NULL, DISPATCH_TASK_PRIO, NULL);
|
||||
|
||||
/* Enable GPIO interrupt */
|
||||
portENTER_CRITICAL();
|
||||
{
|
||||
VICIntSelect &= ~(VIC_CHAN_TO_MASK(VIC_CHAN_NUM_EINT3));
|
||||
VICIntEnClr = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_EINT3);
|
||||
VICVectAddr17 = (void *)gpioISR;
|
||||
VICVectCntl7 = 0x01;
|
||||
VICIntEnable = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_EINT3);
|
||||
}
|
||||
portEXIT_CRITICAL();
|
||||
|
||||
// \MARK NEW PINSETTINGS FOR TESTER (2)
|
||||
#if (PINSET_TESTER == 2)
|
||||
/* Init both MUX lines as Outputs */
|
||||
DIO_MUX_DIR |= (DIN_MUX_BIT | DOUT_MUX_BIT);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void dio_inMuxEn (BOOLEAN mode)
|
||||
{
|
||||
// \MARK NEW PINSETTINGS FOR TESTER (2)
|
||||
#if (PINSET_TESTER == 2)
|
||||
if (mode == TRUE)
|
||||
{
|
||||
DIN_MUX_SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
DIN_MUX_CLR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void dio_outMuxEn (BOOLEAN mode)
|
||||
{
|
||||
// \MARK NEW PINSETTINGS FOR TESTER (2)
|
||||
#if (PINSET_TESTER == 2)
|
||||
if (mode == TRUE)
|
||||
{
|
||||
DOUT_MUX_SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
DOUT_MUX_CLR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN dio_inMuxRB (void)
|
||||
{
|
||||
// \MARK NEW PINSETTINGS FOR TESTER (2)
|
||||
#if (PINSET_TESTER == 2)
|
||||
if (DIO_MUX_SET & DIN_MUX_BIT)
|
||||
{
|
||||
/* MUX of digital input is switched to Extension Board */
|
||||
return (TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MUX of digital input is switched to Main Board */
|
||||
return (FALSE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN dio_outMuxRB (void)
|
||||
{
|
||||
// \MARK NEW PINSETTINGS FOR TESTER (2)
|
||||
#if (PINSET_TESTER == 2)
|
||||
if (DIO_MUX_SET & DOUT_MUX_BIT)
|
||||
{
|
||||
/* MUX of digital input is switched to Extension Board */
|
||||
return (TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MUX of digital input is switched to Main Board */
|
||||
return (FALSE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
RESULT dioRegisterCallback (t_dio_callbackfunc pFunc, UINT8 channel, t_di_mode mode)
|
||||
{
|
||||
RESULT result = OK;
|
||||
|
||||
disableChannelInterrupt(channel);
|
||||
|
||||
// Create item
|
||||
t_callbackListItem *newCallbackListItem =
|
||||
(t_callbackListItem *) pvPortMalloc(sizeof(t_callbackListItem));
|
||||
if (newCallbackListItem == NULL)
|
||||
{
|
||||
result = ERROR;
|
||||
} else
|
||||
{
|
||||
if (inputPins[channel].pCallbackList == NULL)
|
||||
{
|
||||
enableChannelInterrupt(channel);
|
||||
}
|
||||
|
||||
// Fill list item
|
||||
newCallbackListItem->pCallback = pFunc;
|
||||
newCallbackListItem->mode = mode;
|
||||
|
||||
// Add to front of list
|
||||
newCallbackListItem->next = inputPins[channel].pCallbackList;
|
||||
inputPins[channel].pCallbackList = newCallbackListItem;
|
||||
}
|
||||
|
||||
enableChannelInterrupt(channel);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Remove register callback function for digital input
|
||||
* \retval OK Callback was removed succesfully
|
||||
* \retval ERROR Failed to remove Callback-function from channel
|
||||
*/
|
||||
RESULT dioRemoveCallback(t_dio_callbackfunc pFunc, UINT8 channel)
|
||||
{
|
||||
RESULT result = OK;
|
||||
|
||||
disableChannelInterrupt(channel);
|
||||
|
||||
// Check if channel has callback list
|
||||
if (inputPins[channel].pCallbackList == NULL)
|
||||
{
|
||||
result = ERROR;
|
||||
} else
|
||||
{
|
||||
BOOLEAN callbackFound = FALSE;
|
||||
t_callbackListItem * previousItem= NULL;
|
||||
t_callbackListItem * currentItem = inputPins[channel].pCallbackList;
|
||||
|
||||
// Find callbackfunc
|
||||
while ((!callbackFound) && (currentItem != NULL))
|
||||
{
|
||||
callbackFound = (currentItem->pCallback == pFunc);
|
||||
|
||||
if (!callbackFound)
|
||||
{
|
||||
previousItem = currentItem;
|
||||
currentItem = currentItem->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (callbackFound)
|
||||
{
|
||||
if (previousItem == NULL)
|
||||
{
|
||||
// Remove first item from list
|
||||
inputPins[channel].pCallbackList = currentItem->next;
|
||||
} else
|
||||
{
|
||||
// Remove list item
|
||||
previousItem->next = currentItem->next;
|
||||
}
|
||||
vPortFree(currentItem); // Release resources of listitem
|
||||
} else
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (inputPins[channel].pCallbackList != NULL)
|
||||
{
|
||||
enableChannelInterrupt(channel);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Read digital input.*/
|
||||
BOOLEAN dioRead(UINT8 device, /**< 0 = Self, 1..32 = Remote device */
|
||||
UINT8 channel /**< 0..10 = valid, 11..255 = future use */
|
||||
)
|
||||
{
|
||||
BOOLEAN Result;
|
||||
volatile UINT32 *gpioRegister;
|
||||
|
||||
if (device == 0)
|
||||
{
|
||||
gpioRegister = (UINT32 *)(inputPins[channel].portBaseAddr + PIN_OFFSET);
|
||||
|
||||
// device is now ignored, future implementation
|
||||
|
||||
// Get result
|
||||
if (*gpioRegister & inputPins[channel].pinMask)
|
||||
{
|
||||
Result = FALSE;
|
||||
} else
|
||||
{
|
||||
Result = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = bpecDioRead( device, channel );
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
/** \brief Readback digital outputs.*/
|
||||
BOOLEAN dioReadBack(UINT8 device, /**< 0 = Self, 1..32 = Remote device */
|
||||
UINT8 channel /**< 0..7 = valid, 8..255 = future use */
|
||||
)
|
||||
{
|
||||
BOOLEAN Result;
|
||||
volatile UINT32 *gpioRegister;
|
||||
|
||||
if (device == 0)
|
||||
{
|
||||
gpioRegister = (UINT32 *)(outputPins[channel].portBaseAddr + PIN_OFFSET);
|
||||
|
||||
// device is now ignored, future implementation
|
||||
|
||||
// Get result
|
||||
// NOTE: Input signal is inverted
|
||||
if (*gpioRegister & outputPins[channel].pinMask)
|
||||
{
|
||||
Result = TRUE;
|
||||
} else
|
||||
{
|
||||
Result = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = bpecDioReadBack( device, channel );
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
/** \brief Write digital outputs.*/
|
||||
void dioWrite(UINT8 device, /**< 0 = Self, 1..32 = Remote device */
|
||||
UINT8 channel, /**< 0..7 = valid, 8..255 = future use */
|
||||
BOOLEAN data)
|
||||
{
|
||||
volatile UINT32 *gpioRegister;
|
||||
|
||||
if (device == 0)
|
||||
{
|
||||
if (data == TRUE)
|
||||
{
|
||||
gpioRegister = (UINT32 *)(outputPins[channel].portBaseAddr
|
||||
+ SET_OFFSET);
|
||||
*gpioRegister = outputPins[channel].pinMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpioRegister = (UINT32 *)(outputPins[channel].portBaseAddr
|
||||
+ CLR_OFFSET);
|
||||
*gpioRegister = outputPins[channel].pinMask;
|
||||
}
|
||||
} else
|
||||
{
|
||||
bpecWriteDioValue(device, channel, data);
|
||||
}
|
||||
}
|
||||
|
||||
void setMaskDirRegisters()
|
||||
{
|
||||
int i;
|
||||
volatile UINT32 *gpioRegister;
|
||||
|
||||
for (i=0; i< maxDO_Channels; i++)
|
||||
{
|
||||
// Clear bit in mask Register
|
||||
gpioRegister = (UINT32 *)(outputPins[i].portBaseAddr + MASK_OFFSET);
|
||||
*gpioRegister &= ~(outputPins[i].pinMask);
|
||||
|
||||
// Set direction bit to output
|
||||
gpioRegister = (UINT32 *)(outputPins[i].portBaseAddr + DIR_OFFSET);
|
||||
*gpioRegister |= outputPins[i].pinMask;
|
||||
}
|
||||
|
||||
for (i=0; i< maxDI_Channels; i++)
|
||||
{
|
||||
// Clear bit in maskRegister
|
||||
gpioRegister = (UINT32 *)(inputPins[i].portBaseAddr + MASK_OFFSET);
|
||||
*gpioRegister &= ~(inputPins[i].pinMask);
|
||||
|
||||
// Set direction bit to input
|
||||
gpioRegister = (UINT32 *)(inputPins[i].portBaseAddr + DIR_OFFSET);
|
||||
*gpioRegister &= ~(inputPins[i].pinMask);
|
||||
|
||||
// Reset callback functions
|
||||
inputPins[i].pCallbackList = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void enableChannelInterrupt(UINT8 channel)
|
||||
{
|
||||
if (inputPins[channel].portBaseAddr == PORT0_BASE_ADDR)
|
||||
{
|
||||
IO0_INT_CLR = inputPins[channel].pinMask;
|
||||
IO0_INT_EN_R |= inputPins[channel].pinMask;
|
||||
IO0_INT_EN_F |= inputPins[channel].pinMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
IO2_INT_CLR = inputPins[channel].pinMask;
|
||||
IO2_INT_EN_R |= inputPins[channel].pinMask;
|
||||
IO2_INT_EN_F |= inputPins[channel].pinMask;
|
||||
}
|
||||
}
|
||||
|
||||
void disableChannelInterrupt(UINT8 channel)
|
||||
{
|
||||
if (inputPins[channel].portBaseAddr == PORT0_BASE_ADDR)
|
||||
{
|
||||
IO0_INT_EN_R &= ~BIT(inputPins[channel].pinMask);
|
||||
IO0_INT_EN_F &= ~BIT(inputPins[channel].pinMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
IO2_INT_EN_R &= ~BIT(inputPins[channel].pinMask);
|
||||
IO2_INT_EN_F &= ~BIT(inputPins[channel].pinMask);
|
||||
}
|
||||
}
|
||||
|
||||
void isrDispatchTask(void *pvParameters)
|
||||
{
|
||||
t_IsrDispatchQueueItem dispatchItem;
|
||||
UINT32 channelcnt;
|
||||
|
||||
do /* As long as active */
|
||||
{
|
||||
/* If an Input Interrupt occures, enter if Statement */
|
||||
if (xQueueReceive(dispatchedIsrQueue, &dispatchItem, Int_queue_time))
|
||||
{
|
||||
/* Check for each single Channel, which one is active */
|
||||
for (channelcnt=0; channelcnt < maxDI_Channels; channelcnt++)
|
||||
{
|
||||
/* Go further if CallBack exists for corresponding Channel */
|
||||
if (inputPins[channelcnt].pCallbackList != NULL)
|
||||
{
|
||||
/* Check if this bit is active */
|
||||
int portIndex = (inputPins[channelcnt].portBaseAddr
|
||||
== PORT0_BASE_ADDR ? 0 : 1);
|
||||
|
||||
/* Check if Interrupt occured from a RISING EDGE */
|
||||
if (dispatchItem.riseInterrupts[ portIndex ]
|
||||
& inputPins[channelcnt].pinMask)
|
||||
{ /* Rising Edge Interrupt detected */
|
||||
if (dechatterTime[channelcnt] == 0)
|
||||
{ /* If dechatterTime is set to ZERO */
|
||||
/* call Callback directly */
|
||||
callAllCallbacks(
|
||||
inputPins[channelcnt].pCallbackList,
|
||||
RISING_EDGE);
|
||||
}
|
||||
else /* If there is a dechattering Time */
|
||||
{ /* Start dechattering the Input */
|
||||
startDechatterInput(channelcnt, RISING_EDGE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if Interrupt occured from a FALLING EDGE */
|
||||
if (dispatchItem.fallInterrupts[ portIndex ]
|
||||
& inputPins[channelcnt].pinMask)
|
||||
{ /* Falling Edge Interrupt detected */
|
||||
if (dechatterTime[channelcnt] == 0)
|
||||
{ /* If dechatterTime is set to ZERO */
|
||||
/* call Callback directly */
|
||||
callAllCallbacks(
|
||||
inputPins[channelcnt].pCallbackList,
|
||||
FALLING_EDGE);
|
||||
}
|
||||
else /* if there is a dechattering Time */
|
||||
{ /* Start dechattering the Input */
|
||||
startDechatterInput(channelcnt, FALLING_EDGE);
|
||||
}
|
||||
}
|
||||
} /* EndIf CallBack exists Check */
|
||||
} /* End of FOR Loop */
|
||||
} /* End Check for occuring Interrupt */
|
||||
|
||||
|
||||
endDechatterInput(); /* Call dechatter monitor Function */
|
||||
|
||||
} while (dioActive == TRUE);
|
||||
}
|
||||
|
||||
|
||||
void startDechatterInput(UINT8 ChannelNumber, t_di_mode Edge)
|
||||
{
|
||||
|
||||
/* If corresponding Channel is currently not monitored */
|
||||
if (dechatterLockFlag[ChannelNumber] == 0)
|
||||
{
|
||||
/* Set dechatter Timer */
|
||||
dechatterStopTime[ChannelNumber] = xTaskGetTickCount()
|
||||
+ dechatterTime[ChannelNumber];
|
||||
/* Handle type of detected Edge in channel Lock Flag */
|
||||
switch (Edge)
|
||||
{
|
||||
case RISING_EDGE:
|
||||
dechatterLockFlag[ChannelNumber] = 1;
|
||||
break;
|
||||
case FALLING_EDGE:
|
||||
dechatterLockFlag[ChannelNumber] = 2;
|
||||
break;
|
||||
// case BOTH_EDGES:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If come here, an already monitored Channel causes a new Interrupt
|
||||
* (which means, within the Timer a new Edge occured)
|
||||
* This is a chatter!
|
||||
* Reload the Timer!
|
||||
*/
|
||||
else
|
||||
{
|
||||
dechatterStopTime[ChannelNumber] = xTaskGetTickCount()
|
||||
+ dechatterTime[ChannelNumber];
|
||||
}
|
||||
|
||||
}
|
||||
void endDechatterInput(void)
|
||||
{
|
||||
UINT32 channelcnt;
|
||||
|
||||
/* Check every single Channel */
|
||||
for (channelcnt = 0; channelcnt < maxDI_Channels; channelcnt++)
|
||||
{
|
||||
/* If Timeout for corresponding channel occured */
|
||||
if (hasTimeoutPast( dechatterStopTime[channelcnt]) )
|
||||
{
|
||||
/* Switch corresponding to the former detected Edge */
|
||||
switch (dechatterLockFlag[channelcnt])
|
||||
{
|
||||
case 1: /* a Rising Edge was dechattered */
|
||||
/* Is Input still High? If Yes, channel is dechattered */
|
||||
if (dioRead(0, channelcnt) == TRUE)
|
||||
{ /* Call Callback Functions */
|
||||
callAllCallbacks(inputPins[channelcnt].pCallbackList,
|
||||
RISING_EDGE);
|
||||
}
|
||||
dechatterLockFlag[channelcnt] = 0; /* release Lock Flag */
|
||||
break;
|
||||
|
||||
case 2: /* a Falling Edge was dechattered */
|
||||
/* Is Input still Low? If Yes, channel is dechattered */
|
||||
if (dioRead(0, channelcnt) == FALSE)
|
||||
{ /* Call Callback Functions */
|
||||
callAllCallbacks(inputPins[channelcnt].pCallbackList,
|
||||
FALLING_EDGE);
|
||||
}
|
||||
dechatterLockFlag[channelcnt] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void callAllCallbacks(t_callbackListItem *pCallbackList, t_di_mode detectedEdge)
|
||||
{
|
||||
while (pCallbackList != NULL)
|
||||
{
|
||||
if ( (pCallbackList->mode == detectedEdge) || (pCallbackList->mode
|
||||
== BOTH_EDGES))
|
||||
{
|
||||
// Call the callback
|
||||
pCallbackList->pCallback();
|
||||
}
|
||||
|
||||
// Check next item
|
||||
pCallbackList = pCallbackList->next;
|
||||
}
|
||||
}
|
||||
|
||||
void dioSetDechatterTime(UINT8 channel, UINT32 time)
|
||||
{
|
||||
dechatterTime[channel] = time;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN hasTimeoutPast( UINT32 endTick )
|
||||
{
|
||||
UINT32 nowTick = xTaskGetTickCount();
|
||||
|
||||
if (nowTick >= endTick)
|
||||
{
|
||||
if ((nowTick - endTick) > 0x0000FFFF)
|
||||
{
|
||||
// the endTick has gone through 0 point, nowTick is at end of range
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// nowTick passed endTick.
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((endTick - nowTick) > 0x0000FFFF)
|
||||
{
|
||||
|
||||
// the endTick was at end of range, nowTick has gone through 0 point
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// nowTick still has to pass endTick
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user