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.
Components/Interfaces/PLC_class.cpp
- Committer:
- apalmieri
- Date:
- 2016-02-19
- Revision:
- 0:b66a560b6618
File content as of revision 0:b66a560b6618:
/**
******************************************************************************
* @file PLC_class.h
* @author AST/CL
* @version V1.0.0
* @date Feb 9th, 2016
* @brief This file contains the abstract class describing the interface of a
* generic component.
******************************************************************************
* @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 ------------------------------------------------------------------*/
#include "PLC_class.h"
/**
* @brief Mirrors input data
* @param Input channel state buffer
* @retval Input buffer state
*/
uint8_t PLC::signalMirror(uint8_t In_Array)
{
return(In_Array);
}
void PLC::handleFreezeTo(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 PLC::outputFreeze(uint8_t N_Channel, uint16_t msec)
{
if(freezeTo) {
timeout.detach();
return(0x00);
} else if(!attached) {
attached = true;
timeout.attach(this, &PLC::handleFreezeTo, msec/1000);
}
return N_Channel;
}
/**
* @brief Regroup output buffer according to out_Array
* @param Regroup array
* @retval Value
*/
uint8_t PLC::outputRegroup(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 PLC::inputSum(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 PLC::setOutput(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 PLC::inputsAND(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 PLC::inputsOR(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 PLC::inputsNOT(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 PLC::inputsXOR(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 PLC::outputParityBits(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 PLC::outputCycling(void)
{
if(!attached) {
attached = true;
ticker.attach(this, &PLC::toggleOutput, 0.3);
}
}
void PLC::toggleOutput(void)
{
/* Reset & set CS1 to refresh VNI watchdog */
plcIn.setInputSPI(0);
plcIn.setInputSPI(1);
outBuff[1] = ~(outBuff[1]);
/* Parity bits calculation */
outputParityBits(outBuff);
/* Transmit data to VNI on SPI */
plcOut.Ssrelay_SetOutput(outBuff);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/