What enables the alternative function on port M

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

What enables the alternative function on port M

Jump to solution
799 Views
buhas
Contributor I

I have an S12XE micro and I am trying to reverse engineer how the micro to DSP

SPI communication works.

 

Port M is configured to drive the SPI0 signals to a DSP (Balckfin) so it can

download the DSP image while the S12XE SPI0 is in Master mode.

 

So these are the PTM2/PTM3/PTM4/PTM5 pins (which are supposedly configured to drive

the SCK0/MISO0/SS0/MOSI0 signals to the DSP.

 

How is the "alternative" function of these pins programmed in the XE ?

How is the priority of the other "alternative" function of these pins determined?

 

If I enable just bit 6 (SPE) in the SPICR1 register, does that mean the SPI "alternative"

function is selected ?

 

Now if I enable the CAN2 module, does it mean the priority is now changed and the same

pins are driving TXCAN0/RXCAN0 ?

 

I am having trouble understandiung the concept of "routed" SPI 0, routed CAN0, etc. Below

is the excerpt from the S12XE documentation.

 

======================================================================================

Port M general purpose input/output data—Data Register

Port M pin 5 is associated with the TXCAN signal of CAN2 and the routed CAN4 and CAN0, as well as with SCK

signals of SPI0. The CAN2 function takes precedence over the routed CAN0, routed CAN4, the routed SPI0 and the general purpose

I/O function if the CAN2 module is enabled. The routed CAN0 function takes precedence over the routed CAN4, the

routed SPI0 and the general purpose I/O function if the routed CAN0 module is enabled. The routed CAN4 function

takes precedence over the routed SPI0 and general purpose I/O function if the routed CAN4 module is enabled. The

routed SPI0 function takes precedence of the general purpose I/O function if the routed SPI0 is enabled.

When not used with the alternative function, this pin can be used as general purpose I/O.

If the associated data direction bit of this pin is set to 1, a read returns the value of the port register, otherwise the

buffered pin input state is read.

Labels (1)
0 Kudos
1 Solution
598 Views
lama
NXP TechSupport
NXP TechSupport

Yes Edward is right,

just to add 2.3.44 Module Routing Register (MODRR)

MC9S12XEP100RMV1

Rev. 1.25

02/2013

http://cache.freescale.com/files/microcontrollers/doc/data_sheet/MC9S12XEP100RMV1.pdf

View solution in original post

0 Kudos
4 Replies
599 Views
lama
NXP TechSupport
NXP TechSupport

Yes Edward is right,

just to add 2.3.44 Module Routing Register (MODRR)

MC9S12XEP100RMV1

Rev. 1.25

02/2013

http://cache.freescale.com/files/microcontrollers/doc/data_sheet/MC9S12XEP100RMV1.pdf

0 Kudos
598 Views
buhas
Contributor I

Thanks for the replies.

I set MODRR to 0x10. This enables the SPI0 function via port M pins 2,3,4,5.

I enable the SPI control registers as follows:

SPI0CR1 = 0x56

SPI0CR2 = 0x10

SPIBR = 0x20

Based on the documentation, the Port M register pin directions are forced to be input/output

accordingly based on the MODRR register setting. I expect the following to be the case:

PM2 -> SPI_MISO - input

PM3 -> SPI_SS - output

PM4 -> SPI_MOSI - output

PM5 -> SPI_SCK - output

Additionally I also set DDRM as:

DDRM = 0x38

On the other side of the SPI I have a Blackfin BF531 setup via hardware to boot-up via SPI.

The code to write to the SPI data register is below:

       ldab  CTBF_buffer
        clra
        tx_wait_loop_1:
        //JW hier noch mal nach den Registern SPI0SR, SPI0DR schauen!
        brclr SPI0SR,32,tx_wait_loop_1
        stab  SPI0DR
        addd  CTBF_checksum
        std   CTBF_checksum

        /* transmit second byte and add to checksum */
        ldab  CTBF_buffer:1
        clra
        tx_wait_loop_2:
        brclr SPI0SR,32,tx_wait_loop_2
        stab  SPI0DR
        addd  CTBF_checksum
       

std   CTBF_checksum

There is a backpressure line from the DSP (SPI_CTRL_0). Based on the analyzer trace this signal

is always low, so no problem. We use Port S pin 0 for this signal. The DDRS register is set as follows:

DDRS = 0xFC

Problem is I never see the SPI0 signals being driven. All I see is the SPI_SCK being driven to 0 for 1.291ms

once.

I compile my project with CodeWarrior compiler ver 5.1.

Strangest part of all this is that I have an almost identical code base compiled with the Cosmic compiler

that boots the DSP just fine on the same hardware. We triple checked all the S12X registers and they are

identical.

I am running out of ideas what to look at next.

0 Kudos
598 Views
buhas
Contributor I

I was able to find the problem but still looking to understand completely

why it is happenning.

An _IO8 macro was replaced with an _IO16 macro to do a Write to the SPI Data

register. This code change was made when changing from the S12XD

processor to the S12XE processor. The "x256.h" file was replaced with the

"me51.h" file. This header file contains the register definitions and I am not sure

of its origin.

/* w SPI0DR $dc SPI1 Data Register*/

//_IO16(SPI0DR,0xdc)      <<<---not working

_IO8(SPI0DR,0xdd)          <<<--working

#  define _IO8(name,offset)  extern volatile u8  (name); /*CRCK_NO_CHECK*/

#  define _IO16(name,offset) extern volatile u16 (name); /*CRCK_NO_CHECK*/

and in the "me51.inc" file I have the following:

_REGBAS   equ $0000

; w SPI0DR $dc SPI1 Data Register

SPI0DR equ (_REGBAS + $dc)

As I mentioned before, the _IO16 write works ok when the same codebase is compiled

with the Cosmic compiler. Yet when compiling with CodeWarriror the _IO16 does not

work.

Here is the assembly code that writes to the SPI Data register

# asm

            /* transmit first byte and add to checksum */

            ldab  CTBF_buffer

            clra

            tx_wait_loop_1:

            //JW hier noch mal nach den Registern SPI0SR, SPI0DR schauen!

            brclr SPI0SR,32,tx_wait_loop_1

            stab  SPI0DR

            addd  CTBF_checksum

            std   CTBF_checksum

            /* transmit second byte and add to checksum */

            ldab  CTBF_buffer:1

            clra

            tx_wait_loop_2:

            brclr SPI0SR,32,tx_wait_loop_2

            stab  SPI0DR

            addd  CTBF_checksum

            std   CTBF_checksum

# endasm

where "CTBF_buffer" is a global defined as follows:

u16 CTBF_buffer = 0;

0 Kudos
598 Views
kef2
Senior Contributor IV

1. On S12XE there are several port routing registers, see their descriptions. 2. After routing peripheral priority is solved by enabling only peripherals which need to be enabled.