![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
20200716 read Status Register each second
Dependencies: SDFileSystem mbed-os-example-ble-GattServer max32630fthr
Revision 21:51e162c130a9, committed 2020-07-16
- Comitter:
- aureliocarella
- Date:
- Thu Jul 16 14:59:04 2020 +0000
- Parent:
- 13:21b02b0b2cb2
- Commit message:
- 20200716
Changed in this revision
diff -r 21b02b0b2cb2 -r 51e162c130a9 BLEProcess.h --- a/BLEProcess.h Fri Dec 14 13:15:33 2018 +0000 +++ b/BLEProcess.h Thu Jul 16 14:59:04 2020 +0000 @@ -149,6 +149,7 @@ void when_connection(const Gap::ConnectionCallbackParams_t *connection_event) { printf("Connected.\r\n"); + //send MAX30001 Start Commands } void when_disconnection(const Gap::DisconnectionCallbackParams_t *event) @@ -170,7 +171,7 @@ static GapAdvertisingData make_advertising_data(void) { - static const uint8_t device_name[] = "GattServer"; + static const uint8_t device_name[] = "TCARE-ECG"; GapAdvertisingData advertising_data; // add advertising flags
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/HspLed/HspLed/HspLed.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/HspLed/HspLed/HspLed.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "HspLed.h" +#include "Peripherals.h" + +void hspled_int_handler(void); + +//******************************************************************************* +HspLed::HspLed(PinName ledPin) : + redLed(LED_RED, 0), isStarted(false), timerIntervalLast(-1), timerInterval(500) { +} + + +//******************************************************************************* +void HspLed::state(int state) { + redLed.write(state); +} + + +//******************************************************************************* +void HspLed::toggle(void) { + state(!redLed.read()); +} + + +//******************************************************************************* +void HspLed::setMode(eMode mode) { + this->mode = mode; +} + +//******************************************************************************* +void HspLed::blink(uint32_t mSeconds) { + mode = eLedPeriod; + this->timerInterval = (float)mSeconds / 1000.0f; + start(); +} + +//******************************************************************************* +void HspLed::pattern(uint32_t bitPattern, uint32_t mSeconds) { + mode = eLedPattern; + this->bitPattern = bitPattern; + this->timerInterval = (float)mSeconds / 1000.0f; + start(); +} + +//******************************************************************************* +void HspLed::on(void) { + mode = eLedOn; + state(HSP_LED_ON); + start(); +} + + +//******************************************************************************* +void HspLed::off(void) { + mode = eLedOff; + state(HSP_LED_OFF); + start(); +} + + +//******************************************************************************* +void HspLed::patternToLed(void) { + uint32_t bit; + bit = bitPattern & 1; + state(bit); + // rotate the pattern + bitPattern = bitPattern >> 1; + bitPattern = bitPattern | (bit << 31); +} + + +//******************************************************************************* +void HspLed::service(void) { + switch (mode) { + case eLedOn: + state(HSP_LED_ON); + break; + case eLedOff: + state(HSP_LED_OFF); + break; + case eLedPeriod: + toggle(); + break; + case eLedPattern: + patternToLed(); + break; + } +} + +//******************************************************************************* +void HspLed::start(void) { + if (timerInterval != timerIntervalLast && isStarted == true) { + stop(); + } + ticker.attach(&hspled_int_handler, timerInterval); + timerIntervalLast = timerInterval; + + isStarted = true; +} + +//******************************************************************************* +void HspLed::stop(void) { + ticker.detach(); + isStarted = false; +} + +//******************************************************************************* +void hspled_int_handler(void) { + HspLed *hspLed = Peripherals::hspLed(); + hspLed->service(); +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/HspLed/HspLed/HspLed.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/HspLed/HspLed/HspLed.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _LED_H_ +#define _LED_H_ + +#include "mbed.h" + +/** + * Driver for the HSP Led, supports different blink rates and patterns + * + * @code + * #include <stdio.h> + * #include "mbed.h" + * #include "xxx.h" + * + * I2C i2c(I2C_SDA, I2C_SCL); + * xxx xxx(&i2c); + * + * int main(void) { + * printf("Initialized xxx\n"); + * while(1) { + * if (xxx.init() != 0) { + * printf("Error communicating with xxx\n"); + * } else { + * printf("Initialized xxx\n"); + * break; + * } + * wait(1); + * } + * + * while(1) { + * printf(""); + * wait(1); + * } + * } + * @endcode + */ + +class HspLed { +public: + static const int LED_ON = 0; + static const int LED_OFF = 1; + + /// define all of the modes the LED can support + typedef enum eMode { + eLedOn, + eLedOff, + eLedPeriod, + eLedPattern + } eMode; + /// define the values that turn the LED on or off at the pin + #define HSP_LED_ON 0 + #define HSP_LED_OFF 1 + + /* + * @brief Constructor where you specify the LED pin name + */ + HspLed(PinName ledPin); + + /** + * Blink the HSP LED at a set time interval + * @param mSeconds Number of seconds to set the timer interval + */ + void blink(uint32_t mSeconds); + + /** + * @brief Start rotating the LED through a 32-bit pattern at a mS rate specified + * @param pattern 32-bit pattern to rotate through + * @param mSeconds the amount of time to take per bit in the pattern + */ + void pattern(uint32_t pattern, uint32_t mSeconds); + + /** + * @brief Turn the LED on + */ + void on(void); + + /** + * @brief Turn the LED off + */ + void off(void); + + /** + * @brief Update the LED + */ + void service(void); + +private: + + /** + * Set the mode of the LED, the mode include blinking at a set rate or blinking + * according to a pattern + * @param mode Mode to set the LED to + */ + void setMode(eMode state); + + /** + * Toggle the state of the LED + */ + void toggle(void); + + /** + * Start the LED blinking or rotating through a pattern + */ + void start(void); + + /** + * Stop blinking or rotating through a pattern + */ + void stop(void); + + /** + * Write the LED pin to a state + * @param state A one or zero value to write to the LED pin + */ + void state(int state); + + /* + * @brief Single step through the pattern and output to the LED + */ + void patternToLed(void); + + /// timer interval in mS + float timerInterval; + /// last timer interval set to... used to prevent resetting the timer to the same value + float timerIntervalLast; + /// local state of the pattern to rotate through + uint32_t bitPattern; + /// current mode of the LED + eMode mode; + /// the LED digital output + DigitalOut redLed; + /// Timer service used to update the LED + Ticker ticker; + /// Flag to indicate if the timer has been started + bool isStarted; +}; + +#endif /* _LED_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/HspLed/HspLed_RPC.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/HspLed/HspLed_RPC.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "HspLed_RPC.h" +#include "HspLed.h" +#include "StringHelper.h" +#include "Peripherals.h" + +int Led_On(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + Peripherals::hspLed()->on(); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int Led_Off(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + Peripherals::hspLed()->off(); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int Led_BlinkHz(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[1]; + uint32_t reply[1]; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + Peripherals::hspLed()->blink(args[0]); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int Led_BlinkPattern(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[2]; + uint32_t reply[1]; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + Peripherals::hspLed()->pattern(args[0], args[1]); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/HspLed/HspLed_RPC.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/HspLed/HspLed_RPC.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _LED_RPC_H_ +#define _LED_RPC_H_ + +#include "mbed.h" + +int Led_On(char argStrs[32][32], char replyStrs[32][32]); +int Led_Off(char argStrs[32][32], char replyStrs[32][32]); +int Led_BlinkHz(char argStrs[32][32], char replyStrs[32][32]); +int Led_BlinkPattern(char argStrs[32][32], char replyStrs[32][32]); + +#endif /* _LED_RPC_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/MAX30001/MAX30001/MAX30001.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/MAX30001/MAX30001/MAX30001.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,1299 @@ + +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "mbed.h" +#include "MAX30001.h" + +MAX30001 *MAX30001::instance = NULL; + + +//****************************************************************************** +MAX30001::MAX30001(PinName mosi, PinName miso, PinName sclk, PinName cs) +{ + m_spi = new SPI(mosi, miso, sclk); + m_cs = new DigitalOut(cs, 1); + + m_spi->frequency(3000000); + spi_owner = true; + functionpointer.attach(&spiHandler); + onDataAvailableCallback = NULL; + instance = this; +} + + +//****************************************************************************** +MAX30001::MAX30001(SPI *spi, DigitalOut *cs) +{ + m_spi = spi; + m_cs = cs; + spi->frequency(3000000); + spi_owner = false; + functionpointer.attach(&spiHandler); + onDataAvailableCallback = NULL; + instance = this; +} + + +//****************************************************************************** +MAX30001::~MAX30001(void) { + + if (spi_owner) { + delete m_spi; + delete m_cs; + } +} + +//****************************************************************************** +int MAX30001::max30001_Rbias_FMSTR_Init(uint8_t En_rbias, uint8_t Rbiasv, + uint8_t Rbiasp, uint8_t Rbiasn, + uint8_t Fmstr) { + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_rbias = En_rbias; + max30001_cnfg_gen.bit.rbiasv = Rbiasv; + max30001_cnfg_gen.bit.rbiasp = Rbiasp; + max30001_cnfg_gen.bit.rbiasn = Rbiasn; + max30001_cnfg_gen.bit.fmstr = Fmstr; + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_CAL_InitStart(uint8_t En_Vcal, uint8_t Vmode, + uint8_t Vmag, uint8_t Fcal, uint16_t Thigh, + uint8_t Fifty) { + // CNFG_CAL + if (max30001_reg_read(CNFG_CAL, &max30001_cnfg_cal.all) == -1) { + return -1; + } + + max30001_cnfg_cal.bit.vmode = Vmode; + max30001_cnfg_cal.bit.vmag = Vmag; + max30001_cnfg_cal.bit.fcal = Fcal; + max30001_cnfg_cal.bit.thigh = Thigh; + max30001_cnfg_cal.bit.fifty = Fifty; + + if (max30001_reg_write(CNFG_CAL, max30001_cnfg_cal.all) == -1) { + return -1; + } + + // RTOS uses a 32768HZ clock. 32768ticks represents 1secs. 1sec/10 = + // 100msecs. + wait(1.0 / 10.0); + + if (max30001_reg_read(CNFG_CAL, &max30001_cnfg_cal.all) == -1) { + return -1; + } + + max30001_cnfg_cal.bit.en_vcal = En_Vcal; + + if (max30001_reg_write(CNFG_CAL, max30001_cnfg_cal.all) == -1) { + return -1; + } + + // RTOS uses a 32768HZ clock. 32768ticks represents 1secs. 1sec/10 = + // 100msecs. + wait(1.0 / 10.0); + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_CAL_Stop(void) { + + if (max30001_reg_read(CNFG_CAL, &max30001_cnfg_cal.all) == -1) { + return -1; + } + + max30001_cnfg_cal.bit.en_vcal = 0; // Disable VCAL, all other settings are left unaffected + + if (max30001_reg_write(CNFG_CAL, max30001_cnfg_cal.all) == -1) { + return -1; + } + + return 0; +} +//****************************************************************************** +//****************************************************************************** +int MAX30001::max30001_INT_assignment(max30001_intrpt_Location_t en_enint_loc, max30001_intrpt_Location_t en_eovf_loc, max30001_intrpt_Location_t en_fstint_loc, + max30001_intrpt_Location_t en_dcloffint_loc, max30001_intrpt_Location_t en_bint_loc, max30001_intrpt_Location_t en_bovf_loc, + max30001_intrpt_Location_t en_bover_loc, max30001_intrpt_Location_t en_bundr_loc, max30001_intrpt_Location_t en_bcgmon_loc, + max30001_intrpt_Location_t en_pint_loc, max30001_intrpt_Location_t en_povf_loc, max30001_intrpt_Location_t en_pedge_loc, + max30001_intrpt_Location_t en_lonint_loc, max30001_intrpt_Location_t en_rrint_loc, max30001_intrpt_Location_t en_samp_loc, + max30001_intrpt_type_t intb_Type, max30001_intrpt_type_t int2b_Type) + + +{ + // INT1 + + if (max30001_reg_read(EN_INT, &max30001_en_int.all) == -1) { + return -1; + } + + // max30001_en_int2.bit.en_pint = 0b1; // Keep this off... + + max30001_en_int.bit.en_eint = 0b1 & en_enint_loc; + max30001_en_int.bit.en_eovf = 0b1 & en_eovf_loc; + max30001_en_int.bit.en_fstint = 0b1 & en_fstint_loc; + + max30001_en_int.bit.en_dcloffint = 0b1 & en_dcloffint_loc; + max30001_en_int.bit.en_bint = 0b1 & en_bint_loc; + max30001_en_int.bit.en_bovf = 0b1 & en_bovf_loc; + + max30001_en_int.bit.en_bover = 0b1 & en_bover_loc; + max30001_en_int.bit.en_bundr = 0b1 & en_bundr_loc; + max30001_en_int.bit.en_bcgmon = 0b1 & en_bcgmon_loc; + + max30001_en_int.bit.en_pint = 0b1 & en_pint_loc; + max30001_en_int.bit.en_povf = 0b1 & en_povf_loc; + max30001_en_int.bit.en_pedge = 0b1 & en_pedge_loc; + + max30001_en_int.bit.en_lonint = 0b1 & en_lonint_loc; + max30001_en_int.bit.en_rrint = 0b1 & en_rrint_loc; + max30001_en_int.bit.en_samp = 0b1 & en_samp_loc; + + max30001_en_int.bit.intb_type = intb_Type; + + if (max30001_reg_write(EN_INT, max30001_en_int.all) == -1) { + return -1; + } + + // INT2 + + if (max30001_reg_read(EN_INT2, &max30001_en_int2.all) == -1) { + return -1; + } + + max30001_en_int2.bit.en_eint = 0b1 & (en_enint_loc >> 1); + max30001_en_int2.bit.en_eovf = 0b1 & (en_eovf_loc >> 1); + max30001_en_int2.bit.en_fstint = 0b1 & (en_fstint_loc >> 1); + + max30001_en_int2.bit.en_dcloffint = 0b1 & (en_dcloffint_loc >> 1); + max30001_en_int2.bit.en_bint = 0b1 & (en_bint_loc >> 1); + max30001_en_int2.bit.en_bovf = 0b1 & (en_bovf_loc >> 1); + + max30001_en_int2.bit.en_bover = 0b1 & (en_bover_loc >> 1); + max30001_en_int2.bit.en_bundr = 0b1 & (en_bundr_loc >> 1); + max30001_en_int2.bit.en_bcgmon = 0b1 & (en_bcgmon_loc >> 1); + + max30001_en_int2.bit.en_pint = 0b1 & (en_pint_loc >> 1); + max30001_en_int2.bit.en_povf = 0b1 & (en_povf_loc >> 1); + max30001_en_int2.bit.en_pedge = 0b1 & (en_pedge_loc >> 1); + + max30001_en_int2.bit.en_lonint = 0b1 & (en_lonint_loc >> 1); + max30001_en_int2.bit.en_rrint = 0b1 & (en_rrint_loc >> 1); + max30001_en_int2.bit.en_samp = 0b1 & (en_samp_loc >> 1); + + max30001_en_int2.bit.intb_type = int2b_Type; + + if (max30001_reg_write(EN_INT2, max30001_en_int2.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_ECG_InitStart(uint8_t En_ecg, uint8_t Openp, + uint8_t Openn, uint8_t Pol, + uint8_t Calp_sel, uint8_t Caln_sel, + uint8_t E_fit, uint8_t Rate, uint8_t Gain, + uint8_t Dhpf, uint8_t Dlpf) { + + // CNFG_EMUX + + if (max30001_reg_read(CNFG_EMUX, &max30001_cnfg_emux.all) == -1) { + return -1; + } + + max30001_cnfg_emux.bit.openp = Openp; + max30001_cnfg_emux.bit.openn = Openn; + max30001_cnfg_emux.bit.pol = Pol; + max30001_cnfg_emux.bit.calp_sel = Calp_sel; + max30001_cnfg_emux.bit.caln_sel = Caln_sel; + + if (max30001_reg_write(CNFG_EMUX, max30001_cnfg_emux.all) == -1) { + return -1; + } + + /**** ENABLE CHANNELS ****/ + // CNFG_GEN + + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_ecg = En_ecg; // 0b1 + + // fmstr is default + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + + /**** Wait for PLL Lock & References to settle down ****/ + + max30001_timeout = 0; + + do { + if (max30001_reg_read(STATUS, &max30001_status.all) == -1) // Wait and spin for PLL to lock... + { + return -1; + } + } while (max30001_status.bit.pllint == 1 && max30001_timeout++ <= 1000); + + // MNGR_INT + + if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { + return -1; + } + + max30001_mngr_int.bit.e_fit = E_fit; // 31 + + if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { + return -1; + } + + // CNFG_ECG + + if (max30001_reg_read(CNFG_ECG, &max30001_cnfg_ecg.all) == -1) { + return -1; + } + + max30001_cnfg_ecg.bit.rate = Rate; + max30001_cnfg_ecg.bit.gain = Gain; + max30001_cnfg_ecg.bit.dhpf = Dhpf; + max30001_cnfg_ecg.bit.dlpf = Dlpf; + + if (max30001_reg_write(CNFG_ECG, max30001_cnfg_ecg.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_ECGFast_Init(uint8_t Clr_Fast, uint8_t Fast, uint8_t Fast_Th) { + if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { + return -1; + } + + max30001_mngr_int.bit.clr_fast = Clr_Fast; + + if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { + return -1; + } + + if (max30001_reg_read(MNGR_DYN, &max30001_mngr_dyn.all) == -1) { + return -1; + } + + max30001_mngr_dyn.bit.fast = Fast; + max30001_mngr_dyn.bit.fast_th = Fast_Th; + + if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_Stop_ECG(void) { + + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_ecg = 0; // Stop ECG + + // fmstr is default + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_PACE_InitStart(uint8_t En_pace, uint8_t Clr_pedge, + uint8_t Pol, uint8_t Gn_diff_off, + uint8_t Gain, uint8_t Aout_lbw, + uint8_t Aout, uint8_t Dacp, + uint8_t Dacn) { + + /**** SET MASTER FREQUENCY, ENABLE CHANNELS ****/ + + // CNFG_GEN + + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_pace = En_pace; // 0b1; + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + + /**** Wait for PLL Lock & References to settle down ****/ + max30001_timeout = 0; + + do { + if (max30001_reg_read(STATUS, &max30001_status.all) == + -1) // Wait and spin for PLL to lock... + { + return -1; + } + + } while (max30001_status.bit.pllint == 1 && max30001_timeout++ <= 1000); + + // MNGR_INT + + if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { + return -1; + } + + max30001_mngr_int.bit.clr_pedge = Clr_pedge; // 0b0; + + if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { + return -1; + } + + /* Put: CNFG_PACE */ + + max30001_reg_read(CNFG_PACE, &max30001_cnfg_pace.all); + + max30001_cnfg_pace.bit.pol = Pol; + max30001_cnfg_pace.bit.gn_diff_off = Gn_diff_off; + max30001_cnfg_pace.bit.gain = Gain; + max30001_cnfg_pace.bit.aout_lbw = Aout_lbw; + max30001_cnfg_pace.bit.aout = Aout; + max30001_cnfg_pace.bit.dacp = Dacp; + max30001_cnfg_pace.bit.dacn = Dacn; + + max30001_reg_write(CNFG_PACE, max30001_cnfg_pace.all); + + return 0; +} +//****************************************************************************** +int MAX30001::max30001_Stop_PACE(void) { + + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_pace = 0; // Stop PACE + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_BIOZ_InitStart( + uint8_t En_bioz, uint8_t Openp, uint8_t Openn, uint8_t Calp_sel, + uint8_t Caln_sel, uint8_t CG_mode, uint8_t B_fit, uint8_t Rate, + uint8_t Ahpf, uint8_t Ext_rbias, uint8_t Gain, uint8_t Dhpf, uint8_t Dlpf, + uint8_t Fcgen, uint8_t Cgmon, uint8_t Cgmag, uint8_t Phoff, uint8_t Inapow_mode) { + + // CNFG_BMUX + + if (max30001_reg_read(CNFG_BMUX, &max30001_cnfg_bmux.all) == -1) { + return -1; + } + + max30001_cnfg_bmux.bit.openp = Openp; // 0b1; + max30001_cnfg_bmux.bit.openn = Openn; // 0b1; + max30001_cnfg_bmux.bit.calp_sel = Calp_sel; // 0b10; + max30001_cnfg_bmux.bit.caln_sel = Caln_sel; // 0b11; + max30001_cnfg_bmux.bit.cg_mode = CG_mode; // 0b00; + + if (max30001_reg_write(CNFG_BMUX, max30001_cnfg_bmux.all) == -1) { + return -1; + } + + /**** SET MASTER FREQUENCY, ENABLE CHANNELS ****/ + + // CNFG_GEN + + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_bioz = En_bioz; + + // fmstr is default + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + + /**** Wait for PLL Lock & References to settle down ****/ + + max30001_timeout = 0; + + do { + if (max30001_reg_read(STATUS, &max30001_status.all) == + -1) // Wait and spin for PLL to lock... + { + return -1; + } + + } while (max30001_status.bit.pllint == 1 && max30001_timeout++ <= 1000); + + /**** Start of CNFG_BIOZ ****/ + + // MNGR_INT + + if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { + return -1; + } + + max30001_mngr_int.bit.b_fit = B_fit; //; + + if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { + return -1; + } + + // CNFG_BIOZ + + if (max30001_reg_read(CNFG_BIOZ, &max30001_cnfg_bioz.all) == -1) { + return -1; + } + + max30001_cnfg_bioz.bit.rate = Rate; + max30001_cnfg_bioz.bit.ahpf = Ahpf; + max30001_cnfg_bioz.bit.ext_rbias = Ext_rbias; + max30001_cnfg_bioz.bit.gain = Gain; + max30001_cnfg_bioz.bit.dhpf = Dhpf; + max30001_cnfg_bioz.bit.dlpf = Dlpf; + max30001_cnfg_bioz.bit.fcgen = Fcgen; + max30001_cnfg_bioz.bit.cgmon = Cgmon; + max30001_cnfg_bioz.bit.cgmag = Cgmag; + max30001_cnfg_bioz.bit.phoff = Phoff; + max30001_cnfg_bioz.bit.inapow_mode = Inapow_mode; + + if (max30001_reg_write(CNFG_BIOZ, max30001_cnfg_bioz.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_Stop_BIOZ(void) { + + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_bioz = 0; // Stop BIOZ + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_BIOZ_InitBist(uint8_t En_bist, uint8_t Rnom, + uint8_t Rmod, uint8_t Fbist) { + + // CNFG_BMUX + + if (max30001_reg_read(CNFG_BMUX, &max30001_cnfg_bmux.all) == -1) { + return -1; + } + + max30001_cnfg_bmux.bit.en_bist = En_bist; + max30001_cnfg_bmux.bit.rnom = Rnom; + max30001_cnfg_bmux.bit.rmod = Rmod; + max30001_cnfg_bmux.bit.fbist = Fbist; + + if (max30001_reg_write(CNFG_BMUX, max30001_cnfg_bmux.all) == -1) { + return -1; + } + + return 0; +} +//****************************************************************************** +int MAX30001::max30001_RtoR_InitStart(uint8_t En_rtor, uint8_t Wndw, + uint8_t Gain, uint8_t Pavg, uint8_t Ptsf, + uint8_t Hoff, uint8_t Ravg, uint8_t Rhsf, + uint8_t Clr_rrint) { + + // MNGR_INT + + if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { + return -1; + } + + max30001_mngr_int.bit.clr_rrint = + Clr_rrint; // 0b01 & 0b00 are for interrupt mode... + // 0b10 is for monitoring mode... it just overwrites the data... + + if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { + return -1; + } + + // RTOR1 + if (max30001_reg_read(CNFG_RTOR1, &max30001_cnfg_rtor1.all) == -1) { + return -1; + } + + max30001_cnfg_rtor1.bit.wndw = Wndw; + max30001_cnfg_rtor1.bit.gain = Gain; + max30001_cnfg_rtor1.bit.en_rtor = En_rtor; + max30001_cnfg_rtor1.bit.pavg = Pavg; + max30001_cnfg_rtor1.bit.ptsf = Ptsf; + + if (max30001_reg_write(CNFG_RTOR1, max30001_cnfg_rtor1.all) == -1) { + return -1; + } + // RTOR2 + + if (max30001_reg_read(CNFG_RTOR2, &max30001_cnfg_rtor2.all) == -1) { + return -1; + } + max30001_cnfg_rtor2.bit.hoff = Hoff; + max30001_cnfg_rtor2.bit.ravg = Ravg; + max30001_cnfg_rtor2.bit.rhsf = Rhsf; + + if (max30001_reg_write(CNFG_RTOR2, max30001_cnfg_rtor2.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_Stop_RtoR(void) { + + if (max30001_reg_read(CNFG_RTOR1, &max30001_cnfg_rtor1.all) == -1) { + return -1; + } + + max30001_cnfg_rtor1.bit.en_rtor = 0; // Stop RtoR + + if (max30001_reg_write(CNFG_RTOR1, max30001_cnfg_rtor1.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_PLL_lock(void) { + // Spin to see PLLint become zero to indicate a lock. + + max30001_timeout = 0; + + do { + if (max30001_reg_read(STATUS, &max30001_status.all) == + -1) // Wait and spin for PLL to lock... + { + return -1; + } + + } while (max30001_status.bit.pllint == 1 && max30001_timeout++ <= 1000); + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_sw_rst(void) { + // SW reset for the MAX30001 chip + + if (max30001_reg_write(SW_RST, 0x000000) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_synch(void) { // For synchronization + if (max30001_reg_write(SYNCH, 0x000000) == -1) { + return -1; + } + return 0; +} + +//****************************************************************************** +int MAX30001::max300001_fifo_rst(void) { // Resets the FIFO + if (max30001_reg_write(FIFO_RST, 0x000000) == -1) { + return -1; + } + return 0; +} + +//****************************************************************************** +// int MAX30001::max30001_reg_write(uint8_t addr, uint32_t data) +int MAX30001::max30001_reg_write(MAX30001_REG_map_t addr, uint32_t data) { + + uint8_t result[4]; + uint8_t data_array[4]; + int32_t success = 0; + + data_array[0] = (addr << 1) & 0xff; + + data_array[3] = data & 0xff; + data_array[2] = (data >> 8) & 0xff; + data_array[1] = (data >> 16) & 0xff; + + success = SPI_Transmit(&data_array[0], 4, &result[0], 4); + + if (success != 0) { + return -1; + } else { + return 0; + } +} + +//****************************************************************************** + int MAX30001::max30001_reg_read(uint8_t addr, uint32_t *return_data){ +/*int MAX30001::max30001_reg_read(MAX30001_REG_map_t addr, + uint32_t *return_data) {*/ + uint8_t result[4]; + uint8_t data_array[1]; + int32_t success = 0; + + data_array[0] = ((addr << 1) & 0xff) | 1; // For Read, Or with 1 + success = SPI_Transmit(&data_array[0], 1, &result[0], 4); + *return_data = /*result[0] + */ (uint32_t)(result[1] << 16) + + (result[2] << 8) + result[3]; + if (success != 0) { + return -1; + } else { + return 0; + } +} + +//****************************************************************************** +int MAX30001::max30001_Enable_DcLeadOFF_Init(int8_t En_dcloff, int8_t Ipol, + int8_t Imag, int8_t Vth) { + // the leads are not touching the body + + // CNFG_EMUX, Set ECGP and ECGN for external hook up... + + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_dcloff = En_dcloff; + max30001_cnfg_gen.bit.ipol = Ipol; + max30001_cnfg_gen.bit.imag = Imag; + max30001_cnfg_gen.bit.vth = Vth; + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_Disable_DcLeadOFF(void) { + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_dcloff = 0; // Turned off the dc lead off. + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_BIOZ_Enable_ACLeadOFF_Init(uint8_t En_bloff, + uint8_t Bloff_hi_it, + uint8_t Bloff_lo_it) { + + // CNFG_GEN + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_bloff = En_bloff; + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + + // MNGR_DYN + if (max30001_reg_read(MNGR_DYN, &max30001_mngr_dyn.all) == -1) { + return -1; + } + + max30001_mngr_dyn.bit.bloff_hi_it = Bloff_hi_it; + max30001_mngr_dyn.bit.bloff_lo_it = Bloff_lo_it; + + if (max30001_reg_write(MNGR_DYN, max30001_mngr_dyn.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_BIOZ_Disable_ACleadOFF(void) { + // CNFG_GEN + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_bloff = 0b0; // Turns of the BIOZ AC Lead OFF feature + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + + return 0; +} + +//****************************************************************************** +int MAX30001::max30001_BIOZ_Enable_BCGMON(void) { + // CNFG_BIOZ + if (max30001_reg_read(CNFG_BIOZ, &max30001_cnfg_bioz.all) == -1) { + return -1; + } + + max30001_cnfg_bioz.bit.cgmon = 1; + + if (max30001_reg_write(CNFG_BIOZ, max30001_cnfg_bioz.all) == -1) { + return -1; + } + + max30001_reg_read(CNFG_BIOZ, &max30001_cnfg_bioz.all); + + return 0; +} + +#if 1 +//****************************************************************************** +int MAX30001::max30001_Enable_LeadON(int8_t Channel) // Channel: ECG = 0b01, BIOZ = 0b10, Disable = 0b00 +{ + + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_ecg = 0b0; + max30001_cnfg_gen.bit.en_bioz = 0b0; + max30001_cnfg_gen.bit.en_pace = 0b0; + + max30001_cnfg_gen.bit.en_ulp_lon = Channel; // BIOZ ULP lead on detection... + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all); + + max30001_reg_read(STATUS, &max30001_status.all); + + return 0; +} +//****************************************************************************** +int MAX30001::max30001_Disable_LeadON(void) { + + if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { + return -1; + } + + max30001_cnfg_gen.bit.en_ulp_lon = 0b0; + + if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { + return -1; + } + + return 0; +} +#endif +//****************************************************************************** +#define LEADOFF_SERVICE_TIME 0x2000 // 0x1000 = 1 second +#define LEADOFF_NUMSTATES 2 +uint32_t leadoffState = 0; +uint32_t max30001_LeadOffoldTime = 0; +void MAX30001::max30001_ServiceLeadoff(uint32_t currentTime) { + + uint32_t delta_Time; + + delta_Time = currentTime - max30001_LeadOffoldTime; + + if (delta_Time > LEADOFF_SERVICE_TIME) { + switch (leadoffState) { + case 0: /* switch to ECG DC Lead OFF */ + max30001_Enable_DcLeadOFF_Init(0b01, 0b0, 0b001, 0b00); + break; + + case 1: /* switch to BIOZ DC Lead OFF */ + max30001_Enable_DcLeadOFF_Init(0b10, 0b0, 0b001, 0b00); + break; + } + + leadoffState++; + leadoffState %= LEADOFF_NUMSTATES; + + max30001_LeadOffoldTime = currentTime; + } +} +//****************************************************************************** +#define LEADON_SERVICE_TIME 0x2000 // 0x1000 = 1 second +#define LEADON_NUMSTATES 2 +uint32_t leadOnState = 0; +uint32_t max30001_LeadOnoldTime = 0; +void MAX30001::max30001_ServiceLeadON(uint32_t currentTime) { + + uint32_t delta_Time; + + delta_Time = currentTime - max30001_LeadOnoldTime; + + if (delta_Time > LEADON_SERVICE_TIME) { + switch (leadOnState) { + case 0: /* switch to ECG DC Lead ON */ + max30001_Enable_LeadON(0b01); + break; + + case 1: /* switch to BIOZ DC Lead ON */ + max30001_Enable_LeadON(0b10); + break; + } + + leadOnState++; + leadOnState %= LEADON_NUMSTATES; + + max30001_LeadOnoldTime = currentTime; + } +} + +//****************************************************************************** +int MAX30001::max30001_FIFO_LeadONOff_Read(void) { + + uint8_t result[32 * 3]; // 32words - 3bytes each + uint8_t paceResult[6 * 3]; + uint8_t data_array[4]; + int32_t success = 0; + int i, j; + + uint32_t total_databytes; + uint8_t i_index; + uint8_t data_chunk; + uint8_t loop_logic; + + uint8_t etag, ptag, btag; + + uint8_t adr; + + //int8_t ReadAllPaceOnce; + bool anyPaceDetected = false; + static uint8_t dcloffint_OneShot = 0; + static uint8_t acloffint_OneShot = 0; + static uint8_t bcgmon_OneShot = 0; + static uint8_t acleadon_OneShot = 0; + + int8_t ret_val; + + if (max30001_status.bit.eint == 1) { + adr = ECG_FIFO_BURST; + data_array[0] = ((adr << 1) & 0xff) | 1; + + // The SPI routine only sends out data of 32 bytes in size. Therefore the + // data is being read in + // smaller chunks in this routine... + + total_databytes = (max30001_mngr_int.bit.e_fit + 1) * 3; + + i_index = 0; + loop_logic = 1; + + while (loop_logic) { + if (total_databytes > 30) { + data_chunk = 30; + total_databytes = total_databytes - 30; + } else { + data_chunk = total_databytes; + loop_logic = 0; + } + + /* The extra 1 byte is for the extra byte that comes out of the SPI */ + success = SPI_Transmit(&data_array[0], 1, &result[i_index], (data_chunk + 1)); // Make a copy of the FIFO over here... + + if (success != 0) { + return -1; + } + + /* This is important, because every transaction above creates an empty + * redundant data at result[0] */ + for (j = i_index; j < (data_chunk + i_index); j++) /* get rid of the 1 extra byte by moving the whole array up one */ + { + result[j] = result[j + 1]; + } + + i_index = i_index + 30; /* point to the next array location to put the data in */ + } + + //ReadAllPaceOnce = 0; + + /* Put the content of the FIFO based on the EFIT value, We ignore the + * result[0] and start concatenating indexes: 1,2,3 - 4,5,6 - 7,8,9 - */ + for (i = 0, j = 0; i < max30001_mngr_int.bit.e_fit + 1; i++, j = j + 3) // index1=23-16 bit, index2=15-8 bit, index3=7-0 bit + { + max30001_ECG_FIFO_buffer[i] = ((uint32_t)result[j] << 16) + (result[j + 1] << 8) + result[j + 2]; + + etag = (0b00111000 & result[j + 2]) >> 3; + ptag = 0b00000111 & result[j + 2]; + + if (ptag != 0b111 ){//&& ReadAllPaceOnce == 0) { + + //ReadAllPaceOnce = 1; // This will prevent extra read of PACE, once group + // 0-5 is read ONCE. + readPace(ptag, paceResult); // BUG: result data from ECG is being overwritten by the PACE data + anyPaceDetected = true; + } + } + + if (anyPaceDetected) + dataAvailable(MAX30001_DATA_PACE, max30001_PACE, 18); // Send out the Pace data once only + + if (etag != 0b110) { + + dataAvailable(MAX30001_DATA_ECG, max30001_ECG_FIFO_buffer, (max30001_mngr_int.bit.e_fit + 1)); + } + + } /* End of ECG init */ + + /* RtoR */ + + if (max30001_status.bit.rrint == 1) { + if (max30001_reg_read(RTOR, &max30001_RtoR_data) == -1) { + return -1; + } + + max30001_RtoR_data = (0x00FFFFFF & max30001_RtoR_data) >> 10; + + hspValMax30001.R2R = (uint16_t)max30001_RtoR_data; + hspValMax30001.fmstr = (uint16_t)max30001_cnfg_gen.bit.fmstr; + + dataAvailable(MAX30001_DATA_RTOR, &max30001_RtoR_data, 1); + } + + // Handling BIOZ data... + + if (max30001_status.bit.bint == 1) { + adr = 0x22; + data_array[0] = ((adr << 1) & 0xff) | 1; + + /* [(BFIT+1)*3byte]+1extra byte due to the addr */ + + if (SPI_Transmit(&data_array[0], 1, &result[0],((max30001_mngr_int.bit.b_fit + 1) * 3) + 1) == -1) // Make a copy of the FIFO over here... + + { + return -1; + } + + btag = 0b00000111 & result[3]; + + /* Put the content of the FIFO based on the BFIT value, We ignore the + * result[0] and start concatenating indexes: 1,2,3 - 4,5,6 - 7,8,9 - */ + for (i = 0, j = 0; i < max30001_mngr_int.bit.b_fit + 1; i++, j = j + 3) // index1=23-16 bit, index2=15-8 bit, index3=7-0 bit + { + max30001_BIOZ_FIFO_buffer[i] = ((uint32_t)result[j + 1] << 16) + (result[j + 2] << 8) + result[j + 3]; + } + + if (btag != 0b110) { + dataAvailable(MAX30001_DATA_BIOZ, max30001_BIOZ_FIFO_buffer, 8); + } + } + + ret_val = 0; + + if (max30001_status.bit.dcloffint == 1) // ECG/BIOZ Lead Off + { + dcloffint_OneShot = 1; + max30001_DCLeadOff = 0; + max30001_DCLeadOff = max30001_DCLeadOff | (max30001_cnfg_gen.bit.en_dcloff << 8) | (max30001_status.all & 0x00000F); + dataAvailable(MAX30001_DATA_LEADOFF_DC, &max30001_DCLeadOff, 1); + + ret_val = 0b100; + + } else if (dcloffint_OneShot == 1 && max30001_status.bit.dcloffint == 0) // Just send once when it comes out of dc lead off + { + max30001_DCLeadOff = 0; + max30001_DCLeadOff = max30001_DCLeadOff | (max30001_cnfg_gen.bit.en_dcloff << 8) | (max30001_status.all & 0x00000F); + dataAvailable(MAX30001_DATA_LEADOFF_DC, &max30001_DCLeadOff, 1); + dcloffint_OneShot = 0; + } + + if (max30001_status.bit.bover == 1 || max30001_status.bit.bundr == 1) // BIOZ AC Lead Off + { + acloffint_OneShot = 1; + max30001_ACLeadOff = 0; + max30001_ACLeadOff = + max30001_ACLeadOff | ((max30001_status.all & 0x030000) >> 16); + dataAvailable(MAX30001_DATA_LEADOFF_AC, &max30001_ACLeadOff, 1); + + ret_val = 0b1000; + } else if (acloffint_OneShot == 1 && max30001_status.bit.bover == 0 && max30001_status.bit.bundr == 0) // Just send once when it comes out of ac lead off + { + max30001_ACLeadOff = 0; + max30001_ACLeadOff = max30001_ACLeadOff | ((max30001_status.all & 0x030000) >> 16); + dataAvailable(MAX30001_DATA_LEADOFF_AC, &max30001_ACLeadOff, 1); + acloffint_OneShot = 0; + } + + if (max30001_status.bit.bcgmon == 1) // BIOZ BCGMON check + { + bcgmon_OneShot = 1; + max30001_bcgmon = 0; + max30001_bcgmon = max30001_bcgmon | ((max30001_status.all & 0x000030) >> 4); + dataAvailable(MAX30001_DATA_BCGMON, &max30001_bcgmon, 1); + + ret_val = 0b10000; + } else if (bcgmon_OneShot == 1 && max30001_status.bit.bcgmon == 0) { + max30001_bcgmon = 0; + max30001_bcgmon = max30001_bcgmon | ((max30001_status.all & 0x000030) >> 4); + bcgmon_OneShot = 0; + dataAvailable(MAX30001_DATA_BCGMON, &max30001_bcgmon, 1); + } + +#if 0 +if(max30001_status.bit.lonint == 1) // AC LeadON Check +{ + max30001_LeadOn = 0; + max30001_reg_read(STATUS,&max30001_status.all); // Reading is important + max30001_LeadOn = max30001_LeadOn | (max30001_cnfg_gen.bit.en_ulp_lon << 8) | ((max30001_status.all & 0x000800) >> 11); // 0b01 will mean ECG Lead On, 0b10 will mean BIOZ Lead On + // LEAD ON has been detected... Now take actions +} +#endif + + if (max30001_status.bit.lonint == 1 && + acleadon_OneShot == 0) // AC LeadON Check, when lead is on + { + max30001_LeadOn = 0; + max30001_reg_read(STATUS, &max30001_status.all); // Reading is important + max30001_LeadOn = + max30001_LeadOn | (max30001_cnfg_gen.bit.en_ulp_lon << 8) | + ((max30001_status.all & 0x000800) >> + 11); // 0b01 will mean ECG Lead On, 0b10 will mean BIOZ Lead On + + // LEAD ON has been detected... Now take actions + acleadon_OneShot = 1; + dataAvailable(MAX30001_DATA_ACLEADON, &max30001_LeadOn, 1); // One shot data will be sent... + } else if (max30001_status.bit.lonint == 0 && acleadon_OneShot == 1) { + max30001_LeadOn = 0; + max30001_reg_read(STATUS, &max30001_status.all); + max30001_LeadOn = + max30001_LeadOn | (max30001_cnfg_gen.bit.en_ulp_lon << 8) | ((max30001_status.all & 0x000800) >> 11); // 0b01 will mean ECG Lead On, 0b10 will mean BIOZ Lead On + dataAvailable(MAX30001_DATA_ACLEADON, &max30001_LeadOn, 1); // One shot data will be sent... + acleadon_OneShot = 0; + } + + return ret_val; +} + +//****************************************************************************** +uint32_t MAX30001::readPace(int group, uint8_t* result) { + uint8_t data_array[4]; + uint32_t success; + int adr = PACE0_FIFO_BURST + group*4; + + if (group >= 6) + return (uint32_t)-1; + + data_array[0] = ((adr << 1) & 0xff) | 1; // For Read Or with 1 + success = SPI_Transmit(&data_array[0], 1, &result[0], 10); + + max30001_PACE[group * 3 + 0] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; + max30001_PACE[group * 3 + 1] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; + max30001_PACE[group * 3 + 2] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; + + return success; +} + +//****************************************************************************** + +//****************************************************************************** + +int MAX30001::max30001_int_handler(void) { + + static uint32_t InitReset = 0; + + int8_t return_value; + bool check_one_more = true; + + status_check: + max30001_reg_read(STATUS, &max30001_status.all); + + // Inital Reset and any FIFO over flow invokes a FIFO reset + if (InitReset == 0 || max30001_status.bit.eovf == 1 || max30001_status.bit.bovf == 1) { + // Do a FIFO Reset + max30001_reg_write(FIFO_RST, 0x000000); + + InitReset++; + return 2; + } + + return_value = 0; + + // The four data handling goes on over here + if (max30001_status.bit.eint == 1 || max30001_status.bit.pint == 1 || max30001_status.bit.bint == 1 || max30001_status.bit.rrint == 1 + || max30001_status.bit.dcloffint == 1 || max30001_status.bit.bover == 1 || max30001_status.bit.bundr == 1 + || max30001_status.bit.bcgmon == 1 || max30001_status.bit.lonint == 1) { + return_value = return_value | max30001_FIFO_LeadONOff_Read(); + } +/* + // ECG/BIOZ DC Lead Off test + if (max30001_status.bit.dcloffint == 1) { + return_value = return_value | max30001_FIFO_LeadONOff_Read(); + } + + // BIOZ AC Lead Off test + if (max30001_status.bit.bover == 1 || max30001_status.bit.bundr == 1) { + return_value = return_value | max30001_FIFO_LeadONOff_Read(); + } + + // BIOZ DRVP/N test using BCGMON. + if (max30001_status.bit.bcgmon == 1) { + return_value = return_value | max30001_FIFO_LeadONOff_Read(); + } + + if (max30001_status.bit.lonint == 1) // ECG Lead ON test: i.e. the leads are touching the body... + { + + max30001_FIFO_LeadONOff_Read(); + } +*/ + if (check_one_more) { + check_one_more = false; + goto status_check; + } + return return_value; +} + +/// function pointer to the async callback +static event_callback_t functionpointer; +/// flag used to indicate an async xfer has taken place +static volatile int xferFlag = 0; + +/** +* @brief Callback handler for SPI async events +* @param events description of event that occurred +*/ + + +static void spiHandler(int events) { xferFlag = 1; } + +/** +* @brief Transmit and recieve QUAD SPI data +* @param tx_buf pointer to transmit byte buffer +* @param tx_size number of bytes to transmit +* @param rx_buf pointer to the recieve buffer +* @param rx_size number of bytes to recieve +*/ +int MAX30001::SPI_Transmit(const uint8_t *tx_buf, uint32_t tx_size, uint8_t *rx_buf, uint32_t rx_size) +{ + m_cs->write(0); + for(int i = 0; i < tx_size; i++) + { + m_spi->write(tx_buf[i]); + } + for(int i = 0; i < (rx_size - tx_size); i++) + { + rx_buf[i + 1] = m_spi->write(0xFF); + } + m_cs->write(1); + + return 0; +} + +//****************************************************************************** +void MAX30001::max30001_ReadHeartrateData(max30001_t *_hspValMax30001) { + _hspValMax30001->R2R = hspValMax30001.R2R; + _hspValMax30001->fmstr = hspValMax30001.fmstr; +} + +//****************************************************************************** +void MAX30001::onDataAvailable(PtrFunction _onDataAvailable) { + onDataAvailableCallback = _onDataAvailable; +} + +/** +* @brief Used to notify an external function that interrupt data is available +* @param id type of data available +* @param buffer 32-bit buffer that points to the data +* @param length length of 32-bit elements available +*/ +void MAX30001::dataAvailable(uint32_t id, uint32_t *buffer, uint32_t length) { + if (onDataAvailableCallback != NULL) { + (*onDataAvailableCallback)(id, buffer, length); + } +} + +/** +* @brief Callback handler for SPI async events +* @param events description of event that occurred +*/ +void MAX30001::spiHandler(int events) { xferFlag = 1; } + +//****************************************************************************** +static int allowInterrupts = 0; + +void MAX30001Mid_IntB_Handler(void) { + if (allowInterrupts == 0) return; + MAX30001::instance->max30001_int_handler(); +} + +void MAX30001Mid_Int2B_Handler(void) { + if (allowInterrupts == 0) return; + MAX30001::instance->max30001_int_handler(); +} + +void MAX30001_AllowInterrupts(int state) { +allowInterrupts = state; +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/MAX30001/MAX30001/MAX30001.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/MAX30001/MAX30001/MAX30001.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,1083 @@ +/******************************************************************************* +* Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +*******************************************************************************/ +/* + * max30001.h + * + * Created on: Oct 9, 2015 + * Author: faisal.tariq + */ + +#ifndef MAX30001_H_ +#define MAX30001_H_ + +#include "mbed.h" + +#define mbed_COMPLIANT // Uncomment to Use timer for MAX30001 FCLK (for mbed) + // Comment to use the RTC clock + +#define ASYNC_SPI_BUFFER_SIZE (32 * 3) // Maximimum buffer size for async byte transfers + +// Defines for data callbacks +#define MAX30001_DATA_ECG 0x30 +#define MAX30001_DATA_PACE 0x31 +#define MAX30001_DATA_RTOR 0x32 +#define MAX30001_DATA_BIOZ 0x33 +#define MAX30001_DATA_LEADOFF_DC 0x34 +#define MAX30001_DATA_LEADOFF_AC 0x35 +#define MAX30001_DATA_BCGMON 0x36 +#define MAX30001_DATA_ACLEADON 0x37 + +#define MAX30001_SPI_MASTER_PORT 0 +#define MAX30001_SPI_SS_INDEX 0 + +#define MAX30001_INT_PORT_B 3 +#define MAX30001_INT_PIN_B 6 + +#define MAX30001_INT_PORT_2B 4 +#define MAX30001_INT_PIN_2B 5 + +#define MAX30001_INT_PORT_FCLK 1 +#define MAX30001_INT_PIN_FCLK 7 + +#define MAX30001_FUNC_SEL_TMR 2 // 0=FW Control, 1= Pulse Train, 2=Timer + +#define MAX30001_INDEX 3 +#define MAX30001_POLARITY 0 +#define MAX30001_PERIOD 30518 +#define MAX30001_CYCLE 50 + +#define MAX30001_IOMUX_IO_ENABLE 1 + +#define MAX30001_SPI_PORT 0 +#define MAX30001_CS_PIN 0 +#define MAX30001_CS_POLARITY 0 +#define MAX30001_CS_ACTIVITY_DELAY 0 +#define MAX30001_CS_INACTIVITY_DELAY 0 +#define MAX30001_CLK_HI 1 +#define MAX30001_CLK_LOW 1 +#define MAX30001_ALT_CLK 0 +#define MAX30001_CLK_POLARITY 0 +#define MAX30001_CLK_PHASE 0 +#define MAX30001_WRITE 1 +#define MAX30001_READ 0 + +#define MAX30001_INT_PORT_B 3 +#define MAX30001INT_PIN_B 6 + +void MAX30001_AllowInterrupts(int state); + +/** +* Maxim Integrated MAX30001 ECG/BIOZ chip +*/ +class MAX30001 { + +public: + typedef enum { // MAX30001 Register addresses + STATUS = 0x01, + EN_INT = 0x02, + EN_INT2 = 0x03, + MNGR_INT = 0x04, + MNGR_DYN = 0x05, + SW_RST = 0x08, + SYNCH = 0x09, + FIFO_RST = 0x0A, + INFO = 0x0F, + CNFG_GEN = 0x10, + CNFG_CAL = 0x12, + CNFG_EMUX = 0x14, + CNFG_ECG = 0x15, + CNFG_BMUX = 0x17, + CNFG_BIOZ = 0x18, + CNFG_PACE = 0x1A, + CNFG_RTOR1 = 0x1D, + CNFG_RTOR2 = 0x1E, + + // Data locations + ECG_FIFO_BURST = 0x20, + ECG_FIFO = 0x21, + FIFO_BURST = 0x22, + BIOZ_FIFO = 0x23, + RTOR = 0x25, + + PACE0_FIFO_BURST = 0x30, + PACE0_A = 0x31, + PACE0_B = 0x32, + PACE0_C = 0x33, + + PACE1_FIFO_BURST = 0x34, + PACE1_A = 0x35, + PACE1_B = 0x36, + PACE1_C = 0x37, + + PACE2_FIFO_BURST = 0x38, + PACE2_A = 0x39, + PACE2_B = 0x3A, + PACE2_C = 0x3B, + + PACE3_FIFO_BURST = 0x3C, + PACE3_A = 0x3D, + PACE3_B = 0x3E, + PACE3_C = 0x3F, + + PACE4_FIFO_BURST = 0x40, + PACE4_A = 0x41, + PACE4_B = 0x42, + PACE4_C = 0x43, + + PACE5_FIFO_BURST = 0x44, + PACE5_A = 0x45, + PACE5_B = 0x46, + PACE5_C = 0x47, + + } MAX30001_REG_map_t; + + /** + * @brief STATUS (0x01) + */ + union max30001_status_reg { + uint32_t all; + + struct { + uint32_t loff_nl : 1; + uint32_t loff_nh : 1; + uint32_t loff_pl : 1; + uint32_t loff_ph : 1; + + uint32_t bcgmn : 1; + uint32_t bcgmp : 1; + uint32_t reserved1 : 1; + uint32_t reserved2 : 1; + + uint32_t pllint : 1; + uint32_t samp : 1; + uint32_t rrint : 1; + uint32_t lonint : 1; + + uint32_t pedge : 1; + uint32_t povf : 1; + uint32_t pint : 1; + uint32_t bcgmon : 1; + + uint32_t bundr : 1; + uint32_t bover : 1; + uint32_t bovf : 1; + uint32_t bint : 1; + + uint32_t dcloffint : 1; + uint32_t fstint : 1; + uint32_t eovf : 1; + uint32_t eint : 1; + + uint32_t reserved : 8; + + } bit; + + } max30001_status; + + + /** + * @brief EN_INT (0x02) + */ + + union max30001_en_int_reg { + uint32_t all; + + struct { + uint32_t intb_type : 2; + uint32_t reserved1 : 1; + uint32_t reserved2 : 1; + + uint32_t reserved3 : 1; + uint32_t reserved4 : 1; + uint32_t reserved5 : 1; + uint32_t reserved6 : 1; + + uint32_t en_pllint : 1; + uint32_t en_samp : 1; + uint32_t en_rrint : 1; + uint32_t en_lonint : 1; + + uint32_t en_pedge : 1; + uint32_t en_povf : 1; + uint32_t en_pint : 1; + uint32_t en_bcgmon : 1; + + uint32_t en_bundr : 1; + uint32_t en_bover : 1; + uint32_t en_bovf : 1; + uint32_t en_bint : 1; + + uint32_t en_dcloffint : 1; + uint32_t en_fstint : 1; + uint32_t en_eovf : 1; + uint32_t en_eint : 1; + + uint32_t reserved : 8; + + } bit; + + } max30001_en_int; + + + /** + * @brief EN_INT2 (0x03) + */ + union max30001_en_int2_reg { + uint32_t all; + + struct { + uint32_t intb_type : 2; + uint32_t reserved1 : 1; + uint32_t reserved2 : 1; + + uint32_t reserved3 : 1; + uint32_t reserved4 : 1; + uint32_t reserved5 : 1; + uint32_t reserved6 : 1; + + uint32_t en_pllint : 1; + uint32_t en_samp : 1; + uint32_t en_rrint : 1; + uint32_t en_lonint : 1; + + uint32_t en_pedge : 1; + uint32_t en_povf : 1; + uint32_t en_pint : 1; + uint32_t en_bcgmon : 1; + + uint32_t en_bundr : 1; + uint32_t en_bover : 1; + uint32_t en_bovf : 1; + uint32_t en_bint : 1; + + uint32_t en_dcloffint : 1; + uint32_t en_fstint : 1; + uint32_t en_eovf : 1; + uint32_t en_eint : 1; + + uint32_t reserved : 8; + + } bit; + + } max30001_en_int2; + + /** + * @brief MNGR_INT (0x04) + */ + union max30001_mngr_int_reg { + uint32_t all; + + struct { + uint32_t samp_it : 2; + uint32_t clr_samp : 1; + uint32_t clr_pedge : 1; + uint32_t clr_rrint : 2; + uint32_t clr_fast : 1; + uint32_t reserved1 : 1; + uint32_t reserved2 : 4; + uint32_t reserved3 : 4; + + uint32_t b_fit : 3; + uint32_t e_fit : 5; + + uint32_t reserved : 8; + + } bit; + + } max30001_mngr_int; + + /** + * @brief MNGR_DYN (0x05) + */ + union max30001_mngr_dyn_reg { + uint32_t all; + + struct { + uint32_t bloff_lo_it : 8; + uint32_t bloff_hi_it : 8; + uint32_t fast_th : 6; + uint32_t fast : 2; + uint32_t reserved : 8; + } bit; + + } max30001_mngr_dyn; + + // 0x08 + // uint32_t max30001_sw_rst; + + // 0x09 + // uint32_t max30001_synch; + + // 0x0A + // uint32_t max30001_fifo_rst; + + + /** + * @brief INFO (0x0F) + */ + union max30001_info_reg { + uint32_t all; + struct { + uint32_t serial : 12; + uint32_t part_id : 2; + uint32_t sample : 1; + uint32_t reserved1 : 1; + uint32_t rev_id : 4; + uint32_t pattern : 4; + uint32_t reserved : 8; + } bit; + + } max30001_info; + + /** + * @brief CNFG_GEN (0x10) + */ + union max30001_cnfg_gen_reg { + uint32_t all; + struct { + uint32_t rbiasn : 1; + uint32_t rbiasp : 1; + uint32_t rbiasv : 2; + uint32_t en_rbias : 2; + uint32_t vth : 2; + uint32_t imag : 3; + uint32_t ipol : 1; + uint32_t en_dcloff : 2; + uint32_t en_bloff : 2; + uint32_t reserved1 : 1; + uint32_t en_pace : 1; + uint32_t en_bioz : 1; + uint32_t en_ecg : 1; + uint32_t fmstr : 2; + uint32_t en_ulp_lon : 2; + uint32_t reserved : 8; + } bit; + + } max30001_cnfg_gen; + + + /** + * @brief CNFG_CAL (0x12) + */ + union max30001_cnfg_cal_reg { + uint32_t all; + struct { + uint32_t thigh : 11; + uint32_t fifty : 1; + uint32_t fcal : 3; + uint32_t reserved1 : 5; + uint32_t vmag : 1; + uint32_t vmode : 1; + uint32_t en_vcal : 1; + uint32_t reserved2 : 1; + uint32_t reserved : 8; + } bit; + + } max30001_cnfg_cal; + + /** + * @brief CNFG_EMUX (0x14) + */ + union max30001_cnfg_emux_reg { + uint32_t all; + struct { + uint32_t reserved1 : 16; + uint32_t caln_sel : 2; + uint32_t calp_sel : 2; + uint32_t openn : 1; + uint32_t openp : 1; + uint32_t reserved2 : 1; + uint32_t pol : 1; + uint32_t reserved : 8; + } bit; + + } max30001_cnfg_emux; + + + /** + * @brief CNFG_ECG (0x15) + */ + union max30001_cnfg_ecg_reg { + uint32_t all; + struct { + uint32_t reserved1 : 12; + uint32_t dlpf : 2; + uint32_t dhpf : 1; + uint32_t reserved2 : 1; + uint32_t gain : 2; + uint32_t reserved3 : 4; + uint32_t rate : 2; + + uint32_t reserved : 8; + } bit; + + } max30001_cnfg_ecg; + + /** + * @brief CNFG_BMUX (0x17) + */ + union max30001_cnfg_bmux_reg { + uint32_t all; + struct { + uint32_t fbist : 2; + uint32_t reserved1 : 2; + uint32_t rmod : 3; + uint32_t reserved2 : 1; + uint32_t rnom : 3; + uint32_t en_bist : 1; + uint32_t cg_mode : 2; + uint32_t reserved3 : 2; + uint32_t caln_sel : 2; + uint32_t calp_sel : 2; + uint32_t openn : 1; + uint32_t openp : 1; + uint32_t reserved4 : 2; + uint32_t reserved : 8; + } bit; + + } max30001_cnfg_bmux; + + /** + * @brief CNFG_BIOZ (0x18) + */ + union max30001_bioz_reg { + uint32_t all; + struct { + uint32_t phoff : 4; + uint32_t cgmag : 3; + uint32_t cgmon : 1; + uint32_t fcgen : 4; + uint32_t dlpf : 2; + uint32_t dhpf : 2; + uint32_t gain : 2; + uint32_t inapow_mode : 1; + uint32_t ext_rbias : 1; + uint32_t ahpf : 3; + uint32_t rate : 1; + uint32_t reserved : 8; + } bit; + + } max30001_cnfg_bioz; + + + /** + * @brief CNFG_PACE (0x1A) + */ + union max30001_cnfg_pace_reg { + uint32_t all; + + struct { + uint32_t dacn : 4; + uint32_t dacp : 4; + uint32_t reserved1 : 4; + uint32_t aout : 2; + uint32_t aout_lbw : 1; + uint32_t reserved2 : 1; + uint32_t gain : 3; + uint32_t gn_diff_off : 1; + uint32_t reserved3 : 3; + uint32_t pol : 1; + uint32_t reserved : 8; + } bit; + + } max30001_cnfg_pace; + + /** + * @brief CNFG_RTOR1 (0x1D) + */ + union max30001_cnfg_rtor1_reg { + uint32_t all; + struct { + uint32_t reserved1 : 8; + uint32_t ptsf : 4; + uint32_t pavg : 2; + uint32_t reserved2 : 1; + uint32_t en_rtor : 1; + uint32_t gain : 4; + uint32_t wndw : 4; + uint32_t reserved : 8; + } bit; + + } max30001_cnfg_rtor1; + + /** + * @brief CNFG_RTOR2 (0x1E) + */ + union max30001_cnfg_rtor2_reg { + uint32_t all; + struct { + uint32_t reserved1 : 8; + uint32_t rhsf : 3; + uint32_t reserved2 : 1; + uint32_t ravg : 2; + uint32_t reserved3 : 2; + uint32_t hoff : 6; + uint32_t reserved4 : 2; + uint32_t reserved : 8; + } bit; + + } max30001_cnfg_rtor2; + + /*********************************************************************************/ + + typedef enum { + MAX30001_NO_INT = 0, // No interrupt + MAX30001_INT_B = 1, // INTB selected for interrupt + MAX30001_INT_2B = 2 // INT2B selected for interrupt + } max30001_intrpt_Location_t; + + typedef enum { + MAX30001_INT_DISABLED = 0b00, + MAX30001_INT_CMOS = 0b01, + MAX30001_INT_ODN = 0b10, + MAX30001_INT_ODNR = 0b11 + } max30001_intrpt_type_t; + + typedef enum { // Input Polarity selection + MAX30001_NON_INV = 0, // Non-Inverted + MAX30001_INV = 1 // Inverted + } max30001_emux_pol; + + typedef enum { // OPENP and OPENN setting + MAX30001_ECG_CON_AFE = 0, // ECGx is connected to AFE channel + MAX30001_ECG_ISO_AFE = 1 // ECGx is isolated from AFE channel + } max30001_emux_openx; + + typedef enum { // EMUX_CALP_SEL & EMUX_CALN_SEL + MAX30001_NO_CAL_SIG = 0b00, // No calibration signal is applied + MAX30001_INPT_VMID = 0b01, // Input is connected to VMID + MAX30001_INPT_VCALP = 0b10, // Input is connected to VCALP + MAX30001_INPT_VCALN = 0b11 // Input is connected to VCALN + } max30001_emux_calx_sel; + + typedef enum { // EN_ECG, EN_BIOZ, EN_PACE + MAX30001_CHANNEL_DISABLED = 0b0, // + MAX30001_CHANNEL_ENABLED = 0b1 + } max30001_en_feature; + + /*********************************************************************************/ + // Data + uint32_t max30001_ECG_FIFO_buffer[32]; // (303 for internal test) + uint32_t max30001_BIOZ_FIFO_buffer[8]; // (303 for internal test) + + uint32_t max30001_PACE[18]; // Pace Data 0-5 + + uint32_t max30001_RtoR_data; // This holds the RtoR data + + uint32_t max30001_DCLeadOff; // This holds the LeadOff data, Last 4 bits give + // the status, BIT3=LOFF_PH, BIT2=LOFF_PL, + // BIT1=LOFF_NH, BIT0=LOFF_NL + // 8th and 9th bits tell Lead off is due to ECG or BIOZ. + // 0b01 = ECG Lead Off and 0b10 = BIOZ Lead off + + uint32_t max30001_ACLeadOff; // This gives the state of the BIOZ AC Lead Off + // state. BIT 1 = BOVER, BIT 0 = BUNDR + + uint32_t max30001_bcgmon; // This holds the BCGMON data, BIT 1 = BCGMP, BIT0 = + // BCGMN + + uint32_t max30001_LeadOn; // This holds the LeadOn data, BIT1 = BIOZ Lead ON, + // BIT0 = ECG Lead ON, BIT8= Lead On Status Bit + + uint32_t max30001_timeout; // If the PLL does not respond, timeout and get out. + + typedef struct { // Creating a structure for BLE data + int16_t R2R; + int16_t fmstr; + } max30001_t; + + max30001_t hspValMax30001; // R2R, FMSTR + + //jjj 14MAR17 + //added DigitalOut so we can use any pin for cs + //jjj + MAX30001(SPI *spi, DigitalOut *cs); + + + /** + * @brief Constructor that accepts pin names for the SPI interface + * @param mosi master out slave in pin name + * @param miso master in slave out pin name + * @param sclk serial clock pin name + * @param cs chip select pin name + */ + MAX30001(PinName mosi, PinName miso, PinName sclk, PinName cs); + + /** + * MAX30001 destructor + */ + ~MAX30001(void); + + /** + * @brief This function sets up the Resistive Bias mode and also selects the master clock frequency. + * @brief Uses Register: CNFG_GEN-0x10 + * @param En_rbias: Enable and Select Resitive Lead Bias Mode + * @param Rbiasv: Resistive Bias Mode Value Selection + * @param Rbiasp: Enables Resistive Bias on Positive Input + * @param Rbiasn: Enables Resistive Bias on Negative Input + * @param Fmstr: Selects Master Clock Frequency + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_Rbias_FMSTR_Init(uint8_t En_rbias, uint8_t Rbiasv, + uint8_t Rbiasp, uint8_t Rbiasn, uint8_t Fmstr); + + /** + * @brief This function uses sets up the calibration signal internally. If it is desired to use the internal signal, then + * @brief this function must be called and the registers set, prior to setting the CALP_SEL and CALN_SEL in the ECG_InitStart + * @brief and BIOZ_InitStart functions. + * @brief Uses Register: CNFG_CAL-0x12 + * @param En_Vcal: Calibration Source (VCALP and VCALN) Enable + * @param Vmode: Calibration Source Mode Selection + * @param Vmag: Calibration Source Magnitude Selection (VMAG) + * @param Fcal: Calibration Source Frequency Selection (FCAL) + * @param Thigh: Calibration Source Time High Selection + * @param Fifty: Calibration Source Duty Cycle Mode Selection + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_CAL_InitStart(uint8_t En_Vcal, uint8_t Vmode, uint8_t Vmag, + uint8_t Fcal, uint16_t Thigh, uint8_t Fifty); + + /** + * @brief This function disables the VCAL signal + * @returns 0-if no error. A non-zero value indicates an error. + */ + int max30001_CAL_Stop(void); + + /** + * @brief This function handles the assignment of the two interrupt pins (INTB & INT2B) with various + * @brief functions/behaviors of the MAX30001. Also, each pin can be configured for different drive capability. + * @brief Uses Registers: EN_INT-0x02 and EN_INT2-0x03. + * @param max30001_intrpt_Locatio_t <argument>: All the arguments with the aforementioned enumeration essentially + * can be configured to generate an interrupt on either INTB or INT2B or NONE. + * @param max30001_intrpt_type_t intb_Type: INTB Port Type (EN_INT Selections). + * @param max30001_intrpt_type _t int2b_Type: INT2B Port Type (EN_INT2 Selections) + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_INT_assignment(max30001_intrpt_Location_t en_enint_loc, max30001_intrpt_Location_t en_eovf_loc, max30001_intrpt_Location_t en_fstint_loc, + max30001_intrpt_Location_t en_dcloffint_loc, max30001_intrpt_Location_t en_bint_loc, max30001_intrpt_Location_t en_bovf_loc, + max30001_intrpt_Location_t en_bover_loc, max30001_intrpt_Location_t en_bundr_loc, max30001_intrpt_Location_t en_bcgmon_loc, + max30001_intrpt_Location_t en_pint_loc, max30001_intrpt_Location_t en_povf_loc, max30001_intrpt_Location_t en_pedge_loc, + max30001_intrpt_Location_t en_lonint_loc, max30001_intrpt_Location_t en_rrint_loc, max30001_intrpt_Location_t en_samp_loc, + max30001_intrpt_type_t intb_Type, max30001_intrpt_type_t int2b_Type); + + + + /** + * @brief For MAX30001/3 ONLY + * @brief This function sets up the MAX30001 for the ECG measurements. + * @brief Registers used: CNFG_EMUX, CNFG_GEN, MNGR_INT, CNFG_ECG. + * @param En_ecg: ECG Channel Enable <CNFG_GEN register bits> + * @param Openp: Open the ECGN Input Switch (most often used for testing and calibration studies) <CNFG_EMUX register bits> + * @param Openn: Open the ECGN Input Switch (most often used for testing and calibration studies) <CNFG_EMUX register bits> + * @param Calp_sel: ECGP Calibration Selection <CNFG_EMUX register bits> + * @param Caln_sel: ECGN Calibration Selection <CNFG_EMUX register bits> + * @param E_fit: ECG FIFO Interrupt Threshold (issues EINT based on number of unread FIFO records) <CNFG_GEN register bits> + * @param Clr_rrint: RTOR R Detect Interrupt (RRINT) Clear Behavior <CNFG_GEN register bits> + * @param Rate: ECG Data Rate + * @param Gain: ECG Channel Gain Setting + * @param Dhpf: ECG Channel Digital High Pass Filter Cutoff Frequency + * @param Dlpf: ECG Channel Digital Low Pass Filter Cutoff Frequency + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_ECG_InitStart(uint8_t En_ecg, uint8_t Openp, uint8_t Openn, + uint8_t Pol, uint8_t Calp_sel, uint8_t Caln_sel, + uint8_t E_fit, uint8_t Rate, uint8_t Gain, + uint8_t Dhpf, uint8_t Dlpf); + + /** + * @brief For MAX30001/3 ONLY + * @brief This function enables the Fast mode feature of the ECG. + * @brief Registers used: MNGR_INT-0x04, MNGR_DYN-0x05 + * @param Clr_Fast: FAST MODE Interrupt Clear Behavior <MNGR_INT Register> + * @param Fast: ECG Channel Fast Recovery Mode Selection (ECG High Pass Filter Bypass) <MNGR_DYN Register> + * @param Fast_Th: Automatic Fast Recovery Threshold + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_ECGFast_Init(uint8_t Clr_Fast, uint8_t Fast, uint8_t Fast_Th); + + /** + * @brief For MAX30001/3 ONLY + * @brief This function disables the ECG. + * @brief Uses Register CNFG_GEN-0x10. + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_Stop_ECG(void); + + /** + * @brief For MAX30001 ONLY + * @brief This function sets up the MAX30001 for pace signal detection. + * @brief If both PACE and BIOZ are turned ON, then make sure Fcgen is set for 80K or 40K in the + * @brief max30001_BIOZ_InitStart() function. However, if Only PACE is on but BIOZ off, then Fcgen can be set + * @brief for 80K only, in the max30001_BIOZ_InitStart() function + * @brief Registers used: MNGR_INT-0x04, CNFG_GEN-0x37, CNFG_PACE-0x1A. + * @param En_pace : PACE Channel Enable <CNFG_GEN Register> + * @param Clr_pedge : PACE Edge Detect Interrupt (PEDGE) Clear Behavior <MNGR_INT Register> + * @param Pol: PACE Input Polarity Selection <CNFG_PACE Register> + * @param Gn_diff_off: PACE Differentiator Mode <CNFG_PACE Register> + * @param Gain: PACE Channel Gain Selection <CNFG_PACE Register> + * @param Aout_lbw: PACE Analog Output Buffer Bandwidth Mode <CNFG_PACE Register> + * @param Aout: PACE Single Ended Analog Output Buffer Signal Monitoring Selection <CNFG_PACE Register> + * @param Dacp (4bits): PACE Detector Positive Comparator Threshold <CNFG_PACE Register> + * @param Dacn(4bits): PACE Detector Negative Comparator Threshold <CNFG_PACE Register> + * @returns 0-if no error. A non-zero value indicates an error <CNFG_PACE Register> + * + */ + int max30001_PACE_InitStart(uint8_t En_pace, uint8_t Clr_pedge, uint8_t Pol, + uint8_t Gn_diff_off, uint8_t Gain, + uint8_t Aout_lbw, uint8_t Aout, uint8_t Dacp, + uint8_t Dacn); + + /** + *@brief For MAX30001 ONLY + *@param This function disables the PACE. Uses Register CNFG_GEN-0x10. + *@returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_Stop_PACE(void); + + /** + * @brief For MAX30001/2 ONLY + * @brief This function sets up the MAX30001 for BIOZ measurement. + * @brief Registers used: MNGR_INT-0x04, CNFG_GEN-0X10, CNFG_BMUX-0x17,CNFG_BIOZ-0x18. + * @param En_bioz: BIOZ Channel Enable <CNFG_GEN Register> + * @param Openp: Open the BIP Input Switch <CNFG_BMUX Register> + * @param Openn: Open the BIN Input Switch <CNFG_BMUX Register> + * @param Calp_sel: BIP Calibration Selection <CNFG_BMUX Register> + * @param Caln_sel: BIN Calibration Selection <CNFG_BMUX Register> + * @param CG_mode: BIOZ Current Generator Mode Selection <CNFG_BMUX Register> + * @param B_fit: BIOZ FIFO Interrupt Threshold (issues BINT based on number of unread FIFO records) <MNGR_INT Register> + * @param Rate: BIOZ Data Rate <CNFG_BIOZ Register> + * @param Ahpf: BIOZ/PACE Channel Analog High Pass Filter Cutoff Frequency and Bypass <CNFG_BIOZ Register> + * @param Ext_rbias: External Resistor Bias Enable <CNFG_BIOZ Register> + * @param Gain: BIOZ Channel Gain Setting <CNFG_BIOZ Register> + * @param Dhpf: BIOZ Channel Digital High Pass Filter Cutoff Frequency <CNFG_BIOZ Register> + * @param Dlpf: BIOZ Channel Digital Low Pass Filter Cutoff Frequency <CNFG_BIOZ Register> + * @param Fcgen: BIOZ Current Generator Modulation Frequency <CNFG_BIOZ Register> + * @param Cgmon: BIOZ Current Generator Monitor <CNFG_BIOZ Register> + * @param Cgmag: BIOZ Current Generator Magnitude <CNFG_BIOZ Register> + * @param Phoff: BIOZ Current Generator Modulation Phase Offset <CNFG_BIOZ Register> + * @param Inapow_mode: BIOZ Channel Instrumentation Amplifier (INA) Power Mode <CNFG_BIOZ Register> + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_BIOZ_InitStart(uint8_t En_bioz, uint8_t Openp, uint8_t Openn, + uint8_t Calp_sel, uint8_t Caln_sel, + uint8_t CG_mode, + /* uint8_t En_bioz,*/ uint8_t B_fit, uint8_t Rate, + uint8_t Ahpf, uint8_t Ext_rbias, uint8_t Gain, + uint8_t Dhpf, uint8_t Dlpf, uint8_t Fcgen, + uint8_t Cgmon, uint8_t Cgmag, uint8_t Phoff, uint8_t Inapow_mode); + + /** + * @brief For MAX30001/2 ONLY + * @brief This function disables the BIOZ. Uses Register CNFG_GEN-0x10. + * @returns 0-if no error. A non-zero value indicates an error. + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_Stop_BIOZ(void); + + /** + * @brief For MAX30001/2 ONLY + * @brief BIOZ modulated Resistance Built-in-Self-Test, Registers used: CNFG_BMUX-0x17 + * @param En_bist: Enable Modulated Resistance Built-in-Self-test <CNFG_BMUX Register> + * @param Rnom: BIOZ RMOD BIST Nominal Resistance Selection <CNFG_BMUX Register> + * @param Rmod: BIOZ RMOD BIST Modulated Resistance Selection <CNFG_BMUX Register> + * @param Fbist: BIOZ RMOD BIST Frequency Selection <CNFG_BMUX Register> + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_BIOZ_InitBist(uint8_t En_bist, uint8_t Rnom, uint8_t Rmod, + uint8_t Fbist); + + /** + * @brief For MAX30001/3/4 ONLY + * @brief Sets up the device for RtoR measurement + * @param EN_rtor: ECG RTOR Detection Enable <RTOR1 Register> + * @param Wndw: R to R Window Averaging (Window Width = RTOR_WNDW[3:0]*8mS) <RTOR1 Register> + * @param Gain: R to R Gain (where Gain = 2^RTOR_GAIN[3:0], plus an auto-scale option) <RTOR1 Register> + * @param Pavg: R to R Peak Averaging Weight Factor <RTOR1 Register> + * @param Ptsf: R to R Peak Threshold Scaling Factor <RTOR1 Register> + * @param Hoff: R to R minimum Hold Off <RTOR2 Register> + * @param Ravg: R to R Interval Averaging Weight Factor <RTOR2 Register> + * @param Rhsf: R to R Interval Hold Off Scaling Factor <RTOR2 Register> + * @param Clr_rrint: RTOR Detect Interrupt Clear behaviour <MNGR_INT Register> + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_RtoR_InitStart(uint8_t En_rtor, uint8_t Wndw, uint8_t Gain, + uint8_t Pavg, uint8_t Ptsf, uint8_t Hoff, + uint8_t Ravg, uint8_t Rhsf, uint8_t Clr_rrint); + + /** + * @brief For MAX30001/3/4 ONLY + * @brief This function disables the RtoR. Uses Register CNFG_RTOR1-0x1D + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_Stop_RtoR(void); + + /** + * @brief This is a function that waits for the PLL to lock; once a lock is achieved it exits out. (For convenience only) + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_PLL_lock(void); + + /** + * @brief This function causes the MAX30001 to reset. Uses Register SW_RST-0x08 + * @return 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_sw_rst(void); + + /** + * @brief This function provides a SYNCH operation. Uses Register SYCNH-0x09. Please refer to the data sheet for + * @brief the details on how to use this. + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_synch(void); + + /** + * @brief This function performs a FIFO Reset. Uses Register FIFO_RST-0x0A. Please refer to the data sheet + * @brief for the details on how to use this. + * @returns 0-if no error. A non-zero value indicates an error. + */ + int max300001_fifo_rst(void); + + /** + * + * @brief This is a callback function which collects all the data from the ECG, BIOZ, PACE and RtoR. It also handles + * @brief Lead On/Off. This function is passed through the argument of max30001_COMMinit(). + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_int_handler(void); + + /** + * @brief This is function called from the max30001_int_handler() function and processes all the ECG, BIOZ, PACE + * @brief and the RtoR data and sticks them in appropriate arrays and variables each unsigned 32 bits. + * @param ECG data will be in the array (input): max30001_ECG_FIFO_buffer[] + * @param Pace data will be in the array (input): max30001_PACE[] + * @param RtoRdata will be in the variable (input): max30001_RtoR_data + * @param BIOZ data will be in the array (input): max30001_BIOZ_FIFO_buffer[] + * @param global max30001_ECG_FIFO_buffer[] + * @param global max30001_PACE[] + * @param global max30001_BIOZ_FIFO_buffer[] + * @param global max30001_RtoR_data + * @param global max30001_DCLeadOff + * @param global max30001_ACLeadOff + * @param global max30001_LeadON + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_FIFO_LeadONOff_Read(void); + + /** + * @brief This function allows writing to a register. + * @param addr: Address of the register to write to + * @param data: 24-bit data read from the register. + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_reg_write(MAX30001_REG_map_t addr, uint32_t data); + + /** + * @brief This function allows reading from a register + * @param addr: Address of the register to read from. + * @param *return_data: pointer to the value read from the register. + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + //int max30001_reg_read(MAX30001_REG_map_t addr, uint32_t *return_data); +int max30001_reg_read(uint8_t addr, uint32_t *return_data); + /** + * @brief This function enables the DC Lead Off detection. Either ECG or BIOZ can be detected, one at a time. + * @brief Registers Used: CNFG_GEN-0x10 + * @param En_dcloff: BIOZ Digital Lead Off Detection Enable + * @param Ipol: DC Lead Off Current Polarity (if current sources are enabled/connected) + * @param Imag: DC Lead off current Magnitude Selection + * @param Vth: DC Lead Off Voltage Threshold Selection + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_Enable_DcLeadOFF_Init(int8_t En_dcloff, int8_t Ipol, int8_t Imag, + int8_t Vth); + + /** + * @brief This function disables the DC Lead OFF feature, whichever is active. + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_Disable_DcLeadOFF(void); + + /** + * @brief This function sets up the BIOZ for AC Lead Off test. + * @brief Registers Used: CNFG_GEN-0x10, MNGR_DYN-0x05 + * @param En_bloff: BIOZ Digital Lead Off Detection Enable <CNFG_GEN register> + * @param Bloff_hi_it: DC Lead Off Current Polarity (if current sources are enabled/connected) <MNGR_DYN register> + * @param Bloff_lo_it: DC Lead off current Magnitude Selection <MNGR_DYN register> + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_BIOZ_Enable_ACLeadOFF_Init(uint8_t En_bloff, uint8_t Bloff_hi_it, + uint8_t Bloff_lo_it); + + /** + * @brief This function Turns of the BIOZ AC Lead OFF feature + * @brief Registers Used: CNFG_GEN-0x10 + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_BIOZ_Disable_ACleadOFF(void); + + /** + * @brief This function enables the Current Gnerator Monitor + * @brief Registers Used: CNFG_BIOZ-0x18 + * @returns 0-if no error. A non-zero value indicates an error. + * + */ + int max30001_BIOZ_Enable_BCGMON(void); + + /** + * + * @brief This function enables the Lead ON detection. Either ECG or BIOZ can be detected, one at a time. + * @brief Also, the en_bioz, en_ecg, en_pace setting is saved so that when this feature is disabled through the + * @brief max30001_Disable_LeadON() function (or otherwise) the enable/disable state of those features can be retrieved. + * @param Channel: ECG or BIOZ detection + * @returns 0-if everything is good. A non-zero value indicates an error. + * + */ + int max30001_Enable_LeadON(int8_t Channel); + + /** + * @brief This function turns off the Lead ON feature, whichever one is active. Also, retrieves the en_bioz, + * @brief en_ecg, en_pace and sets it back to as it was. + * @param 0-if everything is good. A non-zero value indicates an error. + * + */ + int max30001_Disable_LeadON(void); + + /** + * + * @brief This function is toggled every 2 seconds to switch between ECG Lead ON and BIOZ Lead ON detect + * @brief Adjust LEADOFF_SERVICE_TIME to determine the duration between the toggles. + * @param CurrentTime - This gets fed the time by RTC_GetValue function + * + */ + void max30001_ServiceLeadON(uint32_t currentTime); + + /** + * + * @brief This function is toggled every 2 seconds to switch between ECG DC Lead Off and BIOZ DC Lead Off + * @brief Adjust LEADOFF_SERVICE_TIME to determine the duration between the toggles. + * @param CurrentTime - This gets fed the time by RTC_GetValue function + * + */ + void max30001_ServiceLeadoff(uint32_t currentTime); + + /** + * + * @brief This function sets current RtoR values and fmstr values in a pointer structure + * @param hspValMax30001 - Pointer to a structure where to store the values + * + */ + void max30001_ReadHeartrateData(max30001_t *_hspValMax30001); + + /** + * @brief type definition for data interrupt + */ + typedef void (*PtrFunction)(uint32_t id, uint32_t *buffer, uint32_t length); + + /** + * @brief Used to connect a callback for when interrupt data is available + */ + void onDataAvailable(PtrFunction _onDataAvailable); + + static MAX30001 *instance; + +private: + void dataAvailable(uint32_t id, uint32_t *buffer, uint32_t length); + /// interrupt handler for async spi events + static void spiHandler(int events); + /// wrapper method to transmit and recieve SPI data + int SPI_Transmit(const uint8_t *tx_buf, uint32_t tx_size, uint8_t *rx_buf, + uint32_t rx_size); + uint32_t readPace(int group, uint8_t* result); + + //jjj 14MAR17 + //pointer to DigitalOut for cs + DigitalOut * m_cs; + //jjj + /// pointer to mbed SPI object + SPI *m_spi; + /// is this object the owner of the spi object + bool spi_owner; + /// buffer to use for async transfers + uint8_t buffer[ASYNC_SPI_BUFFER_SIZE]; + /// function pointer to the async callback + event_callback_t functionpointer; + /// callback function when interrupt data is available + PtrFunction onDataAvailableCallback; + +}; // End of MAX30001 Class + +/** + * @brief Preventive measure used to dismiss interrupts that fire too early during + * @brief initialization on INTB line + * + */ +void MAX30001Mid_IntB_Handler(void); + +/** + * @brief Preventive measure used to dismiss interrupts that fire too early during + * @brief initialization on INT2B line + * + */ +void MAX30001Mid_Int2B_Handler(void); + +/** + * @brief Allows Interrupts to be accepted as valid. + * @param state: 1-Allow interrupts, Any-Don't allow interrupts. + * + */ +void MAX30001_AllowInterrupts(int state); + +#endif /* MAX30001_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/MAX30001/MAX30001_RPC.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/MAX30001/MAX30001_RPC.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,473 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include <stdio.h> +#include "StringHelper.h" +#include "MAX30001.h" +#include "Streaming.h" +#include "StringInOut.h" +#include "MAX30001_helper.h" +#include "RpcFifo.h" +#include "RpcServer.h" +#include "Peripherals.h" +#include "DataLoggingService.h" + +int highDataRate = 0; + +uint32_t max30001_RegRead(MAX30001::MAX30001_REG_map_t addr) { + uint32_t data; + Peripherals::max30001()->max30001_reg_read(addr, &data); + return data; +} + +void max30001_RegWrite(MAX30001::MAX30001_REG_map_t addr, uint32_t data) { + Peripherals::max30001()->max30001_reg_write(addr, data); +} + +int MAX30001_WriteReg(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[2]; + uint32_t reply[1]; + uint32_t value; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + + max30001_RegWrite((MAX30001::MAX30001_REG_map_t)args[0], args[1]); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int MAX30001_ReadReg(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[1]; + uint32_t reply[1]; + uint32_t value; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + value = max30001_RegRead((MAX30001::MAX30001_REG_map_t)args[0]); + reply[0] = value; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int MAX30001_Rbias_FMSTR_Init(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[5]; + uint32_t reply[1]; + uint32_t value; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + + value = Peripherals::max30001()->max30001_Rbias_FMSTR_Init(args[0], // En_rbias + args[1], // Rbiasv + args[2], // Rbiasp + args[3], // Rbiasn + args[4]); // Fmstr + + reply[0] = value; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int MAX30001_CAL_InitStart(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[6]; + uint32_t reply[1]; + uint32_t value; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + + // Peripherals::serial()->printf("MAX30001_CAL_InitStart 0 "); + value = Peripherals::max30001()->max30001_CAL_InitStart(args[0], // En_Vcal + args[1], // Vmag + args[2], // Fcal + args[3], // Thigh + args[4], // Fifty + args[5]); // Vmode + + reply[0] = value; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int MAX30001_ECG_InitStart(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[11]; + uint32_t reply[1]; + uint32_t value; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + + // Peripherals::serial()->printf("MAX30001_ECG_InitStart 0 "); + value = Peripherals::max30001()->max30001_ECG_InitStart(args[0], // En_ecg + args[1], // Openp + args[2], // Openn + args[3], // Pol + args[4], // Calp_sel + args[5], // Caln_sel + args[6], // E_fit + args[7], // Rate + args[8], // Gain + args[9], // Dhpf + args[10]); // Dlpf + // Peripherals::serial()->printf("MAX30001_ECG_InitStart 1 "); + MAX30001_Helper_SetStreamingFlag(eStreaming_ECG, 1); + reply[0] = value; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int MAX30001_ECGFast_Init(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[3]; + uint32_t reply[1]; + uint32_t value; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + + value = Peripherals::max30001()->max30001_ECGFast_Init(args[0], // Clr_Fast + args[1], // Fast + args[2]); // Fast_Th + + reply[0] = value; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int MAX30001_PACE_InitStart(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[9]; + uint32_t reply[1]; + uint32_t value; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + + value = + Peripherals::max30001()->max30001_PACE_InitStart(args[0], // En_pace + args[1], // Clr_pedge + args[2], // Pol + args[3], // Gn_diff_off + args[4], // Gain + args[5], // Aout_lbw + args[6], // Aout + args[7], // Dacp + args[8]); // Dacn + + MAX30001_Helper_SetStreamingFlag(eStreaming_PACE, 1); + reply[0] = value; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int MAX30001_BIOZ_InitStart(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[18]; + uint32_t reply[1]; + uint32_t value; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + + value = Peripherals::max30001()->max30001_BIOZ_InitStart(args[0], // En_bioz + args[1], // Openp + args[2], // Openn + args[3], // Calp_sel + args[4], // Caln_sel + args[5], // CG_mode + args[6], // B_fit + args[7], // Rate + args[8], // Ahpf + args[9], // Ext_rbias + args[10], // Gain + args[11], // Dhpf + args[12], // Dlpf + args[13], // Fcgen + args[14], // Cgmon + args[15], // Cgmag + args[16], // Phoff + args[17]); //INAPow_mode + + MAX30001_Helper_SetStreamingFlag(eStreaming_BIOZ, 1); + reply[0] = value; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int MAX30001_RtoR_InitStart(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[9]; + uint32_t reply[1]; + uint32_t value; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + + value = Peripherals::max30001()->max30001_RtoR_InitStart(args[0], // En_rtor + args[1], // Wndw + args[2], // Gain + args[3], // Pavg + args[4], // Ptsf + args[5], // Hoff + args[6], // Ravg + args[7], // Rhsf + args[8]); // Clr_rrint + + MAX30001_Helper_SetStreamingFlag(eStreaming_RtoR, 1); + reply[0] = value; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int MAX30001_Stop_ECG(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + Peripherals::max30001()->max30001_Stop_ECG(); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} +int MAX30001_Stop_PACE(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + Peripherals::max30001()->max30001_Stop_PACE(); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} +int MAX30001_Stop_BIOZ(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + Peripherals::max30001()->max30001_Stop_BIOZ(); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} +int MAX30001_Stop_RtoR(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + Peripherals::max30001()->max30001_Stop_RtoR(); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} +int MAX30001_Stop_Cal(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + // max30001_Stop_Cal(); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +void max30001_ServiceStreaming() { + char ch; + uint32_t val; + //USBSerial *usbSerial = Peripherals::usbSerial(); + + fifo_clear(GetStreamOutFifo()); + + SetStreaming(TRUE); + clearOutReadFifo(); + while (IsStreaming() == TRUE) { + + if (fifo_empty(GetStreamOutFifo()) == 0) { + fifo_get32(GetStreamOutFifo(), &val); + + //usbSerial->printf("%02X ", val); + printf("%02X ", val); + } + // if (usbSerial->available()) { + // ch = usbSerial->_getc(); + if (1) { + ch = 1; + + MAX30001_Helper_Stop(); + SetStreaming(FALSE); + fifo_clear(GetUSBIncomingFifo()); // clear USB serial incoming fifo + fifo_clear(GetStreamOutFifo()); + } + + } +} + +int MAX30001_Start(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + uint32_t all; + fifo_clear(GetUSBIncomingFifo()); + Peripherals::max30001()->max30001_synch(); + // max30001_ServiceStreaming(); + highDataRate = 0; + Peripherals::max30001()->max30001_reg_read(MAX30001::STATUS, &all); + LoggingService_StartLoggingUsb(); + + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int MAX30001_Stop(char argStrs[32][32], char replyStrs[32][32]) { + /* uint32_t args[1]; + uint32_t reply[1]; + uint32_t value; + //ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + max30001_StopTest(); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs);*/ + return 0; +} + +int MAX30001_INT_assignment(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[17]; + uint32_t reply[1]; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + /* + printf("MAX30001_INT_assignment "); + printf("%d ",args[0]); + printf("%d ",args[1]); + printf("%d ",args[2]); + printf("%d ",args[3]); + printf("%d ",args[4]); + printf("%d ",args[5]); + printf("%d ",args[6]); + printf("%d ",args[7]); + printf("%d ",args[8]); + printf("%d ",args[9]); + printf("%d ",args[10]); + printf("%d ",args[11]); + printf("%d ",args[12]); + printf("%d ",args[13]); + printf("%d ",args[14]); + printf("%d ",args[15]); + printf("%d ",args[16]); + printf("\n"); + fflush(stdout); + */ + + Peripherals::max30001()->max30001_INT_assignment( + (MAX30001::max30001_intrpt_Location_t)args[0], + (MAX30001::max30001_intrpt_Location_t)args[1], + (MAX30001::max30001_intrpt_Location_t)args[2], + (MAX30001::max30001_intrpt_Location_t)args[3], + (MAX30001::max30001_intrpt_Location_t)args[4], + (MAX30001::max30001_intrpt_Location_t)args[5], + (MAX30001::max30001_intrpt_Location_t)args[6], + (MAX30001::max30001_intrpt_Location_t)args[7], + (MAX30001::max30001_intrpt_Location_t)args[8], + (MAX30001::max30001_intrpt_Location_t)args[9], + (MAX30001::max30001_intrpt_Location_t)args[10], + (MAX30001::max30001_intrpt_Location_t)args[11], + (MAX30001::max30001_intrpt_Location_t)args[12], + (MAX30001::max30001_intrpt_Location_t)args[13], + (MAX30001::max30001_intrpt_Location_t)args[14], + (MAX30001::max30001_intrpt_type_t)args[15], + (MAX30001::max30001_intrpt_type_t)args[16]); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int MAX30001_StartTest(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + // ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + + /*** Set FMSTR over here ****/ + + /*** Set and Start the VCAL input ***/ + /* NOTE VCAL must be set first if VCAL is to be used */ + Peripherals::max30001()->max30001_CAL_InitStart(0b1, 0b1, 0b1, 0b011, 0x7FF, 0b0); + + /**** ECG Initialization ****/ + Peripherals::max30001()->max30001_ECG_InitStart(0b1, 0b1, 0b1, 0b0, 0b10, 0b11, 31, 0b00, 0b00, 0b0, 0b01); + + /***** PACE Initialization ***/ + Peripherals::max30001()->max30001_PACE_InitStart(0b1, 0b0, 0b0, 0b1, 0b000, 0b0, 0b00, 0b0, 0b0); + + /**** BIOZ Initialization ****/ + Peripherals::max30001()->max30001_BIOZ_InitStart( + 0b1, 0b1, 0b1, 0b10, 0b11, 0b00, 7, 0b0, 0b111, 0b0, 0b10, 0b00, 0b00, 0b0001, 0b0, 0b111, 0b0000, 0b0000); + + /*** Set RtoR registers ***/ + Peripherals::max30001()->max30001_RtoR_InitStart( + 0b1, 0b0011, 0b1111, 0b00, 0b0011, 0b000001, 0b00, 0b000, 0b01); + + /*** Set Rbias & FMSTR over here ****/ + Peripherals::max30001()->max30001_Rbias_FMSTR_Init(0b01, 0b10, 0b1, 0b1, 0b00); + + /**** Interrupt Setting ****/ + + /*** Set ECG Lead ON/OFF ***/ + // max30001_ECG_LeadOnOff(); + + /*** Set BIOZ Lead ON/OFF ***/ + // max30001_BIOZ_LeadOnOff(); Does not work yet... + + /**** Do a Synch ****/ + Peripherals::max30001()->max30001_synch(); + + fifo_clear(GetUSBIncomingFifo()); + max30001_ServiceStreaming(); + + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} +/* +static void StopAll() { + if (startedEcg == 1) { + max30001_Stop_ECG(); + } + if (startedCal == 1) { + } + if (startedBioz == 1) { + max30001_Stop_BIOZ(); + } + if (startedPace == 1) { + max30001_Stop_PACE(); + } + if (startedRtor == 1) { + max30001_Stop_RtoR(); + } + startedEcg = 0; + startedBioz = 0; + startedCal = 0; + startedPace = 0; + startedRtor = 0; +} +*/ +/* +// switch to ECG DC Lead ON +max30001_Enable_LeadON(0b01); +// switch to BIOZ DC Lead ON +max30001_Enable_LeadON(0b10); +*/ +int MAX30001_Enable_ECG_LeadON(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + // switch to ECG DC Lead ON + Peripherals::max30001()->max30001_Enable_LeadON(0b01); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} +int MAX30001_Enable_BIOZ_LeadON(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + // switch to BIOZ DC Lead ON + Peripherals::max30001()->max30001_Enable_LeadON(0b10); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} +// uint32_t max30001_LeadOn; // This holds the LeadOn data, BIT1 = BIOZ Lead ON, BIT0 = ECG Lead ON +int MAX30001_Read_LeadON(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + // return the max30001_LeadOn var from the MAX30001 driver + reply[0] = Peripherals::max30001()->max30001_LeadOn; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/MAX30001/MAX30001_RPC.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/MAX30001/MAX30001_RPC.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef __MAX300001_RPC_H +#define __MAX300001_RPC_H + +int MAX30001_WriteReg(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_ReadReg(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_Start(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_Stop(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_Rbias_FMSTR_Init(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_CAL_InitStart(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_ECG_InitStart(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_ECGFast_Init(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_PACE_InitStart(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_BIOZ_InitStart(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_RtoR_InitStart(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_Stop_ECG(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_Stop_PACE(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_Stop_BIOZ(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_Stop_RtoR(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_Stop_Cal(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_Enable_ECG_LeadON(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_Enable_BIOZ_LeadON(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_Read_LeadON(char argStrs[32][32], char replyStrs[32][32]); + +int MAX30001_StartTest(char argStrs[32][32], char replyStrs[32][32]); +int MAX30001_INT_assignment(char argStrs[32][32], char replyStrs[32][32]); + +#endif /* __MAX300001_RPC_H */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/MAX30001/MAX30001_helper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/MAX30001/MAX30001_helper.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,126 @@ + +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "MAX30001_helper.h" +#include "MAX30001.h" +#include "StringInOut.h" +#include "Peripherals.h" + +static uint8_t flags[4]; + +int MAX30001_Helper_IsStreaming(eFlags flag) { + return flags[(uint32_t)flag]; +} + +void MAX30001_Helper_SetStreamingFlag(eFlags flag, uint8_t state) { + flags[(uint32_t)flag] = state; +} + +void MAX30001_Helper_Stop(void) { + if (flags[(uint32_t)eStreaming_ECG] == 1) { + Peripherals::max30001()->max30001_Stop_ECG(); + } + if (flags[(uint32_t)eStreaming_PACE] == 1) { + Peripherals::max30001()->max30001_Stop_PACE(); + } + if (flags[(uint32_t)eStreaming_BIOZ] == 1) { + Peripherals::max30001()->max30001_Stop_BIOZ(); + } + if (flags[(uint32_t)eStreaming_RtoR] == 1) { + Peripherals::max30001()->max30001_Stop_RtoR(); + } + MAX30001_Helper_ClearStreamingFlags(); +} + +int MAX30001_AnyStreamingSet(void) { + uint32_t i; + for (i = 0; i < 4; i++) { + if (flags[i] == 1) return 1; + } + return 0; +} + +void MAX30001_Helper_StartSync(void) { + if (MAX30001_AnyStreamingSet() == 1) { + Peripherals::max30001()->max30001_synch(); + } +} + +void MAX30001_Helper_ClearStreamingFlags(void) { + uint32_t i; + for (i = 0; i < 4; i++) { + flags[i] = 0; + } +} + +void MAX30001_Helper_Debug_ShowStreamFlags(void) { + putStr("\r\n"); + if (flags[(uint32_t)eStreaming_ECG] == 1) { + putStr("eStreaming_ECG, "); + } + if (flags[(uint32_t)eStreaming_PACE] == 1) { + putStr("eStreaming_PACE, "); + } + if (flags[(uint32_t)eStreaming_BIOZ] == 1) { + putStr("eStreaming_BIOZ, "); + } + if (flags[(uint32_t)eStreaming_RtoR] == 1) { + putStr("eStreaming_RtoR, "); + } + putStr("\r\n"); +} + +void MAX30001_Helper_SetupInterrupts() { + // We removed this baed on the assumption that user provides a INT_assignment command + /* + Peripherals::max30001()->max30001_INT_assignment(MAX30001::MAX30001_INT_B, MAX30001::MAX30001_NO_INT, MAX30001::MAX30001_NO_INT, // en_enint_loc, en_eovf_loc, en_fstint_loc, + MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_NO_INT, // en_dcloffint_loc, en_bint_loc, en_bovf_loc, + MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_NO_INT, // en_bover_loc, en_bundr_loc, en_bcgmon_loc, + MAX30001::MAX30001_INT_B, MAX30001::MAX30001_NO_INT, MAX30001::MAX30001_NO_INT, // en_pint_loc, en_povf_loc, en_pedge_loc, + MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_INT_B, MAX30001::MAX30001_NO_INT, // en_lonint_loc, en_rrint_loc, en_samp_loc, + MAX30001::MAX30001_INT_ODNR, MAX30001::MAX30001_INT_ODNR); // intb_Type, int2b_Type) + */ +} + + + +static uint8_t serialNumber[6]; +uint8_t *MAX30001_Helper_getVersion(void) { + // read the id + Peripherals::max30001()->max30001_reg_read(MAX30001::INFO, (uint32_t *)serialNumber); + // read id twice because it needs to be read twice + Peripherals::max30001()->max30001_reg_read(MAX30001::INFO, (uint32_t *)serialNumber); + return serialNumber; +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/MAX30001/MAX30001_helper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/MAX30001/MAX30001_helper.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef MAX30001_HELPER_H_ +#define MAX30001_HELPER_H_ + +#include "mbed.h" + +typedef enum eFlags { + eStreaming_ECG, + eStreaming_PACE, + eStreaming_BIOZ, + eStreaming_RtoR +} eFlags; + +int MAX30001_Helper_IsStreaming(eFlags flag); +void MAX30001_Helper_SetStreamingFlag(eFlags flag, uint8_t state); +void MAX30001_Helper_Stop(void); +void MAX30001_Helper_ClearStreamingFlags(void); +int MAX30001_AnyStreamingSet(void); +void MAX30001_Helper_Debug_ShowStreamFlags(void); +void MAX30001_Helper_StartSync(void); +void MAX30001_Helper_SetupInterrupts(void); +uint8_t *MAX30001_Helper_getVersion(void); + +#endif /* MAX30001_HELPER_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/PushButton/PushButton.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/PushButton/PushButton.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "PushButton.h" +#include "Peripherals.h" + +PushButton::PushButton(PinName pin) : interruptButton(pin) { + this->pin = pin; + + interruptButton.mode(PullUp); + debouncingState = false; + // Delay for initial pullup to take effect + wait(0.01f); + // Attach the address of the interrupt handler routine for pushbutton + interruptButton.fall(callback(this, &PushButton::pb_hit_interrupt_fall)); +} + +bool PushButton::GetButtonFallState(void) { + return buttonFallState; +} + +void PushButton::SetButtonFallState(bool state) { + buttonFallState = state; +} + +void PushButton::clearButtonFallState(void) { + buttonFallState = false; +} + +int PushButton::Read(void) { + return interruptButton.read(); +} + +void PushButton::pb_hit_interrupt_fall(void) { + /* switch debouncing */ + if (!debouncingState) + { + timeout.attach(callback(this, &PushButton::pb_debounce_timeout), debounceTime); + } +} + +void PushButton::pb_debounce_timeout(void) { + if (!interruptButton.read()) + { + if (Peripherals::pushButton() != NULL){ + Peripherals::pushButton()->SetButtonFallState(true); + } + } + debouncingState = false; +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/PushButton/PushButton.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/PushButton/PushButton.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _PUSHBUTTON_H +#define _PUSHBUTTON_H + +#include "mbed.h" + +class PushButton { +public: + /** + * @brief Constructor with a PinName + */ + PushButton(PinName pin); + /** + * @brief Get the pushed state of the button + */ + bool GetButtonFallState(void); + /** + * @brief Clear the pushed state of the button + */ + void clearButtonFallState(void); + /** + * @brief Read the button input + * @return Represented as 0 or 1 (int) + */ + int Read(void); + /** + * @brief Set the state + * @param state Set the button state to this value + */ + void SetButtonFallState(bool state); + +private: + InterruptIn interruptButton; + bool buttonFallState; + PinName pin; + Timeout timeout; + bool debouncingState; + const static float debounceTime = 0.02; + + void pb_hit_interrupt_fall(void); + void pb_debounce_timeout(void); +}; + +#endif /* _PUSHBUTTON_H */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/S25FS256/S25FS512.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/S25FS256/S25FS512.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,473 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +// +// Flash Non-Volatile Memory +// U27 S25FS512 +// Nimitz SPIM1 +// + +#include "mbed.h" +#include "S25FS512.h" +#include "QuadSpiInterface.h" + +#define IOMUX_IO_ENABLE 1 + +#define S25FS512_SPI_PORT 1 +#define S25FS512_CS_PIN 0 +#define S25FS512_CS_POLARITY 0 +#define S25FS512_CS_ACTIVITY_DELAY 0 +#define S25FS512_CS_INACTIVITY_DELAY 0 +#define S25FS512_CLK_HI 4 +#define S25FS512_CLK_LOW 4 +#define S25FS512_ALT_CLK 0 +#define S25FS512_CLK_POLARITY 0 +#define S25FS512_CLK_PHASE 0 +#define S25FS512_WRITE 1 +#define S25FS512_READ 0 + +#define INT_PORT_B 3 +#define INT_PIN_B 6 + +uint8_t flashBuffer[257 + 10]; + +//****************************************************************************** +S25FS512::S25FS512(QuadSpiInterface *_quadSpiInterface) { + this->quadSpiInterface = _quadSpiInterface; +} + +//****************************************************************************** +S25FS512::~S25FS512(void) { +} + +//****************************************************************************** +int S25FS512::init(void) { + setQuadMode(); + return 0; +} + +//****************************************************************************** +int S25FS512::wren4Wire(void) { + uint8_t cmdArray[8]; + // Send WREN + cmdArray[0] = 0x06; + wait_1mS(); + return reg_write_read_multiple_4Wire(cmdArray, 1, flashBuffer, 1); +} + +//****************************************************************************** +uint8_t S25FS512::wren(void) { + uint8_t cmdArray[8]; + // Send WREN + cmdArray[0] = 0x06; + wait_1mS(); + return reg_write_read_multiple_quad(cmdArray, 1, flashBuffer, 0); +} + +//****************************************************************************** +int8_t S25FS512::reg_write_read_multiple_quad_last(uint8_t *bufferOut, + uint8_t numberOut, + uint8_t *bufferIn, + uint8_t numberIn, + uint8_t last) { + int32_t success = 0; + + success = quadSpiInterface->SPI_Transmit( + bufferOut, numberOut, + bufferIn, numberIn, (int)last); + + if (success != 0) return -1; + return 0; +} + +//****************************************************************************** +int8_t S25FS512::reg_write_read_multiple_4Wire(uint8_t *bufferOut, + uint8_t numberOut, + uint8_t *bufferIn, + uint8_t numberIn) { + int32_t success = 0; + success = quadSpiInterface->SPI_Transmit4Wire(bufferOut, numberOut, bufferIn, + numberIn, (int)1); + + if (success != 0) return -1; + return 0; +} + +//****************************************************************************** +int8_t S25FS512::reg_write_read_multiple_quad(uint8_t *bufferOut, + uint8_t numberOut, + uint8_t *bufferIn, + uint8_t numberIn) { + int8_t ret; + ret = reg_write_read_multiple_quad_last(bufferOut, numberOut, bufferIn, + numberIn, 1); + return ret; +} + +//****************************************************************************** +void S25FS512::readID(uint8_t *id) { + uint8_t cmd = 0x9F; + reg_write_read_multiple_quad(&cmd, 1, id, 4); +} + +//****************************************************************************** +int8_t S25FS512::writeAnyRegister(uint32_t address, uint8_t data) { + uint8_t cmdArray[5]; + cmdArray[0] = 0x71; + cmdArray[1] = (address >> 16) & 0xFF; + cmdArray[2] = (address >> 8) & 0xFF; + cmdArray[3] = (address >> 0) & 0xFF; + cmdArray[4] = data; + return reg_write_read_multiple_quad(cmdArray, 5, flashBuffer, 0); +} + +int8_t S25FS512::writeAnyRegister4Wire(uint32_t address, uint8_t data) { + uint8_t cmdArray[5]; + cmdArray[0] = 0x71; + cmdArray[1] = (address >> 16) & 0xFF; + cmdArray[2] = (address >> 8) & 0xFF; + cmdArray[3] = (address >> 0) & 0xFF; + cmdArray[4] = data; + return reg_write_read_multiple_4Wire(cmdArray, 5, flashBuffer, 5); +} + +//****************************************************************************** +int8_t S25FS512::writeRegisters(void) { + uint8_t cmdArray[3]; + wait_1mS(); + cmdArray[0] = 0x01; + cmdArray[1] = 0x00; + cmdArray[2] = 0x02; // set Quad to 1 + reg_write_read_multiple_quad(cmdArray, 3, flashBuffer, 0); + return 0; +} + +//****************************************************************************** +int8_t S25FS512::readAnyRegister(uint32_t address, uint8_t *data, + uint32_t length) { + uint8_t cmdArray[4]; + cmdArray[0] = 0x65; + cmdArray[1] = (address >> 16) & 0xFF; + cmdArray[2] = (address >> 8) & 0xFF; + cmdArray[3] = (address >> 0) & 0xFF; + return reg_write_read_multiple_quad(cmdArray, 4, data, length); +} + +//****************************************************************************** +int8_t S25FS512::bulkErase(void) { + uint8_t cmdArray[1]; + cmdArray[0] = 0x60; + return reg_write_read_multiple_quad(cmdArray, 1, flashBuffer, 0); +} + +//****************************************************************************** +int8_t S25FS512::pageProgram(uint32_t address, uint8_t *buffer) { + uint32_t i; + uint8_t cmdArray[5 + 256]; + uint8_t *ptr; + + // for (i = 0; i < 256; i++) { + // dataArray[i] = i; + //} + cmdArray[0] = 0x02; // 0x71; + // cmdArray[1] = (address >> 24) & 0xFF; + cmdArray[1] = (address >> 16) & 0xFF; + cmdArray[2] = (address >> 8) & 0xFF; + cmdArray[3] = (address >> 0) & 0xFF; + for (i = 0; i < 256; i++) { + cmdArray[4 + i] = buffer[i]; + } + // reg_write_read_multiple_quad(cmdArray,256 + 4,flashBuffer,256 + 4); + + ptr = cmdArray; + reg_write_read_multiple_quad_last(ptr, 4 + 64, flashBuffer, 0, 0); + wait_1mS(); + ptr += (4 + 64); + reg_write_read_multiple_quad_last(ptr, 64, flashBuffer, 0, 0); + wait_1mS(); + ptr += 64; + reg_write_read_multiple_quad_last(ptr, 64, flashBuffer, 0, 0); + wait_1mS(); + ptr += 64; + reg_write_read_multiple_quad_last(ptr, 64, flashBuffer, 0, 1); + wait_1mS(); + return 0; +} + +//****************************************************************************** +int8_t S25FS512::quadIoRead_Pages(uint32_t address, uint8_t *buffer, + uint32_t numberOfPages) { + uint8_t cmdArray[5]; + uint8_t *ptr; + uint8_t last; + uint32_t i; + + cmdArray[0] = 0xEB; + cmdArray[1] = (address >> 16) & 0xFF; + cmdArray[2] = (address >> 8) & 0xFF; + cmdArray[3] = (address >> 0) & 0xFF; + ptr = buffer; + last = 0; + // only send the command + reg_write_read_multiple_quad_last(cmdArray, 4, ptr, 0, 0); + wait_1mS(); + reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 5, 0); + wait_1mS(); + for (i = 0; i < numberOfPages; i++) { + reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 64, 0); + wait_1mS(); + ptr += 64; + reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 64, 0); + wait_1mS(); + ptr += 64; + reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 64, 0); + wait_1mS(); + ptr += 64; + // check if this is the last page + if ((i + 1) == numberOfPages) { + last = 1; + } + reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 64, last); + wait_1mS(); + ptr += 64; + } + return 0; +} + +//****************************************************************************** +int8_t S25FS512::checkBusy(void) { + uint8_t cmdArray[5]; + cmdArray[0] = 0x05; + reg_write_read_multiple_quad(cmdArray, 1, flashBuffer, 2); + return flashBuffer[1] & 0x1; +} + +//****************************************************************************** +void S25FS512::waitTillNotBusy(void) { + while (checkBusy() == 1) { + } +} + +//****************************************************************************** +int8_t S25FS512::sectorErase(uint32_t address) { + uint8_t cmdArray[5]; + cmdArray[0] = 0xD8; + cmdArray[1] = (address >> 16) & 0xFF; + cmdArray[2] = (address >> 8) & 0xFF; + cmdArray[3] = (address >> 0) & 0xFF; + return reg_write_read_multiple_quad(cmdArray, 4, flashBuffer, 0); +} + +//****************************************************************************** +int8_t S25FS512::parameterSectorErase(uint32_t address) { + uint8_t cmdArray[5]; + cmdArray[0] = 0x20; + cmdArray[1] = (address >> 16) & 0xFF; + cmdArray[2] = (address >> 8) & 0xFF; + cmdArray[3] = (address >> 0) & 0xFF; + reg_write_read_multiple_quad(cmdArray, 4, flashBuffer, 0); + return 0; +} + +#define ONE_MS (32768 / 500) +#define ONEHUNDRED_US (32768 / 1000) +#define TEM_MS (32768 / 50) + +//****************************************************************************** +void S25FS512::wait_1mS(void) { + wait_ms(1); +} + +//****************************************************************************** +void S25FS512::wait_100uS(void) { +wait_us(100); +} + +//****************************************************************************** +void S25FS512::wait_10mS(void) { +wait_ms(10); +} + +//****************************************************************************** +int8_t S25FS512::readIdentification(uint8_t *dataArray, uint8_t length) { + // 4QIOR = 0x9F + uint8_t cmdArray[1]; + cmdArray[0] = 0x9F; // read ID command + return reg_write_read_multiple_quad(cmdArray, 1, dataArray, length); +} + +//****************************************************************************** +uint8_t S25FS512::reset(void) { + uint8_t cmdArray[8]; + wait_1mS(); + cmdArray[0] = 0x66; + reg_write_read_multiple_quad(cmdArray, 1, flashBuffer, 0); + wait_1mS(); + cmdArray[0] = 0x99; + reg_write_read_multiple_quad(cmdArray, 1, flashBuffer, 0); + return 0; +} + +//****************************************************************************** +uint8_t S25FS512::enableHWReset(void) { + uint8_t data[8]; + wait_1mS(); + // CR2V Configuration Register-2 Volatile + // bit 5 + readAnyRegister(0x00800003, data, 8); + writeAnyRegister(0x00800003, 0x64); + return 0; +} + +//****************************************************************************** +uint8_t S25FS512::detect(void) { + uint8_t array[8]; + uint8_t array2[8]; + + // Send WREN + wren(); + // Send WREN + wren(); + // delay + wait_1mS(); + // Send WREN + wren(); + // delay + wait_1mS(); + + // Send write any register cmd + writeAnyRegister(0x0003, 0x48); + // delay + wait_1mS(); + array[0] = 0x9F; // read ID command + reg_write_read_multiple_quad(array, 1, array2, 7); + return 0; +} + +//****************************************************************************** +int S25FS512::setQuadMode(void) { + wait_1mS(); + wren4Wire(); + wait_1mS(); + writeAnyRegister4Wire(0x800002, 0x02); // set Quad = 1 + wait_1mS(); + wren4Wire(); + wait_1mS(); + writeAnyRegister4Wire(0x800003, 0x48); // set 8 latency, set QPI 4-4-4 +} + +//****************************************************************************** +uint32_t S25FS512::isPageEmpty(uint8_t *ptr) { + int i; + for (i = 0; i < 256; i++) { + if (ptr[i] != 0xFF) + return 0; + } + return 1; +} + +//****************************************************************************** +int8_t S25FS512::parameterSectorErase_Helper(uint32_t address) { + waitTillNotBusy(); + wait_100uS(); + wren(); + wait_100uS(); + parameterSectorErase(address); + wait_100uS(); + waitTillNotBusy(); + wait_100uS(); + return 0; +} + +//****************************************************************************** +int8_t S25FS512::sectorErase_Helper(uint32_t address) { + waitTillNotBusy(); + wait_100uS(); + wren(); + wait_100uS(); + if (address < 0x8000) { + parameterSectorErase(address); + } else { + sectorErase(address); + } + wait_100uS(); + waitTillNotBusy(); + wait_100uS(); + return 0; +} + +//****************************************************************************** +int8_t S25FS512::bulkErase_Helper(void) { + waitTillNotBusy(); + wait_100uS(); + wren(); + wait_100uS(); + bulkErase(); + wait_100uS(); + waitTillNotBusy(); + wait_100uS(); + return 0; +} + +//****************************************************************************** +// write a page worth of data (256 bytes) from buffer, offset defined where in +// the buffer to begin write +int8_t S25FS512::writePage_Helper(uint32_t pageNumber, uint8_t *buffer, + uint32_t offset) { + uint8_t *ptr; + waitTillNotBusy(); + wait_1mS(); + wren(); + ptr = &buffer[offset]; + wait_1mS(); + pageProgram(pageNumber << 8, ptr); + wait_1mS(); + return 0; +} + +//****************************************************************************** +// read pages from flash into buffer, offset defined where in the buffer use +int8_t S25FS512::readPages_Helper(uint32_t startPageNumber, + uint32_t endPageNumber, uint8_t *buffer, + uint32_t offset) { + uint8_t *ptr; + uint32_t page; + ptr = &buffer[offset]; + for (page = startPageNumber; page <= endPageNumber; page++) { + wait_100uS(); + quadIoRead_Pages((uint32_t)(page << 8), (uint8_t *)ptr, 1); + ptr += 0x100; + } + return 0; +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/S25FS256/S25FS512.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/S25FS256/S25FS512.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef S25FS512_H_ +#define S25FS512_H_ + +#include "mbed.h" +#include "QuadSpiInterface.h" + +class S25FS512 { +public: + S25FS512(QuadSpiInterface *_quadSpiInterface); + ~S25FS512(void); + + QuadSpiInterface *quadSpiInterface; + + /** Initialize the driver + */ + int init(void); + + /** Detect the presence of the flash device + */ + uint8_t detect(void); + + /** Read the identification of the flash + */ + int8_t readIdentification(uint8_t *dataArray, uint8_t length); + + /** Bulk erase the flash device + */ + int8_t bulkErase_Helper(void); + + /** Erase Parameter Sectors + */ + int8_t parameterSectorErase_Helper(uint32_t address); + + /** Write a Page + */ + int8_t writePage_Helper(uint32_t pageNumber, uint8_t *buffer, + uint32_t offset); + + /** Read a Page + * @param + */ + int8_t readPages_Helper(uint32_t startPageNumber, uint32_t endPageNumber, + uint8_t *buffer, uint32_t offset); + + /** Erase a Sector + @param address Address of sector to erase + */ + + int8_t sectorErase_Helper(uint32_t address); + /** Scans through byte pointer for a page worth of data to see if the page is all FFs + @param ptr Byte pointer to buffer to scan + @return Returns a 1 if the page is empty, 0 if it is not all FFs + */ + uint32_t isPageEmpty(uint8_t *ptr); + + /** Issue a software reset to the flash device + */ + + uint8_t reset(void); + /** Enable a hardware reset + */ + + uint8_t enableHWReset(void); + /** Read the id byte of this device + */ + + void readID(uint8_t *id); + +private: + int8_t reg_write_read_multiple_quad_last(uint8_t *dataIn, uint8_t numberIn, uint8_t *dataOut, uint8_t numberOut, uint8_t last); + int8_t reg_write_read_multiple_quad(uint8_t *dataIn, uint8_t numberIn, uint8_t *dataOut, uint8_t numberOut); + int8_t reg_write_read_multiple_4Wire(uint8_t *bufferOut, uint8_t numberOut, uint8_t *bufferIn, uint8_t numberIn); + uint8_t spiWriteRead (uint8_t writeNumber,uint8_t *writeData, uint8_t readNumber, uint8_t *readData); + uint8_t spiWriteRead4Wire(uint8_t writeNumber,uint8_t *writeData, uint8_t readNumber, uint8_t *readData); + + int8_t writeAnyRegister(uint32_t address, uint8_t data); + int8_t writeAnyRegister4Wire(uint32_t address, uint8_t data); + int8_t writeRegisters(void); + uint8_t wren(void); + int setQuadMode(void); + int wren4Wire(void); + // int8_t setQuadMode(); + int8_t readAnyRegister(uint32_t address, uint8_t *data, uint32_t length); + int8_t bulkErase(void); + int8_t pageProgram(uint32_t address, uint8_t *buffer); + int8_t quadIoRead_Pages(uint32_t address, uint8_t *buffer, uint32_t numberOfPages); + int8_t checkBusy(void); + void waitTillNotBusy(void); + int8_t sectorErase(uint32_t address); + int8_t parameterSectorErase(uint32_t address); + void wait_1mS(void); + void wait_100uS(void); + void wait_10mS(void); +}; +#endif /* S25FS512_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/S25FS256/S25FS512_RPC.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/S25FS256/S25FS512_RPC.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "S25FS512_RPC.h" +#include "S25FS512.h" +#include "StringInOut.h" +#include "StringHelper.h" +#include "Peripherals.h" +#include "SDFileSystem.h" + +int S25FS512_Reset(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + Peripherals::s25FS512()->reset(); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int S25FS512_EnableHWReset(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + Peripherals::s25FS512()->enableHWReset(); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int S25FS512_SpiWriteRead(char argStrs[32][32], char replyStrs[32][32]) { + uint8_t args[16]; + uint8_t reply[16]; + uint8_t writeNumber; + uint8_t readNumber; + // get the number of bytes to write + ProcessArgs(argStrs, args, 1); + writeNumber = args[0]; + ProcessArgs(argStrs, args, writeNumber + 2); + readNumber = args[writeNumber + 1]; + FormatReply(reply, readNumber, replyStrs); + return 0; +} + +int S25FS512_SpiWriteRead4Wire(char argStrs[32][32], char replyStrs[32][32]) { + uint8_t args[16]; + uint8_t reply[16]; + uint8_t writeNumber; + uint8_t readNumber; + // get the number of bytes to write + ProcessArgs(argStrs, args, 1); + writeNumber = args[0]; + ProcessArgs(argStrs, args, writeNumber + 2); + readNumber = args[writeNumber + 1]; + FormatReply(reply, readNumber, replyStrs); + return 0; +} + +int S25FS512_ReadPage(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[2]; + uint32_t reply[1]; + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +//int S25FS512_ReadPagesBinary(char argStrs[32][32], char replyStrs[32][32]) { +// uint32_t args[2]; +// uint32_t reply[1]; +// uint8_t pageData[256]; +// +// uint32_t startPage; +// uint32_t endPage; +// uint32_t page; +// +// ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); +// startPage = args[0]; +// endPage = args[1]; +// for (page = startPage; page <= endPage; page++) { +// Peripherals::s25FS512()->readPages_Helper(page, page, pageData, 0); +// putBytes256Block(pageData, 1); +// } +// reply[0] = 0x80; +// FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); +// return 0; +//} +extern char dataFileName[32]; +int S25FS512_ReadPagesBinary(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t args[2]; + uint32_t reply[1]; + uint8_t pageData[256]; + + uint32_t startPage; + uint32_t endPage; + uint32_t page; + + ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t)); + startPage = args[0]; + endPage = args[1]; + FILE *fp = NULL; + fp = fopen(dataFileName, "rb"); + for (page = startPage-0x12; page <= endPage-0x12; page++) { + memset(pageData, 0xffffffff, sizeof(pageData)); + printf("reading from page %d\r\n", page); + if (fp != NULL) { + fseek(fp,page*256,SEEK_SET); + uint8_t count = 0; + while(!feof(fp)) + { + printf("."); + pageData[count++] = (unsigned char) fgetc(fp); + if (count == 0) break; + }; + } + printf("\r\nEND\r\n"); + putBytes256Block(pageData, 1); + } + if (fp != NULL) fclose(fp); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +int S25FS512_ReadId(char argStrs[32][32], char replyStrs[32][32]) { + char str[32]; + uint8_t data[128]; + Peripherals::s25FS512()->readIdentification(data, sizeof(data)); + Peripherals::s25FS512()->readIdentification(data, sizeof(data)); + sprintf(str, "%02X%02X%02X%02X", data[0], data[1], data[2], data[3]); + strcpy(replyStrs[0], str); + return 0; +} +int SDCard_IsReady(char argStrs[32][32], char replyStrs[32][32]) { + + DigitalIn *detect = Peripherals::SDDetect(); + + bool isReady = false; + + if(detect->read()) + { + isReady = false; + strcpy(replyStrs[0], "not_ok"); + return 0; + } + + Peripherals::sdFS()->disk_initialize(); + FILE *fp = fopen("/sd/test", "r"); + if ( fp != NULL) + isReady = true; + else + { + FILE *fp = fopen("/sd/test", "w"); + if ( fp != NULL) + isReady = true; + } + + if (fp != NULL) fclose(fp); + + if (isReady) + strcpy(replyStrs[0], "ok"); + else + strcpy(replyStrs[0], "not_ok"); + return 0; +}
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Devices/S25FS256/S25FS512_RPC.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Devices/S25FS256/S25FS512_RPC.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _S25FS512_RPC_H_ +#define _S25FS512_RPC_H_ + +#include "mbed.h" + +int S25FS512_ReadPagesBinary(char argStrs[32][32], char replyStrs[32][32]); +int S25FS512_ReadPage(char argStrs[32][32], char replyStrs[32][32]); +int S25FS512_ReadPagesBinary(char argStrs[32][32], char replyStrs[32][32]); +int S25FS512_ReadId(char argStrs[32][32], char replyStrs[32][32]); +int S25FS512_Reset(char argStrs[32][32], char replyStrs[32][32]); +int S25FS512_EnableHWReset(char argStrs[32][32], char replyStrs[32][32]); +int S25FS512_SpiWriteRead(char argStrs[32][32], char replyStrs[32][32]); +int S25FS512_SpiWriteRead4Wire(char argStrs[32][32], char replyStrs[32][32]); +int SDCard_IsReady(char argStrs[32][32], char replyStrs[32][32]); + +#endif /* _S25FS512_RPC_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Interfaces/QuadSpiInterface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Interfaces/QuadSpiInterface.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "QuadSpiInterface.h" + +/** +* @brief Constructor that accepts pin names for the QUAD SPI interface +* @param mosi master out slave in pin name +* @param miso master in slave out pin name +* @param sclk serial clock pin name +* @param cs chip select pin name +*/ +QuadSpiInterface::QuadSpiInterface(PinName mosi, PinName miso, PinName sclk, + PinName cs) + : spi(mosi, miso, sclk), csPin(cs) { + + } + +/** +* @brief Transmit and recieve QUAD SPI data +* @param tx_buf pointer to transmit byte buffer +* @param tx_size number of bytes to transmit +* @param rx_buf pointer to the recieve buffer +* @param rx_size number of bytes to recieve +* @param last flag to indicate if this is the last QUAD SPI transaction for the +* current chip select cycle +*/ +int QuadSpiInterface::SPI_Transmit(const uint8_t *tx_buf, uint32_t tx_size, + uint8_t *rx_buf, uint32_t rx_size, + int last) { + uint32_t i; + int result = 0; + int index = 0; + // lower chip select + csPin = 0; + // write bytes out QUAD SPI + spi.setQuadMode(); + for (i = 0; i < tx_size; i++) { + rx_buf[index] = spi.write((int)tx_buf[i]); + index++; + } + // read in bytes from QUAD SPI + for (i = 0; i < rx_size; i++) { + rx_buf[index] = (uint8_t)spi.read(); + index++; + } + // raise chip select if this is the last transaction + if (last) csPin = 1; + return result; +} + +/** +* @brief Transmit and recieve QUAD SPI data +* @param tx_buf pointer to transmit byte buffer +* @param tx_size number of bytes to transmit +* @param rx_buf pointer to the recieve buffer +* @param rx_size number of bytes to recieve +* @param last flag to indicate if this is the last QUAD SPI transaction for the +* current chip select cycle +*/ +int QuadSpiInterface::SPI_Transmit4Wire(const uint8_t *tx_buf, uint32_t tx_size, + uint8_t *rx_buf, uint32_t rx_size, + int last) { + uint32_t i; + int result = 0; + int index = 0; + // lower chip select + csPin = 0; + // write bytes out Single SPI + spi.setSingleMode(); + for (i = 0; i < tx_size; i++) { + rx_buf[index] = spi.write((int)tx_buf[i]); + index++; + } + // raise chip select if this is the last transaction + if (last) csPin = 1; + return result; +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Interfaces/QuadSpiInterface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Interfaces/QuadSpiInterface.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _QUADSPIINTERFACE_H_ +#define _QUADSPIINTERFACE_H_ + +#include "mbed.h" +#include "QuadSpi.h" + +class QuadSpiInterface { +public: + /** + * @brief Constructor that accepts pin names for the QUAD SPI interface + * @param mosi master out slave in pin name + * @param miso master in slave out pin name + * @param sclk serial clock pin name + * @param cs chip select pin name + */ + QuadSpiInterface(PinName mosi, PinName miso, PinName sclk, PinName cs); + /** + * @brief Transmit and recieve QUAD SPI data + * @param tx_buf pointer to transmit byte buffer + * @param tx_size number of bytes to transmit + * @param rx_buf pointer to the recieve buffer + * @param rx_size number of bytes to recieve + * @param last flag to indicate if this is the last QUAD SPI transaction for + * the current chip select cycle + */ + int SPI_Transmit(const uint8_t *tx_buf, uint32_t tx_size, uint8_t *rx_buf, + uint32_t rx_size, int last = 1); + + /** + * @brief Transmit and recieve Four Wrire SPI data + * @param tx_buf pointer to transmit byte buffer + * @param tx_size number of bytes to transmit + * @param rx_buf pointer to the recieve buffer + * @param rx_size number of bytes to recieve + * @param last flag to indicate if this is the last QUAD SPI transaction for + * the current chip select cycle + */ + int SPI_Transmit4Wire(const uint8_t *tx_buf, uint32_t tx_size, + uint8_t *rx_buf, uint32_t rx_size, int last = 1); + +private: + // QUAD SPI object + QuadSPI spi; + // chip select object + DigitalOut csPin; +}; + +#endif // _QUADSPIINTERFACE_H_ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/LoggingService/DataLoggingService.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/LoggingService/DataLoggingService.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,613 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "mbed.h" +#include "Logging.h" +#include "Streaming.h" +#include "RpcServer.h" +#include "S25FS512.h" +#include "PacketFifo.h" +#include "DataLoggingService.h" +#include "HspLed.h" +#include "MAX30001_helper.h" +#include "StringInOut.h" +#include "StringHelper.h" +#include "Peripherals.h" +#include "Device_Logging.h" + +/// BMP280 logging object reference +extern Device_Logging *bmp280_Logging; +/// MAX14720 instance 0 logging object reference +extern Device_Logging *MAX30205_0_Logging; +/// MAX14720 instance 1 logging object reference +extern Device_Logging *MAX30205_1_Logging; + +#define PING_PONG_BUFFER_SIZE 512 +#define HALF_OF_PING_PONG_BUFFER_SIZE PING_PONG_BUFFER_SIZE / 2 +#define MISSION_DEFINITION_SIZE 4096 +#define MISSION_FILE_NAME_LEN 32 + +eLoggingTrigger loggingTrigger; + +/// file on SDCard where mission strings are stored +char missionFileName[MISSION_FILE_NAME_LEN] = "/sd/missions.txt"; + +/// data file on SDCard where mission strings are stored +char dataFileName[MISSION_FILE_NAME_LEN] = "/sd/data.txt"; + +/// buffer where mission strings are stored +char loggingMissionCmds[MISSION_DEFINITION_SIZE]; +/// This houses two 256 byte ram concatenated to act as a ping-pong +uint8_t PingPong_SRAM[PING_PONG_BUFFER_SIZE]; +uint32_t buttonTrigger = 0; + +eLoggingOutput loggingOutput; +// extern int bleStartCommand; +bool volatile globalFlag; +extern int highDataRate; +static uint32_t currentPage; +static uint32_t sramIndex; +/// flag to indicate that sram buffer 0 is dirty and will need to be flushed +static uint32_t sram_buffer_0_dirty; +/// flag to indicate that sram buffer 1 is dirty and will need to be flushed +static uint32_t sram_buffer_1_dirty; +/// usb byte buffer for sending out a bulk transfer +static uint8_t usb_block[64]; +/// running index used to accumulate bytes to send as a block via bulk transfer +static uint16_t usb_block_index = 0; + +typedef enum { + eStartEvent_NULL, + eStartEvent_BLE, + eStartEvent_BUTTON, + eStartEvent_RPC_TO_USB, + eStartEvent_RPC_TO_FLASH +} eStartEvent; +static eStartEvent startEvent; + +/** +* @brief Sets a flag to start USB logging (streaming) +*/ +void LoggingService_StartLoggingUsb(void) { + loggingTrigger = eTriggerLog_RPC_USB; +} + +/** +* @brief Sets a flag to start flash logging +*/ +void LoggingService_StartLoggingFlash(void) { + loggingTrigger = eTriggerLog_RPC_FLASH; +} + +/** +* @brief Checks the various logging start condition +* @return 1 if a start condition is true, 0 if there is no start condition +*/ +static bool _LoggingService_CheckStartCondition(void) { + bool buttonPressed; + buttonPressed = Peripherals::pushButton()->GetButtonFallState(); + + // default not logging USB or flash + loggingOutput = eLogToNothing; + startEvent = eStartEvent_NULL; + if (buttonPressed) { + Peripherals::pushButton()->clearButtonFallState(); + // a falling state has been detected... wait for a fraction of a second and + // re-read the pin + // only start datalogging if the pin was released within this wait time + wait(0.75f); + int buttonRead = Peripherals::pushButton()->Read(); + // if after a period of time the button is still pressed then get out + if (buttonRead == 0) + return 0; + buttonTrigger = 0; + + loggingTrigger = eTriggerLog_BUTTON; + loggingOutput = eLogToFlash; + startEvent = eStartEvent_BUTTON; + return true; + } + if (loggingTrigger == eTriggerLog_RPC_FLASH) { + loggingOutput = eLogToFlash; + startEvent = eStartEvent_RPC_TO_FLASH; + return true; + } + /*if (Peripherals::hspBLE()->getStartDataLogging()) { + loggingTrigger = eTriggerLog_BLE; + loggingOutput = eLogToFlash; + startEvent = eStartEvent_BLE; + return true; + }*/ + // check if start is from RPC call for USB streaming + if (loggingTrigger == eTriggerLog_RPC_USB) { + loggingOutput = eLogtoUsb; + startEvent = eStartEvent_RPC_TO_USB; + return true; + } + return false; +} + +/** +* @brief Read the mission string from flash into a buffer +* @return false if a mission was not defined, true if mission was read and +* buffered +*/ +static bool _LoggingService_ReadMissionFromFlash(void) { + // get mission from flash + Logging_ReadMissionFromFlash((uint8_t *)loggingMissionCmds); + if (Logging_IsMissionDefined((uint8_t *)loggingMissionCmds) == 0) { + return false; + } + printf(loggingMissionCmds); + fflush(stdout); + RPC_ProcessCmds(loggingMissionCmds); + return true; +} + +/** +* @brief Read the mission string from SDCARD into a buffer +* @return false if a mission was not defined, true if mission was read and +* buffered +*/ +static bool _LoggingService_ReadMissionFromSDCard(void) { + // get mission from flash + Logging_ReadMissionFromSDCard((uint8_t *)loggingMissionCmds); + if (Logging_IsMissionDefined((uint8_t *)loggingMissionCmds) == 0) { + return false; + } + printf(loggingMissionCmds); + fflush(stdout); + RPC_ProcessCmds(loggingMissionCmds); + return true; +} + +/** +* @brief Process a RPC command that is pointed to. +* @param cmd RPC string to process +*/ +void ProcessCmd(char *cmd) { + char cmd_[256]; + char reply[512]; + strcpy(cmd_, cmd); + RPC_call(cmd_, reply); +} + +/** +* @brief Buffer sensor fifo data in ram buffers, when a ram buffer is full (a +* flash page worth of data is accumulated) then flash that buffer. +* A buffer ping pong method is used so that one buffer can be flashing as +* the other buffer fills with sensor fifo data. +* @param fifoData Sensor data taken from the fifo to be stored into flash +*/ +static void _LoggingServer_OutputToFlash(uint32_t fifoData) { + uint32_t index; + char str[128]; + uint8_t *ptr; + // + // Log To Flash + // + // i.e. there is data, read one 32-bit size data at a time. + // put the fifo data into the ping-pong SRAM + PingPong_SRAM[sramIndex++] = fifoData & 0xFF; // LSByte goes into index N + PingPong_SRAM[sramIndex++] = (fifoData >> 8) & 0xFF; + PingPong_SRAM[sramIndex++] = (fifoData >> 16) & 0xFF; + PingPong_SRAM[sramIndex++] = (fifoData >> 24) & 0xFF; // MSByte goes into index N+3 + + // flag this buffer as dirty + if (sramIndex <= 256) + sram_buffer_0_dirty = 1; + else + sram_buffer_1_dirty = 1; + + if (sramIndex == 256 || + sramIndex == 512) // Either Ping SRAM or Pong SRAM location is full + { // therefore write to Flash + + index = sramIndex - 256; + ptr = &PingPong_SRAM[index]; + sprintf(str, "currentPage=%d", currentPage); + Peripherals::s25FS512()->writePage_Helper(currentPage, ptr, 0); + + // this page is no longer dirty + if (index == 0) + sram_buffer_0_dirty = 0; + if (index == 256) + sram_buffer_1_dirty = 0; + + currentPage++; + } + sramIndex = sramIndex % 512; // Wrap around the index +} + +/** +* @brief Buffer sensor fifo data in ram buffers, when a ram buffer is full (a +* flash page worth of data is accumulated) then flash that buffer. +* A buffer ping pong method is used so that one buffer can be flashing as +* the other buffer fills with sensor fifo data. +* @param fifoData Sensor data taken from the fifo to be stored into flash +*/ +static void _LoggingServer_OutputToSDCard(FILE* fp, uint32_t fifoData) { + if (fp != NULL){ + fwrite(&fifoData,sizeof(fifoData),1,fp); + } +} + +/** +* @brief If flash ram buffers are flagged as dirty, flush to flash +*/ +static void _LoggingServer_WriteDirtySramBufferToFlash(void) { + uint8_t *ptr = PingPong_SRAM; + if (sram_buffer_0_dirty == 0 && sram_buffer_1_dirty == 0) + return; + if (sram_buffer_0_dirty == 1) { + ptr += 0; + } + if (sram_buffer_1_dirty == 1) { + ptr += 256; + } + printf("_LoggingServer_WriteDirtySramBufferToFlash:%d,%d\n", + sram_buffer_0_dirty, sram_buffer_1_dirty); + fflush(stdout); + // s25fs512_WritePage_Helper(currentPage, ptr, 0); + Peripherals::s25FS512()->writePage_Helper(currentPage, ptr, 0); +} + +/** +* @brief Initialize the USB block running index +* @param fifoData Sensor data taken from the fifo to be sent out USB +*/ +static void _LoggingServer_OutputToCdcAcm(uint32_t fifoData) { + uint8_t *ptr; + uint8_t str[16]; + sprintf((char *)str, "%X ", fifoData); + ptr = str; + usb_block_index = 0; + while (*ptr != 0) { + usb_block[usb_block_index] = *ptr; + ptr++; + usb_block_index++; + } + //Peripherals::usbSerial()->writeBlock(usb_block, usb_block_index); +} + +/** +* @brief Initialize the USB block running index +*/ +static void _LoggingServer_OutputToCdcAcm_Start(void) { usb_block_index = 0; } + +/** +* @brief Buffer up fifoData from sensors, do a USB block transfer if buffer is +* full +* @param fifoData Sensor data taken from the fifo to be send out USB within a +* bulk block transfer +* @return Return the success status of the writeblock operation +*/ +static bool _LoggingServer_OutputToCdcAcm_Block(uint32_t fifoData) { + uint8_t str[64]; + uint8_t *ptr; + bool result; + // + // Log to CDCACM + // + result = true; + sprintf((char *)str, "%X ", fifoData); + ptr = str; + while (*ptr != 0) { + usb_block[usb_block_index] = *ptr; + ptr++; + usb_block_index++; + if (usb_block_index >= 64) { + //result = Peripherals::usbSerial()->writeBlock(usb_block, 64); + usb_block_index = 0; + } + } + return result; +} + +/** +* @brief Output a full USB block via bulk transfer +*/ +static void _LoggingServer_OutputToCdcAcm_End(void) { + if (usb_block_index == 0) + return; + //Peripherals::usbSerial()->writeBlock(usb_block, usb_block_index - 1); +} + +/** +* @brief Blink LED pattern that indicates that the flash end boundary has been +* reached +*/ +static void BlinkEndOfDatalogging(void) { + // blink to signal end of logging + Peripherals::hspLed()->pattern(0x55555555, 20); + wait(2); +} + +/** +* @brief Reads the first data page of flash, if all FF's then the page is empty +* @return 1 if the flash is empty as indicated by the first data page of the +* flash, 0 if not +*/ +int isFlashEmpty(void) { + int i; + uint8_t data[256]; + int firstDataPage = Logging_GetLoggingStartPage(); + Peripherals::s25FS512()->readPages_Helper(firstDataPage, firstDataPage, data, 0); + for (i = 0; i < 256; i++) { + if (data[i] != 0xFF) + return 0; + } + return 1; +} + +/** +* @brief Reads the first data from SDCard, if all FF's then the page is empty +* @return 1 if the flash is empty as indicated by the first data page of the +* flash, 0 if not +*/ +int isSDCardWithoutDataLog(void) { + FILE *fp = NULL; + fp = fopen(dataFileName, "rb"); + if (fp != NULL) { + uint8_t count = 0; + do + { + count ++; + char c = (char)fgetc(fp); + if (count > 2) + { + fclose(fp); + return 0; + } + } while(!feof(fp)); + fclose(fp); + } + return 1; + +} + +/** +* @brief Blink LED pattern that indicates that the flash is not empty and a new +* flash logging session can not occur +*/ +void BlinkFlashNotEmpty(void) { + Peripherals::hspLed()->pattern(0x55555555, 20); + wait(1); +} + +void ExecuteDefaultMission(void) { + ProcessCmd("/MAX30001/CAL_InitStart 01 01 01 03 7FF 00"); + ProcessCmd("/MAX30001/ECG_InitStart 01 01 01 00 02 03 1F 0 00 00 01"); + ProcessCmd("/MAX30001/RtoR_InitStart 01 03 0F 00 03 01 00 00 01"); + ProcessCmd("/MAX30001/Rbias_FMSTR_Init 01 02 01 01 00"); +} + +void LoggingService_Init(void) { loggingTrigger = eTriggerLog_NULL; } + +/** +* @brief This routine checks to see if a USB or flash logging action needs to be taken +* The routine checks for a start condition via button press, USB command, or BLE command +* Once one of these start conditions is present, the logging begins until stopped or memory is full +* @return 1 if successful, 0 if error or logging was aborted and no logging occurred +*/ +uint8_t LoggingService_ServiceRoutine(void) { + uint32_t fifoData; + uint32_t endPage; + FILE *fp; +// USBSerial *usbSerial = Peripherals::usbSerial(); + // BMP280 *bmp280 = Peripherals::bmp280(); + bool buttonPressed; + bool endSDLogging = false; + int packetBurstCount = 0; + HspLed *hspLed = Peripherals::hspLed(); + + sramIndex = 0; + // only start logging if conditions exist + + if (_LoggingService_CheckStartCondition() == false) return 0; + printf("Begin Logging..."); + if (startEvent == eStartEvent_NULL) printf("eStartEvent_NULL..."); + if (startEvent == eStartEvent_BLE) printf("eStartEvent_BLE..."); + if (startEvent == eStartEvent_BUTTON) printf("eStartEvent_BUTTON..."); + if (startEvent == eStartEvent_RPC_TO_USB) printf("eStartEvent_RPC_TO_USB..."); + if (startEvent == eStartEvent_RPC_TO_FLASH) printf("eStartEvent_RPC_TO_FLASH..."); + fflush(stdout); + + // start logging stuttered blink pattern + hspLed->pattern(0xA0F3813, 20); + + if (startEvent == eStartEvent_RPC_TO_FLASH || + startEvent == eStartEvent_BUTTON) { + // check to see if datalog already in flash... abort and force user to erase + // flash if needed + if (loggingOutput == eLogToFlash) { + if (isSDCardWithoutDataLog() == 0) { + Logging_SetStart(false); + // bleStartCommand = 0x00; + BlinkFlashNotEmpty(); + hspLed->blink(1000); + printf("Abort Logging, flash log exists. "); + fflush(stdout); + return 0; + } + } + } + + if (startEvent == eStartEvent_BLE) { + // check for mission in flash + if (_LoggingService_ReadMissionFromSDCard() == false) { + // if there is no mission in flash then do a default mission for the sake + // of ble Android app working "out-of-the-box" and stream RtoR and Accel + printf("No Mission in Flash...ExecuteDefaultMission..."); + fflush(stdout); + ExecuteDefaultMission(); + // do not log this data + loggingOutput = eLogToNothing; + } else { + // there is a mission in flash check if there is already logged data + if (isSDCardWithoutDataLog() == 0) { + // just do default mission + printf("Logged Data Detected...ExecuteDefaultMission..."); + fflush(stdout); + ExecuteDefaultMission(); + // do not log this data + loggingOutput = eLogToNothing; + } else { + // flag that we are logging to flash + loggingOutput = eLogToFlash; + } + } + } + + // if we are logging to flash then read mission in flash + if (loggingOutput == eLogToFlash) { + if (_LoggingService_ReadMissionFromSDCard() == + false) { // if there is no mission in flash then get out + Logging_SetStart(false); + Peripherals::hspLed()->pattern(0xC3C3C3C3, 20); + wait(2); + printf("Abort Logging, Mission does not exist. "); + fflush(stdout); + return 0; + } + currentPage = Logging_GetLoggingStartPage(); + endPage = Logging_GetLoggingEndPage(); + } + + MAX30001_Helper_SetupInterrupts(); + if (MAX30001_AnyStreamingSet() == 1) { + MAX30001_Helper_StartSync(); + } + + SetDataLoggingStream(TRUE); + +/* while (usbSerial->readable()) { + usbSerial->_getc(); + } + fifo_clear(GetUSBIncomingFifo()); // clear USB serial incoming fifo + fifo_clear(GetStreamOutFifo()); +*/ + sram_buffer_0_dirty = 0; + sram_buffer_1_dirty = 0; + + + if (loggingOutput == eLogToNothing) printf("eLogToNothing..."); fflush(stdout); + if (loggingOutput == eLogToFlash) printf("eLogToFlash..."); fflush(stdout); + if (loggingOutput == eLogtoUsb) printf("eLogtoUsb..."); fflush(stdout); + printf("highDataRate=%d...",highDataRate); fflush(stdout); + + + Peripherals::timestampTimer()->reset(); + Peripherals::timestampTimer()->start(); + + _LoggingServer_OutputToCdcAcm_Start(); + while (1) { + if (loggingOutput == eLogToFlash) { + // check if we are at the end of flash + if (currentPage >= endPage) { + BlinkEndOfDatalogging(); // blink for 3 seconds to signal end of logging + break; + } + } + + if (startEvent == eStartEvent_BUTTON) { + buttonPressed = Peripherals::pushButton()->GetButtonFallState(); + if (buttonPressed) { + printf("button pressed, flush the FIFO buffer to SDCard before ending logging\r\n"); + Peripherals::pushButton()->clearButtonFallState(); + // if there is a dirty sram buffer... flush it to flash + _LoggingServer_WriteDirtySramBufferToFlash(); + endSDLogging = true; + } + } + +/* if (startEvent == eStartEvent_RPC_TO_USB || + startEvent == eStartEvent_RPC_TO_FLASH) { + if (usbSerial->available()) { + if (loggingOutput == eLogToFlash) { + _LoggingServer_WriteDirtySramBufferToFlash(); + } + wait(0.2f); + while (usbSerial->available()) { + usbSerial->_getc(); + } + fifo_clear(GetUSBIncomingFifo()); // clear USB serial incoming fifo + fifo_clear(GetStreamOutFifo()); + break; + } + }*/ + if (fp == NULL && loggingOutput == eLogToFlash) + fp = fopen(dataFileName, "ab+"); + // check to see if data is available + packetBurstCount = 0; + while (PacketFifo_Empty() == 0) { + printf("*"); + if (packetBurstCount >= 100 && endSDLogging == false) + break; + fifoData = PacketFifo_GetUint32(); + if (loggingOutput == eLogToFlash) { + //_LoggingServer_OutputToFlash(fifoData); + _LoggingServer_OutputToSDCard(fp, fifoData); + } + if (loggingOutput == eLogtoUsb) { + if (highDataRate == 0) + _LoggingServer_OutputToCdcAcm(fifoData); + else + _LoggingServer_OutputToCdcAcm_Block(fifoData); + } + packetBurstCount++; + } + + if (endSDLogging) { + endSDLogging = false; + if (fp != NULL) fclose(fp); + fp == NULL; + BlinkEndOfDatalogging(); // blink for 3 seconds to signal end of logging + break; + } + + } + _LoggingServer_OutputToCdcAcm_End(); + printf("End Logging.\n"); + fflush(stdout); + + MAX30001_Helper_Stop(); // if any MAX30001 streams have been started, stop + // them + SetDataLoggingStream(FALSE); + Peripherals::timestampTimer()->stop(); + hspLed->blink(1000); + // default to non-usb packet speed optimizing + highDataRate = 0; + loggingTrigger = eTriggerLog_NULL; + return 1; +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/LoggingService/DataLoggingService.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/LoggingService/DataLoggingService.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _LOGGINGSERVICE_H_ +#define _LOGGINGSERVICE_H_ + +#include "mbed.h" + +/// types of logging +typedef enum { + /// do not log + eLogToNothing, + /// log to USB + eLogtoUsb, + /// Log to external flash memory + eLogToFlash +} eLoggingOutput; + +/// types of logging +typedef enum { + eTriggerLog_NULL, + eTriggerLog_RPC_USB, + eTriggerLog_RPC_FLASH, + eTriggerLog_BUTTON, + eTriggerLog_BLE, +} eLoggingTrigger; + +/// extern that indicates the hardware button on the HSP was pressed +extern uint32_t buttonTrigger; + +void LoggingService_Init(void); + +/** +* @brief This routine checks to see if a USB or flash logging action needs to be +* taken +* The routine checks for a start condition via button press, USB +* command, or BLE command +* Once one of these start conditions is present, the logging begins +* until stopped or memory is full +* @return 1 if successful, 0 if error or logging was aborted and no logging +* occurred +*/ +uint8_t LoggingService_ServiceRoutine(void); +/** +* @brief This is called via one of the RPC USB functions to set start conditons +* to start streaming USB +*/ +void LoggingService_StartLoggingUsb(void); +/** +* @brief This is called via one of the RPC USB functions to set start conditons +* to start logging to flash +*/ +void LoggingService_StartLoggingFlash(void); + +#endif /* _LOGGINGSERVICE_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/LoggingService/Device_Logging.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/LoggingService/Device_Logging.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include "Device_Logging.h" + +/** +* @brief Check if logging is enabled for this device +*/ +int Device_Logging::isLoggingEnabled(void) { return enabled; } + +/** +* @brief Returns the sample rate for the device, rate is in seconds +*/ +int Device_Logging::getLoggingSampleRate(void) { return sampleRate; } + +/** +* @brief Initialize the sampling rate for the device +* @param sampleRate Rate to log device output in seconds +*/ +void Device_Logging::initStart(int sampleRate) { + this->sampleRate = sampleRate; + enabled = 1; +} + +/** +* @brief Disables further datalog and streaming sampling for the device +* @param time Time for next sample in seconds, time is relative to a timer +*/ +void Device_Logging::stop(void) { enabled = 0; } + +/** +* @brief Gets a value that represents when device needs to be sampled again, +* used for datalogging and usb streaming +*/ +int Device_Logging::getNextSampleTime(void) { return nextSampleTime; } + +/** +* @brief Sets a value that represents when device needs to be sampled again, +* used for datalogging and usb streaming +* @param time Time for next sample in seconds, time is relative to a timer +*/ +void Device_Logging::setNextSampleTime(int time) { nextSampleTime = time; } +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/LoggingService/Device_Logging.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/LoggingService/Device_Logging.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _DEVICE_LOGGING_H_ +#define _DEVICE_LOGGING_H_ + +#include "mbed.h" + +/** +* @brief Class that is used to store device logging parameters when logging to +* flash or streaming usb +*/ +class Device_Logging { +public: + /** + * @brief Check if logging is enabled for this device + */ + int isLoggingEnabled(void); + /** + * @brief Returns the sample rate for the device, rate is in seconds + */ + int getLoggingSampleRate(void); + /** + * @brief Initialize the sampling rate for the device + * @param sampleRate Rate to log device output in seconds + */ + void initStart(int sampleRate); + /** + * @brief Gets a value that represents when device needs to be sampled again, + * used for datalogging and usb streaming + */ + int getNextSampleTime(void); + /** + * @brief Sets a value that represents when device needs to be sampled again, + * used for datalogging and usb streaming + * @param time Time for next sample in seconds, time is relative to a timer + */ + void setNextSampleTime(int time); + /** + * @brief Disables further datalog and streaming sampling for the device + * @param time Time for next sample in seconds, time is relative to a timer + */ + void stop(void); + +private: + /// The sample rate in seconds + int sampleRate; + /// If logging is enabled or not + int enabled; + /// Bookkeeping var to keep track of the next sample time + int nextSampleTime; +}; + +#endif /* _DEVICE_LOGGING_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/LoggingService/Logging.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/LoggingService/Logging.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "mbed.h" +#include "RpcServer.h" +#include "Logging.h" +#include "S25FS512.h" +#include "Peripherals.h" + +/// length of flash page as dictated by the device +#define LENGTH_OF_FLASH_PAGE 256 // length of flash page in bytes +/// size in bytes of the external flash device on the HSP platform +#define SIZE_OF_EXTERNAL_FLASH \ + (16777216 / 2) // length of external flash in bytes +/// start page of where the mission is defined +#define MISSION_DEFINITION_START_PAGE 0x00 +/// end page of the mission +#define MISSION_DEFINITION_END_PAGE 0x0F +/// page of where the logging data starts +#define LOGGING_START_PAGE 0x12 +/// the last logging page +#define LOGGING_END_PAGE (SIZE_OF_EXTERNAL_FLASH / LENGTH_OF_FLASH_PAGE) + +/// static flag to know if logging was started via RPC +static bool startLoggingViaRpc = false; + +extern char missionFileName[32]; + +/** +* @brief This will read the mission location and if there is something valid, +* then run the Logging_ProcessMissionCmds() +* @param cmdBuffer buffer +*/ +uint32_t Logging_IsMissionDefined(uint8_t *cmdBuffer) { + uint32_t valid = 1; + if ((cmdBuffer[0] == 0xFF) || (cmdBuffer[0] == 0x0)) + valid = 0; + return valid; +} + +/** +* @brief Read the mission from flash and place in buffer +* @param buffer pointer to byte array that will contain the read results +*/ +int8_t Logging_ReadMissionFromFlash(uint8_t *buffer) { + return Peripherals::s25FS512()->readPages_Helper( + MISSION_DEFINITION_START_PAGE, MISSION_DEFINITION_END_PAGE, buffer, 0); +} + +/** +* @brief Read the mission from SDCard and place in buffer +* @param buffer pointer to byte array that will contain the read results +*/ +int8_t Logging_ReadMissionFromSDCard(uint8_t *buffer) { + FILE *fp = NULL; + if (buffer == NULL) + return -1; + fp = fopen(missionFileName, "r"); + if (fp != NULL) { + do + { + char c = (char)fgetc(fp); + *buffer++ = c; + } while(!feof(fp)); + fclose(fp); + } + else + return -1; + return 0; +} + +//****************************************************************************** +// return the page where mission is defined, Mission specific +uint32_t Logging_GetMissionStartPage(void) { + return MISSION_DEFINITION_START_PAGE; +} + +//****************************************************************************** +// return the page where the mission definition ends, Mission specific +uint32_t Logging_GetMissionEndPage(void) { return MISSION_DEFINITION_END_PAGE; } + +//****************************************************************************** +// Returns the location where the Writing can start from, for data logging... +uint32_t Logging_GetLoggingStartPage(void) { return LOGGING_START_PAGE; } + +//****************************************************************************** +// Returns the end location available where the Flash ends essentially.... for +// data logging. +uint32_t Logging_GetLoggingEndPage(void) { return LOGGING_END_PAGE; } + +//****************************************************************************** +void Logging_SetStart(bool state) { startLoggingViaRpc = state; } + +//****************************************************************************** +bool Logging_GetStart(void) { return startLoggingViaRpc; } + +//****************************************************************************** +// for debugging... always say that usb is not connected... for easy bench +// testing +uint32_t Usb_IsConnected(void) { return 0; } +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/LoggingService/Logging.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/LoggingService/Logging.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,38 @@ +#ifndef _LOGGING_H_ +#define _LOGGING_H_ + +#include "mbed.h" + +/** +* @brief This will read the mission location and if there is something valid, +* then run the Logging_ProcessMissionCmds() +* @param cmdBuffer buffer +*/ +uint32_t Logging_IsMissionDefined(uint8_t *cmdBuffer); + +int8_t Logging_ReadMissionFromSDCard(uint8_t *buffer); + +int8_t Logging_ReadMissionFromFlash(uint8_t *buffer); + +// return the page where mission is defined, Mission specific +uint32_t Logging_GetMissionStartPage(void); + +// return the page where the mission definition ends, Mission specific +uint32_t Logging_GetMissionEndPage(void); + +// Returns the location where the Writing can start from, for data logging... +uint32_t Logging_GetLoggingStartPage(void); + +// Returns the end location available where the Flash ends essentially.... for +// data logging. +uint32_t Logging_GetLoggingEndPage(void); + +// returns one if the usb is connected, zero if not +uint32_t Usb_IsConnected(void); + +void Logging_SetStart(bool state); + +bool Logging_GetStart(void); + +#endif /* _LOGGING_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/LoggingService/Logging_RPC.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/LoggingService/Logging_RPC.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,259 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ****************************************************************************** + */ +#include "StringHelper.h" +#include <stdint.h> +#include "Streaming.h" +#include "StringInOut.h" +#include "DataLoggingService.h" +#include "Peripherals.h" +#include "Logging.h" + +extern char loggingMissionCmds[4096]; +uint32_t missionCmdIndex; +extern char missionFileName[32]; +extern char dataFileName[32]; + //****************************************************************************** + int Logging_RPC_StartMissionDefine(char argStrs[32][32], + char replyStrs[32][32]) { + uint32_t i; + uint32_t reply[1]; + + // reset the missionCmdIndex to the beginning of the cmd buffer + missionCmdIndex = 0; + // clear the mission command buffer, fill with zeros + for (i = 0; i < sizeof(loggingMissionCmds); i++) { + loggingMissionCmds[i] = 0; + } + + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +//****************************************************************************** +int Logging_RPC_AppendMissionCmd(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + char *strPtr; + uint32_t count = 0; + uint8_t result = 0x80; + // append the string to the mission cmd log + strPtr = argStrs[0]; + while (*strPtr != 0) { + loggingMissionCmds[missionCmdIndex] = *strPtr; + missionCmdIndex++; + strPtr++; + // do not overrun buffer + if (missionCmdIndex > (sizeof(loggingMissionCmds) - 2)) { + result = 0xFF; + break; + } + count++; + // do not read more than max count in incoming string + if (count > (32 * 32)) { + result = 0xFF; + break; + } + } + if (result != 0x80) { + reply[0] = 0xFF; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; + } + // add cr/lf to the end of this cmd string + loggingMissionCmds[missionCmdIndex++] = 13; + loggingMissionCmds[missionCmdIndex++] = 10; + + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +//****************************************************************************** +int Logging_RPC_EndMissionDefine(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +//****************************************************************************** +int Logging_RPC_WriteMission(char argStrs[32][32], char replyStrs[32][32]) { + char *ptr; + uint32_t reply[1]; + + ptr = loggingMissionCmds; + FILE *fp = fopen(missionFileName, "w"); + if (fp != NULL){ + fprintf(fp, ptr); + fclose(fp); + } + + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +//****************************************************************************** +int Logging_RPC_ReadMission(char argStrs[32][32], char replyStrs[32][32]) { + char *ptr; + uint32_t i; + FILE *fp; + ptr = loggingMissionCmds; + fp = fopen(missionFileName, "r"); + if (fp != NULL) { + do + { + char c = (char)fgetc(fp); + *ptr++ = c; + } while(!feof(fp)); + ptr--; + *ptr = 0; + fclose(fp); + } + ptr = loggingMissionCmds; + for (i = 0; i < sizeof(loggingMissionCmds); i++) { + if (*ptr == 13) { + *ptr = ':'; + } else if (*ptr == 10) { + *ptr = ' '; + } + ptr++; + } + + // send it out via uart + putStr(loggingMissionCmds); + replyStrs[0][0] = 0; + return 0; +} + +//****************************************************************************** +int Logging_RPC_EraseMission(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + FILE *fp = fopen(missionFileName, "w"); + if (fp != NULL){ + fprintf(fp, ""); + fclose(fp); + } + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +#define SECTOR_SIZE_256K 0x10000 +#define PAGE_INC_256K 0x400 +#define SECTOR_SIZE_4K 0x1000 +#define PAGE_INC_4K 0x10 +#define TOTAL_SECTOR_NUMBER 263 + +//****************************************************************************** +int Logging_EraseWrittenSectors(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + uint8_t data[512]; + + printf("Logging_EraseWrittenSectors "); + FILE *fp = fopen(missionFileName, "w"); + if (fp != NULL){ + fprintf(fp, ""); + fclose(fp); + } + + fp = fopen(dataFileName, "w"); + if (fp != NULL){ + fprintf(fp, ""); + fclose(fp); + } + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + printf("Logging_EraseWrittenSectors done. \n"); + fflush(stdout); + return 0; +} + +//****************************************************************************** +int Logging_Start(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + Logging_SetStart(true); + reply[0] = 0x80; // indicate success + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +//****************************************************************************** +int Logging_GetLastWrittenPage(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + + uint32_t page; + uint32_t lastPage; + uint32_t pageEmpty; + uint8_t data[512]; + + printf("Logging_GetLastWrittenPage "); + fflush(stdout); + lastPage = Logging_GetLoggingEndPage(); + for (page = 2; page <= lastPage; page++) { + // Peripherals::serial()->printf("checking page %d ",page); fflush(stdout); + // sample the page + Peripherals::s25FS512()->readPages_Helper(page, page, data, 0); + pageEmpty = Peripherals::s25FS512()->isPageEmpty(data); + if (pageEmpty != 0) { + break; + } + } + if (page > lastPage) + page = lastPage; + printf("last page %d, 0x%X ", page, page); + fflush(stdout); + reply[0] = page; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +extern int highDataRate; +//****************************************************************************** +int Logging_StartLoggingUsb(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + // highDataRate = 0; + LoggingService_StartLoggingUsb(); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} +//****************************************************************************** +int Logging_StartLoggingFlash(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + // highDataRate = 0; + LoggingService_StartLoggingFlash(); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +}
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/LoggingService/Logging_RPC.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/LoggingService/Logging_RPC.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _LOGGING_H_ +#define _LOGGING_H_ + +int Logging_RPC_StartMissionDefine(char argStrs[32][32], char replyStrs[32][32]); +int Logging_RPC_AppendMissionCmd(char argStrs[32][32], char replyStrs[32][32]); +int Logging_RPC_EndMissionDefine(char argStrs[32][32], char replyStrs[32][32]); +int Logging_RPC_WriteMission(char argStrs[32][32], char replyStrs[32][32]); +int Logging_RPC_ReadMission(char argStrs[32][32], char replyStrs[32][32]); +int Logging_RPC_EraseMission(char argStrs[32][32], char replyStrs[32][32]); +int Logging_RPC_TestMission(char argStrs[32][32], char replyStrs[32][32]); +int Logging_RPC_TestWriteLog(char argStrs[32][32], char replyStrs[32][32]); +int Logging_RPC_TestReadLog(char argStrs[32][32], char replyStrs[32][32]); +int Logging_RPC_TestBulkErase(char argStrs[32][32], char replyStrs[32][32]); +int Logging_RPC_TestSectorsErase(char argStrs[32][32], char replyStrs[32][32]); +int Logging_RPC_TestReadPage(char argStrs[32][32], char replyStrs[32][32]); +int Logging_RPC_TestWritePage(char argStrs[32][32], char replyStrs[32][32]); +int Logging_EraseWrittenSectors(char argStrs[32][32], char replyStrs[32][32]); +int Logging_StartLoggingUsb(char argStrs[32][32], char replyStrs[32][32]); +int Logging_StartLoggingFlash(char argStrs[32][32], char replyStrs[32][32]); +int Logging_GetLastWrittenPage(char argStrs[32][32], char replyStrs[32][32]); +int Logging_Start(char argStrs[32][32], char replyStrs[32][32]); + +#endif /* _LOGGING_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/QuadSPI/QuadSpi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/QuadSPI/QuadSpi.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "QuadSpi.h" +//#include "spi_multi_api.h" + +/** Initialize a SPI master for Quad SPI + * + * @param mosi Pin used for Master Out Slave In + * @param miso Pin used for Master In Slave Out + * @param sclk Pin used for Clock + * @param ssel Pin used for Chip Select + */ +QuadSPI::QuadSPI(PinName mosi, PinName miso, PinName sclk, PinName ssel) + : SPI(mosi, miso, sclk, ssel) { +} + +/******************************************************************************/ +void QuadSPI::setQuadMode() {}//spi_master_width(&_spi, WidthQuad); } +/******************************************************************************/ +void QuadSPI::setSingleMode() {}//spi_master_width(&_spi, WidthSingle); } + +/** Write a byte out in master mode and receive a value + * + * @param value Byte Value to send + * @return Returns Zero + */ +int QuadSPI::write(int value) { + aquire(); + spi_master_write(&_spi, value); + return 0; +} + +/** Read a byte in master mode using Quad SPI simplex transfer + * + * @return Returns the value received from Quad SPI + */ +int QuadSPI::read(void) { + aquire(); + return 0;//spi_master_read(&_spi); +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/QuadSPI/QuadSpi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/QuadSPI/QuadSpi.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _QUADSPI_H_ +#define _QUADSPI_H_ + +#include "mbed.h" + + + + +/** +* This class provides a Quad SPI interface for quad spi devices +* the class also allows single (4-Wire) communication +*/ +class QuadSPI : SPI { + +public: + /** Create a QuadSPI master connected to the specified pins + * + * mosi or miso can be specfied as NC if not used + * + * @param mosi QuadSPI Master Out, Slave In pin + * @param miso QuadSPI Master In, Slave Out pin + * @param sclk QuadSPI Clock pin + * @param ssel QuadSPI chip select pin + */ + QuadSPI(PinName mosi, PinName miso, PinName sclk, PinName ssel = NC); + + /** Write to the Quad SPI Slave and return the response + * + * @param value Data to be sent to the SPI slave + * + * @returns + * none + */ + int write(int value); + + /** Read from the Quad SPI Slave and return the response + * + * @param none + * + * @returns + * Response from the SPI slave + */ + int read(void); + + /** Allow switching to and from Single SPI and Quad SPI + * + * @param none + * + * @returns + * Response from the SPI slave + */ + void setSingleMode(); + void setQuadMode(); +}; + +#endif /* _QUADSPI_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/PacketFifo.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/PacketFifo.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "RpcFifo.h" +#include "Streaming.h" +#include "RpcServer.h" + +// this will create a packet and insert it on the "jFifo" to be streamed out or +// saved in flash +void PacketFifo_InsertPacket(uint32_t packetId, uint32_t *buffer, + uint32_t numberInBuffer) { + StreamPacketUint32(packetId, buffer, numberInBuffer); +} + +// clears the packet fifo "jFifo" +void PacketFifo_Clear(void) { fifo_clear(GetStreamOutFifo()); } + +// returns one if fifo is empty, zero if not empty +int PacketFifo_Empty(void) { return fifo_empty(GetStreamOutFifo()); } + +// returns a uint32 from the fifo, this uint32 is destined to be streamed out +// USB or saved in flash +uint32_t PacketFifo_GetUint32(void) { + uint32_t val; + fifo_get32(GetStreamOutFifo(), &val); + return val; +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/PacketFifo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/PacketFifo.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES +* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +* Except as contained in this notice, the name of Maxim Integrated +* Products, Inc. shall not be used except as stated in the Maxim Integrated +* Products, Inc. Branding Policy. +* +* The mere transfer of this software does not imply any licenses +* of trade secrets, proprietary technology, copyrights, patents, +* trademarks, maskwork rights, or any other form of intellectual +* property whatsoever. Maxim Integrated Products, Inc. retains all +* ownership rights. +******************************************************************************* +*/ +#ifndef _PACKETFIFO_H_ +#define _PACKETFIFO_H_ + +#include "mbed.h" + +/** +* this will create a packet and insert it into an outbound fifo to be streamed out or saved in flash +* @param packetId number id to assign to this packet +* @param buffer a 32-bit buffer that contains data that will be used in the packet +* @param numberInBuffer the number of 32-bit elements to be copied from the buffer +*/ +void PacketFifo_InsertPacket(uint32_t packetId, uint32_t *buffer, uint32_t numberInBuffer); + +/** +* clears the packet outbound fifo +*/ +void PacketFifo_Clear(void); + +/** +* returns one if outbound fifo is empty, zero if not empty +*/ +uint32_t PacketFifo_Empty(void); + +/** +* returns a uint32 from the fifo, this uint32 is destined to be streamed out USB or saved in flash +*/ +uint32_t PacketFifo_GetUint32(void); + +#endif /* _PACKETFIFO_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/RpcDeclarations.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/RpcDeclarations.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,444 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _RPCDECLARATIONS_H_ +#define _RPCDECLARATIONS_H_ + +/// define the parts of a RPC. ObjectName, MethodName and function +struct RPC_registeredProcedure { + const char *objectName; + const char *methodName; + //enum eArgType argTypes[4]; + int (*func)(char args[32][32], char results[32][32]); + struct RPC_registeredProcedure *next; +}; + +/// used to keep track of the head of the list and the end of a list +struct RPC_Object { + struct RPC_registeredProcedure *head; + struct RPC_registeredProcedure *last; +}; + +//example /I2c/WriteRead 1 A0 3 11 22 33 2 +#define System_NAME "System" + +/** +* @brief /System/ReadVer +* @details Returns the version string of the FW that is currently running +* @details Example: /System/ReadVer +* @details The command returns a version string similar to this: "HSP FW Version 2.0.1f 8/23/16" +*/ +struct RPC_registeredProcedure Define_System_ReadVer = { System_NAME, "ReadVer", System_ReadVer }; +/** +* @brief /System/ReadBuildTime +* @details Returns the build string of the FW that is currently running, this is the time and date that the firmware was built +* @details Example: /System/ReadBuildTime +* @details The command returns a build string similar to this: "Build Time: Fri Jul 1 15:48:31 2016" +*/ +struct RPC_registeredProcedure Define_System_ReadBuildTime = { System_NAME, "ReadBuildTime", System_ReadBuildTime }; + +#define MAX30001_NAME "MAX30001" +#define MAX30003_NAME "MAX30003" + +#define MAX31725_NAME "MAX31725" +#define MAX30205_NAME "MAX30205" + +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_WriteReg = { MAX30001_NAME, "WriteReg", MAX30001_WriteReg }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_ReadReg = { MAX30001_NAME, "ReadReg", MAX30001_ReadReg }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_Start = { MAX30001_NAME, "Start", MAX30001_Start }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_Stop = { MAX30001_NAME, "Stop", MAX30001_Stop }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_Rbias_FMSTR_Init = { MAX30001_NAME, "Rbias_FMSTR_Init", MAX30001_Rbias_FMSTR_Init }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_CAL_InitStart = { MAX30001_NAME, "CAL_InitStart", MAX30001_CAL_InitStart }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_ECG_InitStart = { MAX30001_NAME, "ECG_InitStart", MAX30001_ECG_InitStart }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_ECGFast_Init = { MAX30001_NAME, "ECGFast_Init", MAX30001_ECGFast_Init }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_PACE_InitStart = { MAX30001_NAME, "PACE_InitStart", MAX30001_PACE_InitStart }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_BIOZ_InitStart = { MAX30001_NAME, "BIOZ_InitStart", MAX30001_BIOZ_InitStart }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_RtoR_InitStart = { MAX30001_NAME, "RtoR_InitStart", MAX30001_RtoR_InitStart }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_Stop_ECG = { MAX30001_NAME, "Stop_ECG", MAX30001_Stop_ECG }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_Stop_PACE = { MAX30001_NAME, "Stop_PACE", MAX30001_Stop_PACE }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_Stop_BIOZ = { MAX30001_NAME, "Stop_BIOZ", MAX30001_Stop_BIOZ }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_Stop_RtoR = { MAX30001_NAME, "Stop_RtoR", MAX30001_Stop_RtoR }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_Stop_Cal = { MAX30001_NAME, "Stop_Cal", MAX30001_Stop_Cal }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_Enable_ECG_LeadON = { MAX30001_NAME, "Enable_ECG_LeadON", MAX30001_Enable_ECG_LeadON }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_Enable_BIOZ_LeadON = { MAX30001_NAME, "Enable_BIOZ_LeadON", MAX30001_Enable_BIOZ_LeadON }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_Read_LeadON = { MAX30001_NAME, "Read_LeadON", MAX30001_Read_LeadON }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_StartTest = { MAX30001_NAME, "StartTest", MAX30001_StartTest }; +/** +* @brief /MAX30101/SpO2mode_init fifo_waterlevel_mark sample_avg sample_rate pulse_width red_led_current ir_led_current +* @details This function sets up for the SpO2 mode. +* @param fifo_waterlevel_mark +* @param sample_avg +* @param sample_rate +* @param pulse_width +* @param red_led_current +* @param ir_led_current +*/ +struct RPC_registeredProcedure Define_MAX30001_INT_assignment = { MAX30001_NAME, "INT_assignment", MAX30001_INT_assignment }; + +#define LOGGING_NAME "Logging" +/** +* @brief /Logging/StartMissionDefine +* @details A command to send when you are starting to define a mission +*/ +struct RPC_registeredProcedure Define_Logging_StartMissionDefine = { LOGGING_NAME, "StartMissionDefine", Logging_RPC_StartMissionDefine }; +/** +* @brief /Logging/AppendMissionCmd missionString +* @details Specify a RPC command that is part of a mission +*/ +struct RPC_registeredProcedure Define_Logging_AppendMissionCmd = { LOGGING_NAME, "AppendMissionCmd", Logging_RPC_AppendMissionCmd }; +/** +* @brief /Logging/EndMissionDefine +* @details RPC command that indicated the end of defining a mission +*/ +struct RPC_registeredProcedure Define_Logging_EndMissionDefine = { LOGGING_NAME, "EndMissionDefine", Logging_RPC_EndMissionDefine }; +/** +* @brief /Logging/WriteMission +* @details Write the described mission to flash +*/ +struct RPC_registeredProcedure Define_Logging_WriteMission = { LOGGING_NAME, "WriteMission", Logging_RPC_WriteMission }; +/** +* @brief /Logging/ReadMission +* @details Read the mission from flash +*/ +struct RPC_registeredProcedure Define_Logging_ReadMission = { LOGGING_NAME, "ReadMission", Logging_RPC_ReadMission }; +/** +* @brief /Logging/EraseMission +* @details Erase the mission in flash +*/ +struct RPC_registeredProcedure Define_Logging_EraseMission = { LOGGING_NAME, "EraseMission", Logging_RPC_EraseMission }; +/** +* @brief /Logging/EraseWrittenSectors +* @details Erase the datalog in flash, this erases all of the datalog that has been written to the flash +*/ +struct RPC_registeredProcedure Define_Logging_EraseWrittenSectors = { LOGGING_NAME, "EraseWrittenSectors", Logging_EraseWrittenSectors }; +/** +* @brief /Logging/StartLoggingUsb +* @details Start streaming data through USB +*/ +struct RPC_registeredProcedure Define_Logging_StartLoggingUsb = { LOGGING_NAME, "StartLoggingUsb", Logging_StartLoggingUsb }; +/** +* @brief /Logging/StartLoggingFlash +* @details Start logging data to flash +*/ +struct RPC_registeredProcedure Define_Logging_StartLoggingFlash = { LOGGING_NAME, "StartLoggingFlash", Logging_StartLoggingFlash }; +/** +* @brief /Logging/GetLastWrittenPage +* @details Returns the last page that has been written to flash, this call searchs until it finds an empty flash page +*/ +struct RPC_registeredProcedure Define_Logging_GetLastWrittenPage = { LOGGING_NAME, "GetLastWrittenPage", Logging_GetLastWrittenPage }; +/** +* @brief /Logging/Start +* @details Starts a datalogging session into flash, allows the ability to start datalogging via RPC call +*/ +struct RPC_registeredProcedure Define_Logging_Start = { LOGGING_NAME, "Start", Logging_Start }; + +#define LED_NAME "Led" +/** +* @brief /Led/On +* @details Turn on the HSP onboard LED +*/ +struct RPC_registeredProcedure Define_Led_On = { LED_NAME, "On", Led_On }; +/** +* @brief /Led/Off +* @details Turn off the HSP onboard LED +*/ +struct RPC_registeredProcedure Define_Led_Off = { LED_NAME, "Off", Led_Off }; +/** +* @brief /Led/Blink mS +* @details Start blinking the HSP onboard LED +* @param mS Blink using a mS period +*/ +struct RPC_registeredProcedure Define_Led_BlinkHz = { LED_NAME, "Blink", Led_BlinkHz }; +/** +* @brief /Led/Pattern pattern +* @details Rotate a 32-bit pattern through the LED so that specific blink patterns can be obtained +* @param pattern A 32-bit pattern to rotate through +*/ +struct RPC_registeredProcedure Define_Led_BlinkPattern = { LED_NAME, "Pattern", Led_BlinkPattern }; + +#define S25FS512_NAME "S25FS512" +#define SDCARD_NAME "SDCard" +/** +* @brief /S25FS512/ReadId +* @details Rotate a 32-bit pattern through the LED so that specific blink patterns can be obtained +* @param pattern A 32-bit pattern to rotate through +*/ +struct RPC_registeredProcedure Define_S25FS512_ReadId = { S25FS512_NAME, "ReadId", S25FS512_ReadId }; +/** +* @brief /S25FS512/ReadPagesBinary startPage endPage +* @details Read a page from flash, return the data in binary (non-ascii) +* @param startPage The Starting page to read from +* @param endPage The last page to read from +*/ +struct RPC_registeredProcedure Define_S25FS512_ReadPagesBinary = { S25FS512_NAME, "ReadPagesBinary", S25FS512_ReadPagesBinary }; +/** +* @brief /S25FS512/Reset +* @details Issue a soft reset to the flash device +*/ +struct RPC_registeredProcedure Define_S25FS512_Reset = { S25FS512_NAME, "Reset", S25FS512_Reset }; +/** +* @brief /S25FS512/EnableHWReset +* @details Enable HW resets to the device +*/ +struct RPC_registeredProcedure Define_S25FS512_EnableHWReset = { S25FS512_NAME, "EnableHWReset", S25FS512_EnableHWReset }; +/** +* @brief /S25FS512/SpiWriteRead +* @details Write and read SPI to the flash device using Quad SPI +*/ +struct RPC_registeredProcedure Define_S25FS512_SpiWriteRead = { S25FS512_NAME, "SpiWriteRead", S25FS512_SpiWriteRead }; +/** +* @brief /S25FS512/SpiWriteRead4Wire +* @details Write and read SPI to the flash device using 4 wire +*/ +struct RPC_registeredProcedure Define_S25FS512_SpiWriteRead4Wire = { S25FS512_NAME, "SpiWriteRead4Wire", S25FS512_SpiWriteRead4Wire }; +/** +* @brief /SDCard/IsReady +* @details Check whether SD Card File System is accessible +*/ +struct RPC_registeredProcedure Define_SDCard_IsReady = { SDCARD_NAME, "IsReady", SDCard_IsReady }; + + +#define TESTING_NAME "Testing" +/** +* @brief /Testing/Test_S25FS512 +* @details Start a testing sequence for this device, returns PASS and FAIL strings and detailed results of the test +*/ +struct RPC_registeredProcedure Define_Testing_Test_S25FS512 = { TESTING_NAME, "Test_S25FS512", Test_S25FS512}; + +/** +* @brief /Testing/Test_MAX30001 +* @details Start a testing sequence for this device, returns PASS and FAIL strings and detailed results of the test +*/ +struct RPC_registeredProcedure Define_Testing_Test_MAX30001 = { TESTING_NAME, "Test_MAX30001", Test_MAX30001 }; + +#endif /* _RPCDECLARATIONS_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/RpcFifo.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/RpcFifo.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,254 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "mbed.h" +#include "RpcFifo.h" + +/****************************************************************************/ +void fifo_init(fifo_t *fifo, void *mem, unsigned int length) { + // atomic FIFO access + __disable_irq(); + + fifo->rindex = 0; + fifo->windex = 0; + fifo->data = mem; + fifo->length = length; + + __enable_irq(); +} + +/****************************************************************************/ +int fifo_put8(fifo_t *fifo, uint8_t element) { + // Check if FIFO is full + if ((fifo->windex == (fifo->rindex - 1)) || + ((fifo->rindex == 0) && (fifo->windex == (fifo->length - 1)))) { + return -1; + } + + // atomic FIFO access + __disable_irq(); + + // Put data into FIFO + ((uint8_t *)(fifo->data))[fifo->windex] = element; + + // Increment pointer + fifo->windex++; + if (fifo->windex == fifo->length) { + fifo->windex = 0; + } + + __enable_irq(); + + return 0; +} + +/****************************************************************************/ +int fifo_get8(fifo_t *fifo, uint8_t *element) { + // Check if FIFO is empty + if (fifo->rindex == fifo->windex) + return -1; + + // atomic FIFO access + __disable_irq(); + + // Get data from FIFO + *element = ((uint8_t *)(fifo->data))[fifo->rindex]; + + // Increment pointer + fifo->rindex++; + if (fifo->rindex == fifo->length) { + fifo->rindex = 0; + } + + __enable_irq(); + + return 0; +} + +/****************************************************************************/ +int fifo_put16(fifo_t *fifo, uint16_t element) { + // Check if FIFO is full + if ((fifo->windex == (fifo->rindex - 1)) || + ((fifo->rindex == 0) && (fifo->windex == (fifo->length - 1)))) { + return -1; + } + + // atomic FIFO access + __disable_irq(); + + // Put data into FIFO + ((uint16_t *)(fifo->data))[fifo->windex] = element; + + // Increment pointer + fifo->windex++; + if (fifo->windex == fifo->length) { + fifo->windex = 0; + } + + __enable_irq(); + + return 0; +} + +/****************************************************************************/ +int fifo_get16(fifo_t *fifo, uint16_t *element) { + // Check if FIFO is empty + if (fifo->rindex == fifo->windex) + return -1; + + // atomic FIFO access + __disable_irq(); + + // Get data from FIFO + *element = ((uint16_t *)(fifo->data))[fifo->rindex]; + + // Increment pointer + fifo->rindex++; + if (fifo->rindex == fifo->length) { + fifo->rindex = 0; + } + + __enable_irq(); + + return 0; +} + +/****************************************************************************/ +int fifo_put32(fifo_t *fifo, uint32_t element) { + // Check if FIFO is full + if ((fifo->windex == (fifo->rindex - 1)) || + ((fifo->rindex == 0) && (fifo->windex == (fifo->length - 1)))) { + return -1; + } + + // atomic FIFO access + __disable_irq(); + + // Put data into FIFO + ((uint32_t *)(fifo->data))[fifo->windex] = element; + + // Increment pointer + fifo->windex++; + if (fifo->windex == fifo->length) { + fifo->windex = 0; + } + + __enable_irq(); + + return 0; +} + +/****************************************************************************/ +int fifo_get32(fifo_t *fifo, uint32_t *element) { + // Check if FIFO is empty + if (fifo->rindex == fifo->windex) + return -1; + + // atomic FIFO access + __disable_irq(); + + // Get data from FIFO + *element = ((uint32_t *)(fifo->data))[fifo->rindex]; + + // Increment pointer + fifo->rindex++; + if (fifo->rindex == fifo->length) { + fifo->rindex = 0; + } + + __enable_irq(); + + return 0; +} +/****************************************************************************/ +void fifo_clear(fifo_t *fifo) { + // atomic FIFO access + __disable_irq(); + + fifo->rindex = 0; + fifo->windex = 0; + + __enable_irq(); +} + +/****************************************************************************/ +int fifo_empty(fifo_t *fifo) { return (fifo->rindex == fifo->windex); } + +/****************************************************************************/ +int fifo_full(fifo_t *fifo) { + int retval; + + // atomic FIFO access + __disable_irq(); + retval = ((fifo->windex == (fifo->rindex - 1)) || + ((fifo->rindex == 0) && (fifo->windex == (fifo->length - 1)))); + __enable_irq(); + + return retval; +} + +/****************************************************************************/ +unsigned int fifo_level(fifo_t *fifo) { + uint16_t value; + + // atomic FIFO access + __disable_irq(); + + if (fifo->windex >= fifo->rindex) { + value = fifo->windex - fifo->rindex; + } else { + value = fifo->length - fifo->rindex + fifo->windex; + } + + __enable_irq(); + + return value; +} + +/****************************************************************************/ +unsigned int fifo_remaining(fifo_t *fifo) { + uint16_t value; + + // atomic FIFO access + __disable_irq(); + + if (fifo->rindex > fifo->windex) { + value = fifo->rindex - fifo->windex - 1; + } else { + value = fifo->length - fifo->windex + fifo->rindex - 1; + } + + __enable_irq(); + + return value; +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/RpcFifo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/RpcFifo.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + ******************************************************************************** + */ +#ifndef _RPCFIFO_H_ +#define _RPCFIFO_H_ + +#include <stdint.h> + +/// Structure used for FIFO management +typedef struct { + unsigned int length; ///< FIFO size (number of elements) + void *data; ///< pointer to the FIFO buffer + unsigned int rindex; ///< current FIFO read index + unsigned int windex; ///< current FIFO write index +} fifo_t; + +/** +* @param fifo FIFO on which to perform the operation +* @param mem memory buffer to use for FIFO element storage +* @param length number of elements that the memory buffer can contain +* @returns 0 if successful, -1 upon failure +*/ +void fifo_init(fifo_t *fifo, void *mem, unsigned int length); + +/** +* @brief Adds and 8-bit element to the FIFO +* @param fifo FIFO on which to perform the operation +* @param element element to add to the FIFO +* @returns 0 if successful, -1 upon failure +*/ +int fifo_put8(fifo_t *fifo, uint8_t element); + +/** +* @brief Gets the next 8-bit element to the FIFO +* @param fifo FIFO on which to perform the operation +* @param element pointer to where to store the element from the FIFO +* @returns 0 if successful, -1 upon failure +*/ +int fifo_get8(fifo_t *fifo, uint8_t *element); + +/** +* @brief Adds the next 16-bit element to the FIFO +* @param fifo FIFO on which to perform the operation +* @param element element to add to the FIFO +* @returns 0 if successful, -1 upon failure +*/ +int fifo_put16(fifo_t *fifo, uint16_t element); + +/** +* @brief Gets the next 16-bit element to the FIFO +* @param fifo FIFO on which to perform the operation +* @param element pointer to where to store the element from the FIFO +* @returns 0 if successful, -1 upon failure +*/ +int fifo_get16(fifo_t *fifo, uint16_t *element); + +/** +* @brief Adds the next 16-bit element to the FIFO +* @param fifo FIFO on which to perform the operation +* @param element element to add to the FIFO +* @returns 0 if successful, -1 upon failure +*/ +int fifo_put32(fifo_t *fifo, uint32_t element); + +/** +* @brief Gets the next 16-bit element to the FIFO +* @param fifo FIFO on which to perform the operation +* @param element pointer to where to store the element from the FIFO +* @returns 0 if successful, -1 upon failure +*/ +int fifo_get32(fifo_t *fifo, uint32_t *element); + +/** +* @brief Immediately resets the FIFO to the empty state +* @param fifo FIFO on which to perform the operation +*/ +void fifo_clear(fifo_t *fifo); + +/** +* @brief Determines if the FIFO is empty +* @param fifo FIFO on which to perform the operation +* @returns #TRUE if FIFO is empty, #FALSE otherwise +*/ +int fifo_empty(fifo_t *fifo); + +/** +* @brief FIFO status function +* @param fifo FIFO on which to perform the operation +* @returns #TRUE if FIFO is full, #FALSE otherwise +*/ +int fifo_full(fifo_t *fifo); + +/** +* @brief FIFO status function +* @param fifo FIFO on which to perform the operation +* @returns the number of elements currently in the FIFO +*/ +unsigned int fifo_level(fifo_t *fifo); + +/** +* @brief FIFO status function +* @param fifo FIFO on which to perform the operation +* @returns the remaining elements that can be added to the FIFO +*/ +unsigned int fifo_remaining(fifo_t *fifo); + +#endif // _RPCFIFO_H_ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/RpcServer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/RpcServer.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,399 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "RpcServer.h" +#include "StringInOut.h" +#include "StringHelper.h" +#include "MAX30001_RPC.h" +#include "Logging_RPC.h" +#include "Peripherals.h" +#include "HspLed_RPC.h" +#include "S25FS512_RPC.h" +#include "Testing_RPC.h" +#include "RpcDeclarations.h" +#include "Device_Logging.h" +#include "../version.h" + +/// define the version string that is reported with a RPC "ReadVer" command +#define FW_VERSION_STRING "MAX30001 FW Ver" + +char args[32][32]; +char results[32][32]; + +/// define a fifo for incoming USB data +static fifo_t fifo; +/// define a buffer for incoming USB data +static uint8_t fifoBuffer[128]; +/// define stream out fifo +static fifo_t fifoStreamOut; +/// allocate a large fifo buffer for streaming out +static uint32_t streamOutBuffer[0xC000 / 4]; + +/// define a device log for the BMP280, keeps track of mission and loggin status +Device_Logging *bmp280_Logging; +/// define a device log for the MAX30205 (instance 0), keeps track of mission +/// and loggin status +Device_Logging *MAX30205_0_Logging; +/// define a device log for the MAX30205 (instance 1), keeps track of mission +/// and loggin status +Device_Logging *MAX30205_1_Logging; + +//****************************************************************************** +fifo_t *GetUSBIncomingFifo(void) { return &fifo; } + +//****************************************************************************** +fifo_t *GetStreamOutFifo(void) { return &fifoStreamOut; } + +//****************************************************************************** +int System_ReadVer(char argStrs[32][32], char replyStrs[32][32]) { + char version[32]; + snprintf(version, sizeof(version)/sizeof(char), "%s %d.%d.%d %02d/%02d/%02d", + FW_VERSION_STRING, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, + VERSION_MONTH, VERSION_DAY, VERSION_SHORT_YEAR); + strcpy(replyStrs[0], version); + strcpy(replyStrs[1], "\0"); + return 0; +} + +//****************************************************************************** +int System_ReadBuildTime(char argStrs[32][32], char replyStrs[32][32]) { + // strcpy(replyStrs[0],buildTime); + // strcpy(replyStrs[1],"\0"); + return 0; +} + +//****************************************************************************** +int System_SystemCoreClock(char argStrs[32][32], char replyStrs[32][32]) { + sprintf(replyStrs[0], "SystemCoreClock = %d", SystemCoreClock); + strcpy(replyStrs[1], "\0"); + return 0; +} + +//****************************************************************************** +int System_GetTimestamp(char argStrs[32][32], char replyStrs[32][32]) { + sprintf(replyStrs[0], "GetTimestamp = %d", 0); + strcpy(replyStrs[1], "\0"); + return 0; +} + +static struct RPC_Object RPC_Procedures = {NULL, NULL}; + +//****************************************************************************** +void RPC_addProcedure(struct RPC_registeredProcedure *procedure) { + struct RPC_Object *obj = &RPC_Procedures; + if (obj->last != NULL) { + obj->last->next = procedure; + } + if (obj->head == NULL) { + obj->head = procedure; + } + procedure->next = NULL; + obj->last = procedure; +} + +//****************************************************************************** +void RPC_init(void) { + + fifo_init(&fifo, fifoBuffer, sizeof(fifoBuffer)); + fifo_init(&fifoStreamOut, streamOutBuffer, + sizeof(streamOutBuffer) / sizeof(uint32_t)); + + // MAX30001 + RPC_addProcedure(&Define_MAX30001_WriteReg); + RPC_addProcedure(&Define_MAX30001_ReadReg); + RPC_addProcedure(&Define_MAX30001_Start); + RPC_addProcedure(&Define_MAX30001_Stop); + RPC_addProcedure(&Define_MAX30001_Enable_ECG_LeadON); + RPC_addProcedure(&Define_MAX30001_Enable_BIOZ_LeadON); + RPC_addProcedure(&Define_MAX30001_Read_LeadON); + RPC_addProcedure(&Define_MAX30001_StartTest); + RPC_addProcedure(&Define_MAX30001_INT_assignment); + RPC_addProcedure(&Define_MAX30001_Rbias_FMSTR_Init); + RPC_addProcedure(&Define_MAX30001_CAL_InitStart); + RPC_addProcedure(&Define_MAX30001_ECG_InitStart); + RPC_addProcedure(&Define_MAX30001_ECGFast_Init); + RPC_addProcedure(&Define_MAX30001_PACE_InitStart); + RPC_addProcedure(&Define_MAX30001_BIOZ_InitStart); + RPC_addProcedure(&Define_MAX30001_RtoR_InitStart); + RPC_addProcedure(&Define_MAX30001_Stop_ECG); + RPC_addProcedure(&Define_MAX30001_Stop_PACE); + RPC_addProcedure(&Define_MAX30001_Stop_BIOZ); + RPC_addProcedure(&Define_MAX30001_Stop_RtoR); + RPC_addProcedure(&Define_MAX30001_Stop_Cal); + + // Logging + RPC_addProcedure(&Define_Logging_StartMissionDefine); + RPC_addProcedure(&Define_Logging_AppendMissionCmd); + RPC_addProcedure(&Define_Logging_EndMissionDefine); + RPC_addProcedure(&Define_Logging_WriteMission); + RPC_addProcedure(&Define_Logging_ReadMission); + RPC_addProcedure(&Define_Logging_EraseMission); + RPC_addProcedure(&Define_Logging_EraseWrittenSectors); + RPC_addProcedure(&Define_Logging_StartLoggingUsb); + RPC_addProcedure(&Define_Logging_StartLoggingFlash); + RPC_addProcedure(&Define_Logging_GetLastWrittenPage); + RPC_addProcedure(&Define_Logging_Start); + + // led + RPC_addProcedure(&Define_Led_On); + RPC_addProcedure(&Define_Led_Off); + RPC_addProcedure(&Define_Led_BlinkHz); + RPC_addProcedure(&Define_Led_BlinkPattern); + + // S25FS512 + RPC_addProcedure(&Define_S25FS512_ReadId); + RPC_addProcedure(&Define_S25FS512_ReadPagesBinary); + RPC_addProcedure(&Define_S25FS512_Reset); + RPC_addProcedure(&Define_S25FS512_EnableHWReset); + RPC_addProcedure(&Define_S25FS512_SpiWriteRead); + RPC_addProcedure(&Define_S25FS512_SpiWriteRead4Wire); + + RPC_addProcedure(&Define_Testing_Test_MAX30001); + + // SDCard + RPC_addProcedure(&Define_SDCard_IsReady); + + // System + RPC_addProcedure(&Define_System_ReadVer); + RPC_addProcedure(&Define_System_ReadBuildTime); +} + +//****************************************************************************** +struct RPC_registeredProcedure *RPC_lookup(char *objectName, char *methodName) { + struct RPC_registeredProcedure *ptr; + // lookup all registered methods + ptr = RPC_Procedures.head; + while (ptr != NULL) { + if (strcmp(ptr->objectName, objectName) == 0 && + strcmp(ptr->methodName, methodName) == 0) { + // we found a match... return with it + return ptr; + } + ptr = ptr->next; + } + return NULL; +} + +//****************************************************************************** +char *GetToken(char *inStr, char *outStr, int start, char ch) { + int i; + int index = 0; + int length = strlen(inStr); + for (i = start; i < length; i++) { + if (inStr[i] != ch) { + outStr[index++] = inStr[i]; + } else { + break; + } + } + outStr[index++] = 0; + return outStr; +} + +//****************************************************************************** +void SendCommandList(char *reply) { + struct RPC_registeredProcedure *ptr; + reply[0] = 0; + ptr = RPC_Procedures.head; + while (ptr != NULL) { + strcat(reply, "/"); + strcat(reply, ptr->objectName); + strcat(reply, "/"); + strcat(reply, ptr->methodName); + strcat(reply, ","); + ptr = ptr->next; + } + strcat(reply, "\r\n"); +} + +//****************************************************************************** +int CheckForDoubleQuote(char *str) { + int doubleQuoteFound; + // scan through arguments, see if there is a double quote for a string + // argument + doubleQuoteFound = 0; + while (*str != 0) { + if (*str == '\"') { + doubleQuoteFound = 1; + break; + } + str++; + } + return doubleQuoteFound; +} + +//****************************************************************************** +void ExtractDoubleQuoteStr(char *src, char *dst) { + int start; + + dst[0] = 0; + start = 0; + while (*src != 0) { + // look for start + if ((*src == '\"') && (start == 0)) { + start = 1; + src++; + continue; + } + // look for end + if ((*src == '\"') && (start == 1)) { + *dst = 0; // terminate the string + break; + } + if (start == 1) { + *dst = *src; + dst++; + } + src++; + } +} + +//****************************************************************************** +void RPC_call_test(void) { + int doubleQuoteFound; + char doubleQuoteStr[64]; + char *request = "/Logging/AppendMissionCmd \"BMP280 InitStart 1\""; + + // scan through arguments, see if there is a double quote for a string + // argument + doubleQuoteFound = CheckForDoubleQuote(request); + if (doubleQuoteFound) { + ExtractDoubleQuoteStr(request, doubleQuoteStr); + } +} + +//****************************************************************************** +void RPC_call(char *request, char *reply) { + const char slash[2] = "/"; + const char space[2] = " "; + char *objectName; + char *methodName; + char doubleQuoteStr[128]; + char requestCpy[256]; + char *token; + int argIndex; + int resultIndex; + int doubleQuoteFound; + struct RPC_registeredProcedure *procedurePtr; + + // clear out the reply + reply[0] = 0; + // copy the request for scanning and extraction later + strcpy(requestCpy, request); + // check for beginning forward slash + if (request[0] != '/') { + return; + } + // check for only a forward slash + if (request[0] == '/' && request[1] == 0) { + SendCommandList(reply); + return; + } + strcat(request, " "); + // get the object name + token = strtok(request, slash); + // token = GetToken(request, tokenBuffer, 1, '/'); + objectName = token; + if (objectName == NULL) + return; // must have an object name + // get the method name + token = strtok(NULL, space); + methodName = token; + if (methodName == NULL) + return; // must have a method name + + // scan through arguments, see if there is a double quote for a string + // argument + doubleQuoteFound = CheckForDoubleQuote(requestCpy); + + if (doubleQuoteFound == 0) { + // walk through arguments + argIndex = 0; + token = strtok(NULL, space); + while (token != NULL) { + // save this arg in array + strcpy(args[argIndex++], token); + // read next token arg if any + token = strtok(NULL, space); + } + // terminate the end of the string array with an empty string + strcpy(args[argIndex], "\0"); + strcpy(results[0], "\0"); + } else { + // grab out the double quote string + ExtractDoubleQuoteStr(requestCpy, doubleQuoteStr); + argIndex = 0; + // token = strtok(NULL, quote); + strcpy(args[argIndex++], doubleQuoteStr); + } + + // + // alias the MAX30001 and MAX30003 names + // + if (strcmp(objectName, MAX30003_NAME) == 0) { + strcpy(objectName, MAX30001_NAME); + } + + procedurePtr = RPC_lookup(objectName, methodName); + if (procedurePtr != NULL) { + // printf("RPC_call: %s processing\n",requestCpy); + procedurePtr->func(args, results); + } else { + printf("RPC_call: %s not found\n", requestCpy); + // printf("Unable to lookup %s %s", objectName, methodName); + } + + // loop while (if) there are results to return + resultIndex = 0; + strcpy(reply, "\0"); + while (results[resultIndex][0] != '\0') { + strcat(reply, results[resultIndex++]); + strcat(reply, " "); + } + strcat(reply, "\r\n"); +} + +//****************************************************************************** +void RPC_ProcessCmds(char *cmds) { + char cmd[32 * 32]; + char *ptrCmds; + char reply[512]; + ptrCmds = cmds; + + while (*ptrCmds != 0) { + ptrCmds = ParseUntilCRLF(ptrCmds, cmd, sizeof(cmd)); + if (*cmd != 0) { + RPC_call(cmd, reply); + } + } +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/RpcServer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/RpcServer.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _RPCSERVER_H_ +#define _RPCSERVER_H_ + +#include "mbed.h" +#include "RpcFifo.h" +#include "Device_Logging.h" + +/** +* @brief Reads the Version of the HSP FCache_Writel +*/ +int System_ReadVer(char argStrs[32][32], char replyStrs[32][32]); +/** +* @brief Reads the built time of the RPC FW +*/ +int System_ReadBuildTime(char argStrs[32][32], char replyStrs[32][32]); + +void RPC__init(void); +void RPC__call(char *request, char *reply); +fifo_t *GetUSBIncomingFifo(void); +fifo_t *GetStreamOutFifo(void); +/** +* @brief Batch process RPC commands +*/ +void RPC_ProcessCmds(char *cmds); +/** +* @brief Initialize the RPC server with all of the commands that it supports +*/ +void RPC_init(void); +/** +* @brief Initialize the RPC server with all of the commands that it supports +*/ +void RPC_call(char *request, char *reply); + +#endif // _RPCSERVER_H_ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/Streaming.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/Streaming.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "RpcServer.h" +#include "RpcFifo.h" +#include "Streaming.h" +#include "Peripherals.h" +#include "MAX30001.h" +#include "Test_MAX30001.h" +#include "Peripherals.h" + +bool streaming = FALSE; +bool dataLogging = FALSE; + +/** +* @brief Encodes a 0x55 0xAA signature and a simple checksum to the id byte in +* the 32 bit field +* @param id Streaming ID +*/ +uint32_t StreamIdChecksumCalculate(uint32_t id) { + uint32_t sum; + uint32_t calculated; + sum = 0x55; + sum += 0xAA; + sum += id; + sum &= 0xFF; + sum = sum << 8; + calculated = 0x55AA0000 + sum + id; + return calculated; +} + +/** +* @brief Creates a packet that will be streamed via USB or saved into flash +* datalog memory +* @brief the packet created will be inserted into a fifo to be streamed at a +* later time +* @param id Streaming ID +* @param buffer Pointer to a uint32 array that contains the data to include in +* the packet +* @param number Number of elements in the buffer +*/ +void StreamPacketUint32(uint32_t id, uint32_t *buffer, uint32_t number) { + uint32_t checksumId; + if (streaming == TRUE || dataLogging == TRUE) { + checksumId = StreamIdChecksumCalculate(id); + StreamFifoId(checksumId); + StreamFifoTimeStamp(); + StreamFifoLength(number); + StreamFifoUint32Array(buffer, number); + } + if (testing_max30001 == 1) { + if (id == MAX30001_DATA_ECG) + testing_ecg_flags[TESTING_ECG_FLAG] = 1; + if (id == MAX30001_DATA_BIOZ) + testing_ecg_flags[TESTING_BIOZ_FLAG] = 1; + if (id == MAX30001_DATA_PACE) + testing_ecg_flags[TESTING_PACE_FLAG] = 1; + if (id == MAX30001_DATA_RTOR) + testing_ecg_flags[TESTING_RTOR_FLAG] = 1; + } +} + +/** +* @brief Insert a buffer into the out going fifo +* @param buffer Array of uint32 to send to the fifo +* @param len Length of the array +*/ +int StreamFifoUint32Array(uint32_t buffer[], uint32_t len) { + int status; + uint32_t i; + for (i = 0; i < len; i++) { + status = fifo_put32(GetStreamOutFifo(), buffer[i]); + if (status == -1) { + printf("FIFO_OF!"); + fflush(stdout); + while (1) + ; + } + } + return 0; +} + +/** +* @brief Insert a timestamp into the out going fifo +*/ +int StreamFifoTimeStamp(void) { + int status; + // uint32_t timer = timestamp_GetCurrent(); //RTC_GetVal(); + uint32_t timer = (uint32_t)Peripherals::timestampTimer()->read_us(); + status = fifo_put32(GetStreamOutFifo(), timer); + if (status == -1) { + printf("FIFO_OF!"); + fflush(stdout); + while (1) + ; + } + return 0; +} + +/** +* @brief Insert a packet id into the out going fifo +* @param id The uint32 packet id +*/ +int StreamFifoId(uint32_t id) { + int status; + status = fifo_put32(GetStreamOutFifo(), id); + if (status == -1) { + printf("FIFO_OF!"); + fflush(stdout); + while (1) + ; + } + return 0; +} + +/** +* @brief Insert a length value into the out going fifo +* @param length A uint32 number representing a length +*/ +int StreamFifoLength(uint32_t length) { + int status; + status = fifo_put32(GetStreamOutFifo(), length); + if (status == -1) { + printf("FIFO_OF!"); + fflush(stdout); + while (1) + ; + } + return 0; +} + +/** +* @brief Return a value that indicates if the system is streaming data +* @returns Returns a one or zero value +*/ +uint8_t IsStreaming(void) { return streaming; } + +/** +* @brief Set a flag to indicate if streaming is enabled +* @param state A one or zero value +*/ +void SetStreaming(uint8_t state) { streaming = state; } + +/** +* @brief Set a flag to indicate if datalogging is enabled +* @param state A one or zero value +*/ +void SetDataLoggingStream(uint8_t state) { dataLogging = state; } +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/Streaming.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/Streaming.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _STREAMING_H_ +#define _STREAMING_H_ + +#include "mbed.h" + +#define PACKET_LIS2DH 0x20 + +#define PACKET_MAX30205_TEMP_TOP 0x40 +#define PACKET_MAX30205_TEMP_BOTTOM 0x50 +#define PACKET_BMP280_PRESSURE 0x60 +#define PACKET_LSM6DS3_ACCEL 0x70 +#define PACKET_MAX30205_TEMP 0x80 +#define PACKET_NOP 0x90 + +/** +* @brief Creates a packet that will be streamed via USB or saved into flash +* datalog memory +* @brief the packet created will be inserted into a fifo to be streamed at a +* later time +* @param id Streaming ID +* @param buffer Pointer to a uint32 array that contains the data to include in +* the packet +* @param number Number of elements in the buffer +*/ +void StreamPacketUint32(uint32_t id, uint32_t *buffer, uint32_t number); +/** +* @brief Insert a buffer into the out going fifo +* @param buffer Array of uint32 to send to the fifo +* @param len Length of the array +*/ +int StreamFifoUint32Array(uint32_t buffer[], uint32_t len); +/** +* @brief Insert a timestamp into the out going fifo +*/ +int StreamFifoTimeStamp(void); +/** +* @brief Insert a packet id into the out going fifo +* @param id The uint32 packet id +*/ +int StreamFifoId(uint32_t id); +/** +* @brief Return a value that indicates if the system is streaming data +* @returns Returns a one or zero value +*/ +uint8_t IsStreaming(void); +/** +* @brief Set a flag to indicate if streaming is enabled +* @param state A one or zero value +*/ +void SetStreaming(uint8_t state); +/** +* @brief Set a flag to indicate if datalogging is enabled +* @param state A one or zero value +*/ +void SetDataLoggingStream(uint8_t state); +/** +* @brief Insert a length value into the out going fifo +* @param length A uint32 number representing a length +*/ +int StreamFifoLength(uint32_t length); + +#endif // _STREAMING_H_ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/StringHelper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/StringHelper.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,241 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "mbed.h" +#include "StringHelper.h" + +/** +* @brief Process an array of hex alpha numeric strings representing arguments of +* type uint8 +* @param args Array of strings to process +* @param argsUintPtr Pointer of uint8 to save converted arguments +* @param numberOf Number of strings to convert +*/ +void ProcessArgs(char args[32][32], uint8_t *argsUintPtr, int numberOf) { + int i; + int val; + for (i = 0; i < numberOf; i++) { + sscanf(args[i], "%x", &val); + argsUintPtr[i] = (uint8_t)val; + } +} + +/** +* @brief Process an array of hex alpha numeric strings representing arguments of +* type uint32 +* @param args Array of strings to process +* @param argsUintPtr Pointer of uint32 to save converted arguments +* @param numberOf Number of strings to convert +*/ +void ProcessArgs32(char args[32][32], uint32_t *argsUintPtr, int numberOf) { + int i; + int val; + for (i = 0; i < numberOf; i++) { + sscanf(args[i], "%x", &val); + argsUintPtr[i] = val; + } +} + +/** +* @brief Process an array of decimal numeric strings representing arguments of +* type uint32 +* @param args Array of strings to process +* @param argsUintPtr Pointer of uint32 to save converted arguments +* @param numberOf Number of strings to convert +*/ +void ProcessArgs32Dec(char args[32][32], uint32_t *argsUintPtr, int numberOf) { + int i; + int val; + for (i = 0; i < numberOf; i++) { + sscanf(args[i], "%d", &val); + argsUintPtr[i] = val; + } +} + +/** +* @brief Parse a single string in decimal format to a uint32 number +* @param str String to process +* @returns Returns the converted number of type uint32 +*/ +uint32_t ParseAsciiDecU32(char *str) { + uint32_t val; + sscanf(str, "%d", &val); + return val; +} + +/** +* @brief Parse a single string in hex format to a uint32 number +* @param str String to process +* @returns Returns the converted number of type uint32 +*/ +uint32_t ParseAsciiHexU32(char *str) { + uint32_t val; + sscanf(str, "%x", &val); + return val; +} + +/** +* @brief Process a string that is "embedded" within another string using the /" +* delimiters +* @brief Extract the string +* @param str String to process +* @returns Returns the string +*/ +void ProcessString(char args[32][32], uint8_t *str, int numberOf) { + int i; + int start; + uint8_t *ptr; + uint8_t *strPtr; + ptr = (uint8_t *)args; + strPtr = str; + start = 0; + for (i = 0; i < numberOf; i++) { + if ((start == 0) && (*ptr == '/"')) { + start = 1; + ptr++; + continue; + } + if ((start == 1) && (*ptr == '/"')) { + break; + } + if (start == 1) { + *strPtr = *ptr; + strPtr++; + } + ptr++; + } + // terminate the string + *strPtr = 0; +} + +/** +* @brief Parse an incoming string until a CRLF is encountered, dst will contain +* the parsed string +* @param src source string to process +* @param dst destination string to contain the parsed incoming string +* @param length length of incoming src string +* @returns updated pointer in src string +*/ +char *ParseUntilCRLF(char *src, char *dst, int length) { + int i; + char *srcPtr; + + srcPtr = src; + i = 0; + *dst = 0; + while ((*srcPtr != 0) && (*srcPtr != 13)) { + dst[i] = *srcPtr; + i++; + if (i >= length) + break; + srcPtr++; + } + if (*srcPtr == 13) + srcPtr++; + if (*srcPtr == 10) + srcPtr++; + dst[i] = 0; // terminate the string + return srcPtr; +} + +/** +* @brief Parse an incoming string hex value into an 8-bit value +* @param str string to process +* @returns 8-bit byte that is parsed from the string +*/ +uint8_t StringToByte(char str[32]) { + int val; + uint8_t byt; + sscanf(str, "%x", &val); + byt = (uint8_t)val; + return byt; +} + +/** +* @brief Parse an incoming string hex value into 32-bit value +* @param str string to process +* @returns 32-bit value that is parsed from the string +*/ +uint32_t StringToInt(char str[32]) { + int val; + uint32_t byt; + sscanf(str, "%x", &val); + byt = (uint32_t)val; + return byt; +} + +/** +* @brief Format a binary 8-bit array into a string +* @param uint8Ptr byte buffer to process +* @param numberOf number of bytes in the buffer +* @param reply an array of strings to place the converted array values into +*/ +void FormatReply(uint8_t *uint8Ptr, int numberOf, char reply[32][32]) { + int i; + for (i = 0; i < numberOf; i++) { + sprintf(reply[i], "%02X", uint8Ptr[i]); + } + strcpy(reply[i], "\0"); +} + +/** +* @brief Format a binary 32-bit array into a string +* @param uint32Ptr 32-bit value buffer to process +* @param numberOf number of values in the buffer +* @param reply an array of strings to place the converted array values into +*/ +void FormatReply32(uint32_t *uint32Ptr, int numberOf, char reply[32][32]) { + int i; + for (i = 0; i < numberOf; i++) { + sprintf(reply[i], "%02X", uint32Ptr[i]); + } + strcpy(reply[i], "\0"); +} + +/** +* @brief Format a binary 8-bit array into a string +* @param data 8-bit value buffer to process +* @param length number of values in the buffer +* @param str output string buffer +* @return output string +*/ +char *BytesToHexStr(uint8_t *data, uint32_t length, char *str) { + uint32_t i; + char tmpStr[8]; + str[0] = 0; + for (i = 0; i < length; i++) { + sprintf(tmpStr, "%02X ", data[i]); + strcat(str, tmpStr); + } + return str; +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/StringHelper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/StringHelper.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _STRINGHELPER_H_ +#define _STRINGHELPER_H_ + +#include "mbed.h" + +/** +* @brief Process an array of hex alpha numeric strings representing arguments of +* type uint8 +* @param args Array of strings to process +* @param argsUintPtr Pointer of uint8 to save converted arguments +* @param numberOf Number of strings to convert +*/ +void ProcessArgs(char args[32][32], uint8_t *argsUintPtr, int numberOf); +/** +* @brief Format a binary 8-bit array into a string +* @param uint8Ptr byte buffer to process +* @param numberOf number of bytes in the buffer +* @param reply an array of strings to place the converted array values into +*/ +void FormatReply(uint8_t *uint8Ptr, int numberOf, char reply[32][32]); +/** +* @brief Process an array of hex alpha numeric strings representing arguments of +* type uint32 +* @param args Array of strings to process +* @param argsUintPtr Pointer of uint32 to save converted arguments +* @param numberOf Number of strings to convert +*/ +void ProcessArgs32(char args[32][32], uint32_t *argsUintPtr, int numberOf); +/** +* @brief Process an array of decimal numeric strings representing arguments of +* type uint32 +* @param args Array of strings to process +* @param argsUintPtr Pointer of uint32 to save converted arguments +* @param numberOf Number of strings to convert +*/ +void ProcessArgs32Dec(char args[32][32], uint32_t *argsUintPtr, int numberOf); +/** +* @brief Format a binary 32-bit array into a string +* @param uint32Ptr 32-bit value buffer to process +* @param numberOf number of values in the buffer +* @param reply an array of strings to place the converted array values into +*/ +void FormatReply32(uint32_t *uint32Ptr, int numberOf, char reply[32][32]); +/** +* @brief Parse an incoming string hex value into an 8-bit value +* @param str string to process +* @returns 8-bit byte that is parsed from the string +*/ +uint8_t StringToByte(char str[32]); +/** +* @brief Parse an incoming string hex value into 32-bit value +* @param str string to process +* @returns 32-bit value that is parsed from the string +*/ +uint32_t StringToInt(char str[32]); +/** +* @brief Parse a single string in decimal format to a uint32 number +* @param str String to process +* @returns Returns the converted number of type uint32 +*/ +uint32_t ParseAsciiDecU32(char *str); +/** +* @brief Parse a single string in hex format to a uint32 number +* @param str String to process +* @returns Returns the converted number of type uint32 +*/ +uint32_t ParseAsciiHexU32(char *str); +/** +* @brief Format a binary 8-bit array into a string +* @param data 8-bit value buffer to process +* @param length number of values in the buffer +* @param str output string buffer +* @return output string +*/ +char *BytesToHexStr(uint8_t *data, uint32_t length, char *str); +/** +* @brief Parse an incoming string until a CRLF is encountered, dst will contain +* the parsed string +* @param src source string to process +* @param dst destination string to contain the parsed incoming string +* @param length length of incoming src string +* @returns updated pointer in src string +*/ +char *ParseUntilCRLF(char *src, char *dst, int length); + +#endif // _STRINGHELPER_H_ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/StringInOut.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/StringInOut.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "mbed.h" +//#include "USBSerial.h" +#include "RpcFifo.h" +#include "RpcServer.h" +#include "StringInOut.h" +#include "Peripherals.h" + +/// a running index that keeps track of where an incoming string has been +/// buffered to +static int lineBuffer_index = 0; +/// a flag that keeps track of the state of accumulating a string +static int getLine_State = GETLINE_WAITING; + +/** +* @brief Place incoming USB characters into a fifo +* @param data_IN buffer of characters +* @param len length of data +*/ +int fifoIncomingChars(uint8_t data_IN[], unsigned int len) { + int i; + for (i = 0; i < len; i++) { + fifo_put8(GetUSBIncomingFifo(), data_IN[i]); + } + return 0; +} + +/** +* @brief Check the USB incoming fifo to see if there is data to be read +* @return 1 if there is data to be read, 0 if data is not available +*/ +int isReadReady(void) { + if (fifo_empty(GetUSBIncomingFifo()) == 0) + return 1; + return 0; +} + +/** +* @brief Clear the incoming USB read fifo +*/ +void clearOutReadFifo(void) { fifo_clear(GetUSBIncomingFifo()); } + +/** +* @brief Block until a character can be read from the USB +* @return the character read +*/ +char getch(void) { + uint8_t ch; + // block until char is ready + while (isReadReady() == 0) { + } + // read a char from buffer + fifo_get8(GetUSBIncomingFifo(), &ch); + return ch; +} + +/** +* @brief Place incoming USB characters into a fifo +* @param lineBuffer buffer to place the incoming characters +* @param bufferLength length of buffer +* @return GETLINE_WAITING if still waiting for a CRLF, GETLINE_DONE +*/ +int getLine(char *lineBuffer, int bufferLength) { + uint8_t ch; + + //USBSerial *serial = Peripherals::usbSerial(); + if (getLine_State == GETLINE_DONE) { + getLine_State = GETLINE_WAITING; + } +// if (serial->available() != 0) { +// ch = serial->_getc(); + if (1) { + ch = 1; + if (ch != 0x0A && ch != 0x0D) { + lineBuffer[lineBuffer_index++] = ch; + } + if (ch == 0x0D) { + lineBuffer[lineBuffer_index++] = 0; + lineBuffer_index = 0; + getLine_State = GETLINE_DONE; + } + if (lineBuffer_index > bufferLength) { + lineBuffer[bufferLength - 1] = 0; + getLine_State = GETLINE_DONE; + } + } + return getLine_State; +} + +/** +* @brief Block until a fixed number of characters has been accumulated from the +* incoming USB +* @param lineBuffer buffer to place the incoming characters +* @param maxLength length of buffer +*/ +void getStringFixedLength(uint8_t *lineBuffer, int maxLength) { + uint8_t ch; + int index = 0; + // block until maxLength is captured + while (1) { + ch = getch(); + lineBuffer[index++] = ch; + if (index == maxLength) + return; + } +} + +/** +* @brief Output a string out the USB serial port +* @param str output this str the USB channel +*/ +int putStr(const char *str) { + //Peripherals::usbSerial()->printf("%s", str); // fflush(stdout); + + // uint8_t *ptr; + // uint8_t buffer[256]; + // int index = 0; + /* int length; + ptr = (uint8_t *)str; + length = strlen(str); + + Peripherals::usbSerial()->writeBlock(ptr,length); */ + return 0; +} + +/** +* @brief Outut an array of bytes out the USB serial port +* @param data buffer to output +* @param length length of buffer +*/ +int putBytes(uint8_t *data, uint32_t length) { + int sendThis = 64; + int sent = 0; + int thisLeft; + uint8_t *ptr = data; + if (length < 64) + sendThis = length; + do { + //Peripherals::usbSerial()->writeBlock(ptr, sendThis); + sent += sendThis; + ptr += sendThis; + thisLeft = length - sent; + sendThis = 64; + if (thisLeft < 64) + sendThis = thisLeft; + } while (sent != length); + return 0; +} + +/** +* @brief Outut 256 byte blocks out the USB serial using writeBlock bulk +* transfers +* @param data buffer of blocks to output +* @param length length of 256-byte blocks +*/ +int putBytes256Block(uint8_t *data, int numberBlocks) { + int i; + uint8_t *ptr; + ptr = data; + const int BLOCK_SIZE = 32; + const int FLASH_PAGE_SIZE = 256; + for (i = 0; i < numberBlocks * (FLASH_PAGE_SIZE / BLOCK_SIZE); i++) { + //Peripherals::usbSerial()->writeBlock(ptr, BLOCK_SIZE); + ptr += BLOCK_SIZE; + } + return 0; +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/RpcServer/StringInOut.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/RpcServer/StringInOut.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _STRINGINOUT_H_ +#define _STRINGINOUT_H_ + +#include "mbed.h" +//#include "USBSerial.h" + +/// indicates that a string up to a CRLF is being accumulated +#define GETLINE_WAITING 1 +/// indicates that a string is being processes +#define GETLINE_PROCESSING 2 +/// indicates that a CRLF string has been buffered and can be processed +#define GETLINE_DONE 3 + +/** +* @brief Clear the incoming USB read fifo +*/ +void clearOutReadFifo(void); +/** +* @brief Block until a character can be read from the USB +* @return the character read +*/ +char getch(void); +/** +* @brief Place incoming USB characters into a fifo +* @param lineBuffer buffer to place the incoming characters +* @param bufferLength length of buffer +* @return GETLINE_WAITING if still waiting for a CRLF, GETLINE_DONE +*/ +int getLine(char *lineBuffer, int bufferLength); +/** +* @brief Block until a fixed number of characters has been accumulated from the +* incoming USB +* @param lineBuffer buffer to place the incoming characters +* @param maxLength length of buffer +*/ +void getStringFixedLength(uint8_t *lineBuffer, int maxLength); +/** +* @brief Output a string out the USB serial port +* @param str output this str the USB channel +*/ +int putStr(const char *str); +/** +* @brief Place incoming USB characters into a fifo +* @param data_IN buffer of characters +* @param len length of data +*/ +int fifoIncomingChars(uint8_t data_IN[], unsigned int len); +/** +* @brief Outut an array of bytes out the USB serial port +* @param data buffer to output +* @param length length of buffer +*/ +int putBytes(uint8_t *data, uint32_t length); +/** +* @brief Outut 256 byte blocks out the USB serial using writeBlock bulk +* transfers +* @param data buffer of blocks to output +* @param length length of 256-byte blocks +*/ +int putBytes256Block(uint8_t *data, int numberBlocks); + +#endif // _STRINGINOUT_H_ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/System/Peripherals.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/System/Peripherals.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "Peripherals.h" + +//è, meglio cosìUSBSerial *Peripherals::mUSBSerial = NULL; +MAX30001 *Peripherals::mMAX30001 = NULL; +HspLed *Peripherals::mHspLed = NULL; +Timer *Peripherals::mTimestampTimer = NULL; +S25FS512 *Peripherals::mS25FS512 = NULL; +PushButton *Peripherals::mPushButton = NULL; +SDFileSystem *Peripherals::mSD = NULL; +DigitalIn *Peripherals::mSDDetect = NULL;
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/System/Peripherals.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/System/Peripherals.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _PERIPHERALS_H_ +#define _PERIPHERALS_H_ + +#include "mbed.h" +//#include "USBSerial.h" +#include "HspLed.h" +#include "MAX30001.h" +#include "S25FS512.h" +#include "PushButton.h" +#include "SDFileSystem.h" +/** +* This static class is used as a central locatoin for all devices on the HSP platform +* it gives (in-effect) a singleton interface for each device so that anywhere in code +* one can reference on of these devices +*/ +class Peripherals { +public: + //static USBSerial *setUSBSerial(USBSerial * device) { mUSBSerial = device; return device; } + //static USBSerial *usbSerial(void) { return mUSBSerial; } + + static HspLed *hspLed(void) { return mHspLed; } + static HspLed *setHspLed(HspLed *device) { mHspLed = device; return device; } + + static MAX30001 *max30001(void) { return mMAX30001; } + static MAX30001 *setMAX30001(MAX30001 *device) { mMAX30001 = device; return device; } + + static Timer *timestampTimer(void) { return mTimestampTimer; } + static Timer *setTimestampTimer(Timer *timer) { mTimestampTimer = timer; return timer; } + + static S25FS512 *s25FS512(void) { return mS25FS512; } + static S25FS512 *setS25FS512(S25FS512 *s25FS512) { mS25FS512 = s25FS512; return s25FS512; } + + static PushButton *pushButton(void) { return mPushButton; } + static PushButton *setPushButton(PushButton *pushButton) { mPushButton = pushButton; return pushButton; } + + static SDFileSystem *sdFS(void) { return mSD; } + static SDFileSystem *setSdFS(SDFileSystem *SD) { mSD = SD; return SD; } + + static DigitalIn *SDDetect(void) { return mSDDetect; } + static DigitalIn *setSDDetect(DigitalIn *SDDetect) { mSDDetect = SDDetect; return SDDetect; } + +private: + //static USBSerial *mUSBSerial; + static MAX30001 *mMAX30001; + static HspLed *mHspLed; + static Serial *mSerial; + static Timer *mTimestampTimer; + static S25FS512 *mS25FS512; + static PushButton *mPushButton; + static SDFileSystem *mSD; + static DigitalIn *mSDDetect; +}; + +#endif // _PERIPHERALS_H_ + +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/System/System.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/System/System.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "mbed.h" + +//****************************************************************************** +void I2CM_Init_Reset(uint8_t index, int speed) { + mxc_i2cm_regs_t *regs = MXC_I2CM_GET_I2CM(index); + /* reset module */ + regs->ctrl = MXC_F_I2CM_CTRL_MSTR_RESET_EN; + regs->ctrl = 0; + /* enable tx_fifo and rx_fifo */ + regs->ctrl |= (MXC_F_I2CM_CTRL_TX_FIFO_EN | MXC_F_I2CM_CTRL_RX_FIFO_EN); +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/System/System.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/System/System.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _SYSTEM_H_ +#define _SYSTEM_H_ + +/** +* This issues a reset to the I2C Peripheral +*/ +void I2CM_Init_Reset(uint8_t index, int speed); + +#endif // _SYSTEM_H_ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Test/Test_MAX30001.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Test/Test_MAX30001.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "Test_MAX30001.h" +#include "Test_Utilities.h" + +uint32_t testing_max30001 = 0; +uint32_t testing_ecg_flags[4]; + +//****************************************************************************** +void test_MAX30001(void (*outputString)(const char *)) { + int totalPass = 1; + int pass; + uint32_t foundEcg = 0; + uint32_t foundBioz = 0; + uint32_t foundPace = 0; + uint32_t foundRtoR = 0; + uint32_t id; + char str2[128]; + int partVersion; // 0 = 30004 + // 1 = 30001 + // 2 = 30002 + // 3 = 30003 + Timer timer; + MAX30001 *max30001; + max30001 = Peripherals::max30001(); + + // read the id + max30001->max30001_reg_read(MAX30001::INFO, &id); + // read id twice because it needs to be read twice + max30001->max30001_reg_read(MAX30001::INFO, &id); + partVersion = id >> 12; + partVersion = partVersion & 0x3; + + // display header + if (partVersion == 0) + outputString("Testing MAX30004|"); + if (partVersion == 1) { + outputString("Testing MAX30001|"); + outputString("Testing ECG, RtoR, BioZ, PACE|"); + } + if (partVersion == 2) + outputString("Testing MAX30002|"); + if (partVersion == 3) { + outputString("Testing MAX30003|"); + outputString("Only Testing ECG and RtoR|"); + } + sprintf(str2, "Device ID = 0x%06X|", id); + outputString(str2); + + // clear testing flags + testing_ecg_flags[TESTING_ECG_FLAG] = 0; + testing_ecg_flags[TESTING_BIOZ_FLAG] = 0; + testing_ecg_flags[TESTING_PACE_FLAG] = 0; + testing_ecg_flags[TESTING_RTOR_FLAG] = 0; + + // start streams + testing_max30001 = 1; + if (partVersion == 1) + outputString("Start Streaming ECG, RtoR, PACE, BIOZ, CAL enabled, " + "verifying streams...|"); + if (partVersion == 3) + outputString( + "Start Streaming ECG, RtoR, CAL enabled, verifying streams...|"); + // max30001_CAL_InitStart(0b1, 0b1, 0b1, 0b011, 0x7FF, 0b0); + max30001->max30001_CAL_InitStart(0b1, 0b1, 0b1, 0b011, 0x7FF, 0b0); + max30001->max30001_ECG_InitStart(0b1, 0b1, 0b1, 0b0, 0b10, 0b11, 0x1F, 0b00, + 0b00, 0b0, 0b01); + if (partVersion == 1) + max30001->max30001_PACE_InitStart(0b1, 0b0, 0b0, 0b1, 0x0, 0b0, 0b00, 0b0, + 0b0); + if (partVersion == 1) + max30001->max30001_BIOZ_InitStart(0b1, 0b1, 0b1, 0b10, 0b11, 0b00, 7, 0b0, + 0b010, 0b0, 0b10, 0b00, 0b00, 2, 0b0, + 0b111, 0b0000, 0b0000); + max30001->max30001_RtoR_InitStart(0b1, 0b0011, 0b1111, 0b00, 0b0011, 0b000001, + 0b00, 0b000, 0b01); + max30001->max30001_Rbias_FMSTR_Init(0b01, 0b10, 0b1, 0b1, 0b00); + max30001->max30001_synch(); + + // look for each stream + timer.start(); + while (1) { + if ((foundEcg == 0) && (testing_ecg_flags[TESTING_ECG_FLAG] == 1)) { + foundEcg = 1; + outputString("ECG Stream: PASS|"); + } + if ((foundBioz == 0) && (testing_ecg_flags[TESTING_BIOZ_FLAG] == 1)) { + foundBioz = 1; + outputString("Bioz Stream: PASS|"); + } + if ((foundPace == 0) && (testing_ecg_flags[TESTING_PACE_FLAG] == 1)) { + foundPace = 1; + outputString("PACE Stream: PASS|"); + } + if ((foundRtoR == 0) && (testing_ecg_flags[TESTING_RTOR_FLAG] == 1)) { + foundRtoR = 1; + outputString("RtoR Stream: PASS|"); + } + if ((foundEcg == 1) && (foundBioz == 1) && (foundPace == 1) && + (foundRtoR == 1) && (partVersion == 1)) { + break; + } + if ((foundEcg == 1) && (foundRtoR == 1) && (partVersion == 3)) { + break; + } + if (timer.read() >= TESTING_MAX30001_TIMEOUT_SECONDS) { + break; + } + } + timer.stop(); + if (foundEcg == 0) { + outputString("ECG Stream: FAIL|"); + totalPass &= pass; + } + if ((foundBioz == 0) && (partVersion == 1)) { + outputString("Bioz Stream: FAIL|"); + totalPass &= pass; + } + if ((foundPace == 0) && (partVersion == 1)) { + outputString("PACE Stream: FAIL|"); + totalPass &= pass; + } + if (foundRtoR == 0) { + outputString("RtoR Stream: FAIL|"); + totalPass &= pass; + } + + // stop all streams + max30001->max30001_Stop_ECG(); + if (partVersion == 1) + max30001->max30001_Stop_PACE(); + if (partVersion == 1) + max30001->max30001_Stop_BIOZ(); + max30001->max30001_Stop_RtoR(); + testing_max30001 = 0; + // final results + outputString("Result: "); + _printPassFail(totalPass, 0, outputString); +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Test/Test_MAX30001.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Test/Test_MAX30001.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _TEST_MAX30001_H_ +#define _TEST_MAX30001_H_ + +#include "mbed.h" +#include "MAX30001.h" +#include "Peripherals.h" + +#define TESTING_ECG_FLAG 0 +#define TESTING_BIOZ_FLAG 1 +#define TESTING_PACE_FLAG 2 +#define TESTING_RTOR_FLAG 3 + +#define TESTING_MAX30001_TIMEOUT_SECONDS 10 + +extern uint32_t testing_max30001; +extern uint32_t testing_ecg_flags[4]; + +/** +* @brief Selftest the MAX30001 and output the results as strings using the pointer function +* @param outputString Pointer to the function used to output the test results +*/ +void test_MAX30001(void (*outputString)(const char *)); + +#endif /* _TEST_MAX30101_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Test/Test_S25FS512.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Test/Test_S25FS512.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "Test_S25FS512.h" +#include "Test_Utilities.h" + +//****************************************************************************** +void test_S25FS512(void (*outputString)(const char *)) { + char tempStr[32]; + uint8_t page[264]; + int totalPass = 1; + int pass; + int status; + int i; + uint8_t data[128]; + S25FS512 *s25FS512; + + s25FS512 = Peripherals::s25FS512(); + + // display header + outputString("Testing S25FS512|"); + + // read id test + s25FS512->readIdentification(data, sizeof(data)); + s25FS512->readIdentification(data, sizeof(data)); + if ((data[1] == 0x01) && (data[2] == 0x02) && (data[3] == 0x19) && + (data[4] == 0x4D)) { + sprintf(tempStr, "Read ID: Pass "); + outputString(tempStr); + } else { + sprintf(tempStr, "Read ID: Fail "); + outputString(tempStr); + totalPass = 0; + } + sprintf(tempStr, "(%02X%02X%02X%02X)|", data[1], data[2], data[3], data[4]); + outputString(tempStr); + + if (totalPass == 1) { + // format sector 0 + outputString("Formatting Sector 0, "); + s25FS512->sectorErase_Helper(0); + + // verify format sector 0 + outputString("Verifying Format of Sector 0: "); + s25FS512->readPages_Helper(0, 0, page, 0); + pass = s25FS512->isPageEmpty(page); + _printPassFail(pass, 1, outputString); + totalPass &= pass; + + // fill page with pattern + for (i = 0; i < 256; i++) { + page[i] = i; + } + // write to page 0 + outputString("Writing Page 0 to pattern, "); + s25FS512->writePage_Helper(0, page, 0); + // clear pattern in memory + for (i = 0; i < 256; i++) { + page[i] = 0x00; + } + // read back page and verify + outputString("Read Page Verify: "); + s25FS512->readPages_Helper(0, 0, page, 0); + // compare memory for pattern + pass = 1; + for (i = 0; i < 256; i++) { + if (page[i] != i) + pass = 0; + } + _printPassFail(pass, 1, outputString); + totalPass &= pass; + + // format sector 0 to clean up after tests + s25FS512->sectorErase_Helper(0); + } else { + outputString("Read Id Failed, Skipping rest of test|"); + } + + // final results + outputString("Result: "); + _printPassFail(totalPass, 0, outputString); +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Test/Test_S25FS512.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Test/Test_S25FS512.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _TEST_S25FS512_H_ +#define _TEST_S25FS512_H_ + +#include "mbed.h" +#include "S25FS512.h" +#include "Peripherals.h" + +/** +* @brief Selftest the S25FS512 and output the results as strings using the pointer function +* @param outputString Pointer to the function used to output the test results +*/ +void test_S25FS512(void (*outputString)(const char *)); + +#endif /* _TEST_S25FS512_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Test/Test_Utilities.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Test/Test_Utilities.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include "Test_Utilities.h" + +//****************************************************************************** +void _printPassFail(int status, int newLine, void (*outputString)(char const *)) { + if (status == 1) { + outputString("PASS"); + } else { + outputString("FAIL"); + } + if (newLine == 1) { + outputString("|"); + } +} +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Test/Test_Utilities.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Test/Test_Utilities.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _TEST_UTILITIES_H_ +#define _TEST_UTILITIES_H_ + +#include "mbed.h" + +/** +* Function that will output a pass/fail formated string based on the incoming status value +* @param status Value that indicated pass or fail status +* @param newLine Should this call output a new line +* @param outputString Pointer to a function that will do the actual outputting of the string +*/ +void _printPassFail(int status, int newLine, void (*outputString)(const char *)); + +#endif /* _TEST_UTILITIES_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Test/Testing_RPC.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Test/Testing_RPC.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#include <stdint.h> +#include "StringHelper.h" +#include "Test_MAX30001.h" +#include "Test_S25FS512.h" +#include "StringInOut.h" + +void outputTestResultString(const char *resultStr); + +//****************************************************************************** +int Test_S25FS512(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + test_S25FS512(outputTestResultString); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +//****************************************************************************** +int Test_MAX30001(char argStrs[32][32], char replyStrs[32][32]) { + uint32_t reply[1]; + test_MAX30001(outputTestResultString); + reply[0] = 0x80; + FormatReply32(reply, sizeof(reply) / sizeof(uint32_t), replyStrs); + return 0; +} + +void outputTestResultString(const char *resultStr) { putStr(resultStr); } +
diff -r 21b02b0b2cb2 -r 51e162c130a9 HSP/Test/Testing_RPC.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HSP/Test/Testing_RPC.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ +#ifndef _TESTING_RPC_H_ +#define _TESTING_RPC_H_ + +/** +* RPC executed routine that will perform platform self testing for the S25FS512 +*/ +int Test_S25FS512(char argStrs[32][32], char replyStrs[32][32]); +/** +* RPC executed routine that will perform platform self testing for the MAX30001 +*/ +int Test_MAX30001(char argStrs[32][32], char replyStrs[32][32]); + +#endif /* _TESTING_RPC_H_ */ +
diff -r 21b02b0b2cb2 -r 51e162c130a9 SDFileSystem.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/aureliocarella/code/SDFileSystem/#60a4bf4842aa
diff -r 21b02b0b2cb2 -r 51e162c130a9 main.cpp --- a/main.cpp Fri Dec 14 13:15:33 2018 +0000 +++ b/main.cpp Thu Jul 16 14:59:04 2020 +0000 @@ -28,6 +28,18 @@ #include "ble/GattServer.h" #include "BLEProcess.h" +#include "max32630fthr.h" +#include "RpcServer.h" +#include "StringInOut.h" +#include "Peripherals.h" +#include "MAX30001.h" +#include "DataLoggingService.h" +#include "PushButton.h" +#include "Streaming.h" +#include "SDFileSystem.h" +#include "version.h" + + using mbed::callback; /** @@ -45,29 +57,35 @@ typedef ClockService Self; public: + uint8_t second; + uint8_t minute; + uint8_t hour; + ClockService() : - _hour_char("485f4145-52b9-4644-af1f-7a6b9322490f", 0), - _minute_char("0a924ca7-87cd-4699-a3bd-abdcd9cf126a", 0), - _second_char("8dd6a1b7-bc75-4741-8a26-264af75807de", 0), - _clock_service( + _ecg("485f4145-52b9-4644-af1f-7a6b9322490f", 0), + _rr_bpm("0a924ca7-87cd-4699-a3bd-abdcd9cf126a", 0), + _max30001_chr("8dd6a1b7-bc75-4741-8a26-264af75807de", 0), + _ecg_service( /* uuid */ "51311102-030e-485f-b122-f8f381aa84ed", - /* characteristics */ _clock_characteristics, - /* numCharacteristics */ sizeof(_clock_characteristics) / - sizeof(_clock_characteristics[0]) + /* characteristics */ _ecg_characteristics, + /* numCharacteristics */ sizeof(_ecg_characteristics) / + sizeof(_ecg_characteristics[0]) ), _server(NULL), + _event_queue(NULL) { // update internal pointers (value, descriptors and characteristics array) - _clock_characteristics[0] = &_hour_char; - _clock_characteristics[1] = &_minute_char; - _clock_characteristics[2] = &_second_char; + _ecg_characteristics[0] = &_ecg; + _ecg_characteristics[1] = &_rr_bpm; + _ecg_characteristics[2] = &_max30001_chr; // setup authorization handlers - _hour_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); - _minute_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); - _second_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); + _ecg.setWriteAuthorizationCallback(this, &Self::authorize_client_write); + _rr_bpm.setWriteAuthorizationCallback(this, &Self::authorize_client_write); + _max30001_chr.setWriteAuthorizationCallback(this, &Self::authorize_client_write); } + @@ -82,7 +100,7 @@ // register the service printf("Adding demo service\r\n"); - ble_error_t err = _server->addService(_clock_service); + ble_error_t err = _server->addService(_ecg_service); if (err) { printf("Error %u during demo service registration.\r\n", err); @@ -101,12 +119,12 @@ // print the handles printf("clock service registered\r\n"); - printf("service handle: %u\r\n", _clock_service.getHandle()); - printf("\thour characteristic value handle %u\r\n", _hour_char.getValueHandle()); - printf("\tminute characteristic value handle %u\r\n", _minute_char.getValueHandle()); - printf("\tsecond characteristic value handle %u\r\n", _second_char.getValueHandle()); + printf("service handle: %u\r\n", _ecg_service.getHandle()); + printf("\thour characteristic value handle %u\r\n", _ecg.getValueHandle()); + printf("\tminute characteristic value handle %u\r\n", _rr_bpm.getValueHandle()); + printf("\tsecond characteristic value handle %u\r\n", _max30001_chr.getValueHandle()); - _event_queue->call_every(1000 /* ms */, callback(this, &Self::increment_second)); + _event_queue->call_every(2000 /* ms */, callback(this, &Self::increment_second)); } private: @@ -127,12 +145,15 @@ printf("data written:\r\n"); printf("\tconnection handle: %u\r\n", e->connHandle); printf("\tattribute handle: %u", e->handle); - if (e->handle == _hour_char.getValueHandle()) { + if (e->handle == _ecg.getValueHandle()) { printf(" (hour characteristic)\r\n"); - } else if (e->handle == _minute_char.getValueHandle()) { + hour = e->data[0]; + } else if (e->handle == _rr_bpm.getValueHandle()) { printf(" (minute characteristic)\r\n"); - } else if (e->handle == _second_char.getValueHandle()) { + minute = e->data[0]; + } else if (e->handle == _max30001_chr.getValueHandle()) { printf(" (second characteristic)\r\n"); + second = e->data[0]; } else { printf("\r\n"); } @@ -156,11 +177,11 @@ printf("data read:\r\n"); printf("\tconnection handle: %u\r\n", e->connHandle); printf("\tattribute handle: %u", e->handle); - if (e->handle == _hour_char.getValueHandle()) { + if (e->handle == _ecg.getValueHandle()) { printf(" (hour characteristic)\r\n"); - } else if (e->handle == _minute_char.getValueHandle()) { + } else if (e->handle == _rr_bpm.getValueHandle()) { printf(" (minute characteristic)\r\n"); - } else if (e->handle == _second_char.getValueHandle()) { + } else if (e->handle == _max30001_chr.getValueHandle()) { printf(" (second characteristic)\r\n"); } else { printf("\r\n"); @@ -222,7 +243,7 @@ } if ((e->data[0] >= 60) || - ((e->data[0] >= 24) && (e->handle == _hour_char.getValueHandle()))) { + ((e->data[0] >= 24) && (e->handle == _ecg.getValueHandle()))) { printf("Error invalid data\r\n"); e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED; return; @@ -236,16 +257,29 @@ */ void increment_second(void) { - uint8_t second = 0; - ble_error_t err = _second_char.get(*_server, second); + + ble_error_t err = _max30001_chr.get(*_server, second); if (err) { printf("read of the second value returned error %u\r\n", err); return; } second = (second + 1) % 60; - - err = _second_char.set(*_server, second); + uint32_t* mamt; + //MAX30001::MAX30001_REG_map_t reg = (MAX30001_REG_map_t)0x01; + uint8_t addr = 0x01; //STATUS + printf("reg=%d ", addr); + int res = Peripherals::max30001()->max30001_reg_read(addr, mamt); + printf("MAMT=%d, %x\r\n", res, *mamt); + + /* printf("RPC"); + char reply1[128]; + // process the RPC string + RPC_call("/System/ReadVer", reply1); + //Send reply to debug port + printf(reply1);*/ + printf("%d-%d-%d\r\n",hour, minute, second); + err = _max30001_chr.set(*_server, second); if (err) { printf("write of the second value returned error %u\r\n", err); return; @@ -261,8 +295,8 @@ */ void increment_minute(void) { - uint8_t minute = 0; - ble_error_t err = _minute_char.get(*_server, minute); + + ble_error_t err = _rr_bpm.get(*_server, minute); if (err) { printf("read of the minute value returned error %u\r\n", err); return; @@ -270,7 +304,7 @@ minute = (minute + 1) % 60; - err = _minute_char.set(*_server, minute); + err = _rr_bpm.set(*_server, minute); if (err) { printf("write of the minute value returned error %u\r\n", err); return; @@ -286,8 +320,8 @@ */ void increment_hour(void) { - uint8_t hour = 0; - ble_error_t err = _hour_char.get(*_server, hour); + + ble_error_t err = _ecg.get(*_server, hour); if (err) { printf("read of the hour value returned error %u\r\n", err); return; @@ -295,7 +329,7 @@ hour = (hour + 1) % 24; - err = _hour_char.set(*_server, hour); + err = _ecg.set(*_server, hour); if (err) { printf("write of the hour value returned error %u\r\n", err); return; @@ -378,22 +412,143 @@ uint8_t _value; }; - ReadWriteNotifyIndicateCharacteristic<uint8_t> _hour_char; - ReadWriteNotifyIndicateCharacteristic<uint8_t> _minute_char; - ReadWriteNotifyIndicateCharacteristic<uint8_t> _second_char; + ReadWriteNotifyIndicateCharacteristic<uint8_t> _ecg; + ReadWriteNotifyIndicateCharacteristic<uint8_t> _rr_bpm; + ReadWriteNotifyIndicateCharacteristic<uint8_t> _max30001_chr; // list of the characteristics of the clock service - GattCharacteristic* _clock_characteristics[3]; + GattCharacteristic* _ecg_characteristics[3]; // demo service - GattService _clock_service; + GattService _ecg_service; GattServer* _server; events::EventQueue *_event_queue; }; + +//Init PMIC on FTHR board and set logic thresholds to 3.3V +MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3); + +SDFileSystem sd(P0_5, P0_6, P0_4, P0_7, "sd"); // mosi, miso, sclk, cs + +//SD card insertion detection pin +DigitalIn SDDetect(P2_2, PullUp); + + +/// DigitalOut for CS +DigitalOut cs(P5_6); +/// SPI Master 2 with SPI0_SS for use with MAX30001 +SPI spi(SPI2_MOSI, SPI2_MISO, SPI2_SCK); // used by MAX30001 +/// SPI Master 1 +QuadSpiInterface quadSpiInterface(SPI1_MOSI, SPI1_MISO, SPI1_SCK, + SPI1_SS); // used by S25FS512 + /// External Flash +S25FS512 s25fs512(&quadSpiInterface); +/// ECG device +MAX30001 max30001(&spi, &cs); +InterruptIn max30001_InterruptB(P5_5); +InterruptIn max30001_Interrupt2B(P5_4); + + +/// HSP platform LED +HspLed hspLed(LED_RED); +/// Packet TimeStamp Timer, set for 1uS +Timer timestampTimer; +/// HSP Platform push button +PushButton pushButton(SW1); + +// local input state of the RPC +int inputState; +// RPC request buffer +char request[128]; +// RPC reply buffer +char reply[128]; int main() { + + + // display start banner + printf("Maxim Integrated mbed hSensor %d.%d.%d %02d/%02d/%02d\n", + VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, + VERSION_MONTH, VERSION_DAY, VERSION_SHORT_YEAR); + + // turn on red led + printf("Init HSPLED...\n"); + fflush(stdout); + hspLed.on(); + + // set NVIC priorities for GPIO to prevent priority inversion + printf("Init NVIC Priorities...\n"); + fflush(stdout); + NVIC_SetPriority(GPIO_P0_IRQn, 5); + NVIC_SetPriority(GPIO_P1_IRQn, 5); + NVIC_SetPriority(GPIO_P2_IRQn, 5); + NVIC_SetPriority(GPIO_P3_IRQn, 5); + NVIC_SetPriority(GPIO_P4_IRQn, 5); + NVIC_SetPriority(GPIO_P5_IRQn, 5); + NVIC_SetPriority(GPIO_P6_IRQn, 5); + // used by the MAX30001 + NVIC_SetPriority(SPIM2_IRQn, 0); + + // Be able to statically reference these devices anywhere in the application + Peripherals::setS25FS512(&s25fs512); + Peripherals::setTimestampTimer(×tampTimer); + Peripherals::setHspLed(&hspLed); + Peripherals::setPushButton(&pushButton); + Peripherals::setMAX30001(&max30001); + Peripherals::setSdFS(&sd); + Peripherals::setSDDetect(&SDDetect); + + // init the S25FS256 external flash device + printf("Init S25FS512...\n"); + fflush(stdout); + s25fs512.init(); + + // start blinking led1 + printf("Init HSPLED Blink...\n"); + fflush(stdout); + + // + // MAX30001 + // + printf("Init MAX30001 callbacks, interrupts...\n"); + fflush(stdout); + max30001_InterruptB.disable_irq(); + max30001_Interrupt2B.disable_irq(); + max30001_InterruptB.mode(PullUp); + max30001_InterruptB.fall(&MAX30001Mid_IntB_Handler); + max30001_Interrupt2B.mode(PullUp); + max30001_Interrupt2B.fall(&MAX30001Mid_Int2B_Handler); + max30001_InterruptB.enable_irq(); + max30001_Interrupt2B.enable_irq(); + MAX30001_AllowInterrupts(1); + max30001.max30001_sw_rst(); // Do a software reset of the MAX30001 + max30001.max30001_INT_assignment(MAX30001::MAX30001_INT_B, MAX30001::MAX30001_NO_INT, MAX30001::MAX30001_NO_INT, // en_enint_loc, en_eovf_loc, en_fstint_loc, + MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_NO_INT, // en_dcloffint_loc, en_bint_loc, en_bovf_loc, + MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_NO_INT, // en_bover_loc, en_bundr_loc, en_bcgmon_loc, + MAX30001::MAX30001_INT_B, MAX30001::MAX30001_NO_INT, MAX30001::MAX30001_NO_INT, // en_pint_loc, en_povf_loc, en_pedge_loc, + MAX30001::MAX30001_INT_2B, MAX30001::MAX30001_INT_B, MAX30001::MAX30001_NO_INT, // en_lonint_loc, en_rrint_loc, en_samp_loc, + MAX30001::MAX30001_INT_ODNR, MAX30001::MAX30001_INT_ODNR); // intb_Type, int2b_Type) + max30001.onDataAvailable(&StreamPacketUint32); + + // initialize the RPC server + printf("Init RPC Server...\n"); + fflush(stdout); + RPC_init(); + // initialize the logging service + printf("Init LoggingService...\n"); + fflush(stdout); + LoggingService_Init(); + // initialize the SD disk + sd.disk_initialize(); + + // start main loop + printf("Start main loop...\n"); + fflush(stdout); + + BLE &ble_interface = BLE::Instance(); + events::EventQueue event_queue; ClockService demo_service; BLEProcess ble_process(event_queue, ble_interface); @@ -405,6 +560,7 @@ ble_process.start(); // Process the event queue. + event_queue.dispatch_forever(); return 0;
diff -r 21b02b0b2cb2 -r 51e162c130a9 max32630fthr.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/max32630fthr.lib Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/teams/MaximIntegrated/code/max32630fthr/#02d6b69121e5
diff -r 21b02b0b2cb2 -r 51e162c130a9 mbed-os-example-ble-GattServer.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-GattServer.lib Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-ble-GattServer/#21b02b0b2cb2
diff -r 21b02b0b2cb2 -r 51e162c130a9 version.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/version.h Thu Jul 16 14:59:04 2020 +0000 @@ -0,0 +1,7 @@ +#define VERSION_MAJOR 3 +#define VERSION_MINOR 1 +#define VERSION_PATCH 0 + +#define VERSION_SHORT_YEAR 17 +#define VERSION_MONTH 8 +#define VERSION_DAY 23 \ No newline at end of file