Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
BSP/XNucleoPLC01A1.cpp
- Committer:
 - wayky
 - Date:
 - 2021-07-08
 - Revision:
 - 7:48c3b056fa68
 - Parent:
 - 5:0845d4141a01
 
File content as of revision 7:48c3b056fa68:
/**
 ******************************************************************************
 * @file    XNucleoPLC01A1.cpp
 * @author  AST/CL
 * @version V1.1.0
 * @date    February 23rd, 2016
 * @brief   Implementation file for the X_NUCLEO_PLC01A1 expansion board.
 ******************************************************************************
 * @attention
 *
 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *   1. Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *   3. Neither the name of STMicroelectronics nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************
 */
 
 
/* Includes ------------------------------------------------------------------*/
/* ACTION 1 ------------------------------------------------------------------*
 * Include here platform specific header files.                               *
 *----------------------------------------------------------------------------*/
#include "mbed.h"
/* ACTION 2 ------------------------------------------------------------------*
 * Include here expansion board specific header files.                        *
 *----------------------------------------------------------------------------*/
#include "XNucleoPLC01A1.h"
/**
  * @brief      Mirrors input data  
  * @param      Input channel state buffer
  * @retval     Input buffer state
  */
uint8_t XNucleoPLC01A1::signal_mirror(uint8_t In_Array)
{
  return(In_Array);
}
void XNucleoPLC01A1::handle_freeze_to(void)
{
    freezeTo = true;
}
/**
  * @brief      Freeze selected output for a given time
  * @param      Output channels to be freezed
  * @param      Duration of freeze
  * @retval     Output value
  */
uint8_t XNucleoPLC01A1::output_freeze(uint8_t N_Channel, uint16_t msec)
{
  if (freezeTo) {
      timeout.detach();
      return(0x00);
  } else if(!attached) {
      attached = true;
      timeout.attach(this, &XNucleoPLC01A1::handle_freeze_to, msec/1000);
  }
  
  return N_Channel;
}
/**
  * @brief      Regroup output buffer according to out_Array  
  * @param      Regroup array
  * @retval     Value
  */
uint8_t XNucleoPLC01A1::output_regroup(uint8_t Out_Array)
{
  return(Out_Array);
}
/**
  * @brief      Sum all the inputs at high state 
  * @param      Input channel state data
  * @retval     Value corresponding to the sum of inputs at high
  */
uint8_t XNucleoPLC01A1::input_sum(uint8_t* Buffer, uint8_t In_Array)
{
  
  uint8_t inputChannelsOn = 0;
  uint8_t count = 0;
  *Buffer = In_Array;
  for(count = 0; count<8; count++)
  {
    if ((In_Array & 0x01) == 0x01) {
      inputChannelsOn++;
    }
    
    In_Array = In_Array >> 1;
  }
  
  return inputChannelsOn;
  
}
/**
  * @brief      Set the output channels on/off 
  * @param      Output to set
  * @retval     Output value 
  */
uint8_t XNucleoPLC01A1::set_output(uint8_t Out_Array)
{
  return(Out_Array); 
}
/**
  * @brief      AND Inputs for selected output channels
  * @param      Input channels state
  * @param      Outputs to be AND with inputs
  * @retval     Result of AND operation
  */
uint8_t XNucleoPLC01A1::inputs_and(uint8_t In_Array, uint8_t Out_Channel)
{
  uint8_t outArray = 0;
  outArray = In_Array & Out_Channel;
  
  return outArray;
}
/**
  * @brief      OR Inputs for selected output channels
  * @param      Input channels state
  * @param      Outputs to be OR with inputs
  * @retval     Result of OR operation
  */
uint8_t XNucleoPLC01A1::inputs_or(uint8_t In_Array, uint8_t Out_Channel)
{
  uint8_t outArray = 0;
  outArray = In_Array | Out_Channel;
  
  return outArray;
}
/**
  * @brief      NOT Inputs
  * @param      Input channels state
  * @retval     Result of OR operation
  */
uint8_t XNucleoPLC01A1::inputs_not(uint8_t In_Array)
{
  uint8_t outArray = 0;
  In_Array = ~(In_Array);
  outArray = In_Array;
  
  return outArray;
}
/**
  * @brief      XOR Inputs for selected output channels
  * @param      Input channels state
  * @param      Outputs to be XOR with inputs
  * @retval     Result of XOR operation
  */
uint8_t XNucleoPLC01A1::inputs_xor(uint8_t In_Array, uint8_t Out_Channel)
{
  uint8_t outArray = 0;
  outArray = In_Array ^ Out_Channel;
  
  return outArray;
}
/**
  * @brief      Calculate and set parity bits for Ssrelay transmission
  * @param      Output value buffer
  * @retval     None
  */
void XNucleoPLC01A1::output_parity_bits(uint8_t* Buffer)
{
  uint8_t Parity_Cal0 = 0x00;
  uint8_t Parity_Cal1 = 0x00;
  uint8_t Parity_Cal2 = 0x00;
  uint8_t Parity_Cal3 = 0x00;
  uint8_t Parity_Cal4 = 0x00;
  uint8_t Parity_Cal5 = 0x00;
  uint8_t Parity_Cal6 = 0x00;
  uint8_t Parity_Cal7 = 0x00;
  uint8_t nP0 = 0x00;
  uint8_t P0 = 0x00;
  uint8_t P1 = 0x00;
  uint8_t P2 = 0x00;
  Parity_Cal0 = Buffer[1] & 0x80;
  Parity_Cal0 = Parity_Cal0>>7;
  
  Parity_Cal1 = Buffer[1] & 0x40;
  Parity_Cal1 = Parity_Cal1>>6;
  
  Parity_Cal2 = Buffer[1] & 0x20;
  Parity_Cal2 = Parity_Cal2>>5;
  
  Parity_Cal3 = Buffer[1] & 0x10;
  Parity_Cal3 = Parity_Cal3>>4;
  
  Parity_Cal4 = Buffer[1] & 0x08;
  Parity_Cal4 = Parity_Cal4>>3;
  
  Parity_Cal5 = Buffer[1] & 0x04;
  Parity_Cal5 = Parity_Cal5>>2;
  
  Parity_Cal6 = Buffer[1] & 0x02;
  Parity_Cal6 = Parity_Cal6>>1;
  
  Parity_Cal7 = Buffer[1] & 0x01;
 
  
  /* Caluculate parity bits based on output data */
  P2 = ((Parity_Cal7^Parity_Cal5)^Parity_Cal3)^Parity_Cal1;
  if (P2 == 0x01) {
    P2 = 0x08;
  } else {
    P2 = 0x00;
  }
 
  P1 = ((Parity_Cal6^Parity_Cal4)^Parity_Cal2)^Parity_Cal0;
  if (P1 == 0x01) {
    P1 = 0x04;
  } else {
    P1 = 0x00;
  }
  
  P0 = ((((((Parity_Cal7^Parity_Cal6)^Parity_Cal5)^Parity_Cal4)^Parity_Cal3)
         ^Parity_Cal2)^Parity_Cal1)^Parity_Cal0;
  if (P0 == 0x01) {
    P0 = 0X02;
  } else {
    P0 = 0x00;
  }
  
  nP0 = 0x00;
  if (P0 == 0x02) {
    nP0 = 0x00;
  } else {
    nP0 = 0x01;
  }
  
  /* Set Ssrelay_TxBuffer parity bits field */
  Buffer[0] = P2|P1|P0|nP0;
}
/**
  * @brief      Toggle selected output for given frequency
  * @param      Output channels to be toggled
  * @retval     None
  */
void XNucleoPLC01A1::output_cycling(void)
{
  if (!attached) {
    attached = true;
    ticker.attach(this, &XNucleoPLC01A1::toggle_output, 0.3);
  }
}
void XNucleoPLC01A1::toggle_output(void)
{
  /* Reset & set CS1 to refresh VNI watchdog */
  plcIn.set_input_spi(0);
  plcIn.set_input_spi(1);
  outBuff[1] = ~(outBuff[1]);
  /* Parity bits calculation */
  output_parity_bits(outBuff);
  /* Transmit data to VNI on SPI */
  plcOut.ssrelay_set_output(outBuff);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/