MVMFirmwareCpp v0.1
fw_board_ni_v4.cpp
Go to the documentation of this file.
1 //
2 //
3 //
4 
5 #include "fw_board_ni_v4.h"
6 
7 
8 #include <Wire.h>
9 
10 
11 #define VALVE_IN_PIN A1
12 #define VALVE_OUT_PIN 32
13 
14 #define BUZZER 21
15 #define ALARM_LED 17
16 #define ALARM_RELE A12
17 #define BREETHE 4
18 
19 #define TCAADDR 0x70
20 
37 {
38 
39  //Init serial port 115200,8,n,1
40  Serial.begin(115200);
41 
42  //Init PWM for PV1, 10KHz, 12 bit
43  ledcSetup(0, 10000, 12);
44  ledcAttachPin(VALVE_IN_PIN, 0);
45  ledcWrite(0, 0);
46 
47  //Init pins: PV2, ALARM LED, BUZZER, RELE
48  digitalWrite(VALVE_OUT_PIN, LOW);
49  digitalWrite(ALARM_LED, LOW);
50  digitalWrite(BUZZER, LOW);
51  digitalWrite(ALARM_RELE, HIGH);
52 
53  pinMode(VALVE_OUT_PIN, OUTPUT);
54  pinMode(ALARM_LED, OUTPUT);
55  pinMode(BUZZER, OUTPUT);
56  pinMode(ALARM_RELE, OUTPUT);
57 
58  //Start I2C Master and Scan bus
59  Wire.begin();
60 
61  for (int i = 0; i < 8; i++) {
62  i2c_MuxSelect(i);
63  Serial.println("SCAN I2C BUS: " + String(i));
65  }
66 
67  //Init list of devices on I2C bus
68 
69  iic_devs[0].t_device = IIC_PS_0; //NAME OF THE SENSORE
70  iic_devs[0].muxport = 0; //Multiplexer PORT
71  iic_devs[0].address = 0x76; //I2C ADDRESS
72 
74  iic_devs[1].muxport = 0;
75  iic_devs[1].address = 0x77;
76 
78  iic_devs[2].muxport = 1;
79  iic_devs[2].address = 0x76;
80 
81 #ifdef USE_SPIROMETER_SFM3019
83  iic_devs[3].muxport = 1;
84  iic_devs[3].address = 0x2E;
85 
86 #endif
87 
88 #ifdef USE_SPIROMETER_SFM3000
90  iic_devs[3].muxport = 1;
91  iic_devs[3].address = 0x40;
92 #endif
93 
95  iic_devs[4].muxport = 4;
96  iic_devs[4].address = 0x48;
97 
99  iic_devs[5].muxport = 3;
100  iic_devs[5].address = 0x22;
101 
102 
104  iic_devs[6].muxport = -1;
105  iic_devs[6].address = 0x70;
106 
108  iic_devs[7].muxport = 1;
109  iic_devs[7].address = 0x00;
110 
111 
112  batteryStatus_reading_LT = GetMillis();
113 
114 
115  currentBatteryCharge = 100;
116  pWall=true;
117  pIN=3;
118  BoardTemperature=25;
119 
120  //init supervisor watchdog
121 
122  /*
123  * During development we keep disabled supervisor watchdog
124  * otherwise it will trigger low level alarm every time
125  * we reprogram ESP
126  *
127  * 0 : DEVELOPMENT - NO SUPERVISOR WATCHDOG
128  * 1 : PRODUCTION - ENABLE SUPERVISOR WATCHDOG
129  */
130 
131 
132 }
133 
145 bool HW_V4::I2CWrite(t_i2cdevices device, uint8_t* wbuffer, int wlength, bool stop)
146 {
147  uint8_t address;
148  uint8_t result;
149 
150  //Search I2C device by name
151  t_i2cdev dev = GetIICDevice(device);
152  address = dev.address;
153 
154  //Switch multiplexer
155  i2c_MuxSelect(dev.muxport);
156 
157  //Arduino I2C Write operation
158  Wire.beginTransmission(address);
159  for (int i = 0;i < wlength; i++)
160  Wire.write(wbuffer[i]);
161  result = Wire.endTransmission();
162 
163  if (result != 0)
164  return false;
165  else
166  return true;
167 }
168 
182 bool HW_V4::I2CRead(t_i2cdevices device, uint8_t* wbuffer, int wlength, uint8_t* rbuffer, int rlength, bool stop)
183 {
184  uint8_t address;
185  uint8_t count;
186  uint8_t result;
187 
188  //Search I2C device by name
189  t_i2cdev dev = GetIICDevice(device);
190  address = dev.address;
191 
192  //Switch multiplexer
193  i2c_MuxSelect(dev.muxport);
194 
195  //Arduino I2C Write operation
196  Wire.beginTransmission(address);
197  for (int i = 0;i < wlength; i++)
198  Wire.write(wbuffer[i]);
199  result = Wire.endTransmission();
200  if (result != 0)
201  return false;
202 
203  //Arduino I2C Read operation
204  count = Wire.requestFrom((uint16_t)address, (uint8_t)rlength, stop);
205  if (count < rlength)
206  return false;
207 
208  for (int i = 0;i < rlength; i++)
209  {
210  rbuffer[i] = Wire.read();
211  }
212 
213  return true;
214 }
215 
227 bool HW_V4::I2CRead(t_i2cdevices device, uint8_t* rbuffer, int rlength, bool stop)
228 {
229  uint8_t count;
230  uint8_t address;
231  t_i2cdev dev = GetIICDevice(device);
232  address = dev.address;
233  i2c_MuxSelect(dev.muxport);
234 
235  count = Wire.requestFrom((uint16_t)address, (uint8_t)rlength, stop);
236 
237  if (count < rlength)
238  return false;
239 
240 
241  for (int i = 0;i < rlength; i++)
242  {
243  rbuffer[i] = Wire.read();
244  }
245 
246  return true;
247 }
248 
256 bool HW_V4::PWMSet(hw_pwm id, float value)
257 {
258 
259  if ((value < 0) || (value > 100.0)) return false;
260 
261  switch (id)
262  {
263  case PWM_PV1:
264  uint32_t v = (uint32_t)value * 4095.0 / 100.0;
265  ledcWrite(0, v);
266  /*
267  * The breethe signal is used by the supervisor to check
268  * whenever the driver for PV1 and PV2 is not working
269  * We need to commutate breethe synchronous with PV1
270  */
271  if (v > 0)
272  digitalWrite(BREETHE, HIGH);
273  break;
274 
275  }
276 
277 
278  return true;
279 }
280 
288 bool HW_V4::IOSet(hw_gpio id, bool value)
289 {
290  switch (id)
291  {
292  case GPIO_PV2:
293  digitalWrite(VALVE_OUT_PIN, value ? HIGH : LOW);
294  /*
295  * The breethe signal is used by the supervisor to check
296  * whenever the driver for PV1 and PV2 is not working
297  * We need to commutate breethe synchronous with PV2
298  */
299  if (value==LOW)
300  digitalWrite(BREETHE, LOW);
301  break;
302  case GPIO_BUZZER:
303  digitalWrite(BUZZER, value ? HIGH : LOW);
304  break;
305  case GPIO_LED:
306  digitalWrite(ALARM_LED, value ? HIGH : LOW);
307  break;
308  case GPIO_RELEALLARM:
309  digitalWrite(ALARM_RELE, value ? HIGH : LOW);
310  break;
311  default:
312  return false;
313  break;
314  }
315  return true;
316 }
317 
325 bool HW_V4::IOGet(hw_gpio id, bool* value)
326 {
327  switch (id)
328  {
329  case GPIO_PV2:
330  *value = digitalRead(VALVE_OUT_PIN);
331  break;
332  case GPIO_BUZZER:
333  *value = digitalRead(BUZZER);
334  break;
335  case GPIO_LED:
336  *value = digitalRead(ALARM_LED);
337  break;
338  case GPIO_RELEALLARM:
339  *value = digitalRead(ALARM_RELE);
340  break;
341  default:
342  return false;
343  break;
344  }
345  return true;
346 }
347 
353 void HW_V4::__delay_blocking_ms(uint32_t ms)
354 {
355  delay(ms);
356 }
357 
369 {
370  Serial.print(s);
371 }
372 
373 
385 {
386  Serial.println(s);
387 }
388 
404 {
405  if (Get_dT_millis(batteryStatus_reading_LT)>1000)
406  {
407  batteryStatus_reading_LT = GetMillis();
408  currentBatteryCharge = (float)ReadSupervisor(0x51);
411  pWall = ReadSupervisor(0x52) >0 ? false : true ;
412  pIN = ((float)ReadSupervisor(0x50));
413  BoardTemperature = ((float)ReadSupervisor(0x56)/10.0);
414  HW_AlarmsFlags = (uint16_t)ReadSupervisor(0x57);
415 
416  //reset supervisor watchdog
417  WriteSupervisor(0x00, 1);
418 
420  WriteSupervisor(0x01, 1);
421  EnableWatchdogSupervisor = false;
422  }
423  //Serial.println("Battery: " + String(currentBatteryCharge) + " PWALL: " + String (pWall));
424  }
425 
426 
427  return;
428 }
429 
430 
438 void HW_V4::GetPowerStatus(bool* batteryPowered, float* charge)
439 {
440  *batteryPowered = pWall ? false:true;
441  *charge = currentBatteryCharge ;
442 
443 }
444 
445 
453 {
454  return Serial.available();
455 }
456 
463 bool HW_V4::WriteUART0(String s)
464 {
465  Serial.println(s);
466  return true;
467 }
468 
475 {
476  //PERICOLO. SE IL \n NON VIENE INVIATO TUTTO STALLA!!!!
477  return Serial.readStringUntil('\n');
478 }
479 
485 uint64_t HW_V4::GetMillis()
486 {
487  return (uint64_t)millis();
488 }
489 
496 int64_t HW_V4::Get_dT_millis(uint64_t ms)
497 {
498  return (int64_t)(millis() - ms);
499 }
500 
501 
507 {
508  byte error, address;
509  int nDevices;
510  Serial.println("Scanning... I2C");
511  nDevices = 0;
512  for (address = 1; address < 127; address++) {
513  Wire.beginTransmission(address);
514  error = Wire.endTransmission();
515  if (error == 0) {
516  Serial.print("I2C device found at address 0x");
517  if (address < 16) {
518  Serial.print("0");
519  }
520  Serial.println(address, HEX);
521  nDevices++;
522  }
523  else if (error == 4) {
524  Serial.print("Unknow error at address 0x");
525  if (address < 16) {
526  Serial.print("0");
527  }
528  Serial.println(address, HEX);
529  }
530  }
531  if (nDevices == 0) {
532  Serial.println("No I2C devices found\n");
533  }
534  else {
535  Serial.println("done\n");
536  }
537 }
538 
546 void HW_V4::i2c_MuxSelect(uint8_t i)
547 {
548  if (i > 7)
549  return;
550 
551  if (i < 0)
552  return;
553 
554  if (current_muxpos == i) return;
555 
556  current_muxpos = i;
557 
558  Wire.beginTransmission(TCAADDR);
559  Wire.write(1 << i);
560  Wire.endTransmission();
561  delayMicroseconds(500);
562 }
563 
571 {
572  for (int i = 0; i < IIC_COUNT; i++)
573  {
574  if (iic_devs[i].t_device == device)
575  {
576  return iic_devs[i];
577  }
578  }
579 }
580 
587 uint16_t HW_V4::ReadSupervisor(uint8_t i_address)
588 {
589  uint8_t wbuffer[4];
590  uint8_t rbuffer[4];
591 
592  wbuffer[0] = i_address;
593  I2CRead(IIC_SUPERVISOR, wbuffer, 1, rbuffer, 2, true);
594 
595  uint16_t a;
596 
597  a = (rbuffer [1]<< 8) | rbuffer[0];
598  return a;
599 }
600 
607 void HW_V4::WriteSupervisor( uint8_t i_address, uint16_t write_data)
608 {
609  uint8_t wbuffer[4];
610  wbuffer[0] = i_address;
611  wbuffer[1] = write_data & 0xFF;
612  wbuffer[2] = (write_data >> 8) & 0xFF;
613 
614  I2CWrite(IIC_SUPERVISOR, wbuffer, 3, true);
615 
616 }
617 
624 {
625  return pIN;
626 }
627 
634 {
635  return BoardTemperature;
636 }
637 
653 {
654  return HW_AlarmsFlags;
655 }
656 
657 
658 // # # ###
659 // ## # #
660 // # # # #
661 // # # # #
662 // # # # #
663 // # ## #
664 // # # ###
665 //
666 // Nuclear Instruments 2020 - All rights reserved
667 // Any commercial use of this code is forbidden
668 // Contact info@nuclearinstruments.eu
t_i2cdev::address
uint8_t address
Definition: generic_definitions.h:53
t_i2cdev::muxport
int8_t muxport
Definition: generic_definitions.h:54
HW_V4::pIN
float pIN
Definition: fw_board_ni_v4.h:67
HW_V4::Init
bool Init()
Initialize hardware peripheral in the system.
Definition: fw_board_ni_v4.cpp:36
HW_V4::PrintLineDebugConsole
void PrintLineDebugConsole(String s)
Print a message on console used for Debug with a CR+LR at end.
Definition: fw_board_ni_v4.cpp:384
VALVE_IN_PIN
#define VALVE_IN_PIN
Definition: fw_board_ni_v4.cpp:11
HW_V4::GetSupervisorAlarms
uint16_t GetSupervisorAlarms()
API return Supervisor managed alarms.
Definition: fw_board_ni_v4.cpp:652
IIC_PS_2
@ IIC_PS_2
Definition: generic_definitions.h:39
HW_V4::iic_devs
t_i2cdev iic_devs[IIC_COUNT]
Definition: fw_board_ni_v4.h:60
PWM_PV1
@ PWM_PV1
Definition: generic_definitions.h:32
HW_V4::I2CRead
bool I2CRead(t_i2cdevices device, uint8_t *wbuffer, int wlength, uint8_t *rbuffer, int rlength, bool stop)
Write buffer to I2C bus and read data.
Definition: fw_board_ni_v4.cpp:182
GPIO_RELEALLARM
@ GPIO_RELEALLARM
Definition: generic_definitions.h:33
IIC_FLOW1
@ IIC_FLOW1
Definition: generic_definitions.h:43
HW_V4::ReadUART0UntilEOL
String ReadUART0UntilEOL()
Return a terminated string from communication interface.
Definition: fw_board_ni_v4.cpp:474
t_i2cdev::t_device
t_i2cdevices t_device
Definition: generic_definitions.h:52
IIC_PS_0
@ IIC_PS_0
Definition: generic_definitions.h:37
BREETHE
#define BREETHE
Definition: fw_board_ni_v4.cpp:17
IIC_COUNT
#define IIC_COUNT
Definition: fw_board_ni_v4.h:14
fw_board_ni_v4.h
hw_gpio
hw_gpio
Definition: generic_definitions.h:33
HW_V4::__service_i2c_detect
void __service_i2c_detect()
Detect all I2C devices on bus.
Definition: fw_board_ni_v4.cpp:506
IIC_ADC_0
@ IIC_ADC_0
Definition: generic_definitions.h:45
HW_V4::PrintDebugConsole
void PrintDebugConsole(String s)
Print a message on console used for Debug.
Definition: fw_board_ni_v4.cpp:368
IIC_MUX
@ IIC_MUX
Definition: generic_definitions.h:48
BUZZER
#define BUZZER
Definition: fw_board_ni_v4.cpp:14
HW_V4::I2CWrite
bool I2CWrite(t_i2cdevices device, uint8_t *wbuffer, int wlength, bool stop)
Write buffer to I2C bus.
Definition: fw_board_ni_v4.cpp:145
Serial::println
void println()
ALARM_LED
#define ALARM_LED
Definition: fw_board_ni_v4.cpp:15
GPIO_PV2
@ GPIO_PV2
Definition: generic_definitions.h:33
HW_V4::pWall
bool pWall
Definition: fw_board_ni_v4.h:65
Serial
Definition: arduino.h:2
HW_V4::batteryStatus_reading_LT
uint64_t batteryStatus_reading_LT
Definition: fw_board_ni_v4.h:63
HW_V4::WriteUART0
bool WriteUART0(String s)
API to write a string to the communication interfaces.
Definition: fw_board_ni_v4.cpp:463
GPIO_LED
@ GPIO_LED
Definition: generic_definitions.h:33
t_i2cdev
Definition: generic_definitions.h:51
ALARM_RELE
#define ALARM_RELE
Definition: fw_board_ni_v4.cpp:16
HW_V4::Tick
void Tick()
Tick function must be called periodically.
Definition: fw_board_ni_v4.cpp:403
HW_V4::currentBatteryCharge
float currentBatteryCharge
Definition: fw_board_ni_v4.h:64
HW_V4::GetIICDevice
t_i2cdev GetIICDevice(t_i2cdevices device)
Search in the iic_devs list a particular device and return descriptor.
Definition: fw_board_ni_v4.cpp:570
Serial::begin
void begin()
HW_V4::GetPowerStatus
void GetPowerStatus(bool *batteryPowered, float *charge)
API to read battery charge and power supply status.
Definition: fw_board_ni_v4.cpp:438
HW_V4::GetPIN
float GetPIN()
API return pressure on input of MVM.
Definition: fw_board_ni_v4.cpp:623
TCAADDR
#define TCAADDR
Definition: fw_board_ni_v4.cpp:19
GPIO_BUZZER
@ GPIO_BUZZER
Definition: generic_definitions.h:33
HW_V4::BoardTemperature
float BoardTemperature
Definition: fw_board_ni_v4.h:68
HW_V4::GetBoardTemperature
float GetBoardTemperature()
API return temperature of the board.
Definition: fw_board_ni_v4.cpp:633
t_i2cdevices
t_i2cdevices
Definition: generic_definitions.h:36
HW_V4::HW_AlarmsFlags
uint16_t HW_AlarmsFlags
Definition: fw_board_ni_v4.h:69
HW_V4::DataAvailableOnUART0
bool DataAvailableOnUART0()
API to read if on the communication interfaces there are bytes to be read.
Definition: fw_board_ni_v4.cpp:452
HW_V4::PWMSet
bool PWMSet(hw_pwm id, float value)
Control PWM device (PV1)
Definition: fw_board_ni_v4.cpp:256
HW_V4::EnableWatchdogSupervisor
bool EnableWatchdogSupervisor
Definition: fw_board_ni_v4.h:51
HW_V4::WriteSupervisor
void WriteSupervisor(uint8_t i_address, uint16_t write_data)
Write a supervisor register.
Definition: fw_board_ni_v4.cpp:607
IIC_SUPERVISOR
@ IIC_SUPERVISOR
Definition: generic_definitions.h:46
HW_V4::ReadSupervisor
uint16_t ReadSupervisor(uint8_t i_address)
Read a supervisor register.
Definition: fw_board_ni_v4.cpp:587
Serial::print
void print()
HW_V4::IOSet
bool IOSet(hw_gpio id, bool value)
Set a GPIO Status (IE Control PV6, Alarms, etc)
Definition: fw_board_ni_v4.cpp:288
IIC_GENERAL_CALL_SENSIRION
@ IIC_GENERAL_CALL_SENSIRION
Definition: generic_definitions.h:49
VALVE_OUT_PIN
#define VALVE_OUT_PIN
Definition: fw_board_ni_v4.cpp:12
HW_V4::current_muxpos
uint8_t current_muxpos
Definition: fw_board_ni_v4.h:61
HW_V4::IOGet
bool IOGet(hw_gpio id, bool *value)
Get GPIO Status.
Definition: fw_board_ni_v4.cpp:325
Serial::readStringUntil
int readStringUntil()
HW_V4::i2c_MuxSelect
void i2c_MuxSelect(uint8_t i)
Switch I2C multiplexer.
Definition: fw_board_ni_v4.cpp:546
hw_pwm
hw_pwm
Definition: generic_definitions.h:32
IIC_PS_1
@ IIC_PS_1
Definition: generic_definitions.h:38