Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
ICBM
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
detectors
DSSC
ICBM
Commits
c8cde2a0
Commit
c8cde2a0
authored
3 weeks ago
by
Cyril Danilevski
Browse files
Options
Downloads
Patches
Plain Diff
Perform power down sequence from port expander interrupt
parent
4d32668b
No related branches found
No related tags found
1 merge request
!5
Perform power down sequence from port expander trigger
Pipeline
#166084
passed
3 weeks ago
Stage: test
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
icbm.ino
+9
-4
9 additions, 4 deletions
icbm.ino
pins.cpp
+105
-33
105 additions, 33 deletions
pins.cpp
pins.hpp
+5
-1
5 additions, 1 deletion
pins.hpp
powerproc.hpp
+2
-0
2 additions, 0 deletions
powerproc.hpp
with
121 additions
and
38 deletions
icbm.ino
+
9
−
4
View file @
c8cde2a0
...
...
@@ -15,11 +15,13 @@ void setup() {
initializeRoutes
();
initializeSNMP
();
start
=
millis
();
// Poll port expander to initialize the PINS struct.
poll_port_expander
();
PINS
.
last_triggered
=
millis
();
PINS
.
stage
=
""
;
PINS
.
ramping
=
false
;
start
=
millis
();
}
enum
{
...
...
@@ -28,7 +30,7 @@ enum {
OFF
,
};
void
serial
_l
oop
()
{
void
serial
L
oop
()
{
if
(
millis
()
-
start
>=
1000
)
{
start
=
millis
();
Serial
.
print
(
eth_connected
?
"."
:
"-"
);
...
...
@@ -40,5 +42,8 @@ void loop() {
snmp
.
loop
();
restServer
.
handleClient
();
toggle_status_led
();
serial_loop
();
serialLoop
();
if
(
eth_connected
)
{
// We may be triggered, but disconnected from the network.
powerOffCheckLoop
();
}
}
This diff is collapsed.
Click to expand it.
pins.cpp
+
105
−
33
View file @
c8cde2a0
#include
"pins.hpp"
#include
"powerproc.hpp"
MCP23S08
MCP
(
SS
,
MISO
,
MOSI
,
SCK
);
volatile
byte
ISR_FLAG
=
0
;
// Semaphores for handling interrupts and power down events.
volatile
byte
MCP_ISR_FLAG
=
0
;
volatile
byte
PERFORM_PROCEDURE_FROM_INTERRUPT
=
0
;
struct
pins
PINS
;
void
IRAM_ATTR
isr
()
{
ISR_FLAG
=
1
;
}
void
IRAM_ATTR
isr
()
{
MCP_
ISR_FLAG
=
1
;
}
void
initializeMCP
()
{
pinMode
(
ISR_PIN
,
INPUT_PULLUP
);
...
...
@@ -18,40 +24,54 @@ void initializeMCP() {
MCP
.
enableInterrupt
(
0
,
CHANGE
);
MCP
.
enableInterrupt
(
1
,
CHANGE
);
MCP
.
enableInterrupt
(
2
,
CHANGE
);
// Inform SIB we're ready
MCP
.
write1
(
ALERT_SIB_PIN
,
HIGH
);
Serial
.
println
(
"MCP23S08 Started"
);
}
void
isr_check_loop
()
{
if
(
ISR_FLAG
==
1
)
{
PINS
.
sib
=
false
;
PINS
.
plc
=
false
;
PINS
.
ups
=
false
;
PINS
.
last_triggered
=
millis
();
Serial
.
print
(
"Interrupt: "
);
uint8_t
regval
=
MCP
.
getInterruptCaptureRegister
();
// INTCAP
Serial
.
print
(
regval
,
BIN
);
uint8_t
mask
=
1
<<
0
;
if
(
!
(
regval
&
mask
))
{
Serial
.
print
(
" UPS"
);
PINS
.
ups
=
true
;
}
mask
=
1
<<
1
;
if
(
!
(
regval
&
mask
))
{
Serial
.
print
(
" PLC"
);
PINS
.
plc
=
true
;
}
mask
=
1
<<
2
;
if
(
!
(
regval
&
mask
))
{
Serial
.
print
(
" SIB"
);
PINS
.
sib
=
true
;
}
Serial
.
println
();
ISR_FLAG
=
0
;
if
(
MCP_ISR_FLAG
==
0
)
{
return
;
}
// False means triggered (not ok).
PINS
.
sib
=
false
;
PINS
.
plc
=
false
;
PINS
.
ups
=
false
;
PINS
.
last_triggered
=
millis
();
// Get the pins status at the time of the interrupt, and check their statuses.
Serial
.
print
(
"Interrupt: "
);
uint8_t
regval
=
MCP
.
getInterruptCaptureRegister
();
// INTCAP
Serial
.
print
(
regval
,
BIN
);
uint8_t
mask
=
1
<<
0
;
if
(
!
(
regval
&
mask
))
{
Serial
.
print
(
" UPS"
);
PINS
.
ups
=
true
;
}
mask
=
1
<<
1
;
if
(
!
(
regval
&
mask
))
{
Serial
.
print
(
" PLC"
);
PINS
.
plc
=
true
;
}
mask
=
1
<<
2
;
if
(
!
(
regval
&
mask
))
{
Serial
.
print
(
" SIB"
);
PINS
.
sib
=
true
;
}
Serial
.
println
();
// This interrupt was handled
MCP_ISR_FLAG
=
0
;
// If not all ok, set the power down flag, later handled.
if
(
!
(
PINS
.
sib
&&
PINS
.
plc
&&
PINS
.
ups
))
{
PERFORM_PROCEDURE_FROM_INTERRUPT
=
1
;
}
}
...
...
@@ -59,7 +79,6 @@ void poll_port_expander() {
PINS
.
sib
=
false
;
PINS
.
plc
=
false
;
PINS
.
ups
=
false
;
PINS
.
last_triggered
=
millis
();
int
regval
=
MCP
.
read8
();
uint8_t
mask
=
1
<<
0
;
...
...
@@ -92,3 +111,56 @@ void toggle_status_led() {
MCP
.
write1
(
STATUS_LED_PIN
,
on
);
}
}
void
powerOffCheckLoop
()
{
if
(
!
PERFORM_PROCEDURE_FROM_INTERRUPT
)
{
return
;
}
// Disable interrupts while performing power procedure.
// Once we've been triggered, we perform the power down procedure, uninterrupted,
// regardless of changes in the environment.
detachInterrupt
(
digitalPinToInterrupt
(
ISR_PIN
));
// Update status on serial interface and status webpage.
PINS
.
ramping
=
true
;
Serial
.
println
(
"POWERING DOWN DUE TO TRIGGER."
);
// Inform SIB that we're about to perform a procedure.
MCP
.
write1
(
ALERT_SIB_PIN
,
LOW
);
Serial
.
println
(
"asked sib down"
);
// Wait for SIB to acknowledge by checking its input (should go to triggered).
/* This require hardware changes, not implemented yet.
// TODO: apply a timeout and go ahead anyway?
do {
delay(200);
poll_port_expander();
} while(!(PINS.sib));
Serial.println("SIB ACK");
*/
// Iterate through each group and power down.
String
group
;
String
groups
;
for
(
int8_t
groupIdx
=
pproc
.
stagesCount
-
1
;
groupIdx
>=
0
;
groupIdx
--
)
{
group
=
pproc
.
stages
[
groupIdx
].
name
;
groups
+=
group
;
groups
+=
","
;
PINS
.
stage
=
group
;
pproc
.
powerOff
(
group
);
delay
(
1000
);
}
// Clear statuses on webpage and serial interfaces.
PINS
.
ramping
=
false
;
Serial
.
print
(
"Finished powering down from interrupt: "
);
Serial
.
println
(
groups
);
PINS
.
stage
=
"Ramped down"
;
// This event has been handled.
PERFORM_PROCEDURE_FROM_INTERRUPT
=
0
;
// Inform SIB that we're done and it can take data again.
MCP
.
write1
(
ALERT_SIB_PIN
,
HIGH
);
// Re-enable interrupts before exiting.
attachInterrupt
(
digitalPinToInterrupt
(
ISR_PIN
),
isr
,
CHANGE
);
}
This diff is collapsed.
Click to expand it.
pins.hpp
+
5
−
1
View file @
c8cde2a0
...
...
@@ -13,9 +13,12 @@
//AlCon Logic Board interrupt
#define TRIGGER_SIGNAL 14
// LED pin on MCP23S08 ex
te
nder
// LED pin on MCP23S08 ex
pa
nder
#define STATUS_LED_PIN 6
// Pin to inform SIB that a power down is about to happen, on MCP23S08 expander
#define ALERT_SIB_PIN 7
struct
pins
{
bool
sib
;
bool
plc
;
...
...
@@ -32,3 +35,4 @@ void initializeMCP();
void
isr_check_loop
();
void
poll_port_expander
();
void
toggle_status_led
();
void
powerOffCheckLoop
();
This diff is collapsed.
Click to expand it.
powerproc.hpp
+
2
−
0
View file @
c8cde2a0
...
...
@@ -34,4 +34,6 @@ public:
String
toJSON
();
};
void
powerOffCheckLoop
();
extern
PowerProcedure
pproc
;
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment