diff --git a/Arduino.h b/Arduino.h index e8073f9..a961aa0 100644 --- a/Arduino.h +++ b/Arduino.h @@ -22,9 +22,19 @@ SOFTWARE. // The "Arduino.h" header file is intended to only be included by C++ sources. -#ifndef _ARDUINO_H_ -#define _ARDUINO_H_ +#ifndef _ARDUINO_MBED_BRIDGE_ARDUINO_H_ +#define _ARDUINO_MBED_BRIDGE_ARDUINO_H_ #include "mbed.h" -#endif // _ARDUINO_H_ +#define PinMode Arduino_PinMode // note: this changes the Arduino API for mbed compatibility - use Arduino_PinMode where PinMode was specified in the Arduino API +#include "core-api/api/ArduinoAPI.h" +#undef PinMode + +#include "core-extend/ArduinoAPI.h" + +#include "bridge/pins.h" + +#include "variant.h" // user-supplied + +#endif // _ARDUINO_MBED_BRIDGE_ARDUINO_H_ diff --git a/bridge/pins.cpp b/bridge/pins.cpp new file mode 100644 index 0000000..7446d4a --- /dev/null +++ b/bridge/pins.cpp @@ -0,0 +1,61 @@ +/* +Copyright (c) 2020 SparkFun Electronics + +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 THE +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#include "bridge/pins.h" + +pin_size_t pinIndexByName(PinName name){ + pin_size_t index = 0; + while(index < variantPinCount){ + if(variantPinStates[index].name == name){ return index; } + index++; + } + return variantPinCount; +} + +pin_size_t pinIndexByNumber(pin_size_t number){ + pin_size_t index = 0; + while(index < variantPinCount){ + if(variantPinStates[index].number == number){ return index; } + index++; + } + return variantPinCount; +} + +pin_size_t pinNumberByIndex(pin_size_t index){ + if(index >= variantPinCount){ return (pin_size_t)NC; } + return variantPinStates[index].number; +} + +pin_size_t pinNumberByName(PinName name){ + pin_size_t index = pinIndexByName(name); + return pinNumberByIndex(index); +} + +PinName pinNameByIndex(pin_size_t index){ + if(index >= variantPinCount){ return NC; } + return variantPinStates[index].name; +} + +PinName pinNameByNumber(pin_size_t number){ + pin_size_t index = pinIndexByNumber(number); + return pinNameByIndex(index); +} diff --git a/bridge/pins.h b/bridge/pins.h new file mode 100644 index 0000000..568abd9 --- /dev/null +++ b/bridge/pins.h @@ -0,0 +1,56 @@ +/* +Copyright (c) 2020 SparkFun Electronics + +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 THE +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#ifndef _ARDUINO_MBED_BRIDGE_BRIDGE_PINS_H_ +#define _ARDUINO_MBED_BRIDGE_BRIDGE_PINS_H_ + +#include "Arduino.h" + +typedef struct _PinState { + PinName name; + pin_size_t number; + arduino::InterruptInParam* irq; + // PwmOut* pwm; // todo: implement this + // AnalogOut* dac; // todo: implement this + // AnalogIn* adc; // todo: implement this + DigitalInOut* gpio; +} PinState; + +pin_size_t pinIndexByName(PinName name); +pin_size_t pinIndexByNumber(pin_size_t number); + +pin_size_t pinNumberByIndex(pin_size_t index); +pin_size_t pinNumberByName(PinName name); + +PinName pinNameByIndex(pin_size_t index); +PinName pinNameByNumber(pin_size_t number); + +#define pinIRQByIndex(I) variantPinStates[I].irq +#define pinPWMByIndex(I) variantPinStates[I].pwm +#define pinDACByIndex(I) variantPinStates[I].dac +#define pinADCByIndex(I) variantPinStates[I].adc +#define pinGPIOByIndex(I) variantPinStates[I].gpio + +extern const pin_size_t variantPinCount; +extern PinState variantPinStates[]; + +#endif // _ARDUINO_MBED_BRIDGE_BRIDGE_PINS_H_ \ No newline at end of file diff --git a/core-extend/ArduinoAPI.h b/core-extend/ArduinoAPI.h new file mode 100644 index 0000000..98c31d1 --- /dev/null +++ b/core-extend/ArduinoAPI.h @@ -0,0 +1,28 @@ +/* +Copyright (c) 2020 SparkFun Electronics + +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 THE +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#ifndef _ARDUINO_MBED_BRIDGE_CORE_EXTEND_ARDUINOAPI_H_ +#define _ARDUINO_MBED_BRIDGE_CORE_EXTEND_ARDUINOAPI_H_ + +#include "core-extend/Common.h" + +#endif // _ARDUINO_MBED_BRIDGE_CORE_EXTEND_ARDUINOAPI_H_ diff --git a/core-extend/Common.h b/core-extend/Common.h new file mode 100644 index 0000000..80b4603 --- /dev/null +++ b/core-extend/Common.h @@ -0,0 +1,143 @@ +/* +Copyright (c) 2020 SparkFun Electronics + +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 THE +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#ifndef _ARDUINO_MBED_BRIDGE_CORE_EXTEND_COMMON_H_ +#define _ARDUINO_MBED_BRIDGE_CORE_EXTEND_COMMON_H_ + +#include "mbed.h" + +#define PinMode Arduino_PinMode // note: this changes the Arduino API for mbed compatibility - use Arduino_PinMode where PinMode was specified in the Arduino API +#include "core-api/api/Common.h" +#undef PinMode + +void indexPinMode(pin_size_t index, Arduino_PinMode pinMode); +void pinMode(PinName pinName, Arduino_PinMode pinMode); + +void indexDigitalWrite(pin_size_t index, PinStatus val); +void digitalWrite(PinName pinName, PinStatus val); + +PinStatus indexDigitalRead(pin_size_t index); +PinStatus digitalRead(PinName pinName); + +int indexAnalogRead(pin_size_t index); +int analogRead(PinName pinName); + +void indexAnalogWriteDAC(pin_size_t index, int val); +void analogWriteDAC(PinName pinName, int val); +void analogWriteDAC(pin_size_t pinNumber, int val); + +void indexAnalogWrite(pin_size_t index, int val); +void analogWrite(PinName pinName, int val); + +void indexShiftOut(pin_size_t data_index, pin_size_t clock_index, BitOrder bitOrder, uint8_t val); +void shiftOut(PinName dataPinName, PinName clockPinName, BitOrder bitOrder, uint8_t val); + +pin_size_t indexShiftIn(pin_size_t data_index, pin_size_t clock_index, BitOrder bitOrder); +pin_size_t shiftIn(PinName dataPinName, PinName clockPinName, BitOrder bitOrder); + +void indexAttachInterrupt(pin_size_t index, voidFuncPtr callback, PinStatus mode); +void attachInterrupt(PinName pinName, voidFuncPtr callback, PinStatus mode); + +void indexAttachInterruptParam(pin_size_t index, voidFuncPtrParam callback, PinStatus mode, void* param); +void attachInterruptParam(PinName pinName, voidFuncPtrParam callback, PinStatus mode, void* param); + +void indexDetachInterrupt(pin_size_t index); +void detachInterrupt(PinName pinName); + +#ifdef __cplusplus + +void indexTone(pin_size_t index, unsigned int frequency, unsigned long duration = 0); +unsigned long indexPulseIn(pin_size_t index, uint8_t state, unsigned long timeout = 1000000L); +unsigned long pulseIn(PinName pinName, uint8_t state, unsigned long timeout = 1000000L); +unsigned long indexPulseInLong(pin_size_t index, uint8_t state, unsigned long timeout = 1000000L); +unsigned long pulseInLong(PinName pinName, uint8_t state, unsigned long timeout = 1000000L); + +#if DEVICE_INTERRUPTIN + +namespace arduino { + +class InterruptInParam : public mbed::InterruptIn { +private: +protected: +public: + /** Create an InterruptIn connected to the specified pin + * + * @param pin InterruptIn pin to connect to + */ + InterruptInParam(PinName pin); + + /** Create an InterruptIn connected to the specified pin, + * and the pin configured to the specified mode. + * + * @param pin InterruptIn pin to connect to + * @param mode Desired Pin mode configuration. + * (Valid values could be PullNone, PullDown, PullUp and PullDefault. + * See PinNames.h for your target for definitions) + * + */ + InterruptInParam(PinName pin, PinMode mode); + + virtual ~InterruptInParam(); + + /** Attach a function to call when a rising edge occurs on the input + * + * @param func A pointer to a void function with argument, or 0 to set as none + */ + void rise(Callback func, void* param); + + /** Attach a function to call when a rising edge occurs on the input + * + * @param func A pointer to a void function, or 0 to set as none + */ + void rise(Callback func); // shadows InterruptIn::rise + + /** Attach a function to call when a falling edge occurs on the input + * + * @param func A pointer to a void function with argument, or 0 to set as none + */ + void fall(Callback func, void* param); + + /** Attach a function to call when a falling edge occurs on the input + * + * @param func A pointer to a void function, or 0 to set as none + */ + void fall(Callback func); // shadows InterruptIn::fall + + static void _irq_handler(uint32_t id, gpio_irq_event event); + +protected: + Callback _rise; // shadows InterruptIn::_rise + Callback _fall; // shadows InterruptIn::_fall + + void* _rise_param = nullptr; + void* _fall_param = nullptr; + + void irq_init(PinName pin); // shadows InterruptIn::irq_init +}; + +} // namespace arduio + +#endif //DEVICE_INTERRUPTIN + +#endif // __cplusplus + +#endif // _ARDUINO_MBED_BRIDGE_CORE_EXTEND_COMMON_H_ diff --git a/core-implement/CommonAnalog.cpp b/core-implement/CommonAnalog.cpp new file mode 100644 index 0000000..e712b8c --- /dev/null +++ b/core-implement/CommonAnalog.cpp @@ -0,0 +1,133 @@ +/* +Copyright (c) 2020 SparkFun Electronics + +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 THE +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#include "mbed.h" + +#define PinMode Arduino_PinMode +#include "core-api/api/Common.h" +#undef PinMode + +#include "core-extend/Common.h" +#include "bridge/pins.h" + +#define standInFunc() printf("Stand-In for '%s' [file: %s, line: %d]\n", __FUNCTION__, __FILE__, __LINE__) + +// int indexAnalogRead(pin_size_t index){ +// // todo: support mbed AnalogIn modules +// mbed::AnalogIn* adc = pinADCByIndex(index); +// if (adc == NULL) { +// adc = new mbed::AnalogIn(name); +// pinADCByIndex(index) = adc; +// #ifdef ANALOG_CONFIG +// if (isAdcConfigChanged) { +// adc->configure(adcCurrentConfig); +// } +// #endif +// } +// return (adc->read_u16() >> (16 - read_resolution)); +// } + +int analogRead(PinName pinName){ + pin_size_t index = pinIndexByName(pinName); + if( index == variantPinCount ){ return 0; } + return indexAnalogRead(index); +} + +int analogRead(pin_size_t pinNumber){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return 0; } + return indexAnalogRead(index); +} + +// static int res_analog_w = 8; +// static int res_analog_r = 10; +void indexAnalogWriteDAC(pin_size_t index, int val){ + standInFunc(); + // // todo: support mbed DAC modules + // mbed::AnalogOut* dac = pinDACByIndex(index); + // if (dac == NULL) { + // dac = new mbed::AnalogOut(pinNameByIndex(index)); + // pinDACByIndex(index) = dac; + // } + // float percent = (float)val/(float)(1 << res_analog_w); + // dac->write(percent); +} + +void analogWriteDAC(PinName pinName, int val){ + pin_size_t index = pinIndexByName(pinName); + if( index == variantPinCount ){ return; } + indexAnalogWriteDAC(index, val); +} + +void analogWriteDAC(pin_size_t pinNumber, int val){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return; } + indexAnalogWriteDAC(index, val); +} + +// void indexAnalogWrite(pin_size_t index, int val){ +// standInFunc(); +// // mbed::PwmOut* pwm = pinPWMByIndex(index); +// // if (pwm == NULL) { +// // pwm = new mbed::PwmOut(pinNameByIndex(index)); +// // pinPWMByIndex(index) = pwm; +// // } +// // pwm->period_ms(2); +// // float percent = (float)val/(float)(1 << res_analog_w); +// // pwm->write(percent); +// } + +void analogWrite(PinName pinName, int val){ + pin_size_t index = pinIndexByName(pinName); + if( index == variantPinCount ){ return; } + indexAnalogWrite(index, val); +} + +void analogWrite(pin_size_t pinNumber, int val){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return; } + indexAnalogWrite(index, val); +} + +// void indexTone(pin_size_t index, unsigned int frequency, usigned long duration){ +// // // todo: implement with mbed +// // mbed::PwmOut* pwm = pinPWMByIndex(index); +// // if (pwm == NULL) { +// // pwm = new mbed::PwmOut(pinNameByIndex(index)); +// // pinPWMByIndex(index) = pwm; +// // } +// // pwm->period_ms(2); +// // float percent = (float)val/(float)(1 << res_analog_w); +// // pwm->write(percent); +// } + +void tone(uint8_t pinNumber, unsigned int frequency, unsigned long duration){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return; } + indexTone(index, frequency, duration); +} + +void noTone(uint8_t pinNumber){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return; } + indexTone(index, 0, 0); +} \ No newline at end of file diff --git a/core-implement/CommonDigital.cpp b/core-implement/CommonDigital.cpp new file mode 100644 index 0000000..3594253 --- /dev/null +++ b/core-implement/CommonDigital.cpp @@ -0,0 +1,169 @@ +/* +Copyright (c) 2020 SparkFun Electronics + +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 THE +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#include "mbed.h" + +#define PinMode Arduino_PinMode +#include "core-api/api/Common.h" +#undef PinMode + +#include "core-extend/Common.h" +#include "bridge/pins.h" + +void indexPinMode(pin_size_t index, Arduino_PinMode pinMode){ + DigitalInOut* gpio = pinGPIOByIndex(index); + if( gpio == NULL ){ + gpio = new DigitalInOut(pinNameByIndex(index)); + } + pinGPIOByIndex(index) = gpio; + + switch (pinMode) { + case INPUT: + gpio->input(); + gpio->mode(PullNone); + break; + case OUTPUT: + gpio->output(); + break; + case INPUT_PULLUP: + gpio->input(); + gpio->mode(PullUp); + break; + case INPUT_PULLDOWN: + default: + gpio->input(); + gpio->mode(PullDown); + break; + } +} + +void pinMode(pin_size_t pinNumber, Arduino_PinMode pinMode){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return; } + indexPinMode(index, pinMode); +} + +void pinMode(PinName pinName, Arduino_PinMode pinMode){ + pin_size_t index = pinIndexByName(pinName); + if( index == variantPinCount ){ return; } + indexPinMode(index, pinMode); +} + +void indexDigitalWrite(pin_size_t index, PinStatus val){ + mbed::DigitalInOut* gpio = pinGPIOByIndex(index); + if (gpio == NULL) { + gpio = new mbed::DigitalInOut(pinNameByIndex(index), PIN_OUTPUT, PullNone, val); + pinGPIOByIndex(index) = gpio; + } + gpio->write(val); +} + +void digitalWrite(pin_size_t pinNumber, PinStatus val){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return; } + indexDigitalWrite(index, val); +} + +void digitalWrite(PinName pinName, PinStatus val){ + pin_size_t index = pinIndexByName(pinName); + if( index == variantPinCount ){ return; } + indexDigitalWrite(index, val); +} + +PinStatus indexDigitalRead(pin_size_t index){ + mbed::DigitalInOut* gpio = pinGPIOByIndex(index); + if (gpio == NULL) { + gpio = new mbed::DigitalInOut(pinNameByIndex(index), PIN_INPUT, PullNone, 0); + pinGPIOByIndex(index) = gpio; + } + return (PinStatus) gpio->read(); +} + +PinStatus digitalRead(pin_size_t pinNumber){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return LOW; } + return indexDigitalRead(index); +} + +PinStatus digitalRead(PinName pinName){ + pin_size_t index = pinIndexByName(pinName); + if( index == variantPinCount ){ return LOW; } + return indexDigitalRead(index); +} + +void indexShiftOut(pin_size_t data_index, pin_size_t clock_index, BitOrder bitOrder, uint8_t val){ + for (uint8_t idx = 0; idx < 8; idx++) { + if (bitOrder == LSBFIRST) { + indexDigitalWrite(data_index, !!(val & (1 << idx)) ? HIGH : LOW); + }else{ + indexDigitalWrite(data_index, !!(val & (1 << (7 - idx))) ? HIGH : LOW); + } + indexDigitalWrite(clock_index, HIGH); + indexDigitalWrite(clock_index, LOW); + } +} + +void shiftOut(pin_size_t dataPinNumber, pin_size_t clockPinNumber, BitOrder bitOrder, uint8_t val){ + pin_size_t data_index = pinIndexByNumber(dataPinNumber); + pin_size_t clock_index = pinIndexByNumber(dataPinNumber); + if( data_index == variantPinCount ){ return; } + if( clock_index == variantPinCount ){ return; } + indexShiftOut(data_index, clock_index, bitOrder, val); +} + +void shiftOut(PinName dataPinName, PinName clockPinName, BitOrder bitOrder, uint8_t val){ + pin_size_t data_index = pinIndexByName(dataPinName); + pin_size_t clock_index = pinIndexByName(clockPinName); + if( data_index == variantPinCount ){ return; } + if( clock_index == variantPinCount ){ return; } + indexShiftOut(data_index, clock_index, bitOrder, val); +} + +pin_size_t indexShiftIn(pin_size_t data_index, pin_size_t clock_index, BitOrder bitOrder){ + uint8_t value = 0; + for (uint8_t idx = 0; idx < 8; ++idx) { + indexDigitalWrite(clock_index, HIGH); + if (bitOrder == LSBFIRST){ + value |= indexDigitalRead(data_index) << idx; + }else{ + value |= indexDigitalRead(data_index) << (7 - idx); + } + indexDigitalWrite(clock_index, LOW); + } + return value; +} + +pin_size_t shiftIn(pin_size_t dataPinNumber, pin_size_t clockPinNumber, BitOrder bitOrder){ + pin_size_t data_index = pinIndexByNumber(dataPinNumber); + pin_size_t clock_index = pinIndexByNumber(clockPinNumber); + if( data_index == variantPinCount ){ return 0x00; } + if( clock_index == variantPinCount ){ return 0x00; } + return indexShiftIn(data_index, clock_index, bitOrder); +} + +pin_size_t shiftIn(PinName dataPinName, PinName clockPinName, BitOrder bitOrder){ + pin_size_t data_index = pinIndexByName(dataPinName); + pin_size_t clock_index = pinIndexByName(clockPinName); + if( data_index == variantPinCount ){ return 0x00; } + if( clock_index == variantPinCount ){ return 0x00; } + return indexShiftIn(data_index, clock_index, bitOrder); +} \ No newline at end of file diff --git a/core-implement/CommonInit.cpp b/core-implement/CommonInit.cpp new file mode 100644 index 0000000..94ee912 --- /dev/null +++ b/core-implement/CommonInit.cpp @@ -0,0 +1,33 @@ +/* +Copyright (c) 2020 SparkFun Electronics + +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 THE +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#define PinMode Arduino_PinMode +#include "core-api/api/Common.h" +#undef PinMode + +#include "core-extend/Common.h" + +extern void initTimer(void); + +void init(void){ + initTimer(); +} diff --git a/core-implement/CommonInterrupt.cpp b/core-implement/CommonInterrupt.cpp new file mode 100644 index 0000000..ef72089 --- /dev/null +++ b/core-implement/CommonInterrupt.cpp @@ -0,0 +1,207 @@ +/* +Copyright (c) 2020 SparkFun Electronics + +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 THE +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#include "mbed.h" + +#define PinMode Arduino_PinMode +#include "core-api/api/Common.h" +#undef PinMode + +#include "core-extend/Common.h" +#include "bridge/pins.h" + +#define standInFunc() printf("Stand-In for '%s' [file: %s, line: %d]\n", __FUNCTION__, __FILE__, __LINE__) + +void indexAttachInterruptParam(pin_size_t index, voidFuncPtrParam callback, PinStatus mode, void* param){ + indexDetachInterrupt(index); + arduino::InterruptInParam* irq = pinIRQByIndex(index); + if(!irq){ + irq = new arduino::InterruptInParam(pinNameByIndex(index)); + } + pinIRQByIndex(index) = irq; + switch (mode) { + case CHANGE : + irq->rise(mbed::callback(callback), param); + irq->fall(mbed::callback(callback), param); + break; + case FALLING : + irq->fall(mbed::callback(callback), param); + break; + case RISING : + default : + irq->rise(mbed::callback(callback), param); + break; + } + if(!pinGPIOByIndex(index)){ // Give a default pullup for the pin, since calling InterruptIn with PinMode is impossible + switch (mode) { + case FALLING : + indexPinMode(index, INPUT_PULLUP); + break; + case RISING : + indexPinMode(index, INPUT_PULLDOWN); + break; + case CHANGE : + default: + indexPinMode(index, INPUT); + break; + } + } +} + +void attachInterruptParam(pin_size_t pinNumber, voidFuncPtrParam callback, PinStatus mode, void* param){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return; } + indexAttachInterruptParam(index, callback, mode, param); +} + +void attachInterruptParam(PinName pinName, voidFuncPtrParam callback, PinStatus mode, void* param){ + pin_size_t index = pinIndexByName(pinName); + if( index == variantPinCount ){ return; } + indexAttachInterruptParam(index, callback, mode, param); +} + +void indexAttachInterrupt(pin_size_t index, voidFuncPtr callback, PinStatus mode){ + indexAttachInterruptParam(index, (voidFuncPtrParam)callback, mode, NULL); +} + +void attachInterrupt(pin_size_t pinNumber, voidFuncPtr callback, PinStatus mode){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return; } + indexAttachInterrupt(index, callback, mode); +} + +void attachInterrupt(PinName pinName, voidFuncPtr callback, PinStatus mode){ + pin_size_t index = pinIndexByName(pinName); + if( index == variantPinCount ){ return; } + indexAttachInterrupt(index, callback, mode); +} + +void indexDetachInterrupt(pin_size_t index){ + arduino::InterruptInParam* irq = pinIRQByIndex(index); + if(!irq){ return; } + irq->rise(NULL, NULL); + irq->fall(NULL, NULL); +} + +void detachInterrupt(pin_size_t pinNumber){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return; } + indexDetachInterrupt(index); +} + +void detachInterrupt(PinName pinName){ + pin_size_t index = pinIndexByName(pinName); + if( index == variantPinCount ){ return; } + indexDetachInterrupt(index); +} + +// +// InterruptInParam implementation + +// Note: This single-parameter constructor exists to maintain binary +// compatibility. +// If not for that, we could simplify by having only the 2-param +// constructor, with a default value for the PinMode. +InterruptInParam::InterruptInParam(PinName pin) : + InterruptIn(pin) +{ + irq_init(pin); +} + +InterruptInParam::InterruptInParam(PinName pin, PinMode mode) : + InterruptIn(pin, mode) +{ + irq_init(pin); +} + +InterruptInParam::~InterruptInParam() +{ + +} + +void InterruptInParam::irq_init(PinName pin) +{ + gpio_irq_init(&gpio_irq, pin, (&InterruptInParam::_irq_handler), (uint32_t)this); +} + +void InterruptInParam::rise(Callback func, void* param) +{ + core_util_critical_section_enter(); + if (func) { + _rise = func; + gpio_irq_set(&gpio_irq, IRQ_RISE, 1); + } else { + _rise = nullptr; + gpio_irq_set(&gpio_irq, IRQ_RISE, 0); + } + if (param) { + _rise_param = param; + } else { + _rise_param = nullptr; + } + core_util_critical_section_exit(); +} + +void InterruptInParam::rise(Callback func){ + error("InterruptInParam.rise called with 'void(void)' callback (should be 'void(void*)')\r\n"); +} + +void InterruptInParam::fall(Callback func, void* param) +{ + core_util_critical_section_enter(); + if (func) { + _fall = func; + gpio_irq_set(&gpio_irq, IRQ_FALL, 1); + } else { + _fall = nullptr; + gpio_irq_set(&gpio_irq, IRQ_FALL, 0); + } + if (param) { + _fall_param = param; + } else { + _fall_param = nullptr; + } + core_util_critical_section_exit(); +} + +void InterruptInParam::fall(Callback func){ + error("InterruptInParam.fall called with 'void(void)' callback (should be 'void(void*)')\r\n"); +} + +void InterruptInParam::_irq_handler(uint32_t id, gpio_irq_event event) +{ + InterruptInParam *handler = (InterruptInParam *)id; + switch (event) { + case IRQ_RISE: + if (handler->_rise) { + handler->_rise(handler->_rise_param); + } + break; + case IRQ_FALL: + if (handler->_fall) { + handler->_fall(handler->_fall_param); + } + break; + case IRQ_NONE: + break; + } +} diff --git a/core-implement/CommonPulse.cpp b/core-implement/CommonPulse.cpp new file mode 100644 index 0000000..4949553 --- /dev/null +++ b/core-implement/CommonPulse.cpp @@ -0,0 +1,63 @@ +/* +Copyright (c) 2020 SparkFun Electronics + +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 THE +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#include "mbed.h" + +#define PinMode Arduino_PinMode +#include "core-api/api/Common.h" +#undef PinMode + +#include "core-extend/Common.h" +#include "bridge/pins.h" + +// unsigned long indexPulseIn(pin_size_t index, uint8_t state, unsigned long timeout){ +// standInFunc(); +// return 0; +// } + +unsigned long pulseIn(PinName pinName, uint8_t state, unsigned long timeout){ + pin_size_t index = pinIndexByName(pinName); + if( index == variantPinCount ){ return 0; } + return indexPulseIn(index, state, timeout); +} + +unsigned long pulseIn(pin_size_t pinNumber, uint8_t state, unsigned long timeout){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return 0; } + return indexPulseIn(index, state, timeout); +} + +unsigned long indexPulseInLong(pin_size_t index, uint8_t state, unsigned long timeout){ + return indexPulseIn(index, state, timeout); // pulseIn and pulseInLong are identical +} + +unsigned long pulseInLong(PinName pinName, uint8_t state, unsigned long timeout){ + pin_size_t index = pinIndexByName(pinName); + if( index == variantPinCount ){ return 0; } + return pulseInLong(index, state, timeout); +} + +unsigned long pulseInLong(pin_size_t pinNumber, uint8_t state, unsigned long timeout){ + pin_size_t index = pinIndexByNumber(pinNumber); + if( index == variantPinCount ){ return 0; } + return pulseInLong(index, state, timeout); +} diff --git a/core-implement/CommonTiming.cpp b/core-implement/CommonTiming.cpp new file mode 100644 index 0000000..df2f29a --- /dev/null +++ b/core-implement/CommonTiming.cpp @@ -0,0 +1,64 @@ +/* +Copyright (c) 2020 SparkFun Electronics + +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 THE +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#include "mbed.h" + +#define PinMode Arduino_PinMode +#include "core-api/api/Common.h" +#undef PinMode + +#include "core-extend/Common.h" + +#define standInFunc() printf("Stand-In for '%s' [file: %s, line: %d]\n", __FUNCTION__, __FILE__, __LINE__) + +// #if DEVICE_LPTICKER +// static mbed::LowPowerTimer t; +// #else +static mbed::Timer t; +// #endif + +using namespace std::chrono_literals; +using namespace std::chrono; + +void initTimer(void){ + t.start(); +} + +unsigned long millis(void){ + return duration_cast(t.elapsed_time()).count(); +} + +unsigned long micros(void){ + return t.elapsed_time().count(); +} + +void delay(unsigned long ms){ +#ifndef NO_RTOS + rtos::ThisThread::sleep_for(ms * 1ms); +#else + wait_us(ms * 1000); +#endif +} + +void delayMicroseconds(unsigned int us){ + wait_us(us); +} diff --git a/main.cpp b/main.cpp index 5708552..90c6c75 100644 --- a/main.cpp +++ b/main.cpp @@ -22,11 +22,10 @@ SOFTWARE. #include "Arduino.h" -extern void setup(void); -extern void loop(void); - int main(void) { + init(); + initVariant(); setup(); for (;;) {