S12MSCANV2 How to access transmit buffer space?

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

S12MSCANV2 How to access transmit buffer space?

Jump to solution
1,008 Views
joel5
Contributor I

This is regarding a 9S12DJ128.  I am trying to implement a design using the CAN module in order to control an instrument panel cluster for a simulator.  I am writing the code directly in assembly language and not using an API.  The memory map for my processor for CAN0 is from $0140 - $017F.  Various configuration registers are defined from $0140 - $015F.  The receive foreground register is 16 bytes:  $0160 - $016F.  The transmit foreground register is 16 bytes:  $0170 - $017F.  Then, CAN1 takes over from $0180 - $01BF. 

 

Documentation states that there are 3 transmit buffers that are addressable by the CPU.  However, memory mapping only shows one, from $0170 - $017F.  Does anyone know how to address all of the transmit buffers?  There are transmit buffer select bits in the CANTBSEL register:  TX2 - TX0.  It states:  The lowest numbered bit places the respective transmit buffer in the CANTXFG ($0170 - $017F) register space.

 

My question is, how does the CPU know where the 3 transmit buffers are located?  I.e., how can I load a message into either transmit buffer 1 or 2 or 3, when I don't even know where it is mapped in memory?

 

I appreciate the help of anyone with expertise in this area.

 

Joel

Labels (1)
0 Kudos
Reply
1 Solution
807 Views
RadekS
NXP Employee
NXP Employee

It is simply, there are three 3 tx buffers which shares one space in memory model. Access is driven by CANTBSEL register.

CANTBSEL register has special feature – when we write and read this register, it will find the lowest ordered bit set to “1”, all other bits will be read as “0”. This feature allows simple code for selecting proper buffer.

Datasheet says:

The application software wants to get the next available transmit buffer. It reads the CANTFLG register and writes this value back into the CANTBSEL register. In this example Tx buffers TX1 and TX2 are available. The value read from CANTFLG is therefore 0b0000_0110. When writing this value back to CANTBSEL the Tx buffer TX1 is selected in the CANTXFG because the lowest numbered bit set to “1” is at bit position 1. Reading back this value out of CANTBSEL results in 0b0000_0010, because only the lowest numbered bit position set to “1” is presented. This mechanism eases the application software the selection of the next available Tx buffer.

LDD CANTFLG; value read is 0b0000_0110

STD CANTBSEL; value written is 0b0000_0110

LDD CANTBSEL; value read is 0b0000_0010

So, you can use this code:

CAN0TBSEL = CAN0TFLG;             /* Select lowest empty buffer */

txbuffer = CAN0TBSEL;                  /* Backup selected buffer */

//fill Tx buffer

CAN0TFLG = txbuffer;                 /* Start transmission */

In attachment you can find simple example code.

Note: example code was created for different S12 MCU, therefore some details doesn’t need to fit, however principle is the same.


View solution in original post

0 Kudos
Reply
2 Replies
808 Views
RadekS
NXP Employee
NXP Employee

It is simply, there are three 3 tx buffers which shares one space in memory model. Access is driven by CANTBSEL register.

CANTBSEL register has special feature – when we write and read this register, it will find the lowest ordered bit set to “1”, all other bits will be read as “0”. This feature allows simple code for selecting proper buffer.

Datasheet says:

The application software wants to get the next available transmit buffer. It reads the CANTFLG register and writes this value back into the CANTBSEL register. In this example Tx buffers TX1 and TX2 are available. The value read from CANTFLG is therefore 0b0000_0110. When writing this value back to CANTBSEL the Tx buffer TX1 is selected in the CANTXFG because the lowest numbered bit set to “1” is at bit position 1. Reading back this value out of CANTBSEL results in 0b0000_0010, because only the lowest numbered bit position set to “1” is presented. This mechanism eases the application software the selection of the next available Tx buffer.

LDD CANTFLG; value read is 0b0000_0110

STD CANTBSEL; value written is 0b0000_0110

LDD CANTBSEL; value read is 0b0000_0010

So, you can use this code:

CAN0TBSEL = CAN0TFLG;             /* Select lowest empty buffer */

txbuffer = CAN0TBSEL;                  /* Backup selected buffer */

//fill Tx buffer

CAN0TFLG = txbuffer;                 /* Start transmission */

In attachment you can find simple example code.

Note: example code was created for different S12 MCU, therefore some details doesn’t need to fit, however principle is the same.


0 Kudos
Reply
807 Views
Lundin
Senior Contributor IV

The 3 tx buffers are a "tripple buffer", one buffer used for the message currently sent, one for the message currently being loaded by software, and one middle buffer in between them, to make continuous CAN transmission possible, without the delays that a double buffer solution would have. Thus it only makes sense to load the message into "a free" tx buffer. This is done by copying the contents of CANTFLG into CANTBSEL. This will "expose" the selected buffer, making it appear at the address of CANTXFG. So you really don't need to concern yourself about there being 3 buffers, the hardware will keep track of them.

I'd strongly recommend to read the whole MSCAN manual in detail before writing any driver for it.