To: | <> |
---|---|
Subject: | [ts-7000] how do I synchronize two (or more) digital output pins |
From: | " [ts-7000]" <> |
Date: | 27 Aug 2014 12:02:04 -0700 |
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; 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) 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" "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" "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: __,_._,___ |
<Prev in Thread] | Current Thread | [Next in Thread> |
---|---|---|
|
Next by Date: | RE: [ts-7000] how do I synchronize two (or more) digital output pins, 'Daniel Perron' djperron@optest.com [ts-7000] |
---|---|
Next by Thread: | RE: [ts-7000] how do I synchronize two (or more) digital output pins, 'Daniel Perron' djperron@optest.com [ts-7000] |
Indexes: | [Date] [Thread] [Top] [All Lists] |
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