int io_devctl(resmgr_context_t *ctp, io_devctl_t *msg, RESMGR_OCB_T *ocb)
{
    int     nbytes, status, previous;
    union 
    {
        data_t  data;
        int     data32;
        // ... other devctl types you can receive
    } *rx_data;
    

    /*
     Let common code handle DCMD_ALL_* cases.
     You can do this before or after you intercept devctl's depending
     on your intentions.  Here we aren't using any pre-defined values
     so let the system ones be handled first.
    */
    if ((status = iofunc_devctl_default(ctp, msg, ocb)) != _RESMGR_DEFAULT) {
        return(status);
    }
    status = nbytes = 0;

    /*
     Note this assumes that you can fit the entire data portion of
     the devctl into one message.  In reality you should probably
     perform a MsgReadv() once you know the type of message you
     have received to suck all of the data in rather than assuming
     it all fits in the message.  We have set in our main routine
     that we'll accept a total message size of up to 2k so we
     don't worry about it in this example where we deal with ints.
    */
    rx_data = _DEVCTL_DATA(msg->i);
    
    /* 
     rx_data is also used as output buffer since io_devctl_t is a union (see iofunc_devctl).
     int* outData = _DEVCTL_DATA(msg->o); is not needed! 
    */

    /*
     Three examples of devctl operations.
     SET: Setting a value (int) in the server
     GET: Getting a value (int) from the server
     SETGET: Setting a new value and returning with the previous value
    */
    switch (msg->i.dcmd) {
    case MY_DEVCTL_SETVAL: 
        global_integer = rx_data->data32;
        nbytes = 0;
        break;

    case MY_DEVCTL_GETVAL: 
        rx_data->data32 = global_integer;
        nbytes = sizeof(rx_data->data32);
        break;
        
    case MY_DEVCTL_SETGET: 
        previous = global_integer; 
        global_integer = rx_data->data.tx;
        rx_data->data.rx = previous;        //Overwrites tx data
        nbytes = sizeof(rx_data->data.rx);
        break;

    default:
        return(ENOSYS); 
    }

    /* Clear the return message ... note we saved our data _after_ this */
    memset(&msg->o, 0, sizeof(msg->o));

    /*
     If you wanted to pass something different to the return
     field of the devctl() you could do it through this member.
    */
    msg->o.ret_val = status;

    /* Indicate the number of bytes and return the message */
    msg->o.nbytes = nbytes;
    return(_RESMGR_PTR(ctp, &msg->o, sizeof(msg->o) + nbytes));
}
Example #2
0
int io_devctl (resmgr_context_t *ctp, io_devctl_t *msg, RESMGR_OCB_T *ocb){
  int nbytes, status, previous;
  uint32_t chip, page, reg;
  uint32_t value, temp, command, offset;
  uint32_t sequencer_base = 0x00100000;
  struct ICS660_FILTER filter_str;
  struct ICS660_FREQ freq_str;
  struct ICS660_PHASE phase_str;
  struct ICS660_sequencer seq_data;
  union {
    data_t data;
    uint32_t data32;
    int int_data;
    struct ICS660_FILTER filter_str;
    struct ICS660_FREQ freq_str;
    struct ICS660_PHASE phase_str;
    struct dc60m_p_val dc60m_p;
    struct dc60m_pg_reg pg_reg;
    struct ICS660_sequencer seq_data;
  } *rx_data;

  pdebug("IO_DEVCTL - entry -\n");

  if((status = iofunc_devctl_default(ctp, msg, ocb)) != _RESMGR_DEFAULT) 
    return(status);

  rx_data = _DEVCTL_DATA(msg->i);
  //pdebug("IO_DEVCTL - rx_data %d filter_str %d\n",rx_data,sizeof(rx_data->filter_str));
  //pdebug("IO_DEVCTL - msg %d  msg.i %d \n",msg,msg->i);

  command = get_device_command(msg->i.dcmd);
  pdebug("IO_DEVCTL - command %x  %x\n",msg->i.dcmd,command);

  switch(msg->i.dcmd){
    
  case ICS660_BOARD_RESET:
    pdebug("IO_DEVCTL - BOARD_RESET  %x\n",value);
    *(unsigned int*)(ics660->regs.board_reset) = RESET_VALUE;
    break;

  case ICS660_CLEAR_IMASK:
    pdebug("IO_DEVCTL - CLEAR_IMASK %x\n",value);
    *(unsigned int*)(ics660->regs.interrupt_mask) = (uint32_t)IMASK_VALUE;
    break;

  case ICS660_TRIGGER_SOURCE:
    value = rx_data->data32;
    pdebug("IO_DEVCTL - TRIGGER_SOURCE %x\n",value);
    temp = *(uint32_t *)ics660->regs.control & ~TRIGGER_SOURCE;
    *(uint32_t *)ics660->regs.control = temp | value;
    break;
    
  case ICS660_CLOCK_SELECT:
    value = rx_data->data32;
    temp = *(uint32_t *)ics660->regs.control & ~CLOCK_SELECT;
    value = (value << 1) & CLOCK_SELECT;
    pdebug("IO_DEVCTL - CLOCK_SELECT %x\n",value);
    *(uint32_t *)ics660->regs.control = temp | value;
    break;

  case ICS660_MODE:
    value = rx_data->data32;
    temp = *(uint32_t *)ics660->regs.control & ~MODE;
    value = value & MODE;
    pdebug("IO_DEVCTL - ICS660_MODE %x\n",value);
    *(uint32_t *)ics660->regs.control = temp | value;
    break;

  case ICS660_UPCONVERTER_SELECT:
    value = rx_data->data32;
    temp = *(uint32_t *)ics660->regs.control & ~UPCONVERTER_SELECT;
    value = (value << 4) & UPCONVERTER_SELECT;
    pdebug("IO_DEVCTL - UPCONVERTER_SELECT  %x\n",value);
    *(uint32_t *)ics660->regs.control = temp | value;
    break;

  case ICS660_DATA_SOURCE:
    value = rx_data->data32;
    temp = *(uint32_t *)ics660->regs.control & ~DATA_SOURCE;
    value = (value << 5) & DATA_SOURCE;
    pdebug("IO_DEVCTL - DATA_SOURCE %x\n",value);
    *(uint32_t *)ics660->regs.control = temp | value;
    break;

  case ICS660_FPDP_CLOCK_SEL:
    value = rx_data->data32;
    temp = *(uint32_t *)ics660->regs.control & ~FPDP_CLOCK_SEL;
    value = (value << 6) & FPDP_CLOCK_SEL;
    pdebug("IO_DEVCTL - FPDP_CLOCK_SEL %x\n",value);
    *(uint32_t *)ics660->regs.control = temp | value;
    break;

  case ICS660_FPDP_TERM:
    value = rx_data->data32;
    temp = *(uint32_t *)ics660->regs.control & ~FPDP_TERM;
    value = (value << 7) & FPDP_TERM;
    pdebug("IO_DEVCTL - FPDP_TERM %x\n",value);
    *(uint32_t *)ics660->regs.control = temp | value;
    break;

  case ICS660_SYNC_MASTER:
    value = rx_data->data32;
    temp = *(uint32_t *)ics660->regs.control & ~SYNC_MASTER;
    value = (value << 8) & SYNC_MASTER;
    pdebug("IO_DEVCTL - SYNC_MASTER %x\n",value);
    *(uint32_t *)ics660->regs.control = temp | value;
    break;

  case ICS660_SYNC_TERM:
    value = rx_data->data32;
    temp = *(uint32_t *)ics660->regs.control & ~SYNC_TERM;
    value = (value << 9) & SYNC_TERM;
    pdebug("IO_DEVCTL - SYNC_TERM %x\n",value);
    *(uint32_t *)ics660->regs.control = temp | value;
    break;

  case ICS660_DAC_ENABLE:
    value = rx_data->data32;
    temp = *(uint32_t *)ics660->regs.control & ~DAC_ENABLE;
    value = (value << 10) & DAC_ENABLE;
    pdebug("IO_DEVCTL - DAC_ENABLE %x\n",value);    
    *(uint32_t *)ics660->regs.control = temp | value;
    break;

  case ICS660_DAC_RESET:
    value = rx_data->data32;
    pdebug("IO_DEVCTL - DAC_RESET %x\n",value);
    *(uint32_t *)ics660->regs.dac_reset =  value;
    break;

  case ICS660_TRIGGER:
    value = rx_data->data32;
    temp = *(uint32_t *)ics660->regs.control & ~TRIGGER;
    value = (value << 11) & TRIGGER;
    pdebug("IO_DEVCTL - TRIGGER  %x\n",value);
    *(uint32_t *)ics660->regs.control = temp | value;
    break;

  case ICS660_BANK_WIDTH:
    value = rx_data->int_data;
    pdebug("IO_DEVCTL - BANK_WIDTH %d\n",value);
    *(uint32_t *)ics660->regs.bank_width = (uint32_t) value;
    break;
    
  case ICS660_BANK_LENGTH:
    value = rx_data->int_data;
    pdebug("IO_DEVCTL - BANK_LENGTH %d\n",value);
    *(uint32_t *)ics660->regs.bank_length = (uint32_t) value;
    break;

  case ICS660_PERSISTENCE_REG:
    value = rx_data->int_data;
    pdebug("IO_DEVCTL - PERSISTENCE %d\n",value);
    *(uint32_t *)ics660->regs.persistence = (uint32_t) value;
    break;
    
  case ICS660_TRANS_LENGTH:
    value = rx_data->int_data;
    pdebug("IO_DEVCTL - TRANSMIT_LENGTH: %d\n",value);
    *(uint32_t *)ics660->regs.trans_length = (uint32_t) value;
    break;

  case ICS660_WRITE_SEQUENCER:
    pdebug("IO_DEVCTL - WRITE_SEQUENCER offset: %x  value: %x\n",(uint32_t)rx_data->seq_data.offset,(uint32_t)rx_data->seq_data.value );
    seq_data.offset = rx_data->seq_data.offset;
    seq_data.value  = rx_data->seq_data.value;
    *(uint32_t *)(ics660->mem0 + sequencer_base + (uint32_t)seq_data.offset) 
    = (uint32_t)seq_data.value;
    break;

  case ICS660_LOAD_FILTER:
    pdebug("_ICS660_DRV: LOAD_FILTER\n");
    filter_str.chip = rx_data->filter_str.chip;
    filter_str.channel = rx_data->filter_str.channel;
    filter_str.f_corner = rx_data->filter_str.f_corner;
    filter_str.state_time = rx_data->filter_str.state_time;
    pdebug("_ICS660_DRV: LOAD_FILTER - \n  CHIP %d\n  CHANNEL %d\n  F_CORNER %d\n  STATE_TIME %f\n",filter_str.chip,filter_str.channel,filter_str.f_corner,filter_str.state_time);
    select_chip(ics660->mod_control_reg,filter_str.chip);
    load_filter_taps(ics660->dc60m_regs,filter_str.channel,filter_str.f_corner,
		     filter_str.state_time);
    select_chip(ics660->mod_control_reg,0);
    break;

  case ICS660_LOAD_FREQUENCY:
    pdebug("_ICS660_DRV: LOAD_FREQUENCY\n");
    freq_str.chip = rx_data->freq_str.chip;
    freq_str.channel = rx_data->freq_str.channel;
    freq_str.freq = rx_data->freq_str.freq;
    select_chip(ics660->mod_control_reg,freq_str.chip);
    pdebug("_ICS660_DRV: LOAD_FREQ - \n  CHIP %d\n  CHANNEL %d\n  FREQ %f\n",freq_str.chip,freq_str.channel,freq_str.freq);
    load_frequency(ics660->dc60m_regs,freq_str.channel,freq_str.freq);
    break;

  case ICS660_LOAD_PHASE:
    pdebug("_ICS660_DRV: LOAD_PHASE\n");
    phase_str.chip = rx_data->phase_str.chip;
    phase_str.channel = rx_data->phase_str.channel;
    phase_str.phase = rx_data->phase_str.phase;
    select_chip(ics660->mod_control_reg,phase_str.chip);
    load_phase(ics660->dc60m_regs,phase_str.channel,phase_str.phase);
    break;

  case ICS660_SET_DC_READY:
    pdebug("IO_DEVCTL - SET_DC_READY %x\n",value);
    set_dc_ready(ics660->mod_control_reg);
    break;

  case ICS660_RELEASE_RESETS:
    pdebug("IO_DEVCTL - RELEASE_RESETS %x\n",value);
    release_dc60m_resets(ics660->mod_control_reg,ics660->dc60m_regs);
    break;

  case ICS660_SET_CHIP:
    chip = rx_data->data32;
    select_chip(ics660->mod_control_reg,chip);
    break;

  case ICS660_SET_PAGE:
    chip = rx_data->data32;
    select_chip(ics660->mod_control_reg,chip);
    break;

  case ICS660_MODULE_CONTROL_REG:
    value = rx_data->data32;
    pdebug("IO_DEVCTL - MODULE_CONTROL_REG %d\n",value);
    *(uint32_t *)ics660->mod_control_reg = (uint32_t)value;
    break;

  case ICS660_DC60M_RESET:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - DC60M_RESET - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.reset = (uint32_t) value;
    break;

  case ICS660_MISCELANEOUS:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - MISCELANEOUS - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.miscelaneous = (uint32_t)value;
    break;

  case ICS660_SYNC_MODE:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - SYNC_MODE - chip %d value %x\n",chip,value);
   *(uint32_t *)ics660->dc60m_regs.sync_mode = (uint32_t) value;
    break;

  case ICS660_INTERPOLATION_MODE:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - INTERPOLATION_MODE - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.interpolation_mode = (uint32_t) value;
    break;

  case ICS660_CHANNEL_A_SYNC:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - CHANNEL_A_SYNC - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.channel_a_sync = (uint32_t) value;
    break;

  case ICS660_CHANNEL_B_SYNC:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - CHANNEL_B_SYNC - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.channel_b_sync = (uint32_t) value;
    break;

  case ICS660_CHANNEL_C_SYNC:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - CHANNEL_C_SYNC - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.channel_c_sync = (uint32_t) value;
    break;

  case ICS660_CHANNEL_D_SYNC:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - CHANNEL_D_SYNC - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.channel_d_sync = (uint32_t) value;
    break;

  case ICS660_CHANNEL_FLUSH_MODE:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - CHANNEL_FLUSH_MODE - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.channel_flush_mode = (uint32_t) value;
    break;

  case ICS660_INTERPOLATION_GAIN:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - INTERPOLATION_GAIN - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.interpolation_gain = (uint32_t) value;
    break;

  case ICS660_INTERPOLATION_BYTE0:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - INTERPOLATION_BYTE0 - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.interpolation_byte0 = (uint32_t) value;
    break;

  case ICS660_INTERPOLATION_BYTE1:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - INTERPOLATION_BYTE1 - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.interpolation_byte1 = (uint32_t) value;
    break;

  case ICS660_COUNTER_BYTE0:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - COUNTER_BYTE0 - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.counter_byte0 = (uint32_t) value;
    break;

  case ICS660_COUNTER_BYTE1:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - COUNTER_BYTE1 - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.counter_byte1 = (uint32_t) value;
    break;

  case ICS660_DC_STAT:
    chip = rx_data->dc60m_p.chip;
    value = rx_data->dc60m_p.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - STAT - chip %d value %x\n",chip,value);
    *(uint32_t *)ics660->dc60m_regs.stat = (uint32_t) value;
    break;

  case ICS660_SET_PAGE_REG:
    page = rx_data->pg_reg.page;
    chip = rx_data->pg_reg.chip;
    reg = rx_data->pg_reg.reg;
    value = rx_data->pg_reg.value;
    select_chip(ics660->mod_control_reg,chip);
    pdebug("IO_DEVCTL - PAGE_REG - chip %d page %d reg %d value %x\n",chip,page,reg,value);
    *(uint32_t *)ics660->dc60m_regs.page = page;
    *(uint32_t *)ics660->dc60m_regs.input_registers[(int)reg] = (uint32_t) value;
    break;


  default:
    pdebug("IO_DEVCTL - ERROR - no matching case %d\n",value);
    return(ENOSYS);
  }

  memset(&msg->o, 0, sizeof(msg->o));
  
  msg->o.ret_val = status;

  msg->o.nbytes = nbytes;
  return(_RESMGR_PTR(ctp, &msg->o, sizeof(msg->o)+nbytes));
}
Example #3
0
int io_devctl (resmgr_context_t *ctp, io_devctl_t *msg, RESMGR_OCB_T *ocb)
{
	int status;
	int dcmd;
	void *data;
	IOFUNC_ATTR_T *pattr = ocb->io_ocb.attr;
	das_func_t *pfunc = &pattr->func;

	/* temporary pointers for devctl data */
	struct sigevent event;
	das_sample_t *pset;
	das_da_sync_t *psync;
	das_din_t *pdin;
	das_dout_t *pdout;
	das_tmr_mode_t *ptmr_mode;
	long mask;
	int chnl;

	/// see if it's a standard POSIX-supported devctl()
	if ((status = iofunc_devctl_default (ctp, msg, (iofunc_ocb_t *) ocb)) != _RESMGR_DEFAULT) {
		return (status);
	}

	/** set up "data" to point to the data area after the devctl msg struct
         * this pointer is the same for input message and output message type
	 * save dcmd field and clear message header 
	 * when data is to be returned in the reply, ctp->iov is set
	 * up, otherwise no data is returned
	 */
	data = _DEVCTL_DATA(msg->i);  
	dcmd = msg->i.dcmd;
	memset (&msg->o, 0, sizeof (msg->o));

	///  see which command it was, and act on it
	switch (dcmd) {

	case DCMD_DAS_QUERY:
		* (das_info_typ *) data = pattr->das_info; 
		msg->o.nbytes = sizeof(das_info_typ);
	        return(_RESMGR_PTR(ctp, &msg->o, sizeof(msg->o) + msg->o.nbytes));
		
	case DCMD_DAS_AD_ENQ:
		event =  * (struct sigevent *) data;
		return (pfunc->ad_enqueue(ctp, ocb, event));
			
	case DCMD_DAS_AD_TERM:
		chnl = * (int *) data;
		return (pfunc->ad_term(ctp, ocb, chnl));
				
	case DCMD_DAS_AD_SET_SMP:
		pset = (das_sample_t *) data;
		return (pfunc->ad_set_sample(ctp, ocb,
			 pset->chnl, pset->ticks));
				
	case DCMD_DAS_DA_SYNC:
		psync = (das_da_sync_t *) data;
		status = pfunc->da_sync(ctp, ocb, psync->chnl, psync->data);
#ifdef DO_TRACE
		printf("DCMD_DAS_AD_DA_SYNC: status %d\n", status);
#endif
		return (status);

	case DCMD_DAS_DIG_DIR:
		pdin = (das_din_t *) data;
#ifdef DO_TRACE
		printf("DCMD_DAS_DIG_DIR: mask %#x\n", (unsigned int)pdin->bits);
#endif
		return (pfunc->digital_dir(ctp, ocb, pdin->bits));
				
	case DCMD_DAS_DIG_IN:
		pdin = (das_din_t *) data;
#ifdef DO_TRACE
		printf("DCMD_DAS_DIG_IN: port %#x bits %#x\n", 
			pdin->port, pdin->bits);
#endif
		status = pfunc->digital_in(ctp, ocb, pdin->port,
				&pdin->bits);
		msg->o.nbytes = sizeof(das_din_t);
	        return(_RESMGR_PTR(ctp, &msg->o, sizeof(msg->o) + msg->o.nbytes));
		
	case DCMD_DAS_DIG_OUT:
		pdout = (das_dout_t *) data;
		status = pfunc->digital_out(ctp, ocb, pdout->port,
				pdout->mask,pdout->bits, &pdout->old_bits,
				&pdout->new_bits);
		msg->o.nbytes = sizeof(msg) + sizeof(das_dout_t);
#ifdef DO_TRACE
		printf("&msg->o 0x%lx, pdout 0x%lx\n", (long) &msg->o, (long) pdout);
		printf("DCMD_DAS_DIG_OUT: old 0x%lx, new 0x%lx\n",
				pdout->old_bits, pdout->new_bits);
#endif
	        return(_RESMGR_PTR(ctp, &msg->o, sizeof(msg->o) + msg->o.nbytes));
				
	case DCMD_DAS_TMR_MODE:
		ptmr_mode = (das_tmr_mode_t *) data;
		return(pfunc->tmr_mode(ctp, ocb, ptmr_mode->timer,
			ptmr_mode->mode, ptmr_mode->value));
				
	/* This dcmd is for testing only, will call pfunc->ad_pulse
	 * normally called only when hardware interrupt is received.
	 */
	case DCMD_DAS_TEST_PULSE:
#ifdef DO_TRACE
		printf("DAS_TEST_PULSE, ppocb 0x%x\n", (int) &ocb);
#endif
		status = pfunc->ad_pulse((message_context_t *) ctp, 0, 0, &ocb);
		return(status);
	default:
		return (ENOSYS);
	}
}