How to modify ASF "CAN-LIN-LOOPBACKS-DEMO" for two nodes on one channel !!

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hallo,

 

I have modified the ASF "CAN-LIN-LOOPBACKS-DEMO" to work on two nodes by using two channels (tow can buses), RX on channel1 and TX on channel0 for both of two nodes!!

 

Now how can i modify it so that it works on one channel(one can bus) instead of two channels !!?

 

I am using AT32UC3C-EK board with 32-bit AT32UC3C0512C microcontroller.

 

Thank you

 

 

Last Edited: Tue. Sep 26, 2017 - 07:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hallo,

 

i have modified can_task.c in ASF "CAN-LIN-LOOPBACKS-DEMO" to work on two nodes by using one channel but it didn't work !!

would you help me please !!?

 

Thank you !!

 

 

//can_task.c

#include <stddef.h>
#include <stdio.h>
#include <avr32/io.h>
#include "compiler.h"
#include "board.h"
#include "power_clocks_lib.h"
#include "gpio.h"
#include "pm_uc3c.h"
#include "scif_uc3c.h"
#include "print_funcs.h"
#include "can_task.h"
#include "conf_can_task.h"
#include "dsp.h"
#include "conf_demo.h"
#include <asf.h>
#include "flashc.h"

//! Local Mob Declaration
can_msg_t mob_ram_ch0[NB_MOB_CHANNEL];
/*can_msg_t mob_ram_ch1[NB_MOB_CHANNEL];*/

//! Local function to prepare RX and TX buffers
void can_example_prepare_data_to_send_and_receive(void);
void can_out_callback_transmission_and_reception(U8 handle, U8 event);
//! External reference on ADC Current Conversion
extern volatile uint16_t adc_current_conversion;

//! Buffer to store ADC Conversions
A_ALIGNED dsp16_t signal3_buf[BUFFER_LENGTH];

//! Boolean for message transmitted on CAN channel 0
volatile bool message_transmitted_on_channel0 = false;

//! Boolean for message received on CAN channel 0
volatile bool message_received_on_channel0 = false;

/*! \brief CAN Call Back when message is transmitted
 *
 */
void can_out_callback_transmission_and_reception(U8 handle, U8 event)
{
 gpio_tgl_gpio_pin(LED2_GPIO);
 // Transmission Only
 can_mob_free(0,handle);
 message_transmitted_on_channel0 = true;
 
 gpio_tgl_gpio_pin(LED3_GPIO);
 // Reception Only
 pCANMOB_message2[0].can_msg->data.u64 = can_get_mob_data(0,handle).u64;
 pCANMOB_message2[0].can_msg->id = can_get_mob_id(0,handle);
 pCANMOB_message2[0].dlc = can_get_mob_dlc(0,handle);
 pCANMOB_message2[0].status = event;
 can_mob_free(0,handle);
 message_received_on_channel0 = true;
}

/*! \brief CAN Call Back when message is received
 */
void can_out_callback_reception(U8 handle, U8 event)
{
 gpio_tgl_gpio_pin(LED3_GPIO);
 // Reception Only
 pCANMOB_message2[0].can_msg->data.u64 = can_get_mob_data(0,handle).u64;
 pCANMOB_message2[0].can_msg->id = can_get_mob_id(0,handle);
 pCANMOB_message2[0].dlc = can_get_mob_dlc(0,handle);
 pCANMOB_message2[0].status = event;
 can_mob_free(0,handle);
 message_received_on_channel0 = true;
}

void can_task_init(void)
{
 // Setup the generic clock for CAN
 scif_gc_setup(AVR32_SCIF_GCLK_CANIF,
  SCIF_GCCTRL_OSC0,
  AVR32_SCIF_GC_NO_DIV_CLOCK,
  0);
 // Now enable the generic clock
 scif_gc_enable(AVR32_SCIF_GCLK_CANIF);
 static const gpio_map_t CAN_GPIO_MAP = {
  {AVR32_CANIF_RXLINE_0_0_PIN, AVR32_CANIF_RXLINE_0_0_FUNCTION},
  {AVR32_CANIF_TXLINE_0_0_PIN, AVR32_CANIF_TXLINE_0_0_FUNCTION},
  {AVR32_CANIF_RXLINE_1_2_PIN, AVR32_CANIF_RXLINE_1_2_FUNCTION},
  {AVR32_CANIF_TXLINE_1_2_PIN, AVR32_CANIF_TXLINE_1_2_FUNCTION}
 };
 // Assign GPIO to CAN.
 gpio_enable_module(CAN_GPIO_MAP,
  sizeof(CAN_GPIO_MAP) / sizeof(CAN_GPIO_MAP[0]));

 can_example_prepare_data_to_send_and_receive();
}

/*! \brief CAN Task:
 *        - Check if messages are correctly transmitted/received
 *        - Update message for transmission/reception
 */

// Prepare one mob for TX
void prepare_one_mob_for_tx(void)
{
 pCANMOB_message0[0].handle = can_mob_alloc(0); // ADC

 // Check return if no mob are available
 if (pCANMOB_message0[0].handle==CAN_CMD_REFUSED) {
  while(true);
 }
 pCANMOB_message0[0].can_msg->data.u8[0] =
 ((adc_current_conversion&0xFF00)>>8);
 pCANMOB_message0[0].can_msg->data.u8[1] =
 (adc_current_conversion&0xFF);
   
 can_tx(0,
 pCANMOB_message0[0].handle,
 pCANMOB_message0[0].dlc,
 pCANMOB_message0[0].req_type,
 pCANMOB_message0[0].can_msg);
}

// Prepare one mob for RX
void prepare_one_mob_for_rx(void)
{
pCANMOB_message2[0].handle = can_mob_alloc(0);

can_rx(0,
pCANMOB_message2[0].handle,
pCANMOB_message2[0].req_type,
pCANMOB_message2[0].can_msg);
}

void can_task(void)
{
int16_t i;
int16_t value;
 if (message_transmitted_on_channel0 == true) {
  message_transmitted_on_channel0 = false;

  prepare_one_mob_for_tx(); 
  }
  
 if (message_received_on_channel0 == true) {
  message_received_on_channel0 = false;
  for (i=BUFFER_LENGTH-1;i>=1;i--) {
  signal3_buf[i] = signal3_buf[i-1];
  }
  value = (pCANMOB_message2[0].can_msg->data.u8[0]<<8)| \
  (pCANMOB_message2[0].can_msg->data.u8[1]);
  signal3_buf[0] = ( value*0x20) - 0x8000;
  
  prepare_one_mob_for_rx();
 }
}

/*! \brief CAN Prepare Data to Send
 *        - Allocate one MOB in transmission
 *        - Fill the MOB with the correct DATA
 *        - Start the transmission
 */
void can_example_prepare_data_to_send_and_receive(void)
{
 // Initialize channel 0 for transmission
 can_init(0,
  ((U32)&mob_ram_ch0[0]),
  CANIF_CHANNEL_MODE_NORMAL,
  can_out_callback_transmission_and_reception);

 prepare_one_mob_for_tx();
 
 prepare_one_mob_for_rx();
}

/*! \brief CAN Prepare Data to Receive
 *        - Allocate one MOB in reception
 *        - Start the reception
 */
void can_example_prepare_data_to_receive(void)
{
 // Initialize channel 0 for reception
  can_init(0,
   ((U32)&mob_ram_ch0[0]),
   CANIF_CHANNEL_MODE_NORMAL,
   can_out_callback_reception);
  
 prepare_one_mob_for_rx();
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have not used the CANIF but I cannot see where you set the address(es) for the destination device(s).
can_mob_t contains a pointer to a can_msg_t structure.
can_msg_t contains a field called id

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you mikech for your reply....

 

Now changing the potentiometer value on one node is displayed on the LCD screen from the node itself !!?

can_mob_t and can_msg_t ​are in the following file called conf_can_task.h :

 

// conf_can_task.h

#ifndef _CONF_CAN_EXAMPLE_H
#define _CONF_CAN_EXAMPLE_H

//_____ I N C L U D E S ________________________________________________________
#include "avr32/io.h"
#include "compiler.h"
#include "can.h"
#include "board.h"

/*
 *
 */
#define STDIO_USART                     (&AVR32_USART2)
#define STDIO_USART_RX_PIN              AVR32_USART2_RXD_0_1_PIN
#define STDIO_USART_RX_FUNCTION         AVR32_USART2_RXD_0_1_FUNCTION
#define STDIO_USART_TX_PIN              AVR32_USART2_TXD_0_1_PIN
#define STDIO_USART_TX_FUNCTION         AVR32_USART2_TXD_0_1_FUNCTION
#define STDIO_USART_BAUDRATE            57600
#define STDIO_USART_IRQ                 AVR32_USART2_IRQ
#define STDIO_USART_IRQ_LEVEL           AVR32_INTC_INT1
/*
 *
 */
#if defined (__ICCAVR32__)
can_msg_t msg_tx_sot =
{
    0x133,                    // Identifier
    0x1ff,                    // Mask
    0x0102030405060708LL,     // Data
};
#else
can_msg_t msg_tx_sot =
{
  {
    {
      .id = 0x133,                    // Identifier
      .id_mask  = 0x1ff,              // Mask
    },
  },
 .data.u64 = 0x0102030405060708LL,    // Data
};
#endif

can_mob_t pCANMOB_message0[10] = {
                                    {
                                      CAN_MOB_NOT_ALLOCATED,
                                      &msg_tx_sot,
                                      8,
                                      CAN_DATA_FRAME,
                                      CAN_STATUS_NOT_COMPLETED
                                    },
                               };

#if defined (__ICCAVR32__)
can_msg_t msg_rx_listening =
{
     0,                // Identifier
     0,                // Mask
     0x0LL,            // Data
};
#else
can_msg_t msg_rx_listening =
{
  {
    {
      .id = 0,                      // Identifier
      .id_mask  = 0,                // Mask
    },
  },
 .data.u64 = 0x0LL,                 // Data
};
#endif

can_mob_t pCANMOB_message2[1] = {
                                  {CAN_MOB_NOT_ALLOCATED,&msg_rx_listening,0,CAN_DATA_FRAME,CAN_STATUS_NOT_COMPLETED}
                                 };

 

Last Edited: Mon. Oct 2, 2017 - 08:38 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So have you used the debugger to watch what's happening internally?

 

Or added prints to trace what's happening ... ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you awneil for your reply....

 

What do you mean adding prints? because i have no experience with Atmel Studio7 as well as with CAN bus!!

 

I think, the interrupt callback does not now if it is transmission or reception !!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Raaa wrote:
What do you mean adding prints? 

I mean sending messages out of the UART - so that you can watch / capture / analyse on a terminal

 

because i have no experience with Atmel Studio7

This has nothing to do with Atmel Studio - after blinking LEDs, it must be the most basic debug technique

 

http://www.avrfreaks.net/comment...

 

http://www.avrfreaks.net/comment...