MSCAN Problem... I don't know where!

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

MSCAN Problem... I don't know where!

2,935 Views
RubenCG
Contributor III
Hi all,

We're using mc9sxdp512 MCU and we're trying to use MSCAN module. My rutines are:

void Can0Init (void)
{
  
  CAN0CTL0_INITRQ = 0x01;                // Modo inicializacion
  while(!(CAN0CTL1_INITAK))
  {
    SCI1_OutChar('I');
    SCI1_OutChar(CR);
  }
  CAN0BTR0=0xC1; // 4Tq de Sync Jump Width.
                 // Prescaler 2...125Kbps(4Mhz)
                
  CAN0BTR1=0x3A;  // One sample per bit
                  // Time Segment 1 = 11 Tq
                  // Time Segment 2 = 4 Tq
                  
  CAN0CTL1=0xA0;  // MSCAN enable + LoopBack
  /*
  7 CANE   1
  6 CLKSRC 0
  5 LOOPB  1 
  4 LISTEN 0
  3 BORM   0
  2 WUPM   0
  1 SLPAK  0
  0 INITAK 0
  */
 
  /* Configuracion de los filtros de aceptacion de mensajes*/
  CAN0IDMR0=0xFF;
  CAN0IDMR1=0xFF;
  CAN0IDMR2=0xFF;
  CAN0IDMR3=0xFF;
  CAN0IDMR4=0xFF;
  CAN0IDMR5=0xFF;
  CAN0IDMR6=0xFF;
  CAN0IDMR7=0xFF;
 
  CAN0CTL0=0x00;          // Salir modo inicializacion
  while(CAN0CTL1_INITAK)
  {
  };
 
  CAN0RIER=0x01; // ON Rx Interrupts
 
  INT_CFADDR=  INTVECT_CAN0RX & 0xF0;
  INT_CFDATA_ARR[(INTVECT_CAN0RX & 0x0F) >> 1]= 0x04;
 
  INT_CFADDR=  INTVECT_CAN0TX & 0xF0;
  INT_CFDATA_ARR[(INTVECT_CAN0TX & 0x0F) >> 1]= 0x04;
}

void CAN0_InBuffer(void)
{
 
  unsigned char i;
 
  while((CAN0RFLG & CAN0RFLG_RXF_MASK)== 0){};
  CanRx_Store.DLR = CAN0RXDLR & 0x0F;

  for(i=0;i<CanRx_Store.DLR;i++)
  {
    CanRx_Store.Data[i]=*(&CAN0RXDSR0+i);   
  }
  CAN0RFLG=0x01;
}

void CAN0_OutBuffer(struct Can_struct Tx_struct)
{
 
  unsigned char i, txbuffer;
 
  //Libre Buffer0?
 
 if(CAN0TFLG_TXE0==1)
 {
  // Buffer0 libre
  Stop_CAN0_Tx(0); // Deshabilita las interrupciones por el Buffer0
 
  CAN0TBSEL=CAN0TFLG;
  txbuffer=CAN0TBSEL; 
 
  CAN0TXIDR0 = Tx_struct.ID;
  CAN0TXDLR = Tx_struct.DLR;
  CAN0TXTBPR = Tx_struct.Priority;
  for(i=0;i<Tx_struct.DLR;i++)
  {
    // Relleno el buffer de salida
    *(&CAN0TXDSR0+i)=Tx_struct.Data[i];
  }
  CAN0TFLG=txbuffer; // Clear TXE flag
  Start_CAN0_Tx(0); // Habilita las interrupciones en el Buffer0
 }
 
 //Libre Buffer1?
 
 else if(CAN0TFLG_TXE1==1)
 {
  // Buffer1 libre
  Stop_CAN0_Tx(1); // Deshabilita las interrupciones por el Buffer0
 
  CAN0TBSEL=CAN0TFLG;
  txbuffer=CAN0TBSEL;
 
  CAN0TXIDR0 = Tx_struct.ID;
  CAN0TXDLR = Tx_struct.DLR;
  CAN0TXTBPR = Tx_struct.Priority;
  for(i=0;i<Tx_struct.DLR;i++)
  {
    // Relleno el buffer de salida
    *(&CAN0TXDSR0+i)=Tx_struct.Data[i];
  }
  CAN0TFLG=txbuffer; // Clear TXE flag
  Start_CAN0_Tx(1); // Habilita las interrupciones en el Buffer1
 }
 
 //Libre Buffer2?
 
 else if(CAN0TFLG_TXE2==1)
 {
  // Buffer2 libre
  Stop_CAN0_Tx(2); // Deshabilita las interrupciones por el Buffer0
 
  CAN0TBSEL=CAN0TFLG;
  txbuffer=CAN0TBSEL;
 
  CAN0TXIDR0 = Tx_struct.ID;
  CAN0TXDLR = Tx_struct.DLR;
  CAN0TXTBPR = Tx_struct.Priority;
  for(i=0;i<Tx_struct.DLR;i++)
  {
    // Relleno el buffer de salida
    *(&CAN0TXDSR0+i)=Tx_struct.Data[i];
  }
  CAN0TFLG=txbuffer; // Clear TXE flag
  Start_CAN0_Tx(2); // Habilita las interrupciones en el Buffer02
 }   
}

void Start_CAN0_Tx(unsigned char buffer)
{
  // On Tx interrupts en CAN0
  switch(buffer)
  {
    case 0x00:
      CAN0TIER_TXEIE0=0x01; // ON Buffer 0
      break;
    case 0x01:
      CAN0TIER_TXEIE1=0x01; // ON Buffer 1
      break;
    case 0x02:
      CAN0TIER_TXEIE2=0x01; // ON Buffer 2
      break;
    case 0x03:
      CAN0TIER_TXEIE0=0x01; // ON Buffer 0 
      CAN0TIER_TXEIE1=0x01; // ON Buffer 1 
      CAN0TIER_TXEIE2=0x01; // ON Buffer 2 
      break;
    default:
      break;
  } 
}

void Stop_CAN0_Tx(unsigned char buffer)
{
  // OFF Tx Interrupts
  switch(buffer)
  {
    case 0:
      CAN0TIER_TXEIE0=0x00; // OFF Buffer 0
      break;
    case 1:
      CAN0TIER_TXEIE1=0x00; // OFF Buffer 1
      break;
    case 2:
      CAN0TIER_TXEIE2=0x00; // OFF Buffer 2
      break;
    case 3:
      CAN0TIER_TXEIE0=0x00; // OFF Buffer 0 
      CAN0TIER_TXEIE1=0x00; // OFF Buffer 1 
      CAN0TIER_TXEIE2=0x00; // OFF Buffer 2 
      break;
    default:
      break;
  }
}

What is the problem? It seems that TX part works fine but in RX arrives data but not good-data.

Can anyone help me? I know these forums is the unique place in the world where I can find my solution... at least my last problems have been solved!






Labels (1)
0 Kudos
7 Replies

670 Views
kef
Specialist I
Is it OK that loopback mode is on.
0 Kudos

670 Views
RubenCG
Contributor III
Hi,

Yes, I switched ON the loopback mode to test my software without BUS.

I don't understand why my software doesn't work properly, it's very simple.

Thanks,
Rbn
0 Kudos

670 Views
harry_haeusern
Contributor I
I see you initialize the RX interrupt. But why you use polling mechanisme in CAN0_InBuffer() by testing CAN0RFLG_RXF_MASK?
Can you specify more, how the CAN-data is corupted and is the receiced CAN-ID correct?
 
0 Kudos

669 Views
RubenCG
Contributor III
Hi Harry,

It know that the test of RXF bit is NOT absolutely necessary, the routine works with and without this bit-testing. If the Rx-interrupt comes the RXF-bit is set by CPU.

Information:

CAN0IDMR0=0xFF;
CAN0IDMR1=0xFF;
CAN0IDMR2=0xFF;
CAN0IDMR3=0xFF;
CAN0IDMR4=0xFF;
CAN0IDMR5=0xFF;
CAN0IDMR6=0xFF;
CAN0IDMR7=0xFF;

So, I think the CAN-ID doesn't matter.

Tx-Data in bytes: 0x01 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0x02
Rx-Data in bytes: 0x87 0xC9 0xDD 0xDD 0xDD 0xDD 0xDD 0x02

To be sincere I don't know if the problem is Tx or Rx. Perhaps the routine in interrupts are not properly. Hace you any example (CanRx-interrupt or Tx.interrupt) to compare code?

Thanks for your interest,
Rbn

0 Kudos

669 Views
harry_haeusern
Contributor I
I wrote a CAN-Driver for HC9S12C32, this is base on CAN-module MSCAN12 (uC MC9S12C32)
 
if you are interested I can send it to you?
 

 
 

 
0 Kudos

670 Views
RubenCG
Contributor III
I think it could be positive for me, I've read my code 100 times and I can't find my errors... too much for me!

My email is rcampog@icf.com.es


Thank you once again,
Rbn

0 Kudos

669 Views
RubenCG
Contributor III
Harry... You were right last email, the problem was the ID. I tried to use Standard ID and all the mask are 0xFF but when I fill CAN0IDR0, CAN0IDR1, CAN0IDR2, CAN0IDR3 with 0x00 the problem has disappeared.

Can you explain me what was the problem? If the ID didn't match, why the RXF flag is set and the RX-Interrupt is requested?... for me is unexplained!

If you have any problem I'm still interested in reading your CAN-drive.

Really thanks, I hope I can help you in the future.
Rbn  

0 Kudos