sound_t *sound_run(int pin, int pin2) { sound_t *device; device = (void *) malloc(sizeof(sound_t)); sound_config(device); if(pin == -1 || pin2 == -1) { device->ctraval = (0b00110 << 26); if(pin != -1) { device->ctraval |= pin; device->pinmask = 1 << pin; } else if(pin2 != -1) { device->ctraval |= pin2; device->pinmask = 1 << pin2; } } else { device->ctraval = (0b00111 << 26) | pin | (pin2 << 9); device->pinmask = (1 << pin) | (1 << pin2); } device->divVal = 2; if(device->cog == 0) { extern int binary_audiosynth_dat_start[]; device->cog = 1 + cognew((void*)binary_audiosynth_dat_start, (void*)device); } return device; }
/* * function to start up a new cog running the toggle * code (which we've placed in the .coguser0 section) */ void startvga(volatile void *parptr) { extern unsigned int _load_start_vga_cog[]; int r; r = cognew(_load_start_vga_cog, parptr); printf("started cog %d\n", r); }
/* * TV_Text start function starts TV on a cog * See header file for more details. */ int tvText_start(int basepin) { extern uint32_t binary_TV_dat_start[]; col = 0; row = 0; flag = 0; tvPtr = &tvText; tvPtr->status = 0; tvPtr->enable = 1; tvPtr->pins = ((basepin & 0x38) << 1) | (((basepin & 4) == 4) ? 0x5 : 0); tvPtr->mode = 0x12; tvPtr->colors = colorTable; tvPtr->screen = screen; tvPtr->ht = TV_TEXT_COLS; tvPtr->vt = TV_TEXT_ROWS; tvPtr->hx = 4; tvPtr->vx = 1; tvPtr->ho = 0; tvPtr->vo = -2; tvPtr->broadcast = 0; tvPtr->auralcog = 0; // set main fg/bg color tvText_setColorPalette(&gpalette[TV_TEXT_PAL_WHITE_BLUE]); // blank the screen wordfill(tvPtr->screen, blank, TV_TEXT_SCREENSIZE); #if defined(__PROPELLER_XMM__) // start new cog from external memory using pasm and tvPtr memcpy((char*)pasm,(char*)binary_TV_dat_start,PASMLEN<<2); gTvTextCog = cognew(pasm, (uint32_t)tvPtr) + 1; #else gTvTextCog = cognew((uint32_t)binary_TV_dat_start, (uint32_t)tvPtr) + 1; #endif waitcnt((CLKFREQ>>4)+CNT); // 100us is all we need really // clear screen wordfill(tvPtr->screen, color << 11 | blank, TV_TEXT_SCREENSIZE); col = 0; row = 0; return gTvTextCog; }
/* start rtc cog */ int start_rtc(volatile void *parptr) { int size = (_load_stop_rtc_cog - _load_start_rtc_cog)*4;//code size in bytes printf("rtc cog code size %i bytes\n",size); unsigned int code[size]; //allocate enough HUB to hold the COG code memcpy(code, _load_start_rtc_cog, size); //assume xmmc return cognew(code, parptr); }
int start_dio(volatile void *parptr) { int size = (_load_stop_dio_cog - _load_start_dio_cog)*4; printf("dio cog code size %i bytes\n",size); unsigned int code[size]; memcpy(code, _load_start_dio_cog, size); //assume xmmc return cognew(code, parptr); }
int xmemStart(void *code, xmem_mbox_t *mboxes, int count, uint32_t config1, uint32_t config2, uint32_t config3, uint32_t config4) { uint32_t *xmem = (uint32_t *)code; memset(mboxes, 0, sizeof(xmem_mbox_t) * count); mboxes[count].hubaddr = XMEM_END; xmem[1] = config1; xmem[2] = config2; xmem[3] = config3; xmem[4] = config4; return cognew(code, mboxes); }
/* start rtc cog */ int start_rtc(volatile void *parptr) { extern unsigned int _load_start_rtc_cog[]; // beginning addresses of the code for the rtc cog */ extern unsigned int _load_stop_rtc_cog[]; // ending addresses of the code for the rtc cog */ int size = (_load_stop_rtc_cog - _load_start_rtc_cog)*4;//code size in bytes printf(" rtc cog code size %i bytes\n",size); unsigned int code[size]; //allocate enough HUB to hold the COG code memcpy(code, _load_start_rtc_cog, size); //assume xmmc return cognew(code, parptr); }
int32_t screen_start(void) { self = &badgeScreen; int32_t okay = 0; // Start SPI Engine - starts a cog // returns false if no cog available screen_stop(); okay = (self->cog = cognew((int32_t)(&(*(int32_t *)&oleddat[1024])), (int32_t)(&self->command)) + 1); screenLock = locknew(); lockclr(screenLock); return okay; }
/* start cogA */ int start_cogA(volatile void *parptr) { extern unsigned int _load_start_cogA_cog[]; //start address for cog code extern unsigned int _load_stop_cogA_cog[]; //end address for cog code if(parA.A.cog != -1) //see if the cog is running cogstop(parA.A.cog); //stop the cog int size = (_load_stop_cogA_cog - _load_start_cogA_cog)*4; //code size in bytes printf(" cogA code size %i bytes - ",size); unsigned int code[size]; //allocate enough HUB to hold the COG code memcpy(code, _load_start_cogA_cog, size); //copy the code to HUB memory parA.A.cog = cognew(code, parptr); //start the cog return parA.A.cog; }
uint32_t cacheStart(void *code, cache_mbox_t *mbox, uint8_t *cache, uint32_t config1, uint32_t config2, uint32_t config3, uint32_t config4) { cache_init_t params; params.mbox = mbox; params.cache = cache; params.config1 = config1; params.config2 = config2; params.config3 = config3; params.config4 = config4; mbox->cmd = 1; cognew(code, ¶ms); while (mbox->cmd) ; return (uint32_t)params.mbox; }
/* * start C code running in another cog * returns -1 on failure, otherwise the * id of the new cog * "func" is the function to start running * "arg" is the argument * "stacktop" is the top of the new process' stack * NOTE: this is a raw low-level function; the * pthreads functions may be more useful */ int _start_cog_thread(void *stacktop, void (*func)(void *), void *arg, _thread_state_t *tls) { void *tmp = __builtin_alloca(1984); unsigned int *sp = stacktop; int r; #if defined(__PROPELLER_USE_XMM__) /* the space for the cache is taken from the top of the stack space */ unsigned int cachebase; sp -= (CACHE_EXTRA_SPACE/sizeof(*sp)); cachebase = ~0xf & (15 + (unsigned int)sp); /* align to 16 byte boundary */ #endif /* copy the kernel into temporary (HUB) memory */ _clone_cog(tmp); /* push the pointer to thread local storage */ *--sp = (unsigned int)tls; /* push the parameter to the function */ *--sp = (unsigned int)arg; /* push the code address */ *--sp = (unsigned int)func; #if defined(__PROPELLER_USE_XMM__) { unsigned int cogid = __builtin_propeller_cogid(); // push the cache geometry *--sp = CACHE_GEOMETRY; // push the cache line storage address *--sp = cachebase; // push the cache tag storage address *--sp = cachebase + CACHE_SIZE; // push the base of the hub mailbox array *--sp = ((unsigned int)_hub_mailbox) - (cogid<<3); } #endif /* now start the kernel */ r = cognew(tmp, sp); return r; }
int32_t light_start(void) { self = &badgeLight; // Start conference badge charlieplex driver // stop cog if running light_stop(); // base of blue group ((uint8_t *)(int32_t)(&self->ledbits))[0] = BLU_CP0; // base of rgb group ((uint8_t *)(int32_t)(&self->ledbits))[1] = RGB_CP0; // update LEDs at 300Hz self->cycleticks = (CLKFREQ / 300) / 6; // start pasm cog self->cog = cognew((int32_t)(&(*(int32_t *)&leddat[0])), (int32_t)(&self->ledbits)) + 1; return self->cog; }
int32_t ILI9341_spi::Start(int32_t nRES, int32_t nCS, int32_t RS, int32_t MOSI, int32_t SCLK) { int32_t mask; int32_t result = 0; Stop(); cmd = CMD_SETUP; ((int32_t *)&dat[1484])[0] = 1 << nCS; ((int32_t *)&dat[1488])[0] = 1 << RS; ((int32_t *)&dat[1492])[0] = 1 << MOSI; ((int32_t *)&dat[1496])[0] = 1 << SCLK; ((int32_t *)&dat[1500])[0] = 1 << nRES; ((int32_t *)&dat[1504])[0] = ((*(int32_t *)&dat[1500]) | (*(int32_t *)&dat[1484])) | (*(int32_t *)&dat[1496]); arg0 = (int32_t)(&(*(int32_t *)&dat[0])); cog = 1 + cognew((int32_t)(&(*(int32_t *)&dat[156])), (int32_t)(&cmd)); if (cog != 0) { Synch(); } result = cog; return result; }
I2C::I2C(int scl, int sda, int freq) { // only allow speeds up to 400khz for now if (freq > 400000) freq = 400000; //I2C_INIT init; m_par.cog = -1; m_par.init.scl = scl; m_par.init.sda = sda; m_par.init.ticks_per_cycle = (CLKFREQ / freq)-25; m_par.init.mailbox = &m_par.mailbox; m_par.mailbox.cmd = I2C_CMD_INIT; // Start the COG according to the method needed for LMM/XMM memory models #if defined(__PROPELLER_XMMC__) || defined(__PROPELLER_XMM__) int size = _load_stop_I2CDriver_cog - _load_start_I2CDriver_cog; unsigned int cogbuffer[size]; // memcpy does bytes, so we copy numbytes * 4 = num ints. memcpy(cogbuffer, _load_start_I2CDriver_cog, size<<2); #else int *cogbuffer = (int*)_load_start_I2CDriver_cog; #endif m_par.cog = cognew(cogbuffer, &m_par.init); volatile int n; while (m_par.mailbox.cmd != I2C_CMD_IDLE) { if (n > 127) { m_ready = 0; return; // Timeout waiting after ~3.8ms } pollDelay(); // Wait 30 uSecs. n++; } m_ready = 1; }
int main(void) { uint8_t *buffer = (uint8_t *)(((uint32_t)padded_buffer + 15) & ~15); SdLoaderInfo *info = (SdLoaderInfo *)_load_start_coguser0; uint32_t load_address, index_width, offset_width, addr, count; uint32_t tags_size, cache_size, cache_lines, cache_tags, mboxes, *sp; VolumeInfo vinfo; FileInfo finfo; PexeFileHdr *hdr; int sd_id, i; uint8_t *p; // determine the cache size and setup cache variables index_width = info->cache_geometry >> 8; offset_width = info->cache_geometry & 0xff; tags_size = (1 << index_width) * 4; cache_size = 1 << (index_width + offset_width); cache_lines = HUB_SIZE - cache_size; cache_tags = cache_lines - tags_size; mboxes = cache_tags - sizeof(xmem_mbox_t) * 8 - 4; xmem_mbox = (xmem_mbox_t *)mboxes; // load the external memory driver DPRINTF("Loading external memory driver\n"); memset((void *)mboxes, 0, sizeof(xmem_mbox_t) * 8 + 4); xmem_mbox[8].hubaddr = XMEM_END; cognew(_load_start_coguser1, mboxes); DPRINTF("Loading SD driver\n"); sd_mbox = (uint32_t *)mboxes - 2; sd_mbox[0] = 0xffffffff; if ((sd_id = cognew(_load_start_coguser2, sd_mbox)) < 0) { DPRINTF("Error loading SD driver\n"); return 1; } while (sd_mbox[0]) ; DPRINTF("Initializing SD card\n"); if (SD_Init(sd_mbox, 5) != 0) { DPRINTF("SD card initialization failed\n"); return 1; } DPRINTF("Mounting filesystem\n"); if (MountFS(buffer, &vinfo) != 0) { DPRINTF("MountFS failed\n"); return 1; } // open the .pex file DPRINTF("Opening 'autorun.pex'\n"); if (FindFile(buffer, &vinfo, FILENAME, &finfo) != 0) { DPRINTF("FindFile '%s' failed\n", FILENAME); return 1; } // read the file header DPRINTF("Reading PEX file header\n"); if (GetNextFileSector(&finfo, kernel_image, &count) != 0 || count < PEXE_HDR_SIZE) { DPRINTF("Error reading PEX file header\n"); return 1; } // verify the header DPRINTF("Verifying PEX file header\n"); hdr = (PexeFileHdr *)kernel_image; if (strncmp(hdr->tag, PEXE_TAG, sizeof(hdr->tag)) != 0 || hdr->version != PEXE_VERSION) { DPRINTF("Bad PEX file header\n"); return 1; } load_address = hdr->loadAddress; // move past the header memmove(kernel_image, (uint8_t *)kernel_image + PEXE_HDR_SIZE, SECTOR_SIZE - PEXE_HDR_SIZE); p = (uint8_t *)kernel_image + SECTOR_SIZE - PEXE_HDR_SIZE; // read the .kernel cog image DPRINTF("Reading kernel image\n"); for (i = 1; i < 4; ++i) { if (GetNextFileSector(&finfo, p, &count) != 0 || count < SECTOR_SIZE) return 1; p += SECTOR_SIZE; } // load the image DPRINTF("Loading image at 0x%08x\n", load_address); addr = load_address; while (GetNextFileSector(&finfo, buffer, &count) == 0) { write_block(addr, buffer, XMEM_SIZE_512); addr += SECTOR_SIZE; } // stop the sd driver DPRINTF("Stopping SD driver\n"); cogstop(sd_id); // setup the stack // at start stack contains xmem_mbox, cache_tags, cache_lines, cache_geometry, pc sp = (uint32_t *)mboxes; *--sp = load_address; *--sp = info->cache_geometry; *--sp = cache_lines; *--sp = cache_tags; *--sp = mboxes; // start the xmm kernel boot code DPRINTF("Starting kernel\n"); coginit(cogid(), kernel_image, sp); // should never reach this return 0; }
/* * function to start up a new cog running the toggle * code (which we've placed in the .coguser1 section) */ void start(void *parptr) { extern unsigned int _load_start_toggle_fw_cog[]; cognew(_load_start_toggle_fw_cog, parptr); }