Hint dma_transfer(XAxiCdma *dma, Huint SrcAddr, Huint DstAddr, Hint byte_Length) { Hint Status, CDMA_Status; // Wait for the dma controller to not be busy while(dma_getbusy(dma)); Status = XAxiCdma_SimpleTransfer(dma, SrcAddr, DstAddr, byte_Length, NULL, NULL); if (Status != SUCCESS) { CDMA_Status = dma_geterror(dma); if (CDMA_Status != SUCCESS) { TRACE_PRINTF( TRACE_ERR, TRACE_DMA, "DMA ERROR: (CDMA Status=0x%08x)\n", CDMA_Status ); // Reset the device dma_reset(dma); } else TRACE_PRINTF( TRACE_ERR, TRACE_DMA, "DMA ERROR: (Perhaps an existing transfer ongoing?)\n"); return FAILURE; } return SUCCESS; }
void sCPU::reset() { CPU::reset(); //note: some registers are not fully reset by SNES regs.pc = 0x000000; regs.x.h = 0x00; regs.y.h = 0x00; regs.s.h = 0x01; regs.d = 0x0000; regs.db = 0x00; regs.p = 0x34; regs.e = 1; regs.mdr = 0x00; regs.wai = false; update_table(); mmio_reset(); dma_reset(); timing_reset(); apu_port[0] = 0x00; apu_port[1] = 0x00; apu_port[2] = 0x00; apu_port[3] = 0x00; }
static void rx_dma_callback(DMA_HANDLE handle, uint8_t status, void *arg) { uint16_t sr = rSR; stm32_dmastop(rx_dma); stm32_dmastop(tx_dma); /* handle the received packet */ rx_handle_packet(); /* re-set DMA for reception first, so we are ready to receive before we start sending */ if (!(sr & SPI_SR_BSY)) { dma_reset(); } /* send the reply to the just-processed request */ dma_packet.crc = 0; dma_packet.crc = crc_packet(&dma_packet); stm32_dmasetup( tx_dma, (uint32_t)&rDR, (uint32_t)&dma_packet, PKT_SIZE(dma_packet), DMA_CCR_DIR | DMA_CCR_MINC | DMA_CCR_PSIZE_8BITS | DMA_CCR_MSIZE_8BITS | DMA_CCR_PRIMED); stm32_dmastart(tx_dma, NULL, NULL, false); perf_end(pc_txns); }
static int spi_interrupt(int irq, FAR void *context) { uint16_t sr = rSR; if (sr & SPI_SR_OVR) { (void)rSR; rSR = 0; if (sr & SPI_SR_BSY) { stm32_dmastop(rx_dma); } else { dma_reset(); } } /* clear any errors that might need it */ if ((sr & SPI_SR_CRCERR) || (sr & SPI_SR_MODF)) { (void)rSR; rSR = 0; } return 0; }
static void rx_dma_callback(DMA_HANDLE handle, uint8_t status, void *arg) { /* * We are here because DMA completed, or UART reception stopped and * we think we have a packet in the buffer. */ perf_begin(pc_txns); /* disable UART DMA */ rCR3 &= ~(USART_CR3_DMAT | USART_CR3_DMAR); /* handle the received packet */ rx_handle_packet(); /* re-set DMA for reception first, so we are ready to receive before we start sending */ dma_reset(); /* send the reply to the just-processed request */ dma_packet.crc = 0; dma_packet.crc = crc_packet(&dma_packet); stm32_dmasetup( tx_dma, (uint32_t)&rDR, (uint32_t)&dma_packet, PKT_SIZE(dma_packet), DMA_CCR_DIR | DMA_CCR_MINC | DMA_CCR_PSIZE_8BITS | DMA_CCR_MSIZE_8BITS); stm32_dmastart(tx_dma, NULL, NULL, false); rCR3 |= USART_CR3_DMAT; perf_end(pc_txns); }
void interface_init(void) { pc_txns = perf_alloc(PC_ELAPSED, "txns"); pc_errors = perf_alloc(PC_COUNT, "errors"); pc_ore = perf_alloc(PC_COUNT, "overrun"); pc_fe = perf_alloc(PC_COUNT, "framing"); pc_ne = perf_alloc(PC_COUNT, "noise"); pc_idle = perf_alloc(PC_COUNT, "idle"); pc_badidle = perf_alloc(PC_COUNT, "badidle"); pc_regerr = perf_alloc(PC_COUNT, "regerr"); pc_crcerr = perf_alloc(PC_COUNT, "crcerr"); /* allocate DMA */ tx_dma = stm32_dmachannel(PX4FMU_SERIAL_TX_DMA); rx_dma = stm32_dmachannel(PX4FMU_SERIAL_RX_DMA); /* configure pins for serial use */ stm32_configgpio(PX4FMU_SERIAL_TX_GPIO); stm32_configgpio(PX4FMU_SERIAL_RX_GPIO); /* reset and configure the UART */ rCR1 = 0; rCR2 = 0; rCR3 = 0; /* clear status/errors */ (void)rSR; (void)rDR; /* configure line speed */ uint32_t usartdiv32 = PX4FMU_SERIAL_CLOCK / (PX4FMU_SERIAL_BITRATE / 2); uint32_t mantissa = usartdiv32 >> 5; uint32_t fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1; rBRR = (mantissa << USART_BRR_MANT_SHIFT) | (fraction << USART_BRR_FRAC_SHIFT); /* connect our interrupt */ irq_attach(PX4FMU_SERIAL_VECTOR, serial_interrupt); up_enable_irq(PX4FMU_SERIAL_VECTOR); /* enable UART and error/idle interrupts */ rCR3 = USART_CR3_EIE; rCR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE | USART_CR1_IDLEIE; #if 0 /* keep this for signal integrity testing */ for (;;) { while (!(rSR & USART_SR_TXE)) ; rDR = 0xfa; while (!(rSR & USART_SR_TXE)) ; rDR = 0xa0; } #endif /* configure RX DMA and return to listening state */ dma_reset(); debug("serial init"); }
void CPU::reset() { create(Enter, system.cpu_frequency()); coprocessors.reset(); PPUcounter::reset(); regs.pc = 0x000000; regs.x.h = 0x00; regs.y.h = 0x00; regs.s.h = 0x01; regs.d = 0x0000; regs.db = 0x00; regs.p = 0x34; regs.e = 1; regs.mdr = 0x00; regs.wai = false; update_table(); regs.pc.l = bus.read(0xfffc); regs.pc.h = bus.read(0xfffd); regs.pc.b = 0x00; status.nmi_valid = false; status.nmi_line = false; status.nmi_transition = false; status.nmi_pending = false; status.frame_event_performed = false; status.irq_valid = false; status.irq_line = false; status.irq_transition = false; status.irq_pending = false; status.irq_lock = false; status.hdma_pending = false; status.wram_addr = 0x000000; status.joypad_strobe_latch = 0; status.nmi_enabled = false; status.virq_enabled = false; status.hirq_enabled = false; status.auto_joypad_poll_enabled = false; status.pio = 0xff; status.htime = 0x0000; status.vtime = 0x0000; status.rom_speed = 8; status.joy1l = status.joy1h = 0x00; status.joy2l = status.joy2h = 0x00; status.joy3l = status.joy3h = 0x00; status.joy4l = status.joy4h = 0x00; dma_reset(); }
void interface_tick() { /* XXX look for stuck/damaged DMA and reset? */ if (idle_ticks++ > 100) { dma_reset(); idle_ticks = 0; } }
void interface_init(void) { debug("spi init"); pc_txns = perf_alloc(PC_ELAPSED, "txns"); pc_errors = perf_alloc(PC_COUNT, "errors"); pc_ore = perf_alloc(PC_COUNT, "overrun"); pc_fe = perf_alloc(PC_COUNT, "framing"); pc_ne = perf_alloc(PC_COUNT, "noise"); pc_idle = perf_alloc(PC_COUNT, "idle"); pc_badidle = perf_alloc(PC_COUNT, "badidle"); pc_regerr = perf_alloc(PC_COUNT, "regerr"); pc_crcerr = perf_alloc(PC_COUNT, "crcerr"); /* allocate DMA handles and initialise DMA */ rx_dma = stm32_dmachannel(DMACHAN_SPI3_RX); tx_dma = stm32_dmachannel(DMACHAN_SPI3_TX); /* enable the spi block clock and reset it */ modifyreg32(STM32_RCC_APB1ENR, 0, RCC_APB1ENR_SPI3EN); modifyreg32(STM32_RCC_APB1RSTR, 0, RCC_APB1RSTR_SPI3RST); modifyreg32(STM32_RCC_APB1RSTR, RCC_APB1RSTR_SPI3RST, 0); /* configure the spi GPIOs */ stm32_configgpio(RPI_SPI_NSS); stm32_configgpio(RPI_SPI_SCK); stm32_configgpio(RPI_SPI_MISO); stm32_configgpio(RPI_SPI_MOSI); /* reset and configure the SPI */ rCR1 = SPI_CR1_CPHA | SPI_CR1_CPOL; /* set for DMA operation */ rCR2 = SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN | SPI_CR2_ERRIE; /* enable event interrupts */ irq_attach(STM32_IRQ_SPI3, spi_interrupt); up_enable_irq(STM32_IRQ_SPI3); /* configure RX DMA and return to listening state */ dma_reset(); /* and enable the SPI port */ rCR1 |= SPI_CR1_SPE; #ifdef DEBUG spi_dump(); #endif }
void play_stop(void) { _dma_off(); dma_wait_for_disable(); dma_reset(); rateclock_stop(); if (gState == STATE_PLAYING_FROM_SD) { f_close(&gFile); } gState = STATE_IDLE; }
static long axi_dma_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct axi_dma_config_info *config_info = (struct axi_dma_config_info *)arg; switch (cmd) { case XDMA_IOCTL_RESET: if(config_info->channel == S2MM_CHANNEL){ dma_reset(config_info->channel, dma_wr_reg, config_info->reset_type); } break; case XDMA_IOCTL_CONFIG: if(config_info->channel == S2MM_CHANNEL){ //dma_init(config_info->channel, config_info->length, config_info->cycle, // config_info->mem_addr, dma_wr_reg); break; } break; case XDMA_START_WAIT_COMPLETE: if(config_info->channel == S2MM_CHANNEL){ dma_start(config_info->channel, 0, dma_wr_reg); wait_for_completion(&dma_completion); } break; case XDMA_MEM_ALLOC: if(config_info->length > 8 && config_info->length <= MEM_MAX_SIZE) { config_info->length = PAGE_ALIGN(config_info->length); mem_info.size = config_info->length; if(mem_info.size == 0) { printk(KERN_ERR"alloc memory failed\n"); return -ENOMEM; } mem_info.mem_base = dma_alloc_writecombine(NULL, mem_info.size, &(mem_info.phy_base), GFP_KERNEL); if(!mem_info.mem_base) { mem_info.phy_base = 0; printk(KERN_ERR"alloc memory failed\n"); return -ENOMEM; } config_info->mem_addr = (unsigned long)mem_info.phy_base; mem_info.mark = MEM_ALLOC; } break; default: return -EINVAL; break; } return 0; }
void pc_reset() { cpu_set(); resetx86(); mem_updatecache(); //timer_reset(); dma_reset(); fdc_reset(); pic_reset(); pit_reset(); serial_reset(); setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); // sb_reset(); ali1429_reset(); // video_init(); }
// -------------------------------------------------------------- // // DMA Transfer Wrapper // // -------------------------------------------------------------- // Hint transfer_dma(void * src, void * des, Hint size) { XAxiCdma dma; Hint status = dma_create(&dma,SLAVE_LOCAL_DMA_DEVICE_ID); if (status != SUCCESS) return FAILURE; // Reset DMA dma_reset(&dma); status = dma_transfer(&dma, (Huint) src, (Huint) des, size); if (status != SUCCESS) return FAILURE; // Wait until done while(dma_getbusy(&dma)); // Check for any errors return (dma_geterror(&dma)); }
void CPU::reset() { create(Enter, system.cpu_frequency()); coprocessors.reset(); PPUcounter::reset(); //note: some registers are not fully reset by SNES regs.pc = 0x000000; regs.x.h = 0x00; regs.y.h = 0x00; regs.s.h = 0x01; regs.d = 0x0000; regs.db = 0x00; regs.p = 0x34; regs.e = 1; regs.mdr = 0x00; regs.wai = false; update_table(); mmio_reset(); dma_reset(); timing_reset(); }
/** **************************************************************************************** * @brief Initialize DMA controller * @description * This function is used to clear callback pointer and enable DMA NVIC IRQ. **************************************************************************************** */ void dma_init(void) { uint32_t reg; #if DMA_CALLBACK_EN==TRUE dma_env.callback = NULL; #endif dma_clock_on(); dma_reset(); /* Wait until current DMA complete */ while (dma_dma_GetIntStatus(QN_DMA) & DMA_MASK_BUSY); #if CONFIG_DMA_ENABLE_INTERRUPT==TRUE reg = DMA_MASK_DONE_IE /* dma done interrupt enable */ | DMA_MASK_ERROR_IE /* dma error interrupt enable */ | DMA_MASK_INT_EN /* enable dma int */ ; dma_dma_SetCR(QN_DMA, reg); /* Enable the DMA Interrupt */ NVIC_EnableIRQ(DMA_IRQn); #endif }
static int serial_interrupt(int irq, void *context, FAR void *arg) { static bool abort_on_idle = false; uint32_t sr = rSR; /* get UART status register */ (void)rDR; /* required to clear any of the interrupt status that brought us here */ if (sr & (USART_SR_ORE | /* overrun error - packet was too big for DMA or DMA was too slow */ USART_SR_NE | /* noise error - we have lost a byte due to noise */ USART_SR_FE)) { /* framing error - start/stop bit lost or line break */ perf_count(pc_errors); if (sr & USART_SR_ORE) { perf_count(pc_ore); } if (sr & USART_SR_NE) { perf_count(pc_ne); } if (sr & USART_SR_FE) { perf_count(pc_fe); } /* send a line break - this will abort transmission/reception on the other end */ rCR1 |= USART_CR1_SBK; /* when the line goes idle, abort rather than look at the packet */ abort_on_idle = true; } if (sr & USART_SR_IDLE) { /* * If we saw an error, don't bother looking at the packet - it should have * been aborted by the sender and will definitely be bad. Get the DMA reconfigured * ready for their retry. */ if (abort_on_idle) { abort_on_idle = false; dma_reset(); return 0; } /* * The sender has stopped sending - this is probably the end of a packet. * Check the received length against the length in the header to see if * we have something that looks like a packet. */ unsigned length = sizeof(dma_packet) - stm32_dmaresidual(rx_dma); if ((length < 1) || (length < PKT_SIZE(dma_packet))) { /* it was too short - possibly truncated */ perf_count(pc_badidle); dma_reset(); return 0; } /* * Looks like we received a packet. Stop the DMA and go process the * packet. */ perf_count(pc_idle); stm32_dmastop(rx_dma); rx_dma_callback(rx_dma, DMA_STATUS_TCIF, NULL); } return 0; }
//--------------------------------------------------------------------------- int g2_init(g2_video_mode mode) { vmode_t *v; v = &(vmodes[mode]); cur_mode = v; g2_max_x = v->width - 1; g2_max_y = v->height - 1; g2_view_x0 = 0; g2_view_y0 = 0; g2_view_x1 = g2_max_x; g2_view_y1 = g2_max_y; gs_origin_x = 1024; gs_origin_y = 1024; gs_mem_current = 0; // nothing allocated yet g2_visible_frame = 0; // display frame 0 g2_active_frame = 0; // draw to frame 0 // - Initialize the DMA. // - Writes a 0 to most of the DMA registers. dma_reset(); // - Sets the RESET bit if the GS CSR register. GS_RESET(); #ifndef FLASH // - Can someone please tell me what the sync.p // instruction does. Synchronizes something :-) __asm__(" sync.p nop "); #endif // - Sets up the GS IMR register (i guess). // - The IMR register is used to mask and unmask certain interrupts, // for example VSync and HSync. We'll use this properly in Tutorial 2. // - Does anyone have code to do this without using the 0x71 syscall? // - I havn't gotten around to looking at any PS2 bios code yet. gs_set_imr(); // - Use syscall 0x02 to setup some video mode stuff. // - Pretty self explanatory I think. // - Does anyone have code to do this without using the syscall? It looks // like it should only set the SMODE2 register, but if I remove this syscall // and set the SMODE2 register myself, it donesn't work. What else does // syscall 0x02 do? gs_set_crtc(NON_INTERLACED, v->ntsc_pal, FRAME); // - I havn't attempted to understand what the Alpha parameters can do. They // have been blindly copied from the 3stars demo (although they don't seem // do have any impact in this simple 2D code. GS_SET_PMODE( 0, // ReadCircuit1 OFF 1, // ReadCircuit2 ON 1, // Use ALP register for Alpha Blending 1, // Alpha Value of ReadCircuit2 for output selection 0, // Blend Alpha with the output of ReadCircuit2 0xFF // Alpha Value = 1.0 ); /* // - Non needed if we use gs_set_crt() GS_SET_SMODE2( 0, // Non-Interlaced mode 1, // FRAME mode (read every line) 0 // VESA DPMS Mode = ON ??? please explain ??? ); */ GS_SET_DISPFB2( 0, // Frame Buffer base pointer = 0 (Address/8192) v->width/64, // Buffer Width (Pixels/64) v->psm, // Pixel Storage Format 0, // Upper Left X in Buffer = 0 0 // Upper Left Y in Buffer = 0 ); // Why doesn't (0, 0) equal the very top-left of the TV? GS_SET_DISPLAY2( 656, // X position in the display area (in VCK units) 36, // Y position in the display area (in Raster units) v->magh-1, // Horizontal Magnification - 1 0, // Vertical Magnification = 1x v->width*v->magh-1, // Display area width - 1 (in VCK units) (Width*HMag-1) v->height-1 // Display area height - 1 (in pixels) (Height-1) ); GS_SET_BGCOLOR( 0, // RED 0, // GREEN 0 // BLUE ); BEGIN_GS_PACKET(gs_dma_buf); GIF_TAG_AD(gs_dma_buf, 6, 1, 0, 0, 0); // Use drawing parameters from PRIM register GIF_DATA_AD(gs_dma_buf, prmodecont, 1); // Setup frame buffers. Point to 0 initially. GIF_DATA_AD(gs_dma_buf, frame_1, GS_FRAME( 0, // FrameBuffer base pointer = 0 (Address/8192) v->width/64, // Frame buffer width (Pixels/64) v->psm, // Pixel Storage Format 0)); // Save address and advance GS memory pointer by buffer size (in bytes) // Do this for both frame buffers. g2_frame_addr[0] = gs_mem_current; gs_mem_current += v->width * v->height * (v->bpp/8); g2_frame_addr[1] = gs_mem_current; gs_mem_current += v->width * v->height * (v->bpp/8); // Displacement between Primitive and Window coordinate systems. GIF_DATA_AD(gs_dma_buf, xyoffset_1, GS_XYOFFSET( gs_origin_x<<4, gs_origin_y<<4)); // Clip to frame buffer. GIF_DATA_AD(gs_dma_buf, scissor_1, GS_SCISSOR( 0, g2_max_x, 0, g2_max_y)); // Create a single 256x128 font buffer g2_fontbuf_addr = gs_mem_current; gs_mem_current += g2_fontbuf_w * g2_fontbuf_h * (v->bpp/8); // Create a texture buffer as big as the screen. // Just save the address advance GS memory pointer by buffer size (in bytes) // The TEX registers are set later, when drawing. g2_texbuf_addr = gs_mem_current; gs_mem_current += v->width * v->height * (v->bpp/8); // Setup test_1 register to allow transparent texture regions where A=0 GIF_DATA_AD(gs_dma_buf, test_1, GS_TEST( 1, // Alpha Test ON ATST_NOTEQUAL, 0x00, // Reject pixels with A=0 AFAIL_KEEP, // Don't update frame or Z buffers 0, 0, 0, 0)); // No Destination Alpha or Z-Buffer Tests // Setup the ALPHA_1 register to correctly blend edges of // pre-antialiased fonts using Alpha Blending stage. // The blending formula is // PIXEL=(SRC-FRAME)*SRC_ALPHA>>7+FRAME GIF_DATA_AD(gs_dma_buf, alpha_1, GS_ALPHA( 0, // A - source 1, // B - frame buffer 0, // C - alpha from source 1, // D - frame buffer 0)); // FIX - not needed SEND_GS_PACKET(gs_dma_buf); return(1); }