altineller 4 Posted February 10, 2015 Share Posted February 10, 2015 Hello, For a certain experiment I need to do, I need to generate some pulses, as fast as possible. For beginning I need a square wave, basically, so I wrote the following code: (which does not work, according to my scope) #include <Energia.h> #include "inc/lm4f120h5qr.h" #include "driverlib/gpio.h" void setup() { GPIOPadConfigSet(GPIO_PORTA_BASE, 0xff, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); GPIODirModeSet(GPIO_PORTA_BASE, 0xff, GPIO_DIR_MODE_OUT); } void loop() { GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6, LOW); GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6, HIGH); } Basically I want to turn on and off gpio_pin_6 as fast as possible? Any ideas/recomendations/help greatly appreciated, Best regards, C.A. Quote Link to post Share on other sites
igor 163 Posted February 11, 2015 Share Posted February 11, 2015 Here is a section snipped from the RGB led matrix driver adaptation I did. (Needed to send a lot of bits as fast as possible). https://github.com/ecdr/RGB-matrix-Panel // Energia does not define portOutputRegister(port) for Tiva, so make up replacement. // portMaskedOutputRegister(port, mask) // include port mask so do not need read, modify, write // can just write to the address, and it will not change other pins // For reference: // void digitalWrite(uint8_t pin, uint8_t val) = // HWREG(portBASERegister(digitalPinToPort(pin)) + (GPIO_O_DATA + (digitalPinToBitMask(pin) << 2))) = val ? 0xFF : 0; // HWREGB should work instead (since all ports are 8 bits max) // 0 //#define HWREG(x) (*((volatile uint32_t *)(x))) //#define HWREGB(x) (*((volatile uint8_t *)(x))) // TODO: Consider bitband version, for 1 bit control lines // BITBAND /* //#define HWREGBITB(x, \ // HWREGB(((uint32_t)(x) & 0xF0000000) | 0x02000000 | \ // (((uint32_t)(x) & 0x000FFFFF) << 5) | (( << 2)) */ // Caution - be careful of adding masks to pointer types. // Cast the portBASERegister back to uint32_t before add offset // Otherwise it will do a clandestine left shift 2 on the mask // Alternative would be to make use of that left shift, // but then need a big note explaining the occult behavior #define portMaskedOutputRegister(port, mask) \ ((volatile uint8_t *) (((uint32_t)portBASERegister(port)) + (GPIO_O_DATA + (((uint32_t)mask) << 2)))) sclkpin = digitalPinToBitMask(sclk); sclkport = portMaskedOutputRegister(digitalPinToPort(sclk), sclkpin); (*sclkport) = 0xFF; (*sclkport) = 0x0; (*sclkport) = 0xFF; (*sclkport) = 0x0; (*sclkport) = 0xFF; (*sclkport) = 0x0; (*sclkport) = 0xFF; (*sclkport) = 0x0; ... Speedups used above: Translate the port/pin into an address once. Used the pin masking features of the Tiva so don't have to do read/modify/write. Save the address in a variable (faster than a constant on ARM). Replaced library calls with inline code. Unroll the loop (i.e. faster to do series of writes without the loop overhead). (Might need some experimentation depends how long a pulse stream you need - depends on cache/etc.) Other approaches: How fast can you do it with a timer? With DMA? (If can do away with overhead of general purpose processor, may be able to do it faster.) Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.