//Where the response should go net_error_e busman_handlemessage(busman_t* man,stream_t* respstream,uint8_t* data,msg_info_t* info){ bool ack = ((info->cmd & MASK_CMD_ACK) == MASK_CMD_ACK); uint8_t cmd = info->cmd & MASK_CMD; switch(cmd){ case CMD_PING: if (ack){ debprintf(CLR_GREEN,0,"Received a ping response, len %u, data %u\n",info->datalen,data[0]); }else{ debprintf(CLR_GREEN,0,"Received a ping: len %u, responding...\n",info->datalen); #ifdef AVR //Magic delay, with a FTDI, 1ms timeout and a 15ms read call. //Any faster, and it misses characters. //_delay_ms(1); #endif //Ping back return busman_sendmessage(/*man*/man,/*ifnum*/respstream,/*data*/data,/*len*/info->datalen,/*cmd*/CMD_PING|MASK_CMD_ACK,/*addr*/1); } return NET_ERR_NONE; break; default: debprintf(CLR_RED,0,"Received unknown command %02X.\n",info->cmd); return NET_ERR_CMD_UNKOWN; } return NET_ERR_UNDEFINED; }
void busman_printinfo(busman_t* man){ debprintf(CLR_CANCEL,0,"Busmanager:\n"); debprintf(CLR_CANCEL,0," streams: %u\n",man->num_streams); for (int i=0;i<man->num_streams;i++){ debprintf(CLR_CANCEL,0,"Stream[%i]\n",i); stream_printinfo(man->streams[i]); } }
int32 mesh_transpose(Mesh *mesh, int32 d1, int32 d2) { int32 ret = RET_OK; uint32 n_incident; uint32 ii; uint32 *nd2 = 0; uint32 D = mesh->topology->max_dim; MeshEntityIterator it2[1], it1[1]; MeshConnectivity *c12 = 0; // d1 -> d2 - to compute debprintf("transpose %d -> %d\n", d1, d2); if (d1 >= d2) { errput("d1 must be smaller than d2 in mesh_transpose()!\n"); ERR_CheckGo(ret); } c12 = mesh->topology->conn[IJ(D, d1, d2)]; // Count entities of d2 -> d1. conn_alloc(c12, mesh->topology->num[d1], 0); ERR_CheckGo(ret); nd2 = c12->offsets + 1; for (mei_init(it2, mesh, d2); mei_go(it2); mei_next(it2)) { for (mei_init_conn(it1, it2->entity, d1); mei_go(it1); mei_next(it1)) { nd2[it1->entity->ii]++; } } // c12->offsets now contains counts - make a cumsum to get offsets. for (ii = 1; ii < c12->num + 1; ii++) { c12->offsets[ii] += c12->offsets[ii-1]; } n_incident = c12->offsets[c12->num]; debprintf("transpose n_incident (%d -> %d): %d\n", d1, d2, n_incident); // Fill in the indices. conn_alloc(c12, 0, n_incident); ERR_CheckGo(ret); for (ii = 0; ii < c12->n_incident; ii++) { c12->indices[ii] = UINT32_None; // "not set" value. } for (mei_init(it2, mesh, d2); mei_go(it2); mei_next(it2)) { for (mei_init_conn(it1, it2->entity, d1); mei_go(it1); mei_next(it1)) { conn_set_to_free(c12, it1->entity->ii, it2->entity->ii); ERR_CheckGo(ret); } } end_label: return(ret); }
static void proc_short_cb(int current_type, void *current_obj, int from_type, void *from_obj, found_conn_type_t type) { AnyObjectType *curr = current_obj, *from = from_obj; short_conn_t *s; s = malloc(sizeof(short_conn_t)); if (from != NULL) { s->from_type = from_type; s->from_id = from->ID; } else { s->from_type = 0; s->from_id = -1; } s->to_type = current_type; s->to = curr; s->type = type; s->edges = 0; s->next = short_conns; short_conns = s; if (curr->ID > short_conns_maxid) short_conns_maxid = curr->ID; num_short_conns++; debprintf(" found %d %d/%p type %d from %d\n", current_type, curr->ID, current_obj, type, from == NULL ? -1 : from->ID); }
//Parse a message on stream index's rxfifo. net_error_e busman_parsemessage(busman_t* man,uint8_t index){ net_error_e err; //Temp location for data: uint8_t msgdata[32]; msg_info_t info; //We expect the same back: err = parse_message(man->streams[index]->rxfifo,msgdata,32,&info); if (err != NET_ERR_NONE){ //Failed. return err; }else{ //What should we do with the message? uint8_t cmd = (info.cmd & MASK_CMD); //Went ok. debprintf(CLR_GREEN,0,"Parse OK: addr %u cmd: %u\n",info.address,cmd); //Does a commandhadler exist? uint8_t handler_index; if (busman_gethandler(man,cmd,&handler_index)){ return man->cmd_handler[handler_index](man,man->streams[index],msgdata,&info); }else{ return busman_handlemessage(man,man->streams[index],msgdata,&info); } } return NET_ERR_UNDEFINED; }
void busman_init(busman_t* man, uint8_t num_streams){ //Address of this device: man->address = DEV_ADDRESS; //Create a bunch of stream pointers man->num_streams = num_streams; man->streams = (stream_t**)malloc(((int)num_streams)*sizeof(stream_t*)); man->streaminfo = (streaminfo_t*)malloc(((int)num_streams)*sizeof(streaminfo_t)); //Set them to nothing: for (uint8_t i=0;i<num_streams;i++){ man->streams[i] = NULL; man->streaminfo[i].addressmin = 0; man->streaminfo[i].addressmax = 0; } //Setup message handlers: for (uint8_t i=0;i<8;i++){ man->cmd_handler[i] = NULL; man->cmd_map[i] = 0; } debprintf(CLR_GREEN,0,"Busman inited\n"); }
//Read messages. void busman_task(busman_t* man){ net_error_e err; //Look for messages: for (int i=0;i<man->num_streams;i++){ uint8_t num = messages_infifo(man->streams[i]->rxfifo); debprintf(CLR_CANCEL,0,"%u messages in fifo\n",num ); while((num = messages_infifo(man->streams[i]->rxfifo))){ debprintf(CLR_GREEN,0,"There are %u messages in %i's rxfifo\n",num, i); //Do it err = busman_parsemessage(man,i); if (err != NET_ERR_NONE){ debprintf(CLR_RED,0,"Failed to parse:");net_error(err); //Continue }else{ debprintf(CLR_GREEN,0,"Parsed message\n"); } } } }
int32 mesh_free_connectivity(Mesh *mesh, int32 d1, int32 d2) { uint32 D = mesh->topology->max_dim; MeshConnectivity *conn = 0; debprintf("free connectivity %d -> %d\n", d1, d2); conn = mesh->topology->conn[IJ(D, d1, d2)]; conn_free(conn); return(RET_OK); }
int32 mesh_setup_connectivity(Mesh *mesh, int32 d1, int32 d2) { int32 ret = RET_OK; int32 d3 = 0; MeshTopology *topology = mesh->topology; uint32 D = topology->max_dim; debprintf("request connectivity %d -> %d\n", d1, d2); if (topology->num[d1] == 0) { mesh_build(mesh, d1); ERR_CheckGo(ret); } if (topology->num[d2] == 0) { mesh_build(mesh, d2); ERR_CheckGo(ret); } if (topology->conn[IJ(D, d1, d2)]->num) { return(ret); } if (d1 < d2) { mesh_setup_connectivity(mesh, d2, d1); mesh_transpose(mesh, d1, d2); } else { if ((d1 == 0) && (d2 == 0)) { d3 = D; } else { d3 = 0; } if ((d1 > 0) && (d2 == 0)) { errput("connectivity %d -> %d should already exist!\n", d1, d2); ERR_CheckGo(ret); } mesh_setup_connectivity(mesh, d1, d3); mesh_setup_connectivity(mesh, d3, d2); mesh_intersect(mesh, d1, d2, d3); } ERR_CheckGo(ret); end_label: return(ret); }
void pawn::UpdateBreaths(int breaths) { this->_breaths += breaths; debprintf(" Adding/Reducing %d breaths of pawn color %c so he has %d\n", breaths, (this->GetColor() == WHITE) ? 'W' : 'S' , this->_breaths); } // UpdateBreaths
pawn::pawn(int row, int column) { this->BreathsInitialize(row, column); debprintf(" Pawn constructor works %d %d breaths %d\n", row, column, this->_breaths); } // pawn
int32 mesh_intersect(Mesh *mesh, int32 d1, int32 d2, int32 d3) { int32 ret = RET_OK; uint32 D = mesh->topology->max_dim; uint32 n_incident, ii; uint32 *nd2 = 0; char *mask = 0; MeshEntityIterator it1[1], it2[1], it3[1]; Indices ei1[1], ei2[1]; MeshConnectivity *c12 = 0; // d1 -> d2 - to compute MeshConnectivity *c10 = 0; // d1 -> 0 - known MeshConnectivity *c20 = 0; // d2 -> 0 - known debprintf("intersect %d -> %d (%d)\n", d1, d2, d3); if (d1 < d2) { errput("d1 must be greater or equal to d2 in mesh_intersect()!\n"); ERR_CheckGo(ret); } c12 = mesh->topology->conn[IJ(D, d1, d2)]; if (d1 > d2) { c10 = mesh->topology->conn[IJ(D, d1, 0)]; c20 = mesh->topology->conn[IJ(D, d2, 0)]; } mask = alloc_mem(char, mesh->topology->num[d2]); // Count entities of d2 -> d1. conn_alloc(c12, mesh->topology->num[d1], 0); ERR_CheckGo(ret); nd2 = c12->offsets + 1; for (mei_init(it1, mesh, d1); mei_go(it1); mei_next(it1)) { // Clear mask for it1 incident entities of dimension d2. for (mei_init_conn(it3, it1->entity, d3); mei_go(it3); mei_next(it3)) { for (mei_init_conn(it2, it3->entity, d2); mei_go(it2); mei_next(it2)) { mask[it2->entity->ii] = 0; } } for (mei_init_conn(it3, it1->entity, d3); mei_go(it3); mei_next(it3)) { for (mei_init_conn(it2, it3->entity, d2); mei_go(it2); mei_next(it2)) { if (mask[it2->entity->ii]) continue; mask[it2->entity->ii] = 1; if (d1 == d2) { if (it1->entity->ii != it2->entity->ii) { nd2[it1->entity->ii]++; } } else { // Get incident vertices. me_get_incident2(it1->entity, ei1, c10); me_get_incident2(it2->entity, ei2, c20); if (contains(ei1, ei2)) { nd2[it1->entity->ii]++; } } } } } // c12->offsets now contains counts - make a cumsum to get offsets. for (ii = 1; ii < c12->num + 1; ii++) { c12->offsets[ii] += c12->offsets[ii-1]; } n_incident = c12->offsets[c12->num]; debprintf("intersect n_incident (%d -> %d): %d\n", d1, d2, n_incident); // Fill in the indices. conn_alloc(c12, 0, n_incident); ERR_CheckGo(ret); for (ii = 0; ii < c12->n_incident; ii++) { c12->indices[ii] = UINT32_None; // "not set" value. } for (mei_init(it1, mesh, d1); mei_go(it1); mei_next(it1)) { // Clear mask for it1 incident entities of dimension d2. for (mei_init_conn(it3, it1->entity, d3); mei_go(it3); mei_next(it3)) { for (mei_init_conn(it2, it3->entity, d2); mei_go(it2); mei_next(it2)) { mask[it2->entity->ii] = 0; } } for (mei_init_conn(it3, it1->entity, d3); mei_go(it3); mei_next(it3)) { for (mei_init_conn(it2, it3->entity, d2); mei_go(it2); mei_next(it2)) { if (mask[it2->entity->ii]) continue; mask[it2->entity->ii] = 1; if (d1 == d2) { if (it1->entity->ii != it2->entity->ii) { conn_set_to_free(c12, it1->entity->ii, it2->entity->ii); ERR_CheckGo(ret); } } else { // Get incident vertices. me_get_incident2(it1->entity, ei1, c10); me_get_incident2(it2->entity, ei2, c20); if (contains(ei1, ei2)) { conn_set_to_free(c12, it1->entity->ii, it2->entity->ii); ERR_CheckGo(ret); } } } } } end_label: free_mem(mask); return(ret); }
int32 mesh_build(Mesh *mesh, int32 dim) { int32 ret = RET_OK; uint32 n_incident, n_v_max, n_loc; uint32 ii, ic, id, found; uint32 D = mesh->topology->max_dim; uint32 facet[4]; // Max. space for single facet. uint32 *oris = 0; uint32 loc_oris[12]; uint32 *nDd = 0; uint32 *ptr1 = 0, *ptr2 = 0; uint32 *cell_types = mesh->topology->cell_types; Indices cell_vertices[1]; MeshEntityIterator it0[1], it1[1], it2[1]; MeshConnectivity *cD0 = 0; // D -> 0 - known MeshConnectivity *cDd = 0; // D -> d - to compute MeshConnectivity *cd0 = 0; // d -> 0 - to compute MeshConnectivity **locs = 0; MeshConnectivity *loc = 0; MeshConnectivity sloc[1]; // Local connectivity with sorted global vertices. MeshConnectivity gloc[1]; // Local connectivity with global vertices. debprintf("build %d\n", dim); if (!mesh->topology->conn[IJ(D, D, D)]->num) { mesh_setup_connectivity(mesh, D, D); } cD0 = mesh->topology->conn[IJ(D, D, 0)]; cDd = mesh->topology->conn[IJ(D, D, dim)]; cd0 = mesh->topology->conn[IJ(D, dim, 0)]; locs = (dim == 1) ? mesh->entities->edges : mesh->entities->faces; // Max. number of vertices in facets. n_v_max = (dim == 1) ? 2 : 4; // Count entities of D -> d. conn_alloc(cDd, mesh->topology->num[D], 0); ERR_CheckGo(ret); nDd = cDd->offsets + 1; for (mei_init(it0, mesh, D); mei_go(it0); mei_next(it0)) { loc = locs[cell_types[it0->it]]; nDd[it0->it] = loc->num; } // cDd->offsets now contains counts - make a cumsum to get offsets. for (ii = 1; ii < cDd->num + 1; ii++) { cDd->offsets[ii] += cDd->offsets[ii-1]; } n_incident = cDd->offsets[cDd->num]; debprintf("build n_incident (%d -> %d): %d\n", D, dim, n_incident); // Cell-local orientations w.r.t. D -> d. oris = alloc_mem(uint32, n_incident); if (dim == 2) { free_mem(mesh->topology->face_oris); mesh->topology->face_oris = oris; } else { free_mem(mesh->topology->edge_oris); mesh->topology->edge_oris = oris; } // Allocate D -> d indices. conn_alloc(cDd, 0, n_incident); ERR_CheckGo(ret); for (ii = 0; ii < cDd->n_incident; ii++) { cDd->indices[ii] = UINT32_None; // "not set" value. } // Allocate maximal buffers for d -> 0 arrays. conn_alloc(cd0, n_incident, n_incident * n_v_max); debprintf("build max. n_incident_vertex: %d\n", n_incident * n_v_max); // Allocate maximal buffers for local connectivity with sorted global // vertices. Counts have to be set to zero to avoid spurious calls to // conn_free()! sloc->num = sloc->n_incident = 0; conn_alloc(sloc, 12, n_v_max * 12); gloc->num = gloc->n_incident = 0; conn_alloc(gloc, 12, n_v_max * 12); id = 0; for (mei_init(it0, mesh, D); mei_go(it0); mei_next(it0)) { // Get vertex sets for local entities of current cell. loc = locs[cell_types[it0->it]]; me_get_incident2(it0->entity, cell_vertices, cD0); get_local_connectivity(gloc, cell_vertices, loc); conn_set_from(sloc, gloc); sort_local_connectivity(sloc, loc_oris, loc->num); // Iterate over entities in the vertex sets. for (ii = 0; ii < loc->num; ii++) { // ii points to a vertex set in sloc/gloc. n_loc = sloc->offsets[ii+1] - sloc->offsets[ii]; // Try to find entity in cells visited previously. for (mei_init_conn(it1, it0->entity, D); mei_go(it1); mei_next(it1)) { if (it1->entity->ii >= it0->entity->ii) continue; // Iterate over facets of visited cells. for (mei_init_conn(it2, it1->entity, dim); mei_go(it2); mei_next(it2)) { ptr1 = cd0->indices + cd0->offsets[it2->entity->ii]; uint32_sort234_copy(facet, ptr1, n_loc); ptr2 = sloc->indices + sloc->offsets[ii]; found = 1; for (ic = 0; ic < n_loc; ic++) { if (facet[ic] != ptr2[ic]) { found = 0; break; } } if (found) { // Assign existing entity to D -> d. conn_set_to_free(cDd, it0->entity->ii, it2->entity->ii); goto found_label; } } } // Entity not found - create new. // Add it as 'id' to D -> d. conn_set_to_free(cDd, it0->entity->ii, id); // Add vertices in gloc to d -> 0. cd0->offsets[id+1] = cd0->offsets[id] + n_loc; ptr1 = cd0->indices + cd0->offsets[id]; ptr2 = gloc->indices + gloc->offsets[ii]; for (ic = 0; ic < n_loc; ic++) { ptr1[ic] = ptr2[ic]; } // Increment entity counter. id++; found_label: // Store entity orientation key to position of the last used item in cDd. ptr1 = cDd->offsets + it0->entity->ii; ic = ptr1[1] - 1; while (ic >= ptr1[0]) { if (cDd->indices[ic] != UINT32_None) { // Not found & free slot. break; } ic--; } // printf("%d << %d, %d\n", ic, ii, loc_oris[ii]); oris[ic] = loc_oris[ii]; } } debprintf("build n_unique: %d, n_incident (%d -> 0): %d\n", id, dim, cd0->offsets[id]); // Update entity count in topology. mesh->topology->num[dim] = id; // Strip d -> 0. conn_resize(cd0, id, cd0->offsets[id]); end_label: conn_free(sloc); conn_free(gloc); return(ret); }
/* returns 0 on succes */ static int proc_short(PinType *pin, PadType *pad, int ignore) { find_callback_t old_cb; Coord x, y; short_conn_t *n, **lut_by_oid, **lut_by_gid, *next; int gids; gr_t *g; void *S, *T; int *solution; int i, maxedges; int bad_gr = 0; if (!TEST_FLAG (ENABLEMINCUTFLAG, PCB)) return bad_gr; if (!Settings.EnableMincut) return bad_gr; /* only one should be set, but one must be set */ assert((pin != NULL) || (pad != NULL)); assert((pin == NULL) || (pad == NULL)); if (pin != NULL) { debprintf("short on pin!\n"); SET_FLAG (WARNFLAG, pin); x = pin->X; y = pin->Y; } else if (pad != NULL) { debprintf("short on pad!\n"); SET_FLAG (WARNFLAG, pad); if (TEST_FLAG (EDGE2FLAG, pad)) { x = pad->Point2.X; y = pad->Point2.Y; } else { x = pad->Point1.X; y = pad->Point1.Y; } } /* run only if net is not ignored */ if (ignore) return 0; short_conns = NULL; num_short_conns = 0; short_conns_maxid = 0; /* perform a search using MINCUTFLAG, calling back proc_short_cb() with the connections */ old_cb = find_callback; find_callback = proc_short_cb; SaveFindFlag(MINCUTFLAG); LookupConnection (x, y, false, 1, MINCUTFLAG); debprintf("- alloced for %d\n", (short_conns_maxid+1)); lut_by_oid = calloc(sizeof(short_conn_t *), (short_conns_maxid+1)); lut_by_gid = calloc(sizeof(short_conn_t *), (num_short_conns+3)); g = gr_alloc(num_short_conns+2); g->node2name = calloc(sizeof(char *), (num_short_conns+2)); /* conn 0 is S and conn 1 is T and set up lookup arrays */ for(n = short_conns, gids=2; n != NULL; n = n->next, gids++) { char *s, *typ; ElementType *parent; n->gid = gids; debprintf(" {%d} found %d %d/%p type %d from %d\n", n->gid, n->to_type, n->to->ID, n->to, n->type, n->from_id); lut_by_oid[n->to->ID] = n; lut_by_gid[n->gid] = n; s = malloc(256); parent = NULL; switch(n->to_type) { case PIN_TYPE: typ = "pin"; parent = ((PinType *)(n->to))->Element; break; case VIA_TYPE: typ = "via"; parent = ((PinType *)(n->to))->Element; break; case PAD_TYPE: typ = "pad"; parent = ((PadType *)(n->to))->Element; break; case LINE_TYPE: typ = "line"; break; default: typ="other"; break; } if (parent != NULL) { TextType *name; name = &parent->Name[1]; if ((name->TextString == NULL) || (*name->TextString == '\0')) sprintf(s, "%s #%d \\nof #%d", typ, n->to->ID, parent->ID); else sprintf(s, "%s #%d \\nof %s", typ, n->to->ID, name->TextString); } else sprintf(s, "%s #%d", typ, n->to->ID); g->node2name[n->gid] = s; } g->node2name[0] = strdup("S"); g->node2name[1] = strdup("T"); /* calculate how many edges each node has and the max edge count */ maxedges = 0; for(n = short_conns; n != NULL; n = n->next) { short_conn_t *from; n->edges++; if (n->edges > maxedges) maxedges = n->edges; if (n->from_id >= 0) { from = lut_by_oid[n->from_id]; if (from == NULL) { /* no from means broken graph (multiple components) */ if (n->from_id >= 2) { /* ID 0 and 1 are start/stop, there won't be from for them */ fprintf(stderr, "rats_mincut.c error: graph has multiple components, bug in find.c (n->from_id=%d)!\n", n->from_id); bad_gr = 1; } continue; } from->edges++; if (from->edges > maxedges) maxedges = from->edges; } } S = NULL; T = NULL; for(n = short_conns; n != NULL; n = n->next) { short_conn_t *from; void *spare; spare = NULL; if (n->to_type == PIN_TYPE) spare = ((PinType *)n->to)->Spare; if (n->to_type == PAD_TYPE) spare = ((PadType *)n->to)->Spare; if (spare != NULL) { void *net = &(((LibraryMenuTypePtr)spare)->Name[2]); debprintf(" net=%s\n", net); if (S == NULL) { debprintf(" -> became S\n"); S = net; } else if ((T == NULL) && (net != S)) { debprintf(" -> became T\n"); T = net; } if (net == S) gr_add_(g, n->gid, 0, 100000); else if (net == T) gr_add_(g, n->gid, 1, 100000); } /* if we have a from object, look it up and make a connection between the two gids */ if (n->from_id >= 0) { int weight; short_conn_t *from = lut_by_oid[n->from_id]; from = lut_by_oid[n->from_id]; /* weight: 1 for connections we can break, large value for connections we shall not break */ if ((n->type == FCT_COPPER) || (n->type == FCT_START)) { /* connection to a pin/pad is slightly stronger than the strongest obj-obj conn; obj-obj conns are weaker at junctions where many objects connect */ if ((n->from_type == PIN_TYPE) || (n->from_type == PAD_TYPE) || (n->to_type == PIN_TYPE) || (n->to_type == PAD_TYPE)) weight = maxedges*2 + 2; else weight = maxedges*2 - n->edges - from->edges + 1; } else weight = 10000; if (from != NULL) { gr_add_(g, n->gid, from->gid, weight); debprintf(" CONN %d %d\n", n->gid, from->gid); } } } /*#define MINCUT_DRAW*/ #ifdef MINCUT_DRAW { static int drw = 0; char gfn[256]; drw++; sprintf(gfn, "A_%d_a", drw); debprintf("gfn=%s\n", gfn); gr_draw(g, gfn, "png"); } #endif if (!bad_gr) { solution = solve(g); if (solution != NULL) { debprintf("Would cut:\n"); for(i = 0; solution[i] != -1; i++) { short_conn_t *s; debprintf("%d:", i); s = lut_by_gid[solution[i]]; debprintf("%d %p", solution[i], s); if (s != NULL) { SET_FLAG (WARNFLAG, s->to); debprintf(" -> %d", s->to->ID); } debprintf("\n"); } free(solution); } else { fprintf(stderr, "mincut didn't find a solution, falling back to the old warn\n"); bad_gr=1; } } free(lut_by_oid); free(lut_by_gid); for(n = short_conns; n != NULL; n = next) { next = n->next; free(n); } ResetFoundLinesAndPolygons(false); ResetFoundPinsViasAndPads(false); RestoreFindFlag(); find_callback = old_cb; return bad_gr; }