Dontronics - Closed
Additional
documentation by Brian Taylor: Latrobe University, Victoria, Australia
<Brian.Taylor
AT latrobe.edu.au>
Back
to product page
The
code that follows is written in PICBasicPro version 2.50.
Start:
How
to write data from a PIC to a USB memory stick, Compact Flash card
or
SD/MMC card.
The
FTDI Vinculum VDIP1 module appears to be a simple way of adding USB
memory
cards to PIC projects for massive storage. Via common USB
multimedia
card readers, Compact Flash, SD/MMC and other Memory Sticks
can
also be written to.
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
patchy
success with inconsistent operation until I flashed the latest
code
into the VDIP1 module. You simply load the appropriately named
file
to a clean memory stick and plug the stick into the VDIP1. The
bootloader
will take over and load the code. If you blow it, which I
did,
the VPROG application allows the code to be added via a PC COM port
and
a max232 level converter.
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 application.
VDIP1
pin 9 called RTS is an output from the VDIP1. It is monitored by
the
PIC and data from the PIC is only sent while RTS is LOW.
VDIP1
pin 10 called CTS is an input to the VDIP1 and 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. Put the button in - you are going to need it.
+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 2.
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 and
will
cost you hours trying to work out why. 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 likely lock up and
need
a manual reset or power cycle before it comes good. Any active file
on
the USB stick will be left open and appear empty when viewed on a PC.
e/
RTS going high apparently indicates there are only 32 character
positions
left in the 64 character buffer. RTS also goes high
immediately
after issuing some commands. Just which commands seems to
vary
with brand and size of card. For example, the WRF 26 <cr> in the
code
below causes pin 9 RTS to immediately 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 and the file will be readable but will be missing
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 upper case 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. This code appears to be universal and has worked reliably
with
6 different brands and sizes of USB stick. It has also been tested
with
Compact Flash and SD/MMC cards plugged into a USB multicard reader.
The
VDIP1 does NOT work with an external hard drive as the storage
medium.
'*************************************************
***************
'*
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 'an Action Flag to halt the code after each pass.
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 'show action flag
pause
1000
if
a = 0 then
write
0,1
'overwrite action flag so
program
runs at next reset
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 characters.
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
Back
to product page
|