void Adafruit_DotStar::show(void) {

  if(!pixels) return;

  uint8_t *ptr = pixels, i;            // -> LED data
  uint16_t n   = numLEDs;              // Counter
  uint16_t b16 = (uint16_t)brightness; // Type-convert for fixed-point math

  //__disable_irq(); // If 100% focus on SPI clocking required

  if(dataPin == USE_HW_SPI) {

    for(i=0; i<4; i++) spi_out(0x00);    // 4 byte start-frame marker
    if(brightness) {                     // Scale pixel brightness on output
      do {                               // For each pixel...
        spi_out(0xFF);                   //  Pixel start
        for(i=0; i<3; i++) spi_out((*ptr++ * b16) >> 8); // Scale, write RGB
      } while(--n);
    } else {                             // Full brightness (no scaling)
      do {                               // For each pixel...
        spi_out(0xFF);                   //  Pixel start
        for(i=0; i<3; i++) spi_out(*ptr++); // Write R,G,B
      } while(--n);
    }

    // Four end-frame bytes are seemingly indistinguishable from a white
    // pixel, and empirical testing suggests it can be left out...but it's
    // always a good idea to follow the datasheet, in case future hardware
    // revisions are more strict (e.g. might mandate use of end-frame
    // before start-frame marker).  i.e. let's not remove this.
    for(i=0; i<4; i++) spi_out(0xFF);

  } else {                               // Soft (bitbang) SPI
Ejemplo n.º 2
0
void Adafruit_DotStar::show(void) {

  if(!pixels) return;

  uint8_t *ptr = pixels, i;            // -> LED data
  uint16_t n   = numLEDs;              // Counter
  uint16_t b16 = (uint16_t)brightness; // Type-convert for fixed-point math

  if(dataPin == USE_HW_SPI) {

#ifdef SPI_PIPELINE
    uint8_t next;
    for(i=0; i<3; i++) spi_out(0x00);    // First 3 start-frame bytes
    SPDR = 0x00;                         // 4th is pipelined
    do {                                 // For each pixel...
      while(!(SPSR & _BV(SPIF)));        //  Wait for prior byte out
      SPDR = 0xFF;                       //  Pixel start
      for(i=0; i<3; i++) {               //  For R,G,B...
        next = brightness ? (*ptr++ * b16) >> 8 : *ptr++; // Read, scale
        while(!(SPSR & _BV(SPIF)));      //   Wait for prior byte out
        SPDR = next;                     //   Write scaled color
      }
    } while(--n);
    while(!(SPSR & _BV(SPIF)));          // Wait for last byte out
#else
    for(i=0; i<4; i++) spi_out(0x00);    // 4 byte start-frame marker
    if(brightness) {                     // Scale pixel brightness on output
      do {                               // For each pixel...
        spi_out(0xFF);                   //  Pixel start
        for(i=0; i<3; i++) spi_out((*ptr++ * b16) >> 8); // Scale, write RGB
      } while(--n);
    } else {                             // Full brightness (no scaling)
      do {                               // For each pixel...
Ejemplo n.º 3
0
static uint8_t readOp (uint8_t op, uint8_t address) {
    spi_enable_eth();
    spi_out(op | (address & ADDR_MASK));
    if (address & 0x80)
        spi_out(0x00);
    uint8_t result = spi_in();
    spi_disable_eth();
    return result;
}
Ejemplo n.º 4
0
static int ap_get_head(struct sc8800_data *sc8800, struct bp_head *packet)
{
	int err = 0, count = 5;
	char buf[BP_PACKET_SIZE];

retry:
	spi_out(sc8800, packet, BP_PACKET_SIZE, &err);

	if(err < 0 && count > 0)
	{
		dev_warn(sc8800->dev, "%s spi_out return error, retry count = %d\n",
				__func__, count);
		count--;
		mdelay(10);
		goto retry;
	}
	if(err < 0)
		return err;

	//memcpy((char *)(packet), buf, BP_PACKET_SIZE);

	sc8800_dbg(sc8800->dev, "%s tag = 0x%4x, type = 0x%4x, length = %x\n",
			__func__, packet->tag, packet->type, packet->length);
		
	if ((packet->tag != 0x7e7f) || (packet->type != 0xaa55)) 
		return -1;
	else
		return 0;
}
Ejemplo n.º 5
0
static int sc8800_rx(struct sc8800_data *sc8800)
{
	int ret = 0, len, real_len;
	struct bp_head packet;
	char *buf = NULL;

	ap_rdy(sc8800,0);
	ret = ap_get_head(sc8800, &packet);

	if(ret < 0){
		dev_err(sc8800->dev, "ERR: %s ap_get_head err = %d\n", __func__, ret);
		goto out;
	}
	len = packet.length;
	if(len > BP_PACKET_DATA_LEN)
		real_len =	(((len -BP_PACKET_DATA_LEN-1)/BP_PACKET_SIZE)+2)*BP_PACKET_SIZE;
	else
		real_len = BP_PACKET_SIZE;
	if(len > RD_BUF_SIZE){
		dev_err(sc8800->dev, "ERR: %s len[%d] is large than buffer size[%lu]\n",
				__func__, real_len, RD_BUF_SIZE);	
		goto out;
	}
	buf = kzalloc(real_len, GFP_KERNEL);
	if(!buf){
		dev_err(sc8800->dev,"ERR: %s no memmory for rx_buf\n", __func__);
		goto out;
	}

	memcpy(buf, packet.data, BP_PACKET_DATA_LEN);
	if(len > BP_PACKET_DATA_LEN)
		spi_out(sc8800, buf + BP_PACKET_DATA_LEN, real_len-BP_PACKET_SIZE, &ret);
	
	if(ret < 0){
		dev_err(sc8800->dev, "ERR: %s spi out err = %d\n", __func__, ret);
		goto out;
	}

	spin_lock(&sc8800->lock);
	if(sc8800->rx_len + len > RD_BUF_SIZE){
		dev_warn(sc8800->dev, "WARN: %s read buffer is full\n", __func__);
	}else
	{
		memcpy(sc8800->rx_buf+sc8800->rx_len, buf, len);
		sc8800->rx_len += len;
	}
	spin_unlock(&sc8800->lock);

	sc8800_dbg(sc8800->dev, "%s rx_len = %d\n", __func__, sc8800->rx_len);

	ret = sc8800->rx_len;

out:
	ap_rdy(sc8800,1);
	if(buf)
		kfree(buf);
	buf = NULL;
	return ret;

}
void Adafruit_WS2801::show(void) {
  uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED
  uint8_t  bit;

  // Write 24 bits per pixel:
  if(hardwareSPI) {
    for(i=0; i<nl3; i++) spi_out(pixels[i]);
  } else {
    for(i=0; i<nl3; i++ ) {
      for(bit=0x80; bit; bit >>= 1) {
#ifdef __AVR__
        if(pixels[i] & bit) *dataport |=  datapinmask;
        else                *dataport &= ~datapinmask;
        *clkport |=  clkpinmask;
        *clkport &= ~clkpinmask;
#else
        if(pixels[i] & bit) digitalWrite(datapin, HIGH);
        else                digitalWrite(datapin, LOW);
        digitalWrite(clkpin, HIGH);
        digitalWrite(clkpin, LOW);
#endif
      }
    }
  }

  delay(1); // Data is latched by holding clock pin low for 1 millisecond
}
Ejemplo n.º 7
0
/**
  * @brief  Set SPI divider
  * @param[in] dev pointer to spi interface structure
  * @param[in] speed desire spi speed
  * @return speed set actually
  */
static uint32_t spiSetSpeed(spi_dev * dev, uint32_t speed)
{
    uint16_t div = (uint16_t)(SPI_INPUT_CLOCK / (2 * speed)) - 1;

    spi_out(dev, div, DIVIDER);
    return ( SPI_INPUT_CLOCK /  (2*(div+1)));
}
Ejemplo n.º 8
0
/**
  * @brief Write data to spi interface
  * @param[in] fd is interface number.
  * @param[in] buff_id is buffer number. If transfer number is 4, application needs write 4 times (buff_id is from 0 to 3) to buffer.
  * @param[in] data is data to be written.
  * @return none
  */
void spiWrite(int32_t fd, uint8_t buff_id, uint32_t data)
{
    spi_dev *dev;

    dev = (spi_dev *)((uint32_t)&spi_device[fd]);
    spi_out(dev, data, (TX0+4*buff_id));
}
Ejemplo n.º 9
0
void LPD8806::show(void) {
  uint8_t  *ptr = pixels;
  uint16_t i    = numBytes;

  // This doesn't need to distinguish among individual pixel color
  // bytes vs. latch data, etc.  Everything is laid out in one big
  // flat buffer and issued the same regardless of purpose.
  if(hardwareSPI) {
    while(i--) spi_out(*ptr++);
  } else {
    uint8_t p, bit;

    while(i--) {
      p = *ptr++;
      for(bit=0x80; bit; bit >>= 1) {
#ifdef __AVR__
	  if(p & bit) *dataport |=  datapinmask;
	  else        *dataport &= ~datapinmask;
	  *clkport |=  clkpinmask;
	  *clkport &= ~clkpinmask;
#else
	  if(p & bit) digitalWrite(datapin, HIGH);
	  else        digitalWrite(datapin, LOW);
	  digitalWrite(clkpin, HIGH);
	  digitalWrite(clkpin, LOW);
#endif
      }
    }
  }
}
Ejemplo n.º 10
0
static void readBuf(uint16_t len, uint8_t* data) {
    spi_enable_eth();
    spi_out(ENC28J60_READ_BUF_MEM);
    while (len--) {
        *data++ = spi_in();
    }
    spi_disable_eth();
}
Ejemplo n.º 11
0
Archivo: lcd.c Proyecto: Damme/LandLord
uint8_t u8g_com_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
{
    switch (msg) {
        case U8G_COM_MSG_STOP:
            break;

        case U8G_COM_MSG_INIT:
            // init spi and ports
            u8g_MicroDelay();
            break;

        case U8G_COM_MSG_ADDRESS:                     /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
            //u8g_10MicroDelay();
            GPIO_SET_PIN_VAL(LCD_A0, arg_val);
            u8g_MicroDelay();
            break;

        case U8G_COM_MSG_CHIP_SELECT:
            GPIO_SET_PIN_VAL(LCD_CSB, !arg_val);

            u8g_MicroDelay();
            break;

        case U8G_COM_MSG_RESET:
            GPIO_SET_PIN_VAL(LCD_RSTB, arg_val);
            u8g_MicroDelay();
            break;

        case U8G_COM_MSG_WRITE_BYTE:
            spi_out(arg_val);
            u8g_MicroDelay();
            break;

        case U8G_COM_MSG_WRITE_SEQ:
        case U8G_COM_MSG_WRITE_SEQ_P: {
                register uint8_t *ptr = arg_ptr;
                while (arg_val > 0) {
                    spi_out(*ptr++);
                    arg_val--;
                }
            }
            break;
    }
    return 1;
}
Ejemplo n.º 12
0
// Enable SPI hardware and set up protocol details:
void LPD8806::startSPI(void) {
#ifdef __AVR_ATtiny85__
  PORTB &= ~(_BV(PORTB1) | _BV(PORTB2)); // Outputs
  DDRB  |=   _BV(PORTB1) | _BV(PORTB2);  // DO (NOT MOSI) + SCK
#else
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  // SPI bus is run at 2MHz.  Although the LPD8806 should, in theory,
  // work up to 20MHz, the unshielded wiring from the Arduino is more
  // susceptible to interference.  Experiment and see what you get.
 #if defined(__AVR__) || defined(CORE_TEENSY)
  SPI.setClockDivider(SPI_CLOCK_DIV8);
 #else
  SPI.setClockDivider((F_CPU + 1000000L) / 2000000L);
 #endif
#endif

  // Issue initial latch/reset to strip:
  for(uint16_t i=((numLEDs+31)/32); i>0; i--) spi_out(0);
}
Ejemplo n.º 13
0
static void writeOp (uint8_t op, uint8_t address, uint8_t data) {
    spi_enable_eth();
    spi_out(op | (address & ADDR_MASK));
    spi_out(data);
    spi_disable_eth();
}
Ejemplo n.º 14
0
uint8_t u8g_com_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
{
  switch(msg)
  {
    case U8G_COM_MSG_STOP:
      break;
    
    case U8G_COM_MSG_INIT:

       if ( arg_val <= U8G_SPI_CLK_CYCLE_50NS )
      {
        spi_init(SPI_BAUDRATEPRESCALER_2);
      }
      else if ( arg_val <= U8G_SPI_CLK_CYCLE_300NS )
      {
        spi_init(SPI_BAUDRATEPRESCALER_4);
      }
      else if ( arg_val <= U8G_SPI_CLK_CYCLE_400NS )
      {
        spi_init(SPI_BAUDRATEPRESCALER_4);
      }
      else
      {
        spi_init(SPI_BAUDRATEPRESCALER_8);
      }
      u8g_MicroDelay();      
      break;
    
    case U8G_COM_MSG_ADDRESS:                     /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
      u8g_10MicroDelay();
      set_gpio_level(LCD_CD_PIN, arg_val);
      u8g_10MicroDelay();
     break;

    case U8G_COM_MSG_CHIP_SELECT:
      if ( arg_val == 0 )
      {
        /* disable */
        uint8_t i;
        /* this delay is required to avoid that the display is switched off too early --> DOGS102 with LPC1114 */
        for( i = 0; i < 5; i++ )u8g_10MicroDelay();
        set_gpio_level(LCD_CS_PIN, 1);
      }
      else
      {
        /* enable */
        set_gpio_level(LCD_CS_PIN, 0);
      }
      u8g_MicroDelay();
      break;
      
    case U8G_COM_MSG_RESET:
      set_gpio_level(LCD_RST_PIN, arg_val);
      u8g_10MicroDelay();
      break;
      
    case U8G_COM_MSG_WRITE_BYTE:
      spi_out(arg_val);
      u8g_MicroDelay();
      break;
    
    case U8G_COM_MSG_WRITE_SEQ:
    case U8G_COM_MSG_WRITE_SEQ_P:
      {
        register uint8_t *ptr = arg_ptr;
        while( arg_val > 0 )
        {
          spi_out(*ptr++);
          arg_val--;
        }
      }
      break;
  }
  return 1;
}
Ejemplo n.º 15
0
/**
  * @brief Support some spi driver commands for application.
  * @param[in] fd is interface number.
  * @param[in] cmd is command.
  * @param[in] arg0 is the first argument of command.
  * @param[in] arg1 is the second argument of command.
  * @return command status.
  * @retval 0 Success otherwise fail. Fail value could be
  *                                    - \ref SPI_ERR_NODEV
  *                                    - \ref SPI_ERR_IO
  *                                    - \ref SPI_ERR_ARG
  */
int32_t spiIoctl(int32_t fd, uint32_t cmd, uint32_t arg0, uint32_t arg1)
{
    spi_dev *dev;

    if(fd != 0 && fd != 1)
        return(SPI_ERR_NODEV);

    dev = (spi_dev *)((uint32_t)&spi_device[fd]);
    if(dev->openflag == 0)
        return(SPI_ERR_IO);

    switch(cmd)
    {
        case SPI_IOC_TRIGGER:
            dev->intflag = 0;
            spi_out(dev, spi_in(dev, CNTRL) | 0x1 ,CNTRL);
            break;

        case SPI_IOC_SET_INTERRUPT:
            if(arg0 == SPI_ENABLE_INTERRUPT)
                spi_out(dev, spi_in(dev, CNTRL) | (0x1<<17) ,CNTRL);
            else
                spi_out(dev, spi_in(dev, CNTRL) & ~(0x1<<17) ,CNTRL);
            break;

        case SPI_IOC_SET_SPEED:
            spiSetSpeed(dev, (uint32_t)arg0);
            break;

        case SPI_IOC_SET_DUAL_QUAD_MODE:
            if(arg0 == SPI_DISABLE_DUAL_QUAD)
            {
                spi_out(dev, (spi_in(dev, CNTRL) & ~(0x3 << 21)) ,CNTRL);
                break;
            }

            if(arg0 == SPI_DUAL_MODE)
                spi_out(dev, (spi_in(dev, CNTRL) & ~(0x3 << 21)) | (0x1 << 22) ,CNTRL);
            else
                spi_out(dev, (spi_in(dev, CNTRL) & ~(0x3 << 21)) | (0x1 << 21) ,CNTRL);
            break;

        case SPI_IOC_SET_DUAL_QUAD_DIR:
            if(arg0 == SPI_DUAL_QUAD_INPUT)
                spi_out(dev, spi_in(dev, CNTRL) & ~(0x1 << 20) ,CNTRL);
            else
                spi_out(dev, spi_in(dev, CNTRL) | (0x1 << 20) ,CNTRL);
            break;

        case SPI_IOC_SET_LSB_MSB:
            if(arg0 == SPI_MSB)
                spi_out(dev, spi_in(dev, CNTRL) & ~(0x1 << 10) ,CNTRL);
            else
                spi_out(dev, spi_in(dev, CNTRL) | (0x1 << 10) ,CNTRL);
            break;

        case SPI_IOC_SET_TX_NUM:
            if(arg0 < 4)
                spi_out(dev, (spi_in(dev, CNTRL) & ~(0x3 << 8)) | (arg0 << 8) ,CNTRL);
            else
                return SPI_ERR_ARG;
            break;

        case SPI_IOC_SET_TX_BITLEN:
            if(arg0 < 32)
                spi_out(dev, (spi_in(dev, CNTRL) & ~(0x1f << 3)) | (arg0 << 3) ,CNTRL);
            else
                return SPI_ERR_ARG;
            break;

        case SPI_IOC_SET_MODE:
            if(arg0 > SPI_MODE_3)
                return SPI_ERR_ARG;

            if(arg0 == SPI_MODE_0)
                spi_out(dev, (spi_in(dev, CNTRL) & ~((0x3<<1) | (1UL<<31))) | (1<<2) ,CNTRL);
            else if(arg0 == SPI_MODE_1)
                spi_out(dev, (spi_in(dev, CNTRL) & ~((0x3<<1) | (1UL<<31))) | (1<<1) ,CNTRL);
            else if(arg0 == SPI_MODE_2)
                spi_out(dev, (spi_in(dev, CNTRL) & ~((0x3<<1) | (1UL<<31))) | ((1UL<<31) | (1<<2)) ,CNTRL);
            else
                spi_out(dev, (spi_in(dev, CNTRL) & ~((0x3<<1) | (1UL<<31))) | ((1UL<<31) | (1<<1)) ,CNTRL);
            break;

        case SPI_IOC_ENABLE_SS:
            if(arg0 == SPI_SS_SS0)
                spi_out(dev, (spi_in(dev, SSR) & ~(0x3)) | 0x1 ,SSR);
            else if(arg0 == SPI_SS_SS1)
                spi_out(dev, (spi_in(dev, SSR) & ~(0x3)) | 0x2 ,SSR);
            else if(arg0 == SPI_SS_BOTH)
                spi_out(dev, (spi_in(dev, SSR) & ~(0x3)) | 0x3 ,SSR);
            else
                return SPI_ERR_ARG;
            break;

        case SPI_IOC_DISABLE_SS:
            if(arg0 == SPI_SS_SS0)
                spi_out(dev, (spi_in(dev, SSR) & ~(0x1)) ,SSR);
            else if(arg0 == SPI_SS_SS1)
                spi_out(dev, (spi_in(dev, SSR) & ~(0x2)) ,SSR);
            else if(arg0 == SPI_SS_BOTH)
                spi_out(dev, (spi_in(dev, SSR) & ~(0x3)) ,SSR);
            else
                return SPI_ERR_ARG;
            break;

        case SPI_IOC_SET_AUTOSS:
            if(arg0 == SPI_DISABLE_AUTOSS)
                spi_out(dev, spi_in(dev, SSR) & ~(0x1 << 3) ,SSR);
            else
                spi_out(dev, spi_in(dev, SSR) | (0x1 << 3) ,SSR);
            break;

        case SPI_IOC_SET_SS_ACTIVE_LEVEL:
            if(arg0 == SPI_SS_ACTIVE_LOW)
                spi_out(dev, spi_in(dev, SSR) & ~(0x1 << 2) ,SSR);
            else
                spi_out(dev, spi_in(dev, SSR) | (0x1 << 2) ,SSR);
        default:
            break;
    }

    return 0;
}