/** * * Set the reset value for the specified timer counter. This is the value * that is loaded into the timer counter when it is reset. This value is also * loaded when the timer counter is started. * * @param InstancePtr is a pointer to the XIOModule instance. * @param TimerNumber is the timer counter of the device to operate on. * Each device may contain multiple timer counters. The timer * number is a zero based number with a range of * 0 to (XTC_DEVICE_TIMER_COUNT - 1). * @param ResetValue contains the value to be used to reset the timer * counter. * * @return None. * * @note None. * ******************************************************************************/ void XIOModule_SetResetValue(XIOModule * InstancePtr, u8 TimerNumber, u32 ResetValue) { u32 TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT; XASSERT_VOID(InstancePtr != NULL); XASSERT_VOID(TimerNumber < XTC_DEVICE_TIMER_COUNT); XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); XIOModule_WriteReg(InstancePtr->BaseAddress, TimerOffset + XTC_TLR_OFFSET, ResetValue); InstancePtr->CurrentTLR[TimerNumber] = ResetValue; }
/** * Set output discrete(s) to logic 1 for the specified GPO channel. * * @param InstancePtr is a pointer to an XIOModule instance to be * worked on. * @param Channel contains the channel of the GPIO (1, 2, 3 or 4) to * operate on. * @param Mask is the set of bits that will be set to 1 in the discrete * data register. All other bits in the data register are * unaffected. * * @return None. * *****************************************************************************/ void XIOModule_DiscreteSet(XIOModule * InstancePtr, unsigned Channel, u32 Mask) { u32 Current; unsigned DataOffset; XASSERT_VOID(InstancePtr != NULL); XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); XASSERT_VOID((Channel >= 1) && (Channel <= XGPO_DEVICE_COUNT)); /* * Calculate the offset to the data register of the GPO */ DataOffset = ((Channel - 1) * XGPO_CHAN_OFFSET) + XGPO_DATA_OFFSET; /* * Read the contents from the instance, merge in Mask and write * back results */ Current = InstancePtr->GpoValue[Channel - 1]; Current |= Mask; XIOModule_WriteReg(InstancePtr->BaseAddress, DataOffset, Current); InstancePtr->GpoValue[Channel - 1] = Current; }
/** * * Starts the specified timer counter of the device such that it starts running. * The timer counter is reset before it is started and the reset value is * loaded into the timer counter. * * If interrupt mode is specified in the options, it is necessary for the caller * to connect the interrupt handler of the timer to the interrupt source, * typically an interrupt controller, and enable the interrupt within the * interrupt controller. * * @param InstancePtr is a pointer to the XIOModule instance. * @param TimerNumber is the timer of the device to operate on. * Each device may contain multiple timers. The timer * number is a zero based number with a range of * 0 to (XTC_DEVICE_TIMER_COUNT - 1). * * @return None. * * @note None. * ******************************************************************************/ void XIOModule_Timer_Start(XIOModule * InstancePtr, u8 TimerNumber) { u32 NewControlStatus; u32 TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT; XASSERT_VOID(InstancePtr != NULL); XASSERT_VOID(TimerNumber < XTC_DEVICE_TIMER_COUNT); XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Set the new value the current contents such that only the necessary * bits of the register are modified in the following operations */ NewControlStatus = InstancePtr->CurrentTCSR[TimerNumber] | XTC_CSR_ENABLE_TMR_MASK; /* * Remove the reset condition such that the timer starts * running with the value loaded from the compare register */ XIOModule_WriteReg(InstancePtr->BaseAddress, TimerOffset + XTC_TCSR_OFFSET, NewControlStatus); InstancePtr->CurrentTCSR[TimerNumber] = NewControlStatus; }
/** * * Initializes a specific timer instance/driver. Initialize fields of the * XIOModule structure, then reset the timer * * @param InstancePtr is a pointer to the XIOModule instance. * @param DeviceId is the unique id of the device controlled by this * XIOModule component. Passing in a device id associates the * generic XIOModule component to a specific device, as chosen by * the caller or application developer. * * @return * - XST_SUCCESS if initialization was successful * - XST_DEVICE_IS_STARTED if the device has already been started * - XST_DEVICE_NOT_FOUND if the device doesn't exist * * @note None. * ******************************************************************************/ int XIOModule_Timer_Initialize(XIOModule * InstancePtr, u16 DeviceId) { XIOModule_Config *IOModuleConfigPtr; int TimerNumber; u32 TimerOffset; u32 StatusReg; XASSERT_NONVOID(InstancePtr != NULL); /* * Lookup the device configuration in the temporary CROM table. Use this * configuration info down below when initializing this component. */ IOModuleConfigPtr = XIOModule_LookupConfig(DeviceId); if (IOModuleConfigPtr == (XIOModule_Config *) NULL) { return XST_DEVICE_NOT_FOUND; } /* * Check each of the timers of the device, if any are already * running, then the device should not be initialized. This allows the * user to stop the device and reinitialize, but prevents a user from * inadvertently initializing. */ for (TimerNumber = 0; TimerNumber < XTC_DEVICE_TIMER_COUNT; TimerNumber++) { TimerOffset = TimerNumber << XTC_TIMER_COUNTER_SHIFT; /* * Use the current register contents and check if the timer * counter is started and running, note that this is not * destructive if the timer counter is already started */ StatusReg = InstancePtr->CurrentTCSR[TimerNumber]; if (StatusReg & XTC_CSR_ENABLE_TMR_MASK) { continue; } /* * Set some default values, including setting the callback * handlers to stubs. */ InstancePtr->BaseAddress = IOModuleConfigPtr->BaseAddress; InstancePtr->Handler = NULL; InstancePtr->CallBackRef = NULL; /* * Clear the statistics for this driver */ InstancePtr->Timer_Stats[TimerNumber].Interrupts = 0; /* Initialize the registers of each timer in the device */ /* * Set the Load register to 0 */ XIOModule_WriteReg(InstancePtr->BaseAddress, TimerOffset + XTC_TLR_OFFSET, 0); InstancePtr->CurrentTLR[TimerNumber] = 0; /* * Set the control/status register to complete initialization * by clearing the reset bit which was just set */ XIOModule_WriteReg(InstancePtr->BaseAddress, TimerOffset + XTC_TCSR_OFFSET, 0); InstancePtr->CurrentTCSR[TimerNumber] = 0; } /* * Indicate the instance is ready to use, successfully initialized */ InstancePtr->IsReady = XCOMPONENT_IS_READY; return XST_SUCCESS; }
/** * * This function sends a buffer that has been previously specified by setting * up the instance variables of the instance. This function is designed to be * an internal function for the XIOModule component such that it may be called * from a shell function that sets up the buffer or from an interrupt handler. * * This function sends the specified buffer of data to the UART in either * polled or interrupt driven modes. This function is non-blocking such that * it will return before the data has been sent by the UART. * * In a polled mode, this function will only send as much data as the UART can * buffer in the transmitter. The application may need to call it repeatedly to * send a buffer. * * In interrupt mode, this function will start sending the specified buffer and * then the interrupt handler of the driver will continue until the buffer * has been sent. A callback function, as specified by the application, will * be called to indicate the completion of sending the buffer. * * @param InstancePtr is a pointer to the XIOModule instance. * * @return NumBytes is the number of bytes actually sent (put into the * UART transmitter and/or FIFO). * * @note None. * *****************************************************************************/ unsigned int XIOModule_SendBuffer(XIOModule *InstancePtr) { unsigned int SentCount = 0; u8 StatusRegister; u8 IntrEnableStatus; /* * Read the status register to determine if the transmitter is full */ StatusRegister = XIOModule_GetStatusReg(InstancePtr->BaseAddress); /* * Enter a critical region by disabling all the UART interrupts to allow * this call to stop a previous operation that may be interrupt driven */ XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, StatusRegister & 0xFFFFFFF8); /* * Save the status register contents to restore the interrupt enable * register to it's previous value when that the critical region is * exited */ IntrEnableStatus = StatusRegister; /* * Fill the FIFO from the the buffer that was specified */ while (((StatusRegister & XUL_SR_TX_FIFO_FULL) == 0) && (SentCount < InstancePtr->SendBuffer.RemainingBytes)) { XIOModule_WriteReg(InstancePtr->BaseAddress, XUL_TX_OFFSET, InstancePtr->SendBuffer.NextBytePtr[ SentCount]); SentCount++; StatusRegister = XIOModule_GetStatusReg(InstancePtr->BaseAddress); } /* * Update the buffer to reflect the bytes that were sent from it */ InstancePtr->SendBuffer.NextBytePtr += SentCount; InstancePtr->SendBuffer.RemainingBytes -= SentCount; /* * Increment associated counters */ InstancePtr->Uart_Stats.CharactersTransmitted += SentCount; /* * Restore the interrupt enable register to it's previous value such * that the critical region is exited */ XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, (InstancePtr->CurrentIER & 0xFFFFFFF8) | (IntrEnableStatus & 0x7)); /* * Return the number of bytes that were sent, althought they really were * only put into the FIFO, not completely sent yet */ return SentCount; }