Blog Sturntech

Archive for October, 2010

Using a PIC18F14K50 for a USB 2.0 CDC Peripheral Device

with 4 comments

USB has become quite ubiquitous across the wide realm of electronic devices. Every modern computer, most cellphones, and even some automobiles have USB support for peripheral devices. The key to USB’s success as an interconnection technology stems from the strict electrical and timing requirements imposed by the USB Implementers Forum (link). This standard is enforced through certification procedures, and ensures all USB devices can “talk to each other” (although making use of what is “said” is left to the implementing engineer).

USB and micro-controllers are commonly merged via external module conversion solutions. Companies such as FTDI Chip (link) have developed IC chips that can accept a UART/SPI communication from a micro-controller and translate/re-package it to conform to the signalling and voltage level requirements of USB. This is fine for most projects as the UART/SPI modules are quite common on micro-controllers, and even the limited maximum throughput provided by these solutions is adequate for most designs.

However, to unleash the full power of USB, this proxy approach is not acceptable. As such, various micro-controller manufacturers have begun integrating USB modules into their chip-sets. These modules are designed to drive a Universal Serial Bus with the proper signaling voltages. However, the designer must still develop firmware to program onto the micro-controller, in order to implement a USB device. The PIC18F14K50 is one such micro-controller.

Overview

The PIC18F14K50 (link) is a FLASH micro-controller that includes a full speed USB 2.0 compliant interface. This micro-controller has several other serial interfaces, a couple motor driving PWM modules, and 9 available ADC channels, which is all well and good, but really I chose it because it is cheap ($2) and has USB 2.0 support.

This project will implement a CDC (Communication Device Class) Peripheral device. There are several CDC classes (seen here). This project will focus implementing a serial communication interface.

Design

This design targets a minimalistic approach. The PIC18F14K50 is the sole logic IC. All other components are support components for the PIC. A 12MHZ oscillator provides a clock to the PIC. A ICSP interface allows for in-circuit programming of the PIC. The USB connector is a USB-A plug (to allow for connecting to a USB Host). A 1.5k resistor connects D+ to +V to indicate Full-Speed USB operation. An additional resistor network is driven from VBUS to function as a Connection-Sense circuit (to detect when the device is plugged into a PC). The PIC multiplexs PGC/PGD with D+/D-, so isolation resistors were included to prevent damage to a connected programmer or USB Host. This project is able to be powered from a bench supply during programming, and is to be powered from the USB connection during operation.

The firmware for this project enumerates the device as a CDC serial device. A PC that enumerates this device will create a virtual COM port through which a serial-terminal/telnet program may connect to the device at 9600,0,0,8. My favorite serial-terminal program is the always-free PuTTY. The windows driver file for this device is based on the generic cdc_ntxp.inf driver provided with the CCS C compiler.

Schematic

The following is the schematic for this project. As you can see, implementing USB only requires 4 pins. This circuit is the same irregardless of what USB Class is being implemented.

Schematic for the PIC18F14K50 USB Project

Firmware

The firmware for this project was written in C and compiled using the CCS C compiler v4.106. The USB stack provided with the CCS C compiler was used to handle the transactional overhead required by the USB standard.

The PIC is configured to use a high-speed external oscillator. The oscillator I chose operates at 12MHZ. The internal x4 PLL is enabled, scaling the processing clock to a frequency of 48MHZ. The PIC is then configured to operate at this clock frequency (CPUDIV1 implies no post-PLL scaling occurs on the processing clock).

The firmware is straight-forward to extend. On power-up, the device holds in a function loop. This loop begins by calling a function (usb_task()) that handles any USB transactions that are queued up. The first transactional status flag checked is whether or not an enumeration transaction has occurred (usb_enumerated()). Following the indication of a successful enumeration, the firmware polls the transaction receive buffer for new content (usb_cdc_kbhit()). If the HOST device sent data, the newest byte is retrieved via a call to usb_cdc_getc(). This firmware compares the result to a static char (ASCII byte). If the comparison passes, a character stream is written to the USB transmit buffer, which is then processed and sent to the HOST.

This firmware will respond with ” Here’s an A \n” when an ASCII “A” is seen in the receive buffer, and with ” Now a B \n” when an ASCII “B” is seen.

The usb_task() function call includes a periodic state check of a connection sense pin. This pin is used to sense the voltage on the VBUS +5V provided by the USB Host through the USB connector. If a voltage is not sensed on this input, the PIC firmware will de-enumerate and return to a waiting-for-enumeration state.

Here is the firmware.  Remember, you’ll need the CCS C compiler v4.106 to use it verbatim. It is recommended that you peruse through the USB_CDC libraries, as there are several variables that may need to be configured to meet your particular application. I won’t include these libraries here as they are included with the CCS C Compiler (and you will need that compiler to use this firmware).
——————————-

// PIC18F14K50 CDC USB Device
// Sturntech 2010

#include "18F14K50.h"

#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOBROWNOUT,PLLEN,CPUDIV1,PUT,MCLR
#use delay(clock=48000000)

#define USB_CON_SENSE_PIN  PIN_C5

// Includes all USB code and interrupts
#include "usb_cdc.h"

void main(void)
{
   BYTE i;
   usb_init_cs();

   do
   {
      usb_task();
      if (usb_enumerated())
      {
         if (usb_cdc_kbhit())
         {
            i = toupper(usb_cdc_getc());

            if (i == 'A')
            {
               printf(usb_cdc_putc, " Here's an A \n");
            }

            if (i == 'B')
            {
               printf(usb_cdc_putc, " Now a B \n");
            }
         }
      }
   } while (TRUE);
}

——————————————

Build

There wasn’t a whole lot to this build. I used a breadboard for the IC and passive components. The USB-A plug was designed for PCB mounting, so I used a piece of protoboard as a mount. I knew I wasn’t going to program the circuit and connect the USB at the same time, so I neglected to place the isolation resistors. The first picture is a close-up of the device. The 2nd picture is the device talking over USB to the serial-terminal program on alaptop.

Close-up picture of the PIC18F14K50 USB Project

Picture of the PIC18F14K50 USB Project connected to a Laptop

Written by sturnfie

October 21st, 2010 at 4:54 pm

Posted in C,Design,EAGLE,PIC,USB

3-D Modeling of PCB designs from EAGLE

without comments

When working with fellow designers on electronic device projects, I have found providing a 3-D model of my PCB designs quite useful for describing the general placement of connectors and components on the PCB. A 3-D model communicates the little informational details that can trip up a project, such as: the polarization a given connector is expected to connect, where the mounting holes are expected to be drilled, and how much clearance mechanical devices might need to be physically accessible.

I’m fond of using EAGLE for my PCB designs, and typically use the Eagle3D expansion to generate 3D renderings of the designs. Eagle3D (which can be found here) is a ULP script for EAGLE. The resultant is a text file with a *.pov extension, written in a format to be read by POV-Ray (found here). POV-Ray is software package that generates ray-traced models from *.pov files.

Here’s an example of the PCB design and the resulting 3-D model:

Printed Circuit Board design for FTC-200: Open-Source

3-D Model from POV-Ray of the FTC-200 Open Source PCB board design

Here are two excellent reference articles describing the exact process and other extensions to this procedure:

http://www.juergentreml.de/archives/846

http://www.societyofrobots.com/electronics_Eagle3D_tutorial.shtml

Written by sturnfie

October 16th, 2010 at 7:45 pm

Posted in Design,EAGLE,Model,PCB

Solder-Mask and Cream-Mask DFM Warnings on EAGLE Designs

without comments

EAGLE CAD (manufacturer link) has a neat feature for automatically generating the solder and cream masks for SMD pads and vias when designing printed circuit boards. A solder-mask is used to protect the copper from oxidization, while acting as something of an isolation channel to prevent solder from bridging across closely spaced pins/pads. A cream-mask is used to define a region for automated application of solder paste.

In EAGLE, the default setting for the mask placement over a board feature is to generate a region that is 3% larger than the feature on each side. This is occasionally enough to trigger all sorts of warnings when running a PCB design through a Design For Manufacturing check, especially with designs that include high-density IC packages. Such packages simply don’t have the space between pins to allow for an additional 3% clearance while adhering to the PCB shop’s manufacturing limitations.

The auto mask generation feature in EAGLE can be configured in the Design Rule Check tool, under the Masks tab. Here’s a screen shot of the tab, along with the settings I use when sending designs to SunStone Circuits for manufacturing.

Screenshot of the Design Rule Check --> Masks tab in EAGLE

Written by sturnfie

October 13th, 2010 at 12:09 pm

Posted in Design,EAGLE,PCB,Tip