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 CCS Technical Support

30F4013 - NOPROTECT problem

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



Joined: 04 Feb 2009
Posts: 83
Location: PA

View user's profile Send private message Send e-mail

30F4013 - NOPROTECT problem
PostPosted: Sat Dec 29, 2012 12:37 am     Reply with quote

Hi all,

I am trying to program a dsPIC30F4013 with a pickit2.

I am using software version 4.120 currently.

The only fuses I have set are:

MCLR
EC_IO
NOWDT
NOPROTECT
NOBROWNOUT
NOPUT
NODEBUG

For a little history on the program, I was previously using an 18f4550 and due to size i needed to go up some and had a 30f4013 on me.

The program is merely using a DS1307 RTC (known working code), and several MCP23017 port expanders (known working code).

Everything worked on the 18f4550, and when i switched to the 30f4013 I was able to get it working well for an entire day...

Now when I program the uC I get the pickit2 to show it is protected and verification fails. When I check the Configuration it does show the last 3 bits of FGS as set (1), which would indicate to me it is protected.
But also, my I2C fails to work at all.

Any thoughts as to why?

I have tried a full erase and blank check but it still seems that these FGS bits will stay set.

I did notice this in v4.120.... I cannot seem to remove the 18f4550.h from the tree... I have even rebuilt the project and it still puts it into the tree.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sat Dec 29, 2012 2:59 am     Reply with quote

How is your ICSP header wired?. In particular, what resistor have you got on the MCLR line. Have seen this exact behaviour, when the resistor used on this line was fractionally too low. The Pickit2, could not then raise Vpp to the required level to properly erase the chip.

Look at Pickit2 datasheet, and in particular at sections 3.1, and 3.2. The diode is much more reliable. The '10k' typical value, is too low on some systems.

Best Wishes
deperkin



Joined: 04 Feb 2009
Posts: 83
Location: PA

View user's profile Send private message Send e-mail

MCLR
PostPosted: Sat Dec 29, 2012 8:32 am     Reply with quote

I use a 10k pullup on MCLR and I have PGD and PGC dedicated pins for programming.
I will take a look and see about the diode. I know I have made a setup like that in the past however I only seem to have this problem on the dsPIC.
deperkin



Joined: 04 Feb 2009
Posts: 83
Location: PA

View user's profile Send private message Send e-mail

MCLR
PostPosted: Sun Dec 30, 2012 9:42 am     Reply with quote

I have tried the solution posed in the manual for the pickit2. It doesnt seem to help... now I am thinking it is another issue with the MCP23017's.

I have 8 of them wired up and I use A1 as a reset pin. If I disconnect the reset pin and just pull all of the resets to high using a resistor than everything works okay.

Looking at the datasheet however (page 7) I should be using the reset. This makes no sense to me.

I use:
Code:

void ResetMCP23X17(){
 output_low(IORESET);
 delay_us(100);
 output_float(IORESET);
}

for my reset function.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sun Dec 30, 2012 2:42 pm     Reply with quote

Er, Do you have the pull up resistor on the line when you use the software operation?. You need it. Otherwise the RESET line is floating, and could do anything. Date sheet 'must be externally biased'....

Best Wishes
deperkin



Joined: 04 Feb 2009
Posts: 83
Location: PA

View user's profile Send private message Send e-mail

PU
PostPosted: Sun Dec 30, 2012 7:29 pm     Reply with quote

Yes I have tried a single 10k pullup on this pin which is wired to all the 8 reset pins of the MCP .

On one of th MCPs I have LEDs on one of the ports. and with just pullups I can get a count going (simple loop in the program) which I also send as in input to another MCP.

On the LCD I am displaying both output and input...

without the pullups, and using A1 on the uC for the reset I get all 8 LEDs to just blink once and get no input on the next MCP.

The schematic is almost exactly like:

[img]http://www.flickr.com/photos/91759188@N08/8328327544/[/img]
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Dec 31, 2012 1:47 am     Reply with quote

You keep saying 'without the pullups'. The point is that there must be a pullup on the lines, when you are operating it from the PIC, or you need to use:
Code:

void ResetMCP23X17(){
 output_low(IORESET);
 delay_us(100);
 output_high(IORESET);  //make the PIC drive the line high
}

The line must be pulled high by _something_.

Your picture flags as 'private'.

Best Wishes
deperkin



Joined: 04 Feb 2009
Posts: 83
Location: PA

View user's profile Send private message Send e-mail

...
PostPosted: Mon Dec 31, 2012 8:09 am     Reply with quote

yes sorry for the confusion.

I have 3 senarios:

1) (1)-10k pullup to A1, with A1 wired to each MCP reset.
2) (8)-10k pullup's on each MCP, without using A1 for reset function.
3) (8)-10k pullup's on each MCP, with A1 wired to each MCP reset.

I know that #3 cannot be right. I only get #2 to work. #1 does not seem to work at all but should be the configuration that does work.

maybe this image will work better:
https://picasaweb.google.com/lh/photo/7t5Ul1bFHpA9MR92CAvLRLuM1AnbSS1d_whfZsoNDaM?feat=directlink


Last edited by deperkin on Thu Jan 03, 2013 9:32 pm; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Dec 31, 2012 9:16 am     Reply with quote

Do you pause after wake up, before calling the reset function?.

I'd suspect the PIC was waking before the MCP chips have completed their POR. '1' should be fine. In figure 2-2 of the data sheet, no time is given for the gap between Vdd rising, and the internal reset going high. The software reset is shown coming after this.....


Best Wishes
deperkin



Joined: 04 Feb 2009
Posts: 83
Location: PA

View user's profile Send private message Send e-mail

code
PostPosted: Mon Dec 31, 2012 10:26 am     Reply with quote

here is my code:

Code:
#include <TEST_BENCH.h>

//-------------------------FILES INCLUDED---------------------------------------
#include <PINOUT.c>          // general pinout
#include <Flex_LCD420.c>     // LCD driver   
#include <DS1307.c>          // driver used for real-time clock/calender
#include <MCP23017.c>        // driver used for port expander(s)
//------------------------PRE-CALLS TO FUNCTIONS--------------------------------
void initialize();
//------------------------EXTERNAL INTERRUPT ROUTINES---------------------------

//------------------------MAIN FUNCTION-----------------------------------------
void main(void){
int8 x,y=0;
byte text;
initialize();
lcd_clear();
delay_ms(2000);
//ds1307_get_time(hours,minutes,seconds);
delay_ms(300);
//------------------------MAIN LOOP---------------------------------------------
x = 0x00;
   while(TRUE){  // prevents uC from going to sleep
     
      delay_ms(100);
      ds1307_get_time(hours,minutes,seconds);
      delay_ms(100);
      lcd_gotoxy(6, 1);
      printf(lcd_putc,"TIME: %02d:%02d:%02d  ",hours,minutes,seconds);  // Optional message
      delay_ms(100);
      Write23X17(GPPUA, 0xFF, 0x00);
      delay_ms(40);
      Write23X17(GPIOA, ~x, 0x00);
      delay_ms(40);
      Write23X17(GPIOA, x, 0x04);
      delay_ms(40);
      y=Read23X17(GPIOB, 0x01);
      delay_ms(200);
      ResetMCP23X17();
      delay_ms(40);
      lcd_gotoxy(1, 2);
      printf(lcd_putc,"CNT:0x%2x",~x); // Optional message
      delay_ms(40);
      lcd_gotoxy(1, 4);
      printf(lcd_putc,"VAL:0x%2x at: 0x%2x",y,0x01); // Optional message
      delay_ms(40);
      x++;
      delay_ms(40);
   }
}

void initialize(){
   int i,j=0;
   APlog = 0;
   delay_ms(2000);   //this delay is required.
//---------------------------LCD Setup------------------------------------------
// The lcd_init() function should always be called once,
// near the start of the program.
   lcd_init();   // Initialize the LCD
   lcd_clear();  // Clear the LCD
   delay_ms(50);
//---------------------------A2D Setup------------------------------------------
   //setup_adc_ports(NO_ANALOGS);  // Set pins for Analog-Digital(A2D) Conversions
   //setup_adc(ADC_CLOCK_INTERNAL);// Set A2D clock
   //set_adc_channel(0);           // Set inital A2D pin (A0)
//---------------------------I2C Setup-----------------------------------------
   ds1307_init();                // Initialize the Real-Time Clock/Calender
   InitMCP();
//---------------------------PWM Setup------------------------------------------
write_eeprom(0x000, 0xCC);
   //setup_ccp1(CCP_PWM);          //Pulse-Width Modulation Pin for DC motor
//---------------------------Timer(s) Setup-------------------------------------
   //setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //timer 1 used for tachometer
   //setup_ccp1(CCP_CAPTURE_RE); //setup compare & capture for tachometer reading
   //setup_timer_2(T2_DIV_BY_1, 100, 1); //timer 2 used for Pulse-Width Modulation
//---------------------------CODE RAN ONLY ONCE:--------------------------------
while(read_eeprom(INIT_DONE_FLAG_ADDR) != INIT_DONE) {
   // Put initialzation code below for first time use:
   // (i.e set time/date, initial variables, etc...)
   day = month = dow = hours = minutes = seconds = 1;
   year = 10;
   ds1307_set_date_time(day,month,year,dow,hours,minutes,seconds);
//------------------------------------------while the cpu is in 'first run' mode
   if(read_eeprom(INIT_DONE_FLAG_ADDR) != INIT_DONE){
   }
   lcd_clear();
   lcd_gotoxy(0,1);
   printf(lcd_putc,"Initialization Done!");  // Optional message
   delay_ms(1000);
//------------------------------------------------Then reset the microcontroller
   lcd_clear();
   lcd_gotoxy(4,1);
   printf(lcd_putc,"Starting now.");  // Optional message
   delay_ms(300);
   lcd_gotoxy(8,2);
   printf(lcd_putc," .");  // Optional message
   delay_ms(300);
   lcd_gotoxy(8,3);
   printf(lcd_putc," .");  // Optional message
   delay_ms(300);
   lcd_gotoxy(8,4);
   printf(lcd_putc," .");  // Optional message
   delay_ms(300);
   write_eeprom(INIT_DONE_FLAG_ADDR, INIT_DONE);
   reset_cpu();            // reset
  }
   lcd_clear();
   for (i=4; i>=1; i--) {
     lcd_gotoxy(j,i);
     printf(lcd_putc, "...");  // Optional message
     delay_ms(300);
     j = j+1;
     }
   lcd_clear();
   delay_ms(300);
}


and TEST_BENCH.h:
Code:
#include <18F4550.h>
//--------------------------FUSES-----------------------------------------------
#fuses MCLR           // enable master reset pin
#fuses XT             // enable clock speed <=4 MHzKOUT
#fuses NOWDT          // disable Watch-Dog Timer
#fuses NOPROTECT      // disable memory protection (TEMPORARY)
#fuses NOBROWNOUT     // disable reset on brownout
#fuses NOPUT          // disable Power-UP timer
#fuses NOLVP          // disable low voltage protection
#fuses NODEBUG        // No Debug mode for ICD
//--------------------------CLOCK SETUP-----------------------------------------
#device *=16
#device adc = 8       // 8-bit resolution for Analog-Digital Conversion
#ocs 250 kHz          // internal clock set to run at 500 KHz
//#ocs OSC_CRYSTAL
#use delay(crystal=4000000),clock=1000000)
//--------------------------GLOBAL-VARIABLES------------------------------------
BYTE seconds,minutes,hours,day,month,year,dow, APlog;
#byte   timer0low = 0xfd6      // memory location used for RTCC interrupt flag
#define BytePtr(var, offset) (char *)(&var + offset) // pointer
//--------------------------EEPROM ADDRESSING-----------------------------------
#rom 0x2100 = {0xFF}                // EEprom address for 18F-series PICs
#define INIT_DONE  0xDD     //flag to signify that initialzation routine is done
#define INIT_DONE_FLAG_ADDR 0x034     // address for storing initialization state
#define TOTALHOURS_DEFAULT_ADDR 0x040 // eeprom address for storing Filter Hours
#define TOTALMINS_DEFAULT_ADDR 0x042  // eeprom address for storing Filter Hours
#define S_DEFAULT_ADDR 0x066  // eeprom address for storing Temporary Seconds
#define M_DEFAULT_ADDR 0x064  // eeprom address for storing Temporary Minutes
#define H_DEFAULT_ADDR 0x060  // eeprom address for storing Filter Hours
//---------------------PORT EXPANDER ADDRESSES----------------------------------
#define MCP0      0
#define MCP1      1
#define MCP2      2
#define MCP3      3
#define MCP4      4
#define MCP5      5
#define MCP6      6
#define MCP7      7

typedef struct TestInput{
   int8     Count;   
   int8     DecAddr;
   int1     PortName;
   char     GpioMask[3];
   char     Connector[4]; 
   char     Cavity[3];
   char     Circuit[5];
   char     Description[33];
};

typedef struct TestOutput{
   int8     Count;   
   int8     DecAddr;
   int1     PortName;
   char     GpioMask[3];
   char     Connector[4]; 
   char     Cavity[3];
   char     Circuit[5];
   char     Description[33];
};


for the MCP23017.c:
Code:
#include <MCP23017.h>

void ResetMCP23X17(){
 delay_us(200);
 output_high(IORESET);
 delay_us(200);
 output_float(IORESET);
 delay_us(200);
}

//****************************************
//   I2CWriteByte(unsigned char addr, unsigned char byte)
//   Writes a byte to the 23017
//****************************************
void I2CWriteByte(unsigned char reg, unsigned char data, unsigned char addr)
{
   i2c_start();
   i2c_write( ControlByte | WrtCmd | addr << 1 );
   i2c_write( reg );
   i2c_write( data );
   i2c_stop();
}
//****************************************
//   I2CWriteByte(unsigned char addr, unsigned char byte)
//   Writes a byte to the 23017
//****************************************

long int I2CReadByte(unsigned int reg, unsigned int addr)
{
   int num;

   i2c_start();
   i2c_write( ControlByte | WrtCmd  | addr << 1 );     // address MCP23017 and set to write operation
   i2c_write(reg);       // write number of register to read
   i2c_start();          // restart
   i2c_write( ControlByte | RdCmd  | addr << 1 );      // address MCP23017 and set to read operation
   num = i2c_read(0);    // read register
   i2c_stop();
   delay_ms(100);
   ResetMCP23X17();
   return(num);

}
/*************************************************************
   Function Name:  Write23X17                                         
   Return Value:   void                                           
   Parameters:     Register address, Data                   
   Description:    Writes a 23X17 register. I2C or SPI is in
                   global byte     
**************************************************************/

void Write23X17(unsigned char reg, unsigned char data, unsigned char addr)
{
   if(SerialMode == I2CMODE)    //If 23017 selected
      I2CWriteByte(reg, data, addr);  //
   else                         //Else MCP23S17 is selected
     //SPIWriteByte(reg, data); //
     break;
}

long int Read23X17(unsigned char reg, unsigned char addr)
{
   unsigned int data;
   if(SerialMode == I2CMODE)    //If 23017 selected
      data = I2CReadByte(reg, addr);  //
   else                         //Else MCP23S17 is selected
     //SPIWriteByte(reg, data); //
     break;
     return (data);
}

void InitMCP( void )
{
  //Configure 23017
  //Write23X17(GPPUA, 0x00,0x00);       // Pullups
  //Write23X17(IPOLA, 0xFF,0x00);     //All ins
  //Write23X17(IPOLB, 0xFF,0x00);     //All ins
  Write23X17(IOCONA, 0x40 | 0x0A,0x00);     //
  Write23X17(IOCONB, 0x40 | 0x0A,0x00);
  Write23X17(IODIRA, 0x00,0x00);     //All outs
  Write23X17(IODIRB, 0x00,0x00);     //All outs
  Write23X17(IOCONA, 0x40 | 0x0A,0x01);     //
  Write23X17(IOCONB, 0x40 | 0x0A,0x01);
  Write23X17(IPOLA, 0xFF,0x01);     //All ins
  Write23X17(IPOLB, 0xFF,0x01);     //All ins   
  Write23X17(IODIRA, 0xFF,0x01);     //All ins
  Write23X17(IODIRB, 0xFF,0x01);     //All ins
  Write23X17(IOCONA, 0x40 | 0x0A,0x04);     //
  Write23X17(IOCONB, 0x40 | 0x0A,0x04);
  Write23X17(IODIRA, 0x00,0x04);     //All outs
  Write23X17(IODIRB, 0x00,0x04);     //All outs
}


and MCP23017.h:

Code:
/**********************************************************
MCP23017.h
#defines are with IOCON.BANK = 0
***********************************************************/

#define I2CMODE 1
#define SPIMODE 0
#define WrtCmd  0
#define RdCmd   1
 
#define IODIRA      0x00
#define IODIRB      0x01
#define IPOLA       0x02
#define IPOLB       0x03
#define GPINTENA    0x04
#define GPINTENB    0x05
#define DEFVALA     0x06
#define DEFVALB     0x07
#define INTCONA     0x08
#define INTCONB     0x09
#define IOCONA      0x0A
#define IOCONB      0x0B
#define GPPUA       0x0C
#define GPPUB       0x0D
#define INTFA       0x0E
#define INTFB       0x0F
#define INTCAPA     0x010
#define INTCAPB     0x011
#define GPIOA       0x012
#define GPIOB       0x013
#define OLATA       0x014
#define OLATB       0x015

#define HRDWADD 0 // device hard address

unsigned char AddrPins = HRDWADD << 1;
unsigned char SerialMode = I2CMODE;
unsigned char ControlByte = 0x40;


for the pinout.c:
Code:
////////////////////////////////////////////////////////////////////////////////
///                             PINOUT.C                                     ///
///                                                                          ///
///      Description: This module is used for all pin reservations           ///                               
///                                                                          ///
///                                                                          ///
////////////////////////////////////////////////////////////////////////////////

/*-------4x20 LCD definitions-------*/
#define LCD_RS        PIN_E0
#define LCD_RW        PIN_E1
#define LCD_E         PIN_E2
#define LCD_DB4       PIN_D4
#define LCD_DB5       PIN_D5
#define LCD_DB6       PIN_D6
#define LCD_DB7       PIN_D7

/*-------1-wire definitions-------*/   
//ONE_WIRE_PIN is used for DS1820 Temp Sensor
//#define ONE_WIRE_PIN  PIN_D2
/*-------RS232 Communications definitions-------*/
#define RS232_XMIT    PIN_C6   //RS232 serial transmit
#define RS232_RCV     PIN_C7   //RS232 serial receive
#use rs232(baud=4800,xmit=RS232_XMIT,rcv=RS232_RCV,parity=N,bits=8,stream=COMP)
/*-------I2C Communications definitions-------*/
#define RTC_SDA       PIN_B0
#define RTC_SCL       PIN_B1
//#use i2c(MULTI_MASTER, sda=RTC_SDA, scl=RTC_SCL, address = 0x08)
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL,FORCE_SW,SLOW)
//#use i2c(master, sda=RTC_SDA, scl=RTC_SCL, address = 0x08,FORCE_SW,SLOW)
/*-------Button definitions-------*/

/*-------OTHER definitions-------*/
//#define IGNITION      PIN_A0 
#define IORESET       PIN_A1 


thanks again for the help Ttelmah.
deperkin



Joined: 04 Feb 2009
Posts: 83
Location: PA

View user's profile Send private message Send e-mail

PostPosted: Mon Dec 31, 2012 10:38 am     Reply with quote

BTW... i did switch back to the PIC4550 for now.

I didnt want to introduce other obstacles before I got everything working as planned.
deperkin



Joined: 04 Feb 2009
Posts: 83
Location: PA

View user's profile Send private message Send e-mail

Fixed
PostPosted: Thu Jan 03, 2013 9:28 pm     Reply with quote

I just tried to increase my delay from :

Code:
void ResetMCP23X17(){
 delay_us(200);
 output_high(IORESET);
 delay_us(200);
 output_float(IORESET);
 delay_us(200);


to:

Code:
void ResetMCP23X17(){
 delay_us(200);
 output_high(IORESET);
 delay_us(200);
 output_float(IORESET);
 delay_us(500);
}


And this fixed it! You are correct as usual Ttelmah.

Thanks for your help.
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