Jump to content

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.

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.

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.

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.

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