|
|
View previous topic :: View next topic |
Author |
Message |
deperkin
Joined: 04 Feb 2009 Posts: 83 Location: PA
|
30F4013 - NOPROTECT problem |
Posted: Sat Dec 29, 2012 12:37 am |
|
|
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: 19535
|
|
Posted: Sat Dec 29, 2012 2:59 am |
|
|
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
|
MCLR |
Posted: Sat Dec 29, 2012 8:32 am |
|
|
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
|
MCLR |
Posted: Sun Dec 30, 2012 9:42 am |
|
|
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: 19535
|
|
Posted: Sun Dec 30, 2012 2:42 pm |
|
|
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
|
PU |
Posted: Sun Dec 30, 2012 7:29 pm |
|
|
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: 19535
|
|
Posted: Mon Dec 31, 2012 1:47 am |
|
|
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
|
... |
Posted: Mon Dec 31, 2012 8:09 am |
|
|
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: 19535
|
|
Posted: Mon Dec 31, 2012 9:16 am |
|
|
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
|
code |
Posted: Mon Dec 31, 2012 10:26 am |
|
|
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
|
|
Posted: Mon Dec 31, 2012 10:38 am |
|
|
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
|
Fixed |
Posted: Thu Jan 03, 2013 9:28 pm |
|
|
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. |
|
|
|
|
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
|