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(); } }
/** * * 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); }
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; }
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); }
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; }
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; }
/** * * 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); } }
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; }
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; }
/* 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); }
/** * * 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; }
/** * * 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); }
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; }
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); }
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; }
/* 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); }
/* 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); }
/* 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); }
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)); }
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)); }
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)); }
void lcd_scroll(Xuint32 command) { // Scrolls entire display (see LCD_SCROLL_* constants) XIo_Out32(XPAR_LCD_0_BASEADDR, 0x18 | (command & 0x04)); }
void lcd_nudge_cursor(Xuint32 command) { // Nudges cursor right or left (see LCD_NUDGE_* constants) XIo_Out32(XPAR_LCD_0_BASEADDR, 0x10 | (command & 0x04)); }
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)); }
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; }
void lcd_entry_mode(Xuint32 command) { // Sets the entry mode (see LCD_ENTRY_* constants) XIo_Out32(XPAR_LCD_0_BASEADDR, 0x04 | (command & 0x03)); }