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.
Solved! Go to Solution.
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
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
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.
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;
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.