ts-7000
[Top] [All Lists]

RE: [ts-7000] how do I synchronize two (or more) digital output pins

To: <>
Subject: RE: [ts-7000] how do I synchronize two (or more) digital output pins
From: "'Daniel Perron' [ts-7000]" <>
Date: Thu, 28 Aug 2014 09:26:32 -0400


sbus_poke16(0x6c, sbus_peek16(0x6c) & ~(1 << pinOffSet));

 

Read 16 bits  IO ports

Create a mask to clear  the corresponding bit .     (1<< n) is equivalent to and the ~ is the complement.

Ex:     ~(1<<(31-21)) =  0xBFF

And write it back.

 

 

In this example it should be possible to write  more than one bits at the time.

 

 

The best way to deal with fast access is to create a complement Mask of all the DIO you want to manipulate and create a Lookup Table with all the possibilities.

Then using the complement mask to knock off DIO bits and the Table to set them will be very effective.

 

 

 

This is an example on how to use it  for a 4 bits LCD display. The DIOS don’t need to be in sequence, it could be any DIO.

 

 

Ex:

 

  #define  NUMBER_OF_DIO  4

 

// set the TABLE_SIZE  to   2 power DIO_NUMBER

#define TABLE_SIZE   16

 

int DIO[NUMBER_OF_DIO]= { 21,22,31,32};

 

unsigned short   Table[TABLE_SIZE];

unsigned short Mask;

 

void initTable(void)

{

  int loop;

 int bits;

  unsigned short _utemp;

  TableSize= pow(2,DIO_NUMBER);

  Table =  alloc(TableSize * sizeof(unsigned short);

 

  // now let’s create the table

 

  for(loop=0;loop<TABLE_SIZE;loop++)

  {

      utemp=0;      

      for(bits=0;bits<NUMBER_OF_DIO;bits++)

        if(loop & (1<<bits))

           utemp|= 1<< (DIO[bits]-21);

      Table[loop]=utemp;

}

// and the Mask;

 Mask = ~Table[TABLE_SIZE-1];

}

 

// And this is the write function

 

void write4bits( unsigned char value)

{

  if(value>= TABLE_SIZE) return;

   sbus_poke16(0x6c, (sbus_peek16(0x6c) & Mask) | Table[value]);

}

 

 

 

This is just an example. 

 

Daniel

 

 

 

 

From: [
Sent: August-27-14 3:02 PM
To:
Subject: [ts-7000] how do I synchronize two (or more) digital output pins

 

 

to turn on and off digital outputs I use the code from sbus.c: 

 

 sbuslock();

 setdiopin(pin, val);

 sbusunlock();

 

//code is below....

 

now this is fine and dandy for setting a single pin on or off, but what if I want to set a bank of DIO's 

(say pin 31 and 33 ) to both on at the same time. 

 

when I do the setdiopin(31,val);

                     setdiopin(33,val); 

 

they don't happen at the same time but rather on after the other.  

 

Now I can see in the code they are bit-mapping, and filtering, but I'm lost in the 1's compliment, and shifting:

          pinOffSet = pin - 21;

         sbus_poke16(0x6c, sbus_peek16(0x6c) & ~(1 << pinOffSet));

 

can someone explain what is happening with the above statement?  sbus_poke16 looks to me as if it is writing an 8-bit value to the address 0x6c, and its masking to ~(1<<pinOffSet) but I'm getting lost. 

 

TIA,

 

Jleslie

 

 

 

 

 

 

 

 

/*******************************************************************************

* setdiopin: accepts a DIO register and value to place in that DIO pin.

*   Values can be 0 (low), 1 (high), or 2 (z - high impedance).

*******************************************************************************/

void setdiopin(int pin, int val)

{

   int pinOffSet;

&nb sp;  int dirPinOffSet; // For Register 0x66 only

   int outPinOffSet; // For Register 0x66 only

 

   // First, check for the high impedance case

   if (val == 2)

   {

      if (pin <= 40 && pin >= 37)

      {

         dirPinOffSet = pin - 33;

         sbus_poke16(0x66, sbus_peek16(0x66) & ~(1 << dirPinOffSet));

      }

      else if (pin <= 36 && pin >= 21)

      {

         pinOffSet = pin - 21;

         sbus_poke16(0x6c, sbus_peek16(0x6c) & ~(1 << pinOffSet));

      }

      else if (pin <= 20 && pin >= 5)

      {

         pinOffSet = pin - 5;

         sbus_poke16(0x72, sbus_peek16(0x72) & ~(1 << pinOffSet));

      }

   }

 

   /*******************************************************************

   *0x66: DIO and tagmem control (RW)

   *  bit 15-12: DIO input for pins 40(MSB)-37(LSB) (RO)

   *  bit 11-8: DIO output for pins 40(MSB)-37(LSB) (RW)

   *  bit 7-4: DIO direction for pins 40(MSB)-37(LSB) (1 - output) (RW)

   ********************************************************************/

   else if (pin <= 40 && pin >= 37)

   {

      dirPinOffSet = pin - 33; // -37 + 4 = Direction; -37 + 8 = Output

      outPinOffSet = pin - 29;

 

      // set bit [pinOffset] to [val] of register [0x66]

      if(val)

      &n bsp;  sbus_poke16(0x66, (sbus_peek16(0x66) | (1 << outPinOffSet)));

      else

         sbus_poke16(0x66, (sbus_peek16(0x66) & ~(1 << outPinOffSet)));

 

      // Make the specified pin into an output in direction bits

      sbus_poke16(0x66, sbus_peek16(0x66) | (1 << dirPinOffSet)); ///

 

   }

 

   /*********************************************************************

   *0x68: DIO input for pins 36(MSB)-21(LSB) (RO)

   *0x6a: DIO output for pins 36(MSB)-21(LSB) (RW)

   *0x6c: DIO direction for pins 36(MSB)-21(LSB) (1 - output) (RW)

   *********************************************************************/

   else if (pin <= 36 && pin >= 21)

   {

      pinOffSet = pin - 21;

 

      // set bit [pinOffset] to [val] of register [0x6a]

      if(val)

         sbus_poke16(0x6a, (sbus_peek16(0x6a) | (1 << pinOffSet)));

      else

         sbus_poke16(0x6a, (sbus_peek16(0x6a) & ~(1 << pinOffSet)));

 

      // Make the specified pin into an output in direction register

      sbus_poke16(0x6c, sbus_peek16(0x6c) | (1 << pinOffSet)); ///

   }

 

   /*********************************************************************

   *0x6e: DIO input for pins 20(MSB)-5(LSB) (RO)

   *0x70: DIO output for pins 20(MSB)-5(LSB) (RW)

   *0x72: DIO direction for pins 20(MSB)-5(LSB) (1 - output) (RW)

   *********************************************************************/

   else if (pin <= 20 && pin >= 5 )

   {

      pinOffSet = pin - 5;

 

      if(val)

         sbus_poke16(0x70, (sbus_peek16(0x70) | (1 << pinOffSet)));

      else

         sbus_poke16(0x70, (sbus_peek16(0x70) & ~(1 << pinOffSet)));

 

      // Make the specified pin into an output in direction register

      sbus_poke16(0x72, sbus_peek16(0x72) | (1 << pinOffSet));

   }

 

}

 

 

void sbus_poke16(unsigned int adr, unsigned short dat) {

        unsigned int dummy;

        if (last_gpio_adr != adr >> 5) {

                last_gpio_adr = adr >> 5;

                cvgpioregs[0] = (cvgpioregs[0] & ~(0x3<<15))|((adr>>5)<<15);

        }

        adr &= 0x1f;

 

        asm volatile (

                "mov %0, %1, lsl #18\n"

                "orr %0, %0, #0x800000\n"

                "orr %0, %0, %2, lsl #3\n"

                "3: ldr r1, [%3, #0x64]\n"

                "cmp r1, #0x0\n"

                "bne 3b\n"

                "2: str %0, [%3, #0x50]\n"

                &q uot;1: ldr r1, [%3, #0x64]\n"

                "cmp r1, #0x0\n"

                "beq 1b\n"

                "ldr %0, [%3, #0x58]\n"

                "ands r1, %0, #0x1\n"

                "moveq %0, #0x0\n"

                "beq 3b\n"

                : "+r"(dummy) : "r"(adr), "r"(dat), "r"(cvspiregs) : "r1","cc"

        );

}

 

 

unsigned short sbus_peek16(unsigned int adr) {

        unsigned short ret;

 

        if (last_gpio_adr != adr >> 5) {

                last_gpio_adr = adr >> 5;

                cvgpioregs[0] = ((adr>>5)<<15|1<<3|1<<17);

        }

        adr &= 0x1f;

 

        asm volatile (

                "mov %0, %1, lsl #18\n"

                "2: str %0, [%2, #0x50]\n"

                "1: ldr r1, [%2, #0x64]\n"

                "cmp r1, #0x0\n"

                "beq 1b\n"

        &nb sp;       "ldr %0, [%2, #0x58]\n"

                "ands r1, %0, #0x10000\n"

                "bicne %0, %0, #0xff0000\n"

                "moveq %0, #0x0\n"

                "beq 2b\n"

                : "+r"(ret) : "r"(adr), "r"(cvspiregs) : "r1", "cc"

        );

 

        return ret;

 

}

 

 

 

 

 



__._,_.___

Posted by: "Daniel Perron" <>



__,_._,___

JPEG image

JPEG image

<Prev in Thread] Current Thread [Next in Thread>
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU