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

Driver for PCE2111 LCD Duplex driver (64 segment)

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



Joined: 29 Jan 2011
Posts: 36

View user's profile Send private message

Driver for PCE2111 LCD Duplex driver (64 segment)
PostPosted: Thu Aug 04, 2022 5:43 am     Reply with quote

I'm a relative beginner with CCS and a complete beginner when it comes to writing device drivers. I'm using a PIC16F887 MCU and PCM 5.092.

I'd like to test an LCD frequency display board on my Revox B261 FM tuner.
It uses an old Mullard/Philips PCE2111 LCD Duplex driver (64 segment). It uses a serial protocol that predates I2C.

https://www.google.co.uk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwj39t6wha35AhVUEsAKHXf9DqgQFnoECBkQAQ&url=https%3A%2F%2Fwww.eevblog.com%2Fforum%2Ftestgear%2Fphilips-pm3295-and-pm3295a%2F%3Faction%3Ddlattach%3Battach%3D205895&usg=AOvVaw1l2A7uxUsj6BkY1DHQeAAK

The LCD itself uses 4 off 14 segment alphanumeric digits 100.00. The 1 has 2 segments and the zero's have 14 segments each as they are used for station names as well as the actual frequency (which goes from 88.00 to 108.00)
I would like to be able to write a simple driver that can turn on the segments in a meaningful way(actually create the numbers AND light up a few of the extra segments). This is to test the hardware. Later I'd like to replace the original LCD with a newer OLED and process the serial data stream from the original MCU (which is mask programmed, so is irreplaceable).
I have some assembly code for a PLL chip which is on the same MCU bus as the display, but I need to trim it down a bit before I post it on here (it has other LCD and rotary encoder assembler code mixed in). Would this assembly code be useful? I'd just like a few pointers or examples that could get me started. I think it's mainly bit banging 3 or 4 pins in a certain order. The timing is important, so mixing in the assembly code in the C listing would probably help. I will post some assembler code over the weekend. I hope someone can get me started.
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Thu Aug 04, 2022 6:32 am     Reply with quote

You are taking me back in time....

Cbus is not at all like I2C. It is not an open collector bus.
Critical question. What voltage is the PCE2111 running off?. Though this
supports 5v operation, it's normal voltage is 3v. If it is running off this
voltage, you would be better using a 3v PIC instead of the 16F887.
The drive is very simple. All you do is raise DLEN, then output 34 bits.
For each bit, just output the bit and pulse the clock high/low. Quite
slow. Allow 8uSec after outputting each bit before the clock, and
operate the clock for 2uSec, then wait another 10 after dropping it.
So you get about 1mSec for the entire transfer.
The leading bit is always a zero, then 32 data bits, and a single flag
bit that says whether this is to load to the high register or the low register.
Then drop DLEN.
Finally send one more clock after you have dropped this.

I'd just do a very simple 'clock' routine to generate the pulse on the clock
line with this sort of timing, then just output the data bits in turn calling
this routine.

When I last drove this, the Z80, was a new chip!... The Marconi lab still
existed only a few miles up the road. Used to go shooting in their indoor
range!.

So something like:
Code:

#define DLEN PIN_xx
#define DATA PIN_yy
#define CLB PIN_zz //set to suit you

int32 low32 = 0x1111;
int32 high32 = 0x5555; //some suitable test values

void init(voios)
{
    //call at start to ensure lines are low
    output_low(DLEN);
    output_low(CLB);
}

#inline
void clock()
{
    //generate one bit clock
    delay_us(8);
    output_high(CLB);
    delay_us(2);
    output_low(CLB);
    delay_us(8);
}

void send(int32 value, int1 lowhigh)
{
    int ctr;
    int32 mask=1; //data is output LSb first
    output_high(DLEN);
    delay_us(8);
    //output 32bit value to either low or high register
    output_low(DATA);
    clock(); //first send a 0
    for (ctr=0;ctr<32;ctr++)
    {
        if (value & mask)
           output_high(DATA);
        else
           output_low(DATA);
        clock();
        mask*=2; //Modern compiler should optimise this to shift
    }
    if (lowhigh)
       output_high(DATA);
    else
       output_low(DATA);
    clock(); //clock out the bit to specify high/low register
    output_low(DLEN);
    clock(); //now clock this into the latches.
    delay_us(8); //do not do anything else for 8uSec
}

void main(void)
{
    init(); //ensure bus is initialised
    delay_us(100)'
    send(low32, 0); //load the low 32bits
    send(high32, 1); //load the high 32bits.
}


You will need to have a character array giving what bit numbers have
to be set for each digit, but this should do the clocking of this to the
display.
djsb



Joined: 29 Jan 2011
Posts: 36

View user's profile Send private message

PostPosted: Thu Aug 04, 2022 7:14 am     Reply with quote

Ttelmah,
Thanks for your very helpful reply.
Here is the schematic at the bottom of my post in the EEVBLOG forum

https://www.eevblog.com/forum/projects/14-segment-lcd-emulation-on-a-128x32-ssd1306-based-oled-display/msg4331803/#msg4331803

The voltage appears to be 3.1v. However, the CBUS pins have 47k resistors in series with them, so maybe this is a crude way of level shifting the 5V down to 3v or so. I've never tried this, I'd normally use proper level shifting on modern chips. Would a LV PIC version have 3.3v logic levels or are there special chips for this. I've only ever worked with 5v PICS.

Are there any post you would recommend on setting up a character array? I'll have a good read of the forum and peruse any example code I can find.
Then I'll make a start with toggling some pins and monitoring the pins on my logic analyser and/or oscilloscope.
djsb



Joined: 29 Jan 2011
Posts: 36

View user's profile Send private message

PostPosted: Fri Aug 05, 2022 9:06 am     Reply with quote

Here is a reply to the post in EEVBLOG that show the screenshot of my Saleae Logic16 connected to Port B0,B1 and B2 of a PIC16F1847.

https://www.eevblog.com/forum/projects/14-segment-lcd-emulation-on-a-128x32-ssd1306-based-oled-display/

The Logic 16 is triggered from the master clear pin when I push the reset button on my development board. I can't post any screenshots on this forum so I have to use EEVBLOG for most of my documentation for this project. I can zoom into the waveforms closer if needed. Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 05, 2022 11:06 am     Reply with quote

Quote:

Are there any posts you would recommend on setting up a character array?

The following link has code for a 14-segment lcd display. It has a digit array.
Scroll down in the code to where it says: Digit_Map[10]
http://www.ccsinfo.com/forum/viewtopic.php?t=33377&start=11
djsb



Joined: 29 Jan 2011
Posts: 36

View user's profile Send private message

PostPosted: Fri Aug 05, 2022 2:36 pm     Reply with quote

Thanks PCM Programmer.
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Sat Aug 06, 2022 3:39 am     Reply with quote

The 47R resistor is _not_ to allow higher drive voltages. It is there to
reduce reflection on the edges of the waveform. A PIC at 5.5v driving in to
the inputs will be breaking the specifications for the chip. Maximum input
voltage on any pin is supply+0.3v.
Either use a lower voltage PIC (the '3.3v' PIC's will usually support operation
down to voltages like 2v), or add your own dividers to the signals. Otherwise
damage may result.
A suitable divider would be something like 220R+330R to ground, which
will then give a nominal 3v max signal (the chip needs 2v).
djsb



Joined: 29 Jan 2011
Posts: 36

View user's profile Send private message

PostPosted: Sat Aug 06, 2022 4:18 am     Reply with quote

Ttelmah wrote:
The 47R resistor is _not_ to allow higher drive voltages. It is there to
reduce reflection on the edges of the waveform. A PIC at 5.5v driving in to
the inputs will be breaking the specifications for the chip. Maximum input
voltage on any pin is supply+0.3v.
Either use a lower voltage PIC (the '3.3v' PIC's will usually support operation
down to voltages like 2v), or add your own dividers to the signals. Otherwise
damage may result.
A suitable divider would be something like 220R+330R to ground, which
will then give a nominal 3v max signal (the chip needs 2v).

There is a 47K resistor on each input on the LCD board and a 3.3k resistor also in series with the output of the CBUS on the MCU board (not posted on this forum). Despite this, I will take a cautious approach and use a potential divider as you suggest when I test the board next week. I'll also have a proper read of the datasheet for the PCE2111. Thanks.
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Sun Aug 07, 2022 10:15 am     Reply with quote

Very Happy

As you say, you didn't mention the other resistors...
Key is to work out what these were actually giving to the Cbus device.

Have fun,
djsb



Joined: 29 Jan 2011
Posts: 36

View user's profile Send private message

PostPosted: Wed Aug 10, 2022 8:07 am     Reply with quote

Ttelmah,
I'd just like to thank you again for the help you've given me with the code. Today I tried out my spare Revox LCD board with my development board fitted with a PIC16F1847. I managed to get nearly ALL the digits and segments lit (well, you know what I mean). Now I just have to work through the mapping of the data to the actual segments and digits.
I'll do this first by decrementing/incrementing the data words slowly (probably by just pressing a switch or by sending the information via RS232) so that I can see and note down how everything works. Later I will experiment with the character array that you and PCM Programmer mentioned earlier. Thanks again.

David.
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Wed Aug 10, 2022 9:45 am     Reply with quote

Well done. Stepping through is the way I'd go. Then you really will know
where everyhing is.Smile
djsb



Joined: 29 Jan 2011
Posts: 36

View user's profile Send private message

PostPosted: Fri Aug 26, 2022 7:37 am     Reply with quote

In preparation for creating a "receive" function to add to the sample code above (or as an entirely separate piece of code), what is the correct way of storing 2 off 32 bit words that are received serially? I have read on this forum that it is best to buffer serial data using a double buffer. I eventually want to feed the output of the DATA, DLEN and CLK lines of the tuner into my development board. The PIC16F1847 will then spit out the binary data word over a RS232 link connected to my PC. I'd also like to separate and store the LOAD bit and any other control bits present.
I could start by feeding the output of the sample code above BACK into another pin as a kind of loopback test. Are there any posts on the forum that cover a similar topic so that I can get some understanding of what to do?

I'm still working on the LCD mapping and will be for a while. This is going quite well. Thanks.
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Fri Aug 26, 2022 7:51 am     Reply with quote

One critical keyword here. 'union'.
Look here, and in the manual, and in the examples.

Key is it allows you to (efficiently) have multiple ways to reference the
same block of data. So you can have for example an array of eight bytes,
that is also readable as two 32bit words.
djsb



Joined: 29 Jan 2011
Posts: 36

View user's profile Send private message

PostPosted: Sat Aug 27, 2022 1:54 pm     Reply with quote

Thanks Ttelmah,
I'll give this a try

https://www.ccsinfo.com/forum/viewtopic.php?t=58956&highlight=union

and I wonder if this would work?

https://www.ccsinfo.com/forum/viewtopic.php?t=55426&highlight=masking
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Mon Aug 29, 2022 4:09 am     Reply with quote

The first one is the way to go.
The second one is talking about how to take individual bytes 'out' of a
larger value. Not putting bytes together to form a larger value. It is also
much less efficient than using the union to do this.
Make 8, and make32 can also be used, but the union is the 'general' C
way of doing this (the make functions are CCS only), and the handling of
unions is as efficient as using these.

I was visualising that you might want to make the union hold two copies
of everything, so it can do your buffering as well.
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