int main() { uart_init(UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU)); sei(); uart_puts("begin\r\n"); nrfInit(); writeReg(RF_SETUP, SET_RF_SETUP); writeAddr(RX_ADDR_P0, SET_RX_ADDR_P0); writeAddr(TX_ADDR, SET_TX_ADDR); writeReg(DYNPD, SET_DYNPD); writeReg(FEATURE, SET_FEATURE); writeReg(RF_CH, SET_RF_CH); writeReg(CONFIG, SET_CONFIG); startRadio(); uint8_t worked; uint8_t size; char sendbuffer[] = "Testing 1..2..3.. Testing."; size = sizeof (sendbuffer); char receivebuffer[33]; char c; char count[10]; int charbuffer; char payloadlength; // uart_puts(sendbuffer); worked = transmit(sendbuffer, size); if (worked == 1) { uart_puts("Transmit Worked!\r\n"); } else { uart_puts("Transmit Failed.\r\n"); } startRx(); while (1) { payloadlength = dynReceive(receivebuffer); if (payloadlength > 0) { uart_puts("Got something:"); uart_puts(receivebuffer); uart_puts("\r\n"); } else { uart_puts("nothin received\r\n"); } c = uart_getc(); if (!(c & UART_NO_DATA)) { uart_putc(c); } printRegisters(); _delay_ms(2000); } }
static asynStatus gpibPortAddressedCmd(void *pdrvPvt,asynUser *pasynUser, const char *data, int length) { niport *pniport = (niport *)pdrvPvt; double timeout = pasynUser->timeout; int addr = 0; int actual; asynStatus status; char cmdbuf[2] = {IBUNT,IBUNL}; status = pasynManager->getAddr(pasynUser,&addr); if(status!=asynSuccess) return status; asynPrint(pasynUser,ASYN_TRACE_FLOW, "%s addr %d gpibPortAddressedCmd nchar %d\n", pniport->portName,addr,length); pniport->errorMessage[0] = 0; status = writeAddr(pniport,0,addr,timeout,transferStateIdle); if(status==asynSuccess) { status=writeCmd(pniport,data,length,timeout,transferStateIdle); } if(status!=asynSuccess) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s writeGpib failed %s",pniport->portName,pniport->errorMessage); } actual = length - pniport->bytesRemainingCmd; asynPrintIO(pasynUser,ASYN_TRACEIO_DRIVER, data,actual,"%s gpibPortAddressedCmd\n",pniport->portName); if(status!=asynSuccess) return status; writeCmd(pniport,cmdbuf,2,timeout,transferStateIdle); return status; }
asynStatus readGpib(niport *pniport,char *buf, int cnt, int *actual, int addr, double timeout,int *eomReason) { char cmdbuf[2] = {IBUNT,IBUNL}; asynStatus status; epicsUInt8 isr1 = pniport->isr1; *actual=0; *buf=0; pniport->bytesRemainingRead = cnt; pniport->nextByteRead = buf; pniport->eomReason = 0; if(isr1&DI) { pniport->bytesRemainingRead--; pniport->nextByteRead++; buf[0] = readRegister(pniport,DIR); } writeRegister(pniport,AUXMR,AUXFH); pniport->status = asynSuccess; status = writeAddr(pniport,addr,0,timeout,transferStateRead); if(status!=asynSuccess) return status; *actual = cnt - pniport->bytesRemainingRead; if(eomReason) *eomReason = pniport->eomReason; writeCmd(pniport,cmdbuf,2,timeout,transferStateIdle); return status; }
uint8_t MMA7455::readReg(uint8_t addr) { startOperation(_READ); //say this is a read operation writeAddr(addr); //send the address to be read port &= ~clk; //tick the clock down ddr &= ~sdio; //set SDIO as input port &= ~sdio; //set SDIO to 0 port |= clk; //tick the clock high //read the register byte result = 0; for(byte a = 0x80; a; a >>= 1) { port &= ~clk; port |= clk; if (pin & sdio) result |= a; } //reset pins to good state port &= ~(clk | sdio); ddr |= sdio; port |= cs; return result; }
static asynStatus gpibPortSerialPoll(void *pdrvPvt, int addr, double timeout,int *statusByte) { niport *pniport = (niport *)pdrvPvt; char buffer[1]; buffer[0] = 0; pniport->bytesRemainingRead = 1; pniport->nextByteRead = buffer; pniport->status = asynSuccess; writeRegister(pniport,AUXMR,AUXFH); writeAddr(pniport,addr,-1,timeout,transferStateRead); *statusByte = buffer[0]; return asynSuccess; }
static asynStatus writeGpib(niport *pniport,const char *buf, int cnt, int *actual, int addr, double timeout) { char cmdbuf[2] = {IBUNT,IBUNL}; asynStatus status; *actual=0; pniport->bytesRemainingWrite = cnt; pniport->nextByteWrite = buf; pniport->status = asynSuccess; status = writeAddr(pniport,0,addr,timeout,transferStateWrite); if(status!=asynSuccess) return status; *actual = cnt - pniport->bytesRemainingWrite; status = pniport->status; if(status!=asynSuccess) return status; writeCmd(pniport,cmdbuf,2,timeout,transferStateIdle); return status; }
void MMA7455::writeReg(uint8_t addr, byte val) { //say this is a write operation startOperation(_WRITE); //send the address of the register writeAddr(addr); //do nothin bit port &= ~clk; port |= clk; //send the value to the register for(byte a = 0x80; a; a >>= 1) { port &= ~clk; if (val & a) port |= sdio; else port &= ~sdio; port |= clk; } port &= ~(clk | sdio); port |= cs; }
bool tryPatch(void *data, size_t size) { // Find the DSDI reserved space in the file addr_t patchOffset = quickFind(static_cast<data_t *>(data), dldiMagicString, size, sizeof(dldiMagicString) / sizeof(char)); // no DLDI section if (patchOffset < 0) return false; data_t *pDH = mpcf_dldi; data_t *pAH = static_cast<data_t *>(data) + patchOffset; if (pDH[DO_driverSize] > pAH[DO_allocatedSpace]) { printf("Not enough space for patch. Available %d bytes, need %d bytes\n", 1 << pAH[DO_allocatedSpace], 1 << pDH[DO_driverSize]); return false; } if (memcmp(&pAH[DO_friendlyName], "Default (No interface)", 22)) { printf("Would have been a candidate for auto-patch DLDI, but there was already a patch installed."); return false; } //----should be able to patch OK----- addr_t memOffset; // Offset of DLDI after the file is loaded into memory addr_t relocationOffset; // Value added to all offsets within the patch to fix it properly addr_t ddmemOffset; // Original offset used in the DLDI file addr_t ddmemStart; // Start of range that offsets can be in the DLDI file addr_t ddmemEnd; // End of range that offsets can be in the DLDI file addr_t ddmemSize; // Size of range that offsets can be in the DLDI file addr_t addrIter; memOffset = readAddr(pAH, DO_text_start); if (!memOffset) memOffset = readAddr(pAH, DO_startup) - DO_code; ddmemOffset = readAddr(pDH, DO_text_start); relocationOffset = memOffset - ddmemOffset; printf("AUTO-PATCHING DLDI to MPCF! Lucky you!\n\n"); printf("Old driver: %s\n", &pAH[DO_friendlyName]); printf("New driver: %s\n", &pDH[DO_friendlyName]); printf("\n"); printf("Position in file: 0x%08X\n", patchOffset); printf("Position in memory: 0x%08X\n", memOffset); printf("Patch base address: 0x%08X\n", ddmemOffset); printf("Relocation offset: 0x%08X\n", relocationOffset); printf("\n"); ddmemStart = readAddr(pDH, DO_text_start); ddmemSize = 1 << pDH[DO_driverSize]; ddmemEnd = ddmemStart + ddmemSize; // Remember how much space is actually reserved pDH[DO_allocatedSpace] = pAH[DO_allocatedSpace]; // Copy the DLDI patch into the application memcpy(pAH, pDH, sizeof(mpcf_dldi)); // Fix the section pointers in the header writeAddr(pAH, DO_text_start, readAddr(pAH, DO_text_start) + relocationOffset); writeAddr(pAH, DO_data_end, readAddr(pAH, DO_data_end) + relocationOffset); writeAddr(pAH, DO_glue_start, readAddr(pAH, DO_glue_start) + relocationOffset); writeAddr(pAH, DO_glue_end, readAddr(pAH, DO_glue_end) + relocationOffset); writeAddr(pAH, DO_got_start, readAddr(pAH, DO_got_start) + relocationOffset); writeAddr(pAH, DO_got_end, readAddr(pAH, DO_got_end) + relocationOffset); writeAddr(pAH, DO_bss_start, readAddr(pAH, DO_bss_start) + relocationOffset); writeAddr(pAH, DO_bss_end, readAddr(pAH, DO_bss_end) + relocationOffset); // Fix the function pointers in the header writeAddr(pAH, DO_startup, readAddr(pAH, DO_startup) + relocationOffset); writeAddr(pAH, DO_isInserted, readAddr(pAH, DO_isInserted) + relocationOffset); writeAddr(pAH, DO_readSectors, readAddr(pAH, DO_readSectors) + relocationOffset); writeAddr(pAH, DO_writeSectors, readAddr(pAH, DO_writeSectors) + relocationOffset); writeAddr(pAH, DO_clearStatus, readAddr(pAH, DO_clearStatus) + relocationOffset); writeAddr(pAH, DO_shutdown, readAddr(pAH, DO_shutdown) + relocationOffset); if (pDH[DO_fixSections] & FIX_ALL) // Search through and fix pointers within the data section of the file for (addrIter = readAddr(pDH, DO_text_start) - ddmemStart; addrIter < readAddr(pDH, DO_data_end) - ddmemStart; ++addrIter) if (ddmemStart <= readAddr(pAH, addrIter) && readAddr(pAH, addrIter) < ddmemEnd) writeAddr(pAH, addrIter, readAddr(pAH, addrIter) + relocationOffset); if (pDH[DO_fixSections] & FIX_GLUE) // Search through and fix pointers within the glue section of the file for (addrIter = readAddr(pDH, DO_glue_start) - ddmemStart; addrIter < readAddr(pDH, DO_glue_end) - ddmemStart; ++addrIter) if (ddmemStart <= readAddr(pAH, addrIter) && readAddr(pAH, addrIter) < ddmemEnd) writeAddr(pAH, addrIter, readAddr(pAH, addrIter) + relocationOffset); if (pDH[DO_fixSections] & FIX_GOT) // Search through and fix pointers within the Global Offset Table section of the file for (addrIter = readAddr(pDH, DO_got_start) - ddmemStart; addrIter < readAddr(pDH, DO_got_end) - ddmemStart; ++addrIter) if (ddmemStart <= readAddr(pAH, addrIter) && readAddr(pAH, addrIter) < ddmemEnd) writeAddr(pAH, addrIter, readAddr(pAH, addrIter) + relocationOffset); if (pDH[DO_fixSections] & FIX_BSS) // Initialise the BSS to 0 memset(&pAH[readAddr(pDH, DO_bss_start) - ddmemStart] , 0, readAddr(pDH, DO_bss_end) - readAddr(pDH, DO_bss_start)); return true; }
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 bool dldiPatchLoader (data_t *binData, u32 binSize, bool clearBSS) { addr_t memOffset; // Offset of DLDI after the file is loaded into memory addr_t patchOffset; // Position of patch destination in the file addr_t relocationOffset; // Value added to all offsets within the patch to fix it properly addr_t ddmemOffset; // Original offset used in the DLDI file addr_t ddmemStart; // Start of range that offsets can be in the DLDI file addr_t ddmemEnd; // End of range that offsets can be in the DLDI file addr_t ddmemSize; // Size of range that offsets can be in the DLDI file addr_t addrIter; data_t *pDH; data_t *pAH; size_t dldiFileSize = 0; // Find the DLDI reserved space in the file patchOffset = quickFind (binData, dldiMagicLoaderString, binSize, sizeof(dldiMagicLoaderString)); if (patchOffset < 0) { // does not have a DLDI section return false; } pDH = (data_t*)(io_dldi_data); pAH = &(binData[patchOffset]); if (*((u32*)(pDH + DO_ioType)) == DEVICE_TYPE_DLDI) { // No DLDI patch return false; } if (pDH[DO_driverSize] > pAH[DO_allocatedSpace]) { // Not enough space for patch return false; } dldiFileSize = 1 << pDH[DO_driverSize]; memOffset = readAddr (pAH, DO_text_start); if (memOffset == 0) { memOffset = readAddr (pAH, DO_startup) - DO_code; } ddmemOffset = readAddr (pDH, DO_text_start); relocationOffset = memOffset - ddmemOffset; ddmemStart = readAddr (pDH, DO_text_start); ddmemSize = (1 << pDH[DO_driverSize]); ddmemEnd = ddmemStart + ddmemSize; // Remember how much space is actually reserved pDH[DO_allocatedSpace] = pAH[DO_allocatedSpace]; // Copy the DLDI patch into the application vramcpy (pAH, pDH, dldiFileSize); // Fix the section pointers in the header writeAddr (pAH, DO_text_start, readAddr (pAH, DO_text_start) + relocationOffset); writeAddr (pAH, DO_data_end, readAddr (pAH, DO_data_end) + relocationOffset); writeAddr (pAH, DO_glue_start, readAddr (pAH, DO_glue_start) + relocationOffset); writeAddr (pAH, DO_glue_end, readAddr (pAH, DO_glue_end) + relocationOffset); writeAddr (pAH, DO_got_start, readAddr (pAH, DO_got_start) + relocationOffset); writeAddr (pAH, DO_got_end, readAddr (pAH, DO_got_end) + relocationOffset); writeAddr (pAH, DO_bss_start, readAddr (pAH, DO_bss_start) + relocationOffset); writeAddr (pAH, DO_bss_end, readAddr (pAH, DO_bss_end) + relocationOffset); // Fix the function pointers in the header writeAddr (pAH, DO_startup, readAddr (pAH, DO_startup) + relocationOffset); writeAddr (pAH, DO_isInserted, readAddr (pAH, DO_isInserted) + relocationOffset); writeAddr (pAH, DO_readSectors, readAddr (pAH, DO_readSectors) + relocationOffset); writeAddr (pAH, DO_writeSectors, readAddr (pAH, DO_writeSectors) + relocationOffset); writeAddr (pAH, DO_clearStatus, readAddr (pAH, DO_clearStatus) + relocationOffset); writeAddr (pAH, DO_shutdown, readAddr (pAH, DO_shutdown) + relocationOffset); if (pDH[DO_fixSections] & FIX_ALL) { // Search through and fix pointers within the data section of the file for (addrIter = (readAddr(pDH, DO_text_start) - ddmemStart); addrIter < (readAddr(pDH, DO_data_end) - ddmemStart); addrIter++) { if ((ddmemStart <= readAddr(pAH, addrIter)) && (readAddr(pAH, addrIter) < ddmemEnd)) { writeAddr (pAH, addrIter, readAddr(pAH, addrIter) + relocationOffset); } } } if (pDH[DO_fixSections] & FIX_GLUE) { // Search through and fix pointers within the glue section of the file for (addrIter = (readAddr(pDH, DO_glue_start) - ddmemStart); addrIter < (readAddr(pDH, DO_glue_end) - ddmemStart); addrIter++) { if ((ddmemStart <= readAddr(pAH, addrIter)) && (readAddr(pAH, addrIter) < ddmemEnd)) { writeAddr (pAH, addrIter, readAddr(pAH, addrIter) + relocationOffset); } } } if (pDH[DO_fixSections] & FIX_GOT) { // Search through and fix pointers within the Global Offset Table section of the file for (addrIter = (readAddr(pDH, DO_got_start) - ddmemStart); addrIter < (readAddr(pDH, DO_got_end) - ddmemStart); addrIter++) { if ((ddmemStart <= readAddr(pAH, addrIter)) && (readAddr(pAH, addrIter) < ddmemEnd)) { writeAddr (pAH, addrIter, readAddr(pAH, addrIter) + relocationOffset); } } } if (clearBSS && (pDH[DO_fixSections] & FIX_BSS)) { // Initialise the BSS to 0, only if the disc is being re-inited memset (&pAH[readAddr(pDH, DO_bss_start) - ddmemStart] , 0, readAddr(pDH, DO_bss_end) - readAddr(pDH, DO_bss_start)); } return true; }