Minimus usb – getting the solder out

May 21, 2012 at 10:31 pm (computers) (, , )

Ok, having spent some time programming the device as is (see my previous posts here and here) if I was to get any further I have to do some soldering!  The minimus has 22 IO pins sitting around the edge of the circuit board.

All 8 port B and port D IO pins are available, along with 5 of port C – bits 2 and 4-7.  Recall that bits 5 and 6 of port D are the onboard LEDs and bit 7 is the onboard switch, so niaively I wondered why only part of port C was exposed, when bits of port D that were already in use were exposed. It turns out that the other bits of port C are used for other things – PC1 is the reset (I think) for example.

So, I have lots of bits of old PCs kicking around, so I found some old IDE cables – with 40 pin connectors, and got a 40 pin IDC PCB mounted connector to plug into it. It is possible to plug the IDE cable to both sides of a connector, so it can effectively join two IDE cables together.

So, I’ve soldered 24 leads of the IDE cable to the minimus, giving me the following:

  • Vcc
  • PC2
  • PD0-7
  • PC4-7
  • PB7-0
  • RST
  • GND

While I was at it, I also reinforced the USB connector’s solder joints, as suggested here on the makestuff blog.

Now I needed some way to check that the minimus survived my heavy handed soldering (I’m much more at home with a keyboard than a screwdriver, let along a soldering iron), so I returned to my LUFA keyboard test code.

I wrote a function that could be called from the CALLBACK_HID_Device_CreateHIDReport function to “insert” keypresses depending on which IO pin was active.  It only needed to return the first one it detected – this would enable me to test each pin and therefore verify my soldering.

I had to initialise all IO pins for input, and enabled the pull-up resistors.  This meant that for me to trigger an IO pin, I had to connect it to ground.

  DDRB = 0;
  PORTB = 0xff;
  DDRC = 0;
  PORTC = 0xff;
  DDRD = 0;
  PORTD = 0xff;

Setting DDRx = 0 sets all bits to input, then writing 0xff to PORTx enables the internal pull-up resistors.  After this, the value can be read (leaving a pin unconnected at Vcc reading 0 and connecting it to GND reading 1) from the PINx registers.

Then I had a function to return a series of key presses to say B, C or D followed by a numeral for 0 through 7.

I ended up with the following:

uint8_t port2num (uint8_t portval)
{
  if (portval & 1)
  {
    return HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS;
  }
  else if (portval & 2)
  {
    return HID_KEYBOARD_SC_1_AND_EXCLAMATION;
  }
  else if (portval & 4)
  {
    return HID_KEYBOARD_SC_2_AND_AT;
  }
  else if (portval & 8)
  {
    return HID_KEYBOARD_SC_3_AND_HASHMARK;
  }
  else if (portval & 16)
  {
    return HID_KEYBOARD_SC_4_AND_DOLLAR;
  }
  else if (portval & 32)
  {
    return HID_KEYBOARD_SC_5_AND_PERCENTAGE;
  }
  else if (portval & 64)
  {
    return HID_KEYBOARD_SC_6_AND_CARET;
  }
  else if (portval & 128)
  {
    return HID_KEYBOARD_SC_7_AND_AND_AMPERSAND;
  }
  else
  {
    return HID_KEYBOARD_SC_X;
  }
}

// Can only add up to 4 more keys
uint8_t checkMinimusIO (USB_KeyboardReport_Data_t*KeyboardReport, uint8_t UsedKeyCodes)
{
  uint8_t usedkeys = UsedKeyCodes;
  if (usedkeys > 3)
  {
    // no room left...
    return 0;
  }

  // Check ports B, C then D
  uint8_t portval;

  // want to reverse the sense of the data (as "unconnected" will be 1)
  portval = ~PINB;
  if (portval)
  {
    KeyboardReport->KeyCode[usedkeys++] = HID_KEYBOARD_SC_B;
    KeyboardReport->KeyCode[usedkeys++] = port2num (portval);
  }
  else
  {
    // Must filter as can only see pins 2, 4-7
    portval = ~(PINC) & (0b11110100);
    if (portval)
    {
      KeyboardReport->KeyCode[usedkeys++] = HID_KEYBOARD_SC_C;
      KeyboardReport->KeyCode[usedkeys++] = port2num (portval);
    }
    else
    {
      // mask out the buttons and LEDS
      portval = ~(PIND) & (0b00011110);
      if (portval)
      {
        KeyboardReport->KeyCode[usedkeys++] = HID_KEYBOARD_SC_D;
        KeyboardReport->KeyCode[usedkeys++] = port2num (portval);
      }
      else
      {
        KeyboardReport->KeyCode[usedkeys++] = HID_KEYBOARD_SC_O;
      }
    }
  }

  return usedkeys;
}

It was quite irritating to find that the numbers weren’t a simple HID_KEYBOARD_SC_0 … through SC_9, but that they all had _AND_WHATEVER on the end. I was hoping for a simple, predictable constant to cut-and-paste in, but no such luck.

Anyway this gave me the checkMinimusIO() function I could call from CALLBACK_HID_Device_CreateHIDReport() as follows:

  if (ButtonStatus_LCL & BUTTONS_BUTTON1)
  {
    UsedKeyCodes = checkMinimusIO (KeyboardReport, UsedKeyCodes);
  }

Note that I only called if it the button was pressed, which just made testing easier for me.

I did have a problem though  when I  first ran it – for some reason, PD0 was always floating no matter what I set it to which meant that whenever I tried to test a pin from port D, I always got D0.  In the end I had to mask that pin out in my code (hence the 0b00011110 value in the test for PIND – masks out pins 5,6,7 – the LEDs and switches and pin 0).

I don’t know if this was as a result of my soldering or if it always did that – I never checked the pins prior to me soldering the cable on.  If I force D0 to GND or Vcc, it all seems to work fine.  They appears to be something wrong with setting the internal pull-up resistor.  Everything else works fine though.  Odd.

It was somewhere around this time that I realised the major flaw in my thinking … I had wired up the pins so that they aligned neatly with the IDE cable in the sequence described above – so 8 adjacent cables were PD0-7 and another 8 were PB7-0 and so on … but by using the PCB connector to join two IDE cables together, the pins are now reversed in the second cable, so when it comes to wiring something up at the other end, the sequence will be something like PC2, VCC, PD1, PD0, PD3, PD2, etc.  And it was such a good idea!  Oh well.

I do however have at least 17 IO pins I can use for other things, all available on the end of an IDE 40 pin connector. I just need to remember which pin goes where.

Kevin.

Advertisements

1 Comment

  1. Minimus usb and 64 LEDs « Kevin's Blog said,

    […] a bit (it will probably be a while before I get my next chance to tinker).  Once I’d got my minimus wired up I wanted to flash some LEDs!  After all, that’s the whole point […]

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: