Example #1
0
int stm32_adc_setup(void)
{
  static bool initialized = false;
  uint8_t channel[1] = {10};
  struct adc_dev_s *adc;
  int rv;

  if (initialized)
    {
      return OK;
    }

  ainfo("INFO: Initializing ADC12_IN10\n");
  stm32_configgpio(GPIO_ADC12_IN10);
  if ((adc = stm32_adcinitialize(1, channel, 1)) == NULL)
    {
      aerr("ERROR: Failed to get adc interface\n");
      return -ENODEV;
    }

  if ((rv = adc_register("/dev/adc0", adc)) < 0)
    {
      aerr("ERROR: adc_register failed: %d\n", rv);
      return rv;
    }

  initialized = true;
  ainfo("INFO: ADC12_IN10 initialized succesfully\n");
  return OK;
}
Example #2
0
int stm32_pwm_setup(void)
{
  static bool initialized = false;
  struct pwm_lowerhalf_s *pwm;
  int ret;

  /* Have we already initialized? */

  if (!initialized)
    {
      /* Call stm32_pwminitialize() to get an instance of the PWM interface */

      pwm = stm32_pwminitialize(STM3240G_EVAL_PWMTIMER);
      if (!pwm)
        {
          aerr("ERROR: Failed to get the STM32 PWM lower half\n");
          return -ENODEV;
        }

      /* Register the PWM driver at "/dev/pwm0" */

      ret = pwm_register("/dev/pwm0", pwm);
      if (ret < 0)
        {
          aerr("ERROR: pwm_register failed: %d\n", ret);
          return ret;
        }

      /* Now we are initialized */

      initialized = true;
    }

  return OK;
}
Example #3
0
int mbed_adc_setup(void)
{
    static bool initialized = false;
    struct adc_dev_s *adc;
    int ret;

    /* Check if we have already initialized */

    if (!initialized)
    {
        /* Call lpc17_adcinitialize() to get an instance of the ADC interface */

        adc = lpc17_adcinitialize();
        if (adc == NULL)
        {
            aerr("ERROR: Failed to get ADC interface\n");
            return -ENODEV;
        }

        /* Register the ADC driver at "/dev/adc0" */

        ret = adc_register("/dev/adc0", adc);
        if (ret < 0)
        {
            aerr("ERROR: adc_register failed: %d\n", ret);
            return ret;
        }

        /* Now we are initialized */

        initialized = true;
    }

    return OK;
}
Example #4
0
FAR struct dac_dev_s *stm32_dacinitialize(int intf)
{
  FAR struct dac_dev_s    *dev;
  FAR struct stm32_chan_s *chan;
  int ret;

#ifdef CONFIG_STM32_DAC1
  if (intf == 1)
    {
      ainfo("DAC1-1 Selected\n");
      dev = &g_dac1dev;
    }
  else
  if (intf == 2)
    {
      ainfo("DAC1-2 Selected\n");
      dev = &g_dac2dev;
    }
  else
#endif
#ifdef CONFIG_STM32_DAC2
  if (intf == 3)
    {
      ainfo("DAC2-1 Selected\n");
      dev = &g_dac3dev;
    }
  else
#endif
    {
      aerr("ERROR: No such DAC interface: %d\n", intf);
      errno = ENODEV;
      return NULL;
    }

  /* Make sure that the DAC block has been initialized */

  ret = dac_blockinit();
  if (ret < 0)
    {
      aerr("ERROR: Failed to initialize the DAC block: %d\n", ret);
      errno = -ret;
      return NULL;
    }

  /* Configure the selected DAC channel */

  chan = dev->ad_priv;
  ret  = dac_chaninit(chan);
  if (ret < 0)
    {
      aerr("ERROR: Failed to initialize DAC channel %d: %d\n", intf, ret);
      errno = -ret;
      return NULL;
    }

  return dev;
}
Example #5
0
int stm32_comp_setup(void)
{
  static bool initialized = false;
  struct comp_dev_s* comp = NULL;
  int ret;

  if (!initialized)
    {
      /* Get the comparator interface */

#ifdef CONFIG_STM32_COMP2
      comp = stm32_compinitialize(2);
      if (comp == NULL)
        {
          aerr("ERROR: Failed to get COMP%d interface\n", 2);
          return -ENODEV;
        }
#endif

#ifdef CONFIG_STM32_COMP4
      comp = stm32_compinitialize(4);
      if (comp == NULL)
        {
          aerr("ERROR: Failed to get COMP%d interface\n", 4);
          return -ENODEV;
        }
#endif

#ifdef CONFIG_STM32_COMP6
      comp = stm32_compinitialize(6);
      if (comp == NULL)
        {
          aerr("ERROR: Failed to get COMP%d interface\n", 6);
          return -ENODEV;
        }
#endif

      /* Register the comparator character driver at /dev/comp0 */

      ret = comp_register("/dev/comp0", comp);
      if (ret < 0)
        {
          aerr("ERROR: comp_register failed: %d\n", ret);
          return ret;
        }

      initialized = true;
    }

  return OK;
}
Example #6
0
int sam_pwm_setup(void)
{
  static bool initialized = false;
  struct pwm_lowerhalf_s *pwm;
  int ret;

  /* Have we already initialized? */

  if (!initialized)
    {
      /* Call sam_pwminitialize() to get an instance of the PWM interface */

      pwm = sam_pwminitialize(CONFIG_SAMA5D4EK_CHANNEL);
      if (!pwm)
        {
          _err("ERROR: Failed to get the SAMA5 PWM lower half\n");
          return -ENODEV;
        }

      /* Register the PWM driver at "/dev/pwm0" */

      ret = pwm_register("/dev/pwm0", pwm);
      if (ret < 0)
        {
          aerr("ERROR: pwm_register failed: %d\n", ret);
          return ret;
        }

      /* Now we are initialized */

      initialized = true;
    }

  return OK;
}
Example #7
0
static void tiva_adc_interrupt(struct tiva_adc_sse_s *sse)
{
  int ret;
  int irq = tiva_adc_getirq(sse->adc, sse->num);

  DEBUGASSERT(sse->ena == true);

  /* Disable further  interrupts. Interrupts will be re-enabled
   * after the worker thread executes.
   */

  up_disable_irq(irq);

  /* Clear interrupt status */

  tiva_adc_sse_clear_int(sse->adc, sse->num);

  /* Transfer processing to the worker thread.  Since interrupts are
   * disabled while the work is pending, no special action should be
   * required to protected the work queue.
   */

  DEBUGASSERT(sse->work.worker == NULL);
  ret = work_queue(HPWORK, &sse->work, tiva_adc_read, sse, 0);
  if (ret != 0)
    {
      aerr("ERROR: Failed to queue work: %d ADC.SSE: %d.%d\n",
           ret, sse->adc, sse->num);
    }
}
Example #8
0
static void tiva_adc_read(void *arg)
{
  struct tiva_adc_s     *priv;
  struct tiva_adc_sse_s *sse        = (struct tiva_adc_sse_s *)arg;
  struct adc_dev_s      *dev        = 0;
  int                    irq        = tiva_adc_getirq(sse->adc, sse->num);
  uint8_t                i          = 0;
  uint8_t                fifo_count = 0;
  int32_t                buf[8];

  /* Get exclusive access to the driver data structure */

  tiva_adc_lock(g_adcs[sse->adc], sse->num);

  /* Get sampled data */

  fifo_count = tiva_adc_sse_data(sse->adc, sse->num, buf);

  /* Determine which adc_dev_s we need */

  dev = g_devs[sse->adc];
  if (dev == NULL)
    {
      /* This is a serious error: indicates invalid pointer indirection
       * and should cause a full system stop.
       */

      aerr("ERROR: Invalid ADC device number given %d\n", sse->adc);
      DEBUGPANIC();
      return;
    }

  priv = (struct tiva_adc_s *)dev->ad_priv;

  /* Verify that the upper-half driver has bound its callback functions */

  if (priv->cb != NULL)
    {
      DEBUGASSERT(priv->cb->au_receive != NULL);

      for (i = 0; i < fifo_count; ++i)
        {
          /* Perform the data received callback */

          priv->cb->au_receive(dev,
                               tiva_adc_get_ain(sse->adc, sse->num, i),
                               buf[i]);
          ainfo("AIN%d = 0x%04x\n",
                tiva_adc_get_ain(sse->adc, sse->num, i), buf[i]);
        }
    }

  /* Exit, re-enabling ADC interrupts */

  up_enable_irq(irq);

  /* Release our lock on the ADC structure */

  tiva_adc_unlock(g_adcs[sse->adc], sse->num);
}
Example #9
0
static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg)
{
  FAR struct stm32_chan_s *chan = dev->ad_priv;
  int ret = OK;

  switch (cmd)
    {
#ifdef HAVE_DMA
      case IO_DMABUFFER_INIT:
        {
          uint16_t *buffer = (uint16_t *)arg;

          /* The caller is responsible for providing buffer with
           * suitable length equal to CONFIG_STM32_DACxCHy_DMA_BUFFER_SIZE
           */

          dma_bufferinit(chan, buffer, chan->buffer_len * sizeof(buffer));
          break;
        }
#endif

      default:
        {
          aerr("ERROR: Unknown cmd: %d\n", cmd);
          ret = -ENOTTY;
          break;
        }
    }

  return ret;
}
Example #10
0
void Matrix3f::fixError() {
  Vector3f a(data, 0);
  Vector3f b(data, 3);

  float err = a.dot(b) / 2;

  Vector3f aerr(a.data, 0);
  aerr.multiply(err);
  Vector3f berr(a.data, 0);
  berr.multiply(err);

  a.substract(&berr);
  a.normalize();

  b.substract(&berr);
  b.normalize();

  Vector3f c(0, 0, 0);
  a.cross(b.data, c.data);

  for (int j = 0; j < 3; j++) {
    data[j] = a.data[j];
  }
  for (int j = 0; j < 3; j++) {
    data[j + 3] = b.data[j];
  }
  for (int j = 0; j < 3; j++) {
    data[j + 6] = c.data[j];
  }
}
Example #11
0
int stm32_adc_setup(void)
{
#ifdef CONFIG_STM32_ADC1
  static bool initialized = false;
  struct adc_dev_s *adc;
  int ret;
  int i;

  /* Check if we have already initialized */

  if (!initialized)
    {
      /* Configure the pins as analog inputs for the selected channels */

      for (i = 0; i < ADC1_NCHANNELS; i++)
        {
          stm32_configgpio(g_pinlist[i]);
        }

      /* Call stm32_adcinitialize() to get an instance of the ADC interface */

      adc = stm32_adcinitialize(1, g_chanlist, ADC1_NCHANNELS);
      if (adc == NULL)
        {
          aerr("ERROR: Failed to get ADC interface\n");
          return -ENODEV;
        }

      /* Register the ADC driver at "/dev/adc0" */

      ret = adc_register("/dev/adc0", adc);
      if (ret < 0)
        {
          aerr("ERROR: adc_register failed: %d\n", ret);
          return ret;
        }

      /* Now we are initialized */

      initialized = true;
    }

  return OK;
#else
  return -ENOSYS;
#endif
}
Example #12
0
int board_adc_setup(void)
{
#ifdef CONFIG_SAMA5_ADC
  static bool initialized = false;
  struct adc_dev_s *adc;
  int ret;

  /* Check if we have already initialized */

  if (!initialized)
    {
      /* Call stm32_adcinitialize() to get an instance of the ADC interface */

      adc = sam_adc_initialize();
      if (adc == NULL)
        {
          aerr("ERROR: Failed to get ADC interface\n");
          return -ENODEV;
        }

      /* Register the ADC driver at "/dev/adc0" */

      ret = adc_register("/dev/adc0", adc);
      if (ret < 0)
        {
          aerr("ERROR: adc_register failed: %d\n", ret);
          return ret;
        }

      /* Now we are initialized */

      initialized = true;
    }

  return OK;
#else
  return -ENOSYS;
#endif
}
Example #13
0
void tiva_adc_irq_detach(uint8_t adc, uint8_t sse)
{
  uint32_t ret = 0;
  int irq = sse2irq[SSE_IDX(adc, sse)];

  /* Disable ADC interrupts at the level of the AIC */

  up_disable_irq(irq);

  /* Then detach the ADC interrupt handler. */

  ret = irq_detach(irq);
  if (ret < 0)
    {
      aerr("ERROR: Failed to detach IRQ %d: %d\n", irq, ret);
      return;
    }
}
Example #14
0
void tiva_adc_irq_attach(uint8_t adc, uint8_t sse, xcpt_t isr)
{

  uint32_t ret = 0;
  int irq = sse2irq[SSE_IDX(adc, sse)];

#ifdef CONFIG_DEBUG_ANALOG
  ainfo("assigning ISR=0x%p to ADC%d SSE%d IRQ=0x%02x...\n",
        isr, adc, sse, irq);
#endif

  ret = irq_attach(irq, isr, NULL);
  if (ret < 0)
    {
      aerr("ERROR: Failed to attach IRQ %d: %d\n", irq, ret);
      return;
    }

  up_enable_irq(irq);
}
Example #15
0
static char *escape_string(char *s)
{
  char buf[256];
  char *t = buf;

  for (; *s != 0; s++) {
    if (*s == '"') {
      strcpy(t, "\\\"");
      t += strlen(t);
      continue;
    }
    if (*s == '\\') {
      strcpy(t, "\\\\");
      t += strlen(t);
      continue;
    }
    *t++ = *s;
  }
  *t++ = *s;
  if (t - buf > sizeof(buf))
    aerr("string is too long\n");
  return strcpy(s, buf);
}
Example #16
0
/*
 * Read a register name.  Return register value, -1 if no register found
 */
int
reg(void)
{
        struct mne *mp;
        char id[NCPS];

        getid(id, -1);
        if ((mp = mlookup(id))==NULL) {
                aerr();
                return (-1);
        }
        switch (mp->m_type) {
        case S_A:
        case S_AB:
        case S_DPTR:
        case S_PC:
        case S_REG:
                return ((int) mp->m_valu);

        default:
                return (-1);
        }
}
Example #17
0
int i2schar_devinit(void)
{
  static bool initialized = false;
  struct i2s_dev_s *i2s;
  int ret;

  /* Have we already initialized? */

  if (!initialized)
    {
      /* Call sam_ssc_initialize() to get an instance of the SSC/I2S interface */

      i2s = sam_ssc_initialize(CONFIG_SAMA5D3XPLAINED_SSC_PORT);
      if (!i2s)
        {
          _err("ERROR: Failed to get the SAMA5 SSC/I2S driver for SSC%d\n",
              CONFIG_SAMA5D3XPLAINED_SSC_PORT);
          return -ENODEV;
        }

      /* Register the I2S character driver at "/dev/i2schar0" */

      ret = i2schar_register(i2s, CONFIG_SAMA5D3XPLAINED_I2SCHAR_MINOR);
      if (ret < 0)
        {
          aerr("ERROR: i2schar_register failed: %d\n", ret);
          return ret;
        }

      /* Now we are initialized */

      initialized = true;
    }

  return OK;
}
Example #18
0
int mbed_pwm_setup(void)
{
  static bool initialized = false;
  struct pwm_lowerhalf_s *pwm;
  struct pwm_lowerhalf_s *mcpwm;
  struct pwm_lowerhalf_s *timer;
  int ret;

  /* Have we already initialized? */

  if (!initialized)
    {
      /* Call lpc17_pwminitialize() to get an instance of the PWM interface */

      pwm = lpc17_pwminitialize(0);
      if (!pwm)
        {
          aerr("ERROR: Failed to get the LPC17XX PWM lower half\n");
          return -ENODEV;
        }

      /* Register the PWM driver at "/dev/pwm0" */

      ret = pwm_register("/dev/pwm0", pwm);
      if (ret < 0)
        {
          aerr("ERROR: pwm_register failed: %d\n", ret);
          return ret;
        }

      mcpwm = lpc17_mcpwminitialize(0);
      if (!mcpwm)
        {
          aerr("ERROR: Failed to get the LPC17XX MOTOR PWM lower half\n");
          return -ENODEV;
        }

      /* Register the MOTOR CONTROL PWM driver at "/dev/mcpwm0" */

      ret = pwm_register("/dev/mcpwm0", mcpwm);
      if (ret < 0)
        {
          aerr("ERROR: mcpwm_register failed: %d\n", ret);
          return ret;
        }

      timer = lpc17_timerinitialize(0);
      if (!timer)
        {
          aerr("ERROR: Failed to get the LPC17XX TIMER lower half\n");
          return -ENODEV;
        }

      /* Register the PWM driver at "/dev/timer0" */

      ret = pwm_register("/dev/timer0", timer);
      if (ret < 0)
        {
          aerr("ERROR: timer_register failed: %d\n", ret);
          return ret;
        }

      /* Now we are initialized */

      initialized = true;
    }

  return OK;
}
Example #19
0
static int dac_chaninit(FAR struct stm32_chan_s *chan)
{
  uint16_t clearbits;
  uint16_t setbits;
#ifdef HAVE_TIMER
  int ret;
#endif

  /* Is the selected channel already in-use? */

  if (chan->inuse)
    {
      /* Yes.. then return EBUSY */

      return -EBUSY;
    }

  /* Configure the DAC output pin:
   *
   * DAC -" Once the DAC channelx is enabled, the corresponding GPIO pin
   * (PA4 or PA5) is automatically connected to the analog converter output
   * (DAC_OUTx). In order to avoid parasitic consumption, the PA4 or PA5 pin
   * should first be configured to analog (AIN)".
   */

  stm32_configgpio(chan->pin);

  /* DAC channel configuration:
   *
   * - Set the trigger selection based upon the configuration.
   * - Set wave generation == None.
   * - Enable the output buffer.
   */

  /* Disable before change */

  stm32_dac_modify_cr(chan, DAC_CR_EN, 0);

  clearbits = DAC_CR_TSEL_MASK |
              DAC_CR_MAMP_MASK |
              DAC_CR_WAVE_MASK |
              DAC_CR_BOFF;
  setbits =
      chan->tsel |           /* Set trigger source (SW or timer TRGO event) */
      DAC_CR_MAMP_AMP1 |     /* Set waveform characteristics */
      DAC_CR_WAVE_DISABLED | /* Set no noise */
      DAC_CR_BOFF_EN;        /* Enable output buffer */
  stm32_dac_modify_cr(chan, clearbits, setbits);

#ifdef HAVE_DMA
  /* Determine if DMA is supported by this channel */

  if (chan->hasdma)
    {
      /* Remap DMA request if necessary*/

      dma_remap(chan);

      /* DAC trigger enable if not external triggering */

      if (!chan->text)
        {
          stm32_dac_modify_cr(chan, 0, DAC_CR_TEN);
        }

      /* Allocate a DMA channel */

      chan->dma = stm32_dmachannel(chan->dmachan);
      if (!chan->dma)
        {
          aerr("ERROR: Failed to allocate a DMA channel\n");
          return -EBUSY;
        }

      /* Configure the timer that supports the DMA operation
       * Do nothing if HRTIM is selected as trigger.
       * All necessary configuration is done in the HRTIM driver.
       */

#ifdef HAVE_TIMER
      if (chan->timer != TIM_INDEX_HRTIM)
        {
          ret = dac_timinit(chan);
          if (ret < 0)
            {
              aerr("ERROR: Failed to initialize the DMA timer: %d\n", ret);
              return ret;
            }
        }
#endif
    }
#endif

  /* Mark the DAC channel "in-use" */

  chan->inuse = 1;
  return OK;
}
Example #20
0
static int dac_timinit(FAR struct stm32_chan_s *chan)
{
  uint32_t pclk;
  uint32_t prescaler;
  uint32_t timclk;
  uint32_t reload;
  uint32_t regaddr;
  uint32_t setbits;

  /* Configure the time base: Timer period, prescaler, clock division,
   * counter mode (up).
   */

  /* Enable the timer.  At most, two of the following cases (pluse the
   * default) will be enabled
   */

  regaddr = STM32_RCC_APB1ENR;

  switch (chan->timer)
    {
#ifdef NEED_TIM2
      case 2:
        setbits = RCC_APB1ENR_TIM2EN;
        pclk    = BOARD_TIM2_FREQUENCY;
        break;
#endif
#ifdef NEED_TIM3
      case 3:
        setbits = RCC_APB1ENR_TIM3EN;
        pclk    = BOARD_TIM3_FREQUENCY;
        break;
#endif
#ifdef NEED_TIM4
      case 4:
        setbits = RCC_APB1ENR_TIM4EN;
        pclk    = BOARD_TIM4_FREQUENCY;
        break;
#endif
#ifdef NEED_TIM5
      case 5:
        setbits = RCC_APB1ENR_TIM5EN;
        pclk    = BOARD_TIM5_FREQUENCY;
        break;
#endif
#ifdef NEED_TIM6
      case 6:
        setbits = RCC_APB1ENR_TIM6EN;
        pclk    = BOARD_TIM6_FREQUENCY;
        break;
#endif
#ifdef NEED_TIM7
      case 7:
        setbits = RCC_APB1ENR_TIM7EN;
        pclk    = BOARD_TIM7_FREQUENCY;
        break;
#endif
#ifdef NEED_TIM8
      case 8:
        regaddr = STM32_RCC_APB2ENR;
        setbits = RCC_APB2ENR_TIM8EN;
        pclk    = BOARD_TIM8_FREQUENCY;
        break;
#endif
      default:
        aerr("ERROR: Could not enable timer\n");
        return -EINVAL;
    }

  /* Enable the timer. */

  modifyreg32(regaddr, 0, setbits);

  /* Calculate optimal values for the timer prescaler and for the timer reload
   * register.  If 'frequency' is the desired frequency, then
   *
   *   reload = timclk / frequency
   *   timclk = pclk / presc
   *
   * Or,
   *
   *   reload = pclk / presc / frequency
   *
   * There are many solutions to this this, but the best solution will be the
   * one that has the largest reload value and the smallest prescaler value.
   * That is the solution that should give us the most accuracy in the timer
   * control.  Subject to:
   *
   *   0 <= presc  <= 65536
   *   1 <= reload <= 65535
   *
   * So presc = pclk / 65535 / frequency would be optimal.
   *
   * Example:
   *
   *  pclk      = 42 MHz
   *  frequency = 100 Hz
   *
   *  prescaler = 42,000,000 / 65,535 / 100
   *            = 6.4 (or 7 -- taking the ceiling always)
   *  timclk    = 42,000,000 / 7
   *            = 6,000,000
   *  reload    = 6,000,000 / 100
   *            = 60,000
   */

  prescaler = (pclk / chan->tfrequency + 65534) / 65535;
  if (prescaler < 1)
    {
      prescaler = 1;
    }
  else if (prescaler > 65536)
    {
      prescaler = 65536;
    }

  timclk = pclk / prescaler;

  reload = timclk / chan->tfrequency;
  if (reload < 1)
    {
      reload = 1;
    }
  else if (reload > 65535)
    {
      reload = 65535;
    }

  /* Set the reload and prescaler values */

  tim_putreg(chan, STM32_BTIM_ARR_OFFSET, (uint16_t)reload);
  tim_putreg(chan, STM32_BTIM_PSC_OFFSET, (uint16_t)(prescaler - 1));

  /* Count mode up, auto reload */

  tim_modifyreg(chan, STM32_BTIM_CR1_OFFSET, 0, ATIM_CR1_ARPE);

  /* Selection TRGO selection: update */

  tim_modifyreg(chan, STM32_BTIM_CR2_OFFSET, ATIM_CR2_MMS_MASK,
                ATIM_CR2_MMS_UPDATE);

  /* Update DMA request enable ???? */
#if 0
  tim_modifyreg(chan, STM32_BTIM_DIER_OFFSET, 0, ATIM_DIER_UDE);
#endif

  /* Enable the counter */

  tim_modifyreg(chan, STM32_BTIM_CR1_OFFSET, 0, ATIM_CR1_CEN);
  return OK;
}
Example #21
0
/*  Classify argument as to address mode */
int
addr(struct expr *esp)
{
        int c;
        unsigned rd;

        if ((c = getnb()) == '#') {
                /*  Immediate mode */
                expr(esp, 0);
                esp->e_mode = S_IMMED;
        }
        else if (c == '@') {
                /* choices are @R0, @R1, @DPTR, @A+PC, @A+DPTR */
                switch (reg()) {
                case R0:
                        esp->e_mode = S_AT_R;
                        esp->e_addr = R0;
                        break;
                case R1:
                        esp->e_mode = S_AT_R;
                        esp->e_addr = R1;
                        break;
                case DPTR:
                        esp->e_mode = S_AT_DP;
                        esp->e_addr = DPTR;
                        break;
                case A:
                        if (getnb() == '+') {
                                rd = reg();
                                if (rd == PC) {
                                        esp->e_mode = S_AT_APC;
                                        esp->e_addr = 0;
                                } else if (rd == DPTR) {
                                        esp->e_mode = S_AT_ADP;
                                        esp->e_addr = 0;
                                } else {
                                        aerr();
                                }
                        } else
                                aerr();
                        break;
                }

                esp->e_flag = 0;
                esp->e_base.e_ap = NULL;
        }
        else if (c == '*') {
                if ((c = getnb()) == '/') {
                        /* Force inverted bit */
                        expr(esp, 0);
                        esp->e_mode = S_NOT_BIT;
                } else {
                        unget(c);
                        /* Force direct page */
                        expr(esp, 0);
                        esp->e_mode = S_DIR;
                }
                if (esp->e_addr & ~0xFF)
                        err('d');
        }
        else if (c == '/') {
                /* Force inverted bit  */
                expr(esp, 0);
                esp->e_mode = S_NOT_BIT;
        }
        else {
                unget(c);

                /* try for register: A, AB, R0-R7, DPTR, PC, Cy */
                if ((esp->e_addr = admode(reg51)) != -1) {
                        switch (esp->e_addr) {
                        case A:
                                esp->e_mode = S_A;
                                break;
                        case AB:
                                esp->e_mode = S_RAB;
                                break;
                        case DPTR:
                                esp->e_mode = S_DPTR;
                                break;
                        case PC:
                                esp->e_mode = S_PC;
                                break;
                        case C:
                                esp->e_mode = S_C;
                                break;
                        default:
                                /* R0-R7 */
                                esp->e_mode = S_REG;
                        }
                } else {
                        /* Must be an expression */
                        esp->e_addr = 0;
                        expr(esp, 0);
                        if ((!esp->e_flag)
                                && (esp->e_base.e_ap==NULL)
                                && !(esp->e_addr & ~0xFF)) {
                                esp->e_mode = S_DIR;
                        } else {
                                esp->e_mode = S_EXT;
                        }
                }
        }
        return (esp->e_mode);
}
Example #22
0
int stm32_adc_setup(void)
{
  static bool initialized = false;
  FAR struct adc_dev_s *adc;
  int ret;
  int i;

  /* Check if we have already initialized */

  if (!initialized)
    {
      /* DEV1 */
      /* Configure the pins as analog inputs for the selected channels */

      for (i = 0; i < DEV1_NCHANNELS; i++)
        {
          stm32_configgpio(g_pinlist1[i]);
        }

      /* Call stm32_adcinitialize() to get an instance of the ADC interface */

      adc = stm32_adcinitialize(DEV1_PORT, g_chanlist1, DEV1_NCHANNELS);
      if (adc == NULL)
        {
          aerr("ERROR: Failed to get ADC interface 1\n");
          return -ENODEV;
        }

      /* Register the ADC driver at "/dev/adc0" */

      ret = adc_register("/dev/adc0", adc);
      if (ret < 0)
        {
          aerr("ERROR: adc_register /dev/adc0 failed: %d\n", ret);
          return ret;
        }

#ifdef DEV2_PORT

      /* DEV2 */
      /* Configure the pins as analog inputs for the selected channels */

      for (i = 0; i < DEV2_NCHANNELS; i++)
        {
          stm32_configgpio(g_pinlist2[i]);
        }

      /* Call stm32_adcinitialize() to get an instance of the ADC interface */

      adc = stm32_adcinitialize(DEV2_PORT, g_chanlist2, DEV2_NCHANNELS);
      if (adc == NULL)
        {
          aerr("ERROR: Failed to get ADC interface 2\n");
          return -ENODEV;
        }

      /* Register the ADC driver at "/dev/adc1" */

      ret = adc_register("/dev/adc1", adc);
      if (ret < 0)
        {
          aerr("ERROR: adc_register /dev/adc1 failed: %d\n", ret);
          return ret;
        }
#endif

      initialized = true;

    }

  return OK;
}
Example #23
0
int tiva_adc_initialize(const char *devpath, struct tiva_adc_cfg_s *cfg,
                                      uint32_t clock, uint8_t sample_rate)
{
  struct tiva_adc_s *adc;
  int ret = 0;

  ainfo("initializing...\n");

  /* Initialize the private ADC device data structure */

  adc = tiva_adc_struct_init(cfg);
  if (adc == NULL)
    {
      aerr("ERROR: Invalid ADC device number: expected=%d actual=%d\n",
           0, cfg->adc);
      return -ENODEV;
    }

  /* Turn on peripheral */

  if (tiva_adc_enable(adc->devno, true) < 0)
    {
      aerr("ERROR: failure to power ADC peripheral (devno=%d)\n",
           cfg->adc);
      return ret;
    }

  /* Perform actual initialization */

  tiva_adc_one_time_init(clock, sample_rate);
  tiva_adc_configure(cfg);
  tiva_adc_irqinitialize(cfg);

  /* Now we are initialized */

  adc->ena = true;
  adc->cb  = NULL;

#ifdef CONFIG_DEBUG_ANALOG
  tiva_adc_runtimeobj_vals();
#endif

  /* Ensure our lower half is valid */

  if (adc->dev == NULL)
    {
      aerr("ERROR: Failed to get interface %s\n", devpath);
      return -ENODEV;
    }

  ainfo("adc_dev_s=0x%08x\n", adc->dev);

  /* Register the ADC driver */

  ainfo("Register the ADC driver at %s\n", devpath);

  ret = adc_register(devpath, adc->dev);
  if (ret < 0)
    {
      aerr("ERROR: Failed to register %s to character driver: %d\n",
           devpath, ret);
      return ret;
    }

  return OK;
}
Example #24
0
int main(int argc, char *argv[])
{
  FILE *fout, *fasm, *fhdr = NULL, *frlist;
  const struct parsed_proto *pp;
  int no_decorations = 0;
  char comment_char = '#';
  char words[20][256];
  char word[256];
  char line[256];
  char last_sym[32];
  unsigned long val;
  unsigned long cnt;
  const char *sym;
  enum dx_type type;
  char **pub_syms;
  int pub_sym_cnt = 0;
  int pub_sym_alloc;
  char **rlist;
  int rlist_cnt = 0;
  int rlist_alloc;
  int header_mode = 0;
  int is_ro = 0;
  int is_label;
  int is_bss;
  int wordc;
  int first;
  int arg_out;
  int arg = 1;
  int len;
  int w, i;
  char *p;
  char *p2;

  if (argc < 4) {
    // -nd: no symbol decorations
    printf("usage:\n%s [-nd] [-i] [-a] <.s> <.asm> <hdrf> [rlist]*\n"
           "%s -hdr <.h> <.asm>\n",
      argv[0], argv[0]);
    return 1;
  }

  for (arg = 1; arg < argc; arg++) {
    if (IS(argv[arg], "-nd"))
      no_decorations = 1;
    else if (IS(argv[arg], "-i"))
      g_cconv_novalidate = 1;
    else if (IS(argv[arg], "-a")) {
      comment_char = '@';
      g_arm_mode = 1;
    }
    else if (IS(argv[arg], "-hdr"))
      header_mode = 1;
    else
      break;
  }

  arg_out = arg++;

  asmfn = argv[arg++];
  fasm = fopen(asmfn, "r");
  my_assert_not(fasm, NULL);

  if (!header_mode) {
    hdrfn = argv[arg++];
    fhdr = fopen(hdrfn, "r");
    my_assert_not(fhdr, NULL);
  }

  fout = fopen(argv[arg_out], "w");
  my_assert_not(fout, NULL);

  pub_sym_alloc = 64;
  pub_syms = malloc(pub_sym_alloc * sizeof(pub_syms[0]));
  my_assert_not(pub_syms, NULL);

  rlist_alloc = 64;
  rlist = malloc(rlist_alloc * sizeof(rlist[0]));
  my_assert_not(rlist, NULL);

  for (; arg < argc; arg++) {
    frlist = fopen(argv[arg], "r");
    my_assert_not(frlist, NULL);

    while (my_fgets(line, sizeof(line), frlist)) {
      p = sskip(line);
      if (*p == 0 || *p == ';')
        continue;

      p = next_word(words[0], sizeof(words[0]), p);
      if (words[0][0] == 0)
        continue;

      if (rlist_cnt >= rlist_alloc) {
        rlist_alloc = rlist_alloc * 2 + 64;
        rlist = realloc(rlist, rlist_alloc * sizeof(rlist[0]));
        my_assert_not(rlist, NULL);
      }
      rlist[rlist_cnt++] = strdup(words[0]);
    }

    fclose(frlist);
    frlist = NULL;
  }

  if (rlist_cnt > 0)
    qsort(rlist, rlist_cnt, sizeof(rlist[0]), cmpstringp);

  qsort(unwanted_syms, ARRAY_SIZE(unwanted_syms),
    sizeof(unwanted_syms[0]), cmpstringp);

  last_sym[0] = 0;

  while (1) {
    next_section(fasm, line);
    if (feof(fasm))
      break;
    if (IS(line + 1, "text"))
      continue;

    if (IS(line + 1, "rdata")) {
      is_ro = 1;
      if (!header_mode)
        fprintf(fout, "\n.section .rodata\n");
    }
    else if (IS(line + 1, "data")) {
      is_ro = 0;
      if (!header_mode)
        fprintf(fout, "\n.data\n");
    }
    else
      aerr("unhandled section: '%s'\n", line);

    if (!header_mode)
      fprintf(fout, ".align %d\n", align_value(4));

    while (my_fgets(line, sizeof(line), fasm))
    {
      sym = NULL;
      asmln++;

      p = sskip(line);
      if (*p == 0)
        continue;

      if (*p == ';') {
        if (IS_START(p, ";org") && sscanf(p + 5, "%Xh", &i) == 1) {
          // ;org is only seen at section start, so assume . addr 0
          i &= 0xfff;
          if (i != 0 && !header_mode)
            fprintf(fout, "\t\t  .skip 0x%x\n", i);
        }
        continue;
      }

      for (wordc = 0; wordc < ARRAY_SIZE(words); wordc++) {
        p = sskip(next_word_s(words[wordc], sizeof(words[0]), p));
        if (*p == 0 || *p == ';') {
          wordc++;
          break;
        }
        if (*p == ',') {
          p = sskip(p + 1);
        }
      }

      if (*p == ';') {
        p = sskip(p + 1);
        if (IS_START(p, "sctclrtype"))
          g_func_sym_pp = NULL;
      }

      if (wordc == 2 && IS(words[1], "ends"))
        break;
      if (wordc <= 2 && IS(words[0], "end"))
        break;
      if (wordc < 2)
        aerr("unhandled: '%s'\n", words[0]);

      // don't cares
      if (IS(words[0], "assume"))
        continue;

      if (IS(words[0], "align")) {
        if (header_mode)
          continue;

        val = parse_number(words[1]);
        fprintf(fout, "\t\t  .align %d", align_value(val));
        goto fin;
      }

      w = 1;
      type = parse_dx_directive(words[0]);
      if (type == DXT_UNSPEC) {
        type = parse_dx_directive(words[1]);
        sym = words[0];
        w = 2;
      }
      if (type == DXT_UNSPEC)
        aerr("unhandled decl: '%s %s'\n", words[0], words[1]);

      if (sym != NULL)
      {
        if (header_mode) {
          int is_str = 0;

          fprintf(fout, "extern ");
          if (is_ro)
            fprintf(fout, "const ");

          switch (type) {
          case DXT_BYTE:
            for (i = w; i < wordc; i++)
              if (words[i][0] == '\'')
                is_str = 1;
            if (is_str)
              fprintf(fout, "char     %s[];\n", sym);
            else
              fprintf(fout, "uint8_t  %s;\n", sym);
            break;

          case DXT_WORD:
            fprintf(fout, "uint16_t %s;\n", sym);
            break;

          case DXT_DWORD:
            fprintf(fout, "uint32_t %s;\n", sym);
            break;

          default:
            fprintf(fout, "_UNKNOWN %s;\n", sym);
            break;
          }

          continue;
        }

        snprintf(last_sym, sizeof(last_sym), "%s", sym);

        pp = proto_parse(fhdr, sym, 1);
        if (pp != NULL) {
          g_func_sym_pp = NULL;

          // public/global name
          if (pub_sym_cnt >= pub_sym_alloc) {
            pub_sym_alloc *= 2;
            pub_syms = realloc(pub_syms, pub_sym_alloc * sizeof(pub_syms[0]));
            my_assert_not(pub_syms, NULL);
          }
          pub_syms[pub_sym_cnt++] = strdup(sym);
        }

        len = strlen(sym);
        fprintf(fout, "%s%s:", no_decorations ? "" : "_", sym);

        len += 2;
        if (len < 8)
          fprintf(fout, "\t");
        if (len < 16)
          fprintf(fout, "\t");
        if (len <= 16)
          fprintf(fout, "  ");
        else
          fprintf(fout, " ");
      }
      else {
        if (header_mode)
          continue;

        fprintf(fout, "\t\t  ");
      }

      // fill out some unwanted strings with zeroes..
      if (type == DXT_BYTE && words[w][0] == '\''
        && is_unwanted_sym(last_sym))
      {
        len = 0;
        for (; w < wordc; w++) {
          if (words[w][0] == '\'') {
            p = words[w] + 1;
            for (; *p && *p != '\''; p++)
              len++;
          }
          else {
            // assume encoded byte
            len++;
          }
        }
        fprintf(fout, ".skip %d", len);
        goto fin;
      }
      else if (type == DXT_BYTE
        && (words[w][0] == '\''
            || (w + 1 < wordc && words[w + 1][0] == '\'')))
      {
        // string; use asciz for most common case
        if (w == wordc - 2 && IS(words[w + 1], "0")) {
          fprintf(fout, ".asciz \"");
          wordc--;
        }
        else
          fprintf(fout, ".ascii \"");

        for (; w < wordc; w++) {
          if (words[w][0] == '\'') {
            p = words[w] + 1;
            p2 = strchr(p, '\'');
            if (p2 == NULL)
              aerr("unterminated string? '%s'\n", p);
            memcpy(word, p, p2 - p);
            word[p2 - p] = 0;
            fprintf(fout, "%s", escape_string(word));
          }
          else {
            val = parse_number(words[w]);
            if (val & ~0xff)
              aerr("bad string trailing byte?\n");
            // unfortunately \xHH is unusable - gas interprets
            // things like \x27b as 0x7b, so have to use octal here
            fprintf(fout, "\\%03lo", val);
          }
        }
        fprintf(fout, "\"");
        goto fin;
      }

      if (w == wordc - 2) {
        if (IS_START(words[w + 1], "dup(")) {
          cnt = parse_number(words[w]);
          p = words[w + 1] + 4;
          p2 = strchr(p, ')');
          if (p2 == NULL)
            aerr("bad dup?\n");
          memmove(word, p, p2 - p);
          word[p2 - p] = 0;

          val = 0;
          if (!IS(word, "?"))
            val = parse_number(word);

          fprintf(fout, ".fill 0x%02lx,%d,0x%02lx",
            cnt, type_size(type), val);
          goto fin;
        }
      }

      if (type == DXT_DWORD && words[w][0] == '\''
        && words[w][5] == '\'' && strlen(words[w]) == 6)
      {
        if (w != wordc - 1)
          aerr("TODO\n");

        p = words[w];
        val = (p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4];
        fprintf(fout, ".long 0x%lx", val);
        snprintf(g_comment, sizeof(g_comment), "%s", words[w]);
        goto fin;
      }

      if (type >= DXT_DWORD && strchr(words[w], '.'))
      {
        if (w != wordc - 1)
          aerr("TODO\n");

        if (g_arm_mode && type == DXT_TEN) {
          fprintf(fout, ".fill 10");
          snprintf(g_comment, sizeof(g_comment), "%s %s",
            type_name_float(type), words[w]);
        }
        else
          fprintf(fout, "%s %s", type_name_float(type), words[w]);
        goto fin;
      }

      first = 1;
      fprintf(fout, "%s ", type_name(type));
      for (; w < wordc; w++)
      {
        if (!first)
          fprintf(fout, ", ");

        is_label = is_bss = 0;
        if (w <= wordc - 2 && IS(words[w], "offset")) {
          is_label = 1;
          w++;
        }
        else if (IS(words[w], "?")) {
          is_bss = 1;
        }
        else if (type == DXT_DWORD
                 && !('0' <= words[w][0] && words[w][0] <= '9'))
        {
          // assume label
          is_label = 1;
        }

        if (is_bss) {
          fprintf(fout, "0");
        }
        else if (is_label) {
          p = words[w];
          if (IS_START(p, "loc_") || IS_START(p, "__imp")
             || strchr(p, '?') || strchr(p, '@')
             || bsearch(&p, rlist, rlist_cnt, sizeof(rlist[0]),
                  cmpstringp))
          {
            fprintf(fout, "0");
            snprintf(g_comment, sizeof(g_comment), "%s", p);
          }
          else {
            pp = check_var(fhdr, sym, p);
            if (pp == NULL) {
              fprintf(fout, "%s%s",
                (no_decorations || p[0] == '_') ? "" : "_", p);
            }
            else {
              if (no_decorations)
                fprintf(fout, "%s", pp->name);
              else
                output_decorated_pp(fout, pp);
            }
          }
        }
        else {
          val = parse_number(words[w]);
          if (val < 10)
            fprintf(fout, "%ld", val);
          else
            fprintf(fout, "0x%lx", val);
        }

        first = 0;
      }

fin:
      if (g_comment[0] != 0) {
        fprintf(fout, "\t\t%c %s", comment_char, g_comment);
        g_comment[0] = 0;
      }
      fprintf(fout, "\n");
    }
  }

  fprintf(fout, "\n");

  // dump public syms
  for (i = 0; i < pub_sym_cnt; i++)
    fprintf(fout, ".global %s%s\n",
      no_decorations ? "" : "_", pub_syms[i]);

  fclose(fout);
  fclose(fasm);
  if (fhdr != NULL)
    fclose(fhdr);

  return 0;
}
Example #25
0
static const struct parsed_proto *check_var(FILE *fhdr,
  const char *sym, const char *varname)
{
  const struct parsed_proto *pp, *pp_sym;
  char fp_sym[256], fp_var[256], *p;
  int i;

  pp = proto_parse(fhdr, varname, 1);
  if (pp == NULL) {
    if (IS_START(varname, "sub_"))
      awarn("sub_ sym missing proto: '%s'\n", varname);
    return NULL;
  }

  if (!pp->is_func && !pp->is_fptr)
    return NULL;

  pp_print(fp_var, sizeof(fp_var), pp);

  if (pp->argc_reg == 0)
    goto check_sym;
  if (pp->argc_reg == 1 && pp->argc_stack == 0
    && IS(pp->arg[0].reg, "ecx"))
  {
    goto check_sym;
  }
  if (!g_cconv_novalidate
    && (pp->argc_reg != 2
       || !IS(pp->arg[0].reg, "ecx")
       || !IS(pp->arg[1].reg, "edx")))
  {
    awarn("unhandled reg call: %s\n", fp_var);
  }

check_sym:
  // fptrs must use 32bit args, callsite might have no information and
  // lack a cast to smaller types, which results in incorrectly masked
  // args passed (callee may assume masked args, it does on ARM)
  for (i = 0; i < pp->argc; i++) {
    if (pp->arg[i].type.is_ptr)
      continue;
    p = pp->arg[i].type.name;
    if (strstr(p, "int8") || strstr(p, "int16")
      || strstr(p, "char") || strstr(p, "short"))
    {
      awarn("reference to %s with arg%d '%s'\n", pp->name, i + 1, p);
    }
  }

  sprint_pp_short(pp, g_comment, sizeof(g_comment));

  if (sym != NULL) {
    g_func_sym_pp = NULL;
    pp_sym = proto_parse(fhdr, sym, 1);
    if (pp_sym == NULL)
      return pp;
    if (!pp_sym->is_fptr)
      aerr("func ptr data, but label '%s' !is_fptr\n", pp_sym->name);
    g_func_sym_pp = pp_sym;
  }
  else {
    pp_sym = g_func_sym_pp;
    if (pp_sym == NULL)
      return pp;
  }

  if (pp_cmp_func(pp, pp_sym)) {
    pp_print(fp_sym, sizeof(fp_sym), pp_sym);
    anote("var: %s\n", fp_var);
    anote("sym: %s\n", fp_sym);
    awarn("^ mismatch\n");
  }

  return pp;
}
Example #26
0
/*
 * Process machine ops.
 */
VOID
machine(struct mne *mp)
{
        char *p, *str;
        char pid[NINPUT], id[NINPUT];
        int c, d, t, t1, v1;
        a_uint op;
        struct sym *sp;
        struct expr e, e1, e2;

        clrexpr(&e);
        clrexpr(&e1);
        clrexpr(&e2);

        op = mp->m_valu;
        switch (mp->m_type) {

        case S_CPU:
                opcycles = OPCY_CPU;
                lmode = SLIST;
                switch(op) {
                default: op = DS8XCXXX;
                case DS8XCXXX: v1 = 2; str = "DS8XCXXX"; sym[2].s_addr = X_DS8XCXXX; break;
                case DS80C310: v1 = 2; str = "DS80C310"; sym[2].s_addr = X_DS80C310; break;
                case DS80C320: v1 = 2; str = "DS80C320"; sym[2].s_addr = X_DS80C320; break;
                case DS80C323: v1 = 2; str = "DS80C323"; sym[2].s_addr = X_DS80C323; break;
                case DS80C390: v1 = 3; str = "DS80C390"; sym[2].s_addr = X_DS80C390; break;
                case DS83C520: v1 = 2; str = "DS83C520"; sym[2].s_addr = X_DS83C520; break;
                case DS83C530: v1 = 2; str = "DS83C530"; sym[2].s_addr = X_DS83C530; break;
                case DS83C550: v1 = 2; str = "DS83C550"; sym[2].s_addr = X_DS83C550; break;
                case DS87C520: v1 = 2; str = "DS87C520"; sym[2].s_addr = X_DS87C520; break;
                case DS87C530: v1 = 2; str = "DS87C530"; sym[2].s_addr = X_DS87C530; break;
                case DS87C550: v1 = 2; str = "DS87C550"; sym[2].s_addr = X_DS87C550; break;
                case DS______: v1 = 2; str = "DS______"; sym[2].s_addr = X_DS______;
                        if (more()) {
                                str = p = pid;
                                d = getnb();
                                while ((c = get()) != d) {
                                        if (c == '\0') {
                                                qerr();
                                        }
                                        if (p < &pid[sizeof(pid)-3]) {
                                                *p++ = c;
                                        } else {
                                                break;
                                        }
                                }
                                *p = 0;
                        }
                        break;
                }
                if (op != 0) {
                        ds8_bytes = v1;
                        exprmasks(v1);
                }
                mchtyp = (int) op;

                sprintf(id, "__%s", str);
                sp = lookup(id);
                if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) {
                        err('m');
                }
                sp->s_type = S_USER;
                sp->s_addr = 1;
                sp->s_flag |= S_ASG;

                sprintf(buff, "%s %s", DS_CPU, str);
                cpu = buff;

                sp = lookup("__SFR_BITS");
                if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) {
                        err('m');
                }
                sp->s_type = S_USER;
                sp->s_flag |= S_ASG;

                if (more()) {
                        expr(&e, 0);
                        abscheck(&e);
                        sp->s_addr = e.e_addr;
                } else {
                        sp->s_addr = 1;
                }
                break;

        case S_AMODE:
                opcycles = OPCY_AMODE;
                if ((mchtyp != 0) && (mchtyp != DS80C390)) {
                        err('o');
                        break;
                }
                expr(&e, 0);
                abscheck(&e);
                amode = (int) e.e_addr;
                if ((amode < 0) || (amode > 2)) {
                        amode = 0;
                        err('o');
                }
                if ((c = getnb()) == ',') {
                        expr(&e1, 0);
                        abscheck(&e1);
                        if (e1.e_addr != 0) {
/* mov  ta,#0aah */             outab(0x075);   outab(0x0C7);   outab(0x0AA);
/* mov  ta,#055h */             outab(0x075);   outab(0x0C7);   outab(0x055);
/* mov  acon,#amode */          outab(0x075);   outab(0x09D);   outab(amode);
                        } else {
                                lmode = SLIST;
                        }
                } else {
                        unget(c);
                        lmode = SLIST;
                }
                break;

        case S_BITS:
                if (ds8_bytes == 0) {
                        ds8_bytes = (int) op;
                        exprmasks(ds8_bytes);
                } else
                if (ds8_bytes != (int) op) {
                        err('m');
                }
                opcycles = OPCY_BITS;
                lmode = SLIST;
                break;

        case S_INH:
                outab(op);
                break;

        case S_JMP11:
                expr(&e, 0);
                if (amode == 2) {
                        outr3bm(&e, R_J19, op);
                } else {
                        outrwm(&e, R_J11, op);
                }
                break;

        case S_JMP16:
                expr(&e, 0);
                outab(op);
                if (amode == 2) {
                        outr3b(&e, R_NORM);
                } else {
                        outrw(&e, R_NORM);
                }
                break;

        case S_ACC:
                t = addr(&e);
                if (t != S_A)
                        aerr();
                outab(op);
                break;

        case S_TYP1:
                /* A, direct, @R0, @R1, R0 to R7.  "INC" also allows DPTR */
                t = addr(&e);

                switch (t) {
                case S_A:
                        outab(op + 4);
                        break;

                case S_DIR:
                case S_EXT:
                        /* Direct is also legal */
                        outab(op + 5);
                        outrb(&e, R_PAG0);
                        break;

                case S_AT_R:
                        outab(op + 6 + e.e_addr);
                        break;

                case S_REG:
                        outab(op + 8 + e.e_addr);
                        break;

                case S_DPTR:
                        if (op != 0)
                                /* only INC (op=0) has DPTR mode */
                                aerr();
                        else
                                outab( 0xA3);
                        break;

                default:
                        aerr();
                }
                break;

        case S_TYP2:
                /* A,#imm; A,direct; A,@R0; A,@R1; A,R0 to A,R7 */
                t = addr(&e);
                if (t != S_A)
                        aerr();
                comma(1);
                t1 = addr(&e1);

                switch (t1) {
                case S_IMMED:
                        outab(op + 4);
                        outrb(&e1, R_NORM);
                        break;

                case S_DIR:
                case S_EXT:
                        outab(op + 5);
                        outrb(&e1, R_PAG0);
                        break;

                case S_AT_R:
                        outab(op + 6 + e1.e_addr);
                        break;

                case S_REG:
                        outab(op + 8 + (e1.e_addr));
                        break;

                default:
                        aerr();
                }
                break;

        case S_TYP3:
                /* dir,A; dir,#imm;
                 * A,#imm; A,direct; A,@R0; A,@R1; A,R0 to A,R7
                 * C,direct;  C,/direct
                 */
                t = addr(&e);
                comma(1);
                t1 = addr(&e1);

                switch (t) {
                case S_DIR:
                case S_EXT:
                        switch (t1) {
                        case S_A:
                                outab(op + 2);
                                outrb(&e, R_PAG0);
                                break;

                        case S_IMMED:
                                outab(op + 3);
                                outrb(&e, R_PAG0);
                                outrb(&e1, R_NORM);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_A:
                        switch (t1) {
                        case S_IMMED:
                                outab(op + 4);
                                outrb(&e1, R_NORM);
                                break;

                        case S_DIR:
                        case S_EXT:
                                outab(op + 5);
                                outrb(&e1, R_PAG0);
                                break;

                        case S_AT_R:
                                outab(op + 6 + e1.e_addr);
                                break;

                        case S_REG:
                                outab(op + 8 + e1.e_addr);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_C:
                        /* XRL has no boolean version.  Trap it */
                        if (op == 0x60)
                                aerr();

                        switch (t1) {
                        case S_DIR:
                        case S_EXT:
                                outab(op + 0x32);
                                outrb(&e1, R_PAG0);
                                break;

                        case S_NOT_BIT:
                                outab(op + 0x60);
                                outrb(&e1, R_PAG0);
                                break;

                        default:
                                aerr();
                        }
                        break;

                default:
                        aerr();
                }
                break;

        case S_TYP4:
                /* A,direct; A,@R0; A,@R1; A,R0 to A,R7 */
                t = addr(&e);
                if (t != S_A)
                        aerr();
                comma(1);
                t1 = addr(&e1);

                switch (t1) {
                case S_DIR:
                case S_EXT:
                        outab(op + 5);
                        outrb(&e1, R_PAG0);
                        break;

                case S_AT_R:
                        outab(op + 6 + e1.e_addr);
                        break;

                case S_REG:
                        outab(op + 8 + e1.e_addr);
                        break;

                default:
                        aerr();
                }
                break;

        /* MOV instruction, all modes */
        case S_MOV:
                t = addr(&e);
                comma(1);
                t1 = addr(&e1);

                switch (t) {
                case S_A:
                        switch (t1) {
                        case S_IMMED:
                                outab(0x74);
                                outrb(&e1, R_NORM);
                                break;

                        case S_DIR:
                        case S_EXT:
                                outab(0xE5);
                                outrb(&e1, R_PAG0);
                                break;

                        case S_AT_R:
                                outab(0xE6 + e1.e_addr);
                                break;

                        case S_REG:
                                outab(0xE8 + e1.e_addr);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_REG:
                        switch (t1) {
                        case S_A:
                                outab(0xF8 + e.e_addr);
                                break;

                        case S_IMMED:
                                outab(0x78 + e.e_addr);
                                outrb(&e1, R_NORM);
                                break;

                        case S_DIR:
                        case S_EXT:
                                outab(0xA8 + e.e_addr);
                                outrb(&e1, R_PAG0);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_DIR:
                case S_EXT:
                        switch (t1) {
                        case S_A:
                                outab(0xF5);
                                outrb(&e, R_PAG0);
                                break;

                        case S_IMMED:
                                outab(0x75);
                                outrb(&e, R_PAG0);
                                outrb(&e1, R_NORM);
                                break;

                        case S_DIR:
                        case S_EXT:
                                outab(0x85);
                                outrb(&e1, R_PAG0);
                                outrb(&e, R_PAG0);
                                break;

                        case S_AT_R:
                                outab(0x86 + e1.e_addr);
                                outrb(&e, R_PAG0);
                                break;

                        case S_REG:
                                outab(0x88 + e1.e_addr);
                                outrb(&e, R_PAG0);
                                break;

                        case S_C:
                                outab(0x92);
                                outrb(&e, R_PAG0);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_AT_R:
                        switch (t1) {
                        case S_IMMED:
                                outab(0x76 + e.e_addr);
                                outrb(&e1, R_NORM);
                                break;

                        case S_DIR:
                        case S_EXT:
                                outab(0xA6 + e.e_addr);
                                outrb(&e1, R_PAG0);
                                break;

                        case S_A:
                                outab(0xF6 + e.e_addr);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_C:
                        if ((t1 != S_DIR) && (t1 != S_EXT))
                                aerr();
                        outab(0xA2);
                        outrb(&e1, R_PAG0);
                        break;

                case S_DPTR:
                        if (t1 != S_IMMED)
                                aerr();
                        outab(0x90);
                        if (amode == 2)
                                outr3b(&e1, R_NORM);
                        else
                                outrw(&e1, R_NORM);
                        break;

                default:
                        aerr();
                }
                break;

        case S_BITBR:   /* JB, JBC, JNB bit,rel */
                /* Branch on bit set/clear */
                t = addr(&e);
                if ((t != S_DIR) && (t != S_EXT))
                        aerr();
                /* sdcc svn rev #4994: fixed bug 1865114 */
                comma(1);
                expr(&e1, 0);

                outab(op);
                outrb(&e, R_PAG0);

                if (mchpcr(&e1)) {
                        v1 = (int) (e1.e_addr - dot.s_addr - 1);
                        /* sdcc svn rev #602: Fix some path problems */
                        if (pass == 2 && ((v1 < -128) || (v1 > 127)))
                                aerr();
                        outab(v1);
                } else {
                        outrb(&e1, R_PCR);
                }
                if (e1.e_mode != S_USER)
                        rerr();
                break;

        case S_BR:  /* JC, JNC, JZ, JNZ */
                /* Relative branch */
                /* sdcc svn rev #4994: fixed bug 1865114 */
                expr(&e1, 0);
                outab(op);

                if (mchpcr(&e1)) {
                        v1 = (int) (e1.e_addr - dot.s_addr - 1);
                        /* sdcc svn rev #602: Fix some path problems */
                        if (pass == 2 && ((v1 < -128) || (v1 > 127)))
                                aerr();
                        outab(v1);
                } else {
                        outrb(&e1, R_PCR);
                }
                if (e1.e_mode != S_USER)
                        rerr();
                break;

        case S_CJNE:
                /* A,#;  A,dir;  @R0,#;  @R1,#;  Rn,# */
                t = addr(&e);
                comma(1);
                t1 = addr(&e1);

                /* Benny */
                comma(1);
                expr(&e2, 0);

                switch (t) {
                case S_A:
                        if (t1 == S_IMMED) {
                                outab(op + 4);
                                outrb(&e1, R_NORM);
                        }
                        else if ((t1 == S_DIR) || (t1 == S_EXT)) {
                                outab(op + 5);
                                outrb(&e1, R_PAG0);
                        }
                        else
                                aerr();
                        break;

                case S_AT_R:
                        outab(op + 6 + e.e_addr);
                        if (t1 != S_IMMED)
                                aerr();
                        outrb(&e1, R_NORM);
                        break;

                case S_REG:
                        outab(op + 8 + e.e_addr);
                        if (t1 != S_IMMED)
                                aerr();
                        outrb(&e1, R_NORM);
                        break;

                default:
                        aerr();
                        break;
                }

                /* branch destination */
                if (mchpcr(&e2)) {
                        v1 = (int) (e2.e_addr - dot.s_addr - 1);
                        /* sdcc svn rev #602: Fix some path problems */
                        if (pass == 2 && ((v1 < -128) || (v1 > 127)))
                                aerr();
                        outab(v1);
                } else {
                        outrb(&e2, R_PCR);
                }
                if (e2.e_mode != S_USER)
                        rerr();
                break;

        case S_DJNZ:
                /* Dir,dest;  Reg,dest */
                t = addr(&e);
                /* sdcc svn rev #4994: fixed bug 1865114 */
                comma(1);
                expr(&e1, 0);

                switch (t) {
                case S_DIR:
                case S_EXT:
                        outab(op + 5);
                        outrb(&e, R_PAG0);
                        break;

                case S_REG:
                        outab(op + 8 + e.e_addr);
                        break;

                default:
                        aerr();
                }

                /* branch destination */
                /* sdcc svn rev #4994: fixed bug 1865114 */
                if (mchpcr(&e1)) {
                        v1 = (int) (e1.e_addr - dot.s_addr - 1);
                        /* sdcc svn rev #602: Fix some path problems */
                        if (pass == 2 && ((v1 < -128) || (v1 > 127)))
                                aerr();
                        outab(v1);
                } else {
                        outrb(&e1, R_PCR);
                }
                if (e1.e_mode != S_USER)
                        rerr();
                break;

        case S_JMP:
                /* @A+DPTR */
                t = addr(&e);
                if (t != S_AT_ADP)
                        aerr();
                outab(op);
                break;

        case S_MOVC:
                /* A,@A+DPTR  A,@A+PC */
                t = addr(&e);
                if (t != S_A)
                        aerr();
                comma(1);
                t1 = addr(&e1);
                if (t1 == S_AT_ADP)
                        outab(0x93);
                else if (t1 == S_AT_APC)
                        outab(0x83);
                else
                        aerr();
                break;

        case S_MOVX:
                /* A,@DPTR  A,@R0  A,@R1  @DPTR,A  @R0,A  @R1,A */
                t = addr(&e);
                comma(1);
                t1 = addr(&e1);

                switch (t) {
                case S_A:
                        switch (t1) {
                        case S_AT_DP:
                                outab(0xE0);
                                break;

                        case S_AT_R:
                                outab(0xE2 + e1.e_addr);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_AT_DP:
                        if (t1 == S_A)
                                outab(0xF0);
                        else
                                aerr();
                        break;

                case S_AT_R:
                        if (t1 == S_A)
                                outab(0xF2 + e.e_addr);
                        else
                                aerr();
                        break;

                default:
                        aerr();
                }
                break;

        /* MUL/DIV A,B */
        case S_AB:
                t = addr(&e);
                if (t != S_RAB)
                        aerr();
                outab(op);
                break;

        /* CLR or CPL:  A, C, or bit */
        case S_ACBIT:
                t = addr(&e);
                switch (t) {
                case S_A:
                        if (op == 0xB2)
                                outab(0xF4);
                        else
                                outab(0xE4);
                        break;

                case S_C:
                        outab(op+1);
                        break;

                case S_DIR:
                case S_EXT:
                        outab(op);
                        outrb(&e, R_PAG0);
                        break;

                default:
                        aerr();
                }
                break;

        /* SETB C or bit */
        case S_SETB:
                t = addr(&e);
                switch (t) {
                case S_C:
                        outab(op+1);
                        break;

                case S_DIR:
                case S_EXT:
                        outab(op);
                        outrb(&e, R_PAG0);
                        break;

                default:
                        aerr();
                }
                break;

        /* direct */
        case S_DIRECT:
                t = addr(&e);
                if (t == S_A) {
                        e.e_addr = 0xE0;
                        e.e_mode = S_DIR;
                } else
                if ((t != S_DIR) && (t != S_EXT)) {
                        aerr();
                        break;
                }
                outab(op);
                outrb(&e, R_PAG0);
                break;

        /* XCHD A,@Rn */
        case S_XCHD:
                t = addr(&e);
                if (t != S_A)
                        aerr();
                comma(1);
                t1 = addr(&e1);
                switch (t1) {
                case S_AT_R:
                        outab(op + e1.e_addr);
                        break;

                default:
                        aerr();
                }
                break;

        default:
                opcycles = OPCY_ERR;
                err('o');
                break;
        }
        if (opcycles == OPCY_NONE) {
                opcycles = ds8pg1[cb[0] & 0xFF];
        }
}
Example #27
0
/*
 * Process a machine op.
 */
VOID  machine(struct mne * mp)
{
  int op, t1, t2;
  struct expr e1, e2;
  int rf, v1, v2;
  
  clrexpr(&e1);
  clrexpr(&e2);
  op = (int) mp->m_valu;
  rf = mp->m_type;
#if 0
  if (!hd64 && rf>X_HD64)
    rf = 0;
#endif
  
  if (!r4k_mode && rf > X_R4K_MODE)
    rf = 0;
  
  switch (rf)
    {
    case S_INH1:
      outab(op);
      break;
      
    case S_INH2:
      outab(0xED);
      outab(op);
      break;
      
    case S_RET:
      if (more()) {
        if ((v1 = admode(CND)) != 0) {
          outab(op | (v1<<3));
        } else {
          qerr();
        }
      } else {
        outab(0xC9);
      }
      break;
      
    case S_PUSH:
      if (admode(R16X)) {
        outab(op+0x30);
        break;
      } else if ((v1 = admode(R8IP)) != 0) {
        outab(0xED);
        if (op == 0xC5) 
          outab(0x76);  /* push */
        else
          outab(0x7E);  /* pop  */
        break;
      } else
        if ((v1 = admode(R16)) != 0 && (v1 &= 0xFF) != SP) {
          if (v1 != gixiy(v1)) {
            outab(op+0x20);
            break;
          }
          outab(op | (v1<<4));
          break;
        } else if (r4k_mode) {
          if ( (v1 = admode(R32_JKHL)) != 0 ) {
            outab(JKHL_PG);
            outab(op+0x30);
            break;
          } else if ( (v1 = admode(R32_BCDE)) != 0 ) {
            outab(BCDE_PG);
            outab(op+0x30);
            break;
          }
        }
      aerr();
      break;
      
    case S_RST:
      v1 = (int) absexpr();
      /* ljm comment -
       *   block RST 00, 08, and 30 b/c those opcodes
       *   are assigned to different instructions in the
       *   rabbit processor
       */
      if ((v1 == 0x00) || (v1 == 0x08) || (v1 == 0x30)) {
        aerr( );
        v1 = 0;
      }
      if (v1 & ~0x38) {
        aerr();
        v1 = 0;
      }
      outab(op|v1);
      break;
      
#if 0
      /* IM x set interrupt mode on Z-80 */
      /* Rabbit processor use the opcode to set interrupt level */
    case S_IM:
      expr(&e1, 0);
      abscheck(&e1);
      if (e1.e_addr > 2) {
        aerr();
        e1.e_addr = 0;
      }
      outab(op);
      outab(imtab[(int) e1.e_addr]);
      break;
#endif
      
    case S_BIT:
      expr(&e1, 0);
      t1 = 0;
      v1 = (int) e1.e_addr;
      if (v1 > 7) {
        ++t1;
        v1 &= 0x07;
      }
      op |= (v1<<3);
      comma(1);
      addr(&e2);
      abscheck(&e1);
      if (genop(0xCB, op, &e2, 0) || t1)
        aerr();
      break;
      
    case S_RL:
      t1 = 0;
      t2 = addr(&e2);
      if ((t2 == S_IMMED) && r4k_mode)
        {
          v1 = (int) e2.e_addr;
          /* v1 should be shift count of 1,2,4, or 8 */
          comma(1);
          clrexpr(&e2);
          t2 = addr(&e2);
          
          if ((t2 != S_R32_BCDE) && (t2 != S_R32_JKHL))
            aerr( );
          
          if (v1 == 1)
            v1 = 0x48;
          else if (v1 == 2)
            v1 = 0x49;
          else if (v1 == 4)
            v1 = 0x4B;
          else if ((v1 == 8) && (op < 0x20 /* op is rlc|rrc|rl|rr */))
            v1 = 0x4F;
          else {
            err('o');
            break;
          }
          
          /* 00 rlc, 08 rrc, 10 rl , 18 rr                    *
           * 20 sla, 28 sra,         38 srl,  [30 sll == sla] */
          outab( ((t2 == S_R32_JKHL)?JKHL_PG:BCDE_PG) );
          outab(v1 + (op << 1));
          break;
        }
      else if (more()) {
        if ((t2 != S_R8) || (e2.e_addr != A))
          ++t1;
        comma(1);
        clrexpr(&e2);
        t2 = addr(&e2);
      } else if (t2 == S_R16) {
        v2 = (int) e2.e_addr;
        if ((v2 == DE) && 
            ((op == 0x10 /* rl */) || (op == 0x18 /* rr */))) {
          outab( 0xF3 - 0x10 + op );
          break;
        }
        
        if ((v2 == HL) && (op == 0x18 /* rr */)) {
          outab( 0xFC );
          break;
        }
        
        if (r4k_mode) {
          if ((v2 == HL) && (op == 0x10 /* rl */)) {
            outab( 0x42 );
            break;
          }
          if (((v2 == BC)||(v2 == DE)) &&
              (op < 0x20 /* 00 rlc, 08 rrc, 10 rl, 18 rr */)) {
            outab( 0x50 + (op >> 3) + ((v2==BC)?0x10:0x00) );
            break;
          }
        }
        
        aerr( );
      }