Go Down

Topic: LIN Bus with CYPRESS CY8CKIT-026 and Arduino Uno or Due (Read 156 times) previous topic - next topic

McMathin

Good morning at all.
I'm a real beginner and I started with the "Arduino story" three weeks ago. During my studies I programmed a bit on Java so I know about the programming basics, but I'm not so familar with it.

My actual project is, to create a small LIN (Local Interconnect Network) with one master and two slaves, and send some messages between them

The messages are not yet defined, but they should control a LED, a servo motor, check a potentiometer and maybe a thermistor. So these points are a bit "open".

The hardware I have:
- Arduino Uno R3 SMD edition (3x)
- Arduino Due R3 (1x)
- Cypress CY8CKIT-026 Can- and LIN-Shield board (3x) http://www.cypress.com/documentation/development-kitsboards/cy8ckit-026-can-and-lin-shield-kit
- Cypress CY8CKIT-042 development board (1x) http://www.cypress.com/documentation/development-kitsboards/cy8ckit-042-psoc-4-pioneer-kit
- PEAK PCAN-USB Pro FD for CAN and LIN (1x) http://www.peak-system.com/PCAN-USB-Pro-FD.366.0.html
- serveral LEDs, a servo motor, a sensor kit, a LCD 16x2 (direct controlled via SDA and SCL), ...

I have to create a small thesis for my actual studies on a functionating LIN bus, where I only add the messages and the hardware like LEDs etc.

I searched and read a lot on forums about existing LINs but I didn't find a proper solution for my actual task. From my point of view, one of the most interesting and maybe functionating post is this: https://github.com/macchina/LIN
But I have to modifiy the code and I'm not able to, because of my programming knowlegde.

The LIN-Transceiver on the Cypress-board is a TJA 1020. http://www.nxp.com/docs/en/data-sheet/TJA1020.pdf?pspll=1
I also found some threads with an TJA 1021, which is basically equal to the TJA 1020.

So, is here anybody who can help with a working LIN bus either with the Uno or the Due? Does anyone have a working code or can modify the GitHub-example?
If I/we found out, that it will only work with the Due, than the university will buy additional Dues.

Just for your information: The idea of the project is from my professor, because the actual LIN bus, which the students work with, is not modificable. And with the arduino-platform there is much more modification possible, also in the future. The first toughts were, to put the Cypress LIN-Shield onto the Uno and put an existing code on it. Than modifiy the messages, if it is working. For my small thesis it is not necessary, to build an arduino library or the complete code.

Many thanks in advance!
McMathin

ard_newbie

#1
Aug 20, 2017, 05:06 pm Last Edit: Aug 20, 2017, 05:09 pm by ard_newbie
AFAIK Arduino DUE USART0 supports LIN Mode.
See section 35.7.8 page 805 of SAM3x datasheet.


You can see related LIN USART0 functions in:
https://github.com/avrxml/asf/blob/master/sam/drivers/usart/usart.c


Code: [Select]

#if (SAM3XA || SAM4L || SAMG55 || SAMV71 || SAMV70 || SAME70 || SAMS70)

/**
 * \brief Configure USART to work in LIN mode and act as a LIN master.
 *
 * \note By default, the transmitter and receiver aren't enabled.
 *
 * \param p_usart Pointer to a USART instance.
 * \param ul_baudrate Baudrate to be used.
 * \param ul_mck USART module input clock frequency.
 *
 * \retval 0 on success.
 * \retval 1 on failure.
 */
uint32_t usart_init_lin_master(Usart *p_usart,uint32_t ul_baudrate,
    uint32_t ul_mck)
{
  /* Reset the USART and shut down TX and RX. */
  usart_reset(p_usart);

  /* Set up the baudrate. */
  if (usart_set_async_baudrate(p_usart, ul_baudrate, ul_mck)) {
    return 1;
  }

  /* Set LIN master mode. */
  p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
      US_MR_USART_MODE_LIN_MASTER;

  usart_enable_rx(p_usart);
  usart_enable_tx(p_usart);

  return 0;
}

/**
 * \brief Configure USART to work in LIN mode and act as a LIN slave.
 *
 * \note By default, the transmitter and receiver aren't enabled.
 *
 * \param p_usart Pointer to a USART instance.
 * \param ul_baudrate Baudrate to be used.
 * \param ul_mck USART module input clock frequency.
 *
 * \retval 0 on success.
 * \retval 1 on failure.
 */
uint32_t usart_init_lin_slave(Usart *p_usart, uint32_t ul_baudrate,
    uint32_t ul_mck)
{
  /* Reset the USART and shut down TX and RX. */
  usart_reset(p_usart);

  usart_enable_rx(p_usart);
  usart_enable_tx(p_usart);

  /* Set LIN slave mode. */
  p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) |
      US_MR_USART_MODE_LIN_SLAVE;

  /* Set up the baudrate. */
  if (usart_set_async_baudrate(p_usart, ul_baudrate, ul_mck)) {
    return 1;
  }

  return 0;
}

/**
 * \brief Abort the current LIN transmission.
 *
 * \param p_usart Pointer to a USART instance.
 */
void usart_lin_abort_tx(Usart *p_usart)
{
  p_usart->US_CR = US_CR_LINABT;
}

/**
 * \brief Send a wakeup signal on the LIN bus.
 *
 * \param p_usart Pointer to a USART instance.
 */
void usart_lin_send_wakeup_signal(Usart *p_usart)
{
  p_usart->US_CR = US_CR_LINWKUP;
}

/**
 * \brief Configure the LIN node action, which should be one of PUBLISH,
 * SUBSCRIBE or IGNORE.
 *
 * \param p_usart Pointer to a USART instance.
 * \param uc_action 0 for PUBLISH, 1 for SUBSCRIBE, 2 for IGNORE.
 */
void usart_lin_set_node_action(Usart *p_usart, uint8_t uc_action)
{
  p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_NACT_Msk) |
      (uc_action << US_LINMR_NACT_Pos);
}

/**
 * \brief Disable the parity check during the LIN communication.
 *
 * \param p_usart Pointer to a USART instance.
 */
void usart_lin_disable_parity(Usart *p_usart)
{
  p_usart->US_LINMR |= US_LINMR_PARDIS;
}

/**
 * \brief Enable the parity check during the LIN communication.
 *
 * \param p_usart Pointer to a USART instance.
 */
void usart_lin_enable_parity(Usart *p_usart)
{
  p_usart->US_LINMR &= ~US_LINMR_PARDIS;
}

/**
 * \brief Disable the checksum during the LIN communication.
 *
 * \param p_usart Pointer to a USART instance.
 */
void usart_lin_disable_checksum(Usart *p_usart)
{
  p_usart->US_LINMR |= US_LINMR_CHKDIS;
}

/**
 * \brief Enable the checksum during the LIN communication.
 *
 * \param p_usart Pointer to a USART instance.
 */
void usart_lin_enable_checksum(Usart *p_usart)
{
  p_usart->US_LINMR &= ~US_LINMR_CHKDIS;
}

/**
 * \brief Configure the checksum type during the LIN communication.
 *
 * \param p_usart Pointer to a USART instance.
 * \param uc_type 0 for LIN 2.0 Enhanced checksum or 1 for LIN 1.3 Classic
 *  checksum.
 */
void usart_lin_set_checksum_type(Usart *p_usart, uint8_t uc_type)
{
  p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_CHKTYP) |
      (uc_type << 4);
}

/**
 * \brief Configure the data length mode during the LIN communication.
 *
 * \param p_usart Pointer to a USART instance.
 * \param uc_mode Indicate the data length type: 0 if the data length is
 * defined by the DLC of LIN mode register or 1 if the data length is defined
 * by the bit 5 and 6 of the identifier.
 */
void usart_lin_set_data_len_mode(Usart *p_usart, uint8_t uc_mode)
{
  p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_DLM) |
      (uc_mode << 5);
}

/**
 * \brief Disable the frame slot mode during the LIN communication.
 *
 * \param p_usart Pointer to a USART instance.
 */
void usart_lin_disable_frame_slot(Usart *p_usart)
{
  p_usart->US_LINMR |= US_LINMR_FSDIS;
}

/**
 * \brief Enable the frame slot mode during the LIN communication.
 *
 * \param p_usart Pointer to a USART instance.
 */
void usart_lin_enable_frame_slot(Usart *p_usart)
{
  p_usart->US_LINMR &= ~US_LINMR_FSDIS;
}

/**
 * \brief Configure the wakeup signal type during the LIN communication.
 *
 * \param p_usart Pointer to a USART instance.
 * \param uc_type Indicate the checksum type: 0 if the wakeup signal is a
 * LIN 2.0 wakeup signal; 1 if the wakeup signal is a LIN 1.3 wakeup signal.
 */
void usart_lin_set_wakeup_signal_type(Usart *p_usart, uint8_t uc_type)
{
  p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_WKUPTYP) |
      (uc_type << 7);
}

/**
 * \brief Configure the response data length if the data length is defined by
 * the DLC field during the LIN communication.
 *
 * \param p_usart Pointer to a USART instance.
 * \param uc_len Indicate the response data length.
 */
void usart_lin_set_response_data_len(Usart *p_usart, uint8_t uc_len)
{
  p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_DLC_Msk) |
      ((uc_len - 1) << US_LINMR_DLC_Pos);
}

/**
 * \brief The LIN mode register is not written by the PDC.
 *
 * \param p_usart Pointer to a USART instance.
 */
void usart_lin_disable_pdc_mode(Usart *p_usart)
{
  p_usart->US_LINMR &= ~US_LINMR_PDCM;
}

/**
 * \brief The LIN mode register (except this flag) is written by the PDC.
 *
 * \param p_usart Pointer to a USART instance.
 */
void usart_lin_enable_pdc_mode(Usart *p_usart)
{
  p_usart->US_LINMR |= US_LINMR_PDCM;
}

/**
 * \brief Configure the LIN identifier when USART works in LIN master mode.
 *
 * \param p_usart Pointer to a USART instance.
 * \param uc_id The identifier to be transmitted.
 */
void usart_lin_set_tx_identifier(Usart *p_usart, uint8_t uc_id)
{
  p_usart->US_LINIR = (p_usart->US_LINIR & ~US_LINIR_IDCHR_Msk) |
      US_LINIR_IDCHR(uc_id);
}

/**
 * \brief Read the identifier when USART works in LIN mode.
 *
 * \param p_usart Pointer to a USART instance.
 *
 * \return The last identifier received in LIN slave mode or the last
 * identifier transmitted in LIN master mode.
 */
uint8_t usart_lin_read_identifier(Usart *p_usart)
{
  return (p_usart->US_LINIR & US_LINIR_IDCHR_Msk);
}

/**
 * \brief Get data length.
 *
 * \param p_usart Pointer to a USART instance.
 *
 * \return Data length.
 */
uint8_t usart_lin_get_data_length(Usart *usart)
{
  if (usart->US_LINMR & US_LINMR_DLM) {
    uint8_t data_length = 1 << ((usart->US_LINIR >>
        (US_LINIR_IDCHR_Pos + 4)) & 0x03);
    return data_length;
  } else {
    return ((usart->US_LINMR & US_LINMR_DLC_Msk) >> US_LINMR_DLC_Pos) + 1;
  }
}

#endif






Go Up