Library to handle the X-NUCLEO-PLC01A1 Programmable Logic Controller Expansion Board based on the VNI8200XP (solid state relay) and CLT01-38SQ7 (octal digital termination array) components.

Dependents:   HelloWorld_PLC01A1

Programmable Logic Controller Library

Library to handle the X-NUCLEO-PLC01A1 Programmable Logic Controller Expansion Board based on the VNI8200XP (solid state relay) and CLT01-38SQ7 (octal digital termination array) components.

Information

For further details on VNI8200XP (Octal high side smart power solid state relay with serial/parallel selectable interface on chip) please refer to ST's web site.

For further details on CLT01-38SQ7 (High speed digital input current limiter) please refer to ST's web site.

SPI configuration

Pin D3 and D13 providing the SPI serial clock are short-circuited in the X-NUCLEO-PLC01A1 Expansion Board.

Please be aware that you may not drive the base board LED if it is connected to pin D13 (as it happens on STM32 Nucleo boards) or D3, otherwise you will get a conflict.

Platform compatibility

  • STM32 NUCLEO boards have been tested with the default configuration provided by the HelloWorld_PLC01A1 example.

return DSPI_HAL_ReadData(spi_address[obj->instance]);

X-NUCLEO-PLC01A1 board powering and startup

The following steps must be followed to run the X-NUCLEO-PLC01A1:

  1. Plug the X-NUCLEO-PLC01A1 onto a base board
  2. Connect the base board to a PC via a standard Type A / mini (or micro) B USB cable
  3. Download the firmware on the MCU hosted on the base board
  4. Supply 24 V to the X-NUCLEO-PLC01A1 board through the J8 connector
  5. The HelloWorld_PLC01A1 demonstration firmware is ready to run: connect any of the 8 inputs on the J8 connector to see the corresponding output on the J10 connector capable of driving a load (i.e. short-circuit input “x” with the 24 V and connect the corresponding output “x” to a load).
Committer:
apalmieri
Date:
Mon Jul 12 10:09:44 2021 +0000
Revision:
7:5d4336d0e372
Parent:
5:0845d4141a01
Update to mbed-os 6 (mbed-os-6.12.0)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Davidroid 5:0845d4141a01 1 /**
Davidroid 5:0845d4141a01 2 ******************************************************************************
Davidroid 5:0845d4141a01 3 * @file XNucleoPLC01A1.cpp
Davidroid 5:0845d4141a01 4 * @author AST/CL
Davidroid 5:0845d4141a01 5 * @version V1.1.0
Davidroid 5:0845d4141a01 6 * @date February 23rd, 2016
Davidroid 5:0845d4141a01 7 * @brief Implementation file for the X_NUCLEO_PLC01A1 expansion board.
Davidroid 5:0845d4141a01 8 ******************************************************************************
Davidroid 5:0845d4141a01 9 * @attention
Davidroid 5:0845d4141a01 10 *
Davidroid 5:0845d4141a01 11 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
Davidroid 5:0845d4141a01 12 *
Davidroid 5:0845d4141a01 13 * Redistribution and use in source and binary forms, with or without modification,
Davidroid 5:0845d4141a01 14 * are permitted provided that the following conditions are met:
Davidroid 5:0845d4141a01 15 * 1. Redistributions of source code must retain the above copyright notice,
Davidroid 5:0845d4141a01 16 * this list of conditions and the following disclaimer.
Davidroid 5:0845d4141a01 17 * 2. Redistributions in binary form must reproduce the above copyright notice,
Davidroid 5:0845d4141a01 18 * this list of conditions and the following disclaimer in the documentation
Davidroid 5:0845d4141a01 19 * and/or other materials provided with the distribution.
Davidroid 5:0845d4141a01 20 * 3. Neither the name of STMicroelectronics nor the names of its contributors
Davidroid 5:0845d4141a01 21 * may be used to endorse or promote products derived from this software
Davidroid 5:0845d4141a01 22 * without specific prior written permission.
Davidroid 5:0845d4141a01 23 *
Davidroid 5:0845d4141a01 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Davidroid 5:0845d4141a01 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Davidroid 5:0845d4141a01 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Davidroid 5:0845d4141a01 27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
Davidroid 5:0845d4141a01 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Davidroid 5:0845d4141a01 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Davidroid 5:0845d4141a01 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Davidroid 5:0845d4141a01 31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Davidroid 5:0845d4141a01 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Davidroid 5:0845d4141a01 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Davidroid 5:0845d4141a01 34 *
Davidroid 5:0845d4141a01 35 ******************************************************************************
Davidroid 5:0845d4141a01 36 */
Davidroid 5:0845d4141a01 37
Davidroid 5:0845d4141a01 38
Davidroid 5:0845d4141a01 39 /* Includes ------------------------------------------------------------------*/
Davidroid 5:0845d4141a01 40
Davidroid 5:0845d4141a01 41 /* ACTION 1 ------------------------------------------------------------------*
Davidroid 5:0845d4141a01 42 * Include here platform specific header files. *
Davidroid 5:0845d4141a01 43 *----------------------------------------------------------------------------*/
Davidroid 5:0845d4141a01 44 #include "mbed.h"
Davidroid 5:0845d4141a01 45 /* ACTION 2 ------------------------------------------------------------------*
Davidroid 5:0845d4141a01 46 * Include here expansion board specific header files. *
Davidroid 5:0845d4141a01 47 *----------------------------------------------------------------------------*/
Davidroid 5:0845d4141a01 48 #include "XNucleoPLC01A1.h"
Davidroid 5:0845d4141a01 49
Davidroid 5:0845d4141a01 50
Davidroid 5:0845d4141a01 51 /**
Davidroid 5:0845d4141a01 52 * @brief Mirrors input data
Davidroid 5:0845d4141a01 53 * @param Input channel state buffer
Davidroid 5:0845d4141a01 54 * @retval Input buffer state
Davidroid 5:0845d4141a01 55 */
Davidroid 5:0845d4141a01 56 uint8_t XNucleoPLC01A1::signal_mirror(uint8_t In_Array)
Davidroid 5:0845d4141a01 57 {
Davidroid 5:0845d4141a01 58 return(In_Array);
Davidroid 5:0845d4141a01 59 }
Davidroid 5:0845d4141a01 60
Davidroid 5:0845d4141a01 61 void XNucleoPLC01A1::handle_freeze_to(void)
Davidroid 5:0845d4141a01 62 {
Davidroid 5:0845d4141a01 63 freezeTo = true;
Davidroid 5:0845d4141a01 64 }
Davidroid 5:0845d4141a01 65
Davidroid 5:0845d4141a01 66 /**
Davidroid 5:0845d4141a01 67 * @brief Freeze selected output for a given time
Davidroid 5:0845d4141a01 68 * @param Output channels to be freezed
Davidroid 5:0845d4141a01 69 * @param Duration of freeze
Davidroid 5:0845d4141a01 70 * @retval Output value
Davidroid 5:0845d4141a01 71 */
Davidroid 5:0845d4141a01 72 uint8_t XNucleoPLC01A1::output_freeze(uint8_t N_Channel, uint16_t msec)
Davidroid 5:0845d4141a01 73 {
Davidroid 5:0845d4141a01 74 if (freezeTo) {
Davidroid 5:0845d4141a01 75 timeout.detach();
Davidroid 5:0845d4141a01 76 return(0x00);
Davidroid 5:0845d4141a01 77 } else if(!attached) {
Davidroid 5:0845d4141a01 78 attached = true;
apalmieri 7:5d4336d0e372 79 timeout.attach(callback(this, &XNucleoPLC01A1::handle_freeze_to), chrono::microseconds(msec*1000));
Davidroid 5:0845d4141a01 80 }
Davidroid 5:0845d4141a01 81
Davidroid 5:0845d4141a01 82 return N_Channel;
Davidroid 5:0845d4141a01 83 }
Davidroid 5:0845d4141a01 84
Davidroid 5:0845d4141a01 85 /**
Davidroid 5:0845d4141a01 86 * @brief Regroup output buffer according to out_Array
Davidroid 5:0845d4141a01 87 * @param Regroup array
Davidroid 5:0845d4141a01 88 * @retval Value
Davidroid 5:0845d4141a01 89 */
Davidroid 5:0845d4141a01 90 uint8_t XNucleoPLC01A1::output_regroup(uint8_t Out_Array)
Davidroid 5:0845d4141a01 91 {
Davidroid 5:0845d4141a01 92 return(Out_Array);
Davidroid 5:0845d4141a01 93 }
Davidroid 5:0845d4141a01 94
Davidroid 5:0845d4141a01 95 /**
Davidroid 5:0845d4141a01 96 * @brief Sum all the inputs at high state
Davidroid 5:0845d4141a01 97 * @param Input channel state data
Davidroid 5:0845d4141a01 98 * @retval Value corresponding to the sum of inputs at high
Davidroid 5:0845d4141a01 99 */
Davidroid 5:0845d4141a01 100 uint8_t XNucleoPLC01A1::input_sum(uint8_t* Buffer, uint8_t In_Array)
Davidroid 5:0845d4141a01 101 {
Davidroid 5:0845d4141a01 102
Davidroid 5:0845d4141a01 103 uint8_t inputChannelsOn = 0;
Davidroid 5:0845d4141a01 104 uint8_t count = 0;
Davidroid 5:0845d4141a01 105 *Buffer = In_Array;
Davidroid 5:0845d4141a01 106
Davidroid 5:0845d4141a01 107 for(count = 0; count<8; count++)
Davidroid 5:0845d4141a01 108 {
Davidroid 5:0845d4141a01 109 if ((In_Array & 0x01) == 0x01) {
Davidroid 5:0845d4141a01 110 inputChannelsOn++;
Davidroid 5:0845d4141a01 111 }
Davidroid 5:0845d4141a01 112
Davidroid 5:0845d4141a01 113 In_Array = In_Array >> 1;
Davidroid 5:0845d4141a01 114 }
Davidroid 5:0845d4141a01 115
Davidroid 5:0845d4141a01 116 return inputChannelsOn;
Davidroid 5:0845d4141a01 117
Davidroid 5:0845d4141a01 118 }
Davidroid 5:0845d4141a01 119
Davidroid 5:0845d4141a01 120 /**
Davidroid 5:0845d4141a01 121 * @brief Set the output channels on/off
Davidroid 5:0845d4141a01 122 * @param Output to set
Davidroid 5:0845d4141a01 123 * @retval Output value
Davidroid 5:0845d4141a01 124 */
Davidroid 5:0845d4141a01 125 uint8_t XNucleoPLC01A1::set_output(uint8_t Out_Array)
Davidroid 5:0845d4141a01 126 {
Davidroid 5:0845d4141a01 127 return(Out_Array);
Davidroid 5:0845d4141a01 128 }
Davidroid 5:0845d4141a01 129
Davidroid 5:0845d4141a01 130 /**
Davidroid 5:0845d4141a01 131 * @brief AND Inputs for selected output channels
Davidroid 5:0845d4141a01 132 * @param Input channels state
Davidroid 5:0845d4141a01 133 * @param Outputs to be AND with inputs
Davidroid 5:0845d4141a01 134 * @retval Result of AND operation
Davidroid 5:0845d4141a01 135 */
Davidroid 5:0845d4141a01 136 uint8_t XNucleoPLC01A1::inputs_and(uint8_t In_Array, uint8_t Out_Channel)
Davidroid 5:0845d4141a01 137 {
Davidroid 5:0845d4141a01 138 uint8_t outArray = 0;
Davidroid 5:0845d4141a01 139 outArray = In_Array & Out_Channel;
Davidroid 5:0845d4141a01 140
Davidroid 5:0845d4141a01 141 return outArray;
Davidroid 5:0845d4141a01 142 }
Davidroid 5:0845d4141a01 143
Davidroid 5:0845d4141a01 144 /**
Davidroid 5:0845d4141a01 145 * @brief OR Inputs for selected output channels
Davidroid 5:0845d4141a01 146 * @param Input channels state
Davidroid 5:0845d4141a01 147 * @param Outputs to be OR with inputs
Davidroid 5:0845d4141a01 148 * @retval Result of OR operation
Davidroid 5:0845d4141a01 149 */
Davidroid 5:0845d4141a01 150 uint8_t XNucleoPLC01A1::inputs_or(uint8_t In_Array, uint8_t Out_Channel)
Davidroid 5:0845d4141a01 151 {
Davidroid 5:0845d4141a01 152 uint8_t outArray = 0;
Davidroid 5:0845d4141a01 153 outArray = In_Array | Out_Channel;
Davidroid 5:0845d4141a01 154
Davidroid 5:0845d4141a01 155 return outArray;
Davidroid 5:0845d4141a01 156 }
Davidroid 5:0845d4141a01 157
Davidroid 5:0845d4141a01 158 /**
Davidroid 5:0845d4141a01 159 * @brief NOT Inputs
Davidroid 5:0845d4141a01 160 * @param Input channels state
Davidroid 5:0845d4141a01 161 * @retval Result of OR operation
Davidroid 5:0845d4141a01 162 */
Davidroid 5:0845d4141a01 163 uint8_t XNucleoPLC01A1::inputs_not(uint8_t In_Array)
Davidroid 5:0845d4141a01 164 {
Davidroid 5:0845d4141a01 165 uint8_t outArray = 0;
Davidroid 5:0845d4141a01 166 In_Array = ~(In_Array);
Davidroid 5:0845d4141a01 167 outArray = In_Array;
Davidroid 5:0845d4141a01 168
Davidroid 5:0845d4141a01 169 return outArray;
Davidroid 5:0845d4141a01 170 }
Davidroid 5:0845d4141a01 171
Davidroid 5:0845d4141a01 172 /**
Davidroid 5:0845d4141a01 173 * @brief XOR Inputs for selected output channels
Davidroid 5:0845d4141a01 174 * @param Input channels state
Davidroid 5:0845d4141a01 175 * @param Outputs to be XOR with inputs
Davidroid 5:0845d4141a01 176 * @retval Result of XOR operation
Davidroid 5:0845d4141a01 177 */
Davidroid 5:0845d4141a01 178 uint8_t XNucleoPLC01A1::inputs_xor(uint8_t In_Array, uint8_t Out_Channel)
Davidroid 5:0845d4141a01 179 {
Davidroid 5:0845d4141a01 180 uint8_t outArray = 0;
Davidroid 5:0845d4141a01 181 outArray = In_Array ^ Out_Channel;
Davidroid 5:0845d4141a01 182
Davidroid 5:0845d4141a01 183 return outArray;
Davidroid 5:0845d4141a01 184 }
Davidroid 5:0845d4141a01 185
Davidroid 5:0845d4141a01 186 /**
Davidroid 5:0845d4141a01 187 * @brief Calculate and set parity bits for Ssrelay transmission
Davidroid 5:0845d4141a01 188 * @param Output value buffer
Davidroid 5:0845d4141a01 189 * @retval None
Davidroid 5:0845d4141a01 190 */
Davidroid 5:0845d4141a01 191 void XNucleoPLC01A1::output_parity_bits(uint8_t* Buffer)
Davidroid 5:0845d4141a01 192 {
Davidroid 5:0845d4141a01 193 uint8_t Parity_Cal0 = 0x00;
Davidroid 5:0845d4141a01 194 uint8_t Parity_Cal1 = 0x00;
Davidroid 5:0845d4141a01 195 uint8_t Parity_Cal2 = 0x00;
Davidroid 5:0845d4141a01 196 uint8_t Parity_Cal3 = 0x00;
Davidroid 5:0845d4141a01 197 uint8_t Parity_Cal4 = 0x00;
Davidroid 5:0845d4141a01 198 uint8_t Parity_Cal5 = 0x00;
Davidroid 5:0845d4141a01 199 uint8_t Parity_Cal6 = 0x00;
Davidroid 5:0845d4141a01 200 uint8_t Parity_Cal7 = 0x00;
Davidroid 5:0845d4141a01 201 uint8_t nP0 = 0x00;
Davidroid 5:0845d4141a01 202 uint8_t P0 = 0x00;
Davidroid 5:0845d4141a01 203 uint8_t P1 = 0x00;
Davidroid 5:0845d4141a01 204 uint8_t P2 = 0x00;
Davidroid 5:0845d4141a01 205
Davidroid 5:0845d4141a01 206 Parity_Cal0 = Buffer[1] & 0x80;
Davidroid 5:0845d4141a01 207 Parity_Cal0 = Parity_Cal0>>7;
Davidroid 5:0845d4141a01 208
Davidroid 5:0845d4141a01 209 Parity_Cal1 = Buffer[1] & 0x40;
Davidroid 5:0845d4141a01 210 Parity_Cal1 = Parity_Cal1>>6;
Davidroid 5:0845d4141a01 211
Davidroid 5:0845d4141a01 212 Parity_Cal2 = Buffer[1] & 0x20;
Davidroid 5:0845d4141a01 213 Parity_Cal2 = Parity_Cal2>>5;
Davidroid 5:0845d4141a01 214
Davidroid 5:0845d4141a01 215 Parity_Cal3 = Buffer[1] & 0x10;
Davidroid 5:0845d4141a01 216 Parity_Cal3 = Parity_Cal3>>4;
Davidroid 5:0845d4141a01 217
Davidroid 5:0845d4141a01 218 Parity_Cal4 = Buffer[1] & 0x08;
Davidroid 5:0845d4141a01 219 Parity_Cal4 = Parity_Cal4>>3;
Davidroid 5:0845d4141a01 220
Davidroid 5:0845d4141a01 221 Parity_Cal5 = Buffer[1] & 0x04;
Davidroid 5:0845d4141a01 222 Parity_Cal5 = Parity_Cal5>>2;
Davidroid 5:0845d4141a01 223
Davidroid 5:0845d4141a01 224 Parity_Cal6 = Buffer[1] & 0x02;
Davidroid 5:0845d4141a01 225 Parity_Cal6 = Parity_Cal6>>1;
Davidroid 5:0845d4141a01 226
Davidroid 5:0845d4141a01 227 Parity_Cal7 = Buffer[1] & 0x01;
Davidroid 5:0845d4141a01 228
Davidroid 5:0845d4141a01 229
Davidroid 5:0845d4141a01 230 /* Caluculate parity bits based on output data */
Davidroid 5:0845d4141a01 231 P2 = ((Parity_Cal7^Parity_Cal5)^Parity_Cal3)^Parity_Cal1;
Davidroid 5:0845d4141a01 232 if (P2 == 0x01) {
Davidroid 5:0845d4141a01 233 P2 = 0x08;
Davidroid 5:0845d4141a01 234 } else {
Davidroid 5:0845d4141a01 235 P2 = 0x00;
Davidroid 5:0845d4141a01 236 }
Davidroid 5:0845d4141a01 237
Davidroid 5:0845d4141a01 238 P1 = ((Parity_Cal6^Parity_Cal4)^Parity_Cal2)^Parity_Cal0;
Davidroid 5:0845d4141a01 239 if (P1 == 0x01) {
Davidroid 5:0845d4141a01 240 P1 = 0x04;
Davidroid 5:0845d4141a01 241 } else {
Davidroid 5:0845d4141a01 242 P1 = 0x00;
Davidroid 5:0845d4141a01 243 }
Davidroid 5:0845d4141a01 244
Davidroid 5:0845d4141a01 245 P0 = ((((((Parity_Cal7^Parity_Cal6)^Parity_Cal5)^Parity_Cal4)^Parity_Cal3)
Davidroid 5:0845d4141a01 246 ^Parity_Cal2)^Parity_Cal1)^Parity_Cal0;
Davidroid 5:0845d4141a01 247 if (P0 == 0x01) {
Davidroid 5:0845d4141a01 248 P0 = 0X02;
Davidroid 5:0845d4141a01 249 } else {
Davidroid 5:0845d4141a01 250 P0 = 0x00;
Davidroid 5:0845d4141a01 251 }
Davidroid 5:0845d4141a01 252
Davidroid 5:0845d4141a01 253 nP0 = 0x00;
Davidroid 5:0845d4141a01 254 if (P0 == 0x02) {
Davidroid 5:0845d4141a01 255 nP0 = 0x00;
Davidroid 5:0845d4141a01 256 } else {
Davidroid 5:0845d4141a01 257 nP0 = 0x01;
Davidroid 5:0845d4141a01 258 }
Davidroid 5:0845d4141a01 259
Davidroid 5:0845d4141a01 260 /* Set Ssrelay_TxBuffer parity bits field */
Davidroid 5:0845d4141a01 261 Buffer[0] = P2|P1|P0|nP0;
Davidroid 5:0845d4141a01 262 }
Davidroid 5:0845d4141a01 263
Davidroid 5:0845d4141a01 264 /**
Davidroid 5:0845d4141a01 265 * @brief Toggle selected output for given frequency
Davidroid 5:0845d4141a01 266 * @param Output channels to be toggled
Davidroid 5:0845d4141a01 267 * @retval None
Davidroid 5:0845d4141a01 268 */
Davidroid 5:0845d4141a01 269 void XNucleoPLC01A1::output_cycling(void)
Davidroid 5:0845d4141a01 270 {
Davidroid 5:0845d4141a01 271 if (!attached) {
Davidroid 5:0845d4141a01 272 attached = true;
apalmieri 7:5d4336d0e372 273 ticker.attach(callback(this, &XNucleoPLC01A1::toggle_output), chrono::microseconds(3*100*1000));
Davidroid 5:0845d4141a01 274 }
Davidroid 5:0845d4141a01 275 }
Davidroid 5:0845d4141a01 276
Davidroid 5:0845d4141a01 277 void XNucleoPLC01A1::toggle_output(void)
Davidroid 5:0845d4141a01 278 {
Davidroid 5:0845d4141a01 279 /* Reset & set CS1 to refresh VNI watchdog */
Davidroid 5:0845d4141a01 280 plcIn.set_input_spi(0);
Davidroid 5:0845d4141a01 281 plcIn.set_input_spi(1);
Davidroid 5:0845d4141a01 282
Davidroid 5:0845d4141a01 283 outBuff[1] = ~(outBuff[1]);
Davidroid 5:0845d4141a01 284
Davidroid 5:0845d4141a01 285 /* Parity bits calculation */
Davidroid 5:0845d4141a01 286 output_parity_bits(outBuff);
Davidroid 5:0845d4141a01 287
Davidroid 5:0845d4141a01 288 /* Transmit data to VNI on SPI */
Davidroid 5:0845d4141a01 289 plcOut.ssrelay_set_output(outBuff);
Davidroid 5:0845d4141a01 290 }
Davidroid 5:0845d4141a01 291
Davidroid 5:0845d4141a01 292 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/