/******************************************************************************* * Outline : Accel_SelfTest * Description : This function reads the acceleromter's X axis * Argument : none * Return value : bool true - pass, false - fail *******************************************************************************/ bool Accel_SelfTest( void ) { bool err =true; uint8_t target_reg_data[2]; uint16_t i; // set the data format + self test mode target_reg_data[0] = ADXL345_DATA_FORMAT_REG; target_reg_data[1] = 0x83; err &= R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &target_reg_data[0], 2, PDL_NO_FUNC, 0 ); // Wait for self-test forces to act for (i = 0; i < 1000; i++); Accel_X = 0; Accel_Y = 0; Accel_Z = 0; for (i = 0; i < 8; i++) { Accel_X += Accel_AxisRd(ADXL345_DATAX0_REG); Accel_Y += Accel_AxisRd(ADXL345_DATAY0_REG); Accel_Z += Accel_AxisRd(ADXL345_DATAZ0_REG); } Accel_X = Accel_X / 8; Accel_Y = Accel_Y / 8; Accel_Z = Accel_Z / 8; // normalize the self test values Accel_X = SCALE_X(Accel_X) - Accel_X_Zero; Accel_Y = SCALE_Y(Accel_Y) - Accel_Y_Zero; Accel_Z = SCALE_Z(Accel_Z) - Accel_Z_Zero; // Range check self-test values err &= ((Accel_X > 6) && (Accel_X < 67)) ? true : false; err &= ((Accel_Y > -67) && (Accel_Y < -6)) ? true : false; err &= ((Accel_Z > 10) && (Accel_Z < 110)) ? true : false; // turn off self test mode target_reg_data[0] = ADXL345_DATA_FORMAT_REG; target_reg_data[1] = 0x03; err &= R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &target_reg_data[0], 2, PDL_NO_FUNC, 0 ); return err; }
// according to cht_format.html from argyll: // "The keywords and associated data must be used in the following order: BOXES, BOX_SHRINK, REF_ROTATION, // XLIST, YLIST and EXPECTED." chart_t *parse_cht(const char *filename) { chart_t *result = (chart_t *)calloc(1, sizeof(chart_t)); int lineno = 0; FILE *fp = fopen(filename, "rb"); if(!fp) { fprintf(stderr, "error opening `%s'\n", filename); ERROR; } // parser control char line[MAX_LINE_LENGTH] = { 0 }; parser_state_t last_block = BLOCK_NONE; int skip_block = 0; // data gathered from the CHT file unsigned int n_boxes; result->d_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free); result->box_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free); result->patch_sets = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_labels_list); float x_min = FLT_MAX, x_max = FLT_MIN, y_min = FLT_MAX, y_max = FLT_MIN; // main loop over the input file while(fgets(line, MAX_LINE_LENGTH, fp)) { if(line[0] == '\0' || line[0] == '\n') { skip_block = 0; continue; } if(skip_block) continue; // we should be at the start of a block now char *c = line; ssize_t len = strlen(line); char *keyword = parse_string(&c); if(!g_strcmp0(keyword, "BOXES") && last_block < BLOCK_BOXES) { last_block = BLOCK_BOXES; if(c - line >= len) ERROR; n_boxes = parse_double(&c); // let's have another loop reading from the file. while(fgets(line, MAX_LINE_LENGTH, fp)) { if(line[0] == '\0' || line[0] == '\n') break; char *c = line; ssize_t len = strlen(line); while(*c == ' ') c++; if(*c == 'F') { float x0, y0, x1, y1, x2, y2, x3, y3; // using sscanf would be nice, but parsign floats does only work with LANG=C // if(sscanf(line, " F _ _ %f %f %f %f %f %f %f %f", &x0, &y0, &x1, &y1, &x2, &y2, &x3, &y3) != 8) // ERROR; c++; while(*c == ' ') c++; if(*c++ != '_') ERROR; while(*c == ' ') c++; if(*c++ != '_') ERROR; while(*c == ' ') c++; if(c - line >= len) ERROR; x0 = parse_double(&c); if(c - line >= len) ERROR; y0 = parse_double(&c); if(c - line >= len) ERROR; x1 = parse_double(&c); if(c - line >= len) ERROR; y1 = parse_double(&c); if(c - line >= len) ERROR; x2 = parse_double(&c); if(c - line >= len) ERROR; y2 = parse_double(&c); if(c - line >= len) ERROR; x3 = parse_double(&c); if(c - line >= len) ERROR; y3 = parse_double(&c); x_min = MIN(x_min, x0); x_min = MIN(x_min, x1); x_min = MIN(x_min, x2); x_min = MIN(x_min, x3); y_min = MIN(y_min, y0); y_min = MIN(y_min, y1); y_min = MIN(y_min, y2); y_min = MIN(y_min, y3); x_max = MAX(x_max, x0); x_max = MAX(x_max, x1); x_max = MAX(x_max, x2); x_max = MAX(x_max, x3); y_max = MAX(y_max, y0); y_max = MAX(y_max, y1); y_max = MAX(y_max, y2); y_max = MAX(y_max, y3); f_line_t *l = (f_line_t *)malloc(sizeof(f_line_t)); l->p[0].x = x0; l->p[0].y = y0; l->p[1].x = x1; l->p[1].y = y1; l->p[2].x = x2; l->p[2].y = y2; l->p[3].x = x3; l->p[3].y = y3; result->f_list = g_list_append(result->f_list, l); } // these get parsed the same way else if((*c == 'D') || (*c == 'X') || (*c == 'Y')) { char kl, *lxs, *lxe, *lys, *lye; float w, h, xo, yo, xi, yi; kl = *c; *c++ = '\0'; if(c - line >= len) ERROR; lxs = parse_string(&c); if(c - line >= len) ERROR; lxe = parse_string(&c); if(c - line >= len) ERROR; lys = parse_string(&c); if(c - line >= len) ERROR; lye = parse_string(&c); if(c - line >= len) ERROR; w = parse_double(&c); if(c - line >= len) ERROR; h = parse_double(&c); if(c - line >= len) ERROR; xo = parse_double(&c); if(c - line >= len) ERROR; yo = parse_double(&c); if(c - line >= len) ERROR; xi = parse_double(&c); if(c - line >= len) ERROR; yi = parse_double(&c); x_min = MIN(x_min, xo); y_min = MIN(y_min, yo); int x_steps = 1, y_steps = 1; size_t lxs_len = strlen(lxs), lxe_len = strlen(lxe), lys_len = strlen(lys), lye_len = strlen(lye); if(lxs_len > lxe_len || lys_len > lye_len) ERROR; char x_label[lxe_len + 1], y_label[lye_len + 1]; // make sure there is enough room to add another char in the beginning char *first_label = NULL, *last_label = NULL; GList *labels = NULL; float y = yo; memcpy(y_label, lys, lys_len + 1); while(1) { float x = xo; memcpy(x_label, lxs, lxs_len + 1); while(1) { // build the label of the box char *label; if(!g_strcmp0(x_label, "_")) label = g_strdup(y_label); else if(!g_strcmp0(y_label, "_")) label = g_strdup(x_label); else { if(kl == 'Y') label = g_strconcat(y_label, x_label, NULL); else label = g_strconcat(x_label, y_label, NULL); } if(!first_label) first_label = label; last_label = label; // store it box_t *box = (box_t *)calloc(1, sizeof(box_t)); box->p.x = x; box->p.y = y; box->w = w; box->h = h; box->color_space = DT_COLORSPACE_NONE; // no color for this box yet if(kl == 'D') g_hash_table_insert(result->d_table, label, box); else g_hash_table_insert(result->box_table, label, box); if(kl == 'X' || kl == 'Y') labels = g_list_append(labels, g_strdup(label)); // increment in x direction if(!g_strcmp0(x_label, lxe)) break; x += xi; x_steps++; if(!strinc(x_label, sizeof(x_label))) ERROR; } x_max = MAX(x_max, x + w); // increment in y direction if(!g_strcmp0(y_label, lye)) break; y += yi; y_steps++; if(!strinc(y_label, sizeof(y_label))) ERROR; } y_max = MAX(y_max, y + h); if(kl == 'X' || kl == 'Y') g_hash_table_insert(result->patch_sets, g_strdup_printf("%s .. %s", first_label, last_label), labels); } else ERROR; } if(n_boxes != g_hash_table_size(result->d_table) + g_hash_table_size(result->box_table)) ERROR; // all the box lines are read and we know the bounding box, // so let's scale all the values to have a bounding box with the longer side having length 1 and start // at (0, 0) result->bb_w = x_max - x_min; result->bb_h = y_max - y_min; #define SCALE_X(x) x = (x - x_min) / result->bb_w #define SCALE_Y(y) y = (y - y_min) / result->bb_h GList *iter = result->f_list; while(iter) { f_line_t *f = iter->data; for(int i = 0; i < 4; i++) { SCALE_X(f->p[i].x); SCALE_Y(f->p[i].y); } iter = g_list_next(iter); } GHashTableIter table_iter; gpointer key, value; g_hash_table_iter_init(&table_iter, result->d_table); while(g_hash_table_iter_next(&table_iter, &key, &value)) { box_t *box = (box_t *)value; SCALE_X(box->p.x); SCALE_Y(box->p.y); box->w /= result->bb_w; box->h /= result->bb_h; } g_hash_table_iter_init(&table_iter, result->box_table); while(g_hash_table_iter_next(&table_iter, &key, &value)) { box_t *box = (box_t *)value; SCALE_X(box->p.x); SCALE_Y(box->p.y); box->w /= result->bb_w; box->h /= result->bb_h; } #undef SCALE_X #undef SCALE_Y } else if(!g_strcmp0(keyword, "BOX_SHRINK") && last_block < BLOCK_BOX_SHRINK) { last_block = BLOCK_BOX_SHRINK; if(c - line >= len) ERROR; result->box_shrink = parse_double(&c); } else if(!g_strcmp0(keyword, "REF_ROTATION") && last_block < BLOCK_REF_ROTATION) { last_block = BLOCK_REF_ROTATION; if(c - line >= len) ERROR; result->ref_rotation = parse_double(&c); } else if(!g_strcmp0(keyword, "XLIST") && last_block < BLOCK_XLIST) { last_block = BLOCK_XLIST; // skip until empty line, we don't care about these skip_block = 1; } else if(!g_strcmp0(keyword, "YLIST") && last_block < BLOCK_YLIST) { last_block = BLOCK_YLIST; // skip until empty line, we don't care about these skip_block = 1; } else if(!g_strcmp0(keyword, "EXPECTED") && last_block < BLOCK_EXPECTED) { last_block = BLOCK_EXPECTED; dt_colorspaces_color_profile_type_t color_space = DT_COLORSPACE_NONE; if(c - line >= len) ERROR; char *cs = parse_string(&c); if(c - line >= len) ERROR; unsigned int n_colors = parse_double(&c); if(!g_strcmp0(cs, "XYZ")) color_space = DT_COLORSPACE_XYZ; else if(!g_strcmp0(cs, "LAB")) color_space = DT_COLORSPACE_LAB; else ERROR; // read and store the numbers. // we use them 1) to draw visual hints on the grid and 2) as a fallback reference set // let's have another loop reading from the file. while(fgets(line, MAX_LINE_LENGTH, fp)) { if(line[0] == '\0' || line[0] == '\n') break; n_colors--; ssize_t len = strlen(line); char *c = line; char *label = parse_string(&c); box_t *box = (box_t *)g_hash_table_lookup(result->box_table, label); if(!box) ERROR; if(c - line >= len) ERROR; float c0 = parse_double(&c); if(c - line >= len) ERROR; float c1 = parse_double(&c); if(c - line >= len) ERROR; float c2 = parse_double(&c); set_color(box, color_space, c0, c1, c2); } if(n_colors != 0) ERROR; } else { fprintf(stderr, "unknown keyword `%s'\n", keyword); ERROR; } } fprintf(stderr, "cht `%s' done\n", filename); goto end; error: fprintf(stderr, "error parsing CHT file, (%s:%d)\n", __FUNCTION__, lineno); // clean up free_chart(result); result = NULL; end: if(fp) fclose(fp); return result; }