void IsrWatchdog(void) { struct s3c24x0_interrupt * const intregs = s3c24x0_get_base_interrupt(); intregs->SUBSRCPND = (1<<13); ClearPending_my(BIT_WDT_AC97 /* BIT_WDT */); intCount++; }
/* Start to initialize h/w stuff */ int udc_init (void) { struct s3c24x0_clock_power * const clk_power = s3c24x0_get_base_clock_power(); struct s3c24x0_interrupt * irq = s3c24x0_get_base_interrupt(); udc_device = NULL; /* Set and check clock control. * We might ought to be using the clock control API to do * this instead of fiddling with the clock registers directly * here. */ clk_power->CLKCON |= (1 << 7); /* Print banner with device revision */ printf("USB: S3C2440 USB Deviced\n"); /* * At this point, device is ready for configuration... */ outl(0x00, S3C24X0_UDC_EP_INT_EN_REG); outl(0x00, S3C24X0_UDC_USB_INT_EN_REG); irq->INTMSK &= ~BIT_DMA2; irq->SRCPND &= ~BIT_DMA2; irq_install_handler(IRQ_USBD, do_usbd_irq, (void *) IRQ_USBD); irq_install_handler(IRQ_DMA2, do_dma2, (void *) IRQ_DMA2); return 0; }
void Ep3Handler(void) { struct s3c24x0_interrupt *intregs = s3c24x0_get_base_interrupt(); struct s3c24x0_usb_device *const usbdevregs = s3c24x0_get_base_usb_device(); U8 out_csr3; int fifoCnt; usbdevregs->INDEX_REG = 3; out_csr3 = usbdevregs->OUT_CSR1_REG; DbgPrintf("<3:%x]",out_csr3); if(out_csr3 & EPO_OUT_PKT_READY) { fifoCnt = usbdevregs->OUT_FIFO_CNT1_REG; if (downloadFileSize == 0) { RdPktEp3((U8 *)downPt, 8); if(download_run == 0) { downloadAddress = tempDownloadAddress; } else { downloadAddress = *((U32 *)downPt); dwUSBBufReadPtr = downloadAddress; dwUSBBufWritePtr = downloadAddress; } downloadFileSize = *((U32 *)(downPt + 4)); DbgPrintf("[dwaddr = %x, dwsize = %x]\n", downloadAddress, downloadFileSize); checkSum = 0; downPt = (U8 *)downloadAddress; /* The first 8-bytes are deleted. */ RdPktEp3_CheckSum((U8 *)downPt, fifoCnt-8); downPt += fifoCnt - 8; #if USBDMA /* * 传输由中断发起(只接收头一个Pkg),由DMA完成. * 因此发生中断后就禁止USBD中断,在DMA传输完成 * 后再次开启. */ intregs->INTMSK |= BIT_USBD; return; #endif } else { RdPktEp3_CheckSum((U8 *)downPt, fifoCnt); downPt += fifoCnt; //fifoCnt = 64 } CLR_EP3_OUT_PKT_READY(); return; } if (out_csr3 & EPO_SENT_STALL) { DbgPrintf("[STALL]"); CLR_EP3_SENT_STALL(); return; } }
void Timer_InitEx(void) { struct s3c24x0_interrupt * const intregs = s3c24x0_get_base_interrupt(); intCount=0; intregs->SUBSRCPND = (1<<13); ClearPending_my(BIT_WDT_AC97/*BIT_WDT*/); intregs->INTMSK&=~(BIT_WDT_AC97 /*BIT_WDT*/); intregs->INTSUBMSK &= ~(1<<13); }
/* Turn off the USB connection by disabling the pullup resistor */ void udc_disconnect (void) { debug("disconnect, disable Pullup\n"); struct s3c24x0_interrupt * irq = s3c24x0_get_base_interrupt(); udc_ctrl(UDC_CTRL_PULLUP_ENABLE, 0); /* Disable interrupt (we don't want to get interrupts while the kernel * is relocating itself */ irq->INTMSK |= BIT_USBD; }
/* Turn on the USB connection by enabling the pullup resistor */ void udc_connect (void) { debug("connect, enable Pullup\n"); struct s3c24x0_interrupt * irq = s3c24x0_get_base_interrupt(); udc_ctrl(UDC_CTRL_PULLUP_ENABLE, 0); udelay(10000); udc_ctrl(UDC_CTRL_PULLUP_ENABLE, 1); irq->INTMSK &= ~BIT_USBD; }
unsigned int Timer_StopEx(void) { int count; struct s3c24x0_watchdog * const wdtregs = s3c24x0_get_base_watchdog(); struct s3c24x0_interrupt * const intregs = s3c24x0_get_base_interrupt(); wdtregs->WTCON=((get_PCLK()/1000000-1)<<8); intregs->INTMSK|=BIT_WDT_AC97; //BIT_WDT; intregs->INTSUBMSK |= (1<<13); count=(0xffff-wdtregs->WTCNT)+(intCount*0xffff); return ((unsigned int)count*16/1000000); }
/* Turn off the USB connection by disabling the pullup resistor */ void udc_disconnect (void) { debug("disconnect, disable Pullup\n"); struct s3c24x0_interrupt * irq = s3c24x0_get_base_interrupt(); struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); gpio->GPGDAT &= ~S3C24X0_MISCCR_USBSUSPND1; /* Disable interrupt (we don't want to get interrupts while the kernel * is relocating itself */ irq->INTMSK |= BIT_USBD; }
/* Turn on the USB connection by enabling the pullup resistor */ void udc_connect (void) { debug("connect, enable Pullup\n"); struct s3c24x0_interrupt * irq = s3c24x0_get_base_interrupt(); struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); gpio->GPGDAT &= ~S3C24X0_MISCCR_USBSUSPND1; udelay(10000); gpio->GPGDAT |= S3C24X0_MISCCR_USBSUSPND1; irq->INTMSK &= ~BIT_USBD; irq->SRCPND &= ~BIT_USBD; }
void IRQ_Handle() { struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); struct s3c24x0_interrupt * const intregs = s3c24x0_get_base_interrupt(); unsigned long oft = intregs->INTOFFSET; // clean int if( oft == 4 ) gpio->EINTPEND = 1<<7; //EINT4-7 in IRQ4 (EINTPEND[3:0] is reserve) intregs->SRCPND = 1<<oft; intregs->INTPND = intregs->INTPND; /* run the isr */ isr_handle_array[oft](); }
int do_wd (cmd_tbl_t *cmdtp, int flag, int argc,char* const argv[]) { unsigned long reset = 0; unsigned long wtcnt= 0; unsigned long wtdat= 0; unsigned long enable = 0; struct s3c24x0_interrupt * intregs = s3c24x0_get_base_interrupt(); struct s3c24x0_watchdog * dogregs = s3c24x0_get_base_watchdog(); if(argc>1) enable = simple_strtoul(argv[1], NULL, 16); if(argc>2) reset = simple_strtoul(argv[2], NULL, 16); if(argc>3) wtdat = simple_strtoul(argv[3], NULL, 16); if(argc>4) wtcnt = simple_strtoul(argv[4], NULL, 16); printf("watchdog cmd: enable = %ld, reset=%ld, wtdat=0x%lx, wtcnt=0x%lx\r\n", enable, reset ,wtdat, wtcnt); if(enable) { intregs->srcpnd |= ISR_BIT(ISR_WDT_OFT); intregs->intpnd |= ISR_BIT(ISR_WDT_OFT); intregs->subsrcpnd |= (1<<13); //subsrcpnd for wdt intregs->intmsk&=~(ISR_BIT(ISR_WDT_OFT) /*BIT_WDT*/); intregs->intsubmsk&= ~(1<<13); dogregs->wtdat = wtdat; dogregs->wtcnt = wtcnt; if(reset) dogregs->wtcon |=(1<<0); dogregs->wtcon |= 0xff00; dogregs->wtcon |=(1<<5)|(1<<2); } else { dogregs->wtcon &=~(1<<5); intregs->srcpnd |= ISR_BIT(ISR_WDT_OFT); intregs->intpnd |= ISR_BIT(ISR_WDT_OFT); intregs->subsrcpnd |= (1<<13); //subsrcpnd for wdt intregs->intmsk|=ISR_BIT(ISR_WDT_OFT); /*BIT_WDT*/ intregs->intsubmsk|= (1<<13); } return 0; }
void IsrDma2() { struct s3c24x0_interrupt *intregs = s3c24x0_get_base_interrupt(); struct s3c24x0_usb_device *usbdevregs = s3c24x0_get_base_usb_device(); U8 out_csr3; U32 dwEmptyCnt; U8 saveIndexReg = usbdevregs->INDEX_REG; usbdevregs->INDEX_REG = 3; out_csr3 = usbdevregs->OUT_CSR1_REG; ClearPending_my((int)BIT_DMA2); if (!totalDmaCount) totalDmaCount = dwWillDMACnt + EP3_PKT_SIZE; else totalDmaCount += dwWillDMACnt; dwUSBBufWritePtr = ((dwUSBBufWritePtr + dwWillDMACnt - dwUSBBufBase) % dwUSBBufSize) + dwUSBBufBase; if (totalDmaCount >= downloadFileSize) { /* last */ totalDmaCount = downloadFileSize; ConfigEp3IntMode(); if (out_csr3 & EPO_OUT_PKT_READY) CLR_EP3_OUT_PKT_READY(); /* 关闭DMA2中断并重新开启USBD中断 */ intregs->INTMSK |= BIT_DMA2; intregs->INTMSK &= ~(BIT_USBD); } else { if ((totalDmaCount + 0x80000) < downloadFileSize) dwWillDMACnt = 0x80000; else dwWillDMACnt = downloadFileSize - totalDmaCount; dwEmptyCnt = (dwUSBBufReadPtr - dwUSBBufWritePtr - 1 + dwUSBBufSize) % dwUSBBufSize; if (dwEmptyCnt >= dwWillDMACnt) ConfigEp3DmaMode(dwUSBBufWritePtr, dwWillDMACnt); } usbdevregs->INDEX_REG = saveIndexReg; }
void Isr_Init(void) { int i = 0; struct s3c24x0_interrupt * const intregs = s3c24x0_get_base_interrupt(); for (i = 0; i < sizeof(isr_handle_array) / sizeof(isr_handle_array[0]); i++ ) { isr_handle_array[i] = Dummy_isr; } intregs->INTMOD=0x0; // All=IRQ mode intregs->INTMSK=BIT_ALLMSK; // All interrupt is masked. isr_handle_array[ISR_TIMER4_OFT] = IsrTimer4; isr_handle_array[ISR_WDT_OFT] = IsrWatchdog; //#ifdef CONFIG_USB_DEVICE isr_handle_array[ISR_USBD_OFT] = IsrUsbd; isr_handle_array[ISR_DMA2_OFT] = IsrDma2; ClearPending_my(BIT_DMA2); ClearPending_my(BIT_USBD); //#endif }
__u32 usb_receive(char *buf, size_t len, U32 wait) { int first=1; U8 tempMem[16]; U32 j; unsigned int dwRecvTimeSec = 0; char c; struct s3c24x0_interrupt * intregs = s3c24x0_get_base_interrupt(); dwUSBBufReadPtr = dwUSBBufBase; // USB_BUF_BASE; thiswa.diy, 2006.06.21 dwUSBBufWritePtr = dwUSBBufBase; // USB_BUF_BASE; thiswa.diy, 2006.06.21 bDMAPending = 0; /* add by thisway.diy */ tempDownloadAddress = dwUSBBufBase; // USB_BUF_BASE; thiswa.diy, 2006.06.21 // RAM_BASE, changed by thisway.diy for wince, 2006.06.18 downloadAddress=(U32)tempMem; //_RAM_STARTADDRESS; downPt=(unsigned char *)downloadAddress; //This address is used for receiving first 8 byte. downloadFileSize=0; /*******************************/ /* File download */ /*******************************/ if(isUsbdSetConfiguration==0) { printf("USB host is not connected yet.\n"); } while(downloadFileSize==0) /* wait until send a file */ { if(first==1 && isUsbdSetConfiguration!=0) { printf("USB host is connected. Waiting a download.\n"); first=0; } c = awaitkey(1, 0); if ((c & 0x7f) == INTR) { printf("Cancelled by user\n"); return 0; } } printf("get downloadFileSize = %d !!\n",downloadFileSize); /* add by thisway.diy */ if (downloadFileSize - 10 > len) { printf("Length of file is too big : %d > %d\n", downloadFileSize - 10, len); return 0; } Timer_InitEx(); Timer_StartEx(); #if USBDMA writel((readl(&intregs->intmsk) & ~(BIT_DMA2)), &intregs->intmsk); // intregs->INTMSK&=~(BIT_DMA2); ClearEp3OutPktReady(); // indicate the first packit is processed. // has been delayed for DMA2 cofiguration. if(downloadFileSize>EP3_PKT_SIZE) { if(downloadFileSize - EP3_PKT_SIZE<=(0x80000)) { /* set the source and length */ dwUSBBufWritePtr = downloadAddress + EP3_PKT_SIZE-8; dwWillDMACnt = downloadFileSize - EP3_PKT_SIZE; } else { dwUSBBufWritePtr = downloadAddress + EP3_PKT_SIZE - 8; // dwWillDMACnt = 0x80000 - EP3_PKT_SIZE; /* Changed by thisway.diy, 2006.06.22 * We want When the first DMA interrupt happened, * it has received (0x80000 + 8) bytes data from PC * The format of data PC send out is: <ADDR(DATA):4>+<SIZE(n+10):4>+<DATA:n>+<CS:2> * So, the first 8 bytes isn't the real data we want * We want the dwUSBBufWritePtr is always 0x80000 aligin */ dwWillDMACnt = 0x80000 + 8 - EP3_PKT_SIZE; } totalDmaCount = 0; ConfigEp3DmaMode(dwUSBBufWritePtr, dwWillDMACnt); } else { dwUSBBufWritePtr = downloadAddress + downloadFileSize - 8; totalDmaCount = downloadFileSize; } #endif printf("\nNow, Downloading [ADDRESS:%xh,TOTAL:%d]\n", downloadAddress,downloadFileSize); if (wait) { printf("RECEIVED FILE SIZE:%8d",0); j = totalDmaCount + 0x10000; while (totalDmaCount != downloadFileSize) { if (totalDmaCount > j) { printf("\b\b\b\b\b\b\b\b%8d", j); j = totalDmaCount + 0x10000; } } printf("\b\b\b\b\b\b\b\b%8d ", totalDmaCount); dwRecvTimeSec = Timer_StopEx(); if (dwRecvTimeSec == 0) { dwRecvTimeSec = 1; } printf("(%dKB/S, %dS)\n", (downloadFileSize/dwRecvTimeSec/1024), dwRecvTimeSec); } return downloadFileSize - 10; }
void do_irq (struct pt_regs *pt_regs) { struct s3c24x0_interrupt *irq = s3c24x0_get_base_interrupt(); u_int32_t intpnd = readl(&irq->INTPND); }
void Dummy_isr(void) { struct s3c24x0_interrupt * const intregs = s3c24x0_get_base_interrupt(); printf("Dummy_isr error, interrupt number: %d, INTMSK = 0x%x\n", intregs->INTOFFSET, intregs->INTMSK); while(1); }
void ClearPending_my(int bit) { struct s3c24x0_interrupt * const intregs = s3c24x0_get_base_interrupt(); intregs->SRCPND = bit; intregs->INTPND = bit; }