Fork to see if I can get working
Dependencies: BufferedSerial OneWire WinbondSPIFlash libxDot-dev-mbed5-deprecated
Fork of xDotBridge_update_test20180823 by
Revision 49:18f1354f9e51, committed 2017-02-17
- Comitter:
- Matt Briggs
- Date:
- Fri Feb 17 08:06:37 2017 -0700
- Parent:
- 48:bab9f747d9ed
- Child:
- 50:e89647e77fd5
- Commit message:
- Debugged both test and bbio lib. Most IO working at this point.
Changed in this revision
--- a/xDotBridge/README.md Mon Feb 13 17:10:59 2017 -0700 +++ b/xDotBridge/README.md Fri Feb 17 08:06:37 2017 -0700 @@ -112,3 +112,25 @@ Just use the xDots and the conduit as they are designed to be used. No pairing just straight LoRaWAN. * Future idea maybe a RX with WAN enabled acts as a repeater to conduit. + +# Nonvolatile Memory Map +## Radio Parameters +TBD. Most of this should be stored automatically by dot-firmware. WIll try to figure out where in overall +memory map. Reserved dot NVM 0x0000 -> 0x0FFF + +## IO Baseboard Parameters +============================================== += Dot Relative Addr | Size (in Bytes) | Name = +============================================== += 0x1000 | 2 Bytes | Baseboard Flag = +============================================== += 0x1002 | 2 Bytes | Baseboard Rev = +============================================== += 0x1004 | 2 Bytes | Baseboard Serial = +============================================== += 0x1004 | 2 Bytes | Baseboard Configuration = +============================================== += 0x1010 | 4 Bytes | PortEx0 64 bit ROM Addr = +============================================== += 0x1014 | 4 Bytes | PortEx1 64 bit ROM Addr = +==============================================
--- a/xDotBridge/TESTS/autoLibs/testDs2408/testAPI.cpp Mon Feb 13 17:10:59 2017 -0700
+++ b/xDotBridge/TESTS/autoLibs/testDs2408/testAPI.cpp Fri Feb 17 08:06:37 2017 -0700
@@ -17,6 +17,7 @@
using namespace utest::v1;
+DigitalOut switchedIO(I2C_SCL, 0); // Always enable Switched IO for test
OneWire OWMaster(I2C_SDA);
uint8_t ds2408Addr[8];
@@ -25,16 +26,17 @@
*/
void test_search() {
uint8_t result;
- wait(1.0);
- for (int i=0; i<5; i++) {
+ for (int i=0; i<1; i++) {
OWMaster.reset();
wait(1.0);
result = OWMaster.search(ds2408Addr);
+ TEST_ASSERT(result == 1);
+ result = OWMaster.search(ds2408Addr);
if (result == 1) {
break;
}
+ TEST_ASSERT(result == 1);
}
- TEST_ASSERT(result == 1);
}
/**
--- a/xDotBridge/config.h Mon Feb 13 17:10:59 2017 -0700 +++ b/xDotBridge/config.h Fri Feb 17 08:06:37 2017 -0700 @@ -8,7 +8,7 @@ #define __TEST__ 1 // Comment out for main application // Manual test -#define __TEST_BBIO__ // Comment out for main application +//#define __TEST_BBIO__ // Comment out for main application //#define __TEST_LRR__ // Comment out for main application // These define which wireless bridge you are generating code for #define BRIDGE_TX_BRUTE 0
--- a/xDotBridge/inc/BaseboardIO.h Mon Feb 13 17:10:59 2017 -0700
+++ b/xDotBridge/inc/BaseboardIO.h Fri Feb 17 08:06:37 2017 -0700
@@ -167,7 +167,7 @@
*
* @return bool
*/
- bool isCCNC() {return isCCNO();}
+ bool isCCNC() {return !isCCNO();}
/**
* @brief Returns the current state of the Rx/Tx switch
@@ -322,6 +322,14 @@
DS2408 *mPortEx0;
DS2408 *mPortEx1;
+ void enableSwitchedIO () {
+ mSwitchedIOCtrl = 0; // assert since PMOS
+ }
+ void disableSwitchedIO () {
+ mSwitchedIOCtrl = 1; // deassertted since PMOS
+// mSwitchedIOCtrl = 0; // FIXME
+ }
+
/**
* @brief Reads baseboard information from non-volatile memory (NVM)
*
--- a/xDotBridge/manualTest/testBaseboardIO/testBaseboardIO.cpp Mon Feb 13 17:10:59 2017 -0700
+++ b/xDotBridge/manualTest/testBaseboardIO/testBaseboardIO.cpp Fri Feb 17 08:06:37 2017 -0700
@@ -2,10 +2,14 @@
#include <string>
#include "..\..\config.h"
#include "BaseboardIO.h"
+#include "MTSLog.h"
+#include "critical.h"
#ifdef __TEST_BBIO__
Serial pc(USBTX, USBRX); // Externally defined
+const int VERSION = 1;
+
char* bool2Str(bool in) {
if (in) {
return "Asserted\ "; // Extra space for alignment
@@ -15,11 +19,13 @@
}
}
-uint8_t ccInIntCnt;
-uint8_t tamperIntCnt;
-uint8_t pairBtnIntCnt;
+volatile uint8_t ccInIntCnt;
+volatile uint8_t tamperIntCnt;
+volatile uint8_t pairBtnIntCnt;
+volatile uint8_t pvdIntCnt;
void ccInIntCallback () {
+// core_util_atomic_incr_u8(&ccInIntCnt, 1); // Not needed since function is wrapped in critical section code.
ccInIntCnt++;
}
void tamperIntCallback () {
@@ -28,6 +34,9 @@
void pairBtnIntCallback () {
pairBtnIntCnt++;
}
+void HAL_PWR_PVDCallback () { // Override callback in lib
+ pvdIntCnt++;
+}
class MenuManager
{
@@ -85,7 +94,7 @@
mBbio->sampleUserSwitches();
pc.printf("\r\n\r\n");
pc.printf("===============================================\r\n");
- pc.printf("= Baseboard I/O Tester =\r\n");
+ pc.printf("= Baseboard I/O Tester v%02d =\r\n", VERSION);
pc.printf("===============================================\r\n");
pc.printf("===============================================\r\n");
pc.printf("= Selection Options =\r\n");
@@ -103,13 +112,15 @@
pc.printf("= Status and Counters =\r\n");
pc.printf("===============================================\r\n");
pc.printf("= Pair btn. State: %s IntCnt: %02d =\r\n",
- bool2Str(mBbio->isPairBtn()), 0);
- pc.printf("= Tamper. State: N/A IntCnt: %02d =\r\n",
- 0);
+ bool2Str(mBbio->isPairBtn()), pairBtnIntCnt);
+ pc.printf("= Tamper. State: N/A IntCnt: %04d =\r\n",
+ tamperIntCnt);
pc.printf("= CCIN. State: %s IntCnt: %02d =\r\n",
- bool2Str(0), 0);
+ bool2Str(0), ccInIntCnt);
+ pc.printf("= PVD. State: N/A IntCnt: %02d =\r\n",
+ pvdIntCnt);
pc.printf("= Is TX. State: %s =\r\n", bool2Str(mBbio->isTx()));
- pc.printf("= CC Normally Open. State: %s =\r\n", bool2Str(mBbio->isCCNO()));
+ pc.printf("= CC Normally Closed. State: %s =\r\n", bool2Str(mBbio->isCCNC()));
pc.printf("= Is LoraWAN. State: %s =\r\n", bool2Str(mBbio->isLoRaWANMode()));
pc.printf("= Rotary Switch 1. Value: %02d =\r\n", mBbio->rotarySwitch1());
pc.printf("= Rotary Switch 2. Value: %02d =\r\n", mBbio->rotarySwitch2());
@@ -117,6 +128,7 @@
}
};
+char WAIT_CHARS [] = {'-', '\\', '|', '/'};
/**
* Checks that in idle state all the IOs are pulled up.
*/
@@ -127,8 +139,38 @@
ccInIntCnt = 0;
tamperIntCnt = 0;
pairBtnIntCnt = 0;
+ pvdIntCnt = 0;
pc.baud(115200);
+ mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
+
+ // Setup programmable voltage detector
+ // PVD_LEVEL0 Falling 1.85
+ // PVD_LEVEL1 Falling 2.04
+ // PVD_LEVEL2 Falling 2.24
+ // PVD_LEVEL3 Falling 2.44
+ // PVD_LEVEL4 Falling 2.64
+ // PVD_LEVEL5 Falling 2.84
+ // PVD_LEVEL6 Falling 3.05
+// PWR_PVDTypeDef pvdConfig;
+//// pvdConfig.Mode = PWR_PVD_MODE_EVENT_RISING_FALLING; //PWR_PVD_MODE_NORMAL;
+// pvdConfig.Mode = PWR_PVD_MODE_IT_RISING_FALLING | PWR_PVD_MODE_EVENT_RISING_FALLING;
+// pvdConfig.PVDLevel = PWR_PVDLEVEL_5;
+//
+// HAL_PWR_ConfigPVD(&pvdConfig);
+// HAL_PWR_EnablePVD();
+// logInfo("Programmable Voltage Detector set for level: %d", pvdConfig.PVDLevel);
+//
+//// HAL_PWR_PVDCallback(); // Does inc the value
+//
+//// __HAL_PWR_PVD_EXTI_CLEAR_FLAG();
+// HAL_PWR_PVD_IRQHandler(); // This calls the callback and clears the IRQ
+// __HAL_PWR_PVD_EXTI_GENERATE_SWIT();
+
+// __HAL_PPP_EXTI_ENABLE_IT();
+
+// __HAL_PWR_PVD_EXTI_ENABLE_EVENT()
+
wait(1.0);
@@ -146,13 +188,17 @@
pc.printf("= Baseboard Init Finished with Error =\r\n");
}
- bbio.regCCInInt(&ccInIntCallback);
- bbio.regTamperInt(&tamperIntCallback);
- bbio.regPairBtnInt(&pairBtnIntCallback);
+ Callback<void()> ccInIntObj (&ccInIntCallback);
+ Callback<void()> tamperIntObj (&tamperIntCallback);
+ Callback<void()> pairBtnIntObj (&pairBtnIntCallback);
+ bbio.regCCInInt(ccInIntObj);
+ bbio.regTamperInt(tamperIntObj);
+ bbio.regPairBtnInt(pairBtnIntObj);
menuMgr.regBBIO(&bbio);
menuMgr.printMenu();
+ uint8_t waitCharIdx = 0;
while (true) {
if (pc.readable()) {
@@ -162,9 +208,15 @@
menuMgr.printMenu();
}
else {
- pc.printf("*");
+ pc.printf("\b%c", WAIT_CHARS[waitCharIdx]);
+ if (waitCharIdx >= sizeof(WAIT_CHARS)) {
+ waitCharIdx = 0;
+ }
+ else {
+ waitCharIdx++;
+ }
}
- wait(1.0);
+ wait(0.1);
}
return 0;
}
--- a/xDotBridge/src/BaseboardIO.cpp Mon Feb 13 17:10:59 2017 -0700
+++ b/xDotBridge/src/BaseboardIO.cpp Fri Feb 17 08:06:37 2017 -0700
@@ -10,7 +10,7 @@
const float COIL_ON_TIME = 0.030; // 30 ms
-// Port expander 0
+// Port expander 0 (Currently U7)
const uint8_t pEx0232En = 0x01;
const uint8_t pEx0232TxDis = 0x02;
const uint8_t pEx0Rot1B1 = 0x04;
@@ -19,8 +19,9 @@
const uint8_t pEx0Rot1B8 = 0x20;
const uint8_t pEx0Rot2B1 = 0x40;
const uint8_t pEx0Rot2B2 = 0x80;
+const uint8_t pEx0OutMask = 0x03; // Only allow bits 0,1 to be changed
-// Port expander 1
+// Port expander 1 (Currently U8)
const uint8_t pEx1NoNcSel = 0x01;
const uint8_t pEx1RxTxSel = 0x02;
const uint8_t pEx1WanSel = 0x04;
@@ -29,6 +30,7 @@
const uint8_t pEx1Rot2B4 = 0x20;
const uint8_t pEx1RlyB = 0x40; // This is actually a coil
const uint8_t pEx1RlyA = 0x80; // This is actually a coil
+const uint8_t pEx1OutMask = 0xC0; // Only allow bits 6,7 to be changed
/**
* Note for interrupt within uC cannot use two pins with the same numeric suffix (e.g. cannot
@@ -42,7 +44,7 @@
mPairBtn(UART_CTS), // Interrupt pin PA_11
// mLed(SWDIO),
mLed(GPIO0),
- mSwitchedIOCtrl(I2C_SCL)
+ mSwitchedIOCtrl(I2C_SCL, 0)
{
// mCCInIntCallback = NULL;
// mTamperIntCallback = NULL;
@@ -100,16 +102,23 @@
else {
mCCIn.rise(func);
}
+ mPairBtn.mode(PullNone);
+ mCCIn.enable_irq();
}
void BaseboardIO::regTamperInt(Callback<void()> func)
{
// Pulled high, switched low
+ mPairBtn.mode(PullNone);
+ mTamper.rise(func);
mTamper.fall(func);
+ mTamper.enable_irq();
}
void BaseboardIO::regPairBtnInt(Callback<void()> func)
{
// Pulled low, switched high
+ mPairBtn.mode(PullDown);
mPairBtn.rise(func);
+ mPairBtn.enable_irq();
}
// Input
@@ -118,14 +127,19 @@
if ((mPortEx0 == NULL) || (mPortEx1 == NULL))
return cmdError;
// Sample port expanders
+ enableSwitchedIO();
+ wait(0.001); // Wait 1 ms
if (mPortEx0->pioLogicRead(mPortExpanderVal0) != cmdSuccess) {
+ disableSwitchedIO();
logError("Error reading port expander 0.");
return cmdError;
}
if (mPortEx1->pioLogicRead(mPortExpanderVal1) != cmdSuccess) {
+ disableSwitchedIO();
logError("Error reading port expander 1.");
return cmdError;
}
+ disableSwitchedIO();
return cmdSuccess;
}
bool BaseboardIO::isPairBtn()
@@ -136,7 +150,7 @@
bool BaseboardIO::isCCNO()
{
// When DIP switch is not closed (i.e. value reads high) assume NO
- return (mPortExpanderVal1 & pEx1NoNcSel) != 0;
+ return (mPortExpanderVal1 & pEx1NoNcSel) != 0; // Open NO, closed NC
}
bool BaseboardIO::isRx()
{
@@ -211,6 +225,10 @@
CmdResult BaseboardIO::serialRx(bool enable)
{
uint8_t val;
+ if (mPortEx0 == NULL) {
+ logError("Error enabling 232. Port expanders not initialized.");
+ return cmdError;
+ }
mPortEx0->pioLogicRead(val);
// Active low from port expander -> pmos -> 232 (active chip EN)
@@ -221,7 +239,7 @@
val |= pEx0232En;
}
- if (mPortEx1->pioLogicWrite(val) != cmdSuccess) {
+ if (mPortEx0->pioLogicWrite(val | ~pEx0OutMask) != cmdSuccess) {
logError("Error enabling 232");
return cmdError;
}
@@ -230,6 +248,10 @@
CmdResult BaseboardIO::serialTx(bool enable)
{
uint8_t val;
+ if (mPortEx0 == NULL) {
+ logError("Error enabling 232 TX. Port expanders not initialized.");
+ return cmdError;
+ }
mPortEx0->pioLogicRead(val);
// Active high tx disable therefore active low tx enable (note chip must also be enabled for TX)
@@ -240,7 +262,7 @@
val |= pEx0232TxDis;
}
- if (mPortEx1->pioLogicWrite(val) != cmdSuccess) {
+ if (mPortEx0->pioLogicWrite(val | ~pEx0OutMask) != cmdSuccess) {
logError("Error enabling 232 TX");
return cmdError;
}
@@ -262,26 +284,36 @@
{
uint8_t addr[8];
uint8_t result;
+ int i;
// Search Bus
logInfo("Starting OneWire Search");
- int i=0;
- mOWMaster.reset();
- while (true) {
- // TODO maybe change to family based search
- result = mOWMaster.search(addr);
- logInfo("ROM Addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x%02x found.",
- addr[7],addr[6],addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]);
- if (result != 1)
+ enableSwitchedIO();
+ for (int j=0;j<10;j++) { // Try 5 times
+ i=0;
+ mOWMaster.reset();
+ mOWMaster.reset_search();
+ wait(1.0);
+ while (true) {
+ // TODO maybe change to family based search
+ result = mOWMaster.search(addr);
+ if (result != 1) {
+ break;
+ }
+ logInfo("ROM Addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x%02x found.",
+ addr[7],addr[6],addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]);
+ if (i == 0) {
+ std::memcpy(mPortExpanderROM0, addr, sizeof(mPortExpanderROM0));
+ }
+ else if (i == 1) {
+ std::memcpy(mPortExpanderROM1, addr, sizeof(mPortExpanderROM1));
+ }
+ i++;
+ }
+ // TODO maybe only allow a reasonable number of Port Expanders
+ if (i >=2) {
break;
- if (i == 0) {
- std::memcpy(mPortExpanderROM0, addr, sizeof(mPortExpanderROM0));
}
- else if (i == 1) {
- std::memcpy(mPortExpanderROM1, addr, sizeof(mPortExpanderROM1));
- }
- i++;
- // TODO maybe only allow a reasonable number of Port Expanders
}
logInfo("Finished OneWire Search");
@@ -290,25 +322,31 @@
return cmdError;
}
+ // All rotary switches should be at 0. DIPS should be asserted.
// If switches are set in factory default mode then port expander 1 should read 0xFF and
// port expander 2 should read 0xF0.
mPortEx0 = new DS2408(&mOWMaster, mPortExpanderROM0);
mPortEx1 = new DS2408(&mOWMaster, mPortExpanderROM1);
+
+ enableSwitchedIO();
if (mPortEx0->pioLogicRead(mPortExpanderVal0) != cmdSuccess) {
logError("Error during port expander ID. Read failed.");
+ disableSwitchedIO();
delete mPortEx0;
delete mPortEx1;
return cmdError;
}
if (mPortEx1->pioLogicRead(mPortExpanderVal1) != cmdSuccess) {
logError("Error during port expander ID. Read failed.");
+ disableSwitchedIO();
delete mPortEx0;
delete mPortEx1;
return cmdError;
}
+ disableSwitchedIO();
if ((mPortExpanderVal0 == 0xFF) and (mPortExpanderVal1 == 0xF0)) { // Luckily got it right
logInfo("ROMS Swap Not Needed.");
}
@@ -319,7 +357,9 @@
logInfo("Swapped ROMS.");
}
else {
- logError("Error during port expander ID. Port expanders not in expected states. Check user switches.");
+ logError("Error during port expander ID. Port expanders not in "
+ "expected states. Check user switches. Got %02X and %02X",
+ mPortExpanderVal0, mPortExpanderVal1);
delete mPortEx0;
delete mPortEx1;
return cmdError;
@@ -331,56 +371,56 @@
return cmdSuccess;
}
-CmdResult BaseboardIO::closeRelay() {
+CmdResult BaseboardIO::openRelay() {
uint8_t val;
mPortEx1->pioLogicRead(val);
- val |= pEx1RlyA; // Turn on Relay A
- val &= ~pEx1RlyB; // Make sure Relay B is off
+ val |= pEx1RlyA; // Make sure Relay A is off
+ val &= ~pEx1RlyB; // Turn on Relay B
- if (mPortEx1->pioLogicWrite(val) != cmdSuccess) {
- val &= ~pEx1RlyA; // Turn Relay A off
- val &= ~pEx1RlyB; // Turn Relay B off
- mPortEx1->pioLogicWrite(val); // Write a non assert value just to try to overcome an error
+ if (mPortEx1->pioLogicWrite(val | ~pEx1OutMask) != cmdSuccess) {
+ val |= pEx1RlyA; // Turn Relay A off
+ val |= pEx1RlyB; // Turn Relay B off
+ mPortEx1->pioLogicWrite(val | ~pEx1OutMask); // Write a non assert value just to try to overcome an error
logError ("Error turning on coil. Turning both coils off.");
return cmdError;
}
wait(COIL_ON_TIME);
- val &= ~pEx1RlyA; // Turn Relay A off
- val &= ~pEx1RlyB; // Turn Relay B off
+ val |= pEx1RlyA; // Turn Relay A off
+ val |= pEx1RlyB; // Turn Relay B off
- if (mPortEx1->pioLogicWrite(val) != cmdSuccess) {
- mPortEx1->pioLogicWrite(val);
+ if (mPortEx1->pioLogicWrite(val | ~pEx1OutMask) != cmdSuccess) {
+ mPortEx1->pioLogicWrite(val | ~pEx1OutMask);
logError ("Error turning off coils. Trying again.");
return cmdError;
}
return cmdSuccess;
}
-CmdResult BaseboardIO::openRelay() {
+CmdResult BaseboardIO::closeRelay() {
uint8_t val;
mPortEx1->pioLogicRead(val);
- val &= ~pEx1RlyA; // Make sure Relay A is off
- val |= pEx1RlyB; // Turn on Relay B
+ val &= ~pEx1RlyA; // Turn on Relay A
+ val |= pEx1RlyB; // Make sure Relay B is off
- if (mPortEx1->pioLogicWrite(val) != cmdSuccess) {
- val &= ~pEx1RlyA; // Turn Relay A off
- val &= ~pEx1RlyB; // Turn Relay B off
- mPortEx1->pioLogicWrite(val); // Write a non assert value just to try to overcome an error
+ if (mPortEx1->pioLogicWrite(val | ~pEx1OutMask) != cmdSuccess) {
+ val |= pEx1RlyA; // Turn Relay A off
+ val |= pEx1RlyB; // Turn Relay B off
+ mPortEx1->pioLogicWrite(val | ~pEx1OutMask); // Write a non assert value just to try to overcome an error
logError ("Error turning on coil. Turning both coils off.");
return cmdError;
}
wait(COIL_ON_TIME);
- val &= ~pEx1RlyA; // Turn Relay A off
- val &= ~pEx1RlyB; // Turn Relay B off
+ val |= pEx1RlyA; // Turn Relay A off
+ val |= pEx1RlyB; // Turn Relay B off
- if (mPortEx1->pioLogicWrite(val) != cmdSuccess) {
- mPortEx1->pioLogicWrite(val);
+ if (mPortEx1->pioLogicWrite(val | ~pEx1OutMask) != cmdSuccess) {
+ mPortEx1->pioLogicWrite(val | ~pEx1OutMask);
logError ("Error turning off coils. Trying again.");
return cmdError;
}
