Bascom and AVR, Interfacing with USB.
Modern PC and certainly laptops may no longer have an RS-232 or parallel port interface. Instead, they have one or more
USB or Firewire interfaces. So, some means of making a connection between a USB port on the PC and your controller
project may become necessary. I will not go into Firewire interfaces, but if you want to use USB, you should visit
The USB organisation
and read at least the
USB FAQ and perhaps even the
USB-1.1
and
USB-2
standard documents, although the last two are quite a challenge!
As far as I know, there are no AVR's in the ATTiny and ATMEGA range with a USB interface. Atmel has
the
AT43USB
series, but they seems to be a bit 'different' and these IC's are not supported in Bascom anyway.
However, there are IC's that provide a USB interface to the PC-side and a serial or parallel interface
to the controller. I have used the
FTDI
FT232BM
and
FT245BM.
NOTE: the
FT232R
and
FT245R
are more modern versions.
The FT232BM is a sort of 'legacy' chip that provides a USB to RS-232 bridge. The FT245BM does
USB to eight-bit parallel conversion with four-line handshaking.
Note that the 'BM' series of these IC's is the follow-up to the first 'AM' version. There are
differences, if you have the 'AM' version, read the datasheets!
These IC's are particularly easy to use because FTDI provides a Virtual Com Port (VCP) driver.
This presents both the FT232BM and the FT245BM as a com port to the PC's operating system. Talking
to or listening to the FT's involves no more than using a simple terminal emulator program such
as Hyperterminal. FTDI also has a much more advanced D2XX driver, which allows you to interact in a more
direct (but also more complicated) manner with the FT232BM or FT245BM.
You can of course use the FTDI IC's in your projects, but I started with the
USB-1
and
USB-2
modules from
Voti.
The USB-1 module is a simple kit with the FT232BM and 93C46 EEPROM that is a complete USB-RS232 interface. The USB-2
module has the FT245BM and 93C46 EEPROM but is in essence no more than a 32-pin DIP with all FT245BM pins
connected to the DIP pins.
Using the USB-1 kit with the FT232BM.
First, download the latest FTDI VCP driver for your operating system and unzip the files to a
directory on your PC. Make sure you read the
driver installation instructions
.
Build the USB-1 module according to Voti's instructions:

The module has the DTR, DSR, RTS and CTS line for a full hardware RS-232 handshake mode but I used only
RxD and TxD. Note that the USB-1 module is powered by the USB bus. It can supply power other circuitry
by inserting the jumper. This puts app. 5V on the brown wire.

And this test program:
usb-1-rs232.bas
$regfile = "2313def.dat"
$crystal = 4000000
$baud = 9600
Config Pind.6 = Output
Dim Firstnumber As Integer
Dim Secondnumber As Integer
Dim Sum As Integer
Cls
Do
Set Portd.6
Firstnumber = 0
Secondnumber = 0
Input "Enter first number : " , Firstnumber
Cls
Lcd "frst:" ; Firstnumber ; " "
Input "Enter second number: " , Secondnumber
Lcd "scnd:" ; Secondnumber
Sum = Firstnumber + Secondnumber
Print "Sum: " ; Sum
Lowerline
Lcd "sum: " ; Sum
Reset Portd.6
Waitms 100
Loop
End
Default LCD connections are assumed.
The UART is set to a speed of 9600 baud.
The program asks for two numbers and returns the sum. The numbers and the sum are also displayed on the LCD.
Apply power to the breadboard and connect the USB cable to your PC and to the USB-1 module. You should hear
the familiar 'ding-dong' sound, indicating a USB connect. On the PC, the 'Found new hardware' wizard starts.
Follow the wizard, specify
the location where you unzipped the VCP driver files. Once the wizard completes, open the Device Manager
(Start\Settings\Control Panel\System\Hardware\Device Manager) and
check that your system now has an extra Com port in the Ports section.
Now start Hyperterminal, or any other terminal emulator program that you have, and open a connection to this
new com port and set the speed to 9600 baud. Reset the controller and the text "Enter first number: " should
appear in the terminal emulator window. Type in a number, after >enter<, the number appears on the LCD.
The controller asks for a second number. Enter a number, this number and the sum of the two numbers
appears on the LCD. The sum is also reported in the temrinal emulator window.
Note that the USB-1 module has a LED that flashes when there is activity on either the send or receive line.
Using the USB-2 kit with the FT245BM.
The USB-2 module has a FT245BM plus 93C46 EEPROM. The FT245BM has a 128 byte receive Fifo and 384 byte
transmit Fifo. Regard the Fifo's as being a small buffer memory with a First-in/First-out structure.
The USB-2 module kit is a small pcb arranged as a 32-pin DIP, making it easy to
use on a breadboard or on another pcb in a 32-pin IC socket. It requires some external components such as a crystal,
crystal capacitors, decoupling capacitors etcetera:

I tested the USB-2 module in combination with an ATMEGA32. This is a 40-pin DIP IC, having plenty of I/O, memory
etc. (read more on
using the larger AVR's if you need to)
Try this schematic:

(The 'thick' lines in the schematic is a way of drawing groups of lines as one. For example, the Reset, SCK, MISO
and MOSI line from the ATMega32 to the connector header is drawn as one line)
First, let us try to read data from the FT245BM Fifo with this program:
usb-read-fifo.bas
'The ATmega32 is used.
$regfile = "m32def.dat"
$crystal = 4000000
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5
Config Portd.2 = Input
Config Portd.6 = Output
Config Portb.6 = Output
Config Portc = Input
Rxf Alias Pind.2
Rd Alias Portd.6
Led Alias Portb.6
Dim Usbin As Byte
Set Rd
Cls
Lcd "reading..."
Lowerline
Set Led
Waitms 500
Reset Led
Waitms 500
Do
If Rxf = 0 Then
Reset Rd
Usbin = Pinc
Set Rd
'apparently hyperterm sends characters
'with upper bit random on or off...
Usbin = Usbin And &B01111111
Lcd Chr(usbin)
End If
Loop
End
Portc is configured as input to read the FT245BM eight-bit data.
The Rxf line is monitored, once is goes low there is data in the receive Fifo. The data is read by making Rd low.
This data is displayed on the LCD. When I send regular characters with Hyperterm it appears that sometimes the upper
bit is high. I do not know why this is so. I would think that the upper bit is only used the 'extended ascii character set.
Anyway, the upper bit is masked out by 'anding' Usbin with 0111.111.
If you tested the USB-1 module or a seperate schematic with the FT232BM first, you already have the VCP driver
installed on your PC. Otherwise you must do this after the first USB connect following the 'Found new hardware'
wizard directions.
Start Hyperterminal or another terminal emulator program and select the com port just added to your system. You
may have to select a baud-rate in Hyperterminal but it is ignored by the driver since it will communicate with the
FT245BM at the maximum possible speed. Type a character and observe that this character is shown on the LCD.
Monitor the RXF# line (pin 12) on the USB-2 module with an oscilloscope. Every time you enter a character this line goes low. After the
character is read, the receive Fifo is empty and the line goes high. The character is placed on the data bus when RD# goes
low.
Now, let us try sending characters from the FT245BM to the PC with this program:
usb-write-fifo.bas
'The ATmega32 is used.
$regfile = "m32def.dat"
$crystal = 4000000
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5
Config Portd.2 = Input
Config Portd.6 = Output
Config Portd.5 = Input
Config Portd.7 = Output
Config Portc = Output
Rxf Alias Pind.2
Rd Alias Portd.6
Txe Alias Pind.5
Wr Alias Portd.7
Led Alias Portb.6
Dim Usbin As Byte
Set Rd
Cls
Lcd "sending..."
Lowerline
Set Led
Waitms 500
Reset Led
Waitms 500
Do
If Txe = 0 Then
Reset Wr
Portc = Asc( "a")
Set Wr
End If
Loop
End
Portc is configured as output to send characters to the FT245BM data port.
In the Do Loop, the character "a" is sent to the FT245 data port by making Wr low, then high again. The character is not sent
until the Txe line is low, indicating there is room in the transmit Fifo.
Start Hyperterminal and select the com port just added to your system. Observe that the controller just sends a stream
of "a"'s to your PC. Monitor the TXE# line with an oscilloscope. If you click somewhere in the Hyperterminal window the
flow of "a"'s will stop and almost immediately thereafter, the TXE# line will go high indicating that the transmit
Fifo is full and the FT245BM cannot accept more characters. Click outside the Hyperterminal window and the stream of
"a"'s will resume and the TXE# line will go low again. On a slower PC, the TXE# line may go high regularly, indicating that
the PC cannot keep up with receiving characters and the FT245BM transmit Fifo is full.
As a last example, the following program uses an interrupt to receive a character from the receive Fifo and then
send it back to the transmit Fifo:
usb-readonint-write-fifo.bas
'The ATmega32 is used.
$regfile = "m32def.dat"
$crystal = 4000000
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5
Config Int0 = Falling
Config Portd.2 = Input
Config Portd.6 = Output
Config Portd.5 = Input
Config Portd.7 = Output
Config Portb.6 = Output
Rxf Alias Pind.2
Rd Alias Portd.6
Txe Alias Pind.5
Wr Alias Portd.7
Led Alias Portb.6
Dim Usbin As Byte
Dim Readusbfifoflag As Bit
Set Rd
Reset Wr
On Int0 Setreadusbfifoflag
Enable Interrupts
Enable Int0
Cls
Lcd "readonint/wrt..."
Lowerline
Set Led
Waitms 500
Reset Led
Waitms 500
Do
Set Led
Waitms 1000
Reset Led
Waitms 1000
If Readusbfifoflag = 1 Then
Reset Readusbfifoflag
Do
Config Portc = Input
Do
Loop Until Rxf = 0
Reset Rd
Usbin = Pinc
Set Rd
'apparently hyperterm sends characters
'with upper bit random on or off...
Usbin = Usbin And &B01111111
Lcd Chr(usbin)
Config Portc = Output
Do
Loop Until Txe = 0
Set Wr
Portc = Asc(usbin)
Reset Wr
Lcd Chr(usbin)
Loop Until Rxf = 1
End If
Loop
Setreadusbfifoflag:
Set Readusbfifoflag
Return
End
In the interrupt routine, only the flag Readusbfifoflag is set.
The main program is sometimes 'busy' (simulated by using long wait times when flashing the Led),
if the Readusbfifoflag is set, Portc is configured as input and one character is read from the
receive Fifo. It is displayed on the LCD, then Portc is configured as output and the character
is written back into the transmit Fifo and again displayed on the LCD.
I have not found out yet how to program the EEPROM on the USB-1 and USB-2 modules to take advantage of
custom VID, PID, serial number, power descriptor etc.
TOC