CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Trouble using SPI Flash memory SST25VF010A

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
thibow



Joined: 11 Apr 2012
Posts: 30

View user's profile Send private message

Trouble using SPI Flash memory SST25VF010A
PostPosted: Mon May 28, 2012 2:51 pm     Reply with quote

Hello,

I've been looking around to find any sample code to compare with what I am doing, but I couldn't find anything that solved my problem. I am simply trying to read the status register of the memory (SST25VF010A datasheet). I am using a PIC18LF2550, here is my code and the output (I am using CCS compiler and I made my own SPI read/write function) :

Code:
#include <18F2550.H>
#include <STDLIBM.H>

#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,PLL2,CPUDIV4,NOVREGEN,NOMCLR
#use delay(clock=16000000)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C5,bits=8,STOP=1)
#define SPI_SS pin_A5
#define LED1 pin_A1
#define nHOLD pin_A2
#define nWP pin_A3

#byte SSPSTAT = 0xFC7
#bit SMP = SSPSTAT.7
#bit CKE = SSPSTAT.6
#bit D_A = SSPSTAT.5
#bit P = SSPSTAT.4
#bit S = SSPSTAT.3
#bit R_W = SSPSTAT.2
#bit UA = SSPSTAT.1
#bit BF = SSPSTAT.0

#byte SSPBUF = 0xFC9

unsigned char do_spi(unsigned char txdata); // my own SPI fundtion

char *mychar=NULL;
int i=0;
int length;


void init(void){
    setup_spi(spi_master | spi_l_to_h | spi_clk_div_16 | spi_xmit_l_to_h);
    output_HIGH(LED1); //Led lit

    output_HIGH(SPI_SS); // SS initialized
    output_HIGH(nHOLD); // no hold
    output_HIGH(nWP); // no Write protection
}

void main (void){
   
    init();
    printf("\nInit OK"); //tells me the init went all right
    mychar = malloc(length * sizeof(char)+1);  /* space for length chars */
    if (mychar == NULL) {
       printf("Memory not allocated.\n");
     } else {
        delay_us(500);        //wait
        //********  INITIALIZE THE EEPROM FOR READING STATUS **************************
        output_LOW(SPI_SS);       //clear the chip select
        do_spi(0x05);    //Say I want to Read Status
        mychar[0]=do_spi(0);    //read it

        delay_us(1000);       
        output_HIGH(SPI_SS);
        printf("\n\r data 1: %c",mychar[0]);    //Show me what you got through UART
        free(mychar);
        output_toggle(LED1);
    }
}

 unsigned char do_spi(unsigned char txdata)
 {
        SSPBUF = txdata;
        while (!BF);    // SSPSTAT.BF (when the buffer is full)
        return  SSPBUF;
 }


and here is the output :

Quote:
¡Ê+‹OK
data 1:


First of all, I don't understand why my Uart does not want to write correctly "Init" and write "¡Ê+‹" instead.. but this is not so relevant, then of course, as you can see, I don't get anything from the memory..

If you have any clue.

Thank you
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Mon May 28, 2012 3:43 pm     Reply with quote

Couple things - there could be more - but the two things that jump out at me are:
- Implement the PIC's power up timer fuse (add PUT to your #fuses line). That should the fix the problem of the PIC not properly printing your "Init OK" line.
- Your main() lacks an infinite loop. The compiler automatically places a "hidden" sleep() command at the end of main(). Your code is hitting this sleep command and the processor is going to sleep before the UART has a chance to transmit all remaining data. Simply add a while (TRUE) {} to the end of your code to avoid this hidden sleep() command.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue May 29, 2012 12:39 am     Reply with quote

A few more notes:
1) The call to malloc uses a variable 'length' which is uninitialized.
2) Use of malloc in an embedded application is not recommended because memory fragmentation could cause problems in the long run (and embedded is supposed to run very long).
3) Use pin C7 for RS232 transmit instead of C5. Now the compiler will generate a software UART which is not as good as a hardware one.
4) Always add ERRORS to the #use RS232 definition for hardware UARTs, this causes the compiler to add code for clearing error flags. Otherwise the UART will stall after receive buffer overflows.
5) What is the level of the HOLD# pin? It should be HIGH.
6)
Code:
setup_spi(spi_master | spi_l_to_h | spi_clk_div_16 | spi_xmit_l_to_h);
This setup looks right to me, but CCS made it a bit difficult to read. Easier is to add defines for the 4 SPI modes:
Code:
#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)
Your Flash chip operates at either mode 0 or 3 and the configuration can then be setup like:
Code:
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16);
thibow



Joined: 11 Apr 2012
Posts: 30

View user's profile Send private message

PostPosted: Tue May 29, 2012 7:24 am     Reply with quote

Hello,

@newguy: Thank you for your help, I have added "PUT" to the fuses and a while(1); at the end of my main, but I still got nothing as output (plus the microcontroller reset as it prints the "data1" twice..)

output:
Quote:
¡Ê+‹OK
data 1:
¡Ê+‹OK
data 1:


edit :
@ckielstra thank you for your help, I'll try this right now
thibow



Joined: 11 Apr 2012
Posts: 30

View user's profile Send private message

PostPosted: Tue May 29, 2012 7:51 am     Reply with quote

ckielstra wrote:
A few more notes:
1) The call to malloc uses a variable 'length' which is uninitialized.
2) Use of malloc in an embedded application is not recommended because memory fragmentation could cause problems in the long run (and embedded is supposed to run very long).

You're right, I'll use a simple array.

Quote:

3) Use pin C7 for RS232 transmit instead of C5. Now the compiler will generate a software UART which is not as good as a hardware one.

As I prefer to use SW USART than SW SPI, and both SPI and UART use the same pin, I had to make a choice ;)
Quote:

4) Always add ERRORS to the #use RS232 definition for hardware UARTs, this causes the compiler to add code for clearing error flags. Otherwise the UART will stall after receive buffer overflows.

Ok this is done
Quote:

5) What is the level of the HOLD# pin? It should be HIGH.


this is high as stated in the init() function "output_HIGH(nHOLD);"

Quote:

6)
Code:
setup_spi(spi_master | spi_l_to_h | spi_clk_div_16 | spi_xmit_l_to_h);
This setup looks right to me, but CCS made it a bit difficult to read. Easier is to add defines for the 4 SPI modes:
Code:
#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)
Your Flash chip operates at either mode 0 or 3 and the configuration can then be setup like:
Code:
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16);



Ok this is done too, thank you very much, but still.., it doesn't work
here is my code

Code:
#include <18F2550.H>
#include <STDLIBM.H>

#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,PLL2,CPUDIV4,NOVREGEN,NOMCLR, PUT
#use delay(clock=16000000)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C5,bits=8,STOP=1,ERRORS)
#define SPI_SS pin_A5
#define LED1 pin_A1
#define nHOLD pin_A2
#define nWP pin_A3

#byte SSPSTAT = 0xFC7
#bit SMP = SSPSTAT.7
#bit CKE = SSPSTAT.6
#bit D_A = SSPSTAT.5
#bit P = SSPSTAT.4
#bit S = SSPSTAT.3
#bit R_W = SSPSTAT.2
#bit UA = SSPSTAT.1
#bit BF = SSPSTAT.0

#byte SSPBUF = 0xFC9

unsigned char do_spi(unsigned char txdata);

int length=2;
char mychar[length];
int i=0;

#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)

void init(void){
   //configure the device to be a master, mode 0
   setup_spi(spi_master | spi_clk_div_16 | SPI_MODE_0);
   output_HIGH(LED1); //Led lit
   output_HIGH(SPI_SS); // SS initialized
   output_HIGH(nHOLD);
   output_HIGH(nWP);
}

void main (void){
   init();
   printf("\nInit OK");

      delay_us(500);      //wait
      //********  INITIALIZE THE EEPROM FOR READING ID **************************
      output_LOW(SPI_SS);       //clear the chip select
      do_spi(0x05);    //Read Status

      for (i=0;i<length;i++)
      {
         mychar[i]=do_spi(0);   //read it in data
      }

      delay_us(1000);      
      output_HIGH(SPI_SS);
      printf("\n\r data 1: %c",mychar[0]);   //Show me what you got through UART

      output_toggle(LED1);
   while(1);
}

 unsigned char do_spi(unsigned char txdata)
 {
        SSPBUF = txdata;
        while (!BF);    // SSPSTAT.BF (when the buffer is full)
        return  SSPBUF;
 }


and the output is the same
Quote:
¡Ê+‹OK
data 1:
¡Ê+‹OK
data 1:
thibow



Joined: 11 Apr 2012
Posts: 30

View user's profile Send private message

PostPosted: Tue May 29, 2012 12:31 pm     Reply with quote

I have just checked with a scope where the problem could come from.

#HOLD is high
#WP is high
SCLK is ok
SI is ok
#CE goes down when I send or read something and high afterwards
SO does not send anything.

Which means that the problem comes from the SST Flash memory. I have tried to read the status register only, sending 0x05 and then reading 1 byte, and I have tried to read id, sending 0x90, then 0x00 3 times as the address and read 2 bytes. But the memory still doesn't send anything on SO.

Any idea ?
temtronic



Joined: 01 Jul 2010
Posts: 9163
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue May 29, 2012 6:28 pm     Reply with quote

The 'garbage' before 'OK' concerns me....
should it not be 'Init OK' ?

If so,perhaps finding why that's not right(and fixing it) will help with the rest of the program ??
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed May 30, 2012 5:12 am     Reply with quote

On first glance your program looks OK, so let me check a few basic things:
- Post your compiler version number. Some versions have known problems.
- What are the voltages used for your processor and for the flash memory? The Flash is 3.3V and you are running the same voltage for your LF version PIC?
- Post the pin numbers for the connection between PIC and Flash. PIN_C7 to ..., etc.

The garbage data in the RS232 output is indeed troubling. The first character is ok, then some garbage and then fine again. As you are using the software UART you would suspect such behaviour with an interrupt passing through, but that is not present in your code. The code as posted is exactly the same as you are testing with?

Code:
int length=2;
char mychar[length];
This is not exactly legal C and as I don't have a compiler present here I can't test how CCS is handling it. Problem is that length is a variable and you can not declare an array with variable length. A better way of coding would have been:
Code:
define LENGTH   2
char mychar[LENGTH];
or:
Code:
const int LENGTH=2;     // note the 'const' keyword
char mychar[LENGTH];


thibow wrote:
ckielstra wrote:
3) Use pin C7 for RS232 transmit instead of C5. Now the compiler will generate a software UART which is not as good as a hardware one.

As I prefer to use SW USART than SW SPI, and both SPI and UART use the same pin, I had to make a choice ;)
Of course the choice is up to you, but I would have chosen the other way around. RS232 is very sensitive to timing differences, for example from an interrupt being triggered during RS232 transmission. SPI doesn't care for timing, it is only sensitive to clock edges. Writing your own bit banging SPI routine is very easy, in fact you already wrote your own SPI routine and bit banging will be only slightly slower than the hardware implementation.
You can also use the CCS compiler to generate a software SPI for you, check the documentation on #use spi.

Another issue to keep in mind is mentioned in the chip hardware errata sheet. Issue 18 for the A3 hardware revision says that in SPI transmission you shouldn't bit_test the BF flag directly as you are doing. See the linked errata document for possible workarounds.
thibow



Joined: 11 Apr 2012
Posts: 30

View user's profile Send private message

PostPosted: Wed May 30, 2012 2:51 pm     Reply with quote

First of all, thank you very much for your help
ckielstra wrote:

- Post your compiler version number. Some versions have known problems.
- What are the voltages used for your processor and for the flash memory? The Flash is 3.3V and you are running the same voltage for your LF version PIC?
- Post the pin numbers for the connection between PIC and Flash. PIN_C7 to ..., etc.

What I have in CCS help is v.4
I use a 3.3v power supply for both the flash and the pic.

for my µC connections, I am quite sure everything's all right

pin C7 (SDO) to Memory pin 5 (SI)
pin B0 (SDI) to Memory pin 2 (SO)
pin B1 (SCK) to Memory pin 6 (SCK)
pin A5 (SS) to Memory pin 1 (#CE)
pin A2 to Memory pin 7 (#HOLD)
pin A3to Memory pin 3 (#WP)

pin RC6 (TX) and RC5 (sw RX) to my Uart RS232 bridge

Quote:

The garbage data in the RS232 output is indeed troubling. The first character is ok, then some garbage and then fine again. As you are using the software UART you would suspect such behaviour with an interrupt passing through, but that is not present in your code. The code as posted is exactly the same as you are testing with?

Code:
int length=2;
char mychar[length];
This is not exactly legal C and as I don't have a compiler present here I can't test how CCS is handling it. Problem is that length is a variable and you can not declare an array with variable length. A better way of coding would have been:
Code:
define LENGTH   2
char mychar[LENGTH];
or:
Code:
const int LENGTH=2;     // note the 'const' keyword
char mychar[LENGTH];


Well in fact I did the change as it didn't compile without the "const" but I forgot to change it in the posted code, but it exists in my code, otherwise it is exactly the same yes.
Quote:

thibow wrote:
ckielstra wrote:
3) Use pin C7 for RS232 transmit instead of C5. Now the compiler will generate a software UART which is not as good as a hardware one.

As I prefer to use SW USART than SW SPI, and both SPI and UART use the same pin, I had to make a choice ;)
Of course the choice is up to you, but I would have chosen the other way around. RS232 is very sensitive to timing differences, for example from an interrupt being triggered during RS232 transmission. SPI doesn't care for timing, it is only sensitive to clock edges. Writing your own bit banging SPI routine is very easy, in fact you already wrote your own SPI routine and bit banging will be only slightly slower than the hardware implementation.
You can also use the CCS compiler to generate a software SPI for you, check the documentation on #use spi.

Another issue to keep in mind is mentioned in the chip hardware errata sheet. Issue 18 for the A3 hardware revision says that in SPI transmission you shouldn't bit_test the BF flag directly as you are doing. See the linked errata document for possible workarounds.
ok thank you, I guess this could be one thing to think about, I'll try to understand what's wrong and play with the workaround. I'll have a look at the SW SPI to change the SDO pin as well.
Thanks a lot again
thibow



Joined: 11 Apr 2012
Posts: 30

View user's profile Send private message

PostPosted: Wed May 30, 2012 3:02 pm     Reply with quote

Hello, I have switched to a PIC 18F2620 which has UART and SPI pins separated, and I am now on C18 compiler.. which doesn't change much.. I have exactly the same problem, (except that my UART is ok now) and it seems to come from the memory.

Here is what I have CH1 is my clock and CH2 is the SI (I am sending 0x05 to read the status register and reading once)


for this second CH1 is my clock and CH2 is the SO.. I can't figure out why I got these 2 spikes..


Here is my code

Code:
#include <p18F2620.H>
#include <stdio.h>
#include <usart.h>
#include <spi.h>
#include <delays.h>
/*
Pin configuration
----------------------   UART
RX      RC7      pin 18
TX      RC6      pin 17
----------------------   SPI
SDI      RC4      pin 15
SDO      RC5      pin 16
SCK      RC3      pin 14
CE      RB5      pin 7
HOLD      
WP      RA1      pin 3
--------------------   LED
LED0   RA0
*/

#pragma config OSC = HS//
#pragma config PWRT = ON //Power-up RESET Timer Enable A la mise sous tension du µC, lance une temporisation d'environ 72 ms durant laquelle est effectué un RESET interne.
#pragma config WDT = OFF
#pragma config MCLRE = ON //(ON)MCLR pin enabled; RE3 input pin disabled (OFF) RE3 input pin enabled; MCLR disabled
#pragma config STVREN = ON //(ON)Stack full/underflow will cause Reset
#pragma config LVP = OFF //Single-Supply ICSP disabled


#define CE LATAbits.LATA5
#define WP LATAbits.LATA1
#define LED0 LATAbits.LATA0

#define LENGTH 1

unsigned char do_spi(unsigned char byte);

char mychar[LENGTH];
char dummy;
int i=0;

//initialize IO pins
void InitializeIO(void)
{   

   ADCON1 = 0x0F; //disable AD converter functionality on PORTA
   CMCON = 0x07; //disable comparators on PORTA

   TRISAbits.TRISA0 = 0; //make PORTA.0 an output to control LED
   LATAbits.LATA0 = 1; //turn on LED0

   TRISAbits.TRISA1 = 0; //make PORTA.1 an output to control WP
   LATAbits.LATA1 = 1; //Make WP High

   TRISAbits.TRISA5 = 0; //make sure that PORTB.5 OUTPUT since it is CE pin


   TRISCbits.TRISC3 = 0; //make sure that PORTC.3 OUTPUT since it is SCK pin
   TRISCbits.TRISC4 = 1; //make sure that PORTC.4 INPUT since it is SDI pin
   TRISCbits.TRISC5 = 0; //make sure that PORTC.5 OUTPUT since it is SDO pin

   TRISCbits.TRISC6 = 0; //make sure that PORTC.6 OUTPUT since it is TX pin UART
   TRISCbits.TRISC7 = 1; //make sure that PORTC.7 INPUT since it is RX pin UART

   //TRISC = 0x91; //make CSN, CE, SCK, MOSI (SDO), and TX outputs
}

void Initialize(void)
{
   InitializeIO(); //set up IO (directions and functions)
   OpenUSART (USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 51); //open UART with spbrg = 8Mhz/(16*9600)-1
   OpenSPI(SPI_FOSC_16, MODE_00, SMPMID); //open SPI1
   printf("\n\r Init OK");
}

void main (void){
   Initialize();

while(1){

      //********  INITIALIZE THE EEPROM FOR READING ID **************************
      CE=0;       //clear the chip select

      do_spi(0x05);    //Prepare to Read Status

      for (i=0;i<LENGTH;i++)
      {
         mychar[i]=do_spi(0x00);   //read it in data
      }
      
      CE=1;

      printf("\n\r data 1: %c",mychar[0]);   //Show me what you got through UART
      LED0=~LED0;
         Delay10KTCYx(500);
}
}

unsigned char do_spi(unsigned char byte)
{
   SSPBUF = byte;
   
   while(!DataRdySPI());
   
   return SSPBUF;
}   


Here is my output :
Quote:

Init OK
data 1:
data 1:
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 30, 2012 5:12 pm     Reply with quote

1. In your CCS version of the program, why do you use your do_spi()
routine ? Why not use the CCS spi_read() routine, like this:
Code:

mychar[i] = spi_read(0); 


2. When you read the Status register in the memory chip, the power-on
reset default value for the register is 0x0C. But you are attempting to
display it in printf() with "%c". That's for an ASCII character. But you
should be using "%x" so you can properly see the hex value that is returned.

3. Regarding your scope waveforms, are you absolutely sure that you
don't accidentally have the SDO and SDI lines crossed ? If you had the
two SDI pins (on the PIC and Memory chips) connected together, you
might see that signal, due to capacitive pickup from the SCLK line.
thibow



Joined: 11 Apr 2012
Posts: 30

View user's profile Send private message

PostPosted: Wed May 30, 2012 7:59 pm     Reply with quote

Thank you for your suggestion.
I have used read_spi as well, but I remember from another project that there are troubles in CCS library while reading or writing (I don't remember which as there is also a write_spi function that is obviously useless).. so to make sure I wouldn't get any trouble with this I did the way I did in my old project: building my own routine.

About the %c, I was used to do so and then convert the ASCII character in bits to figure out.. I'll give a try tomorrow to %x.

about the SDI and SI (on µC and Memory) together as well as SO and SDO, I have tried to invert them without any luck.. I'll double check this but I am sure I tried both
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu May 31, 2012 2:12 am     Reply with quote

Quote:
What I have in CCS help is v.4
The complete version number has 3 digits after the dot, so something like 4.xxx
You can find this number at the top of the list file (*.lst) in your project directory, or through a link in your Start menu -> PICC -> program version (or similar)

The scope pictures say a lot, the FLASH device is not responding at all and even shows some induced coupling signals.
I think we got bitten by one of the more common errors in PIC programming: on power up many pins are defined to have another function than we expect them to have.

In your original CCS program you were using A2, A3 and A5. These are all configured as analog input on power up. Try adding setup_adc_ports(NO_ANALOGS) to the start of your program.

In the C18 code you do disable the analog ports so this should have solved the problem existing in the CCS code. However.... you are testing this on other hardware. What did you do to the HOLD pin of the SST25VF010A ? It is not in the program any more, so I hope you tied it to 3.3V?

Also you confused me at first:
Code:
CE      RB5      pin 7

and

   TRISAbits.TRISA5 = 0; //make sure that PORTB.5 OUTPUT since it is CE pin
The comments say B5 but the code is still for A5...
Also I miss the code for initializing the CE level to 1, but this should only have a possible effect on the first read.

I don't know the function DataRdySPI, but are you sure this is using one of the suggestions from the errata sheet?

Double check the voltage levels on _all_ pins of the Flash chip. When you measure them, are the levels what you expect them to be?
thibow



Joined: 11 Apr 2012
Posts: 30

View user's profile Send private message

PostPosted: Thu May 31, 2012 8:17 am     Reply with quote

Thank you for your advices. I did a mistake in my comment, but everything was right in the code. I have then implemented the Hold pin, that I didn't before !

I have switched to C18 as I already made a project with spi working fairly well, so I managed to get something trustful at first.

I then did a loop back to test my spi, and it worked well.

PCM Programmer found the problem, it comes from the printf function, I wanted to show a character on the screen, as I usually do, I then convert it into hex, but for an obscure reason it didn't want to convert the hex value into a character. now that I printf a %x instead of a %c I can see my status byte.

I have tried to printf the device id (device id is 49h and manufacturer id is bfh) but it then print me

Quote:
data 1: ffbf

data 2: I


I'll have to worry about the code and not the connections.

Thanks a lot for your help

EDIT: I have created an int array to store the data I get back, and it works well :
int myarray[LENGTH];
printf("\n\r data %d: %x",i,myarray[i]);

output:
Quote:
data 0: bf
data 1: 49
Very Happy
Thank you again
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group