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.
Dependents: HelloWorld_PLC01A1
XNucleoPLC01A1.cpp
00001 /** 00002 ****************************************************************************** 00003 * @file XNucleoPLC01A1.cpp 00004 * @author AST/CL 00005 * @version V1.1.0 00006 * @date February 23rd, 2016 00007 * @brief Implementation file for the X_NUCLEO_PLC01A1 expansion board. 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> 00012 * 00013 * Redistribution and use in source and binary forms, with or without modification, 00014 * are permitted provided that the following conditions are met: 00015 * 1. Redistributions of source code must retain the above copyright notice, 00016 * this list of conditions and the following disclaimer. 00017 * 2. Redistributions in binary form must reproduce the above copyright notice, 00018 * this list of conditions and the following disclaimer in the documentation 00019 * and/or other materials provided with the distribution. 00020 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00021 * may be used to endorse or promote products derived from this software 00022 * without specific prior written permission. 00023 * 00024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00025 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00026 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00028 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00029 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00030 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00032 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 ****************************************************************************** 00036 */ 00037 00038 00039 /* Includes ------------------------------------------------------------------*/ 00040 00041 /* ACTION 1 ------------------------------------------------------------------* 00042 * Include here platform specific header files. * 00043 *----------------------------------------------------------------------------*/ 00044 #include "mbed.h" 00045 /* ACTION 2 ------------------------------------------------------------------* 00046 * Include here expansion board specific header files. * 00047 *----------------------------------------------------------------------------*/ 00048 #include "XNucleoPLC01A1.h" 00049 00050 00051 /** 00052 * @brief Mirrors input data 00053 * @param Input channel state buffer 00054 * @retval Input buffer state 00055 */ 00056 uint8_t XNucleoPLC01A1::signal_mirror(uint8_t In_Array) 00057 { 00058 return(In_Array); 00059 } 00060 00061 void XNucleoPLC01A1::handle_freeze_to(void) 00062 { 00063 freezeTo = true; 00064 } 00065 00066 /** 00067 * @brief Freeze selected output for a given time 00068 * @param Output channels to be freezed 00069 * @param Duration of freeze 00070 * @retval Output value 00071 */ 00072 uint8_t XNucleoPLC01A1::output_freeze(uint8_t N_Channel, uint16_t msec) 00073 { 00074 if (freezeTo) { 00075 timeout.detach(); 00076 return(0x00); 00077 } else if(!attached) { 00078 attached = true; 00079 timeout.attach(callback(this, &XNucleoPLC01A1::handle_freeze_to), chrono::microseconds(msec*1000)); 00080 } 00081 00082 return N_Channel; 00083 } 00084 00085 /** 00086 * @brief Regroup output buffer according to out_Array 00087 * @param Regroup array 00088 * @retval Value 00089 */ 00090 uint8_t XNucleoPLC01A1::output_regroup(uint8_t Out_Array) 00091 { 00092 return(Out_Array); 00093 } 00094 00095 /** 00096 * @brief Sum all the inputs at high state 00097 * @param Input channel state data 00098 * @retval Value corresponding to the sum of inputs at high 00099 */ 00100 uint8_t XNucleoPLC01A1::input_sum(uint8_t* Buffer, uint8_t In_Array) 00101 { 00102 00103 uint8_t inputChannelsOn = 0; 00104 uint8_t count = 0; 00105 *Buffer = In_Array; 00106 00107 for(count = 0; count<8; count++) 00108 { 00109 if ((In_Array & 0x01) == 0x01) { 00110 inputChannelsOn++; 00111 } 00112 00113 In_Array = In_Array >> 1; 00114 } 00115 00116 return inputChannelsOn; 00117 00118 } 00119 00120 /** 00121 * @brief Set the output channels on/off 00122 * @param Output to set 00123 * @retval Output value 00124 */ 00125 uint8_t XNucleoPLC01A1::set_output(uint8_t Out_Array) 00126 { 00127 return(Out_Array); 00128 } 00129 00130 /** 00131 * @brief AND Inputs for selected output channels 00132 * @param Input channels state 00133 * @param Outputs to be AND with inputs 00134 * @retval Result of AND operation 00135 */ 00136 uint8_t XNucleoPLC01A1::inputs_and(uint8_t In_Array, uint8_t Out_Channel) 00137 { 00138 uint8_t outArray = 0; 00139 outArray = In_Array & Out_Channel; 00140 00141 return outArray; 00142 } 00143 00144 /** 00145 * @brief OR Inputs for selected output channels 00146 * @param Input channels state 00147 * @param Outputs to be OR with inputs 00148 * @retval Result of OR operation 00149 */ 00150 uint8_t XNucleoPLC01A1::inputs_or(uint8_t In_Array, uint8_t Out_Channel) 00151 { 00152 uint8_t outArray = 0; 00153 outArray = In_Array | Out_Channel; 00154 00155 return outArray; 00156 } 00157 00158 /** 00159 * @brief NOT Inputs 00160 * @param Input channels state 00161 * @retval Result of OR operation 00162 */ 00163 uint8_t XNucleoPLC01A1::inputs_not(uint8_t In_Array) 00164 { 00165 uint8_t outArray = 0; 00166 In_Array = ~(In_Array); 00167 outArray = In_Array; 00168 00169 return outArray; 00170 } 00171 00172 /** 00173 * @brief XOR Inputs for selected output channels 00174 * @param Input channels state 00175 * @param Outputs to be XOR with inputs 00176 * @retval Result of XOR operation 00177 */ 00178 uint8_t XNucleoPLC01A1::inputs_xor(uint8_t In_Array, uint8_t Out_Channel) 00179 { 00180 uint8_t outArray = 0; 00181 outArray = In_Array ^ Out_Channel; 00182 00183 return outArray; 00184 } 00185 00186 /** 00187 * @brief Calculate and set parity bits for Ssrelay transmission 00188 * @param Output value buffer 00189 * @retval None 00190 */ 00191 void XNucleoPLC01A1::output_parity_bits(uint8_t* Buffer) 00192 { 00193 uint8_t Parity_Cal0 = 0x00; 00194 uint8_t Parity_Cal1 = 0x00; 00195 uint8_t Parity_Cal2 = 0x00; 00196 uint8_t Parity_Cal3 = 0x00; 00197 uint8_t Parity_Cal4 = 0x00; 00198 uint8_t Parity_Cal5 = 0x00; 00199 uint8_t Parity_Cal6 = 0x00; 00200 uint8_t Parity_Cal7 = 0x00; 00201 uint8_t nP0 = 0x00; 00202 uint8_t P0 = 0x00; 00203 uint8_t P1 = 0x00; 00204 uint8_t P2 = 0x00; 00205 00206 Parity_Cal0 = Buffer[1] & 0x80; 00207 Parity_Cal0 = Parity_Cal0>>7; 00208 00209 Parity_Cal1 = Buffer[1] & 0x40; 00210 Parity_Cal1 = Parity_Cal1>>6; 00211 00212 Parity_Cal2 = Buffer[1] & 0x20; 00213 Parity_Cal2 = Parity_Cal2>>5; 00214 00215 Parity_Cal3 = Buffer[1] & 0x10; 00216 Parity_Cal3 = Parity_Cal3>>4; 00217 00218 Parity_Cal4 = Buffer[1] & 0x08; 00219 Parity_Cal4 = Parity_Cal4>>3; 00220 00221 Parity_Cal5 = Buffer[1] & 0x04; 00222 Parity_Cal5 = Parity_Cal5>>2; 00223 00224 Parity_Cal6 = Buffer[1] & 0x02; 00225 Parity_Cal6 = Parity_Cal6>>1; 00226 00227 Parity_Cal7 = Buffer[1] & 0x01; 00228 00229 00230 /* Caluculate parity bits based on output data */ 00231 P2 = ((Parity_Cal7^Parity_Cal5)^Parity_Cal3)^Parity_Cal1; 00232 if (P2 == 0x01) { 00233 P2 = 0x08; 00234 } else { 00235 P2 = 0x00; 00236 } 00237 00238 P1 = ((Parity_Cal6^Parity_Cal4)^Parity_Cal2)^Parity_Cal0; 00239 if (P1 == 0x01) { 00240 P1 = 0x04; 00241 } else { 00242 P1 = 0x00; 00243 } 00244 00245 P0 = ((((((Parity_Cal7^Parity_Cal6)^Parity_Cal5)^Parity_Cal4)^Parity_Cal3) 00246 ^Parity_Cal2)^Parity_Cal1)^Parity_Cal0; 00247 if (P0 == 0x01) { 00248 P0 = 0X02; 00249 } else { 00250 P0 = 0x00; 00251 } 00252 00253 nP0 = 0x00; 00254 if (P0 == 0x02) { 00255 nP0 = 0x00; 00256 } else { 00257 nP0 = 0x01; 00258 } 00259 00260 /* Set Ssrelay_TxBuffer parity bits field */ 00261 Buffer[0] = P2|P1|P0|nP0; 00262 } 00263 00264 /** 00265 * @brief Toggle selected output for given frequency 00266 * @param Output channels to be toggled 00267 * @retval None 00268 */ 00269 void XNucleoPLC01A1::output_cycling(void) 00270 { 00271 if (!attached) { 00272 attached = true; 00273 ticker.attach(callback(this, &XNucleoPLC01A1::toggle_output), chrono::microseconds(3*100*1000)); 00274 } 00275 } 00276 00277 void XNucleoPLC01A1::toggle_output(void) 00278 { 00279 /* Reset & set CS1 to refresh VNI watchdog */ 00280 plcIn.set_input_spi(0); 00281 plcIn.set_input_spi(1); 00282 00283 outBuff[1] = ~(outBuff[1]); 00284 00285 /* Parity bits calculation */ 00286 output_parity_bits(outBuff); 00287 00288 /* Transmit data to VNI on SPI */ 00289 plcOut.ssrelay_set_output(outBuff); 00290 } 00291 00292 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Jul 15 2022 00:11:30 by
1.7.2
X-NUCLEO-PLC01A1 Programmable Logic Controller