Jump to content
Sign in to follow this  

CC3200 : Control pins without digitalWrite

Recommended Posts

I am trying to do some fast bit bang in C to see what is possible without going to asm.


But I havent had much luck in doing a simple on/off or toggle using bit manipulation instead of calling digitalWrite.


My noble attempt didnt really do much.

  uint16_t pin;
  uint8_t port;
  uint8_t mask;

void setup()
  pinMode(4, OUTPUT);
  pin = digital_pin_to_pin_num[4]; //PIN_03 GPIO_12
  port = digital_pin_to_port[4]; //S1
  mask = digital_pin_to_bit_mask[4]; //BV(4),		/*  4  - GPIO_12 */

void loop()
  port ^= mask;

I found digitalWrite in the sourcecode, and it calls MAP_GPIOPinWrite

When then calls GPIOPinWrite or ROM_GPIOPinWrite

Which then calls ASSERT and HWREG.


So maybe I need to call HWREG to get as close to bit bang as possible ?


By the way, I tested the digitalWrite function just to have a baseline, in a while(1) loop turning on and off the same pin, it gets 400ns pulses at 80MHz, so 32cycles if I did the math correctly.

Share this post

Link to post
Share on other sites

Ok, so digital_pin_to_port gives you an index in another table of BASE registers...


So it's more like:


port = digital_pin_to_port[4];

uint32_t portBase = (uint32_t) portBASEregister(port);

HWREG(portBase + (GPIO_O_GPIO_DATA + (mask << 2))) ^= mask;


(haven't tested this yet btw)

Otoh, reading about how that register math works on page 115 of the CC3200 TRM was kind've interesting.  With the GPIO data register, bits [9:2] on the address bus form a mask of which bits are affected by the assigned value, hence the "+ (mask << 2)" part.  Neat.

Share this post

Link to post
Share on other sites

Having to do the xor is probably slowing this down a bit, (means reading the port, doing xor).  Loop of course slows down a lot.  


If you really need it tight, could maybe get the port in a particular state, then do a series of write 0, write 0xFF, write 0, .... (i.e. unroll the loop).  Resulting code should load 0 and 0xFF into a couple of registers, then just be a series of writing alternate registers to the fixed port address (so you get one toggle per instruction).  Should give an order of magnitude speedup.


To go any faster than that would probably involve either a deep knowledge of the ARM instruction set/pipelines/etc., using special hardware (DMA, EPI, etc.), etc.

Share this post

Link to post
Share on other sites

In the final code I will know what state it needs to be, for now its just testing to see what is possible.

To run WS2811 code from c I need toggles around 30-70 cycles and some time left to pull the bytes from a array.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this