Beispiel #1
0
static void vSerialISR( XUartLite *pxUART )
{
unsigned portLONG ulISRStatus;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, lDidSomething;
portCHAR cChar;

	/* Just to remove compiler warning. */
	( void ) pxUART;

	do
	{
		lDidSomething = pdFALSE;

		ulISRStatus = XIo_In32( XPAR_RS232_UART_BASEADDR + XUL_STATUS_REG_OFFSET );

		if( ( ulISRStatus & XUL_SR_RX_FIFO_VALID_DATA ) != 0 )
		{
			/* A character is available - place it in the queue of received
			characters.  This might wake a task that was blocked waiting for 
			data. */
			cChar = ( portCHAR ) XIo_In32( XPAR_RS232_UART_BASEADDR + XUL_RX_FIFO_OFFSET );
			xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
			lDidSomething = pdTRUE;
		}
		
		if( ( ulISRStatus & XUL_SR_TX_FIFO_EMPTY ) != 0 )
		{
			/* There is space in the FIFO - if there are any characters queue for
			transmission they can be sent to the UART now.  This might unblock a
			task that was waiting for space to become available on the Tx queue. */
			if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
			{
				XIo_Out32( XPAR_RS232_UART_BASEADDR + XUL_TX_FIFO_OFFSET, cChar );
				lDidSomething = pdTRUE;
			}			
		}
	} while( lDidSomething == pdTRUE );

	/* If we woke any tasks we may require a context switch. */
	if( xHigherPriorityTaskWoken )
	{
		portYIELD_FROM_ISR();
	}
}
Beispiel #2
0
/**
*
* This function sets the control register of the specified DMA channel.
*
* @param
*
* InstancePtr contains a pointer to the DMA channel to operate on.
*
* @param
*
* Control contains the value to be written to the control register of the DMA
* channel. One or more of the following values may be contained the register.
* Each of the values are unique bit masks such that they may be ORed together
* to enable multiple bits or inverted and ANDed to disable multiple bits.
* - XDC_DMACR_SOURCE_INCR_MASK  Increment the source address
* - XDC_DMACR_DEST_INCR_MASK    Increment the destination address
* - XDC_DMACR_SOURCE_LOCAL_MASK Local source address
* - XDC_DMACR_DEST_LOCAL_MASK   Local destination address
* - XDC_DMACR_SG_ENABLE_MASK    Scatter gather enable
* - XDC_DMACR_GEN_BD_INTR_MASK  Individual buffer descriptor interrupt
* - XDC_DMACR_LAST_BD_MASK      Last buffer descriptor in a packet
*
* @return
*
* None.
*
* @note
*
* None.
*
******************************************************************************/
void XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control)
{
	u32 Register;
	/* assert to verify input arguments except the control which can't be
	 * asserted since all values are valid
	 */
	XASSERT_VOID(InstancePtr != NULL);
	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/*
	 * set the DMA control register to the specified value, not altering the
	 * other fields in the register
	 */

	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
	Register &= XDC_DMACR_TX_CS_INIT_MASK;
	XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET,
		  Register | Control);
}
Beispiel #3
0
int main () {
	unsigned int DataRead;
	unsigned int OldData;
	init_platform();
	// Clear the screen
	xil_printf("%c[2J",27);
	OldData = (unsigned int) 0xffffffff;
	while(1){
	// Read the state of the DIP switches
		DataRead = XIo_In32(XPAR_MY_PERIPHERAL_0_BASEADDR);
	// Send the data to the UART if the settings change
		if(DataRead != OldData){
			xil_printf("DIP Switch settings: 0x%2X\r\n", DataRead);
			// Set the LED outputs to the DIP switch values
			XIo_Out32(XPAR_MY_PERIPHERAL_0_BASEADDR, DataRead);
			// Record the DIP switch settings
			OldData = DataRead;
		}
	}
}
/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_SetPktThreshold
*
* DESCRIPTION:
*
* This function sets the value of the packet count threshold register of the
* DMA channel.	It reflects the number of packets that must be sent or
* received before generating an interrupt.  This value helps implement
* a concept called "interrupt coalescing", which is used to reduce the number
* of interrupts from devices with high data rates.
*
* ARGUMENTS:
*
* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
* channel should be configured to use scatter gather in order for this function
* to be called.
*
* Threshold is the value that is written to the threshold register of the
* DMA channel.
*
* RETURN VALUE:
*
* A status containing XST_SUCCESS if the packet count threshold was
* successfully set.
*
* NOTES:
*
* The packet threshold could be set to larger than the number of descriptors
* allocated to the DMA channel. In this case, the wait bound will take over
* and always indicate data arrival. There was a check in this function that
* returned an error if the treshold was larger than the number of descriptors,
* but that was removed because users would then have to set the threshold
* only after they set descriptor space, which is an order dependency that
* caused confustion.
*
******************************************************************************/
XStatus
XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold)
{
	/* assert to verify input arguments, don't assert the threshold since
	 * it's range is unknown
	 */
	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/* set the packet count threshold in the register such that an interrupt
	 * may be generated, if enabled, when the packet count threshold is
	 * reached or exceeded
	 */
	XIo_Out32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET,
		  (u32) Threshold);

	/* indicate the packet count threshold was successfully set */

	return XST_SUCCESS;
}
Beispiel #5
0
co_error co_register_write(co_register reg, const void *buffer, unsigned int size)
{
  int data;

  switch (size) {
  case 1:
    data=*(char *)buffer;
    break;
  case 2:
    data=*(short *)buffer;
    break;
  default: 
    data=*(int *)buffer;
    break;
  }

  XIo_Out32(reg->io_addr,data);

  return(co_err_none);
}
Beispiel #6
0
static int __exit labx_dma_pdev_remove(struct platform_device *pdev)
{
	int i;
	struct labx_dma_pdev *dma_pdev = (struct labx_dma_pdev*)platform_get_drvdata(pdev);

	/* Make sure the DMA unit is no longer running */
	XIo_Out32(DMA_REGISTER_ADDRESS(&dma_pdev->dma, DMA_CONTROL_REG), DMA_DISABLE);

	misc_deregister(&dma_pdev->miscdev);

	for (i=0; i<MAX_DMA_DEVICES; i++)
	{
		if (dma_pdev == devices[i])
		{
			devices[i] = NULL;
			break;
		}
	}
	return 0;
}
Beispiel #7
0
static int32_t set_output_enabled(struct audio_packetizer *packetizer,
                                  uint32_t whichOutput, 
                                  uint32_t enable) {
  uint32_t outputMask;
  uint32_t controlRegister;

  /* Sanity-check the whichOutput parameter */
  if(whichOutput >= packetizer->capabilities.numOutputs) {
    return(-EINVAL);
  }

  /* Enable or disable the requested output in the control register */
  outputMask = (OUTPUT_A_ENABLE << whichOutput);
  controlRegister = XIo_In32(REGISTER_ADDRESS(packetizer, CONTROL_REG));
  if(enable == PACKETIZER_OUTPUT_ENABLE) {
    controlRegister |= outputMask;
  } else controlRegister &= ~outputMask;
  XIo_Out32(REGISTER_ADDRESS(packetizer, CONTROL_REG), controlRegister);

  return 0;
}
Beispiel #8
0
/**
*
* This function resets the FIFOs, both transmit and receive, of the UART such
* that they are emptied.  Since the UART does not have any way to disable it
* from receiving data, it may be necessary for the application to reset the
* FIFOs to get rid of any unwanted data.
*
* @param    InstancePtr is a pointer to the XUartLite instance to be worked on.
*
* @return
*
* None.
*
* @note
*
* None.
*
*****************************************************************************/
void
XUartLite_ResetFifos(XUartLite * InstancePtr)
{
	u32 ControlRegister;

	XASSERT_VOID(InstancePtr != NULL);
	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/* Read the control register 1st such that the next write to the control
	 * register won't destroy the state of the interrupt enable bit
	 */
	ControlRegister = XIo_In32(InstancePtr->RegBaseAddress +
				   XUL_CONTROL_REG_OFFSET);

	/* Write to the control register to reset both FIFOs, these bits are
	 * self-clearing such that there's no need to clear them
	 */
	XIo_Out32(InstancePtr->RegBaseAddress + XUL_CONTROL_REG_OFFSET,
		  ControlRegister | XUL_CR_FIFO_TX_RESET |
		  XUL_CR_FIFO_RX_RESET);
}
/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_DecrementPktCount
*
* DESCRIPTION:
*
* This function decrements the value of the unserviced packet count register.
* This informs the hardware that the software has processed a packet.  The
* unserviced packet count register may only be decremented by one in the
* hardware.
*
* ARGUMENTS:
*
* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
* channel should be configured to use scatter gather in order for this function
* to be called.
*
* RETURN VALUE:
*
* None.
*
* NOTES:
*
* None.
*
******************************************************************************/
void
XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr)
{
	u32 Register;

	/* assert to verify input arguments */

	XASSERT_VOID(InstancePtr != NULL);
	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/* if the unserviced packet count register can be decremented (rather
	 * than rolling over) decrement it by writing a 1 to the register,
	 * this is the only valid write to the register as it serves as an
	 * acknowledge that a packet was handled by the software
	 */
	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
	if (Register > 0) {
		XIo_Out32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET,
			  1UL);
	}
}
Beispiel #10
0
void fftSample(Xuint32 bufaddress, int n, int inverse) {

	//int test = 12345;
	//Xil_Out32(0x0000ffff,test);

	Xuint32 buf[n];
	Xuint32 out[n];

	int i = 0;
	int count = 0;
	while (i < n) {

		XIo_Out32(buf+count*4,(XIo_In32 (bufaddress + i) & AC97_DATA_MASK)<<11); /*get sample*/
		//XIo_Out32(out+count*4,(XIo_In32 (bufaddress + i) & AC97_DATA_MASK)<<11); /*get sample*/
		i = i + 8;
		count++;
	}

	// _fftSample(buf, out, n, 1,inverse);
     fftAddress = (Xuint32)buf;
}
Beispiel #11
0
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime )
{
portBASE_TYPE xReturn = pdTRUE;

	/* Just to remove compiler warning. */
	( void ) pxPort;

	portENTER_CRITICAL();
	{
		/* If the UART FIFO is full we can block posting the new data on the
		Tx queue. */
		if( XUartLite_mIsTransmitFull( XPAR_RS232_UART_1_BASEADDR ) )
		{
			if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
			{
				xReturn = pdFAIL;
			}
		}
		/* Otherwise, if there is data already in the queue we should add the
		new data to the back of the queue to ensure the sequencing is 
		maintained. */
		else if( uxQueueMessagesWaiting( xCharsForTx ) )
		{
			if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )
			{
				xReturn = pdFAIL;
			}			
		}
		/* If the UART FIFO is not full and there is no data already in the
		queue we can write directly to the FIFO without disrupting the 
		sequence. */
		else
		{
			XIo_Out32( XPAR_RS232_UART_1_BASEADDR + XUL_TX_FIFO_OFFSET, cOutChar );
		}
	}
	portEXIT_CRITICAL();

	return xReturn;
}
Beispiel #12
0
/* Interrupt service routine for the instance */
static irqreturn_t biamp_spi_mailbox_interrupt(int irq, void *dev_id) {
  struct spi_mailbox *mailbox = (struct spi_mailbox*) dev_id;
  uint32_t maskedFlags;
  uint32_t irqMask;

  /* Read the interrupt flags and immediately clear them */
  maskedFlags = XIo_In32(REGISTER_ADDRESS(mailbox, IRQ_FLAGS_REG));
  irqMask = XIo_In32(REGISTER_ADDRESS(mailbox, IRQ_MASK_REG));

  maskedFlags &= irqMask;
  XIo_Out32(REGISTER_ADDRESS(mailbox, IRQ_FLAGS_REG), maskedFlags);

  /* Detect the slave-to-host message wait_received IRQ */
  if((maskedFlags & IRQ_S2H_MSG_RX) != 0) {
    /* Set message ready flag before waking up thread */
    mailbox->messageReadyFlag = MESSAGE_READY;
    /* Wake up all threads waiting for a synchronization event */
    wake_up_interruptible(&(mailbox->messageReadQueue));
  }

  return(IRQ_HANDLED);
}
Beispiel #13
0
/**
*
* Set the Interframe Gap (IFG), which is the time the MAC delays between
* transmitting frames.  There are two parts required.  The total interframe gap
* is the total of the two parts.  The values provided for the Part1 and Part2
* parameters are multiplied by 4 to obtain the bit-time interval. The first
* part should be the first 2/3 of the total interframe gap. The MAC will reset
* the interframe gap timer if carrier sense becomes true during the period
* defined by interframe gap Part1. Part1 may be shorter than 2/3 the total and
* can be as small as zero. The second part should be the last 1/3 of the total
* interframe gap, but can be as large as the total interframe gap. The MAC
* will not reset the interframe gap timer if carrier sense becomes true during
* the period defined by interframe gap Part2.
*
* The device must be stopped before setting the interframe gap.
*
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
* @param Part1 is the interframe gap part 1 (which will be multiplied by 4 to
*        get the bit-time interval).
* @param Part2 is the interframe gap part 2 (which will be multiplied by 4 to
*        get the bit-time interval).
*
* @return
*
* - XST_SUCCESS if the interframe gap was set successfully
* - XST_DEVICE_IS_STARTED if the device has not been stopped
*
* @note
*
* None.
*
******************************************************************************/
XStatus XEmac_SetInterframeGap(XEmac * InstancePtr, u8 Part1, u8 Part2)
{
    u32 Ifg;

    XASSERT_NONVOID(InstancePtr != NULL);
    XASSERT_NONVOID(Part1 <= XEM_IFGP_PART1_MAX);
    XASSERT_NONVOID(Part2 <= XEM_IFGP_PART2_MAX);
    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

    /*
     * Be sure device has been stopped
     */
    if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
        return XST_DEVICE_IS_STARTED;
    }

    Ifg = Part1 << XEM_IFGP_PART1_SHIFT;
    Ifg |= (Part2 << XEM_IFGP_PART2_SHIFT);
    XIo_Out32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET, Ifg);

    return XST_SUCCESS;
}
/**
*
* Initialize a XUartLite instance.  The receive and transmit FIFOs of the
* UART are not flushed, so the user may want to flush them. The hardware
* device does not have any way to disable the receiver such that any valid
* data may be present in the receive FIFO.  This function disables the UART
* interrupt. The baudrate and format of the data are fixed in the hardware
* at hardware build time.
*
* @param InstancePtr is a pointer to the XUartLite instance to be worked on.
* @param Config is a reference to a structure containing information about
*        a specific UART Lite device. This function initializes an
*        InstancePtr object for a specific device specified by the contents
*        of Config. This function can initialize multiple instance objects
*        with the use of multiple calls giving different Config information
*        on each call.
* @param EffectiveAddr is the device base address in the virtual memory address
*        space. The caller is responsible for keeping the address mapping
*        from EffectiveAddr to the device physical base address unchanged
*        once this function is invoked. Unexpected errors may occur if the
*        address mapping changes after this function is called. If address
*        translation is not used, use Config->BaseAddress for this parameters,
*        passing the physical address instead.
*
* @return
*
* - XST_SUCCESS if everything starts up as expected.
*
* @note
*
* The Config pointer argument is not used by this function, but is provided
* to keep the function signature consistent with other drivers.
*
*****************************************************************************/
XStatus XUartLite_CfgInitialize(XUartLite *InstancePtr, XUartLite_Config *Config,
                                Xuint32 EffectiveAddr)
{
    /*
     * Assert validates the input arguments
     */
    XASSERT_NONVOID(InstancePtr != XNULL);

    /*
     * Set some default values, including setting the callback
     * handlers to stubs.
     */

    InstancePtr->SendBuffer.NextBytePtr = XNULL;
    InstancePtr->SendBuffer.RemainingBytes = 0;
    InstancePtr->SendBuffer.RequestedBytes = 0;

    InstancePtr->ReceiveBuffer.NextBytePtr = XNULL;
    InstancePtr->ReceiveBuffer.RemainingBytes = 0;
    InstancePtr->ReceiveBuffer.RequestedBytes = 0;

    InstancePtr->IsReady = XCOMPONENT_IS_READY;
    InstancePtr->RegBaseAddress = EffectiveAddr;
    InstancePtr->RecvHandler = StubHandler;
    InstancePtr->SendHandler = StubHandler;

    /* Write to the control register to disable the interrupts, don't
     * reset the FIFOs are the user may want the data that's present
     */
    XIo_Out32(InstancePtr->RegBaseAddress + XUL_CONTROL_REG_OFFSET, 0);

    /*
     * Clear the statistics for this driver
     */
    XUartLite_mClearStats(InstancePtr);

    return XST_SUCCESS;
}
Beispiel #15
0
/**
*
* Restart the watchdog timer. An application needs to call this function
* periodically to keep the timer from asserting the reset output.
*
* @param	InstancePtr is a pointer to the XWdtTb instance to be worked on.
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void XWdtTb_RestartWdt(XWdtTb * InstancePtr)
{
	u32 ControlStatusRegister0;

	XASSERT_VOID(InstancePtr != NULL);
	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/*
	 * Read the current contents of TCSR0 so that subsequent writes won't
	 * destroy any other bits
	 */
	ControlStatusRegister0 = XIo_In32(InstancePtr->RegBaseAddress +
					  XWT_TWCSR0_OFFSET);
	/*
	 * Clear the bit that indicates the reason for the last
	 * system reset, WRS and the WDS bit, if set, by writing
	 * 1's to TCSR0
	 */
	ControlStatusRegister0 |= (XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK);

	XIo_Out32(InstancePtr->RegBaseAddress + XWT_TWCSR0_OFFSET,
		  ControlStatusRegister0);
}
Beispiel #16
0
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
unsigned long ulControlReg, ulMask;

	/* NOTE: The baud rate used by this driver is determined by the hardware
	parameterization of the UART Lite peripheral, and the baud value passed to
	this function has no effect. */

	/* Create the queues used to hold Rx and Tx characters. */
	xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
	xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed char ) );

	if( ( xRxedChars ) && ( xCharsForTx ) )
	{
		/* Disable the interrupt. */
		XUartLite_mDisableIntr( XPAR_RS232_UART_BASEADDR );
		
		/* Flush the fifos. */
		ulControlReg = XIo_In32( XPAR_RS232_UART_BASEADDR + XUL_STATUS_REG_OFFSET );
		XIo_Out32( XPAR_RS232_UART_BASEADDR + XUL_CONTROL_REG_OFFSET, ulControlReg | XUL_CR_FIFO_TX_RESET | XUL_CR_FIFO_RX_RESET );

		/* Enable the interrupt again.  The interrupt controller has not yet been 
		initialised so there is no chance of receiving an interrupt until the 
		scheduler has been started. */
		XUartLite_mEnableIntr( XPAR_RS232_UART_BASEADDR );

		/* Enable the interrupt in the interrupt controller while maintaining 
		all the other bit settings. */
		ulMask = XIntc_In32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ) );
		ulMask |= XPAR_RS232_UART_INTERRUPT_MASK;
		XIntc_Out32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ), ( ulMask ) );
		XIntc_mAckIntr( XPAR_INTC_SINGLE_BASEADDR, 2 );
	}
	
	return ( xComPortHandle ) 0;
}
Beispiel #17
0
void USB_EPP_Reg_Write (Xuint32 USB_EPP_BASEADDR, Xuint32 ADDRESS, Xuint32 DATA){
	XIo_Out32(USB_EPP_BASEADDR + USB_EPP_ADDRESS_REG_OFFSET, ADDRESS);
	XIo_Out32(USB_EPP_BASEADDR + USB_EPP_DATA_REG_OFFSET, DATA);
}
Beispiel #18
0
int main()
{
	init_platform();
	init_ddr(); // uncomment if using SysAlloc
	print("Hello World\n\r");

	int log2_tree_size;

	/*
	// Code for measuring the latency of RNG
	int k;
	for(k = 0; k <10; k++){
		XIo_Out32(COUNTER_BASE + 4 * k, START);
		RandGen(10);
		XIo_Out32(COUNTER_BASE + 4 * k, STOP);
		putnum(XIo_In32(COUNTER_BASE + 4 * k));
		XIo_Out32(COUNTER_BASE + 4 * k,RESET);
		print("\n");
	}	
	*/

	int *root = NULL;
	int i,j;
	//for(i = 0; i < 21; i++){
		log2_tree_size = 6;
		root = NULL;
		xor_rng_init();

		XIo_Out32(COUNTER_BASE + 4 * 1, START);
		root = PM_1_INSERTION(root, log2_tree_size);
		XIo_Out32(COUNTER_BASE + 4 * 1, STOP);

		XIo_Out32(COUNTER_BASE + 4 * 2, START);
		root = PM_2_CHECK_INSERTION(root, log2_tree_size);
		XIo_Out32(COUNTER_BASE + 4 * 2, STOP);

		XIo_Out32(COUNTER_BASE + 4 * 3, START);
		root = PM_3_UPDATE(root, log2_tree_size);
		XIo_Out32(COUNTER_BASE + 4 * 3, STOP);
		XIo_Out32(COUNTER_BASE + 4 * 4, START);
		root = PM_4_DELETION(root);
		XIo_Out32(COUNTER_BASE + 4 * 4, STOP);

		// read counter result back
		for(j = 1; j<5; j++){
			if(i > 17){
				putnum(XIo_In32(COUNTER_BASE + 4 * (j + 8) ));
			}
			putnum(XIo_In32(COUNTER_BASE + 4 * j));
			print(" ");
			// reset counter
			XIo_Out32(COUNTER_BASE + 4 * j, RESET);
		}
		print("\n");
	//}

	print("\n all done\n");

	cleanup_platform();
	return 0;
}
Beispiel #19
0
/* Function containing the "meat" of the probe mechanism - this is used by
 * the OpenFirmware probe as well as the standard platform device mechanism.
 * @param name - Name of the instance
 * @param pdev - Platform device structure
 * @param addressRange - Resource describing the hardware's I/O range
 * @param irq          - Resource describing the hardware's IRQ
 */
static int mailbox_probe(const char *name, 
                             struct platform_device *pdev,
                             struct resource *addressRange,
                             struct resource *irq) {
  struct labx_mailbox *mailbox;
  int returnValue;
  int i;

  /* Create and populate a device structure */
  mailbox = (struct labx_mailbox*) kmalloc(sizeof(struct labx_mailbox), GFP_KERNEL);
  if(!mailbox) return(-ENOMEM);

  /* Request and map the device's I/O memory region into uncacheable space */
  mailbox->physicalAddress = addressRange->start;
  mailbox->addressRangeSize = ((addressRange->end - addressRange->start) + 1);
  snprintf(mailbox->name, NAME_MAX_SIZE, "%s", name);
  mailbox->name[NAME_MAX_SIZE - 1] = '\0';
  if(request_mem_region(mailbox->physicalAddress, mailbox->addressRangeSize,
                        mailbox->name) == NULL) {
    returnValue = -ENOMEM;
    goto free;
  }

  mailbox->virtualAddress = 
    (void*) ioremap_nocache(mailbox->physicalAddress, mailbox->addressRangeSize);
  if(!mailbox->virtualAddress) {
    returnValue = -ENOMEM;
    goto release;
  }

  /* Ensure that the mailbox and its interrupts are disabled */
  disable_mailbox(mailbox);
  XIo_Out32(REGISTER_ADDRESS(mailbox, SUPRV_IRQ_MASK_REG), NO_IRQS);

  /* Clear the message ready flag for the first time */
  mailbox->messageReadyFlag = MESSAGE_NOT_READY;
  
  /* Retain the IRQ and register our handler, if an IRQ resource was supplied. */
  if(irq != NULL) {
    mailbox->irq = irq->start;
    returnValue = request_irq(mailbox->irq, &mailbox_interrupt, IRQF_DISABLED,
                              mailbox->name, mailbox);
    if (returnValue) {
      printk(KERN_ERR "%s : Could not allocate Mailbox interrupt (%d).\n",
             mailbox->name, mailbox->irq);
      goto unmap;
    }
  } else mailbox->irq = NO_IRQ_SUPPLIED;
  
  /* Announce the device */
  printk(KERN_INFO "%s: Found mailbox at 0x%08X, ",
         mailbox->name, (uint32_t)mailbox->physicalAddress);
  if(mailbox->irq == NO_IRQ_SUPPLIED) {
    printk("polled interlocks\n");
  } else {
    printk("IRQ %d\n", mailbox->irq);
  }

  /* Initialize other resources */
  spin_lock_init(&mailbox->mutex);
  mailbox->opened = true;

  /* Provide navigation between the device structures */
  platform_set_drvdata(pdev, mailbox);
  mailbox->pdev = pdev;

  /* Reset the state of the mailbox */
  reset_mailbox(mailbox);

  /* Initialize the waitqueue used for synchronized writes */
  init_waitqueue_head(&(mailbox->messageReadQueue));

  /* Initialize the netlink state and start the thread */
  mailbox->netlinkSequence = 0;
  mailbox->netlinkTask = kthread_run(netlink_thread, (void*)mailbox, "%s:netlink", mailbox->name);
  if (IS_ERR(mailbox->netlinkTask)) {
    printk(KERN_ERR "Mailbox netlink task creation failed.\n");
    returnValue = -EIO;
    goto free;
  }
  
  /* Now that the device is configured, enable interrupts if they are to be used */
  if(mailbox->irq != NO_IRQ_SUPPLIED) {
    XIo_Out32(REGISTER_ADDRESS(mailbox, SUPRV_IRQ_MASK_REG), ALL_IRQS);
    XIo_Out32(REGISTER_ADDRESS(mailbox, SUPRV_IRQ_FLAGS_REG), ALL_IRQS);
  }

  // Add the mailbox instance to the list of current devices
  for(i=0;i<MAX_MAILBOX_DEVICES;i++) {
    if(NULL == labx_mailboxes[i]) {
      labx_mailboxes[i] = mailbox;
      printk("Adding mailbox: %s\n", labx_mailboxes[i]->name);
      break;
    }
  }

  DBG("Mailbox initialized\n");

  /* Return success */
  return(0);

 unmap:
  iounmap(mailbox->virtualAddress);
 release:
  release_mem_region(mailbox->physicalAddress, mailbox->addressRangeSize);
 free:
  kfree(mailbox);
  return(returnValue);
}
Beispiel #20
0
/* I/O control operations for the driver */
static int aes3_rx_ioctl(struct inode *inode, 
                                   struct file *filp,
                                   unsigned int command, 
                                   unsigned long arg) {
 int returnValue = 0;
 uint32_t Value;
 struct aes3_rx *rx = (struct aes3_rx*)filp->private_data;

 switch(command) {
     
 case IOC_READ_RX_STREAM_STATUS:
   {
     /* Get the rx stream status, then copy into the userspace pointer */
     Value = XIo_In32(REGISTER_ADDRESS(rx, AES_RX_STREAM_STATUS_REG));
     if(copy_to_user((void __user*)arg, &Value, 
                     sizeof(uint32_t)) != 0) {
       return(-EFAULT);
     }
   }
   break;

 case IOC_READ_TX_STREAM_STATUS:
   {
     /* Get the tx stream status, then copy into the userspace pointer */
     Value = XIo_In32(REGISTER_ADDRESS(rx, AES_TX_STREAM_STATUS_REG));
     if(copy_to_user((void __user*)arg, &Value, 
                     sizeof(uint32_t)) != 0) {
       return(-EFAULT);
     }
   }
   break;  

 case IOC_CONFIG_AES: 
  {
   /* Write the AES configuration register. */
   if(copy_from_user(&Value, (void __user*)arg, sizeof(Value)) != 0) {
        return(-EFAULT);
   }
   XIo_Out32(REGISTER_ADDRESS(rx, AES_CONTROL_REG), Value);
  }
   break;
   
 case IOC_CONFIG_RX_PCM_MODE:
  {
   /* Write the RX PCM configuration register. */
   if(copy_from_user(&Value, (void __user*)arg, sizeof(Value)) != 0) {
        return(-EFAULT);
   }
   XIo_Out32(REGISTER_ADDRESS(rx, AES_RX_PCM_MODE_REG), Value);
  }
   break;
   
 case IOC_CONFIG_TX_PCM_MODE:
  {
   /* Write the TX PCM configuration register. */
   if(copy_from_user(&Value, (void __user*)arg, sizeof(Value)) != 0) {
        return(-EFAULT);
   }
   XIo_Out32(REGISTER_ADDRESS(rx, AES_TX_PCM_MODE_REG), Value);
  }
   break;
   
 case IOC_CONFIG_2CHAN_MODE:
  {
   /* Write the two-channel mode configuration register. */
   if(copy_from_user(&Value, (void __user*)arg, sizeof(Value)) != 0) {
        return(-EFAULT);
   }
   XIo_Out32(REGISTER_ADDRESS(rx, AES_TX_2CHAN_MODE_REG), Value);
  }
   break;
   
  case IOC_READ_AES_MASK:
    {
      /* Get the stream mask, then copy into the userspace pointer */
      Value = XIo_In32(REGISTER_ADDRESS(rx, AES_STREAM_MASK_REG));
      if(copy_to_user((void __user*)arg, &Value, 
                      sizeof(uint32_t)) != 0) {
        return(-EFAULT);
      }
    }
    break;
   
  case IOC_SET_AES_MASK: 
    {
      if(copy_from_user(&Value, (void __user*)arg, sizeof(Value)) != 0) {
           return(-EFAULT);
      }
      XIo_Out32(REGISTER_ADDRESS(rx, AES_STREAM_MASK_REG), Value);
    }
    break;

  case IOC_READ_RX_METER_STATUS:
    {
      /* Get the stream mask, then copy into the userspace pointer */
      Value = XIo_In32(REGISTER_ADDRESS(rx, AES_RX_AUDIO_METER_REG));
      if(copy_to_user((void __user*)arg, &Value, sizeof(uint32_t)) != 0) {
        return(-EFAULT);
      }
    }
    break;
   
  case IOC_READ_TX_METER_STATUS:
    {
      /* Get the stream mask, then copy into the userspace pointer */
      Value = XIo_In32(REGISTER_ADDRESS(rx, AES_RX_AUDIO_METER_REG));
      if(copy_to_user((void __user*)arg, &Value, sizeof(uint32_t)) != 0) {
        return(-EFAULT);
      }
    }
    break;
   
  default:
    if((rx->derivedFops != NULL) && 
       (rx->derivedFops->ioctl != NULL)) {
      returnValue = rx->derivedFops->ioctl(inode, filp, command, arg);
    } else returnValue = -EINVAL;  
 
  }
  /* Return an error code appropriate to the command */
  return(returnValue);
}
Beispiel #21
0
/* Function containing the "meat" of the probe mechanism - this is used by
 * the OpenFirmware probe as well as the standard platform device mechanism.
 * This is exported to allow polymorphic drivers to invoke it.
 * @param name - Name of the instance
 * @param pdev - Platform device structure
 * @param addressRange - Resource describing the hardware's I/O 
 * @param irq          - Resource describing the hardware's interrupt
 */
int aes3_rx_probe(const char *name, 
                  struct platform_device *pdev,
                  struct resource *addressRange,
                  struct resource *irq,
                  struct file_operations *derivedFops,
                  void *derivedData,
                  struct aes3_rx **newInstance) {
  struct aes3_rx *rx;
  int returnValue;

  /* Create and populate a device structure */
  rx = (struct aes3_rx*) kmalloc(sizeof(struct aes3_rx), GFP_KERNEL);
  if(!rx) return(-ENOMEM);

  /* Request and map the device's I/O memory region into uncacheable space */
  rx->physicalAddress = addressRange->start;
  rx->addressRangeSize = ((addressRange->end - addressRange->start) + 1);
  snprintf(rx->name, NAME_MAX_SIZE, "%s", name);
  rx->name[NAME_MAX_SIZE - 1] = '\0';
  if(request_mem_region(rx->physicalAddress, rx->addressRangeSize,
                        rx->name) == NULL) {
    returnValue = -ENOMEM;
    goto free;
  }

  rx->virtualAddress = 
    (void*) ioremap_nocache(rx->physicalAddress, rx->addressRangeSize);
  if(!rx->virtualAddress) {
    returnValue = -ENOMEM;
    goto release;
  }
  
  /* Initialize the waitqueue used for status FIFO events */
  init_waitqueue_head(&(rx->statusFifoQueue));


  /* Ensure that the engine and its interrupts are disabled */
  XIo_Out32(REGISTER_ADDRESS(rx, AES_RX_STREAM_STATUS_REG), NO_IRQS);

  /*Initialize the Stream mask, enable all the 8 streams*/
  XIo_Out32(REGISTER_ADDRESS(rx, AES_STREAM_MASK_REG), 0xff);

  /* Run the thread assigned to converting status FIFO words into Netlink packets
   * after initializing its state to wait for the ISR
   */
  rx->statusReadyAes = AES_STATUS_IDLE;
  rx->statusReadyMeter = AES_STATUS_IDLE;
  rx->netlinkSequence = 0;
  rx->netlinkTask = kthread_run(netlink_thread, (void*) rx, "%s:netlink", rx->name);
  if (IS_ERR(rx->netlinkTask)) {
    printk(KERN_ERR "%s: AES Netlink task creation failed\n", rx->name);
    return(-EIO);
  }

  /* Retain the IRQ and register our handler, if an IRQ resource was supplied. */
  if(irq != NULL) {
    rx->meter_irq = irq[0].start;
    returnValue = request_irq(rx->meter_irq, &meter_interrupt, IRQF_DISABLED, rx->name, rx);
    if (returnValue) {
      printk(KERN_ERR "%s : Could not allocate Lab X Mosaic AES3 RX metering interrupt (%d).\n",
             rx->name, rx->meter_irq);
      goto unmap;
    }
    rx->aes_irq = irq[1].start;
    returnValue = request_irq(rx->aes_irq, &aes3_rx_interrupt, IRQF_DISABLED, rx->name, rx);
    if (returnValue) {
      printk(KERN_ERR "%s : Could not allocate Lab X Mosaic AES3 RX channel interrupt (%d).\n",
             rx->name, rx->aes_irq);
      goto unmap;
    }
  } else {
    rx->meter_irq = NO_IRQ_SUPPLIED;
    rx->aes_irq = NO_IRQ_SUPPLIED;
  }

  if(rx->meter_irq == NO_IRQ_SUPPLIED && rx->aes_irq == NO_IRQ_SUPPLIED) {
    printk("%s: polled commands\n", rx->name);
  } else {
    printk("%s: IRQ %d, %d\n", rx->name, rx->meter_irq, rx->aes_irq);
  }

  /* Initialize other resources */
  spin_lock_init(&rx->mutex);

  /* Provide navigation between the device structures */
  platform_set_drvdata(pdev, rx);
  rx->pdev = pdev;

  /* Add as a character device to make the instance available for use */
  cdev_init(&rx->cdev, &aes3_rx_fops);
  rx->cdev.owner = THIS_MODULE;
  rx->instanceNumber = instanceCount++;
  kobject_set_name(&rx->cdev.kobj, "%s.%d", rx->name, rx->instanceNumber);
  cdev_add(&rx->cdev, MKDEV(DRIVER_MAJOR, rx->instanceNumber), 1);

  /*Initialize deviceNode, to be used in the netlink messages */
  rx->deviceNode = MKDEV(DRIVER_MAJOR, rx->instanceNumber);

  /* Retain any derived file operations & data to dispatch to */
  rx->derivedFops = derivedFops;
  rx->derivedData = derivedData;

  /* Return success, setting the return pointer if valid */
  if(newInstance != NULL) *newInstance = rx;
  return(0);

 unmap:
  iounmap(rx->virtualAddress);
 release:
  release_mem_region(rx->physicalAddress, rx->addressRangeSize);
 free:
  kfree(rx);
  return(returnValue);
      
}
Beispiel #22
0
void lcd_ddram_set(Xuint32 address) {
    // Sets entry point to a DDRAM location, allowing text entry
    XIo_Out32(XPAR_LCD_0_BASEADDR, 0x80 | (address & 0x7F));
}
Beispiel #23
0
void lcd_data_write(Xuint32 data) {
    // Writes a byte to the current address (CGRAM or DDRAM)
    XIo_Out32(XPAR_LCD_0_BASEADDR, 0x100 | (data & 0xFF));
}
Beispiel #24
0
void lcd_cgram_set(Xuint32 address) {
    // Sets entry point to a CGRAM location, allowing custom character generation
    XIo_Out32(XPAR_LCD_0_BASEADDR, 0x40 | (address & 0x3F));
}
Beispiel #25
0
void lcd_scroll(Xuint32 command) {
    // Scrolls entire display (see LCD_SCROLL_* constants)
    XIo_Out32(XPAR_LCD_0_BASEADDR, 0x18 | (command & 0x04));
}
Beispiel #26
0
void lcd_nudge_cursor(Xuint32 command) {
    // Nudges cursor right or left (see LCD_NUDGE_* constants)
    XIo_Out32(XPAR_LCD_0_BASEADDR, 0x10 | (command & 0x04));
}
Beispiel #27
0
void lcd_display_ctrl(Xuint32 command) {
    // Controls display and cursor (see LCD_DISPLAY_* and LCD_CURSOR_* constants)
    XIo_Out32(XPAR_LCD_0_BASEADDR, 0x08 | (command & 0x07));
}
Beispiel #28
0
Xuint32 USB_EPP_Reg_Read (Xuint32 USB_EPP_BASEADDR, Xuint32 ADDRESS){
	XIo_Out32(USB_EPP_BASEADDR + USB_EPP_ADDRESS_REG_OFFSET, ADDRESS);
	return XIo_In32(USB_EPP_BASEADDR + USB_EPP_DATA_REG_OFFSET);
}
/**
*
* Send an Ethernet frame using direct FIFO I/O or simple DMA with interrupts.
* The caller provides a contiguous-memory buffer and its length. The buffer
* must be 32-bit aligned. If using simple DMA and the PLB 10/100 Ethernet core,
* the buffer must be 64-bit aligned. The callback function set by using
* SetFifoSendHandler is invoked when the transmission is complete.
*
* It is assumed that the upper layer software supplies a correctly formatted
* Ethernet frame, including the destination and source addresses, the
* type/length field, and the data field.
*
* If the device is configured with DMA, simple DMA will be used to transfer
* the buffer from memory to the Emac. This means that this buffer should not
* be cached.  See the comment section "Simple DMA" in xemac.h for more
* information.
*
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
* @param BufPtr is a pointer to a aligned buffer containing the Ethernet
*        frame to be sent.
* @param ByteCount is the size of the Ethernet frame.
*
* @return
*
* - XST_SUCCESS if the frame was successfully sent. An interrupt is generated
*   when the EMAC transmits the frame and the driver calls the callback set
*   with XEmac_SetFifoSendHandler()
* - XST_DEVICE_IS_STOPPED  if the device has not yet been started
* - XST_NOT_INTERRUPT if the device is not in interrupt mode
* - XST_FIFO_NO_ROOM if there is no room in the FIFO for this frame
* - XST_DEVICE_BUSY if configured for simple DMA and the DMA engine is busy
* - XST_DMA_ERROR if an error occurred during the DMA transfer (simple DMA).
*   The user should treat this as a fatal error that requires a reset of the
*   EMAC device.
*
* @note
*
* This function is not thread-safe. The user must provide mutually exclusive
* access to this function if there are to be multiple threads that can call it.
*
* @internal
*
* The Ethernet MAC uses FIFOs behind its length and status registers. For this
* reason, it is important to keep the length, status, and data FIFOs in sync
* when reading or writing to them.
*
******************************************************************************/
int XEmac_FifoSend(XEmac * InstancePtr, u8 *BufPtr, u32 ByteCount)
{
	int Result;
	volatile u32 StatusReg;

	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(BufPtr != NULL);
	XASSERT_NONVOID(ByteCount > XEM_HDR_SIZE);	/* send at least 1 byte */
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/*
	 * Be sure the device is configured for interrupt mode and it is started
	 */
	if (InstancePtr->IsPolled) {
		return XST_NOT_INTERRUPT;
	}

	if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
		return XST_DEVICE_IS_STOPPED;
	}

	/*
	 * Before writing to the data FIFO, make sure the length FIFO is not
	 * full.  The data FIFO might not be full yet even though the length FIFO
	 * is. This avoids an overrun condition on the length FIFO and keeps the
	 * FIFOs in sync.
	 */
	StatusReg = XEMAC_READ_IISR(InstancePtr->BaseAddress);
	if (StatusReg & XEM_EIR_XMIT_LFIFO_FULL_MASK) {
		return XST_FIFO_NO_ROOM;
	}

	/*
	 * Send either by directly writing to the FIFOs or using the DMA engine
	 */
	if (!XEmac_mIsDma(InstancePtr)) {
		/*
		 * This is a non-blocking write. The packet FIFO returns an error if there
		 * is not enough room in the FIFO for this frame.
		 */
		Result = XPacketFifoV200a_Write(&InstancePtr->SendFifo, BufPtr,
						ByteCount);
		if (Result != XST_SUCCESS) {
			return Result;
		}
	}
	else {
		u32 Vacancy;

		/*
		 * Need to make sure there is room in the data FIFO for the packet
		 * before trying to DMA into it. Get the vacancy count (in words)
		 * and make sure the packet will fit.
		 */
		Vacancy = XPF_V200A_GET_COUNT(&InstancePtr->SendFifo);
		if ((Vacancy * sizeof(u32)) < ByteCount) {
			return XST_FIFO_NO_ROOM;
		}

		/*
		 * Check the DMA engine to make sure it is not already busy
		 */
		if (XDmaChannel_GetStatus(&InstancePtr->SendChannel) &
		    XDC_DMASR_BUSY_MASK) {
			return XST_DEVICE_BUSY;
		}

		/*
		 * Set the DMA control register up properly
		 */
		XDmaChannel_SetControl(&InstancePtr->SendChannel,
				       XDC_DMACR_SOURCE_INCR_MASK |
				       XDC_DMACR_DEST_LOCAL_MASK |
				       XDC_DMACR_SG_DISABLE_MASK);

		/*
		 * Now transfer the data from the buffer to the FIFO
		 */
		XDmaChannel_Transfer(&InstancePtr->SendChannel, (u32 *) BufPtr,
				     (u32 *) (InstancePtr->BaseAddress +
					      XEM_PFIFO_TXDATA_OFFSET),
				     ByteCount);

		/*
		 * Poll here waiting for DMA to be not busy. We think this will
		 * typically be a single read since DMA should be ahead of the SW.
		 */
		do {
			StatusReg =
				XDmaChannel_GetStatus(&InstancePtr->
						      SendChannel);
		}
		while (StatusReg & XDC_DMASR_BUSY_MASK);

		/* Return an error if there was a problem with DMA */
		if ((StatusReg & XDC_DMASR_BUS_ERROR_MASK) ||
		    (StatusReg & XDC_DMASR_BUS_TIMEOUT_MASK)) {
			InstancePtr->Stats.DmaErrors++;
			return XST_DMA_ERROR;
		}
	}

	/*
	 * Set the MAC's transmit packet length register to tell it to transmit
	 */
	XIo_Out32(InstancePtr->BaseAddress + XEM_TPLR_OFFSET, ByteCount);

	/*
	 * Bump stats here instead of the Isr since we know the byte count
	 * here but would have to save it in the instance in order to know the
	 * byte count at interrupt time.
	 */
	InstancePtr->Stats.XmitFrames++;
	InstancePtr->Stats.XmitBytes += ByteCount;

	return XST_SUCCESS;
}
Beispiel #30
0
void lcd_entry_mode(Xuint32 command) {
    // Sets the entry mode (see LCD_ENTRY_* constants)
    XIo_Out32(XPAR_LCD_0_BASEADDR, 0x04 | (command & 0x03));
}