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

MCP23S17 interfacing with SPI with controller PIC18F8722
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
NEW_GUY



Joined: 31 Aug 2012
Posts: 10
Location: India

View user's profile Send private message

MCP23S17 interfacing with SPI with controller PIC18F8722
PostPosted: Fri Aug 31, 2012 4:42 am     Reply with quote

Hi guys,

I am wondering if anyone could help me in my problem,

- There is a driver provided by the CCS compiler for MCP23S17. I am not sure how to use it for communication on SPI.
- Also there are several API for initialization and operations on SPI, will they be suitable for the same controller ?
- Currently interfacing the 16x2 LCD module to it (as I am using PIC18f8722 development board).

I can not even initialize the LCD.
Your help is greatly appreciated.

Thank you.
temtronic



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

View user's profile Send private message

PostPosted: Fri Aug 31, 2012 5:13 am     Reply with quote

First do not try to get the MCP working yet...your priority is to get the LCD 'up and running'.

Post the manufacturer / make/model info of the developement board or a link to it.

Did the board come with any test software like 'Hello World' or 'blinking LED'. Does the mfr have a forum/help/FAQ site?

Is the LCD part of the board or did you add it ?

When you say it doesn't work what are the symptoms? Single row of black boxes ,wrong data on screen, totally 'dead'?

Generally speaking it's a good idea to first get an LED to blink at 1Hz to confirm the board/PIC work..then connect/test an LCD ( use the flex_driver)..then add/test other peripherals..

This way you know the hardware works in a known manner and can always go back to a working configuration.

The more information you give us the better (and faster) we can try to help you.

hth
jay
sseidman



Joined: 14 Mar 2005
Posts: 159

View user's profile Send private message

PostPosted: Fri Aug 31, 2012 9:21 am     Reply with quote

temtronic wrote:
First do not try to get the MCP working yet...your priority is to get the LCD 'up and running'.

Post the manufacturer / make/model info of the developement board or a link to it.

Did the board come with any test software like 'Hello World' or 'blinking LED'. Does the mfr have a forum/help/FAQ site?

Is the LCD part of the board or did you add it ?

When you say it doesn't work what are the symptoms? Single row of black boxes ,wrong data on screen, totally 'dead'?

Generally speaking it's a good idea to first get an LED to blink at 1Hz to confirm the board/PIC work..then connect/test an LCD ( use the flex_driver)..then add/test other peripherals..

This way you know the hardware works in a known manner and can always go back to a working configuration.

The more information you give us the better (and faster) we can try to help you.

hth
jay


Great advice! The only thing I would change is to offer the option of using a serial port instead of the LCD -- less resources, no external drivers, you don't have to make your output fit on two lines, the output doesn't disappear when the next output comes along, and you always have a terminal available as you're programming (well, if you have a box w/ a serial port or a serial to usb converter). You might need to have a serial port driver, if your converter doesn't support straight TTL, but once you have this built, you're done and ready for anything.
NEW_GUY



Joined: 31 Aug 2012
Posts: 10
Location: India

View user's profile Send private message

PostPosted: Mon Sep 03, 2012 2:31 am     Reply with quote

temtronic wrote:
First do not try to get the MCP working yet...your priority is to get the LCD 'up and running'.

Post the manufacturer / make/model info of the development board or a link to it.

Did the board come with any test software like 'Hello World' or 'blinking LED'. Does the mfr have a forum/help/FAQ site?

Is the LCD part of the board or did you add it ?

When you say it doesn't work what are the symptoms? Single row of black boxes, wrong data on screen, totally 'dead'?

Generally speaking it's a good idea to first get an LED to blink at 1Hz to confirm the board/PIC work..then connect/test an LCD ( use the flex_driver)..then add/test other peripherals..

This way you know the hardware works in a known manner and can always go back to a working configuration.

The more information you give us the better (and faster) we can try to help you.

hth
jay


Hey temtronic , Thanks.
I really appreciate your efforts and basic explanations. Thank you for that again.

What is happening actually the development board is from Microchip { PIC18F8722 PICDEM (TM) board. }
It previously had a test code in it, which runs texts WELCOME on LCD. But as i have used it for several months for other firmware development, i didnt need LCD. So that's why i am not aware where i could find that source code.

Actually on the board, LCD is connected only thru the MCP23S17 which is on SPI bus obviously, so i cant even test it by sending my data to it as i am not able to initialize my MCP23S17.

I just needs guidelines/methods/procedures which will follow the correct sequence for execution in case of MCP23S17 initialization.

Regards
temtronic



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

View user's profile Send private message

PostPosted: Mon Sep 03, 2012 6:08 am     Reply with quote

ah..now the light comes on ! The LCD is not attached to the PIC but rather to the SPI I/O expander chip.....( I downloaded the manual...)

I would suggest you download the MCP23S17 datasheet and see what the command/sequence/data is required to 'talk' to the device. Most LCD units share a common command/data set so once you figure out if it's in 4 bit or 8 bit mode, you can reverse engineer the code the PIC uses to send through the MCP23S17 to the LCD module.

It's not that hard as you have all the pieces of the puzzle including schematics !

I don't have that uChip dev board, perhaps others do and have already done the 'exercise' for you. Perhaps searching this forum will find a similar thread ?

hth
jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 03, 2012 5:20 pm     Reply with quote

Here's a thread where someone wrote an LCD driver for the C18 compiler
for that board:
http://www.microchip.com/forums/m423849.aspx
But if you're a newbie to the C language or to CCS, you're probably not
going to be able to convert that code to CCS.
NEW_GUY



Joined: 31 Aug 2012
Posts: 10
Location: India

View user's profile Send private message

PostPosted: Mon Sep 03, 2012 10:23 pm     Reply with quote

PCM programmer wrote:
Here's a thread where someone wrote an LCD driver for the C18 compiler
for that board:
http://www.microchip.com/forums/m423849.aspx
But if you're a newbie to the C language or to CCS, you're probably not
going to be able to convert that code to CCS.


Thank you.
NEW_GUY



Joined: 31 Aug 2012
Posts: 10
Location: India

View user's profile Send private message

PostPosted: Tue Sep 04, 2012 12:57 am     Reply with quote

temtronic wrote:
ah..now the light comes on ! The LCD is not attached to the PIC but rather to the SPI I/O expander chip.....( I downloaded the manual...)

I would suggest you download the MCP23S17 datasheet and see what the command/sequence/data is required to 'talk' to the device. Most LCD units share a common command/data set so once you figure out if it's in 4 bit or 8 bit mode, you can reverse engineer the code the PIC uses to send through the MCP23S17 to the LCD module.

It's not that hard as you have all the pieces of the puzzle including schematics !

I don't have that uChip dev board, perhaps others do and have already done the 'exercise' for you. Perhaps searching this forum will find a similar thread ?

hth
jay



Hey temtronic,

I just come across the main problem,
- according to my knowledge SPI is working fine,
- MCP23S17 is getting init
- but the main problem is LCD,

This LCD is not the normal HITACHI LCD, its from lumex (LCM-SO1602 DTR/M), i never worked on this, so if my code is correct then it must be problem with command sequence while initializing the LCD.

If you can help me finding the command summary for this LCD that wil be great help. FYI, I have searched most possible places on the internet where I could find the info, but I couldn't...

Thank you and regards.
NEW_GUY



Joined: 31 Aug 2012
Posts: 10
Location: India

View user's profile Send private message

PostPosted: Wed Sep 05, 2012 11:24 pm     Reply with quote

I got my code working...
somehow with help of this forum...

There was the mistake in LCD commands, as it is not usual LCD from hitachi.

I am going to post my code here for the reference very soon.
Thank you.
Bill24



Joined: 30 Jun 2012
Posts: 45

View user's profile Send private message

PostPosted: Thu Nov 01, 2012 10:41 am     Reply with quote

NEW_GUY wrote:
I got my code working...
somehow with help of this forum...

There was the mistake in LCD commands, as it is not usual LCD from hitachi.

I am going to post my code here for the reference very soon.
Thank you.


I'd be grateful to see your solution.
Bill24



Joined: 30 Jun 2012
Posts: 45

View user's profile Send private message

PostPosted: Tue Nov 06, 2012 2:40 am     Reply with quote

NEW_GUY wrote:
PCM programmer wrote:
Here's a thread where someone wrote an LCD driver for the C18 compiler
for that board:
http://www.microchip.com/forums/m423849.aspx
But if you're a newbie to the C language or to CCS, you're probably not
going to be able to convert that code to CCS.


Thank you.


Here is a conversion of the code running on a PIC18 Explorer board.


Code:
#include <18F66K80.h>

#device ICD=TRUE
#device adc=16
#device ICD=TRUE
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES VREGSLEEP_SW             //Ultra low-power regulator is enabled
#FUSES INTRC_LP                 //LF-INTOSC in Low-Power mode during Sleep
#FUSES SOSC_DIG                 //Digital mode, I/O port functionality of RC0 and RC1
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES PUT                      //Power Up Timer
#FUSES BORM_LOW                 //Low-power BOR
#FUSES WDT_NOSLEEP              //Watch Dog Timer, disabled during SLEEP
#FUSES DEBUG                    //Debug mode for use with ICD

#use delay(int=8000000,RESTART_WDT)
#USE FAST_IO(a)
#USE FAST_IO(c)
#USE FAST_IO(c)
#USE FAST_IO(f)

// SPI registers
#word LCD_SSPBUF     =  0x0FC9   // SPI1BUF
#word LCD_SPICON1    =  0x0FC6   // SPI1CON1
#word LCD_SPISTAT    =  0x0FC7   // SPI1STAT
#word LCD_SPI_IF     =  0x0F9E   // PIR1
#define SSP1IF_BIT        0x03

#define LED PIN_D0

// ----------- PICDEM HPC Explorer 18 LCD defines
#define   LCD_CS            (PIN_A2)          //LCD chip select
#define   LCD_RST            (PIN_F6)          //LCD Reset
#define   LCD_CLK            (PIN_C3)      
#define   LCD_SI             (PIN_C5)       


// ---------------------------------------------------

// Forward declarations
// PICDEM HPC Explorer 18 LCD controlled via MCP923S17
void LCDBusy(void);
void WritePortA(char b);
void WritePortB(char b);
void d_write(char b);
void i_write(char b);
void LCDLine_1(void);
void LCDLine_2(void);
void LCDClear(void);
void InitWrite(char b);
void InitPortA_SPI(char b);
void InitPortB_SPI(char b);
void InitSPI(void);
void LCDInit(void);

unsigned char LCDText[16*2+1];


void main(void)
{
   int tmpcnt = 0;

    // Set PIN_A2 (chip sel) to output.
    set_tris_a(0x0FB);

    // Set Pin_C3 (clk ) and pin_C5 (si) to output.
    set_tris_c(0x0D7);

    // Set PIN_D0  to output.
    set_tris_d(0x0FE);

    // Set Pin_F6 (reset ) to output.
    set_tris_f(0x0BF);

    // Initialize the LCD display
   LCDInit();

    //Test - blinking LED program
    while(true)
    {
        output_low(LED);
 //       output_low(LCD_CS);      //      PIN_A2
 //       output_low(LCD_RST);   //      PIN_F6
 //       output_low(LCD_CLK);   //      PIN_C3
 //       output_low(LCD_SI);      //      PIN_C5

        delay_ms(500);
        output_high(LED);
 //       output_high(LCD_CS);   //      PIN_A2
 //       output_high(LCD_RST);   //      PIN_F6
 //       output_high(LCD_CLK);   //      PIN_C3
 //       output_high(LCD_SI);   //      PIN_C5
        delay_ms(500);
 
 

        // Write the cammand to start on line 1
        LCDLine_1(); 
        // Write the data one char at a time.
        d_write('H');
        d_write('e');
        d_write('l');
        d_write('l');
        d_write('0');
        // Write the cammand to start on line 2
        LCDLine_2();
        // Write the data to line 2 one char at a time
        // You can put this in a loop and read from a table
        d_write('P');
        d_write('I');
        d_write('C');
        d_write('1');
        d_write('8');
        delay_ms(500);
        tmpcnt++;
        switch(tmpcnt)
        {
            case 10:
                d_write(' ');
                d_write('1');
                d_write('0');
                break;
            case 20:
                d_write(' ');
                d_write('2');
                d_write('0');
                break;
            case 30:
                d_write(' ');
                d_write('3');
                d_write('0');
                break;
            case 40:
                d_write(' ');
                d_write('4');
                d_write('0');
                break;
        }
    }
}
 
//*****************************************************************
// LCD busy delay
//*****************************************************************
void LCDBusy(void)
{
    delay_us(100);
}
//*****************************************************************
// Write to MCP923S17 Port A
//*****************************************************************
void WritePortA(char b)
{
    output_low(LCD_CS);   

   LCD_SSPBUF = 0x40;
   while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);

   LCD_SSPBUF = 0x12;

   while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);
   
   LCD_SSPBUF = b;

   while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);
   
   output_high(LCD_CS);
}
//*****************************************************************
// Write to MCP923S17 Port B
//*****************************************************************
void WritePortB(char b)
{
    output_low(LCD_CS);   
   
   LCD_SSPBUF = 0x40;

   while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);
   
   LCD_SSPBUF = 0x13;

   while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);
   
   LCD_SSPBUF = b;

   while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);
   
   output_high(LCD_CS);
}
//*****************************************************************
// Write the data to the display
//*****************************************************************
void d_write(char b)
{
   WritePortA(0x80);
   LCDBusy();
   WritePortB(b);
    delay_us(10);
   WritePortA(0xC0);
    delay_us(10);
   WritePortA(0x00);
   //TXREG = b;               //carriage return
   //while(!LCD_TXSTA_TRMT);      //wait for data TX
   //LCD_TXSTA_TRMT = 0;
}
//*****************************************************************
// Send a instruction to the display
//*****************************************************************
void i_write(char b)
{
   WritePortA(0x00);
   LCDBusy();
   WritePortB(b);
    delay_us(10);
   WritePortA(0x40);
    delay_us(10);
   WritePortA(0x00);
}
//*****************************************************************
// Write to line 1 of the display
//*****************************************************************
void LCDLine_1(void)
{
   i_write(0x80);
}
//*****************************************************************
// Write to line 1 of the display
//*****************************************************************
void LCDLine_2(void)
{
   i_write(0xC0);
}
//*****************************************************************
// To clear the display
//*****************************************************************
void LCDClear(void)
{
   i_write(0x01);
}
//******************************************************************
// Function to write to the PORT
//******************************************************************
void InitWrite(char b)
{
   WritePortA(0);
   WritePortB(b);
    delay_us(10);
   WritePortA(0x40);
    delay_us(20);
   WritePortA(0);
}
//*****************************************************************
// Initialize MCP923S17 Port A
//*****************************************************************
void InitPortA_SPI(char b)
{
    output_low(LCD_CS);   
   LCD_SSPBUF = 0x40;

   while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);
   
   LCD_SSPBUF = 0x00;

   while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);
   
   LCD_SSPBUF = b;

   while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);
   
    output_high(LCD_CS);   
}
//*****************************************************************
// Initialize MCP923S17 Port B
//*****************************************************************
void InitPortB_SPI(char b)
{
    output_low(LCD_CS);   
   LCD_SSPBUF = 0x40;
   while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);
   
   LCD_SSPBUF = 0x01;
   while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);
   
   LCD_SSPBUF = b;
   while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);
   
    output_high(LCD_CS);   
}
//*****************************************************************
// Initialize MCP923S17 SPI
//*****************************************************************
void InitSPI(void)
{
    // Set SSPM1 bit and SSPEN bit
   LCD_SPICON1 = 0x22;

    // Set CKE bit
   LCD_SPISTAT = 0x40;

    // Set Master Synchronous Serial Port Interrupt Flag bit bit in PIR1 to 0
    bit_clear(LCD_SPI_IF,SSP1IF_BIT);
}
//******************************************************************
// LCD Initialization function
//******************************************************************
void LCDInit(void)
{

    output_high(LCD_CS);
    delay_us(50);

    output_low(LCD_RST);
    delay_us(50);
    output_high(LCD_RST);
   
   InitSPI();
   InitPortA_SPI(0);
   InitPortB_SPI(0);
   
   WritePortA(0);
   
    delay_us(50);
   InitWrite(0x3C);            //0011NFxx
   
    delay_us(50);
   InitWrite(0x0C);            //Display Off
   
    delay_us(50);
   InitWrite(0x01);            //Display Clear
   
    delay_us(50);
   InitWrite(0x06);            //Entry mode
}
ckielstra



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

View user's profile Send private message

PostPosted: Tue Nov 06, 2012 3:55 am     Reply with quote

Thanks for posting the driver.
Could you also post it in the Code Library forum? There it will be easier for people to find.

BTW: do you know why there are functions i_write and initWrite ? Apart from a different delay these are identical.
Bill24



Joined: 30 Jun 2012
Posts: 45

View user's profile Send private message

PostPosted: Wed Nov 07, 2012 6:32 am     Reply with quote

ckielstra wrote:
Thanks for posting the driver.
Could you also post it in the Code Library forum? There it will be easier for people to find.

BTW: do you know why there are functions i_write and initWrite ? Apart from a different delay these are identical.


The code is a quick and dirty port of the Microchip version which itself was ported from assembler. If I get time I will clean it up and post it in the Library.
bboone



Joined: 04 Jun 2014
Posts: 3
Location: United States

View user's profile Send private message

PostPosted: Wed Jun 04, 2014 12:12 pm     Reply with quote

I know this is a couple years old but has anyone got this to work using #use spi and spi_xfer?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 04, 2014 12:33 pm     Reply with quote

See this post in the Code Library:
http://www.ccsinfo.com/forum/viewtopic.php?t=51264

To initialize PortA in the code from this thread, he sends 0x40, 0, 0:
Quote:

void LCDInit(void)
{
.
.
InitPortA_SPI(0);
.
}

void InitPortA_SPI(char b)
{
output_low(LCD_CS);
LCD_SSPBUF = 0x40;

while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);

LCD_SSPBUF = 0x00;

while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);

LCD_SSPBUF = b; // 0x00

while(! bit_test(LCD_SPI_IF,SSP1IF_BIT));
bit_clear(LCD_SPI_IF,SSP1IF_BIT);

output_high(LCD_CS);
}



The Code Library routines do the same thing, but they use spi_xfer():
Quote:

#define IO_DEVICE_ADDRESS_WRITE 0x40
#define IODIRA 0x00

void setup_MCP23S17()
{
MCP23S17_write(IOCON, 0x18);
MCP23S17_write(IODIRA, 0x00);
MCP23S17_write(IODIRB, 0xFF);
MCP23S17_write(GPPUA, 0x00);
MCP23S17_write(GPPUB, 0xFF);
MCP23S17_write(IPOLA, 0xFF);
MCP23S17_write(IPOLB, 0x00);
}


void MCP23S17_write(unsigned char address, unsigned char value)
{
output_low(CS);
spi_xfer(IO_DEVICE_ADDRESS_WRITE); // 0x40
spi_xfer(address); // 0x00
spi_xfer(value); // 0x00
output_high(CS);
}


You should be able to take the Code Library code as an example
and use it to modify the routines in this thread to use spi_xfer().
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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