static int export_output_pin(int portnum, int pin, hal_bit_t ** dbase, hal_bit_t * pbase, hal_bit_t * rbase, int n) { int retval; /* export read only HAL pin for output data */ retval = hal_pin_bit_newf(HAL_IN, dbase + n, comp_id, "parport.%d.pin-%02d-out", portnum, pin); if (retval != 0) { return retval; } /* export parameter for polarity */ retval = hal_param_bit_newf(HAL_RW, pbase + n, comp_id, "parport.%d.pin-%02d-out-invert", portnum, pin); if (retval != 0) { return retval; } /* export parameter for reset */ if (rbase) retval = hal_param_bit_newf(HAL_RW, rbase + n, comp_id, "parport.%d.pin-%02d-out-reset", portnum, pin); return retval; }
static int hal_export_xfunctfv(const hal_export_xfunct_args_t *xf, const char *fmt, va_list ap) { int *prev, next, cmp, sz; hal_funct_t *nf, *fptr; char name[HAL_NAME_LEN + 1]; CHECK_HALDATA(); CHECK_LOCK(HAL_LOCK_LOAD); sz = rtapi_vsnprintf(name, sizeof(name), fmt, ap); if(sz == -1 || sz > HAL_NAME_LEN) { HALERR("length %d invalid for name starting '%s'", sz, name); return -ENOMEM; } HALDBG("exporting function '%s' type %d", name, xf->type); { hal_comp_t *comp __attribute__((cleanup(halpr_autorelease_mutex))); /* get mutex before accessing shared data */ rtapi_mutex_get(&(hal_data->mutex)); comp = halpr_find_owning_comp(xf->owner_id); if (comp == 0) { /* bad comp_id */ HALERR("funct '%s': owning component %d not found", name, xf->owner_id); return -EINVAL; } if (comp->type == TYPE_USER) { /* not a realtime component */ HALERR("funct '%s': component %s/%d is not realtime (%d)", name, comp->name, comp->comp_id, comp->type); return -EINVAL; } bool legacy = (halpr_find_inst_by_id(xf->owner_id) == NULL); // instances may export functs post hal_ready if (legacy && (comp->state > COMP_INITIALIZING)) { HALERR("funct '%s': called after hal_ready", name); return -EINVAL; } /* allocate a new function structure */ nf = alloc_funct_struct(); if (nf == 0) NOMEM("function '%s'", name); /* initialize the structure */ nf->uses_fp = xf->uses_fp; nf->owner_id = xf->owner_id; nf->reentrant = xf->reentrant; nf->users = 0; nf->handle = rtapi_next_handle(); nf->arg = xf->arg; nf->type = xf->type; nf->funct.l = xf->funct.l; // a bit of a cheat really rtapi_snprintf(nf->name, sizeof(nf->name), "%s", name); /* search list for 'name' and insert new structure */ prev = &(hal_data->funct_list_ptr); next = *prev; while (1) { if (next == 0) { /* reached end of list, insert here */ nf->next_ptr = next; *prev = SHMOFF(nf); /* break out of loop and init the new function */ break; } fptr = SHMPTR(next); cmp = strcmp(fptr->name, nf->name); if (cmp > 0) { /* found the right place for it, insert here */ nf->next_ptr = next; *prev = SHMOFF(nf); /* break out of loop and init the new function */ break; } if (cmp == 0) { /* name already in list, can't insert */ free_funct_struct(nf); HALERR("duplicate function '%s'", name); return -EINVAL; } /* didn't find it yet, look at next one */ prev = &(fptr->next_ptr); next = *prev; } // at this point we have a new function and can // yield the mutex by scope exit } /* init time logging variables */ nf->runtime = 0; nf->maxtime = 0; nf->maxtime_increased = 0; /* at this point we have a new function and can yield the mutex */ rtapi_mutex_give(&(hal_data->mutex)); switch (xf->type) { case FS_LEGACY_THREADFUNC: case FS_XTHREADFUNC: /* create a pin with the function's runtime in it */ if (hal_pin_s32_newf(HAL_OUT, &(nf->runtime), xf->owner_id, "%s.time",name)) { HALERR("failed to create pin '%s.time'", name); return -EINVAL; } *(nf->runtime) = 0; /* note that failure to successfully create the following params does not cause the "export_funct()" call to fail - they are for debugging and testing use only */ /* create a parameter with the function's maximum runtime in it */ nf->maxtime = 0; hal_param_s32_newf(HAL_RW, &(nf->maxtime), xf->owner_id, "%s.tmax", name); /* create a parameter with the function's maximum runtime in it */ nf->maxtime_increased = 0; hal_param_bit_newf(HAL_RO, &(nf->maxtime_increased), xf->owner_id, "%s.tmax-inc", name); break; case FS_USERLAND: // no timing pins/params ; } return 0; }
int rtapi_app_main(void){ int i, j, n; int retval; comp_id = hal_init("matrix_kb"); if (comp_id < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: ERROR: hal_init() failed\n"); return -1; } // allocate shared memory for data kb = hal_malloc(sizeof(kb_t)); if (kb == 0) { rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb component: Out of Memory\n"); hal_exit(comp_id); return -1; } // Count the instances. for (kb->num_insts = 0; config[kb->num_insts];kb->num_insts++); // Count the names. for (n = 0; names[n];n++); if (n && n != kb->num_insts){ rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: Number of sizes and number" " of names must match\n"); hal_exit(comp_id); return -1; } kb->insts = hal_malloc(kb->num_insts * sizeof(kb_inst_t)); for (i = 0; i < kb->num_insts; i++){ int a = 0; int c, r; kb_inst_t *inst = &kb->insts[i]; inst->index = i; inst->nrows = 0; inst->ncols = 0; inst->scan = 0; inst->keystroke = 0; inst->param.invert = 1; for(j = 0; config[i][j] !=0; j++){ int n = (config[i][j] | 0x20); //lower case if (n == 'x'){ inst->nrows = a; a = 0; } else if (n >= '0' && n <= '9'){ a = (a * 10) + (n - '0'); } else if (n == 's'){ inst->scan = 1; } } inst->ncols = a; if (inst->ncols == 0 || inst->nrows == 0){ rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: Invalid size format. should be NxN\n"); hal_exit(comp_id); return -1; } if (inst->ncols > 32){ rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: maximum number of columns is 32. Sorry\n"); hal_exit(comp_id); return -1; } for (inst->rowshift = 1; inst->ncols > (1 << inst->rowshift); inst->rowshift++); for (inst->keydown = 0xC0, inst->keyup = 0x80 ; (inst->nrows << inst->rowshift) > inst->keydown ; inst->keydown <<= 1, inst->keyup <<= 1); inst->hal.key = (hal_bit_t **)hal_malloc(inst->nrows * inst->ncols * sizeof(hal_bit_t*)); inst->now = hal_malloc(inst->nrows * sizeof(hal_u32_t)); inst->then = hal_malloc(inst->nrows * sizeof(hal_u32_t)); inst->row = 0; inst->param.rollover = 2; if (names[i]){ rtapi_snprintf(inst->name, sizeof(inst->name), "%s", names[i]); } else { rtapi_snprintf(inst->name, sizeof(inst->name), "matrix_kb.%i", i); } for (c = 0; c < inst->ncols; c++){ for (r = 0; r < inst->nrows; r++){ retval = hal_pin_bit_newf(HAL_OUT, &(inst->hal.key[r * inst->ncols + c]), comp_id, "%s.key.r%xc%x", inst->name, r, c); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: Failed to create output pin\n"); hal_exit(comp_id); return -1; } } } if (inst->scan){ //internally generated scanning inst->hal.rows = (hal_bit_t **)hal_malloc(inst->nrows * sizeof(hal_bit_t*)); inst->hal.cols = (hal_bit_t **)hal_malloc(inst->ncols * sizeof(hal_bit_t*)); for (r = 0; r < inst->nrows; r++){ retval = hal_pin_bit_newf(HAL_OUT, &(inst->hal.rows[r]), comp_id, "%s.row-%02i-out",inst->name, r); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: Failed to create output row pin\n"); hal_exit(comp_id); return -1; } } for (c = 0; c < inst->ncols; c++){ retval = hal_pin_bit_newf(HAL_IN, &(inst->hal.cols[c]), comp_id, "%s.col-%02i-in",inst->name, c); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: Failed to create input col pin\n"); hal_exit(comp_id); return -1; } } retval = hal_pin_u32_newf(HAL_OUT, &(inst->hal.keycode), comp_id, "%s.keycode",inst->name); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: Failed to create output pin\n"); hal_exit(comp_id); return -1; } retval = hal_param_bit_newf(HAL_RW, &(inst->param.invert), comp_id, "%s.negative-logic",inst->name); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: Failed to create output pin\n"); hal_exit(comp_id); return -1; } retval = hal_param_u32_newf(HAL_RW, &(inst->param.rollover), comp_id, "%s.key_rollover",inst->name); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: Failed to create rollover param\n"); hal_exit(comp_id); return -1; } } else // scanning by 7i73 or similar { retval = hal_pin_u32_newf(HAL_IN, &(inst->hal.keycode), comp_id, "%s.keycode",inst->name); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: Failed to create input pin\n"); hal_exit(comp_id); return -1; } } retval = hal_export_funct(inst->name, loop, inst, 1, 0, comp_id); //needs fp? if (retval < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "matrix_kb: ERROR: function export failed\n"); return -1; } } hal_ready(comp_id); return 0; }
int export_gpio(__u8 **ppcfg, board_data_t *board) { __u8 *data; int retval, export_out, export_oe; int portnum, boardnum, pin; char portchar; gpio_t *gpio, **p; int code, addr; __u8 *cfg_bytes; char name[HAL_NAME_LEN + 2]; __u32 mode0, mode1, source0, source1, source2, polarity, mask; /* read and validate config data */ data = *ppcfg; code = data[0]; addr = (data[1] << 8) + data[2]; cfg_bytes = &(data[3]); /* return ptr to next block */ *ppcfg = &(cfg_bytes[24]); /* Allocate HAL memory */ gpio = (gpio_t *)(hal_malloc(sizeof(gpio_t))); if ( gpio == NULL ) { rtapi_print_msg(RTAPI_MSG_ERR, "5i2x: ERROR: hal_malloc() failed\n"); return -1; } /* find end of linked list */ boardnum = board->num; portnum = 0; p = &(board->gpio); while ( *p != NULL ) { p = &((*p)->next); portnum++; } portchar = 'A' + portnum; /* add to end of list */ *p = gpio; gpio->next = NULL; /* save base address */ gpio->addr = board->base + addr; mode0 = 0; mode1 = 0; source0 = 0; source1 = 0; source2 = 0; polarity = 0; mask = 1; for ( pin = 0 ; pin < PINS_PER_PORT ; pin++ ) { if ( cfg_bytes[pin] & HAL_INPUT_PIN_MASK ) { /* export output HAL pins for the input bit */ retval = hal_pin_bit_newf(HAL_OUT, &(gpio->in[pin]), comp_id, "5i20.%d.pin-%c%02d-in", boardnum, portchar, pin); if (retval != 0) return retval; retval = hal_pin_bit_newf(HAL_OUT, &(gpio->in_not[pin]), comp_id, "5i20.%d.pin-%c%02d-in-not", boardnum, portchar, pin); if (retval != 0) return retval; /* initial values for pins */ *(gpio->in[pin]) = 0; *(gpio->in_not[pin]) = 1; } else { /* input pins not used, point them at a dummy */ gpio->in[pin] = &dummy_in; gpio->in_not[pin] = &dummy_in; } export_out = 0; export_oe = 0; if ( (cfg_bytes[pin] & SOURCE_MASK) == 0 ) { switch ( cfg_bytes[pin] & MODE_MASK ) { case MODE_TRI_STATE: export_oe = 1; case MODE_OUTPUT_ONLY: case MODE_OPEN_COLLECTOR: export_out = 1; case MODE_INPUT_ONLY: default: break; } } if ( export_out ) { /* export input HAL pin for the output bit */ retval = hal_pin_bit_newf(HAL_IN, &(gpio->out[pin]), comp_id, "5i20.%d.pin-%c%02d-out", boardnum, portchar, pin); if (retval != 0) return retval; /* export HAL param for inversion */ retval = hal_param_bit_newf(HAL_RW, &(gpio->out_invert[pin]), comp_id, "5i20.%d.pin-%c%02d-invert", boardnum, portchar, pin); if (retval != 0) return retval; /* set initial value for pin and param */ *(gpio->out[pin]) = 0; gpio->out_invert[pin] = 0; } else { /* output pin not used, point at a dummy */ gpio->out[pin] = &dummy_out; } if ( export_oe ) { /* export input HAL pin for the output enable bit */ retval = hal_pin_bit_newf(HAL_IN, &(gpio->out_ena[pin]), comp_id, "5i20.%d.pin-%c%02d-out-en", boardnum, portchar, pin); if (retval != 0) return retval; /* set initial value for pin */ *(gpio->out_ena[pin]) = 0; } else { /* output enable pin not used, point at a dummy */ gpio->out_ena[pin] = &dummy_oe; } /* set appropriate bits in config register words */ if ( cfg_bytes[pin] & SOURCE2_MASK ) source2 |= mask; if ( cfg_bytes[pin] & SOURCE1_MASK ) source1 |= mask; if ( cfg_bytes[pin] & SOURCE0_MASK ) source0 |= mask; if ( cfg_bytes[pin] & MODE1_MASK ) mode1 |= mask; if ( cfg_bytes[pin] & MODE0_MASK ) mode0 |= mask; if ( cfg_bytes[pin] & POLARITY_MASK ) polarity |= mask; mask <<= 1; } /* write config to registers */ iowrite32(source2, gpio->addr+GPIO_SOURCE1); iowrite32(source1, gpio->addr+GPIO_SOURCE1); iowrite32(source0, gpio->addr+GPIO_SOURCE0); iowrite32(mode1, gpio->addr+GPIO_MODE1); iowrite32(mode0, gpio->addr+GPIO_MODE0); iowrite32(polarity, gpio->addr+GPIO_POLARITY); /* export functions - one funct serves all ports */ if ( portnum > 0 ) { /* already exported */ return 0; } rtapi_snprintf(name, HAL_NAME_LEN, "5i20.%d.gpio.read", boardnum); retval = hal_export_funct(name, read_gpios, gpio, 0, 0, comp_id); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "5i20: ERROR: board %d GPIO read funct export failed\n", boardnum); return -1; } rtapi_snprintf(name, HAL_NAME_LEN, "5i20.%d.gpio.write", boardnum); retval = hal_export_funct(name, write_gpios, gpio, 0, 0, comp_id); if (retval != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "5i20: ERROR: board %d GPIO write funct export failed\n", boardnum); return -1; } return 0; }