View previous topic :: View next topic |
Author |
Message |
Wohn Guest
|
Fast_io not working properly on 16F887 |
Posted: Wed Mar 25, 2009 3:50 pm |
|
|
While using fast_io(C) on the 16F887, portc will float the outputs when I try to float 1 pin. All other ports function properly. Let me know if Im doing something wrong or not. Thanks
Code: | #include "16f887.h"
#use delay (clock=4MHz)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#fuses INTRC_IO,NOWDT,PUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT,NOIESO,NOFCMEN,NOLVP,NOWRT,BORV40
int RATIO=255;
void main()
{
set_tris_A(0xFF);
set_tris_B(0x00);
set_tris_C(0x00);
set_tris_D(0x00);
set_tris_E(0x08);
port_B_pullups(0xFF);
output_C(RATIO);
delay_ms(1500);
output_float(PIN_A4);
output_float(PIN_C6);
output_float(PIN_E0);
enable_interrupts(GLOBAL);
sleep();
} |
Im using pcw 4.057 |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Mar 25, 2009 4:43 pm |
|
|
Seems like a compiler bug but I don't understand all the details. What happens for the output_float command on PortC is that the compiler generates code like fast_io is not specified. This is related to an errata setting in chipedit.exe: 'Don't RMW on TRISC'.
Wrong here is that the compiler accepts the fast_io setting for most commands, except for output_float. This creates a corrupted shadow register. The problem also exists in v4.077 (my most recent version).
Possible work around:
- Use normal_io on portC
I don't understand what the chip errata is supposed to do, and I can't find this problem being mentioned in the PIC16F887 Silicon Errata sheet. Maybe someone else can comment on this?
Edit: removed second work around as it appears to be a bad idea.
Last edited by ckielstra on Wed Mar 25, 2009 5:20 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 25, 2009 4:51 pm |
|
|
The compiler maintains a shadow register for TRISC. It's initialized to
"all inputs" by the compiler in its start-up code. The problem is that the
set_tris_c() function doesn't update the shadow register when in #fast_io
mode. But other functions, such as output_float() do access the shadow
register. So they're using the initial value, which is "all inputs", when
it should properly be "all outputs", due to your changing the TRIS C
register with the set_tris_c(0) function. That's why you're seeing a
problem.
Because of this, I'm not sure you can use #fast_io mode on Port C.
I don't normally use #fast_io mode, so I'm not completely up-to-date on
all the machinations that the compiler does in that mode. But the quick
way to fix your problem is just to eliminate #fast_io mode for Port C.
Leave it in standard i/o mode (which is the default).
Example:
Quote: | #use fast_io(A)
#use fast_io(B)
//#use fast_io(C)
#use fast_io(D)
#use fast_io(E) |
|
|
|
Wohn Guest
|
fast_io |
Posted: Wed Mar 25, 2009 5:12 pm |
|
|
I have not been using the fast_io on port c because of this and was
wondering what the problem was and if it was me or a bug. I was just
trying to cut down a few words off the program memory so its no big deal.
Thanks for clearing this up for me. Still alot I need to learn about the way
c gets compiled.
Thank You |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Mar 25, 2009 5:17 pm |
|
|
ckielstra wrote: | I don't understand what the chip errata is supposed to do, and I can't find this problem being mentioned in the PIC16F887 Silicon Errata sheet. Maybe someone else can comment on this? | OK, found out why: searching this forum I found the following link: http://groups.google.com/group/comp.arch.embedded.piclist/msg/e66622c7e2a2677e (Thanks PCM) |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 25, 2009 5:20 pm |
|
|
Hi ckielstra,
It's this paragraph from the 16F877 data sheet, in the I/O ports section
on Port C:
Quote: |
When enabling peripheral functions, care should be
taken in defining TRIS bits for each PORTC pin. Some
peripherals override the TRIS bit to make a pin an output,
while other peripherals override the TRIS bit to
make a pin an input. Since the TRIS bit override is in
effect while the peripheral is enabled, read-modify-write
instructions (BSF, BCF, XORWF) with TRISC as
destination, should be avoided. The user should refer
to the corresponding peripheral section for the correct
TRIS bit settings. |
CCS fixes this problem by doing all modifications to a shadow register
for TRISC, and then when ready, they write the shadow register as a
complete byte to the TRISC register. They never read the physical
TRISC register. They only write to it. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Mar 25, 2009 6:15 pm |
|
|
PCM and FvM, thanks for the extra info!
FvM: the second document you refer to I have never seen before. Seems like I2C on many chips has a problem that we often overlook in this forum. |
|
|
Ttelmah Guest
|
|
Posted: Thu Mar 26, 2009 3:43 am |
|
|
I'd say that really I'm not surprised that 'output_float', would have problems with fast_io.
If you simply say that when 'fast_io' is used, it becomes _your_responsibility to control TRIS then it becomes 'not surprising' that there may be problems. It works on most chips, since TRIS can be read and written normally, but not on the 877, because of the need to use the shadow register. If you want to do this, then go fully 'DIY'. Something like:
Code: |
int8 tris_val;
#define set_trisC(x) tris_val=x;set_tris_c(x)
#define my_float(pin) if((pin & 0xF8)==0x38) \
{bit_set(tris_val,pin&7);set_tris_c(tris_val)} \
else output_float(pin)
|
No guarantees!...
Best Wishes |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Mar 26, 2009 6:26 am |
|
|
If the linked errata sheet information is complete, TRISC read-modify-write must not be disabled, except for designs using I2C slaves. I didn't check, but would give it a try. |
|
|
|