📄 cfw_platform.c
字号:
/* Set DefaultAddressValue */
pVic->DefVectAddr = VIC_NONVECT_INTERRUPT;
/* Set the first 16 interrupts (0-15) as vectored */
for(irq = 0; irq < VIC_NUM_VECTIRQ_LINES; irq++)
{
/* Put source numbers into VectAddr[x] registers */
*(VicVectAddress + irq) = irq;
/* Enable the interrupt sources as vectored */
*(VicVectCntl + irq) = irq | VIC_SET_VECTORED_INT;
/* Clear up to 16 pending interupts that may be around in the vector address register */
/* Actual values unimportant, the read/write action clears the next pending interupt */
pVic->VectAddr = pVic->VectAddr + 1;
}
/* We make sure we read/write the vector address register one more time to cover any non-vectored interrupt */
pVic->VectAddr = pVic->VectAddr + 1;
memset(Logic2SysIntr, (ULONG)LOGINTR_UNDEFINED, sizeof(Logic2SysIntr));
memset(SysIntr2Logic, (ULONG)SYSINTR_UNDEFINED, sizeof(SysIntr2Logic));
memset( LogIntrOpenStatus, 0 , sizeof(LogIntrOpenStatus) );
#define SETUP_INTERRUPT_MAP(SysIntr, Irq) \
{ \
SysIntr2Logic[SysIntr] = Irq; \
Logic2SysIntr[Irq] = SysIntr; \
}
// Set up static interrupt mappings.
SETUP_INTERRUPT_MAP(SYSINTR_SERIAL1, LOGINTR_UART1); // Serial 1
SETUP_INTERRUPT_MAP(SYSINTR_TIMER2, LOGINTR_TIMER1);
SETUP_INTERRUPT_MAP(SYSINTR_SSP0, LOGINTR_SSP0);
SETUP_INTERRUPT_MAP(SYSINTR_AUDIO, LOGINTR_AUDIO);
SETUP_INTERRUPT_MAP(SYSINTR_KBD, LOGINTR_KBD);
SETUP_INTERRUPT_MAP(SYSINTR_EDBG, LOGINTR_EXTINT1);
SETUP_INTERRUPT_MAP(SYSINTR_MPGE, LOGINTR_MP4E);
SETUP_INTERRUPT_MAP(SYSINTR_MPGD, LOGINTR_MP4D);
SETUP_INTERRUPT_MAP(SYSINTR_VIA, LOGINTR_VIA);
SETUP_INTERRUPT_MAP(SYSINTR_CF, LOGINTR_CF);
SETUP_INTERRUPT_MAP(SYSINTR_SCI, LOGINTR_SCI);
SETUP_INTERRUPT_MAP(SYSINTR_SD0, LOGINTR_SD0);
SETUP_INTERRUPT_MAP(SYSINTR_USB, LOGINTR_USB);
SETUP_INTERRUPT_MAP(SYSINTR_DMA2, LOGINTR_DMA23);
SETUP_INTERRUPT_MAP(SYSINTR_TOUCH, LOGINTR_UART2);
SETUP_INTERRUPT_MAP(SYSINTR_TIMER0, LOGINTR_TIMER0);
// Force the OS Timer to be enabled (at the VIC)
pVic->IntEnable = 1 << (IRQ_VIC_TIMER0 - IRQ_VIC_MIN);
pVic->IntEnable = 1 << (IRQ_VIC_GPIO2 - IRQ_VIC_MIN);
}
DWORD OEMTranslateIrq(DWORD Irq)
{
if (Irq < LOGINTR_MIN || Irq > LOGINTR_MAX)
{
return SYSINTR_UNDEFINED;
}
else
{
return Logic2SysIntr[Irq];
}
}
DWORD OEMTranslateSysIntr(DWORD SysIntr)
{
if (SysIntr < SYSINTR_FIRMWARE || SysIntr >= SYSINTR_MAXIMUM)
{
return LOGINTR_UNDEFINED;
}
else
{
return SysIntr2Logic[SysIntr];
}
}
DWORD OEMRequestSysIntr(DWORD Irq)
{
DWORD SysIntr;
/* Is this a valid interrupt source? */
if (Irq < LOGINTR_MIN || Irq > LOGINTR_MAX)
{
return SYSINTR_UNDEFINED;
}
EnterCriticalSection(&csRequestSysIntr);
for(SysIntr = SYSINTR_DYNAMIC; SysIntr < SYSINTR_MAXIMUM; SysIntr++)
if( SysIntr2Logic[SysIntr] == LOGINTR_UNDEFINED ) break;
/* No free SYSINTRs left */
if(SysIntr >= SYSINTR_MAXIMUM )
{
DEBUGMSG(1,(TEXT("OEMRequestSysIntr failed, no free SYSINTRs available.\r\n")));
LeaveCriticalSection(&csRequestSysIntr);
return SYSINTR_UNDEFINED;
}
/* Make SYSINTR -> Irq association NOTE: This architecture supports
* multiple SYSINTR mapped to a single IRQ line. This is mainly for
* the DMA to allocate channels at will and not statically map 8
* SYSINTR lines
*/
SysIntr2Logic[SysIntr] = Irq;
// Make Irq -> SYSINTR association, only if not already mapped (multi-mapping allowed)
if (Logic2SysIntr[Irq] == SYSINTR_UNDEFINED)
{
Logic2SysIntr[Irq] = SysIntr;
}
DEBUGMSG(1,(TEXT("OEMRequestSysIntr success 0x%x = sysintr 0x%x\r\n"),Irq,SysIntr));
LeaveCriticalSection(&csRequestSysIntr);
return SysIntr;
}
DWORD OEMReleaseSysIntr(DWORD SysIntr)
{
DWORD Irq;
DEBUGMSG(1, (L"OEMReleaseSysIntr: SysIntr %d -> Irq %d\r\n", SysIntr,
SysIntr2Logic[SysIntr]));
if( SysIntr < SYSINTR_DYNAMIC || SysIntr >= SYSINTR_MAXIMUM ||
(Irq = SysIntr2Logic[SysIntr]) == LOGINTR_UNDEFINED )
{
// SysIntr is invalid
return ERROR_INVALID_PARAMETER;
}
EnterCriticalSection(&csRequestSysIntr);
// Release
SysIntr2Logic[SysIntr] = LOGINTR_UNDEFINED;
// Remove IRQ -> SYSINTR assocation, if there is one
if (Logic2SysIntr[Irq] == SysIntr)
{
Logic2SysIntr[Irq] = SYSINTR_UNDEFINED;
}
LeaveCriticalSection(&csRequestSysIntr);
return ERROR_SUCCESS;
}
BOOL
OEMGetInterrupt(PDEVICE_LOCATION pDevLoc, PDWORD pIrq)
{
// Currently no support for shared interrupt devices
DEBUGMSG(1, (TEXT("OEMGetInterrupt: Not supported\r\n")) );
return FALSE;
}
#ifndef EXEFLASH
/* Routine to copy the flashed NK image to RAM */
int EverythingRelocate(void)
{
LONG len;
ROMHDR *ptoc;
ULONG pc, *toc, offset, dest;
/*
* First make sure we're running in flash, in
* which case we want to copy everything into
* RAM.
*/
pc = GetPC();
if ((pc <= PHYS_FLASH_BASE) || (pc >= ARMVPB_FLASH_END))
return -1;
/*
* The image has been built to run in RAM
* but is currently stored in flash,
* so we have to calculate the pTOC's address
* relative to the flash address.
*/
offset = NK_FLASH_BASE - ((ULONG)(&pTOC) & 0xffff0000);
toc = (ULONG *)((LONG)(&pTOC) + offset);
ptoc = (ROMHDR *)((LONG)(*toc) + offset);
if( ptoc == (ROMHDR *)-1 )
{
lpWriteDebugStringFunc(TEXT("No TOC found!\r\n"));
while( 1 )
{
/* Spin Forever */ ;
}
}
len = (ptoc->physlast - ptoc->physfirst);
/*
* Convert the start address from a Virtual to a Physical
* address as the MMU is not on yet.
*/
dest = ptoc->physfirst - VA_RAM_BASE + PHYS_RAM_BASE;
memcpy((void *)dest, (void *)NK_FLASH_BASE, len);
/*
* Return new memory location, but skip image header
*/
return (dest + IMAGE_HEADER_SIZE);
}
#endif /* not EXEFLASH */
int SharedGPIOControl( int num , int pin , GPIOControlCode controlcode , int*value )
{
static volatile unsigned int base[] = { VA_GPIO0_BASE , VA_GPIO1_BASE , VA_GPIO2_BASE ,
VA_GPIO3_BASE , VA_GPIO4_BASE , VA_GPIO5_BASE ,
VA_GPIO6_BASE , VA_GPIO7_BASE , VA_GPIO8_BASE ,
};
if( num < 8 && num >=0 && pin < 8 && pin >= 0 )
{
unsigned int Base = base[num];
unsigned char bitmask = 1<<pin;
switch( controlcode )
{
case GPIO_Read :
{
if( value )
{
*(volatile int*)(Base + GPIODIR ) &= ~bitmask;
*value = *(volatile int*)(Base + bitmask*4 );
}
}
break;
case GPIO_Write :
{
if( value )
{
*(volatile int*)(Base + GPIODIR ) = bitmask;
if( *value )
*(volatile int*)(Base + bitmask*4 ) = bitmask ;
else
*(volatile int*)(Base + bitmask*4 ) = 0 ;
}
}
break;
case GPIO_IntRead :
{
if( value )
*value = ( *(volatile int*)(Base + GPIORIS) & bitmask );
}
break;
case GPIO_IntClear :
{
*(volatile int*)(Base + GPIOIC ) = bitmask;
}
break;
case GPIO_IntEnable :
{
if( value )
{
if( *value )
*(volatile int*)(Base + GPIOIE ) |= bitmask;
else
*(volatile int*)(Base + GPIOIE ) &= ~bitmask;
}
}
break;
case GPIO_IntType :
{
switch( *value )
{
case 0x00: // __
{
*(volatile int*)(Base + GPIOIBE ) &= ~bitmask;
*(volatile int*)(Base + GPIOIS ) |= bitmask;
*(volatile int*)(Base + GPIOIEV ) &= ~bitmask;
}
break;
case 0x03: // --
{
*(volatile int*)(Base + GPIOIBE ) &= ~bitmask;
*(volatile int*)(Base + GPIOIS ) |= bitmask;
*(volatile int*)(Base + GPIOIEV ) |= bitmask;
}
break;
case 0x01: // _-
{
*(volatile int*)(Base + GPIOIBE ) &= ~bitmask;
*(volatile int*)(Base + GPIOIS ) &= ~bitmask;
*(volatile int*)(Base + GPIOIEV ) |= bitmask;
}
break;
case 0x02: // -_
{
*(volatile int*)(Base + GPIOIBE ) &= ~bitmask;
*(volatile int*)(Base + GPIOIS ) &= ~bitmask;
*(volatile int*)(Base + GPIOIEV ) &= ~bitmask;
}
break;
case 0x06: // _--_
{
*(volatile int*)(Base + GPIOIBE ) |= bitmask;
*(volatile int*)(Base + GPIOIS ) &= ~bitmask;
}
break;
}
}
break;
}
return 1;
}
return 0;
}
/* EOF cfw_platform.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -