PDA

View Full Version : USB-FTDI[UM232R] with PIC16f877a



bjox
- 23rd February 2008, 16:09
Dear all,

I am new to the PIC uC and have just written a code for the USART function. I am using UM232r [USB module] to communicate with PC.


{ USB module:http://www.ftdichip.com/Documents/DataSheets/Modules/DS_UM232R.pdf

I am using page-14 settings of the USB}

Using serial cable connection, the same code works absolutely fine. As soon as I am using the USB module, it doesn't seem to work at all. That means my code is alright and there might be some error in the USB settings. :(

The TX section of the code [when using without the RX part] is working fine with the USB though but it's not working for the RX section. In my UM232R USB circuit, I have connected the handshaking pins [RTS# and CTS#] to each other and not to the PIC. It works for the TX part. I am not sure whether this is causing the problem when I am receiving the data.

I will be really grateful if you could have a look it.

Many many thanks.

bjox

Ps: I am using TERMINAL on PC for this task.

BrianT
- 23rd February 2008, 23:40
Hello Bjox,

I have used a similar FDTI chip, the Vinculum VDIP1.

With the Vinculum chip you CANNOT tie RTS to CTS. Yes, that is shown in the Circuit Cellar article, but I doubt it ever worked as described.

I found it essential to actively handle RTS and CTS and to check their status before evey character.

The code follows but the thread is worth a look for other peoples comments.

HTH
Brian


How to drive the Vinculum VDIP1 in UART mode.

The FTDI Vinculum VDIP1 module appears to be a simple way of adding USB memory cards and other devices to PIC projects. Their documentation is appalling and there are several traps to waste many hours with. There are also huge timing differences between brands and sizes of memory sticks that need to be catered for.

WARNING - Regardless of when and where you bought your VDIP1 modules, get the latest code first (ver 3.61 as at 11 December 2007). I had ZERO success until I flashed the latest code into the VDIP1 module. I first tried to flash the code in using a slow Rundisk 2 GB card. That killed the bootloader in the VDIP1 and rendered the module useless. I had success with a faster Verbatim 512 MB card and was able to reflash the VDIP1 with version 3.61 code.

Schematic details.
Data TO the VDIP1 destined for the USB stick is sent into pin 8 called RXD.
Data FROM the VDIP1 is ignored in this example.
VDIP1 pin 9 called RTS is monitored by the PIC. Data is only sent while RTS is LOW.
VDIP1 pin 10 called CTS is pulled low by the PIC and left low throughout.
The VDIP1 RESET line, pin 22, needs to float normally but every now and then a manual reset is required. This could either be by code or an external pushbutton.
+5 volts is applied to VDIP1 pin 1. VDIP pins 7 and 18 are tied to ground. All other pins are floating.

Setup for simplest UART mode.
a/ The interface defaults to 9600 bps, 8N1 TTL where steady mark/idle is +v and a space bit is zero volts. Use SEROUT 'driven true' mode.

b/ Set the jumpers to be both 1-2 or both 2-3 for UART mode.

c/ You can permanently ground the VDIP1 pin 10 called CTS. This pin must be low before the VDIP1 will work.

d/ You MUST monitor the VDIP1 pin 9, called RTS. Do NOT tie RTS to CTS as shown in the Circuit Cellar article - that only sometimes works. RTS is low when ready to accept data and when RTS goes high you must stop sending data to the VDIP1. If you continue to send data, the VDIP1 will frequently lock up and need a manual reset or power cycling before it comes good. Any active file on the USB stick will be left open and appear empty when viewed with a PC.

e/ RTS going high apparently indicates there are only 32 character positions left in the buffer. RTS ALSO goes high immediately after issuing some commands. Which commands seems to vary with brand of card. The WRF 26 in my code below causes pin 9 RTS to go high with a Rundisk 2 GB memory stick but RTS does NOT go high with a Verbatim 512 MB stick.

f/ Every command must be terminated with a carriage return. No line feed is necessary.

g/ You must count your characters very carefully. The WRF nn command tells the VDIP1 that nn characters are to be written to the memory stick. If you send more than nn the VDIP1 module will harmlessly truncate the data but the file will be readable minus those overflow characters. If you don't send enough characters however, the VDIP1 will hang waiting for the balance. Subsequent commands to close the file will be lost and the file will remain open and be unreadable or empty.

h/ The following code creates a new directory called TESTFILE (8 character limit) and creates a file in that directory called Test1.txt. It then opens Test1.txt, writes a short header block and closes the file. It then opens the file a second time and appends 10,330 bytes to Test1.txt and closes the file. Finally it opens it, appends a trailer and closes Test1.txt. Only 8.3 format file and directory names are allowed. All file names are changed to capitals by the VDIP1.

i/ I have put a flow control test after every command. This is probably overkill but I don't know what are the fast and what are the slow commands. These appear to vary between brands and memory sizes so I have left them in.

'************************************************* ***************
'* Name : Vinculum01.pbp *
'* Author : Brian Taylor *
'* Notice : Copyright (c) 2007 Brian Taylor *
'* : All Rights Reserved *
'* Date : 4/12/2007 *
'* Version : 1.0 *
'* Notes : USB memory stick interface for PIC 18F4620 *
'* : *
'************************************************* ***************

data @0, 0

VinTxD var portb.0 'data from Vinculum VDIP1 pin 6
VinRxD var portb.1 'data TO VDIP1 pin 8 for writing to USB stick
FlowIn var portb.2 'Flow control FROM VDIP1 pin 9
FlowOut var portb.3 'Flow control TO VDIP1 pin 10
RstVDIP1 var portb.4 'active LOW reset line to VDIP1
LED var portb.5
SpareB6 var portb.6
SpareB7 var portb.7
TRISB = %11001101 'bits 2 & 3 temporarily inputs

TxD var portc.6 'MCS+ bootloader
RxD var portc.7

A var byte
B var byte
C var byte
W var word

Start:
define osc 4
define loader_used 1

Define LCD_DREG PORTD
Define LCD_DBIT 0
Define LCD_RSREG PORTD
Define LCD_RSBIT 5
Define LCD_EREG PORTD
Define LCD_EBIT 4


high rstvdip1 'active LOW so not reset.
low flowout 'pull VDIP1 pin 10 CTS low
input flowin 'from VDIP1 pin 9 RTS

Loop:
read 0,a
lcdout $FE, $01, "A = ", #a
pause 1000
if a = 0 then
write 0,1
lcdout $FE, $01, "Press Reset to", $FE, $C0, "start logging."
end
endif

StartWriteBlock:
high vinrxd 'condition serout pin to mark state
pause 5
serout vinrxd , 2, ["ECS", 13] 'Select Extended Command Set
high vinrxd
Pauseus 10
serout vinrxd, 2, ["IPA", 13] 'Input in ASCII
high vinrxd
pause 10
serout vinrxd , 2, ["MKD TestFile", 13] 'Make Directory called TestFile
Pauseus 10
Wait11:
if flowin = 1 then wait11
lcdout $FE, $01, "Make directory", $FE, $C0, "TestFile"
serout vinrxd, 2, ["CD TestFile", 13] 'Change Directory
Pauseus 10
Wait12:
if flowin = 1 then wait12
WriteHeader:
high vinrxd 'condition serial data line state
pause 5
serout vinrxd , 2, ["OPW Test1.txt", 13] 'Open file test1.txt for Writing
Pauseus 10
Wait13:if flowin = 1 then wait13
serout vinrxd, 2, ["WRF 26",13] 'Write 26 characters to the open file
Pauseus 10
Wait1:
if flowin = 1 then wait1
serout vinrxd, 2, [13, 10, "Start 10,330 byte test "] 'these are the 26.
Pauseus 100
Wait2:
if flowin = 1 then wait2
serout vinrxd, 2, ["CLF Test1.txt", 13]
Pauseus 100
Wait3:
if flowin = 1 then wait3
WriteDataBlock:
high vinrxd
pause 5
serout vinrxd , 2, ["OPW Test1.txt", 13]
high vinrxd
Pauseus 10
wait4:
if flowin = 1 then wait4
serout vinrxd, 2, ["WRF 10330",13]
lcdout $FE, $01, "Writing data", $FE, $C0, "10,330 characters"
Pauseus 10
Wait14:
if flowin = 1 then wait14
for c = 0 to 9
serout vinrxd, 2, [13, 10, #c]
Pauseus 10
Wait15:
if flowin = 1 then wait15
for a = 0 to 9
serout vinrxd, 2, [13, 10, #a]
Pauseus 10
Wait5:
if flowin = 1 then wait5
for w = 0 to 99
serout vinrxd, 2, [#c]
Pauseus 10
Wait6:
if flowin = 1 then wait6
next w
next a
next c
Pauseus 10
serout vinrxd, 2, ["CLF Test1.txt", 13]
Pauseus 10
Wait7:
if flowin = 1 then wait7
CloseDataBlock:
lcdout $FE, $01, "Closing file", $FE, $C0, "Test1.txt"
serout vinrxd , 2, ["OPW Test1.txt", 13] 'Open file for Writing
Pauseus 10
Wait8:
if flowin = 1 then wait8
serout vinrxd, 2, ["WRF 24",13]
Pauseus 10
Wait9:
if flowin = 1 then wait9
serout vinrxd, 2, [13, 10, "End 10,330 byte test",13,10]
Pauseus 10
Wait10:
if flowin = 1 then wait10
serout vinrxd, 2, ["CLF Test1.txt", 13]
Wait16:
if flowin = 1 then wait16
write 0, 0
pause 1000
goto loop
end


Cheers
BrianT