Beispiel #1
0
void spi_init(void)
{
  putreg16(SPI_SET1_EN_CLK | SPI_SET1_WR_IRQ_DIS | SPI_SET1_RDWR_IRQ_DIS,
           SPI_REG(REG_SET1));

  putreg16(0x0001, SPI_REG(REG_SET2));
}
Beispiel #2
0
static void reset_spimaster(void)
{
    SPI_REG(SPIGCR0) = 0x00000000;
    mdelay(1); // Delay for a bit
    SPI_REG(SPIGCR0) = 0x00000001;
    SPI_REG(SPIGCR1) = 0x00000003; //SPIGCR1 CLKMODºÍMASTERMOD
}
Beispiel #3
0
static u32 pch_read_soft_strap(int id)
{
	clrbits_le32(SPI_REG(SPIBAR_FDOC), 0x00007ffc);
	setbits_le32(SPI_REG(SPIBAR_FDOC), 0x00004000 | id * 4);

	return readl(SPI_REG(SPIBAR_FDOD));
}
Beispiel #4
0
// Reading from the SPI device
ssize_t dv_spi_read(struct file *filp, char __user *buf, size_t count, loff_t
                    *f_pos)
{
    Uarray buf_val;
    ssize_t	status = 0;

    if((NULL == buf)||(count <= 0))
    {
        return -1;
    }
#if 0
    len = kfifo_len(g_kfifo);
    if(count > len)
    {
        count = len ;
    }
    memset(g_readbuf,0,sizeof(g_readbuf));
    kfifo_get(g_kfifo,g_readbuf,count);
    // Transferring data to user space
    status = copy_to_user(buf, g_readbuf, count);
    if(0 == status)
    {
        return count;
    }
    else
    {
        return -1;
    }
#else
    if(SPIBUF_RXEMPTY_MASK & SPI_REG(SPIBUF))
    {
        buf_val.udata = SPI_REG(SPIBUF);
        count = (g_dataformat == format_8bit)?1:2;
        // Transferring data to user space
        status = copy_to_user(buf, buf_val.uarray,count);
        if(0 == status)
        {
            return count;
        }
        else
        {
            return -1;
        }
    }
    else
    {
        return -1;
    }
#endif
}
Beispiel #5
0
// Called when a userspace program closes the file
int dv_spi_release(struct inode *inode, struct file *filp)
{
    printk("\nclose\n");
    // Place SPI peripheral into reset
    SPI_REG(SPIGCR0) = 0;
    // Remove the SPI output on the GPIO
    SPI_REG(PINMUX1REG) &= (~0x00000100);
    // Disable the clock thus removing power from the peripheral
    if (g_clkptr)
    {
        clk_disable(g_clkptr);
    }
    g_clkptr = NULL;
    return 0;
}
Beispiel #6
0
BOOL CPU_SPI_Xaction_nWrite8_nRead8( SPI_XACTION_8& Transaction )
{
    LPC_SSP_T *spi = SPI_REG(Transaction.SPI_mod);
    
    UINT8* outBuf = Transaction.Write8;
    UINT8* inBuf  = Transaction.Read8;
    INT32 outLen = Transaction.WriteCount;
    INT32 num, ii, i = 0;
    
    if (Transaction.ReadCount) { // write & read
        num = Transaction.ReadCount + Transaction.ReadStartOffset;
        ii = -Transaction.ReadStartOffset;
    } else { // write only
        num = outLen;
        ii = 0x80000000; // disable write to inBuf
    }

    UINT8 out = outBuf[0];
    UINT16 in;
    SPI_Write(spi, out); // write first word
    while (++i < num) {
        if (i < outLen) out = outBuf[i]; // get new output data
        while (!(SPI_Readable(spi))); // wait for Rx buffer
        in = SPI_Read(spi); // read input
        SPI_Write(spi, out); // start output
        if (ii >= 0) inBuf[ii] = (UINT8)in; // save input data
        ii++;
    }
    while (!(SPI_Readable(spi))); // wait for Rx buffer
    in = SPI_Read(spi); // read last input
    if (ii >= 0) inBuf[ii] = (UINT8)in; // save last input

    return TRUE;
}
Beispiel #7
0
BOOL CPU_SPI_Xaction_Start(const SPI_CONFIGURATION& Configuration)
{
    if (Configuration.SPI_mod >= TOTAL_SPI_PORT) return FALSE;

    LPC_SSP_T *spi = SPI_REG(Configuration.SPI_mod);
    int Bits, Mode;

    // Configure options and clock
    Bits = (Configuration.MD_16bits) ? 16 : 8;
    Mode = (Configuration.MSK_IDLE) ? 2 : 0; // ToDo: Check
    Mode |= (!Configuration.MSK_SampleEdge) ? 1 : 0;
    SPI_Config(spi, Bits, Mode, 0);
    SPI_Frequency(spi, (1000 * Configuration.Clock_RateKHz));
    
    // I/O setup
    GPIO_PIN msk, miso, mosi;
    CPU_SPI_GetPins(Configuration.SPI_mod, msk, miso, mosi);
    UINT32 alternate = 0x252; // AF5 = SPI1/SPI2
    if (Configuration.SPI_mod == 2) alternate = 0x262; // AF6 = SPI3, speed = 2 (50MHz)
    CPU_GPIO_DisablePin(msk,  RESISTOR_DISABLED, 1, (GPIO_ALT_MODE)alternate);
    CPU_GPIO_DisablePin(miso, RESISTOR_DISABLED, 0, (GPIO_ALT_MODE)alternate);
    CPU_GPIO_DisablePin(mosi, RESISTOR_DISABLED, 1, (GPIO_ALT_MODE)alternate);

    // CS setup
    CPU_GPIO_EnableOutputPin(Configuration.DeviceCS, Configuration.CS_Active);
    if(Configuration.CS_Setup_uSecs)
    {
        HAL_Time_Sleep_MicroSeconds_InterruptEnabled(Configuration.CS_Setup_uSecs);
    }

    return TRUE;
}
Beispiel #8
0
static void inline wait_untilsend(void)
{
    if(NULL == g_clkptr)
    {
        return;
    }
    while(SPIBUF_RXEMPTY_MASK & SPI_REG(SPIBUF))
    {
        cpu_relax();
    }
}
Beispiel #9
0
/**
 * Select SPI Master/Slave BASE, than return correct address
 */
static u32 spi_get_reg_addr(u8 spi_inst, u32 offset)
{
	switch (spi_inst) {
		case SPI_MASTER1:
			return SPI_REG(offset);
#if (SPI_INSTANCES > 1)
		case SPI_MASTER2:
			return SPI2_REG(offset);
#endif
# if (SPI_INSTANCES > 2)
		case SPI_MASTER3:
			return SPI3_REG(offset);
#endif
	}

	return 0xffffffff;
}
Beispiel #10
0
BOOL CPU_SPI_Xaction_Stop(const SPI_CONFIGURATION& Configuration)
{
    LPC_SSP_T *spi = SPI_REG(Configuration.SPI_mod);
    while (SPI_Busy(spi)); // wait for completion

    if(Configuration.CS_Hold_uSecs)
    {
        HAL_Time_Sleep_MicroSeconds_InterruptEnabled(Configuration.CS_Hold_uSecs);
    }
    CPU_GPIO_SetPinState(Configuration.DeviceCS, !Configuration.CS_Active);
    GPIO_RESISTOR res = RESISTOR_PULLDOWN;
    if (Configuration.MSK_IDLE) res = RESISTOR_PULLUP;
    GPIO_PIN msk, miso, mosi;
    CPU_SPI_GetPins(Configuration.SPI_mod, msk, miso, mosi);
    CPU_GPIO_EnableInputPin(msk,  FALSE, NULL, GPIO_INT_NONE, res);
    CPU_GPIO_EnableInputPin(miso, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLDOWN);
    CPU_GPIO_EnableInputPin(mosi, FALSE, NULL, GPIO_INT_NONE, RESISTOR_PULLDOWN);

    SPI_Disable(spi); // Disable SPI
    return TRUE;
}
Beispiel #11
0
int spi_xfer(uint8_t dev_idx, uint8_t bitlen, const void *dout, void *din)
{
  uint8_t bytes_per_xfer;
  uint8_t reg_status, reg_ctrl = 0;
  uint32_t tmp;

  if (bitlen == 0)
    {
      return 0;
    }

  if (bitlen > 32)
    {
      return -1;
    }

  if (dev_idx > 4)
    {
      return -1;
    }

  bytes_per_xfer = bitlen / 8;
  if (bitlen % 8)
    {
      bytes_per_xfer ++;
    }

  reg_ctrl |= (bitlen - 1) << SPI_CTRL_NB_SHIFT;
  reg_ctrl |= (dev_idx & 0x7) << SPI_CTRL_AD_SHIFT;

  if (bitlen <= 8)
    {
      tmp = *(uint8_t *)dout;
      tmp <<= 24 + (8-bitlen);  /* align to MSB */
    }
  else if (bitlen <= 16)
    {
      tmp = *(uint16_t *)dout;
      tmp <<= 16 + (16-bitlen);  /* align to MSB */
    }
  else
    {
      tmp = *(uint32_t *)dout;
      tmp <<= (32-bitlen);    /* align to MSB */
    }

  dbg("spi_xfer(dev_idx=%u, bitlen=%u, data_out=0x%08x): ",
      dev_idx, bitlen, tmp);

  /* fill transmit registers */

  putreg16(tmp >> 16, SPI_REG(REG_TX_MSB));
  putreg16(tmp & 0xffff, SPI_REG(REG_TX_LSB));

  /* initiate transfer */

  if (din)
    {
      reg_ctrl |= SPI_CTRL_RDWR;
    }
  else
    {
      reg_ctrl |= SPI_CTRL_WR;
    }

  putreg16(reg_ctrl, SPI_REG(REG_CTRL));
  dbg("reg_ctrl=0x%04x ", reg_ctrl);

  /* wait until the transfer is complete */

  while (1)
  {
    reg_status = getreg16(SPI_REG(REG_STATUS));
    dbg("status=0x%04x ", reg_status);
    if (din && (reg_status & SPI_STATUS_RE))
      {
        break;
      }
    else if (reg_status & SPI_STATUS_WE)
      {
        break;
      }
  }

  /* FIXME: calibrate how much delay we really need (seven 13MHz cycles) */

  usleep(1000);

  if (din)
    {
      tmp = getreg16(SPI_REG(REG_RX_MSB)) << 16;
      tmp |= getreg16(SPI_REG(REG_RX_LSB));
      dbg("data_in=0x%08x ", tmp);

      if (bitlen <= 8)
        {
          *(uint8_t *)din = tmp & 0xff;
        }
      else if (bitlen <= 16)
        {
          *(uint16_t *)din = tmp & 0xffff;
        }
      else
        {
          *(uint32_t *)din = tmp;
        }
    }

  dbg("\n");

  return 0;
}
Beispiel #12
0
// This function will initialize the pinmux register
// --------------------------------
// Configure GPIO Pins for SPI
// --------------------------------
static void init_pinmux(void)
{
    // Enable the SPI pins on the GPIO
    SPI_REG(PINMUX0REG) = VALUE_PINMUX0REG;
    SPI_REG(PINMUX1REG) = VALUE_PINMUX1REG;
}
Beispiel #13
0
ssize_t dv_spi_ioctl(struct inode *inode, struct file *filp,\
                     enum  spi_commands cmd, const unsigned long arg)
{
    int tmp = -1;

    if((cmd < Cmd_reset) || (cmd > Cmd_Selchip) || (arg < Sel_chip0)||(arg > Sel_chip1))
    {
        return -EINVAL ;
    }
    switch(cmd)
    {
    case Cmd_reset:
    {
        reset_spimaster();
        memset(g_readbuf,0,sizeof(g_readbuf));
        kfifo_reset(g_kfifo);
        tmp = 0;
    }
    break;
    case Cmd_enspi:
    {
        if(Sel_chip0 == (enum  spi_selchip)arg)
        {
            SPI_REG(SPIPC0) = 0x00000E01;
        }
        else if(Sel_chip1 == (enum  spi_selchip)arg)
        {
            SPI_REG(SPIPC0) = 0x00000E02;
        }
        tmp = 0;
    }
    break;
    case Cmd_dataformat:
    {
        g_dataformat = (enum spi_dataformat)arg;
        tmp = (format_8bit == g_dataformat)?SPIFMT_8BIT:SPIFMT_16BIT;
        SPI_REG(SPIFMT0) = tmp;
        SPI_REG(SPIFMT1) = tmp;
        tmp = 0;
    }
    break;
    case Cmd_Cshold:
    {
        g_cshold_mask = (Cs_active_hold == (enum spi_cshold)arg)?BIT(28):0;
#if 0
        ret = gpio_request(37,NULL);
        printk("\n gpio_is_valid,ret=%d \n",ret);
        ret = gpio_direction_output(37,1);
        printk("\n gpio_direction_output,ret=%d \n",ret);
        //gpio_direction_output(37, (const unsigned int)arg);
#endif
    }
    break;
    case Cmd_Selchip:
    {
        g_selchip = (enum spi_selchip)arg;
        if(Sel_chip0 == g_selchip)
        {
            SPI_REG(SPIDAT1) = 0x00000000;
            SPI_REG(SPIDAT1) = (0x00020000 | g_cshold_mask);
            SPI_REG(SPIDEF) = 0x00000001;
            g_chip_mask = (CHIP0_MASK | g_cshold_mask);
        }
        else if(Sel_chip1 == g_selchip)
        {
            SPI_REG(SPIDAT1) = 0x01000000;
            SPI_REG(SPIDAT1) = (0x00010000 | g_cshold_mask);
            SPI_REG(SPIDEF) = 0x00000002;
            g_chip_mask = (CHIP1_MASK | g_cshold_mask);
        }
        SPI_REG(SPIGCR1) = 0x01000003;
        tmp = 0;
    }
    break;
    default:
    {
        tmp = -EINVAL;
    }
    break;
    }
    return tmp;
}
Beispiel #14
0
// Writing to the SPI device
ssize_t dv_spi_write(struct file *filp, const char __user *buf, size_t count,
                     loff_t *f_pos)
{
    size_t index = 0;
    unsigned int datareg = 0;
    Uarray buf_val;
    size_t ret = -1;

    if((NULL == buf) || (count <= 0) || (count > MAX_BUF_SIZE))
    {
        return -EINVAL ;
    }
    buf_val.udata = 0;
    while((SPI_REG(SPIBUF) & SPIBUF_RXEMPTY_MASK) == 0)
    {
        cpu_relax();
    }
    if(format_8bit == g_dataformat)
    {
        for(index=0; index<count;)
        {
            buf_val.udata = SPI_REG(SPIBUF);
            if((buf_val.udata & SPIBUF_TXFULL_MASK) == 0)
            {
                ret = copy_from_user(&datareg, buf + index, 1);
                if(ret == 0)
                {
                    datareg &= (0x000000FF);
                    datareg |= g_chip_mask;
                    SPI_REG(SPIDAT1) = datareg;
                    printk("\n1: datareg=%x\n",datareg);
                    wait_untilsend();
                }
            }
            index++;
        }
    }
    else if(format_16bit == g_dataformat)
    {
        for(index=0; index<count;)
        {
            buf_val.udata = SPI_REG(SPIBUF);
            if((buf_val.udata & SPIBUF_TXFULL_MASK) == 0)
            {
                ret = copy_from_user(&datareg, buf + index, 2);
                if(ret == 0)
                {
                    datareg &= (0x0000FFFF);
                    datareg |= g_chip_mask;
                    SPI_REG(SPIDAT1) = datareg;
                    wait_untilsend();
                    SPI_REG(SPIDAT1) = (datareg|0x8000);
                    wait_untilsend();
#if 0
                    buf_val.udata = SPI_REG(SPIBUF);
                    add2kfifo(&(buf_val.uarray[0]),2);
#endif
                }
            }
            index += 2;
        }
    }
    return count;
}