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 support@ccsinfo.com

How to use the Parallel Master Port in PIC18F87J11?
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
norman_tan



Joined: 30 Jan 2008
Posts: 27

View user's profile Send private message

How to use the Parallel Master Port in PIC18F87J11?
PostPosted: Sat Dec 09, 2017 8:11 pm     Reply with quote

Hi Everybody,

Has anybody ever used the Parallel Master Port function in PIC18F series? not Parallel Slave Port!
Traditional C is also OK if you have. I have spent about one week on it but still can not run it...

Thanks!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Dec 10, 2017 2:57 am     Reply with quote

The setup_psp() function has parameters to setup either the master or
the slave. The constants used with this function are in the 18F87J11.h file.

Tell us what you want the Parallel Master Port to do in your project.
norman_tan



Joined: 30 Jan 2008
Posts: 27

View user's profile Send private message

PostPosted: Tue Dec 12, 2017 2:38 am     Reply with quote

Hi PCM Programmer,
I want the PMP of 18F87j11 works under "Master Mode 2" with 8-bit DATA + 13-bit ADDRESS. my version of PCWHD is 5.018, and in the 18F87J11.h file all PMP settings/functions are listed here:
Code:

////////////////////////////////////////////////////////////////// PMP
// PP Functions: SETUP_PSP(),
// PSP_INPUT_FULL(), PSP_OUTPUT_FULL(),
//                PSP_OVERFLOW(), INPUT_D(), OUTPUT_D()
// PP Variables: PSP_DATA
// PP Prototypes:
_bif void setup_psp(int32 mode);
_bif int1 psp_output_full(void);
_bif int1 psp_input_full(void);
_bif int1 psp_overflow(void);
// Constants used in SETUP_PSP() are:
#define PMP_DISABLED     0
#define PMP_ENABLED      0x02008000
#define PMP_COMBINE_RW   0x01000000
#define PSP_ADDRESS_MODE 0x01000000
#define PSP_NORMAL_MODE  0x18000000
#define PMP_16_BIT       0x04000000
#define PMP_INC_ADDR     0x08000000
#define PMP_DEC_ADDR     0x10000000
#define PMP_INT          0x20000000
#define PMP_STALL        0x40000000
#define PMP_INT_3        0x60000000

#define PMP_RD_ACT_HIGH  0x00000101
#define PMP_WR_ACT_HIGH  0x00000202
#define PMP_RD_ACT_LOW   0x00000100
#define PMP_WR_ACT_LOW   0x00000200
#define PMP_BE_ACT_HIGH  0x00000404
#define PMP_BE_ACT_LOW   0x00000400
#define PMP_CS1_ACT_HIGH 0x00000008
#define PMP_CS2_ACT_HIGH 0x00000010
#define PMP_AL_ACT_HIGH  0x00000020
#define PMP_ADDR_MUX_A_D 0x00000800
#define PMP_ADDR_MUX_D   0x00001000
#define PMP_IDLE_OFF     0x00002000

#define PMP_WAITE        0x00010000  // Data hold after strobe, add *2 for 3Tcy or *3 for 4Tcy
#define PMP_WAITM        0x00040000  // Data hold read to strobe, add *n for n*Tcy (n=1..15)
#define PMP_WAITB        0x00400000  // Data hold before R/W, add *2 for 3Tcy or *3 for 4Tcy

#define PP_ACTIVE_IDLE   0x00002000
//////////////////////////////////////////////////////////////////

[b]Then how can  I set the 13-bit address and how to read/write 8-bit data from/to data port? I can not find the suitable library functions.[/b]

In PIC24FJxxxGB10X file,for PMP operation there are many settings/functions in it(as below):
////////////////////////////////////////////////////////////////// PMP from PIC24
// PMP Functions: setup_pmp(), pmp_address(), psp_read(), pmp_read(),
// psp_write(), pmp_write(), psp_output_full(),psp_input_full(),
// psp_overflow(), pmp_output_full(), pmp_input_full(),
// pmp_overflow()
// PMP Prototypes:
_bif void setup_pmp(unsigned int32 mode, unsigned int16 address_mask);
_bif void pmp_address(unsigned int16 address);
_bif unsigned int8 pmp_read(void);
_bif void pmp_write(unsigned int8 data);
_bif int1 pmp_output_full(void);
_bif int1 pmp_input_full(void);
_bif int1 pmp_overflow(void);
_bif void setup_psp(unsigned int32 mode, unsigned int16 address_mask);
_bif unsigned int8 psp_read(void);
_bif unsigned int8 psp_read(unsigned int16 address);
_bif void psp_write(unsigned int8 data);
_bif void psp_write(unsigned int8 data, unsigned int16 address);
_bif int1 psp_output_full(void);
_bif int1 psp_input_full(void);
_bif int1 psp_overflow(void);
// Constants used in SETUP_PMP() and SETUP_PSP() are:
#define PAR_ENABLE                0x8000
#define PAR_DISABLE               0x0000    // Module enable/disable options
#define PAR_STOP_IN_IDLE          0x2000
#define PAR_CONTINUE_IN_IDLE      0x0000
#define PAR_ADDR_NOT_MULTIPLEXED  0x0000    // Address multiplexing options
#define PAR_LOW_ADDR_MULTIPLEXED  0x0800    // Address multiplexing options
#define PAR_FULL_ADDR_MULTIPLEXED 0x1000    // Address multiplexing options
#define PAR_PTBEEN_ENABLE         0x0400  // Byte Enable Port Enable bit
#define PAR_PTWREN_ENABLE         0x0200  // Write Enable Strobe bit
#define PAR_PTRDEN_ENABLE         0x0100  // Read/Write Strobe Port bit
#define PAR_ALP_ACTIVE_HIGH       0x0020 // Address latch polarity high
#define PAR_BEP_ACTIVE_HIGH       0x0004 // Byte Enable Polarity
#define PAR_WRSP_ACTIVE_HIGH      0x0002 // Write strobe Polarity bit
#define PAR_RDSP_ACTIVE_HIGH      0x0001 // Read strobe Polarity bit
#define PAR_CS_XX                 0x0000   // Chip select pins used for address
#define PAR_CS_X1                 0x0008   // Chip select pin 1 used, active high
#define PAR_CS_X0                 0x0000   // Chip select pin 1 used, active low
#define PAR_CS_1X                 0x0050   // Chip select pin 2 used, active high
#define PAR_CS_0X                 0x0040   // Chip select pin 2 used, active low
#define PAR_CS_00                 0x0080   // Chip select pins 1,2 used, active low
#define PAR_CS_11                 0x0098   // Chip select pins 1,2 used, active high
#define PAR_CS_10                 0x0090   // Chip select pins 1,2 used, 1 is active low, 2 is high
#define PAR_CS_01                 0x0088   // Chip select pins 1,2 used, 1 is active high, 2 is low
#define PAR_INTR_ON_RW                0x20000000  // Interrupt on read write
#define PAR_NO_INTR_STALL_ACTIVATED   0x40000000  // No interrupt, processor stall activated
#define PAR_INTR_ON_3_RW_BUF          0x60000000 // Interrupt on write to Buffer 3 or read from Buffer 3
#define PAR_PSP_AUTO_INC              0x18000000 // Read write buffers auto increment
#define PAR_DEC_ADDR                  0x10000000 // Increment the address
#define PAR_INC_ADDR                  0x08000000 // Decrement the address
#define PAR_MASTER_MODE_1             0x03000000  // Master mode 1
#define PAR_MASTER_MODE_2             0x02000000  // Master mode 2
#define PAR_WAITB1                    0x00000000 // 1 Tcy Wait state for data setup R/W
#define PAR_WAITB2                    0x00400000 // 2 Tcy Wait state for data setup R/W
#define PAR_WAITB3                    0x00800000 // 3 Tcy Wait state for data setup R/W
#define PAR_WAITB4                    0x00C00000 // 4 Tcy Wait state for data setup R/W
#define PAR_WAITM0                    0x00000000 // 0 wait state for Read to byte
#define PAR_WAITM1                    0x00040000 // 1 Tcy wait state for Read to byte
#define PAR_WAITM2                    0x00080000 // 2 Tcy wait state for Read to byte
#define PAR_WAITM3                    0x000C0000 // 3 Tcy wait state for Read to byte
#define PAR_WAITM15                   0x003C0000 // 15 wait states
#define PAR_WAITE1                    0x00000000  // 1 Tcy Wait for data hold after strobe
#define PAR_WAITE2                    0x00010000 // 2 Tcy Wait for data hold after strobe
#define PAR_WAITE3                    0x00020000 // 3 Tcy Wait for data hold after strobe
#define PAR_WAITE4                    0x00030000 // 4 Tcy Wait for data hold after strobe
//////////////////////////////////////////////////////////////////
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Dec 12, 2017 3:55 am     Reply with quote

OK. It's been a while since I played with the PMP, but some comments:

The basic setups don't configure all the pin masks. Think about it there are individual bits to enable each bit of the address, so potentially up to 65536 different patterns. All you do is set these to mask what you want. So:
Code:

#WORD PMPEN=getenv("SFR:PMEL")

    PMPEN=0x1FFF; //enables the low 13bits of the address



Unfortunately I think you will have to write to the configuration registers generally yourself. The way I do it above shows a good portable way to define the registers and use them. My memory was that the register numbers selected by the inbuilt functions was wrong when I was looking at them, and this was on a close 'relative' of your chip, and fairly close on compiler versions.
The 32 bit value is meant to be sent to the PMMODE register (upper 16bits), and PMCON (low 16bits), but when I tried it the values were going to completely the wrong registers.
So something like:
Code:

#WORD PMCON=getenv("SFR:PMCONL")
#WORD PMMODE=getenv("SFR:PMMODEL")
#WORD PMPEN=getenv("SFR:PMEL")
#BYTE PMDIN8=getenv("SFR:PMDIN1L")

void psp_setup(int32 value)
{
     PMMODE=value>>16;
     PMCON=value & 0xFFFF;
}

Then calling this instead of setup_psp.

Now 'no guarantees', I haven't got that source code now, and it was a couple of years ago
norman_tan



Joined: 30 Jan 2008
Posts: 27

View user's profile Send private message

PostPosted: Wed Dec 13, 2017 3:46 am     Reply with quote

Dear Ttelmah,
Thanks for your reply!
In fact, I can not understand well the define such as "#define PMP_ENABLED 0x02008000" in 18F87J11.h file. Why setting value as a word? hehe. No studying it carefully.
About 8 year ago, I ever met question as this time, then I could not control the 128*128 LCD in CCS, but I used the original method to operate the SFRs the same as below and successful (but fail this time):
Code:

// define PMP interface
///////////////////////////////////////////////////////////////////////////////
#byte PMADDRH = 0xF69      // PARALLEL PORT ADDRESS REGISTER, HIGH BYTE
#byte PMADDRL = 0xF68      // PARALLEL PORT ADDRESS REGISTER, LOW BYTE
#byte PMDIN1H = 0xF67      // Is used for both input and output data in Master modes.
#byte PMDIN1L = 0xF66      // Is used for both input and output data in Master modes.
#byte PMCONH = 0xF65       // PARALLEL PORT CONTROL HIGH BYTE REGISTER
#byte PMCONL = 0xF64       // PARALLEL PORT CONTROL LOW BYTE REGISTER
#byte PMMODEH = 0xF63      // PARALLEL PORT MODE HIGH BYTE REGISTER
#byte PMMODEL = 0xF62      // PARALLEL PORT MODE LOW BYTE REGISTER
//#byte PMDOUT2H = 0xF61     // Are only used in buffered Slave modes and serve as a buffer for outgoing data
//#byte PMDOUT2L = 0xF60     // Are only used in buffered Slave modes and serve as a buffer for outgoing data
//#byte PMDIN2H = 0xF5F      // Is used for buffering input data in select Slave modes.
//#byte PMDIN2L = 0xF5E      // Is used for buffering input data in select Slave modes.
#byte PMEH = 0xF5D         // PARALLEL PORT ENABLE HIGH BYTE REGISTER
#byte PMEL = 0xF5C         // PARALLEL PORT ENABLE LOW BYTE REGISTER
#byte PMSTATH = 0xF5B      // PARALLEL PORT STATUS HIGH BYTE REGISTER
#byte PMSTATL = 0xF5A      // PARALLEL PORT STATUS LOW BYTE REGISTER

#bit PMPEN = PMCONH.7
#bit PMPEEN = PMCONH.2
#bit PTWREN = PMCONH.1
#bit PTRDEN = PMCONH.0
#bit BUSY = PMMODEH.7
#bit IBOV = PMSTATH.7
#bit OBUF = PMSTATL.6
#bit PMPTTL = 0xFCC.0
///////////////////////////////////////////////////////////////////////////////

// Init the Parallel Master Port
void PMP_init(void)
{
   
   // ---------------------------------- Start of PARALLEL MASTER PORT settings --------------------------------------
   
   PMCONH = 0x83; // PMPEN:1 = PMP is enabled,
                  // PSIDL:0 = Continues module operation in Idle mode,
                  // ADRMUX<1:0>:00 = Address and data appear on separate pins
                  // PTBEEN:0 = PMBE port is enabled,
                  // PTWREN:1 = PMWR/PMENB port is enabled,
                  // PTRDEN:1 = PMRD/PMWR port is enabled
   
   PMCONL = 0xBF; // PMCS1 and PMCS2 function as chip select, ALP/CS2P/CS1P/BEP/WRSP/RDSP active-high
   
   PMMODEH = 0x22; // BUSY: Busy bit (Master mode only and Read only):1 = Port is busy, 0 = Port is not busy
                  // IRQM<1:0>:01 = Interrupt is generated at the end of the read/write cycle
                  // INCM<1:0>:00 = No increment or decrement of address,
                  // MODE16:0 = 8-Bit mode: Data register is 8 bits, a read or write to the Data register invokes one 8-bit transfer
                  // MODE<1:0>:10 = Master Mode 2 (PMCSx, PMRD, PMWR, PMBE, PMA<x:0> and PMD<7:0>)
                 
   PMMODEL = 0x00;  // Do not know how to set it, let it be default value
   
   PMEH = 0x3F;   // PMA15 and PMA14 function as port I/O,PMA<13:8> function as PMP address lines
   
   PMEL = 0xFF;   // PMA<7:2> function as PMP address lines,PMA1 and PMA0 function as either PMA<1:0> or PMALH and PMALL
   
   IBOV = 0; // Other bits of PMSTATH is read only, but this bit has both read and write function
                     // When it is readed as 1, then must clear it. PMSTATH is STATUS HIGH BYTE REGISTER
   
   OBUF = 0; // Other bits of PMSTATL is read only, but this bit has both read and write function
                     // When it is readed as 1, then must clear it. PMSTATL is STATUS LOW BYTE REGISTER
                     
   
   PMPEN = 1;      // PMP is enabled
   PMPEEN = 0;     // PMBE port is disabled(for 16-bit data only)
   PTWREN = 0;     // PMWR port is disabled
   PTRDEN = 0;     // PMRD port is disabled
   PMPTTL = 1;     // 1 = PMP module uses TTL input buffers, 0 = PMP module uses Schmitt Trigger input buffers
   // ---------------------------------- End of PARALLEL MASTER PORT settings -------------------------------------- 
}

Void main()
{
...
    while(TRUE)
   {
       delay_ms(2000);
   
       PMADDRH = 0xC0;
       PMADDRL = 0x00;
   
       PMDIN1L = 0xF0;   // output 0xF0 on data port(LED1-4 should turn on,LED5-8 shoud turn off )
 
       PTWREN = 1;
       delay_us(10);
       PTWREN = 0;
 
       delay_ms(2000);
   
       PMADDRH = 0xC0;
       PMADDRL = 0x00;
       PMDIN1L = 0x0F;     // output 0x0F on data port(LED1-4 should turn off, LED5-8 shoud turn on)
 
       PTWREN = 1;
       delay_us(10);
       PTWREN = 0;
   }
}
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Dec 13, 2017 6:08 am     Reply with quote

Why are the defines words? Because the register/SFR are used for is a word. They should be ored together in setup_pmp() as needed to select the desired functionality.

Here is my PMP set up as used on a PIC24, which has a similar PMP peripheral but may well be different in some important way:
Code:
 
   // PMP setup.
   // Master mode 1 is Motorola compatible, with CS, R/W and Enable lines
   // Master mode 2 is Intel compatible, with CS, WR and RD lines. We are using this mode.
   
   // We have separate data and address lines, hence NOT multiplexed.
   // CS, WR and RD controlled by PMP hardware. This give 100ns read and write strobes and 150ns cycle time (from 80MHz processor clock)
   setup_pmp( PAR_ENABLE | PAR_MASTER_MODE_2 | PAR_ADDR_NOT_MULTIPLEXED | PAR_CS_00 | PAR_STOP_IN_IDLE | PAR_PTWREN_ENABLE | PAR_PTRDEN_ENABLE | PAR_WAITM4 | PAR_WAITM1, 0x401F );


This uses five address lines and a single chip enable. The 0x401f is the address mask for these five address lines, A0-4, and the CS, which gives the 40xx part.

I am a little confused by the reference to LEDs in your code, and also by your bit-banging of WR enable. The PMP is a full bus interface designed to interface with things like external memories, complex addressable peripheral devices (mine are GPIB and LAN ICs) and so on. It is not a latched LED driver. For that simple GPIO bits are all that's needed.

When its correctly set up, which admittedly is tricky, it will automatically generate read and write cycles with all the necessary chip selects, read and write strobes etc, for multiplex and non-multiplexed busses. If correctly set up all you should need to do is set the address and then write to the data register, which triggers the write cycle. Reads are more "fun" as the peripheral is arranged mainly for block access, i.e. reading several words in sequence. Hence when you read the data register you get the result of the previous read and trigger a new one. Reading words on their own, i.e. true random access reads needs a little thought. Here is my (random) read code:

Code:

#bit  PMP_Enable = getenv("BIT:PMPEN")
#bit  PMP_BUSY = getenv("BIT:BUSY")
#word PMP_Data = getenv("SFR:PMDIN1")
#byte PMP_ADDRL = getenv("SFR:PMADDR")
#byte PMP_ADDRH = getenv("SFR:PMADDR") + 1

unsigned int8 PMP_Read(unsigned int8 Address)
{
   // This is for single byte reads at random addresses. For block reads, more efficient code is possible.
   unsigned int8 PMP_Byte;
     
   // This works for up to eight address lines, PMA0-PMA7. Note we do not
   // set the high byte, that's fixed.
   PMP_ADDRL = Address;
 
   // Read the PMP data register, this initiates a read cycle, but doesn't give us the correct result.
   // it actually give us the result of the last read, or even the last byte written!
   PMP_Byte = PMP_Data;
   // Wait for the cycle to finish.
   while(PMP_BUSY);
   PMP_Enable = 0; // disable PMP
   // Read the data again, this gets the byte read in the last cycle, but as the PMP is disabled, will not generate a second read cycle
   PMP_Byte = PMP_Data;
   PMP_Enable = 1; // re-enable the PMP
   return PMP_Byte;
}
norman_tan



Joined: 30 Jan 2008
Posts: 27

View user's profile Send private message

PostPosted: Thu Dec 14, 2017 2:18 am     Reply with quote

Dear RF_Developer,
Thanks for your reply!

About the LEDs I added in code: I only wanted to show whether I have controlled the data port successful - LEDs will blink a little if data write operation is right, (though data port can not be taken as a GPIO). Of course measuring the data port with a scope maybe better than LEDs.

About the WR enable: I added it compulsively in code after many times failure. hehe.

About
Quote:
The 0x401f is the address mask for these five address lines, A0-4, and the CS, which gives the 40xx part.

the value "0x401F" is defined by yourself/CCS according to the chip manual?

Quote:
When its correctly set up, which admittedly is tricky, it will automatically generate read and write cycles with all the necessary chip selects, read and write strobes etc, for multiplex and non-multiplexed busses. If correctly set up all you should need to do is set the address and then write to the data register, which triggers the write cycle. Reads are more "fun" as the peripheral is arranged mainly for block access, i.e. reading several words in sequence. Hence when you read the data register you get the result of the previous read and trigger a new one. Reading words on their own, i.e. true random access reads needs a little thought.

Thank you described them so detailed.

I have submitted new PCB file with PIC24FJxxxGB108 chip to pcb manufactory, this is the standby design scheme if PIC18F87J11 PMP function fails finally in my CCS C project....
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Thu Dec 14, 2017 4:56 am     Reply with quote

Quote:
About "The 0x401f is the address mask for these five address lines, A0-4, and the CS, which gives the 40xx part. " the value "0x401F" is defined by yourself/CCS according to the chip manual?


The value is defined by the datasheet. It is the address mask that goes into PMAEN on the 24s and PMEH and PMEL on the 18F87J11 (the 18s have 8 bit registers, the 24s 16 bit registers). For the 18F87J11 look at pages 171 and 172. In my application there were five non-multiplexed address bits, A0-A4, that means the bottom five bits of the enable register have to be 1s, or 0x001F. You are using thirteen bits, so you need 0x01FF. The 4 in the top nibble of my application is to enable PMCS1, chip select one. Combine the two and for my app I got 0x401F, your probably need 0x41FF. The PMP will not control the other address bits, and they can be used for general IO.

With LEDs, the PMP does cycles so fast I don't think you'll see any visible blinking. An oscilloscope is the way to check its working.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Thu Dec 14, 2017 8:51 am     Reply with quote

No. 13 bits. 0x1FFF.
You are a nibble short.
That's why I showed this value in my post higher up.
norman_tan



Joined: 30 Jan 2008
Posts: 27

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 2:26 am     Reply with quote

Dear RF_Developer and Ttelmah,
I studied the manual of 18s again as you said. It is just the value 0x1FFF if combine PMEH and PMEL.

In my last post, I set the PMEH (set as 14 bit address there) and PMEL as:
PMEH = 0x3F; // PMA15 and PMA14 function as port I/O, PMA<13:8> function as PMP address lines

PMEL = 0xFF; // PMA<7:2> function as PMP address lines,PMA1 and PMA0 function as either PMA<1:0> or PMALH and PMALL

If change the PMEH = 0x1F (13-bit address) and combine PMEH & PMEL, it is 0x1FFF.

Thank you for explaining it so carefully!

Removed the LEDs board and I measured the Data Port & Address Port(checking the pin level change one by one) with an oscilloscope.
Obviously, signals of data port and address port are changed according to the settings. Duty cycle of Address port is 50%, and the duty cycle of data port is very small -- data is a narrow pulse.

But unfortunately, I can not measure the change at PMWR/CS pin (it is always is '0') though I have changed the setting of PTWREN from '0' to '1'.
Code:

void PMP_init(void)
{
   
   // ---------------------------------- Start of PARALLEL MASTER PORT settings --------------------------------------
   
   PMCONH = 0x83; // PMPEN:1 = PMP is enabled,
                  // PSIDL:0 = Continues module operation in Idle mode,
                  // ADRMUX<1:0>:00 = Address and data appear on separate pins
                  // PTBEEN:0 = PMBE port is enabled,
                  // PTWREN:1 = PMWR/PMENB port is enabled,
                  // PTRDEN:1 = PMRD/PMWR port is enabled
   
   PMCONL = 0xBF; // PMCS1 and PMCS2 function as chip select, ALP/CS2P/CS1P/BEP/WRSP/RDSP active-high
   
   PMMODEH = 0x22; // BUSY: Busy bit (Master mode only and Read only):1 = Port is busy, 0 = Port is not busy
                  // IRQM<1:0>:01 = Interrupt is generated at the end of the read/write cycle
                  // INCM<1:0>:00 = No increment or decrement of address,
                  // MODE16:0 = 8-Bit mode: Data register is 8 bits, a read or write to the Data register invokes one 8-bit transfer
                  // MODE<1:0>:10 = Master Mode 2 (PMCSx, PMRD, PMWR, PMBE, PMA<x:0> and PMD<7:0>)
                 
   PMMODEL = 0x00;  // Do not know how to set it, let it be default value
   
   PMEH = 0x1F;   // PMA15, PMA14 and PMA13 function as port I/O,PMA<12:8> function as PMP address lines
   
   PMEL = 0xFF;   // PMA<7:2> function as PMP address lines,PMA1 and PMA0 function as either PMA<1:0> or PMALH and PMALL
   
   IBOV = 0; // Other bits of PMSTATH is read only, but this bit has both read and write function
                     // When it is readed as 1, then must clear it. PMSTATH is STATUS HIGH BYTE REGISTER
   
   OBUF = 0; // Other bits of PMSTATL is read only, but this bit has both read and write function
                     // When it is readed as 1, then must clear it. PMSTATL is STATUS LOW BYTE REGISTER
                     
   
   PMPEN = 1;      // PMP is enabled
   PMPEEN = 0;     // PMBE port is disabled(for 16-bit data only)
   PTWREN = 1;     // PMWR port is disabled
   PTRDEN = 1;     // PMRD port is disabled
   PMPTTL = 1;     // 1 = PMP module uses TTL input buffers, 0 = PMP module uses Schmitt Trigger input buffers
   // ---------------------------------- End of PARALLEL MASTER PORT settings -------------------------------------- 
}

Void main()
{
...
    while(TRUE)
   {
       delay_ms(300);
   
       PMADDRH = 0xC0;
       PMADDRL = 0xF0;
   
       PMDIN1L = 0xF0;
 
   
       delay_ms(300);
 
       PMADDRH = 0xC0;
       PMADDRL = 0x0F;
   
       PMDIN1L = 0x0F;
   }
}

I will return to study the 18s manual much carefully again to find what causes no action at PTWR/CS pin.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 3:13 am     Reply with quote

OK.
Lets make a couple of other comments:

First note how I used '#word'. This allows you to write to a 16bit register as a single 'entity'. Very useful for this sort of thing.
If you are dealing with registers that are fundamentally '8bit' entities, then use #byte. If you are dealing with 16bit registers use #word. The compiler locates the register at the location given, and the next location 'up', so by locating the word at the 'low' register address I get a 16bit register where wanted. Much easier. Smile

Then the key place to look is DS-70299C. From MicroChip. This gives examples of the settings needed for several typical modes, and these are a great starting point. You are looking at 8bit data demultiplexed address?.

Now we come to the first big problem. Look at the data sheet. Figure 26-1. Note how it says 'up to 11bit address'. As far as can see, the module does not support a 13bit address mode. It allows up to 12bit if the chip select is not used, but only eleven bits with a CS. If you look at the pin diagrams, there is not a PMA11 or PMA12 bit... So your 13bit address has problems. Though the register has bits to apparently select these, the ones above A10, are non functional. If you look at the example, all 16 bits are shown as selected, though 11bits are being used....
A look at the PMAEN register in the data sheet shows it stopping at bit 10.

So if you want an address this large you are going to have to 'think again'. Either accessing the chip as pages, with a fixed output for the extra bits, or doing some form of multiplexing.

So a big part of your problem may simply be you are trying to ask the chip to do something it doesn't support.....
norman_tan



Joined: 30 Jan 2008
Posts: 27

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 8:39 pm     Reply with quote

Dear Ttelmah,

In manual DS-70299C, it says "Up to 12 Programmable Address Lines",but this manual is used for "dsPIC33F/PIC24H FRM Section 35. Parallel Master port".

In manual DS39778E, it says "Up to 16 Programmable Address Lines", this is the manual for PIC18F87J11 FAMILY, and in section 12.3.4 ADDRESS MULTIPLEXING, it describes as below :
In Demultiplexed mode (PMCONH<4:3> = 00), data and address information are completely separated. Data bits are presented on PMD<7:0>, and address bits are presented on PMADDRH<7:0> and PMADDRL<7:0>.
I selected this mode here.

OF course for my "standby design scheme"(if PIC18F87J11 PMP function fails finally), I selected PIC24FJxxxGB108 FAMILY. In its manual(DS39897C) ,it says "Up to 16 Programmable Address Lines", “For more information, refer to the PIC24F Family Reference Manual”,Section 13 - Parallel Master Port(PMP) (DS39713)". so if I select the chip PIC24FJ128GB108 for "standby design scheme", it will be OK.

I am editing those CCS codes as advice from you and RF_Developer for a try Very Happy

After copying all PMP settings from PIC24FJ128GB108.h to PIC18F87J11.h(they are very similar between these two chips) and disable all previous settings too, I add command line in code:
setup_pmp(PAR_ENABLE|PAR_CS_11|PAR_CONTINUE_IN_IDLE|PAR_PTBEEN_ENABLE|PAR_PTWREN_ENABLE|PAR_PTRDEN_ENABLE|PAR_MASTER_MODE_2,0x1FFF);

Compile result is:
Error 112: Function used but not defined: ...setrp_pmp 411 SCR=6578

Evil or Very Mad

Function "_bif void setup_pmp(unsigned int32 mode, unsigned int16 address_mask); " has already been included in .h file, and I have already added the PMP into device 18f87J11 in CCS IDE menu too(operation steps as below):
TOOLS\Device Editor\Other Features\Par Port\PMP/PSP, then SAVE change.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Dec 16, 2017 11:35 am     Reply with quote

You use the setup PSP function.

PCM_programmer pointed this out right at the start of the thread.

It's a problem of 'nomenclature'. Some chips have the 'slave only' peripheral, while others have a peripheral that can be set as master or slave. The function was originally introduced to handle the slave peripheral, and kept it's name.
norman_tan



Joined: 30 Jan 2008
Posts: 27

View user's profile Send private message

PostPosted: Sat Dec 16, 2017 9:44 pm     Reply with quote

Dear Ttelmah,
setup_psp() in 18F87J11.h is: _bif void setup_psp(int32 mode);
setup_psp() in 24FJ1128GB108.h is: setup_psp(unsigned int32 mode, unsigned int16 address_mask);
if I call setup_psp(int32 mode) only then I can not set all address port;
if I call setup_psp(unsigned int32 mode, unsigned int16 address_mask) then "Error:58" happens;
the KEY issues in 18f67j11.h are: 1,Can not set the PMP address mode(0x1FFFF); 2, Use "INPUT_D(), OUTPUT_D()" for data operation; 3, Can not set address.

I analyzed those constants in 18 h file as below(sorry for incorrect font format):
REGISTER 12-1&2 PMCONH(PARALLEL PORT CONTROL HIGH BYTE REGISTER) PMCONL(PARALLEL PORT CONTROL LOW BYTE REGISTER)
PMPEN ----- PSIDL ADRMUX1 ADRMUX0 PTBEEN PTWREN PTRDEN CSF1 CSF0 ALP CS2P CS1P BEP WRSP RDSP
bit15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

PMP_RD_ACT_HIGH = 0101 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
PMP_WR_ACT_HIGH = 0202 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0
PMP_BE_ACT_HIGH = 0404 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0
PMP_CS1_ACT_HIGH = 0008 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
PMP_CS2_ACT_HIGH = 0010 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
PMP_ADDR_MUX_A_D = 0800 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
PMP_ADDR_MUX_D = 1000 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
PMP_IDLE_OFF = 2000 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0

REGISTER 12-3&4 PMMODEH(PARALLEL PORT MODE HIGH BYTE REGISTER) PMMODEL(PARALLEL PORT MODE LOW BYTE REGISTER) BUSY IRQM1 IRQM0 INCM1 INCM0 MODE16 MODE1 MODE0 WAITB1 WAITB0 WAITM3 WAITM2 WAITM1 WAITM0 WAITE1 WAITE0
bit15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

PMP_ENABLED =0208 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0
PMP_COMBINE_RW =0100 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
PSP_ADDRESS_MODE=0100 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
PSP_NORMAL_MODE =1800 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0
PMP_16_BIT =0400 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0


Though I can add some constants in it, example :
#define PAR_MASTER_MODE_1 0x03000000 // Master mode 1
#define PAR_MASTER_MODE_2 0x02000000 // Master mode 2
but I still worry there are some libraries/link ignored.

and constants for registers PMEH&PMEL can not be found in 18.h file:

REGISTER 12-5:PMEH: PARALLEL PORT ENABLE HIGH BYTE REGISTER
bit 7-6 PTEN<15:14>: PMCSx Strobe Enable bits
1 = PMA15 and PMA14 function as either PMA<15:14> or PMCS2 and PMCS1
0 = PMA15 and PMA14 function as port I/O
bit 5-0 PTEN<13:8>: PMP Address Port Enable bits
1 = PMA<13:8> function as PMP address

REGISTER 12-6:PMEL: PARALLEL PORT ENABLE LOW BYTE REGISTER
bit 7-2 PTEN<7:2>: PMP Address Port Enable bits
1 = PMA<7:2> function as PMP address lines
0 = PMA<7:2> function as port I/O
bit 1-0 PTEN<1:0>: PMALH/PMALL Strobe Enable bits
1 = PMA1 and PMA0 function as either PMA<1:0>

10 days ago I sent this issue by email to CCS support, but it is still the same answer as before: "The e-mail has been reviewed, however, an answer is not yet ready. A priority has not yet been determined for this issue."
Let it be. Evil or Very Mad
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun Dec 17, 2017 1:00 am     Reply with quote

I showed how to set the address mask earlier. Use the register direct access for this. It is much easier.
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