new USB v1.4 module (with SF HID bootloader)
Moderators: David Barker, Jerry Messina
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
new USB v1.4 module (with SF HID bootloader)
I just posted my updated version of the SF USB library over on Digital-DIY (http://digital-diy.com/Download-documen ... brary.html)
Features include:
- support for all current 30 18F USB devices, including:
18F2550, 18F4550, 18F2553, 18F4553, 18F2455, 18F4455, 18F2458, 18F4458, 18F2450, 18F4450,
18F14K50, 18F13K50, 18F67J50, 18F87J50, 18F66J50, 18F86J50, 18F66J55, 18F86J55, 18F65J50, 18F85J50,
18F24J50, 18F44J50, 18F25J50, 18F45J50, 18F26J50, 18F46J50, 18F26J53, 18F46J53, 18F27J53, 18F47J53
- new USB Extended Ram functionality
- ability to switch between interrupt and polled mode without source code changes
- ability to use HID ReadReport() and WriteReport functions with or without Extended Ram
- device-specific code isolated to two files: usbmem.bas and usbsfr.bas
- various bug fixes to USBSystem.bas
- a SF port of the Microchip HID bootloader with support for all chips (SF source provided)
- an updated version of the Microchip HidBootLoader.exe application program with the ability to
allow/prevent changes to the EEPROM and UserID areas, as well as the Config area. App also
allows changing VID and PID without recompiling source. (source included, VS C++ 2010 Express)
The code has been tested with 18F2553, 18F2450, 18F46J50, and 18F14K50 devices, in interrupt and polled mode for both HID and CDC functions, with and without Extended RAM, and with and without the included SF HIDbootloader18F.
Some memory layouts (such as the 47J53) remain untested, so please let me know if any issues pop up.
You may notice a lot of source code changes, such as always using '()' for subs and function calls, removing block comments, etc. Much of this is purely a personal formatting preference and was done to help me understand the modules. Hopefully, it won't be a big deal.
As always, comments, questions, and criticisms welcome.
Features include:
- support for all current 30 18F USB devices, including:
18F2550, 18F4550, 18F2553, 18F4553, 18F2455, 18F4455, 18F2458, 18F4458, 18F2450, 18F4450,
18F14K50, 18F13K50, 18F67J50, 18F87J50, 18F66J50, 18F86J50, 18F66J55, 18F86J55, 18F65J50, 18F85J50,
18F24J50, 18F44J50, 18F25J50, 18F45J50, 18F26J50, 18F46J50, 18F26J53, 18F46J53, 18F27J53, 18F47J53
- new USB Extended Ram functionality
- ability to switch between interrupt and polled mode without source code changes
- ability to use HID ReadReport() and WriteReport functions with or without Extended Ram
- device-specific code isolated to two files: usbmem.bas and usbsfr.bas
- various bug fixes to USBSystem.bas
- a SF port of the Microchip HID bootloader with support for all chips (SF source provided)
- an updated version of the Microchip HidBootLoader.exe application program with the ability to
allow/prevent changes to the EEPROM and UserID areas, as well as the Config area. App also
allows changing VID and PID without recompiling source. (source included, VS C++ 2010 Express)
The code has been tested with 18F2553, 18F2450, 18F46J50, and 18F14K50 devices, in interrupt and polled mode for both HID and CDC functions, with and without Extended RAM, and with and without the included SF HIDbootloader18F.
Some memory layouts (such as the 47J53) remain untested, so please let me know if any issues pop up.
You may notice a lot of source code changes, such as always using '()' for subs and function calls, removing block comments, etc. Much of this is purely a personal formatting preference and was done to help me understand the modules. Hopefully, it won't be a big deal.
As always, comments, questions, and criticisms welcome.
Jerry,
Great work. I am trying this out with 18F14K50.
1. Everthing compiles great. That's a good start.
2. I cannot run the "new" pc software on WIN7 64-bit.
- "orig" bootloader pc software starts and recognizes device. Seems to program as well. But the cdc code doesn't seem to run.
- I loaded the main_cdc.hex with pickit2 and it worked right away.
- trouble is no cdc drivers for WIN7 (64-bit). Do you know where I can find these?
edit---I found and installed them
3. I am hoping to try all this with 18F2550 as well.
Great work. I am trying this out with 18F14K50.
1. Everthing compiles great. That's a good start.
2. I cannot run the "new" pc software on WIN7 64-bit.
- "orig" bootloader pc software starts and recognizes device. Seems to program as well. But the cdc code doesn't seem to run.
- I loaded the main_cdc.hex with pickit2 and it worked right away.
- trouble is no cdc drivers for WIN7 (64-bit). Do you know where I can find these?
edit---I found and installed them
3. I am hoping to try all this with 18F2550 as well.
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
I updated the library to v1.4.1 to fix the register initialization issue identified by Graham and RangerBob in the thread http://www.sfcompiler.co.uk/forum/viewtopic.php?t=1470
Normally, I wouldn't post an update so soon, but since this one can be a show stopper if you're using a bootloader, I figured it's better to go ahead.
The main fix involves changes to the system.bas file, with some minor changes to the main app .bas files and the bootloader to ensure it gets used.
Since the additions to the startup code in system.bas aren't required if you're not using a bootloader, I also added a new #option to disable them if you don't need it (but they're enabled by default)
Normally, I wouldn't post an update so soon, but since this one can be a show stopper if you're using a bootloader, I figured it's better to go ahead.
The main fix involves changes to the system.bas file, with some minor changes to the main app .bas files and the bootloader to ensure it gets used.
Since the additions to the startup code in system.bas aren't required if you're not using a bootloader, I also added a new #option to disable them if you don't need it (but they're enabled by default)
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
It seems I violated one of the cardinal rules of software development... don't make any changes after testing (no matter how simple), and found out once again why that rule exists.
It seems I added a compile-time check to verify some '#define' settings in the USBCDC file after I had done most of the preliminary testing, and in the process managed to screw up the CDC buffer allocation. While the bug is present for all devices, it only really shows up when using ones with limited USB ram, like the 14K50 and 2450. The symptoms are that the device would enumerate, but no data would be transfered. Since I do most of my development using a 2553, I never noticed this.
While I've updated the entire download package over on Digital-Diy to v1.4.2, the only effected file is USBCDC.bas, so I've included a copy of the updated version here
USBCDC.bas (v1.4.2)
Hopefully, I haven't become a member of the "update-of-the-day" club, but since this one's pretty bad it's an important fix.
Thanks to all for keeping me honest (esp. Keith for pointing out this one), and sorry.
It seems I added a compile-time check to verify some '#define' settings in the USBCDC file after I had done most of the preliminary testing, and in the process managed to screw up the CDC buffer allocation. While the bug is present for all devices, it only really shows up when using ones with limited USB ram, like the 14K50 and 2450. The symptoms are that the device would enumerate, but no data would be transfered. Since I do most of my development using a 2553, I never noticed this.
While I've updated the entire download package over on Digital-Diy to v1.4.2, the only effected file is USBCDC.bas, so I've included a copy of the updated version here
USBCDC.bas (v1.4.2)
Code: Select all
//
//***************************************************************************
// Name : USBCDC.bas *
// Author : David John Barker *
// Notice : Copyright (c) 2007 Mecanique *
// : All Rights Reserved *
// Date : 12/01/2007 *
// Version : 1.4.2 *
// : **BUG FIX 1.4-1: correct compile-time check of _CDC_USED_RAM *
// : inadvertantly changed ram buffer locations (check was added *
// : AFTER initial testing), causing issues with limited ram *
// : devices (ie 14K50). add _CDC_TOTAL_USED_RAM instead *
// : rename CDC_VAR_ADDRESS to CDC_BUF_ADDRESS for clarity *
// Version : 1.4 updated for new stack version *
// : 1.1 ISR now uses USB interrupts *
// : Renamed 'Connected' to 'Attached' *
// : 1.0 Release *
// Notes : This is a Virtual COM Port (VCP) implementation using the *
// : USB CDC class *
//***************************************************************************
//
module CDC
//
// ---------------------------- ---------------------------- ----------------------------
// 18F2455, 18F2550, 18F4455, 18F2455, 18F2550, 18F4455, 18F2450, 18F4450, 13K50, 14K50
// 18F4550 18F4550
// ---------------------------- ---------------------------- ----------------------------
// (A) Dual Port RAM Size 1024 ($400) (A) USB_RAM_SIZE 512 ($200) 256 ($100)
// ---------------------------- ---------------------------- ----------------------------
// CDC EP0..EP3 32 CDC EP0..EP3 32 32
// USB SetupPacket 8 USB SetupPacket 8 8
// USB ControlTransferData 8 USB ControlTransferData 8 8
// CDC Notice 8 CDC Notice 8 8
// CDC DataRX 64 CDC DataRX 64 32
// CDC DataTX 64 CDC DataTX 64 64
// ---------------------------- ---------------------------- ----------------------------
// (B) SUB TOTAL 184 ($B8) (B) SUB TOTAL 184 ($B8) 152 ($98)
// (C) BYTES FREE (A - B) 840 ($348) (C) BYTES FREE (A - B) 328 ($148) 104 ($68)
// ============================ ============================ ============================
// CDC TXBuffer (x2) 32 CDC TXBuffer (x2) 32 32
// CDC RXBuffer 72 CDC RXBuffer 72 72
// ---------------------------- ---------------------------- ----------------------------
// (D) SUB TOTAL 104 (D) SUB TOTAL 104 104
// BYTES FREE (C - D) 736 ($2E0) BYTES FREE (C - D) 224 ($E0) 0
// ============================ ============================ ============================
// CDC Module RAM start CDC Module RAM start
// ($400 + B) 1208 ($4B8) (USB_RAM_BASE + B) 1208 ($4B8) 1176 ($498)
// ============================ ============================ ============================
//
// import the USB memory layout. we need the USB_RAM_SIZE...
include "usbmem.bas"
// see above table for requirements...
// SUB TOTAL(B) comes from:
// CDC_USED_RAM = (EP_SIZE * (MAX_EP_NUMBER+1) * 2) + ' = 4 * (3+1) * 2 = 32
// sizeof(structure CTRL_TRF_SETUP) + ' = 8
// sizeof(structure CTRL_TRF_DATA) + ' = 8
// CDC_INT_EP_SIZE + ' = 8 (aka CDCNotice)
// CDC_BULK_OUT_EP_SIZE + ' = 64 or 32 (CDC_RX_SIZE)
// CDC_BULK_IN_EP_SIZE ' = 64 (CDC_TX_SIZE)
//
// There's no way for us to compute this, as all the required definitions are in usbdefs.bas,
// and we need to set some #options before we include it. Without the DataRX size, it totals
// 120 bytes assuming 4 total EndPoints and a 64-byte CDC_TX_SIZE (which is the max packet size)
// #option CDC_RX_SIZE sets the DataRX size, which is the max amount of data in a single CDC_BULK_OUT
// (receive) message, and will be defined here based on the amount of USB ram we have available.
// If ANY of these numbers change, then this data will need to be recomputed (which isn't likely
// except for possibly the number of EP's)
// The CDC TXBuffer and RXBuffer are allocated here, so we can account for them.
//
#variable _CDC_USED_RAM = 120
#if (USB_RAM_SIZE = 256) // limited ram available...
#define _RX_SIZE = 32 // use a smaller CDC_RX_SIZE
#else // we should have enough ram...
#define _RX_SIZE = 64 // use a standard CDC_BULK_OUT size
#endif
// SUB TOTAL (B): this is the starting offset of the CDC private TX and RX buffers
#variable _CDC_USED_RAM = _CDC_USED_RAM + _RX_SIZE
// these two together make up SUB TOTAL (D)
// (see comments below for setting these two sizes)
#define _CDC_TXB_SIZE = 16 // x2
#define _CDC_RXB_SIZE = 72
// sum of all the requirements above (**BUG FIX 1.4-1: correct check... was _CDC_USED_RAM)
#variable _CDC_TOTAL_USED_RAM = _CDC_USED_RAM + (_CDC_TXB_SIZE * 2) + _CDC_RXB_SIZE
// sanity check the amount of required ram
#if (_CDC_TOTAL_USED_RAM > USB_RAM_SIZE)
#error "USB_RAM_SIZE error"
#endif
// import modules...
#option CDC_RX_SIZE = _RX_SIZE
#option USB_USE_CDC = true
include USB_DESCRIPTOR
include "usbdefs.bas"
include "usbsfr.bas"
include "usbsystem.bas"
include "system.bas"
// this option controls if Initialize() is called automatically or not
#option USB_AUTO_INITIALIZE = true
// on control event type
type
TOnControl = event()
// ISR priority
const
PRIORITY_LEVEL = USB_SERVICE_PRIORITY
// buffer sizes and locations
const
TX_BUFFER_SIZE = _CDC_TXB_SIZE, // higher value may cause RS232 apps problems, leave!
RX_BUFFER_SIZE = _CDC_RXB_SIZE, // must always be larger than sizeof(CDCDataRX)
CDC_BUF_ADDRESS = USB_RAM_BASE + _CDC_USED_RAM // private TX and RX buffer address
#if (_CDC_TXB_SIZE > 16)
#warning "_CDC_TXB_SIZE may cause RS232 application problems"
#endif
#if (_CDC_RXB_SIZE < CDC_BULK_OUT_EP_SIZE)
#error "invalid _CDC_RXB_SIZE"
#endif
// Module RX and TX are mapped onto USB RAM space - two TX buffers are used -
// one is for this module to write to, the other is output by the USB module.
// By swapping them over for transmission, the module can continue to buffer
// data while the USB module outputs the last buffer
const
TX_BUFFERA_ADDRESS = CDC_BUF_ADDRESS,
TX_BUFFERB_ADDRESS = TX_BUFFERA_ADDRESS + TX_BUFFER_SIZE,
RX_BUFFER_ADDRESS = TX_BUFFERB_ADDRESS + TX_BUFFER_SIZE
dim
FTXBufferA(TX_BUFFER_SIZE) as byte absolute TX_BUFFERA_ADDRESS,
FTXBufferB(TX_BUFFER_SIZE) as byte absolute TX_BUFFERB_ADDRESS,
FRXBuffer(RX_BUFFER_SIZE) as byte absolute RX_BUFFER_ADDRESS
// private variables and aliases
dim
FTXPos as byte, // TX buffer current position
FTXBufferAPtr as word, // address of first TX buffer
FTXBufferBPtr as word, // address of second TX buffer
FRXIndexIn as byte, // RX pointer (received)
FRXIndexOut as byte, // RX pointer (read)
FRXOverrun as boolean // overrun flag
// public variables...
public dim
OnControl as TOnControl, // control event handler
DTR as USBSystem.CDCControlSignal.DTR, // DTR
RTS as USBSystem.CDCControlSignal.RTS, // RTS
Overrun as FRXOverrun, // overrun flag
ReadTerminator as char // string read line terminator
// NOTE: (from original source)
// It appears that the default windows driver (usbser.sys) does not
// implement a RTS correctly from host to device - this is based on my own
// observations and sources from the internet. However, I have left the above
// RTS mapped to the correct bit, should another driver become available...
//
// EXTENDED_RAM support (see usbmem.bas)
// Public buffers - these are just mapped onto USB ExtendedRAM space, thus saving
// program RAM. You can use a large 512 byte buffer, or two separate 256
// RX and TX buffers. Using WriteArray() with the large 512 byte buffer
// can give tranfer speeds of approximately 420KBytes/second (3.4 Mbits/second)
// although this figure will be affected by factors such as bus loading. Note
// that these buffers are only available for USB devices that have extended ram
// defined.
// Currently, the CDC module does not use these buffers, so they are not required
// for operation. They are declared here for use by the application code (if desired)
//
#if (USB_EXTENDED_RAM_SIZE > 0)
public const
EXT_RAM_ADDRESS = USB_EXTENDED_RAM_BASE,
EXT_TX_BUFFER_SIZE = USB_EXTENDED_RAM_SIZE/2,
EXT_RX_BUFFER_SIZE = USB_EXTENDED_RAM_SIZE - EXT_TX_BUFFER_SIZE
public dim
Buffer(USB_EXTENDED_RAM_SIZE) as byte absolute EXT_RAM_ADDRESS,
TXBuffer(EXT_TX_BUFFER_SIZE) as byte absolute EXT_RAM_ADDRESS,
RXBuffer(EXT_RX_BUFFER_SIZE) as byte absolute EXT_RAM_ADDRESS + EXT_TX_BUFFER_SIZE
#endif // USB_EXTENDED_RAM_SIZE
public dim
Attached as USBSystem.Attached
//
//**************************************************************************
//Name : ServiceTX (PRIVATE) *
//Purpose : Service the transmission buffer *
//**************************************************************************
//
sub ServiceTX()
dim BufferSwap as word
if (mUSBUSARTIsTxTrfReady() and (FTXPos > 0)) then
mUSBUSARTTxRam(FTXBufferAPtr, FTXPos)
BufferSwap = FTXBufferAPtr
FTXBufferAPtr = FTXBufferBPtr
FTXBufferBPtr = BufferSwap
FTXPos = 0
endif
end sub
//
//**************************************************************************
//Name : ServiceRX (PRIVATE) *
//Purpose : Service the RX buffer *
//**************************************************************************
//
sub ServiceRX()
dim BytesRead as byte
if (mCDCUsartRxIsBusy = 0) then
BytesRead = CDCRXBytesAvailable
FSR0 = addressof(FRXBuffer)
inc(FSR0, FRXIndexIn)
FSR1 = addressof(CDCDataRX)
repeat
POSTINC0 = POSTINC1
inc(FRXIndexIn)
if ((FRXIndexIn > bound(FRXBuffer)) or (FRXIndexIn = 0)) then
FRXIndexIn = 0
FSR0 = addressof(FRXBuffer)
endif
dec(BytesRead)
if (not FRXOverrun) then
FRXOverrun = (FRXIndexIn = FRXIndexOut) and (BytesRead > 0)
endif
until (BytesRead = 0)
CDCRXPrepareForNext()
endif
end sub
//
//**************************************************************************
//Name : Service *
//Purpose : Service a USB connection (private) *
//**************************************************************************
//
sub _service()
dim ControlSignal as byte
ControlSignal = USBSystem.CDCControlSignal._byte
USBCheckBusStatus()
USBDriverService()
CDCTxService()
ServiceTX()
ServiceRX()
ClrWDT()
if (ControlSignal <> USBSystem.CDCControlSignal._byte) then
OnControl()
endif
end sub
//
//**************************************************************************
//Name : USBService (was private NoISRService) *
//Name : Service *
//Purpose : Service a USB connection. You need to call this routine *
// : periodically from your main program to maintain a connection *
// : (every 1 ms or so). You DO NOT need to call this routine if *
// : you have enabled the USB interrupt handler, since the routine *
// : will be optimized away *
//**************************************************************************
//
public inline sub USBService()
#if (USB_SERVICE = false) // only call _service if polled mode
_service()
#endif
end sub
//
//**************************************************************************
//Name : USB_intr_handler (PRIVATE) *
//Purpose : USB isr handler *
//**************************************************************************
// this routine takes ~50us at 48MHz, but since in most cases interrupts are
// generated back to back the effective time is ~100us to 150us.
// they occur at 1ms intervals, but that is host dependant
//
#if (USB_SERVICE)
interrupt USB_intr_handler(PRIORITY_LEVEL)
high(porta.0)
// check for USB intr request
if ((PIR2Bits.USBIF = 1) and (PIE2Bits.USBIE = 1)) then
PIR2Bits.USBIF = 0
save(0, FSR0, FSR1, _service)
_service()
restore
endif
low(porta.0)
end interrupt
#endif
//
//**************************************************************************
//Name : EnableISR *
//Purpose : Enable the ISR to service USB connection *
//**************************************************************************
//
public inline sub EnableISR()
#if (USB_SERVICE)
PIE2Bits.USBIE = 1
#endif
end sub
//
//**************************************************************************
//Name : DisableISR *
//Purpose : Disable the ISR that services the USB connection *
//**************************************************************************
//
public inline sub DisableISR()
#if (USB_SERVICE)
PIE2Bits.USBIE = 0
#endif
end sub
//
//**************************************************************************
//Name : WaitForTX (PRIVATE) *
//Purpose : Wait for next USB TX slot *
//**************************************************************************
//
inline sub WaitForTX()
while (not mUSBUSARTIsTxTrfReady() and Attached)
_service()
end while
end sub
//
//**************************************************************************
//Name : Initialize *
//Purpose : Initialize the USB module *
//**************************************************************************
//
// initialize module variables
inline sub InitializeCDC()
FTXPos = 0
FTXBufferAPtr = addressof(FTXBufferA)
FTXBufferBPtr = addressof(FTXBufferB)
FRXIndexIn = 0
FRXIndexOut = 0
FRXOverrun = false
ReadTerminator = null
OnControl = 0
end sub
public sub Initialize()
// setup PLL (see usbsfr.bas)
SetUSBClock()
mInitializeUSBDriver()
#if (USB_SERVICE)
#if (USB_SERVICE_PRIORITY = ipLow)
IPR2Bits.USBIP = 0
#else
IPR2Bits.USBIP = 1
#endif
PIR2Bits.USBIF = 0 // clear USBIF
PIE2Bits.USBIE = 1 // enable USB interrupt
_service()
UIE = UIE_ENABLE_ALL // unmask all USB interrupts
UEIE = UEIE_ENABLE_ALL // unmask all USB error interrupts
enable(USB_intr_handler)
#endif // USB_SERVICE
end sub
//
//**************************************************************************
//Name : ClearOverrun *
//Purpose : Clear RX overrun flag *
//**************************************************************************
//
public sub ClearOverrun()
DisableISR()
FRXOverrun = false
EnableISR()
end sub
//
//**************************************************************************
//Name : DataAvailable *
//Purpose : Returns true if RX data is available, false otherwise *
//**************************************************************************
//
public function DataAvailable() as boolean
DisableISR()
result = (FRXIndexIn <> FRXIndexOut)
EnableISR()
end function
//
//**************************************************************************
//Name : ReadByte *
//Purpose : Read a single byte - this is a blocking call *
//**************************************************************************
//
public function ReadByte() as byte
DisableISR()
while ((FRXIndexIn = FRXIndexOut) and (not FRXOverrun) and Attached)
_service()
end while
result = FRXBuffer(FRXIndexOut)
inc(FRXIndexOut)
if (FRXIndexOut > bound(FRXBuffer)) then
FRXIndexOut = 0
endif
_service()
EnableISR()
end function
//
//**************************************************************************
//Name : WriteByte *
//Purpose : Write a byte to the TX buffer - will block if the TX buffer *
// : is full until the next transmission slot is available *
//**************************************************************************
//
public sub WriteByte(pValue as byte)
DisableISR()
while ((FTXPos = (TX_BUFFER_SIZE - 1)) and Attached)
_service()
end while
FSR0 = FTXBufferAPtr
inc(FSR0, FTXPos)
INDF0 = pValue
inc(FTXPos)
_service()
EnableISR()
end sub
//
//**************************************************************************
//Name : ReadArray *
//Purpose : Read an array of bytes - pCount is an optional number of bytes *
// : to read. If pCount is not given, the size of the array is used *
//**************************************************************************
//
public sub ReadArray(byref pArray() as byte, pCount as word = 0)
if (pCount = 0) then
pCount = bound(pArray)
inc(pCount)
endif
DisableISR()
FSR2 = addressof(pArray)
while ((pCount > 0) and Attached)
if ((FRXIndexIn = FRXIndexOut) and (not FRXOverrun)) then
_service()
else
POSTINC2 = FRXBuffer(FRXIndexOut)
inc(FRXIndexOut)
if (FRXIndexOut > bound(FRXBuffer)) then
FRXIndexOut = 0
endif
dec(pCount)
endif
end while
EnableISR()
end sub
//
//**************************************************************************
//Name : WriteArray *
//Purpose : Write an array of bytes - pCount is an optional number of *
// : to write. If pCount is not given, the array size is used *
//**************************************************************************
//
public sub WriteArray(byref pArray() as byte, pCount as word = 0)
if (pCount = 0) then
pCount = bound(pArray)
inc(pCount)
endif
DisableISR()
WaitForTX()
mUSBUSARTTxRam(@pArray, pCount)
EnableISR()
end sub
//
//**************************************************************************
//Name : ReadItem (OVERLOAD) *
//Purpose : Read a byte from the USB CDC connection *
//**************************************************************************
//
sub ReadItem(byref pValue as byte)
pValue = ReadByte()
end sub
//
//**************************************************************************
//Name : ReadItem (OVERLOAD) *
//Purpose : Read a string from the USB CDC connection. Use ReadTerminator *
// : to specify the input string terminator character. *
//**************************************************************************
//
sub ReadItem(byref pText as string)
dim b as byte
FSR2 = addressof(pText)
b = ReadByte()
while (b <> byte(ReadTerminator))
POSTINC2 = b
b = ReadByte()
end while
POSTINC2 = null
end sub
//
//**************************************************************************
//Name : ReadItem (OVERLOAD) *
//Purpose : Read an array from the USB CDC connection *
//**************************************************************************
//
sub ReadItem(byref pArray() as byte)
ReadArray(pArray)
end sub
//
//**************************************************************************
//Name : Read (COMPOUND) *
//Purpose : Read an item from the USB CDC connection *
//**************************************************************************
//
public compound sub Read(ReadItem)
//
//**************************************************************************
//Name : WriteItem (OVERLOAD) *
//Purpose : Write a byte value to the USB CDC connection *
//**************************************************************************
//
sub WriteItem(pValue as WREG)
WriteByte(pValue)
end sub
//
//**************************************************************************
//Name : WriteItem (OVERLOAD) *
//Purpose : Write a string value to the USB CDC connection *
//**************************************************************************
//
sub WriteItem(pText as string)
FSR2 = addressof(pText)
while (INDF2 <> 0)
WriteByte(POSTINC2)
end while
end sub
//
//**************************************************************************
//Name : WriteItem (OVERLOAD) *
//Purpose : Write an array value to the USB CDC connection *
//**************************************************************************
//
sub WriteItem(byref pArray() as byte)
WriteArray(pArray)
end sub
//
//**************************************************************************
//Name : Write (COMPOUND) *
//Purpose : Write an item to the USB CDC connection *
//**************************************************************************
//
public compound sub Write(WriteItem)
//
//**************************************************************************
//Name : WaitFor *
//Purpose : Wait for a byte value to be received *
//**************************************************************************
//
public function WaitFor(pValue as byte) as boolean
result = ReadByte() = pValue
end function
//
//**************************************************************************
//Name : DataAvailableTimeout *
//Purpose : Checks to see if a byte value has been received, with *
// : timeout in milliseconds *
//**************************************************************************
//
public function DataAvailableTimeout(pTimeout as word) as boolean
while ((pTimeout > 0) and (not DataAvailable()))
delayms(1)
USBService()
dec(pTimeout)
end while
result = DataAvailable()
end function
//
//**************************************************************************
// initialize the module
//**************************************************************************
//
InitializeCDC()
#if (USB_AUTO_INITIALIZE)
Initialize()
#else
#if (SHOW_USB_BUILD_MSGS)
#warning "USB_AUTO_INITIALIZE false... driver NOT initialized at startup"
#endif
#endif
Thanks to all for keeping me honest (esp. Keith for pointing out this one), and sorry.
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
I finally got around to testing the usb module with a J53 series part (a 18F26J53 to be exact), and everything seems to work ok.
I only bring it up since that series is really nice if you want USB and need a lot of ram available to SF without having to do a lot of manual allocation.
The J53 has the USB buffer up at the top of memory ($D00), so pretty much the full ram is usable. For example, the CDC implementation has over 3.1K of user ram free.
As long as you can live with a 3V3 part it seems like a good choice.
I only bring it up since that series is really nice if you want USB and need a lot of ram available to SF without having to do a lot of manual allocation.
The J53 has the USB buffer up at the top of memory ($D00), so pretty much the full ram is usable. For example, the CDC implementation has over 3.1K of user ram free.
As long as you can live with a 3V3 part it seems like a good choice.
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
Hi David,
If you're looking for testing requests for parts, the PIC18F87J50 has been my go to device for USB for a long time now (since 2008 at least!). Similar to the 46J50, Bunch of Ram (currently difficult to use all), BDT in the middle etc. I've done many projects that use large (> 2k) amounts of memory to test against if you want Beta testers (open example here - USB CDC, SD Card, NMEA buffer & large working file buffer, all currently manually allocated).
Must say Jerry that the 18F26J53 does look like a nice possible replacement though!
Regards,
Rangerbob
If you're looking for testing requests for parts, the PIC18F87J50 has been my go to device for USB for a long time now (since 2008 at least!). Similar to the 46J50, Bunch of Ram (currently difficult to use all), BDT in the middle etc. I've done many projects that use large (> 2k) amounts of memory to test against if you want Beta testers (open example here - USB CDC, SD Card, NMEA buffer & large working file buffer, all currently manually allocated).
Must say Jerry that the 18F26J53 does look like a nice possible replacement though!
Regards,
Rangerbob
Last edited by RangerBob on Mon Feb 27, 2012 4:17 pm, edited 2 times in total.
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
Except for the flash size, those parts are pretty similar. Since the 46J50 has less pins, it has the PPS module which eats up more SFR addresses up at the top.
I think once David has the reserved blocks working, it'll be a moot point. That will be nice for those who need a 5V part and can't switch to the J series. It'll also be nice to get rid of all that Extended Ram stuff in the code since that's pretty confusing.
BTW - it looks like MPLAB 8.84/MPASM 5.44 has preliminary support for a new J94 series of parts. I don't see a datasheet yet, but they seem to be USB + LCD.
I think once David has the reserved blocks working, it'll be a moot point. That will be nice for those who need a 5V part and can't switch to the J series. It'll also be nice to get rid of all that Extended Ram stuff in the code since that's pretty confusing.
BTW - it looks like MPLAB 8.84/MPASM 5.44 has preliminary support for a new J94 series of parts. I don't see a datasheet yet, but they seem to be USB + LCD.