Jump to content
43oh

Recommended Posts

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.

 

 

Link to post
Share on other sites

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.)

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...