//--------------------------------------------------------------------------------- void irqClearAUX(u32 mask) { //--------------------------------------------------------------------------------- int oldIME = enterCriticalSection(); __irqClear(mask,irqTableAUX); irqDisable( mask); leaveCriticalSection(oldIME); }
void timerISR() { // Hide the color sequence of the upper screen after 2 seconds (call to // hideColorSequence()) and disable the timer timer_ticks++; if(timer_ticks == 20) { hideColorSequence(); irqDisable(IRQ_TIMER0); timer_ticks = 0; } }
int RegisterInterrupt(int nIRQ, FN_INTERRUPT_HANDLER pfnHandler, void *pParam) { if(nIRQ<0 || nIRQ>71) return -1; irqDisable(); { g_VectorTable[nIRQ].pfnHandler = pfnHandler; g_VectorTable[nIRQ].pParam = pParam; } irqEnable(); return 0; }
/*----------------------------------------------------------------------------*/ static void interruptHandler(void *object) { static const uint32_t hostErrors = INT_FRUN | INT_HLE; static const uint32_t integrityErrors = INT_RE | INT_RCRC | INT_DCRC | INT_SBE | INT_EBE; static const uint32_t timeoutErrors = INT_RTO | INT_DRTO | INT_HTO; struct Sdmmc * const interface = object; LPC_SDMMC_Type * const reg = interface->base.reg; const uint32_t status = reg->MINTSTS; interruptDisable(interface->finalizer); irqDisable(interface->base.irq); reg->INTMASK = 0; reg->RINTSTS = INT_MASK; if (status & hostErrors) { interface->status = E_ERROR; } else if (status & integrityErrors) { interface->status = E_INTERFACE; } else if (status & timeoutErrors) { interface->status = E_TIMEOUT; } else if (!(reg->STATUS & STATUS_DATA_BUSY)) { interface->status = E_OK; } else { interruptEnable(interface->finalizer); if (!(reg->STATUS & STATUS_DATA_BUSY)) { interface->status = E_OK; interruptDisable(interface->finalizer); } else interface->status = E_BUSY; } if (interface->status != E_BUSY && interface->callback) interface->callback(interface->callbackArgument); }
/*----------------------------------------------------------------------------*/ static void interruptHandler(void *object, enum Result res) { struct DmaOneShot * const stream = object; STM_DMA_CHANNEL_Type * const reg = stream->base.reg; /* Disable the DMA stream */ reg->CCR = 0; /* Disable the NVIC interrupt */ irqDisable(stream->base.irq); dmaResetInstance(stream->base.number); stream->state = res == E_OK ? STATE_DONE : STATE_ERROR; if (stream->callback) stream->callback(stream->callbackArgument); }
/*----------------------------------------------------------------------------*/ static size_t canWrite(void *object, const void *buffer, size_t length) { assert(length % sizeof(struct CanStandardMessage) == 0); struct Can * const interface = object; const struct CanStandardMessage *current = buffer; const struct CanStandardMessage * const last = (const void *)((uintptr_t)buffer + length); /* Acquire exclusive access to the message queue */ irqDisable(interface->base.irq); if (pointerQueueEmpty(&interface->txQueue)) { LPC_CAN_Type * const reg = interface->base.reg; uint32_t status = reg->SR & SR_TBS_MASK; if (interface->sequence || status == SR_TBS_MASK) { while (current < last && status != 0) { /* One of transmit buffers is empty, write new message into it */ sendMessage(interface, (const struct CanMessage *)current, &status); ++current; /* Stop after sequence restart */ if (!interface->sequence) break; } } } while (current < last && !pointerQueueFull(&interface->txQueue)) { struct CanMessage * const output = pointerArrayBack(&interface->pool); pointerArrayPopBack(&interface->pool); memcpy(output, current, sizeof(*current)); pointerQueuePushBack(&interface->txQueue, output); ++current; } irqEnable(interface->base.irq); return (uintptr_t)current - (uintptr_t)buffer; }
void Smoke(void) { static int lastnote = 255; if(tick==0) { if(notes[row]!=255) { if(row > 0 && notes[row] != 255) stop(lastnote); play(notes[row]); if(notes[row] != 255) lastnote = notes[row]; } row++; } if(row==N_ROWS) { TIMER1_CR = 0; irqDisable(IRQ_TIMER1); } tick++; tick%=TICKS_PER_ROW; }
/*----------------------------------------------------------------------------*/ static void resetQueues(struct Can *interface) { irqDisable(interface->base.irq); while (!pointerQueueEmpty(&interface->txQueue)) { struct CanMessage * const message = pointerQueueFront(&interface->txQueue); pointerQueuePopFront(&interface->txQueue); pointerArrayPushBack(&interface->pool, message); } while (!pointerQueueEmpty(&interface->rxQueue)) { struct CanMessage * const message = pointerQueueFront(&interface->rxQueue); pointerQueuePopFront(&interface->rxQueue); pointerArrayPushBack(&interface->pool, message); } irqEnable(interface->base.irq); }
/***************************** * name: vblankinterrupt * function: to provide a 60fps interruption. It is the most simple way and can save power. * argument: none * description: NTSC for 60fps, PAL for 50fps. Call this function to sync with NES emulation. ******************************/ void vblankinterrupt() { debuginfo[6]++; EMU_VBlank(); irqDisable(IRQ_VCOUNT); //we should disable this... }
/*----------------------------------------------------------------------------*/ static void disableInterrupt(const struct PinInterrupt *interrupt) { irqDisable(calcVector(interrupt->channel)); }
/*----------------------------------------------------------------------------*/ static enum Result canInit(void *object, const void *configBase) { const struct CanConfig * const config = configBase; assert(config); const struct CanBaseConfig baseConfig = { .rx = config->rx, .tx = config->tx, .channel = config->channel }; struct Can * const interface = object; enum Result res; /* Call base class constructor */ if ((res = CanBase->init(object, &baseConfig)) != E_OK) return res; interface->base.handler = interruptHandler; interface->callback = 0; interface->timer = config->timer; interface->mode = MODE_LISTENER; interface->sequence = 0; const size_t poolSize = config->rxBuffers + config->txBuffers; if (!pointerArrayInit(&interface->pool, poolSize)) return E_MEMORY; if (!pointerQueueInit(&interface->rxQueue, config->rxBuffers)) return E_MEMORY; if (!pointerQueueInit(&interface->txQueue, config->txBuffers)) return E_MEMORY; interface->poolBuffer = malloc(sizeof(struct CanStandardMessage) * poolSize); struct CanStandardMessage *message = interface->poolBuffer; for (size_t index = 0; index < poolSize; ++index) { pointerArrayPushBack(&interface->pool, message); ++message; } LPC_CAN_Type * const reg = interface->base.reg; reg->MOD = MOD_RM; /* Reset CAN */ reg->IER = 0; /* Disable Receive Interrupt */ reg->GSR = 0; /* Reset error counter */ interface->rate = config->rate; reg->BTR = calcBusTimings(interface, interface->rate); /* Activate Listen Only mode and enable local priority for transmit buffers */ reg->MOD = MOD_LOM | MOD_TPM; LPC_CANAF->AFMR = AFMR_AccBP; //FIXME #ifdef CONFIG_PLATFORM_NXP_CAN_PM if ((res = pmRegister(powerStateHandler, interface)) != E_OK) return res; #endif /* Enable interrupts on message reception and bus error */ reg->IER = IER_RIE | IER_EPIE | IER_BEIE | IER_TIE_MASK; irqSetPriority(interface->base.irq, config->priority); irqEnable(interface->base.irq); return E_OK; } /*----------------------------------------------------------------------------*/ #ifndef CONFIG_PLATFORM_NXP_CAN_NO_DEINIT static void canDeinit(void *object) { struct Can * const interface = object; LPC_CAN_Type * const reg = interface->base.reg; /* Disable all interrupts */ irqDisable(interface->base.irq); reg->IER = 0; #ifdef CONFIG_PLATFORM_NXP_CAN_PM pmUnregister(interface); #endif pointerQueueDeinit(&interface->txQueue); pointerQueueDeinit(&interface->rxQueue); pointerArrayDeinit(&interface->pool); CanBase->deinit(interface); } #endif /*----------------------------------------------------------------------------*/ static enum Result canSetCallback(void *object, void (*callback)(void *), void *argument) { struct Can * const interface = object; interface->callbackArgument = argument; interface->callback = callback; return E_OK; } /*----------------------------------------------------------------------------*/ static enum Result canGetParam(void *object, enum IfParameter parameter, void *data) { struct Can * const interface = object; switch (parameter) { case IF_AVAILABLE: *(size_t *)data = pointerQueueSize(&interface->rxQueue); return E_OK; case IF_PENDING: *(size_t *)data = pointerQueueSize(&interface->txQueue); return E_OK; case IF_RATE: *(uint32_t *)data = interface->rate; return E_OK; default: return E_INVALID; } } /*----------------------------------------------------------------------------*/ static enum Result canSetParam(void *object, enum IfParameter parameter, const void *data) { struct Can * const interface = object; switch ((enum CanParameter)parameter) { case IF_CAN_ACTIVE: changeMode(interface, MODE_ACTIVE); return E_OK; case IF_CAN_LISTENER: changeMode(interface, MODE_LISTENER); return E_OK; case IF_CAN_LOOPBACK: changeMode(interface, MODE_LOOPBACK); return E_OK; default: break; } switch (parameter) { case IF_RATE: { const uint32_t rate = *(const uint32_t *)data; changeRate(interface, rate); interface->rate = rate; return E_OK; } default: return E_INVALID; } } /*----------------------------------------------------------------------------*/ static size_t canRead(void *object, void *buffer, size_t length) { assert(length % sizeof(struct CanStandardMessage) == 0); struct Can * const interface = object; struct CanStandardMessage *current = buffer; const struct CanStandardMessage * const last = (const void *)((uintptr_t)buffer + length); while (!pointerQueueEmpty(&interface->rxQueue) && current < last) { irqDisable(interface->base.irq); struct CanMessage * const input = pointerQueueFront(&interface->rxQueue); pointerQueuePopFront(&interface->rxQueue); memcpy(current, input, sizeof(*current)); pointerArrayPushBack(&interface->pool, input); irqEnable(interface->base.irq); ++current; } return (uintptr_t)current - (uintptr_t)buffer; }
/*----------------------------------------------------------------------------*/ static enum Result serialInit(void *object, const void *configBase) { const struct SerialConfig * const config = configBase; assert(config); const struct UartBaseConfig baseConfig = { .channel = config->channel, .rx = config->rx, .tx = config->tx }; struct Serial * const interface = object; struct UartRateConfig rateConfig; enum Result res; /* Call base class constructor */ if ((res = UartBase->init(object, &baseConfig)) != E_OK) return res; if ((res = uartCalcRate(object, config->rate, &rateConfig)) != E_OK) return res; interface->base.handler = interruptHandler; interface->callback = 0; interface->rate = config->rate; if (!byteQueueInit(&interface->rxQueue, config->rxLength)) return E_MEMORY; if (!byteQueueInit(&interface->txQueue, config->txLength)) return E_MEMORY; LPC_UART_Type * const reg = interface->base.reg; /* Set 8-bit length */ reg->LCR = LCR_WORD_8BIT; /* Enable FIFO and set RX trigger level */ reg->FCR = (reg->FCR & ~FCR_RX_TRIGGER_MASK) | FCR_ENABLE | FCR_RX_TRIGGER(RX_TRIGGER_LEVEL_8); /* Enable RBR and THRE interrupts */ reg->IER = IER_RBR | IER_THRE; /* Transmitter is enabled by default thus TER register is left untouched */ uartSetParity(object, config->parity); uartSetRate(object, rateConfig); #ifdef CONFIG_PLATFORM_NXP_UART_PM if ((res = pmRegister(powerStateHandler, interface)) != E_OK) return res; #endif irqSetPriority(interface->base.irq, config->priority); irqEnable(interface->base.irq); return E_OK; } /*----------------------------------------------------------------------------*/ #ifndef CONFIG_PLATFORM_NXP_UART_NO_DEINIT static void serialDeinit(void *object) { struct Serial * const interface = object; irqDisable(interface->base.irq); #ifdef CONFIG_PLATFORM_NXP_UART_PM pmUnregister(interface); #endif byteQueueDeinit(&interface->txQueue); byteQueueDeinit(&interface->rxQueue); UartBase->deinit(interface); } #endif /*----------------------------------------------------------------------------*/ static enum Result serialSetCallback(void *object, void (*callback)(void *), void *argument) { struct Serial * const interface = object; interface->callbackArgument = argument; interface->callback = callback; return E_OK; } /*----------------------------------------------------------------------------*/ static enum Result serialGetParam(void *object, enum IfParameter parameter, void *data) { struct Serial * const interface = object; #ifdef CONFIG_PLATFORM_NXP_UART_RC switch ((enum SerialParameter)parameter) { case IF_SERIAL_PARITY: *(uint8_t *)data = (uint8_t)uartGetParity(object); return E_OK; default: break; } #endif switch (parameter) { case IF_AVAILABLE: *(size_t *)data = byteQueueSize(&interface->rxQueue); return E_OK; case IF_PENDING: *(size_t *)data = byteQueueSize(&interface->txQueue); return E_OK; #ifdef CONFIG_PLATFORM_NXP_UART_RC case IF_RATE: *(uint32_t *)data = uartGetRate(object); return E_OK; #endif default: return E_INVALID; } } /*----------------------------------------------------------------------------*/ static enum Result serialSetParam(void *object, enum IfParameter parameter, const void *data) { struct Serial * const interface = object; #ifdef CONFIG_PLATFORM_NXP_UART_RC switch ((enum SerialParameter)parameter) { case IF_SERIAL_PARITY: uartSetParity(object, (enum SerialParity)(*(const uint8_t *)data)); return E_OK; default: break; } switch (parameter) { case IF_RATE: { struct UartRateConfig rateConfig; const enum Result res = uartCalcRate(object, *(const uint32_t *)data, &rateConfig); if (res == E_OK) { interface->rate = *(const uint32_t *)data; uartSetRate(object, rateConfig); } return res; } default: return E_INVALID; } #else (void)interface; (void)parameter; (void)data; return E_INVALID; #endif } /*----------------------------------------------------------------------------*/ static size_t serialRead(void *object, void *buffer, size_t length) { struct Serial * const interface = object; irqDisable(interface->base.irq); const size_t read = byteQueuePopArray(&interface->rxQueue, buffer, length); irqEnable(interface->base.irq); return read; } /*----------------------------------------------------------------------------*/ static size_t serialWrite(void *object, const void *buffer, size_t length) { struct Serial * const interface = object; LPC_UART_Type * const reg = interface->base.reg; const uint8_t *bufferPosition = buffer; size_t written = 0; irqDisable(interface->base.irq); /* Check transmitter state */ if ((reg->LSR & LSR_THRE) && byteQueueEmpty(&interface->txQueue)) { /* Transmitter is idle so fill TX FIFO */ const size_t bytesToWrite = MIN(length, TX_FIFO_SIZE); for (; written < bytesToWrite; ++written) reg->THR = *bufferPosition++; length -= written; } /* Fill TX queue with the rest of data */ if (length) written += byteQueuePushArray(&interface->txQueue, bufferPosition, length); irqEnable(interface->base.irq); return written; }
void _interruptController::enterCriticalSection() { ++ _interruptController::criticalCount; irqDisable( IRQ_VBLANK ); // Enter critical Section }
int DisableInterrupts() { irqDisable(); return 0; }
//--------------------------------------------------------------------------------- int loadNDS(int socket, u32 remote) { //--------------------------------------------------------------------------------- int len; int i=0; ioctl(socket,FIONBIO,&i); len = recvall(socket,__NDSHeader,512,0); if (len != 512) { kprintf("Error reading header.\n"); return 1; } int arm7dest = __NDSHeader->arm7destination; int arm7size = __NDSHeader->arm7binarySize; int arm9dest = __NDSHeader->arm9destination; int arm9size = __NDSHeader->arm9binarySize; volatile int response = 0; if (arm9dest + arm9size > (int)_start) response = 1; if (arm7dest >= 0x02000000 && arm7dest < 0x03000000 && arm7dest + arm7size > (int)_start) response = 2; send(socket,(int *)&response,sizeof(response),0); if(response) return 1; kprintf("Reading arm7 binary: "); if (progressRead(socket,(char *)memUncached((void*)0x02000000),arm7size)) { kprintf("\nReceive error.\n"); return 1; } fifoSendValue32(FIFO_USER_01,1); while(!fifoCheckValue32(FIFO_USER_01)) { swiIntrWait(1,IRQ_FIFO_NOT_EMPTY); } fifoGetValue32(FIFO_USER_01); kprintf("Reading arm9 binary: "); if(progressRead(socket,(char *)arm9dest,arm9size)) { kprintf("\nReceive error.\n"); return 1; } volatile int cmdlen=0; char *cmdline; if (arm9size != 0){ cmdline = (char*)(arm9dest+arm9size); } else { cmdline = (char*)(arm7dest+arm7size); } len = recvall(socket,(char*)&cmdlen,4,0); if (cmdlen) { len = recvall(socket,cmdline,cmdlen,0); __system_argv->argvMagic = ARGV_MAGIC; __system_argv->commandLine = cmdline; __system_argv->length = cmdlen; __system_argv->host = remote; } Wifi_DisableWifi(); DC_FlushAll(); REG_IPC_SYNC = 0; fifoSendValue32(FIFO_USER_01,2); fifoSendValue32(FIFO_USER_01,__NDSHeader->arm9executeAddress); irqDisable(IRQ_ALL); REG_IME = 0; //clear out ARM9 DMA channels for (i=0; i<4; i++) { DMA_CR(i) = 0; DMA_SRC(i) = 0; DMA_DEST(i) = 0; TIMER_CR(i) = 0; TIMER_DATA(i) = 0; } u16 *mainregs = (u16*)0x04000000; u16 *subregs = (u16*)0x04001000; for (i=0; i<43; i++) { mainregs[i] = 0; subregs[i] = 0; } REG_DISPSTAT = 0; dmaFillWords(0, BG_PALETTE, (2*1024)); VRAM_A_CR = 0x80; dmaFillWords(0, VRAM, 128*1024); VRAM_A_CR = 0; VRAM_B_CR = 0; // Don't mess with the ARM7's VRAM // VRAM_C_CR = 0; VRAM_D_CR = 0; VRAM_E_CR = 0; VRAM_F_CR = 0; VRAM_G_CR = 0; VRAM_H_CR = 0; VRAM_I_CR = 0; REG_POWERCNT = 0x820F; //set shared ram to ARM7 WRAM_CR = 0x03; // Return to passme loop *((vu32*)0x02FFFE04) = (u32)0xE59FF018; // ldr pc, 0x02FFFE24 *((vu32*)0x02FFFE24) = (u32)0x02FFFE04; // Set ARM9 Loop address REG_IPC_SYNC = 0x500; arm9Reset(); while(1); }
/*----------------------------------------------------------------------------*/ static void interruptHandler(void *object) { struct I2c * const interface = object; LPC_I2C_Type * const reg = interface->base.reg; bool clearInterrupt = true; bool event = false; switch (reg->STAT) { /* Start or Repeated Start conditions have been transmitted */ case STATUS_START_TRANSMITTED: case STATUS_RESTART_TRANSMITTED: if (interface->state == STATE_ADDRESS) { reg->DAT = (interface->txLeft ? DATA_WRITE : DATA_READ) | (interface->address << 1); } reg->CONCLR = CONCLR_STAC; break; /* Slave address and write bit have been transmitted, ACK received */ case STATUS_SLAVE_WRITE_ACK: --interface->txLeft; reg->DAT = *interface->txBuffer++; interface->state = STATE_TRANSMIT; break; /* Slave address and read bit have been transmitted, ACK received */ case STATUS_SLAVE_READ_ACK: if (interface->rxLeft > 1) reg->CONSET = CONSET_AA; /* Assert ACK after data is received */ else reg->CONCLR = CONCLR_AAC; /* Assert NACK after data is received */ interface->state = STATE_RECEIVE; break; /* Data byte has been transmitted, ACK received */ case STATUS_DATA_TRANSMITTED_ACK: if (interface->state != STATE_TRANSMIT) break; /* Send next byte or stop transmission */ if (interface->txLeft) { reg->DAT = *interface->txBuffer++; --interface->txLeft; } else { if (interface->sendStopBit) reg->CONSET = CONSET_STO; else clearInterrupt = false; interface->state = STATE_IDLE; event = true; } break; /* Data has been received and ACK has been returned */ case STATUS_DATA_RECEIVED_ACK: --interface->rxLeft; *interface->rxBuffer++ = reg->DAT; if (interface->rxLeft > 1) reg->CONSET = CONSET_AA; else reg->CONCLR = CONCLR_AAC; break; /* Last byte of data has been received and NACK has been returned */ case STATUS_DATA_RECEIVED_NACK: if (interface->state != STATE_RECEIVE) break; --interface->rxLeft; *interface->rxBuffer++ = reg->DAT; reg->CONSET = CONSET_STO; interface->state = STATE_IDLE; event = true; break; /* Arbitration has been lost during transmission or reception */ case STATUS_ARBITRATION_LOST: /* Data byte has been transmitted, NACK received */ case STATUS_DATA_TRANSMITTED_NACK: /* Address and direction bit have not been acknowledged */ case STATUS_SLAVE_WRITE_NACK: case STATUS_SLAVE_READ_NACK: reg->CONSET = CONSET_STO; interface->state = STATE_ERROR; event = true; break; default: break; } if (clearInterrupt) reg->CONCLR = CONCLR_SIC; if (interface->state == STATE_IDLE || interface->state == STATE_ERROR) irqDisable(interface->base.irq); if (interface->callback && event) interface->callback(interface->callbackArgument); }
/*----------------------------------------------------------------------------*/ static enum result spiInit(void *object, const void *configBase) { const struct SpiConfig * const config = configBase; const struct SspBaseConfig baseConfig = { .channel = config->channel, .miso = config->miso, .mosi = config->mosi, .sck = config->sck, .cs = 0 }; struct Spi * const interface = object; enum result res; /* Call base class constructor */ if ((res = SspBase->init(object, &baseConfig)) != E_OK) return res; interface->base.handler = interruptHandler; interface->callback = 0; interface->rate = config->rate; interface->blocking = true; LPC_SSP_Type * const reg = interface->base.reg; uint32_t controlValue = 0; /* Set frame size */ controlValue |= CR0_DSS(8); /* Set mode for the interface */ if (config->mode & 0x01) controlValue |= CR0_CPHA; if (config->mode & 0x02) controlValue |= CR0_CPOL; reg->CR0 = controlValue; /* Disable all interrupts */ reg->IMSC = 0; /* Try to set the desired data rate */ sspSetRate(object, interface->rate); #ifdef CONFIG_SSP_PM if ((res = pmRegister(interface, powerStateHandler)) != E_OK) return res; #endif /* Enable the peripheral */ reg->CR1 = CR1_SSE; irqSetPriority(interface->base.irq, config->priority); irqEnable(interface->base.irq); return E_OK; } /*----------------------------------------------------------------------------*/ static void spiDeinit(void *object) { struct Spi * const interface = object; LPC_SSP_Type * const reg = interface->base.reg; /* Disable the peripheral */ irqDisable(interface->base.irq); reg->CR1 = 0; #ifdef CONFIG_SSP_PM pmUnregister(interface); #endif SspBase->deinit(interface); } /*----------------------------------------------------------------------------*/ static enum result spiCallback(void *object, void (*callback)(void *), void *argument) { struct Spi * const interface = object; interface->callbackArgument = argument; interface->callback = callback; return E_OK; } /*----------------------------------------------------------------------------*/ static enum result spiGet(void *object, enum ifOption option, void *data) { struct Spi * const interface = object; LPC_SSP_Type * const reg = interface->base.reg; switch (option) { case IF_RATE: *(uint32_t *)data = interface->rate; return E_OK; case IF_STATUS: return (interface->rxLeft || reg->SR & SR_BSY) ? E_BUSY : E_OK; default: return E_INVALID; } } /*----------------------------------------------------------------------------*/ static enum result spiSet(void *object, enum ifOption option, const void *data) { struct Spi * const interface = object; switch (option) { case IF_BLOCKING: interface->blocking = true; return E_OK; case IF_RATE: interface->rate = *(const uint32_t *)data; sspSetRate(object, interface->rate); return E_OK; case IF_ZEROCOPY: interface->blocking = false; return E_OK; default: return E_INVALID; } } /*----------------------------------------------------------------------------*/ static size_t spiRead(void *object, void *buffer, size_t length) { struct Spi * const interface = object; LPC_SSP_Type * const reg = interface->base.reg; if (!length) return 0; interface->rxBuffer = buffer; interface->txBuffer = 0; interface->rxLeft = interface->txLeft = length; /* Clear interrupt flags and enable interrupts */ reg->ICR = ICR_RORIC | ICR_RTIC; reg->IMSC = IMSC_RXIM | IMSC_RTIM; /* Initiate reception by setting pending interrupt flag */ irqSetPending(interface->base.irq); if (interface->blocking) { while (interface->rxLeft || reg->SR & SR_BSY) barrier(); } return length; } /*----------------------------------------------------------------------------*/ static size_t spiWrite(void *object, const void *buffer, size_t length) { struct Spi * const interface = object; LPC_SSP_Type * const reg = interface->base.reg; if (!length) return 0; interface->rxBuffer = 0; interface->txBuffer = buffer; interface->rxLeft = interface->txLeft = length; /* Clear interrupt flags and enable interrupts */ reg->ICR = ICR_RORIC | ICR_RTIC; reg->IMSC = IMSC_RXIM | IMSC_RTIM; /* Initiate transmission by setting pending interrupt flag */ irqSetPending(interface->base.irq); if (interface->blocking) { while (interface->rxLeft || reg->SR & SR_BSY) barrier(); } return length; }
/*-------------------------------------------------------------------------------*/ void cardSpiDisable() { /*-------------------------------------------------------------------------------*/ card_spi_settings.enable_irq = 0; irqDisable(IRQ_CARD_LINE); cardSpiStop(); /* update CR1 register */ }
int runNds (const void* loader, u32 loaderSize, u32 cluster, bool initDisc, bool dldiPatchNds, int argc, const char** argv) { char* argStart; u16* argData; u16 argTempVal = 0; int argSize; const char* argChar; irqDisable(IRQ_ALL); // Direct CPU access to VRAM bank C VRAM_C_CR = VRAM_ENABLE | VRAM_C_LCD; // Load the loader/patcher into the correct address vramcpy (LCDC_BANK_C, loader, loaderSize); // Set the parameters for the loader // STORED_FILE_CLUSTER = cluster; writeAddr ((data_t*) LCDC_BANK_C, STORED_FILE_CLUSTER_OFFSET, cluster); // INIT_DISC = initDisc; writeAddr ((data_t*) LCDC_BANK_C, INIT_DISC_OFFSET, initDisc); // WANT_TO_PATCH_DLDI = dldiPatchNds; writeAddr ((data_t*) LCDC_BANK_C, WANT_TO_PATCH_DLDI_OFFSET, dldiPatchNds); // Give arguments to loader argStart = (char*)LCDC_BANK_C + readAddr((data_t*)LCDC_BANK_C, ARG_START_OFFSET); argStart = (char*)(((int)argStart + 3) & ~3); // Align to word argData = (u16*)argStart; argSize = 0; for (; argc > 0 && *argv; ++argv, --argc) { for (argChar = *argv; *argChar != 0; ++argChar, ++argSize) { if (argSize & 1) { argTempVal |= (*argChar) << 8; *argData = argTempVal; ++argData; } else { argTempVal = *argChar; } } if (argSize & 1) { *argData = argTempVal; ++argData; } argTempVal = 0; ++argSize; } *argData = argTempVal; writeAddr ((data_t*) LCDC_BANK_C, ARG_START_OFFSET, (addr_t)argStart - (addr_t)LCDC_BANK_C); writeAddr ((data_t*) LCDC_BANK_C, ARG_SIZE_OFFSET, argSize); // Patch the loader with a DLDI for the card if (!dldiPatchLoader ((data_t*)LCDC_BANK_C, loaderSize, initDisc)) { return 3; } irqDisable(IRQ_ALL); // Give the VRAM to the ARM7 VRAM_C_CR = VRAM_ENABLE | VRAM_C_ARM7_0x06000000; // Reset into a passme loop REG_EXMEMCNT |= ARM7_OWNS_ROM | ARM7_OWNS_CARD; *((vu32*)0x027FFFFC) = 0; *((vu32*)0x027FFE04) = (u32)0xE59FF018; *((vu32*)0x027FFE24) = (u32)0x027FFE04; swiSoftReset(); return true; }
/*----------------------------------------------------------------------------*/ static enum result tmrInit(void *object, const void *configBase) { const struct GpTimerConfig * const config = configBase; const struct GpTimerBaseConfig baseConfig = { .channel = config->channel }; struct GpTimer * const timer = object; enum result res; assert(config->event < GPTIMER_EVENT_END); timer->event = config->event ? config->event : GPTIMER_MATCH0; --timer->event; /* Call base class constructor */ if ((res = GpTimerBase->init(object, &baseConfig)) != E_OK) return res; timer->base.handler = interruptHandler; timer->callback = 0; /* Initialize peripheral block */ LPC_TIMER_Type * const reg = timer->base.reg; reg->TCR = TCR_CRES; reg->IR = reg->IR; /* Clear pending interrupts */ reg->CCR = 0; reg->CTCR = 0; reg->MCR = 0; updateFrequency(timer, config->frequency); /* Configure prescaler and default match value */ reg->MR[timer->event] = getMaxValue(timer); /* Enable external match to generate signals to other peripherals */ reg->EMR = EMR_CONTROL(timer->event, CONTROL_TOGGLE); #ifdef CONFIG_GPTIMER_PM if ((res = pmRegister(interface, powerStateHandler)) != E_OK) return res; #endif /* Timer is disabled by default */ reg->TCR = 0; irqSetPriority(timer->base.irq, config->priority); irqEnable(timer->base.irq); return E_OK; } /*----------------------------------------------------------------------------*/ static void tmrDeinit(void *object) { struct GpTimer * const timer = object; LPC_TIMER_Type * const reg = timer->base.reg; irqDisable(timer->base.irq); reg->TCR = 0; #ifdef CONFIG_GPTIMER_PM pmUnregister(interface); #endif GpTimerBase->deinit(timer); } /*----------------------------------------------------------------------------*/ static void tmrCallback(void *object, void (*callback)(void *), void *argument) { struct GpTimer * const timer = object; LPC_TIMER_Type * const reg = timer->base.reg; timer->callbackArgument = argument; timer->callback = callback; if (callback) { reg->IR = reg->IR; reg->MCR |= MCR_INTERRUPT(timer->event); } else reg->MCR &= ~MCR_INTERRUPT(timer->event); } /*----------------------------------------------------------------------------*/ static void tmrSetEnabled(void *object, bool state) { struct GpTimer * const timer = object; LPC_TIMER_Type * const reg = timer->base.reg; /* Stop the timer */ reg->TCR = 0; /* Clear pending interrupt flags and direct memory access requests */ reg->IR = IR_MATCH_INTERRUPT(timer->event); if (state) { /* Clear match value to avoid undefined output level */ reg->EMR &= ~EMR_EXTERNAL_MATCH(timer->event); reg->TCR = TCR_CEN; } } /*----------------------------------------------------------------------------*/ static uint32_t tmrGetFrequency(const void *object) { const struct GpTimer * const timer = object; const LPC_TIMER_Type * const reg = timer->base.reg; const uint32_t baseClock = gpTimerGetClock((const struct GpTimerBase *)timer); return baseClock / (reg->PR + 1); } /*----------------------------------------------------------------------------*/ static void tmrSetFrequency(void *object, uint32_t frequency) { updateFrequency(object, frequency); }
/*----------------------------------------------------------------------------*/ static enum Result tmrInit(void *object, const void *configBase) { const struct GpTimerConfig * const config = configBase; assert(config); const struct GpTimerBaseConfig baseConfig = { .channel = config->channel }; struct GpTimer * const timer = object; enum Result res; assert(config->event < GPTIMER_EVENT_END); /* Call base class constructor */ if ((res = GpTimerBase->init(timer, &baseConfig)) != E_OK) return res; timer->base.handler = interruptHandler; timer->callback = 0; timer->event = (config->event ? config->event : GPTIMER_MATCH0) - 1; /* Initialize peripheral block */ LPC_TIMER_Type * const reg = timer->base.reg; reg->TCR = TCR_CRES; reg->IR = reg->IR; /* Clear pending interrupts */ reg->CCR = 0; reg->CTCR = 0; timer->frequency = config->frequency; gpTimerSetFrequency(&timer->base, timer->frequency); /* Configure prescaler and default match value */ reg->MR[timer->event] = getMaxValue(timer); /* Reset the timer after reaching the match register value */ reg->MCR = MCR_RESET(timer->event); /* Enable external match to generate signals to other peripherals */ reg->EMR = EMR_CONTROL(timer->event, CONTROL_TOGGLE); #ifdef CONFIG_PLATFORM_NXP_GPTIMER_PM if ((res = pmRegister(powerStateHandler, timer)) != E_OK) return res; #endif /* Clear timer reset flag, but do not enable */ reg->TCR = 0; irqSetPriority(timer->base.irq, config->priority); irqEnable(timer->base.irq); return E_OK; } /*----------------------------------------------------------------------------*/ #ifndef CONFIG_PLATFORM_NXP_GPTIMER_NO_DEINIT static void tmrDeinit(void *object) { struct GpTimer * const timer = object; LPC_TIMER_Type * const reg = timer->base.reg; irqDisable(timer->base.irq); reg->TCR = 0; #ifdef CONFIG_PLATFORM_NXP_GPTIMER_PM pmUnregister(timer); #endif GpTimerBase->deinit(timer); } #endif /*----------------------------------------------------------------------------*/ static void tmrEnable(void *object) { struct GpTimer * const timer = object; LPC_TIMER_Type * const reg = timer->base.reg; /* Clear pending interrupt flags and direct memory access requests */ reg->IR = IR_MATCH_INTERRUPT(timer->event); /* Clear match value to avoid undefined output level */ reg->EMR &= ~EMR_EXTERNAL_MATCH(timer->event); /* Start the timer */ reg->TCR = TCR_CEN; } /*----------------------------------------------------------------------------*/ static void tmrDisable(void *object) { struct GpTimer * const timer = object; LPC_TIMER_Type * const reg = timer->base.reg; reg->TCR = 0; } /*----------------------------------------------------------------------------*/ static void tmrSetCallback(void *object, void (*callback)(void *), void *argument) { struct GpTimer * const timer = object; LPC_TIMER_Type * const reg = timer->base.reg; timer->callbackArgument = argument; timer->callback = callback; if (callback) { reg->IR = reg->IR; reg->MCR |= MCR_INTERRUPT(timer->event); } else reg->MCR &= ~MCR_INTERRUPT(timer->event); } /*----------------------------------------------------------------------------*/ static uint32_t tmrGetFrequency(const void *object) { const struct GpTimer * const timer = object; const LPC_TIMER_Type * const reg = timer->base.reg; const uint32_t baseClock = gpTimerGetClock(&timer->base); return baseClock / (reg->PR + 1); } /*----------------------------------------------------------------------------*/ static void tmrSetFrequency(void *object, uint32_t frequency) { struct GpTimer * const timer = object; timer->frequency = frequency; gpTimerSetFrequency(&timer->base, timer->frequency); } /*----------------------------------------------------------------------------*/ static uint32_t tmrGetOverflow(const void *object) { const struct GpTimer * const timer = object; const LPC_TIMER_Type * const reg = timer->base.reg; return (reg->MR[timer->event] + 1) & getMaxValue(timer); } /*----------------------------------------------------------------------------*/ static void tmrSetOverflow(void *object, uint32_t overflow) { struct GpTimer * const timer = object; LPC_TIMER_Type * const reg = timer->base.reg; assert(overflow <= getMaxValue(timer)); reg->MR[timer->event] = overflow - 1; } /*----------------------------------------------------------------------------*/ static uint32_t tmrGetValue(const void *object) { const struct GpTimer * const timer = object; const LPC_TIMER_Type * const reg = timer->base.reg; return reg->TC; } /*----------------------------------------------------------------------------*/ static void tmrSetValue(void *object, uint32_t value) { struct GpTimer * const timer = object; LPC_TIMER_Type * const reg = timer->base.reg; assert(value <= reg->MR[timer->event]); reg->PC = 0; reg->TC = value; }
/*----------------------------------------------------------------------------*/ static enum result i2cInit(void *object, const void *configBase) { const struct I2cSlaveConfig * const config = configBase; const struct I2cBaseConfig baseConfig = { .channel = config->channel, .scl = config->scl, .sda = config->sda }; struct I2cSlave * const interface = object; enum result res; /* Call base class constructor */ if ((res = I2cBase->init(object, &baseConfig)) != E_OK) return res; interface->cache = malloc(config->size); if (!interface->cache) return E_MEMORY; memset(interface->cache, 0, config->size); interface->base.handler = interruptHandler; interface->callback = 0; interface->external = 0; interface->internal = 0; interface->size = config->size; interface->state = STATE_IDLE; LPC_I2C_Type * const reg = interface->base.reg; /* Clear all flags */ reg->CONCLR = CONCLR_AAC | CONCLR_SIC | CONCLR_STAC | CONCLR_I2ENC; #ifdef CONFIG_I2C_PM if ((res = pmRegister(interface, powerStateHandler)) != E_OK) return res; #endif irqSetPriority(interface->base.irq, config->priority); irqEnable(interface->base.irq); /* Enable I2C interface */ reg->CONSET = CONSET_AA | CONSET_I2EN; return E_OK; } /*----------------------------------------------------------------------------*/ static void i2cDeinit(void *object) { struct I2cSlave * const interface = object; LPC_I2C_Type * const reg = interface->base.reg; reg->CONCLR = CONCLR_I2ENC; /* Disable I2C interface */ #ifdef CONFIG_I2C_PM pmUnregister(interface); #endif irqDisable(interface->base.irq); free(interface->cache); I2cBase->deinit(interface); } /*----------------------------------------------------------------------------*/ static enum result i2cCallback(void *object, void (*callback)(void *), void *argument) { struct I2cSlave * const interface = object; interface->callbackArgument = argument; interface->callback = callback; return E_OK; } /*----------------------------------------------------------------------------*/ static enum result i2cGet(void *object, enum ifOption option, void *data) { struct I2cSlave * const interface = object; LPC_I2C_Type * const reg = interface->base.reg; switch (option) { case IF_ADDRESS: *(uint16_t *)data = ADR_ADDRESS_VALUE(reg->ADR0); return E_OK; case IF_POSITION: *(uint32_t *)data = interface->internal; return E_OK; case IF_STATUS: return interface->state != STATE_IDLE ? E_BUSY : E_OK; default: return E_INVALID; } } /*----------------------------------------------------------------------------*/ static enum result i2cSet(void *object, enum ifOption option, const void *data) { struct I2cSlave * const interface = object; LPC_I2C_Type * const reg = interface->base.reg; switch (option) { case IF_ADDRESS: if (*(const uint16_t *)data <= 127) { reg->ADR0 = ADR_ADDRESS(*(const uint16_t *)data); return E_OK; } else return E_VALUE; case IF_POSITION: if (*(const uint32_t *)data < interface->size) { interface->internal = *(const uint32_t *)data; return E_OK; } else return E_VALUE; default: return E_INVALID; } } /*----------------------------------------------------------------------------*/ static size_t i2cRead(void *object, void *buffer, size_t length) { struct I2cSlave * const interface = object; const uint8_t * const position = interface->cache + interface->internal; uint16_t left = interface->size - interface->internal; if (!length) return 0; if (length < left) { left = length; interface->internal += length; } else interface->internal = 0; memcpy(buffer, position, left); return left; } /*----------------------------------------------------------------------------*/ static size_t i2cWrite(void *object, const void *buffer, size_t length) { struct I2cSlave * const interface = object; uint8_t * const position = interface->cache + interface->internal; uint16_t left = interface->size - interface->internal; if (!length) return 0; if (length < left) { left = length; interface->internal += length; } else interface->internal = 0; memcpy(position, buffer, left); return left; }