Jump to content
  • 0

uc32 GPIO Programming problem


bgetz

Question

I'm very confused as to why I can't get 3 GPIO's to work as desired.

I'm trying to program 3 external shift registers.  The control lines are Clk, Latch, Output Enable and Data In.  I've implemented a ~240Hz timer to cycle between 4 16-bit values to be sent to the shift registers.  Everything works except the 3 data inputs.  The actual failure is the bit shifting and mask of each of the 16-bits of the 3 data in variables.

I'm including my code and an analyzer trace (uc32 pins directly to a Saleae logic analyzer).

I'd appreciate anyone that could shed some light.

Thanks!

Test.pde

/*

 To turn on any given channel, set the pin LOW.
 To turn off, set the pin HIGH. The higher the analogWrite level,
 the lower the brightness.

 This example code is in the public domain.
*/
#define __32MX340F512H__ 1

#include <p32xxxx.h>
#include <plib.h>

#define CLK        0x0400       // D10
#define Ou1        0x0080       // D07
#define Ou2        0x0040       // D06
#define Ou3        0x0020       // D05
#define OE         0x0010       // D04
#define LE         0x0008       // D03
#define E0         0x0040       // G06
#define E1         0x0080       // G07
#define E2         0x0100       // G08
#define E3         0x0040       // F06
#define INDCTR     0x0800       // D11
#define CTR1       0x0020       // F5
#define CTR0       0x0010       // F4

#define PIN_CLK    8
#define PIN_Ou1    37
#define PIN_Ou2    36
#define PIN_Ou3    34
#define PIN_OE     10
#define PIN_LE     9

#define PIN_E0     13
#define PIN_E1     12
#define PIN_E2     11
#define PIN_E3     38

#define PIN_CTR1   40
#define PIN_CTR0   39
#define PIN_INDCTR 35

#define CPU_HZ                  80000000
#define TICKS_PER_SECOND        (CPU_HZ / 2)

#define Tx_ON                   0x8000
#define Tx_PS_1_8               (3 << 4)
#define Tx_SOURCE_INT           0

volatile uint32_t counter = 0;
volatile uint32_t intHit = 0;
volatile uint32_t eCount = 0;
volatile uint32_t OutA1[4] = { 0xaaaa, 0x5555, 0x9999, 0x6666 };
volatile uint32_t OutA2[4] = { 0x5555, 0x9999, 0x6666, 0xaaaa };
volatile uint32_t OutA3[4] = { 0x9999, 0x6666, 0xaaaa, 0x5555 };

/* Define the Interrupt Service Routine (ISR) */
void __attribute__((interrupt)) myISR() {
   ++counter;
   if ( counter == 4 )
      counter = 0;
   intHit = 1;

   if ( counter & 0x01 )
      LATFSET = CTR0;
   else
      LATFCLR = CTR0;

   if ( counter & 0x02 )
      LATFSET = CTR1;
   else
      LATFCLR = CTR1;

   LATDSET = INDCTR;
   _nop();
   LATDCLR = INDCTR;
   clearIntFlag(_TIMER_3_IRQ);
}

/* start_timer_3 */
void start_timer_3( uint32_t frequency ) {
   uint32_t period;

   period = TICKS_PER_SECOND / frequency;
   T3CONCLR = Tx_ON;            /* Turn the timer off */
   T3CON = Tx_PS_1_8;           /* Set the prescaler */
   TMR3 = 0;                    /* Clear the counter */
   PR3 = period;                /* Set the period */
   T3CONSET = Tx_ON;            /* Turn the timer on */
}

void setup()
{
   // Initialize serial communications:
   Serial.begin(115200);
   Serial.println("hello");

   // Set all used outputs to open-drain
   ODCDSET = CLK | Ou1 | Ou2 | Ou3 | OE | LE | INDCTR;
   ODCFSET = E3 | CTR1 | CTR0;
   ODCGSET = E0 | E1 | E2;

   // Set all used outputs to a low
   LATDCLR = CLK | Ou1 | Ou2 | Ou3 | OE | LE | INDCTR;
   LATFCLR = E3 | CTR1 | CTR0;
   LATGCLR = E0 | E1 | E2;

   // Set all Analogue pins to digitial
   AD1PCFG = 0xffff;

   // Set LED Control outputs to normal TTL, not open-drain
   ODCDCLR = CLK | Ou1 | Ou2 | Ou3 | OE | LE | INDCTR;
   ODCFCLR = E3 | CTR1 | CTR0;
   ODCGCLR = E0 | E1 | E2;

   // set LED control pins as outputs
   TRISDCLR = CLK | Ou1 | Ou2 | Ou3 | OE | LE | INDCTR;
   TRISFCLR = E3 | CTR1 | CTR0;
   TRISGCLR = E0 | E1 | E2;

   // Disable the interrupt-on-change for IO pins
   CNCONCLR = 0xe000;

   // Set OE to high
   LATDSET = OE;

   counter     = 8;
   intHit  = 0;

   start_timer_3( 60 * 4 );               /* 240 Hz */
   setIntVector( _TIMER_3_VECTOR, myISR );
   setIntPriority( _TIMER_3_VECTOR, 4, 0 );
   clearIntFlag( _TIMER_3_IRQ );
   setIntEnable( _TIMER_3_IRQ );
}

void loop()
{
   int i, j;
   int to1, to2, to3;

   if ( intHit ) {
      eCount = counter & 0x03;

      /* Make sure CLK and LE are low */
      digitalWrite( PIN_CLK, LOW );
      digitalWrite( PIN_LE, LOW );

      /* Make sure OE is hi */
      digitalWrite( PIN_OE, HIGH );

      /* Prepare the Out Data lines by setting them LOW */
      digitalWrite( PIN_Ou1, LOW );
      digitalWrite( PIN_Ou2, LOW );
      digitalWrite( PIN_Ou3, LOW );

      to1 = OutA1[eCount];
      to2 = OutA2[eCount];
      to3 = OutA3[eCount];

      for ( i = 0; i < 16; i++ ) {
         /* Test Red */
         if ( to1 & 0x01 ) {
            digitalWrite( PIN_Ou1, HIGH );
         }

         /* Test Green */
         if ( to2 & 0x01 ) {
            digitalWrite( PIN_Ou2, HIGH );
         }

         /* Test Blue */
         if ( to3 & 0x01 ) {
            digitalWrite( PIN_Ou3, HIGH );
         }

         /* Toggle CLK */
         digitalWrite( PIN_CLK, HIGH );
         digitalWrite( PIN_CLK, LOW );

         to1 = to1 >> 1;
         to2 = to2 >> 1;
         to3 = to3 >> 1;
      }

      /* Toggle LE, then set OE low */
      digitalWrite( PIN_LE, HIGH );
      digitalWrite( PIN_LE, LOW );
      digitalWrite( PIN_OE, LOW );

      digitalWrite( PIN_E0, LOW );
      digitalWrite( PIN_E1, LOW );
      digitalWrite( PIN_E2, LOW );
      digitalWrite( PIN_E3, LOW );

      switch ( eCount ) {
      case 0:
         digitalWrite( PIN_E0, HIGH );
         break;
      case 1:
         digitalWrite( PIN_E1, HIGH );
         break;
      case 2:
         digitalWrite( PIN_E2, HIGH );
         break;
      case 3:
         digitalWrite( PIN_E3, HIGH );
         break;
      default:
         break;
      }

      intHit = 0;
   }

uc32_analyzer_trace.png

Link to comment
Share on other sites

1 answer to this question

Recommended Posts

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...