|
|
View previous topic :: View next topic |
Author |
Message |
rwskinner
Joined: 08 Dec 2006 Posts: 125 Location: Texas
|
18F4550 and SW I2C Problem |
Posted: Wed Jan 27, 2010 10:40 pm |
|
|
I'm having to use software I2C because of the shared pin for RS232. At any rate, I have a little test program (HID Example) that loops, and also writes to a MCP23008 Port Expander. The port Expander responds properly for the first few seconds then quits.
Here is the code, and help would be most appreciated.
Main....
Code: |
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(MASTER,SDA=PIN_B3, SCL=PIN_B1)
#DEFINE USB_HID_DEVICE TRUE
#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT
#define USB_EP1_TX_SIZE 40
#define USB_EP1_RX_ENABLE USB_ENABLE_INTERRUPT
#define USB_EP1_RX_SIZE 2
#define USB_CON_SENSE_PIN PIN_B2
#include <pic18_usb.h>
#include "csi_desc_hid.h"
#include <usb.c>
#include "MCP23008-1.c"
// Configure the Test I/O
#define LED1 PIN_A5
#define LED2 PIN_B4
#define LED3 PIN_B5
#define BUTTON PIN_A4
#define LED_ON output_low
#define LED_OFF output_high
void main()
{
int8 z,cnt;
int8 out_data[40];
int8 in_data[2];
int16 send_timer=0;
int16 i;
unsigned char DO_Data= 0;
//Clear Array
for (i=0; i<= 40; i++)
out_data[i] = 0;
LED_OFF(LED1);
LED_OFF(LED2);
LED_OFF(LED3);
printf("Initializing Expander port\r\n");
init_DO(); //Test Expander
printf("Initializing USB port\r\n");
usb_init();
printf("\r\n");
#if defined(AN0)
setup_adc_ports(AN0);
#elif defined(AN0_AN1_AN3)
setup_adc_ports(AN0_AN1_AN3);
#else
#error CONFIGURE ADC PORTS SO WE CAN READ CHANNEL 0
#endif
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
cnt = 0;
while (TRUE)
{
usb_task();
if (DO_Data > 128)
DO_Data = 1;
else
DO_Data++;
printf("Writing %u to MCP \r\n",DO_Data);
write_mcp(0x40, _GPIO, DO_Data );
if (usb_enumerated())
{
if (!send_timer)
{
send_timer=200; //Set timer Cnt for 200ms
cnt++;
if (cnt >= 5) //Every 200ms x 5 = 1000ms, send ADC + DIO
{ cnt = 0;
out_data[0] = 1; //Packet # 1 for ADC + DIO
//Bogus ADC Info - Will be Hi - Lo each chan of ADC
z = 1;
for (i=1; i<= 16; i++)
{ out_data[z] = make8(i+20,0);
z++;
out_data[z] = make8(i+20,1);
z++;
} //End for
out_data[33] = !input(BUTTON); //Digital Inputs
out_data[34] = in_data[0]; //Digital Outputs
if (usb_put_packet(1, out_data, 35, USB_DTS_TOGGLE))
printf("\r\n<-- Sending ADC + DIO bytes");
else
printf("\r\n Error Sending ADC + DIO bytes");
}
else //every 200ms only send DIO
{
out_data[0] = 2; //Packet #2 for DIO Only
for (i=1; i<= 32; i++)
out_data[i] = 0; //Send Zero's for ADC
out_data[33] = !input(BUTTON); //Digital Inputs
out_data[34] = in_data[0]; //Digital Outputs
if (usb_put_packet(1, out_data, 35, USB_DTS_TOGGLE))
printf("\r\n<-- Sending DIO bytes");
else
printf("\r\n Error Sending DIO bytes");
} //End cnt and Else
} //End of SendTimer
if (usb_kbhit(1))
{
usb_get_packet(1, in_data, 2);
printf("\r\n--> Received data: 0x%X 0x%X",in_data[0],in_data[1]);
if (in_data[0]) {LED_ON(LED2);} else {LED_OFF(LED2);}
if (in_data[1]) {LED_ON(LED3);} else {LED_OFF(LED3);}
}
send_timer--;
delay_ms(1);
} //End of Enumerated
} //End of While True
} //End of Main
|
Here is the MCP Lib.....
Code: |
#define DO_WRITE 0x40
#define DO_READ 0x41
#define _IODIR 0x00
#define _IPOL 0x01
#define _GPINTEN 0x02
#define _DEFVAL 0x03
#define _INTCON 0x04
#define _IOCON 0x05
#define _GPPU 0x06
#define _INTF 0x07
#define _INTCAP 0x08
#define _GPIO 0x09
#define _OLAT 0x0A
void write_MCP(unsigned int8 I2C_Addr, unsigned int8 cmd, unsigned int8 data)
{
i2c_start();
i2c_write(I2C_Addr);
i2c_write(cmd);
i2c_write(data);
i2c_stop();
}
void init_DO()
{
Delay_ms(100);
write_MCP(DO_WRITE, _IODIR, 0x00);
write_MCP(DO_WRITE, _GPIO, 0x00);
}
|
|
|
|
mskala
Joined: 06 Mar 2007 Posts: 100 Location: Massachusetts, USA
|
|
Posted: Thu Jan 28, 2010 7:56 am |
|
|
I don't understand. I use 4550 with both hardware I2C and hardware UART, they do not share any pins on the QFP and I couldn't see anything in the datasheet for the other packages either. |
|
|
rwskinner
Joined: 08 Dec 2006 Posts: 125 Location: Texas
|
|
Posted: Thu Jan 28, 2010 8:19 am |
|
|
Sorry, I stated the wrong thing. MSSP (SPI) shares a pin with the RS232.
At any rate, I'm using Int0 or RB0 for something else.
It has to do with RB3 specifically because if I use a different pin it works.
I added:
Setup_ccp2(CCP_OFF);
Setup_ADC(ADC_OFF);
Set_TRIS_B(0x0F); //0000 1111
To try to make sure RB3 is Digital Input but still no luck. It runs approx 5 seconds then quits. |
|
|
Ttelmah Guest
|
|
Posted: Thu Jan 28, 2010 8:22 am |
|
|
Pin RC7, is both SDO, and serial RX.
It is 'silly'. On the 28pin package, it makes sense, but it is surprising there isn't an alternative pin available with the 40/44 pin versions....
To the original question:
What compiler version?.
What silicon revision?.
Does everything else stay operational?.
I have seen problems with the 4550, which I think tie to the USB erratum regarding sending extra data when a control transfer takes place. I think the code supplied then gets confused, and seems to interfere with the main program flow. I switched to one of the J50 chips instead, and the problem disappeared. I also managed to get it working OK, by searching the driver files, for the references to UCON_PKTDIS, and moving these to the start of the routines using them...
Best Wishes |
|
|
rwskinner
Joined: 08 Dec 2006 Posts: 125 Location: Texas
|
|
Posted: Thu Jan 28, 2010 8:30 am |
|
|
I'm using PCH 4.093
I can remove SDA from B3 and put it on just about any other pin and it works fine. So it means I'm missing some setup on B3 I think. |
|
|
Ttelmah Guest
|
|
Posted: Thu Jan 28, 2010 8:45 am |
|
|
What 'puzzles' me, is that you are using I2C, not SPI. I2C, has the hardware available, on B0/B1, fine. It is only the SPI feature of the MSSP, that clashes. I think this is what Rwskinner was pointing out.
I must admit I had assumed you were using SPI, which does have the conflict......
I's add:
NOPBADEN
CCP2C1
To the fuses, but both shouldn't be causing problems with the setup as shown.
Best Wishes |
|
|
rwskinner
Joined: 08 Dec 2006 Posts: 125 Location: Texas
|
|
Posted: Thu Jan 28, 2010 9:09 am |
|
|
Okay, the board I'm dealing with has 2 MCP23008 Expanders using I2C off PortsB1 (SCLK) & B3 (SDA).
The Int from one of the expanders is hooked to B0, which was the only External Int available (INT0).
It has a SPI ADC using SCLK shared with RB1, SDI is shared with RB3, C/S is RD5, and SDO is RD4.
This is because RS232 is hardware driven from C6 and C7.
I have what I have.... The RS232 requirement messed everything up for Hardware SPI, and having only 1 pin left for the external interrupt messed up my Hardware I2C.
In the long run, I may have been better off using Software RS232 and Hardware for SPI and I2C, but since this is a modbus slave, we wanted to make sure the RS232 could be interrupt driven. |
|
|
rwskinner
Joined: 08 Dec 2006 Posts: 125 Location: Texas
|
|
Posted: Thu Jan 28, 2010 9:33 am |
|
|
Found the problem. RB3 is hooked to the ICD Connector. With the ICD-64 disconnected then I2C works fine. That's a little inconvienient. |
|
|
Ttelmah Guest
|
|
Posted: Thu Jan 28, 2010 9:51 am |
|
|
I must admit, I think I'd have tried to sort the layout out differently. Used B0/B1 for the I2C (hardware) B2 for the interrupt, C6/C7 for the RS232, only leaving the SPI having to use software.
However, except for the CCP remapping, there is nothing 'special' about B3, so it should work.
Your code is incomplete, so we can't see what might be going wrong. The only real way to debug, is going to be to trim it down section by section till you find what is actually causing the problem. I'd add 'errors' to the RS232 declaration (this should _always_ be used when using the serial hardware, unless you are implementing your own error check and recovery), and with the long delays in the code, I can easily believe that the RS232 is getting hung. Could this cause an apparent lock up in other parts of the code?.
Best Wishes |
|
|
|
|
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
|