PIC18F27J53 and USB

232 views
Skip to first unread message

Sebastien Lelong

unread,
Mar 27, 2011, 9:54:06 AM3/27/11
to jal...@googlegroups.com
Hi guys,

I've been playing with 18F27J53 these days (blink, serial hw), but, now, here it is: USB... Can't make it work, and I don't know if it's hardware or software related. Maybe some of you have some insights & ways to dig/debug this.

Hardware (based on jaluino bee + "green wire" fixes)
  - PIC18F2753, with 16MHz xtal, PLL enable for 48MHz, powered through USB and 3V3 regulator
  - Vusb connected to GND through 220nF and connected to Vdd (3V3)
  - 1µF accross Vbus and GND on microUSB connector
  - 100nF caps accross Vss/Vdd
  - Vddcore/Vcap connected to GND with 10µF caps

Software: see attached file, compiles against lastest jallib (rev 2525)

jal 2.4o (compiled Feb  1 2011)
generating p-code
2773 tokens, 286566 chars; 6855 lines; 13 files
generating PIC code pass 1
generating PIC code pass 2
writing result
Code area: 6988 of 131064 used (bytes)
Data area: 162 of 3664 used
Software stack available: 2480 bytes
Hardware stack depth 7 of 31
0 errors, 0 warnings



I've performed several tests:

- under windows: it says "oh! new device!", configure it, then popup a buble claiming there's a problem. Hardware manager repots device is there, but not recognized, not handled by any driver. I don't know if it's just a matter of driver, or if something is wrong regarding USB bus. I read somewhere someone had troubles under Linux, but worked under Windows.  

- under Linux, plugging the board gives the following in /var/log/syslog

Mar 27 15:39:50 pixie kernel: [1042979.536099] usb 2-2: new full speed USB device using uhci_hcd and address 110
Mar 27 15:39:50 pixie kernel: [1042979.656092] usb 2-2: device descriptor read/64, error -71
Mar 27 15:39:50 pixie kernel: [1042979.880294] usb 2-2: device descriptor read/64, error -71
Mar 27 15:39:50 pixie kernel: [1042980.096148] usb 2-2: new full speed USB device using uhci_hcd and address 111
Mar 27 15:39:50 pixie kernel: [1042980.216152] usb 2-2: device descriptor read/64, error -71
Mar 27 15:39:50 pixie kernel: [1042980.441146] usb 2-2: device descriptor read/64, error -71
Mar 27 15:39:51 pixie kernel: [1042980.656175] usb 2-2: new full speed USB device using uhci_hcd and address 112
Mar 27 15:39:51 pixie kernel: [1042981.064134] usb 2-2: device not accepting address 112, error -71
Mar 27 15:39:51 pixie kernel: [1042981.176084] usb 2-2: new full speed USB device using uhci_hcd and address 113
Mar 27 15:39:52 pixie kernel: [1042981.584131] usb 2-2: device not accepting address 113, error -71
Mar 27 15:39:52 pixie kernel: [1042981.584179] hub 2-0:1.0: unable to enumerate USB device on port 2

so it tries to reach endpoint, but can't in the end, with error -71. Googling this error often reports something related to hardware problems, but I can't find where).

I'm trying to enable "usbmon" in order to sniff USB packets, but I'm not even sure it'll help as it stucks really early during USB comms.

Does any one try USB with this chip ? Or with 18F26J50 (same kind) ? Do you know tests I could perform to check bus before going further ?

TIA
Cheers,
Seb

jaluino_bee_usb_serial.jal

Oliver Seitz

unread,
Mar 27, 2011, 10:20:02 AM3/27/11
to jal...@googlegroups.com

>- under Linux, plugging the board gives the following in /var/log/syslog

I've tried USB some time ago, and I got similar messages with too old kernels. And too old means anything before 2.6.32, I think.

Sometimes there are some messages even with newer kernels, but a device like /dev/ttyACM0 shows up, and it works.

Greets,
Kiste

Sebastien Lelong

unread,
Mar 27, 2011, 1:20:51 PM3/27/11
to jal...@googlegroups.com
Thanks Kiste for your input. I indeed once had troubles with USB serial with ttyACM0 device, it required kernel >= 2.6.32 to deal with CDC protocol. But in this case, I don't think this is the case, as in the end, kernel doesn't want to do anything with my device, and it doesn't attach any /dev/ttyACM0. I would have seen it in the log anyway.

I'll on another PC to see if it behaves the same.

Cheers,
Seb

2011/3/27 Oliver Seitz <karl...@yahoo.com>

Sebastien Lelong

unread,
Mar 31, 2011, 11:27:16 AM3/31/11
to jal...@googlegroups.com
Hi guys,

Just a follow up about this issue...

I got help from Microchip Forums (newfound), see this thread: http://www.microchip.com/forums/m569370.aspx

It appears 18F27J53 USB RAM structure isn't handled by current USB libraries. Compare figure 17-5 page 173 for 18F4550 datasheet vs. figure 23-4 page 387 for 18F27J53 datasshet for instance. USB libraries assume USB_BASE_ADDRESS as the beginning of USB RAM, corresponding to the Buffer Descriptor Table, and refers actual buffers relative to this address. This is not true for 18F27J53, though indeed, as newfound mentioned in one this last post, last available bank still contiguous and should be used like in 18F4550.

Hope what I'm talking about makes sense to someone, I'll try to fix this, but I'll appreciate any help :)

Cheers,
Seb

2011/3/27 Sebastien Lelong <sebastie...@gmail.com>

mattschinkel

unread,
Mar 31, 2011, 6:30:07 PM3/31/11
to jallib
> SB libraries assume USB_BASE_ADDRESS as the beginning of USB RAM

Where is USB RAM? I would like to find a way for USB RAM to be
reserved so JALv2 knows how much ram is being used when compiling a
program with current device files.

From the post you showed, is this correct?
const USB_BASE_ADDRESS = 0x0200
or
const USB_BASE_ADDRESS = 0x0400

How big is USB RAM?


When reading over the USB generic sample, I see a direct read from
POSTINC1. This should not get called directly, it should be part of a
small buffer'get function:

function usb_buffer'get() return byte is
pragma inline
return POSTINC1
end function

I don't understand how the address POSTINC1 gets set, or how it knows
where to read memory.

I also noticed there are not enough comments in USB files. Maybe some
should be added to make it more understandable? Seb, if you have a
chance to add some comments why you look for a fix, please do!

Albert did not use PRINT library for debugging, this makes the current
implementation of debugging difficult. Again, not enough comments.
When I enable debugging, I mostly see a bunch of junk hex that I have
no clue about. I am still looking into USB MSD (mass storage), but I
have trouble sending data back to the PC. Troubleshooting methods are
limited, and so is my knowledge on USB.

Albert did make a great USB library, it seems that there are a few
small improvements that could be made.

Matt.

Oliver Seitz

unread,
Apr 1, 2011, 3:03:48 AM4/1/11
to jal...@googlegroups.com

> I don't understand how the address POSTINC1 gets set, or
> how it knows
> where to read memory.

It reads from the adress FSR1 points to, but in contrast to reading INDF1, FSR1 is incremented after the read. I had suggested not to use indirect adressing from a JAL program at all. If INDF or POSTINC or so is necessary, some lines of assembler should be used. This is because the compiler makes heavy use of indirect adressing, and you can never know if the pointer registers still contain the values you have loaded there.

Right now, the compiler only uses one INDF register. So using a second register on chips that have more than one is safe at the moment, but Kyle has already said that he might make use of more than one INDF register in the future.

Greets,
Kiste

Sebastien Lelong

unread,
Apr 1, 2011, 2:59:11 PM4/1/11
to jal...@googlegroups.com
Hi guys,

Almost got my USB serial working... I had to adjust USB base address as previously mentioned. But, and that's my worry, I also had to switch back to jalv24n. Last jalv24o beta (1st Feb 2011) doesn't seem to handle properly print_string(serial_hw_data,str[]), producing garbage chars. I wonder if there's a trouble with array (wasn't it previously reported ?), and since USB descriptors use them extensively, it was stuck... That could be an explanation though I couldn't dig this more.

During my USB "travel", I mentioned several issue regarding debug statement (see also issue 153). With the help of newfound from Microchip forums, I pointed another issue about USB base address (Rob, maybe we can work on this ?). I'll try to address both of these.

Stick to jalv24n...

Cheers,
Seb 

2011/4/1 Oliver Seitz <karl...@yahoo.com>

> I don't understand how the address POSTINC1 gets set, or
> how it knows
> where to read memory.

It reads from the adress FSR1 points to, but in rcontrast to reading INDF1, FSR1 is incremented after the read. I had suggested not to use indirect adressing from a JAL program at all. If INDF or POSTINC or so is necessary, some lines of assembler should be used. This is because the compiler makes heavy use of indirect adressing, and you can never know if the pointer registers still contain the values you have loaded there.


Right now, the compiler only uses one INDF register. So using a second register on chips that have more than one is safe at the moment, but Kyle has already said that he might make use of more than one INDF register in the future.

Greets,
Kiste

--
You received this message because you are subscribed to the Google Groups "jallib" group.
To post to this group, send email to jal...@googlegroups.com.
To unsubscribe from this group, send email to jallib+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/jallib?hl=en.




--
Sébastien Lelong
http://www.sirloon.net
http://sirbot.org

Rob Hamerling

unread,
Apr 1, 2011, 4:18:34 PM4/1/11
to jal...@googlegroups.com

Hi Seb,

On 2011/04/01 20:59, Sebastien Lelong wrote:

> During my USB "travel", I mentioned several issue regarding debug
> statement (see also issue 153). With the help of newfound from Microchip
> forums, I pointed another issue about USB base address (Rob, maybe we
> can work on this ?). I'll try to address both of these.

I would be glad to help, but you'll have to tell me more how!

Regards, Rob.

--
R. Hamerling, Netherlands --- http://www.robh.nl

mattschinkel

unread,
Apr 1, 2011, 4:33:03 PM4/1/11
to jallib
> Almost got my USB serial working... I had to adjust USB base address as
> previously mentioned. But, and that's my worry, I also had to switch back to
> jalv24n. Last jalv24o beta (1st Feb 2011) doesn't seem to handle properly
> print_string(serial_hw_data,str[]), producing garbage chars. I wonder if
> there's a trouble with array (wasn't it previously reported ?), and since
> USB descriptors use them extensively, it was stuck... That could be an
> explanation though I couldn't dig this more.

print_string was fixed in jal 2.4o (compiled Mar 6 2011)

Matt.

Sebastien Lelong

unread,
Apr 1, 2011, 5:17:46 PM4/1/11
to jal...@googlegroups.com

2011/4/1 mattschinkel <mattsc...@hotmail.com>

print_string was fixed in jal 2.4o (compiled Mar  6 2011)

Ooops, forgot that, I hope I was on the last beta... I'll try.

Cheers,
Seb

Sebastien Lelong

unread,
Apr 1, 2011, 6:18:01 PM4/1/11
to jal...@googlegroups.com
Ah, ah, that was a bait...

While trying to understand why it didn't work, I compared USB ram on 18F4550, 18F14K50 and 18F27J53. USB ram can span onto specific banks (18F4550, 18F14K50) or all ram (18F27J53). Within USB ram, some is reserved for buffer descriptor tables (BDT), which actually defines some sort of registers with variable size within USB ram. Those locations vary from PIC to PIC. usb_defs.jal currently takes care of 14K50 and 4550, I'll update it for 27J53. But I was wondering if there was a way to make this more generic, maybe enriching these special locations in device files. I had a very quick look at 18f27j53.inc file in MAPSM, I can't find anything related to this, but you know this far better than me, so maybe you'll have an idea.

For 18F27J53, all ram can be used as USB ram, this means you can put buffer anywhere. But current jalv2 USB implementation assumes USB data is following BDT. For this PIC, memory is oragnized as (IIRC): USB data from bank 0 to 13, BDT and USB data on bank 14, USB data on bank 15. this means, with current implementation, only bank 15 can be used, as it's following BDT/bank 14. If we have information about this, maybe we could build a better, more generic USB lib set.

So, to sum up:
  1. is it possible to enrich device file with BDT memory location ?
  2. is it possible to enrich device file with USB data memory location ?

1. would help setting USB_BASE_ADDRESS in usb_defs.jal in a more generic way.
 
2. really is an extra, using this type of information would require huge modifications in libraries. But also would allow to build heavy USB device. I'm not sure it's useful right now though...


Cheers,
Seb

2011/4/1 Rob Hamerling <robham...@gmail.com>

--
You received this message because you are subscribed to the Google Groups "jallib" group.
To post to this group, send email to jal...@googlegroups.com.
To unsubscribe from this group, send email to jallib+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/jallib?hl=en.

mattschinkel

unread,
Apr 2, 2011, 5:22:05 AM4/2/11
to jallib
Seb, please keep us informed if you know how to find what part of
memory USB is using.

It looks like I am making some small amount of progress on USB MSD
class. The HID generic sample was a good starting point, and I seem to
understand USB more now. The HID generic sample should be made into a
template for users to easily create new usb files of different
classes. Hmmm... maybe there's a networking class :)

Matt.

On Apr 1, 6:18 pm, Sebastien Lelong <sebastien.lel...@gmail.com>
wrote:
> 2011/4/1 Rob Hamerling <robhamerl...@gmail.com>
>
>
>
>
>
>
>
> > Hi Seb,
>
> > On 2011/04/01 20:59, Sebastien Lelong wrote:
>
> >  During my USB "travel", I mentioned several issue regarding debug
> >> statement (see also issue 153). With the help of newfound from Microchip
> >> forums, I pointed another issue about USB base address (Rob, maybe we
> >> can work on this ?). I'll try to address both of these.
>
> > I would be glad to help, but you'll have to tell me more how!
>
> > Regards, Rob.
>
> > --
> > R. Hamerling, Netherlands ---http://www.robh.nl
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "jallib" group.
> > To post to this group, send email to jal...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > jallib+un...@googlegroups.com.
> > For more options, visit this group at
> >http://groups.google.com/group/jallib?hl=en.
>
> --
> Sébastien Lelonghttp://www.sirloon.nethttp://sirbot.org- Hide quoted text -
>
> - Show quoted text -

Sebastien Lelong

unread,
Apr 2, 2011, 12:57:07 PM4/2/11
to jal...@googlegroups.com
My mistake, it works with last beta from March 6th...

Thanks
Seb

2011/4/1 mattschinkel <mattsc...@hotmail.com>

Sebastien Lelong

unread,
Apr 2, 2011, 1:03:28 PM4/2/11
to jal...@googlegroups.com
USB ram usage is configured by user, so usage is more or less important. There's no hardware check about declared buffers size, if they are too big, behavior is unexpected. In order to know how much RAM is used you need count bytes in BDT.


Cheers,
Seb 

2011/4/2 mattschinkel <mattsc...@hotmail.com>



--

Rob Hamerling

unread,
Apr 2, 2011, 1:58:48 PM4/2/11
to jal...@googlegroups.com

Hi Seb,

On 2011/04/02 00:18, Sebastien Lelong wrote:

> So, to sum up:
> 1. is it possible to enrich device file with BDT memory location ?
> 2. is it possible to enrich device file with USB data memory location ?

Please open an issue for this. Keeps info together.

mattschinkel

unread,
Apr 3, 2011, 1:47:23 AM4/3/11
to jallib
I figure these lines declare USB memory usage (from usb hid generic
sample):

const bit USB_EP0 = 1
const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE = 8
const word USB_EP0_IN_ADDR = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

Of course, this does not reflect while compiling. Would it make sence
to reserve this memory with an array like this:

var byte ep0_reserve_memory[0x0010 + USB_EP0_OUT_SIZE +
USB_EP0_IN_SIZE] at USB_BASE_ADDRESS

I'm not sure where the 0x0010 comes from (I think it's in blogspot
somewhere). and this array would be removed by the compiler, so we
would have to use it in some way. Maybe with a dummy procedure

By reading the above, it appears that USB buffers do not take much
memory (depending on the application).

Matt.

On Apr 2, 1:03 pm, Sebastien Lelong <sebastien.lel...@gmail.com>
wrote:
> USB ram usage is configured by user, so usage is more or less important.
> There's no hardware check about declared buffers size, if they are too big,
> behavior is unexpected. In order to know how much RAM is used you need count
> bytes in BDT.
>
> Cheers,
> Seb
>
> 2011/4/2 mattschinkel <mattschin...@hotmail.com>
> > > Sébastien Lelonghttp://www.sirloon.nethttp://sirbot.org-Hide quoted text

mattschinkel

unread,
Apr 3, 2011, 2:06:58 AM4/3/11
to jallib
If nobody objects, I would like to make the following change...

in usb_ep_data_out_callback(....,word in buffer_addr,......), we
currently have the following:

var byte src_ptr[2] AT buffer_addr
FSR1L = src_ptr[0]
FSR1H = src_ptr[1]

then each call of POSTINC1 reads one byte from the buffer


I would like to change this usage to the following:

1. Put this in the USB lib, before calling usb_ep_data_out_callback()
var byte src_ptr[2] AT buffer_addr
FSR1L = src_ptr[0]
FSR1H = src_ptr[1]

2. Create a inline usb_out_buffer'get function for POSTINC1

There is no need to change API. I will keep "word in buffer_addr" in
usb_ep_data_out_callback parameters, although it would no longer be
needed. These suggestions would not affect anyone's current code.

It took me longer then needed to figure out what these registers do
since they are not named well, and there are no comments.

Matt.

Sebastien Lelong

unread,
Apr 3, 2011, 3:14:12 AM4/3/11
to jal...@googlegroups.com
But what would be the benefits ?

Seb

2011/4/3 mattschinkel <mattsc...@hotmail.com>

--
You received this message because you are subscribed to the Google Groups "jallib" group.
To post to this group, send email to jal...@googlegroups.com.
To unsubscribe from this group, send email to jallib+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/jallib?hl=en.




--

Oliver Seitz

unread,
Apr 3, 2011, 3:21:09 AM4/3/11
to jal...@googlegroups.com

>But what would be the benefits ?

>>2. Create a inline usb_out_buffer'get function for POSTINC1

If one day the compiler starts to use FSR1 internally, only this 'get function will have to be modified. Or, it can directly be written like

Increment pointer
ASSEMBLER
Load FSR with that pointer
Read back value from INDF
END ASSEMBLER

This would be safe for any additional FSRs the compiler may require. It will be a bit slower, but you can't always have maximum speed and versatility.

Greets,
Kiste

Sebastien Lelong

unread,
Apr 3, 2011, 3:28:49 AM4/3/11
to jal...@googlegroups.com
Yes I did understood that, but putting a pseudo-var for this seems overkill to me, and doesn't fix potential issue either . FSR & POSTINC usage is already centralized in this _usb_copy_arry_to_ram() procedure. (and it could be put in an external library, as it can be useful not only for USB).

If necessary, we could use asm as you suggested, to avoid conflicting with compiler.


Seb

2011/4/3 Oliver Seitz <karl...@yahoo.com>

mattschinkel

unread,
Apr 3, 2011, 3:32:47 AM4/3/11
to jallib
> But what would be the benefits ?

readability, and standardization. Maybe we'll be running USB on
another type of processor some day.

Matt.

Sebastien Lelong

unread,
Apr 3, 2011, 3:48:33 AM4/3/11
to jal...@googlegroups.com
I'd recommend to check stack/prog/ram usage for this change, and compare before/after. I understand your point about readability, you know how often I focus on this, but:

  - this readability occurs within an internal procedure (not exposed to users).
  - you'll get better readability within this procedure as POSTINC will fade way behind your pseudo-var, but your pseudo-var now inherits from this readability (you're moving the readability problem one step away
  - in any case you'll put a comment about POSTINC explaining what it does, so in the end, avoiding a pseudo-var for this + put a comment will bring the level of readability.

Do you see what I mean ? 

Do I understand well when I say this pseudo-var would just be a getter or setter for POSTINC ? Why not using an alias instead, with a more human understable meaning ? Thinking about this, I would not recommend this too as it would hide the very specific usage/meaning of POSTINC behind a user variable (it would look like any other variable but would really be special as it acts on FSR).


Cheers,
Seb 

2011/4/3 mattschinkel <mattsc...@hotmail.com>

Matt.

--
You received this message because you are subscribed to the Google Groups "jallib" group.
To post to this group, send email to jal...@googlegroups.com.
To unsubscribe from this group, send email to jallib+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/jallib?hl=en.

mattschinkel

unread,
Apr 3, 2011, 3:52:41 AM4/3/11
to jallib
just to explain this more.... the class files, like
usb_drv_cdc_class.jal and eventually MSD currently call those
registers, and no other registers. If we can call a procedure instead,
it will be simple to port this file to another processor if there are
usb driver files available.

So, is it ok with you Seb?

PS: I didn't actually read fully through usb_drv_cdc_class.jal to see
if it uses other registers, but I do know that I will not need any
others while writing a lib for msd class driver.

Matt.

mattschinkel

unread,
Apr 3, 2011, 3:54:23 AM4/3/11
to jallib
> Yes I did understood that, but putting a pseudo-var for this seems overkill
> to me

Why overkill? there is no additional processing if it is inline.

Matt.

Sebastien Lelong

unread,
Apr 3, 2011, 4:00:22 AM4/3/11
to jal...@googlegroups.com


2011/4/3 mattschinkel <mattsc...@hotmail.com>


Why overkill? there is no additional processing if it is inline.

Exact same usage ? Don't get me wrong, I'm not the one who will say "no don't do this", but there were several discussions lately about jallib becoming more and more greedy. So I just wanted to "put this on the table". Just check it is exactly the same usage... (will you use "asm block" as suggested by Kiste ?)

Cheers,
Seb 

mattschinkel

unread,
Apr 3, 2011, 4:00:53 AM4/3/11
to jallib
I am a user of the USB drivers, so it is exposed to me.

I am only a writer of a new class library. This should be made easy
for new writers of class libs.

alias may work.

Matt.

On Apr 3, 3:48 am, Sebastien Lelong <sebastien.lel...@gmail.com>
wrote:
> I'd recommend to check stack/prog/ram usage for this change, and compare
> before/after. I understand your point about readability, you know how often
> I focus on this, but:
>
>   - this readability occurs within an internal procedure (not exposed to
> users).
>   - you'll get better readability within this procedure as POSTINC will fade
> way behind your pseudo-var, but your pseudo-var now inherits from this
> readability (you're moving the readability problem one step away
>   - in any case you'll put a comment about POSTINC explaining what it does,
> so in the end, avoiding a pseudo-var for this + put a comment will bring the
> level of readability.
>
> Do you see what I mean ?
>
> Do I understand well when I say this pseudo-var would just be a getter or
> setter for POSTINC ? Why not using an alias instead, with a more human
> understable meaning ? Thinking about this, I would not recommend this too as
> it would hide the very specific usage/meaning of POSTINC behind a user
> variable (it would look like any other variable but would really be special
> as it acts on FSR).
>
> Cheers,
> Seb
>
> 2011/4/3 mattschinkel <mattschin...@hotmail.com>
>
>
>
>
>
> > > But what would be the benefits ?
>
> > readability, and standardization. Maybe we'll be running USB on
> > another type of processor some day.
>
> > Matt.
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "jallib" group.
> > To post to this group, send email to jal...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > jallib+un...@googlegroups.com.
> > For more options, visit this group at
> >http://groups.google.com/group/jallib?hl=en.
>
> --

Oliver Seitz

unread,
Apr 3, 2011, 4:57:54 AM4/3/11
to jal...@googlegroups.com
>Do I understand well when I say this pseudo-var would just be a getter or setter for POSTINC ?

... Or, indeed add some overhead, like starting a new little lib like...
(untested, has to be extended to support 12 and 14bit cores, I think)

procedure dereference’put ( word in pointer, byte in value ) is
assembler
movff pointer, FSR0L
movff pointer+1, FSR0H
movff value,INDF0
end assembler
end procedure

procedure dereference’get ( word in pointer ) return byte is
var byte value
assembler
movff pointer, FSR0L
movff pointer+1, FSR0H
movff INDF0,value
end assembler
dereference=value
end procedure

This may take 15 instruction cycles where direct access to POSTINC takes only one or two, but it can be made quite versatile. It would be an approach to start using pointers without compiler support.

Greets,
Kiste

mattschinkel

unread,
Apr 3, 2011, 8:15:45 PM4/3/11
to jallib
I didn't quite understand the use of these procedures. Can you give an
example please?

This POSTINC1 sounds quite useful & fast. I wonder if it should be
used in sd & hard disk libraries with "if defined(POSTINC1)".

Matt.

Oliver Seitz

unread,
Apr 4, 2011, 3:56:01 AM4/4/11
to jal...@googlegroups.com

> I didn't quite understand the use of
> these procedures. Can you give an
> example please?

It's just a way of hiding the asm part from the user and access arbitrary memory locations in a clean and readable way. Example: Outputting bytes from memory locations 0x80 to 0xa0:

for 0x20 using counter loop
serial_hw_data=dereference[0x80+counter]
end loop


> This POSTINC1 sounds quite useful & fast. I wonder if
> it should be
> used in sd & hard disk libraries with "if
> defined(POSTINC1)".

It does in fact save quite a lot on execution time and also some code space, but I wouldn't use it outside ASM blocks too much as long as Kyle had not promised not to use it...

On PIC12,PIC16... there's only a INDF register for indirect memory access. PIC18 additionally has registers POSTINC, POSTDEC, PREINC and PLUSW which also do indirect memory acces, but modify the FSR value before or after that. Each INDF "module" comes in a group of all of FSRxL, FSRxH, INDFx, POSTINCx, POSTDECx, PREINCx and PLUSWx.

There are PICs that only have one INDF, and those that have three. The PICs with only one INDF do not have POSTINC, POSTDEC, PREINC or PLUSW. Kyle already said he might be using more than one INDF one day. If we did agree that INDF1 is reserved to the compiler and INDF2 is for users, great. But from what I know today, we should regard all INDF related registers as reserved.

Oliver Seitz

unread,
Apr 4, 2011, 4:30:11 AM4/4/11
to jal...@googlegroups.com

> Can you give an
> example please?

Here's a useful one, my favourite way of generating a random seed:

var byte randomseed
var word counter

for 65535 using counter loop
randomseed=randomseed+dereference[counter]
end loop

Some registers have definded values on startup, some don't. Those who don't contain values that may depend on...

- how long power was removed
- the speed of the supply rising
- electromagnetic interference during power-up
- cosmic radiation during power-up...

So it is highly possible that this loop will not yield the same value on each startup. I think it is the best source of entropy on startup without using additional hardware. ADC converters, where available, should be tested however, they may be even better entropy sources. Another idea would be to run ADC conversion at an out-of-spec rate. But that's another issue ;-)

Greets,
Kiste

Sebastien Lelong

unread,
Apr 4, 2011, 4:45:24 AM4/4/11
to jal...@googlegroups.com
Hi Kiste,

Maybe those deference'put|get procedures could into a ptr.jal library (in "include/jal" map) ? I had thoughts about implementing malloc, that could be a starting lib (though malloc was more something being intellectually interesting than efficient, I understand...)

Cheers,
Seb

2011/4/4 Oliver Seitz <karl...@yahoo.com>

mattschinkel

unread,
Apr 4, 2011, 5:07:53 AM4/4/11
to jallib
> It does in fact save quite a lot on execution time and also some code space, but I wouldn't use it outside ASM blocks too much as long as Kyle had not promised not to use it...

Then maybe I can use an if statement for devices that it has been
tested on, or maybe there is a way to detect if it is supported on the
current PIC. If it is not, use a normal array + counter method. Maybe
a lib could be created?

I'll have to test file read/write times on hard disk & sd card. If
there is a big difference, it would be worth it.

I guess I may have trouble anyways since whereis() doesn't work on
arrays or other variables.

Matt.

Oliver Seitz

unread,
Apr 4, 2011, 5:30:09 AM4/4/11
to jal...@googlegroups.com

> [...] or maybe there is a way to detect if it is

> supported on the
> current PIC.

As far as I know, if there is a POSTINC1, there's three sets of INDF registers with all the features.

But, to make use of a POSTINC register, you have to rely on the compiler not changing what you have written to the correspondent FSRxL, FSRxH registers. There's no way to find out but to check the contents of those registers, and this takes far more time than just setting the registers again before any access to a INDF register. For now it is confirmed that "the compiler does not use INDF1 or INDF2 yet." So, until this changes, it's no problem. But if this changes, trouble's ahead.

> If it is not, use a normal array + counter
> method.

I don't really know how the compiler handles arrays. But, if the compiler starts to use more than one INDF, array handling will probably speed up a lot.

> I'll have to test file read/write times on hard disk &
> sd card. If
> there is a big difference, it would be worth it.

If it is for copying sequential memory locations to other sequential memory locations, performance could rise a real lot, especially when using POSTINC1 *and* POSTINC2. One byte could then be copied in only 5 instruction cycles, while when only using one INDF, I think about 20 cycles are needed.

Greets,
Kiste

mattschinkel

unread,
Apr 4, 2011, 5:53:06 AM4/4/11
to jallib
> For now it is confirmed that "the compiler does not use INDF1 or INDF2 yet." So, until this changes, it's no problem. But if this changes, trouble's ahead.

I see what you mean... So, this means USB could get broken by a
compiler upgrade? I guess this is what you have been talking about
which I didn't quite understand.

Another thing to do is create a optional user constant for this (with
a warning comment), for USB and other libs. From previous tests, small
changes in a 512 byte array read loop made a big difference.
Personally, I would want to transfer files as quick as possible.

Matt.

Oliver Seitz

unread,
Apr 4, 2011, 6:50:11 AM4/4/11
to jal...@googlegroups.com
> > For now it is confirmed that
> "the compiler does not use INDF1 or INDF2 yet." So, until
> this changes, it's no problem. But if this changes,
> trouble's ahead.
>
> I see what you mean... So, this means USB could get broken
> by a
> compiler upgrade? I guess this is what you have been
> talking about
> which I didn't quite understand.

That's exactly what I meant :-)

> Another thing to do is create a optional user constant for
> this (with
> a warning comment), for USB and other libs. From previous
> tests, small
> changes in a 512 byte array read loop made a big
> difference.
> Personally, I would want to transfer files as quick as
> possible.

Of course I don't approve to slow things down just to keep a compatibility that is not needed. But again, it is perfectly safe to use these registers in an asm block, as the compiler will never interfere there.

Here some (untested) examples. The memcopy_dword procedure takes little more than three instruction cycles per copied byte. All procedures do only run on PIC18 cores.

Greets,
Kiste


procedure memcopy_bytes ( word in source_ptr, word in dest_ptr, byte in amount ) is
-- copies [amount] bytes from source memory location to dest.
-- amount=0 copies 256 bytes
var byte counter
counter=amount
ASSEMBLER
movfw source_ptr
movwf FSR1L
movfw source_ptr+1
movwf FSR1H
movfw dest_ptr
movwf FSR2L
movfw dest_ptr+1
movwf FSR2H
LOCAL copy_loop
copy_loop:
movfw POSTINC1
movwf POSTINC2
decfsz counter,f
goto copy_loop
END ASSEMBLER
end procedure

procedure memcopy_words ( word in source_ptr, word in dest_ptr, byte in amount ) is
-- copies [amount] words from source memory location to dest.
-- amount=0 copies 256 words=512 bytes
var byte counter
counter=amount
ASSEMBLER
movfw source_ptr
movwf FSR1L
movfw source_ptr+1
movwf FSR1H
movfw dest_ptr
movwf FSR2L
movfw dest_ptr+1
movwf FSR2H
LOCAL copy_loop
copy_loop:
movfw POSTINC1
movwf POSTINC2
movfw POSTINC1
movwf POSTINC2
decfsz counter,f
goto copy_loop
END ASSEMBLER
end procedure

procedure memcopy_dwords ( word in source_ptr, word in dest_ptr, byte in amount ) is
-- copies [amount] dwords from source memory location to dest.
-- amount=0 copies 256 dwords=1024 bytes
var byte counter
counter=amount
ASSEMBLER
movfw source_ptr
movwf FSR1L
movfw source_ptr+1
movwf FSR1H
movfw dest_ptr
movwf FSR2L
movfw dest_ptr+1
movwf FSR2H
LOCAL copy_loop
copy_loop:
movfw POSTINC1
movwf POSTINC2
movfw POSTINC1
movwf POSTINC2
movfw POSTINC1
movwf POSTINC2
movfw POSTINC1
movwf POSTINC2
decfsz counter,f
goto copy_loop
END ASSEMBLER
end procedure


Reply all
Reply to author
Forward
0 new messages