diff --git a/build_flags_template.sh b/build_flags_template.sh new file mode 100644 index 0000000..27ed24f --- /dev/null +++ b/build_flags_template.sh @@ -0,0 +1,27 @@ +#! /bin/bash +# usage: +# first make your own copy of template +# cp build_flags_template.sh my_build_flags.sh +# then edit, change or comment something +# nano my_build_flags.sh +# and source it +# source my_build_flags.sh + echo "==============================================Custom build flags are:=====================================================" + export FLAGS="-DMY_CONFIG_SERVER=lazyhome.ru" + export FLAGS="$FLAGS -DWATCH_DOG_TICKER_DISABLE" + export FLAGS="$FLAGS -DUSE_1W_PIN=12" + export FLAGS="$FLAGS -DSD_CARD_INSERTED" + export FLAGS="$FLAGS -DSERIAL_BAUD=115200" + export FLAGS="$FLAGS -DWiz5500" + export FLAGS="$FLAGS -DDISABLE_FREERAM_PRINT" + export FLAGS="$FLAGS -DCUSTOM_FIRMWARE_MAC=de:ad:be:ef:fe:00" + export FLAGS="$FLAGS -DDMX_DISABLE" + export FLAGS="$FLAGS -DMODBUS_DISABLE" + export FLAGS="$FLAGS -DOWIRE_DISABLE" + export FLAGS="$FLAGS -DAVR_DMXOUT_PIN=18" + export FLAGS="$FLAGS -DLAN_INIT_DELAY=2000" + export FLAGS="$FLAGS -DCONTROLLINO" + export PLATFORMIO_BUILD_FLAGS="$FLAGS" + echo PLATFORMIO_BUILD_FLAGS=$PLATFORMIO_BUILD_FLAGS + echo "==============================================Custom build flags END=====================================================" + unset FLAGS \ No newline at end of file diff --git a/compiled/due/upload.bat b/compiled/due/upload.bat new file mode 100644 index 0000000..affc186 --- /dev/null +++ b/compiled/due/upload.bat @@ -0,0 +1,3 @@ +mode com3:1200,n,8,1 +pause +C:\Users\Akmal\.platformio\packages\tool-bossac\bossac.exe -i --port=com3 -U false -e -w -v -b C:\Users\Akmal\ownCloud\compiled\due\Wiz5500\firmware.bin -R \ No newline at end of file diff --git a/compiled/due/upload999.bat b/compiled/due/upload999.bat new file mode 100644 index 0000000..6f35168 --- /dev/null +++ b/compiled/due/upload999.bat @@ -0,0 +1,3 @@ +mode com3:1200,n,8,1 +pause +C:\Users\Akmal\.platformio\packages\tool-bossac\bossac.exe -i --port=com3 -U false -e -w -v -b C:\Users\Akmal\ownCloud\compiled\due\Wiz5500\firmware999.bin -R \ No newline at end of file diff --git a/compiled/mon.bat b/compiled/mon.bat new file mode 100644 index 0000000..895fb94 --- /dev/null +++ b/compiled/mon.bat @@ -0,0 +1 @@ +pio device monitor -b 115200 diff --git a/config/c4-3e-11-03-1b-1e.config.json b/config/c4-3e-11-03-1b-1e.config.json new file mode 100644 index 0000000..037f27d --- /dev/null +++ b/config/c4-3e-11-03-1b-1e.config.json @@ -0,0 +1,29 @@ +{ + "mqtt":["garden","192.168.10.115",1883,"test","test"], + "ow":{ + "28FFADCE601705A3":{"emit":"t_soil1","item":"h_relay6"}, + "286164123FF96F55":{"emit":"t_soil2"}, + "28FFEF6D60170335":{"emit":"t_soil3"} + }, + "items":{ + "h_relay1":[6,39,1,1], + "h_relay2":[6,38,1,1], + "h_relay3":[6,37,1,1], + "h_relay4":[6,36,1,1], + "h_relay5":[6,35,1,1], + "h_relay6":[5,34,23], + "h_relay7":[6,33,1,1], + "h_relay8":[6,32,1,1], + "h_auto":[6,29,1,1] + }, + "in":{ + "40":{"emit":"/garden/s_in/1"}, + "41":{"emit":"/garden/s_in/2"}, + "42":{"emit":"/garden/s_in/3"}, + "43":{"emit":"/garden/s_in/4"}, + "44":{"emit":"/garden/s_in/5"}, + "45":{"emit":"/garden/s_in/6"}, + "46":{"emit":"/garden/s_in/7"}, + "47":{"emit":"/garden/s_in/8"} + } +} diff --git a/config/de-ad-be-ef-fe-ed.config.json b/config/de-ad-be-ef-fe-ed.config.json new file mode 100644 index 0000000..ad74e84 --- /dev/null +++ b/config/de-ad-be-ef-fe-ed.config.json @@ -0,0 +1,46 @@ +{ + "dmxin":["kuhm","kuhwin","gost","bthr"], + "dmx":[3,60], + "modbus": [96,97], + "items": { + "light":[7,["kuh","ktc","gst","gost"]], + "kuhwin":[1,5], + "kuhline":[1,13], + "kuhfre":[1,25], + "kuhwork":[1,1], + "gost":[1,47], + "sasha1":[1,17], + "sasha2":[1,21], + "vika1":[1,31], + "vika2":[1,35], + "bedr1":[1,39], + "bedr2":[1,43], + "kuhm":[7,["kuhline","kuhfre","kuhwork"]], + "kuh":[7,["kuhline","kuhfre","kuhwork","kuhwin"]], + "sasha":[7,["sasha1","sasha2"]], + "vika":[7,["vika1","vika2"]], + "bedr":[7,["bedr1","bedr2"]], + "balk1":[7,["balk11","balk12"]], + "balk2":[0,53], + "balk11":[0,51], + "balk12":[0,52], + "all":[7,["kuh","gost","vika","sasha","bedr","bth","gst","ktc","balk1","balk2","fm"]], + "bth1":[4,[96,0,0]], + "bth2":[4,[96,0,1]], + "bthr":[1,57], + "bth":[7,["bth1","bth2"]], + "ktc":[4,[97,0,0]], + "gst":[4,[97,0,1]], + "a_vika":[3,8], + "a_sasha":[3,7], + "a_bedr":[3,6], + "a_ext":[3,5], + "fm":[9,10], + "fm_t":[8,"fm"], + "fm_h":[8,"fm"] + + }, + "mqtt":["public_test2","m2m.eclipse.org"] + } + + diff --git a/config/de-ad-be-ef-fe-ef.config.json b/config/de-ad-be-ef-fe-ef.config.json new file mode 100644 index 0000000..b783acb --- /dev/null +++ b/config/de-ad-be-ef-fe-ef.config.json @@ -0,0 +1,43 @@ +{ + "mqtt":["public_test1","m2m.eclipse.org"], + "ow":{ + "2807FFD503000036":{"emit":"t_balk1","item":"h_balk1"}, + "284811170400005B":{"emit":"t_entr"}, + "28FFF95533160459":{"emit":"t_bath1","item":"h_bath1"}, + "28D2FD1604000051":{"emit":"t_exbath2"}, + "28EE634F13160255":{"emit":"t_bath2","item":"h_bath2"}, + "28FFB3B02316030C":{"emit":"t_balk2","item":"h_balk2"}, + "28EE4A571316027A":{"emit":"t_sasha"}, + "28FF0C6A331604FF":{"emit":"t_ext"}, + "28FFDD8C3316042C":{"emit":"t_abath2"}, + "28FFAEAC3316047F":{"emit":"t_abath1"}, + "28EE736E131602D6":{"emit":"t_vika"}, + "28EED85C131602DA":{"emit":"t_kitchen"}, + "28EE5A62131602CF":{"emit":"t_ac"}, + "28EEA76713160204":{"emit":"t_aentr"}, + "28EE8A5B1616019D":{"emit":"t_entr2","item":"h_entr"}, + "28EED16A13160268":{"emit":"t_bedr"} + }, + "items":{ + "all":[7,["h_entr","h_bath1","h_bath2","h_balk1","h_balk2","h_boil1","h_boil2","h_polotenc","spots_en","light_en"]], + "h_bath1":[5,24,33], + "h_bath2":[5,34,32], + "h_entr":[5,35,32], + "h_balk1":[5,25,28], + "h_balk2":[5,27,28], + "h_boil1":[6,23], + "h_boil2":[6,28,1,1], + "h_polotenc":[6,26,1,1], + "spots_en":[6,22,1,1], + "light_en":[6,29,1,1], + "water":[6,36,1,1] + }, + "in":{ + "41":{"T":0,"emit":"/myhome/in/all","scmd":"HALT","rcmd":"REST"}, + "37":{"item":"spots_en","scmd":"TOGGLE","rcmd":"TOGGLE"}, + "38":{"emit":"/myhome/in/light","scmd":"TOGGLE","rcmd":"TOGGLE"}, + "40":{"T":1,"emit":"/myhome/out/all","scmd":"HALT","rcmd":"REST"}, + "39":{"emit":"/myhome/s_out/water_leak"} + } +} + diff --git a/lighthub/colorchannel.cpp b/lighthub/colorchannel.cpp index fa3329c..383c3a1 100644 --- a/lighthub/colorchannel.cpp +++ b/lighthub/colorchannel.cpp @@ -20,7 +20,9 @@ int colorChannel::Ctrl(itemCmd cmd, char* subItem, bool toExecute) { debugSerial<SendStatus(SEND_COMMAND); return 1; diff --git a/lighthub/dmx.cpp b/lighthub/dmx.cpp index 1d21e20..74f186e 100644 --- a/lighthub/dmx.cpp +++ b/lighthub/dmx.cpp @@ -158,7 +158,7 @@ for (short tch=0; tch<=3 ; tch++) if (updated) { DMXImmediateUpdate(tch,DMXin[base],DMXin[base+1],DMXin[base+2],DMXin[base+3]); - D_checkT=millis()+D_CHECKT; + D_checkT=millisNZ(); } } //Serial.print(D_State,BIN);Serial.println(); @@ -185,7 +185,8 @@ short t,tch; } -if ((millis()";} } } - checkTimestamp=now+DMX_SMOOTH_DELAY; + checkTimestamp=now; #endif } diff --git a/lighthub/esp.cpp b/lighthub/esp.cpp new file mode 100644 index 0000000..5348513 --- /dev/null +++ b/lighthub/esp.cpp @@ -0,0 +1,54 @@ +#include "options.h" +#ifdef __ESP__ +#include "esp.h" + +ESP8266WiFiMulti wifiMulti; +WiFiClient ethClient; + +char mqtt_password[16]; + +//default custom static IP +//char static_ip[16] = "10.0.1.56"; +//char static_gw[16] = "10.0.1.1"; +//char static_sn[16] = "255.255.255.0"; + +//flag for saving data +bool shouldSaveConfig = false; + +//callback notifying us of the need to save config +void saveConfigCallback () { + Serial.println(F("Should save config")); + shouldSaveConfig = true; +} + + +void espSetup () { + Serial.println(F("Setting up Wifi")); + shouldSaveConfig = true; + //WiFiManager + + WiFiManagerParameter custom_mqtt_password("", "mqtt password", mqtt_password, 16); + //Local intialization. Once its business is done, there is no need to keep it around + WiFiManager wifiManager; + + wifiManager.setSaveConfigCallback(saveConfigCallback); + + wifiManager.addParameter(&custom_mqtt_password); + wifiManager.setMinimumSignalQuality(); + +if (!wifiManager.autoConnect()) { + Serial.println(F("failed to connect and hit timeout")); + delay(3000); + //reset and try again, or maybe put it to deep sleep + ESP.reset(); + delay(5000); + } + + //if you get here you have connected to the WiFi + Serial.println(F("connected...yeey :)")); + + //read updated parameters + strcpy(mqtt_password, custom_mqtt_password.getValue()); + +} +#endif diff --git a/lighthub/esp.h b/lighthub/esp.h new file mode 100644 index 0000000..2238e09 --- /dev/null +++ b/lighthub/esp.h @@ -0,0 +1,24 @@ +#include +//needed for library +#include +#include +#include //https://github.com/tzapu/WiFiManager +#include + +extern ESP8266WiFiMulti wifiMulti; +extern WiFiClient ethClient; +//WiFiManager wifiManager; + +//define your default values here, if there are different values in config.json, they are overwritten. +//length should be max size + 1 +extern char mqtt_password[16]; + +//default custom static IP +//char static_ip[16] = "10.0.1.56"; +//char static_gw[16] = "10.0.1.1"; +//char static_sn[16] = "255.255.255.0"; + +//flag for saving data +extern bool shouldSaveConfig; + +void espSetup (); diff --git a/lighthub/inputs.cpp b/lighthub/inputs.cpp index e9a947b..40e2943 100644 --- a/lighthub/inputs.cpp +++ b/lighthub/inputs.cpp @@ -289,7 +289,8 @@ switch (cause) { #ifndef COUNTER_DISABLE void Input::counterPoll() { - if(nextPollTime()>millis()) +// if(nextPollTime()>millis()) + if (!isTimeOver(nextPollTime(),millis(),DHT_POLL_DELAY_DEFAULT)) return; if (store->logicState == 0) { #if defined(ARDUINO_ARCH_AVR) @@ -326,7 +327,7 @@ void Input::counterPoll() { sprintf(valstr, "%ld", counterValue); if (mqttClient.connected() && !ethernetIdleCount) mqttClient.publish(addrstr, valstr); - setNextPollTime(millis() + DHT_POLL_DELAY_DEFAULT); + setNextPollTime(millis());// + DHT_POLL_DELAY_DEFAULT); // debugSerial<type == aJson_String) { @@ -391,7 +393,7 @@ void Input::uptimePoll() { if (mqttClient.connected() && !ethernetIdleCount) mqttClient.publish(emit->valuestring, valstr); } - setNextPollTime(millis() + UPTIME_POLL_DELAY_DEFAULT); + setNextPollTime(millis());// + UPTIME_POLL_DELAY_DEFAULT); } void Input::onCounterChanged(int i) { @@ -456,7 +458,8 @@ void Input::setNextPollTime(unsigned long pollTime) { #ifndef DHT_DISABLE void Input::dht22Poll() { - if (nextPollTime() > millis()) + //if (nextPollTime() > millis()) + if (!isTimeOver(nextPollTime(),millis(),DHT_POLL_DELAY_DEFAULT)) return; #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) DHTesp dhtSensor; @@ -495,10 +498,12 @@ void Input::dht22Poll() { if (mqttClient.connected() && !ethernetIdleCount) mqttClient.publish(addrstr, valstr); - setNextPollTime(millis() + DHT_POLL_DELAY_DEFAULT); + //setNextPollTime(millis() + DHT_POLL_DELAY_DEFAULT); // debugSerial << F(" NextPollMillis=") << nextPollTime() << endl; - } else - setNextPollTime(millis() + DHT_POLL_DELAY_DEFAULT / 3); + } + //else + // setNextPollTime(millis() + DHT_POLL_DELAY_DEFAULT / 3); + setNextPollTime(millis()); } #endif /* diff --git a/lighthub/item.cpp b/lighthub/item.cpp index 09df30b..897288b 100644 --- a/lighthub/item.cpp +++ b/lighthub/item.cpp @@ -47,6 +47,7 @@ e-mail anklimov@gmail.com #include "modules/out_modbus.h" #include "modules/out_dmx.h" #include "modules/out_pwm.h" +#include "modules/out_pid.h" short modbusBusy = 0; extern aJsonObject *pollingItem; @@ -97,12 +98,7 @@ int txt2subItem(char *payload) { else if (strcmp_P(payload, HUE_P) == 0) cmd = S_HUE; else if (strcmp_P(payload, SAT_P) == 0) cmd = S_SAT; else if (strcmp_P(payload, TEMP_P) == 0) cmd = S_TEMP; - /* UnUsed now - else if (strcmp_P(payload, SETPOINT_P) == 0) cmd = S_SETPOINT; - else if (strcmp_P(payload, TEMP_P) == 0) cmd = S_TEMP; - else if (strcmp_P(payload, POWER_P) == 0) cmd = S_POWER; - else if (strcmp_P(payload, VOL_P) == 0) cmd = S_VOL; - */ + return cmd; } @@ -166,6 +162,13 @@ void Item::Parse() { // debugSerial<name << F(" T:") << itemType << F(" =") << getArg() << endl; @@ -561,7 +564,7 @@ st.setSuffix(suffixCode); case 4: st.RGBW(Par[0],Par[1],Par[2],Par[3]); default:; } - //return Ctrl(setCommand, i, Par, suffixCode, subItem); + return Ctrl(st,subItem); } default: //some known command @@ -586,10 +589,18 @@ int Item::Ctrl(itemCmd cmd, char* subItem) if (!suffixCode && defaultSuffixCode) suffixCode = defaultSuffixCode; - - debugSerial<0); bool toExecute = (chActive>0); // execute if channel is active now @@ -643,7 +654,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem) case CMD_HALT: //previous command was HALT ? debugSerial << F("Restored from:") << t << endl; toExecute=true; - if (itemType == CH_THERMO) st.Cmd(CMD_AUTO); + if (itemType == CH_THERMO) st.Cmd(CMD_AUTO); //// else st.Cmd(CMD_ON); //turning on break; default: @@ -665,15 +676,15 @@ int Item::Ctrl(itemCmd cmd, char* subItem) } break; - case CMD_DN: - case CMD_UP: - { - //if (itemType == CH_GROUP) break; ////bug here - st.Cmd(CMD_VOID); // Converting to SET value command - short step=0; - if (cmd.isValue()) step=cmd.getInt(); - if (!step) step=DEFAULT_INC_STEP; - if (cmd.getCmd() == CMD_DN) step=-step; + case CMD_DN: + case CMD_UP: + { + //if (itemType == CH_GROUP) break; ////bug here + st.Cmd(CMD_VOID); // Converting to SET value command + short step=0; + if (cmd.isValue()) step=cmd.getInt(); + if (!step) step=DEFAULT_INC_STEP; + if (cmd.getCmd() == CMD_DN) step=-step; switch (suffixCode) { @@ -707,7 +718,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem) case CMD_VOID: // No commands, just set value ////if (itemType == CH_GROUP ) break; //// if (!cmd.isValue()) break; -//// if ( cType == CH_RGB || cType == CH_RGBW || cType == CH_GROUP ) + //// if ( cType == CH_RGB || cType == CH_RGBW || cType == CH_GROUP ) switch (suffixCode) { case S_NOTFOUND: //For empty (universal) suffix - turn ON/OFF automatically @@ -720,7 +731,10 @@ int Item::Ctrl(itemCmd cmd, char* subItem) // continue processing as SET case S_SET: //case S_ESET: - if ((st.getArgType() == ST_RGB || st.getArgType() == ST_RGBW) && (cmd.getArgType() == ST_HSV ) || (cmd.getArgType() == ST_HSV255)) st.setArgType(cmd.getArgType()); + if ((st.getArgType() == ST_RGB || st.getArgType() == ST_RGBW) && + (cmd.getArgType() == ST_HSV ) || (cmd.getArgType() == ST_HSV255)) + st.setArgType(cmd.getArgType()); + if (itemType == CH_GROUP && cmd.isColor()) st.setArgType(ST_HSV);//Extend storage for group channel st.assignFrom(cmd); st.saveItem(this); @@ -754,6 +768,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem) default: st.Cmd(cmd.getCmd()); + st.setSuffix(cmd.getSuffix()); toExecute=true; } //Switch commands @@ -893,9 +908,20 @@ switch (itemType) { } //switch if (st.isCommand()) { + if (cmd.getCmd() == CMD_HALT) + { + if (chActive>0) //if channel was active before CMD_HALT + { + setCmd(CMD_HALT); + SendStatus(SEND_COMMAND); + } + } + else + { setCmd(st.getCmd()); SendStatus(SEND_COMMAND); } + } } return 1; } @@ -1495,17 +1521,17 @@ switch (cause) case CH_MODBUS: checkModbusDimmer(); sendDelayedStatus(); - return INTERVAL_CHECK_MODBUS; + return INTERVAL_SLOW_POLLING; break; case CH_VC: checkFM(); sendDelayedStatus(); - return INTERVAL_CHECK_MODBUS; + return INTERVAL_SLOW_POLLING; break; case CH_VCTEMP: checkHeatRetry(); sendDelayedStatus(); - return INTERVAL_CHECK_MODBUS; + return INTERVAL_SLOW_POLLING; break; #endif /* case CH_RGB: //All channels with slider generate too many updates @@ -1525,7 +1551,7 @@ switch (cause) return driver->Poll(cause); } - return INTERVAL_POLLING; + return 0; } void Item::sendDelayedStatus() @@ -1541,12 +1567,16 @@ void Item::sendDelayedStatus() int Item::SendStatus(int sendFlags) { - if ((sendFlags & SEND_DEFFERED) || (!isNotRetainingStatus() )) { + if ((sendFlags & SEND_DEFFERED) || freeRam()<150 || (!isNotRetainingStatus() )) { setFlag(sendFlags & (SEND_COMMAND | SEND_PARAMETERS)); debugSerial<=0) @@ -372,10 +387,41 @@ itemCmd itemCmd::assignFrom(itemCmd from) case ST_INT32: case ST_UINT32: + param.asInt32=from.param.asInt32; + break; + case ST_FLOAT_FARENHEIT: + toFarenheit = true; case ST_FLOAT: case ST_FLOAT_CELSIUS: - case ST_FLOAT_FARENHEIT: - param.asInt32=from.param.asInt32; + switch (from.cmd.itemArgType) + { + case ST_TENS: + param.asfloat=from.param.asInt32/10.; + break; + + case ST_PERCENTS: + case ST_PERCENTS255: + param.asfloat=from.param.v; + break; + + case ST_INT32: + param.asfloat=from.param.asInt32; + break; + case ST_UINT32: + param.asfloat=from.param.asUint32; + break; + + case ST_FLOAT_FARENHEIT: + // F to C code should be here + // if (!toFarenheit) convert (from.param.asfloat); cmd.itemArgType=ST_FARENHEIT + case ST_FLOAT: + case ST_FLOAT_CELSIUS: + cmd.itemArgType=from.cmd.itemArgType; + param.asfloat=from.param.asfloat; + default: + debugSerial<")<getVal(); cmd.itemArgType= subtype; if (includeCommand) cmd.cmdCode=item->getCmd(); - debugSerial<WiFiAwaitingTime) + // if (millis()>WiFiAwaitingTime) + if (isTimeOver(WiFiAwaitingTime,millis(),WIFI_TIMEOUT)) { errorSerial< nextLanCheckTime) { + //if (millis() > timerLanCheckTime) + if (isTimeOver(timerLanCheckTime,millis(),TIMEOUT_RETAIN)) + { char buf[MQTT_TOPIC_LENGTH+1]; //Unsubscribe from status topics.. @@ -507,14 +512,15 @@ lan_status lanLoop() { case DO_REINIT: // Pause and re-init LAN //if (mqttClient.connected()) mqttClient.disconnect(); // Hmm hungs then cable disconnected - nextLanCheckTime = millis() + 5000; + timerLanCheckTime = millis();// + 5000; lanStatus = REINIT; LED.set(ledRED|((configLoaded)?ledBLINK:0)); break; case REINIT: // Pause and re-init LAN - if (millis() > nextLanCheckTime) + //if (millis() > timerLanCheckTime) + if (isTimeOver(timerLanCheckTime,millis(),TIMEOUT_REINIT)) { lanStatus = INITIAL_STATE; } @@ -522,12 +528,13 @@ lan_status lanLoop() { case DO_RECONNECT: // Pause and re-connect MQTT if (mqttClient.connected()) mqttClient.disconnect(); - nextLanCheckTime = millis() + 5000; + timerLanCheckTime = millis();// + 5000; lanStatus = RECONNECT; break; case RECONNECT: - if (millis() > nextLanCheckTime) + //if (millis() > timerLanCheckTime) + if (isTimeOver(timerLanCheckTime,millis(),TIMEOUT_RECONNECT)) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;//2; break; @@ -535,7 +542,7 @@ lan_status lanLoop() { case READ_RE_CONFIG: // Restore config from FLASH, re-init LAN if (loadConfigFromEEPROM()) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;//2; else { - nextLanCheckTime = millis() + 5000; + //timerLanCheckTime = millis();// + 5000; lanStatus = DO_REINIT;//-10; } break; @@ -575,7 +582,7 @@ lan_status lanLoop() { case DHCP_CHECK_REBIND_FAIL: errorSerial<50){ @@ -831,7 +837,7 @@ void onInitialStateInitLAN() { } #endif lanStatus = AWAITING_ADDRESS; -WiFiAwaitingTime = millis() + 60000L; +WiFiAwaitingTime = millis();// + 60000L; return; /* if (WiFi.status() == WL_CONNECTED) { @@ -844,7 +850,7 @@ if (WiFi.status() == WL_CONNECTED) { { errorSerial< nextInputCheck) { + //if (millis() > timerInputCheck) + if (isTimeOver(timerInputCheck,millis(),INTERVAL_CHECK_INPUT)) + { aJsonObject *input = inputs->child; while (input) { @@ -1999,11 +2007,13 @@ configLocked++; yield(); input = input->next; } - nextInputCheck = millis() + INTERVAL_CHECK_INPUT; + timerInputCheck = millis();// + INTERVAL_CHECK_INPUT; inCache.invalidateInputCache(); } - if (millis() > nextSensorCheck) { + //if (millis() > timerSensorCheck) + if (isTimeOver(timerSensorCheck,millis(),INTERVAL_CHECK_SENSOR)) + { aJsonObject *input = inputs->child; while (input) { if ((input->type == aJson_Object)) { @@ -2013,7 +2023,7 @@ configLocked++; yield(); input = input->next; } - nextSensorCheck = millis() + INTERVAL_CHECK_SENSOR; + timerSensorCheck = millis();// + INTERVAL_CHECK_SENSOR; } configLocked--; } @@ -2053,14 +2063,16 @@ configLocked--; // SLOW POLLING boolean done = false; if (lanStatus == RETAINING_COLLECTING) return; - if (millis() > nextPollingCheck) { + //if (millis() > timerPollingCheck) + if (isTimeOver(timerPollingCheck,millis(),INTERVAL_SLOW_POLLING)) + { while (pollingItem && !done) { if (pollingItem->type == aJson_Array) { Item it(pollingItem); uint32_t ret = it.Poll(POLLING_SLOW); if (ret) { - nextPollingCheck = millis() + ret; //INTERVAL_CHECK_MODBUS; + timerPollingCheck = millis();// + ret; //INTERVAL_CHECK_MODBUS; done = true; } }//if @@ -2095,7 +2107,8 @@ bool thermoDisabledOrDisconnected(aJsonObject *thermoExtensionArray, int thermoS //TODO: refactoring void thermoLoop(void) { - if (millis() < nextThermostatCheck) + // if (millis() < timerThermostatCheck) + if (!isTimeOver(timerThermostatCheck,millis(),THERMOSTAT_CHECK_PERIOD)) return; if (!items) return; bool thermostatCheckPrinted = false; @@ -2104,9 +2117,21 @@ void thermoLoop(void) { if (isThermostatWithMinArraySize(thermoItem, 5)) { aJsonObject *thermoExtensionArray = aJson.getArrayItem(thermoItem, I_EXT); if (thermoExtensionArray && (aJson.getArraySize(thermoExtensionArray) > 1)) { - int thermoPin = aJson.getArrayItem(thermoItem, I_ARG)->valueint; - float thermoSetting = aJson.getArrayItem(thermoItem, I_VAL)->valueint; /// + + Item thermostat(thermoItem); + if (!thermostat.isValid()) continue; + + itemCmd thermostatCmd(&thermostat); + + + //int thermoPin = aJson.getArrayItem(thermoItem, I_ARG)->valueint; + int thermoPin = thermostat.getArg(0); + + //float thermoSetting = aJson.getArrayItem(thermoItem, I_VAL)->valueint; /// + float thermoSetting = thermostatCmd.getFloat(); + int thermoStateCommand = aJson.getArrayItem(thermoItem, I_CMD)->valueint; + float curTemp = aJson.getArrayItem(thermoExtensionArray, IET_TEMP)->valuefloat; if (!aJson.getArrayItem(thermoExtensionArray, IET_ATTEMPTS)->valueint) { @@ -2144,7 +2169,7 @@ void thermoLoop(void) { } } configLocked--; - nextThermostatCheck = millis() + THERMOSTAT_CHECK_PERIOD; + timerThermostatCheck = millis();// + THERMOSTAT_CHECK_PERIOD; publishStat(); #ifndef DISABLE_FREERAM_PRINT (thermostatCheckPrinted) ? debugSerial<itemArr->name, s_mode,"/cmd"); else publishTopic(item->itemArr->name, "OFF","/cmd"); - +/* String raw_str; char raw[75]; for (int i=0; i < 37; i++){ @@ -173,7 +173,7 @@ void out_AC::InsertData(byte data[], size_t size){ raw_str.toCharArray(raw,75); publishTopic(item->itemArr->name, raw,"/raw"); Serial.println(raw); - +*/ /////////////////////////////////// } @@ -241,9 +241,10 @@ int out_AC::Poll(short cause) { if (cause!=POLLING_SLOW) return 0; -long now = millis(); - if (now - prevPolling > INTERVAL_AC_POLLING) { - prevPolling = now; +//long now = millis(); + //if (now - prevPolling > INTERVAL_AC_POLLING) { + if (isTimeOver(prevPolling,millis(),INTERVAL_AC_POLLING)) { + prevPolling = millisNZ(); Serial.println ("Polling"); SendData(qstn, sizeof(qstn)/sizeof(byte)); //Опрос кондиционера } @@ -259,7 +260,7 @@ delay(100); InsertData(data, 37); } } -return INTERVAL_POLLING; +return INTERVAL_SLOW_POLLING; }; //int out_AC::Ctrl(short cmd, short n, int * Parameters, int suffixCode, char* subItem) diff --git a/lighthub/modules/out_dmx.cpp b/lighthub/modules/out_dmx.cpp index 690c309..7a4dee0 100644 --- a/lighthub/modules/out_dmx.cpp +++ b/lighthub/modules/out_dmx.cpp @@ -68,14 +68,18 @@ if (!item || !show) return 0; short cType=getChanType(); uint8_t storageType; +/* switch (cmd.getCmd()){ case CMD_OFF: cmd.Percents(0); break; } +*/ + debugSerial<timestamp=millis(); +store->timestamp=millisNZ(); if (getConfig()) { //item->clearFlag(ACTION_NEEDED); @@ -354,7 +354,7 @@ if (store->pollingRegisters && !modbusBusy && (Status() == CST_INITIALIZED) && i reg = reg->next; } - store->timestamp=millis(); + store->timestamp=millisNZ(); debugSerial<itemArr->name << endl; //Non blocking waiting to release line diff --git a/lighthub/modules/out_motor.cpp b/lighthub/modules/out_motor.cpp index 1c6c5d2..1b22dc9 100644 --- a/lighthub/modules/out_motor.cpp +++ b/lighthub/modules/out_motor.cpp @@ -132,7 +132,8 @@ if (curPos<0) curPos=0; if (curPos>100) curPos=100; } -if (motorOfftime && motorOfftime=0) dif=targetPos-curPos; @@ -145,7 +146,7 @@ if (dif<-POS_ERR) { digitalWrite(pinDown,INACTIVE); - if (!item->getExt())item->setExt(millis()+maxOnTime); + if (!item->getExt())item->setExt(millisNZ()); // //PINS_COUNT @@ -193,7 +194,7 @@ if (dif>POS_ERR) { digitalWrite(pinUp,INACTIVE); -if (!item->getExt()) item->setExt(millis()+maxOnTime); +if (!item->getExt()) item->setExt(millisNZ()); #ifndef ESP32 if (digitalPinHasPWM(pinDown)) { @@ -269,7 +270,7 @@ debugSerial<setVal(cmd.getPercents()); - if (item->getExt()) item->setExt(millis()+maxOnTime); //Extend motor time + if (item->getExt()) item->setExt(millisNZ()); //Extend motor time /* st.assignFrom(cmd); //Store @@ -279,7 +280,7 @@ case S_SET: if (chActive>0 && !st.getPercents()) item->setCmd(CMD_OFF); if (chActive==0 && st.getPercents()) item->setCmd(CMD_ON); item->SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED); - if (item->getExt()) item->setExt(millis()+maxOnTime); //Extend motor time + if (item->getExt()) item->setExt(millisNZ()); //Extend motor time } else item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED); */ @@ -315,12 +316,12 @@ case S_CMD: item->SendStatus(SEND_COMMAND | SEND_PARAMETERS ); } */ - if (item->getExt()) item->setExt(millis()+maxOnTime); //Extend motor time + if (item->getExt()) item->setExt(millisNZ()); //Extend motor time return 1; case CMD_OFF: ////item->SendStatus(SEND_COMMAND); - if (item->getExt()) item->setExt(millis()+maxOnTime); //Extend motor time + if (item->getExt()) item->setExt(millisNZ()); //Extend motor time return 1; } //switch cmd diff --git a/lighthub/modules/out_pid.cpp b/lighthub/modules/out_pid.cpp index 04ce8f9..92695e1 100644 --- a/lighthub/modules/out_pid.cpp +++ b/lighthub/modules/out_pid.cpp @@ -119,7 +119,7 @@ int out_pid::Poll(short cause) if ((Status() == CST_INITIALIZED) && isTimeOver(store->timestamp,millis(),store->pollingInterval)) { - store->timestamp=millis(); + store->timestamp=millisNZ(); debugSerial<itemArr->name << endl; } diff --git a/lighthub/modules/out_pwm.cpp b/lighthub/modules/out_pwm.cpp index cb25356..7d4b487 100644 --- a/lighthub/modules/out_pwm.cpp +++ b/lighthub/modules/out_pwm.cpp @@ -125,12 +125,13 @@ bool inverse = (item->getArg()<0); short cType = getChanType(); uint8_t storageType; +/* switch (cmd.getCmd()){ case CMD_OFF: cmd.Percents(0); break; } - +*/ switch (cType) { diff --git a/lighthub/options.h b/lighthub/options.h index c16f9ee..e155385 100644 --- a/lighthub/options.h +++ b/lighthub/options.h @@ -32,6 +32,12 @@ #define AVR_DMXOUT_PIN 18 #endif +#define WIFI_TIMEOUT 60000UL +#define TIMEOUT_RECONNECT 10000UL +#define TIMEOUT_REINIT 5000UL +#define TIMEOUT_RETAIN 5000UL +#define INTERVAL_1W 5000UL + #define T_ATTEMPTS 200 #define IET_TEMP 0 #define IET_ATTEMPTS 1 @@ -69,8 +75,8 @@ #define INTERVAL_CHECK_SENSOR 5000 #endif -#define INTERVAL_CHECK_MODBUS 2000 -#define INTERVAL_POLLING 100 +#define INTERVAL_SLOW_POLLING 1000 +//#define INTERVAL_POLLING 100 #define THERMOSTAT_CHECK_PERIOD 30000 #ifndef OW_UPDATE_INTERVAL diff --git a/lighthub/owTerm.cpp b/lighthub/owTerm.cpp index 633632b..ca7e5b2 100644 --- a/lighthub/owTerm.cpp +++ b/lighthub/owTerm.cpp @@ -42,7 +42,7 @@ owChangedType owChanged; int owUpdate() { #ifndef OWIRE_DISABLE - unsigned long finish = millis() + OW_UPDATE_INTERVAL; + unsigned long finish = millis();// + OW_UPDATE_INTERVAL; /* if (oneWire->getError() == DS2482_ERROR_SHORT) { @@ -54,7 +54,8 @@ int owUpdate() { if (oneWire) oneWire->reset_search(); for (short i = 0; i < t_count; i++) wstat[i] &= ~SW_FIND; //absent - while (oneWire && oneWire->wireSearch(term[t_count]) > 0 && (t_count < t_max) && finish > millis()) { + while (oneWire && oneWire->wireSearch(term[t_count]) > 0 && (t_count < t_max) && !isTimeOver(finish,millis(), OW_UPDATE_INTERVAL))//&& finish > millis()) + { short ifind = -1; if (oneWire->crc8(term[t_count], 7) == term[t_count][7]) { for (short i = 0; i < t_count; i++) @@ -202,7 +203,12 @@ int sensors_loop(void) { void owLoop() { - if (millis() >= owTimer) owTimer = millis() + sensors_loop(); + //if (millis() >= owTimer) owTimer = millis() + sensors_loop(); + if (isTimeOver(owTimer,millis(),INTERVAL_1W)) + { + sensors_loop(); + owTimer=millis(); + } } diff --git a/lighthub/statusled.cpp b/lighthub/statusled.cpp index a11af27..eddef93 100644 --- a/lighthub/statusled.cpp +++ b/lighthub/statusled.cpp @@ -19,6 +19,7 @@ e-mail anklimov@gmail.com */ #include "statusled.h" +#include "utils.h" statusLED::statusLED(uint8_t pattern) @@ -28,7 +29,7 @@ statusLED::statusLED(uint8_t pattern) pinMode(pinGREEN, OUTPUT); pinMode(pinBLUE, OUTPUT); set(pattern); - timestamp=millis()+ledDelayms; + timestamp=millis();//+ledDelayms; #endif } @@ -71,11 +72,12 @@ void statusLED::poll() curStat&=~ledFlash; show(curStat); } -if (millis()>timestamp) +//if (millis()>timestamp) +if (isTimeOver(timestamp,millis(),(curStat & ledFASTBLINK)?ledFastDelayms:ledDelayms)) { - - if (curStat & ledFASTBLINK) timestamp=millis()+ledFastDelayms; - else timestamp=millis()+ledDelayms; + timestamp=millis(); + //if (curStat & ledFASTBLINK) timestamp=millis()+ledFastDelayms; + // else timestamp=millis()+ledDelayms; if (( curStat & ledBLINK) || (curStat & ledFASTBLINK)) { diff --git a/lighthub/utils.cpp b/lighthub/utils.cpp index 47e23f0..e83a011 100644 --- a/lighthub/utils.cpp +++ b/lighthub/utils.cpp @@ -632,6 +632,13 @@ itemCmd mapInt(int32_t arg, aJsonObject* map) return _itemCmd.Int(arg); } +unsigned long millisNZ() +{ + unsigned long now = millis(); + if (!now) now=1; + return now; +} + #pragma message(VAR_NAME_VALUE(debugSerial)) #pragma message(VAR_NAME_VALUE(SERIAL_BAUD)) diff --git a/lighthub/utils.h b/lighthub/utils.h index 3fdc4cf..ea3d619 100644 --- a/lighthub/utils.h +++ b/lighthub/utils.h @@ -65,3 +65,4 @@ bool isTimeOver(uint32_t timestamp, uint32_t currTime, uint32_t time, uint32_t m bool executeCommand(aJsonObject* cmd, int8_t toggle = -1); bool executeCommand(aJsonObject* cmd, int8_t toggle, itemCmd _itemCmd); itemCmd mapInt(int32_t arg, aJsonObject* map); +unsigned long millisNZ(); diff --git a/my_builds_flags.sh b/my_builds_flags.sh new file mode 100644 index 0000000..72daa63 --- /dev/null +++ b/my_builds_flags.sh @@ -0,0 +1,27 @@ +#! /bin/bash +# usage: +# first make your own copy of template +# cp build_flags_template.sh my_build_flags.sh +# then edit, change or comment something +# nano my_build_flags.sh +# and source it +# source my_build_flags.sh + echo "==============================================Custom build flags are:=====================================================" + export FLAGS="-DMY_CONFIG_SERVER=lazyhome.ru" +# export FLAGS="$FLAGS -DWATCH_DOG_TICKER_DISABLE" +# export FLAGS="$FLAGS -DUSE_1W_PIN=12" +# export FLAGS="$FLAGS -DSD_CARD_INSERTED" + export FLAGS="$FLAGS -DSERIAL_BAUD=115200" + export FLAGS="$FLAGS -DWiz5500" +# export FLAGS="$FLAGS -DDISABLE_FREERAM_PRINT" + export FLAGS="$FLAGS -DCUSTOM_FIRMWARE_MAC=de:ad:be:ef:fe:00" +# export FLAGS="$FLAGS -DDMX_DISABLE" +# export FLAGS="$FLAGS -DMODBUS_DISABLE" +# export FLAGS="$FLAGS -DOWIRE_DISABLE" +# export FLAGS="$FLAGS -DAVR_DMXOUT_PIN=18" + export FLAGS="$FLAGS -DLAN_INIT_DELAY=500" +# export FLAGS="$FLAGS -DCONTROLLINO" + export PLATFORMIO_BUILD_FLAGS="$FLAGS" + echo PLATFORMIO_BUILD_FLAGS=$PLATFORMIO_BUILD_FLAGS + echo "==============================================Custom build flags END=====================================================" + unset FLAGS \ No newline at end of file diff --git a/platformio.bak b/platformio.bak new file mode 100644 index 0000000..16ac566 --- /dev/null +++ b/platformio.bak @@ -0,0 +1,89 @@ +; PlatformIO Project Configuration File (for copy and paste) +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/page/projectconf.html +[platformio] +src_dir = lighthub +env_default = +<<<<<<< HEAD + due-5500 +; controllino +; megaatmega2560 +; megaatmega2560-5500 +; due +======= +; megaatmega2560 + due +>>>>>>> 2b56dcd8dd4e7b95e02c88bcbbbdec0a400a6dc4 +; esp8266 +[env:due] +platform = atmelsam +framework = arduino +board = due +lib_ldf_mode = chain+ +build_flags = !echo -n "-DPIO_SRC_REV="$(git log --pretty=format:%h_%ad -1 --date=short) +lib_deps = + https://github.com/sebnil/DueFlashStorage + https://github.com/anklimov/Arduino-Temperature-Control-Library.git + https://github.com/anklimov/DS2482_OneWire + https://github.com/anklimov/DmxDue + https://github.com/anklimov/ArduinoHttpClient + https://github.com/anklimov/aJson + https://github.com/anklimov/CmdArduino + https://github.com/anklimov/ModbusMaster + https://github.com/anklimov/Ethernet + https://github.com/anklimov/Ethernet2 + https://github.com/knolleary/pubsubclient.git + https://github.com/anklimov/Artnet.git + FastLED + SD + SdFat + + +[env:megaatmega2560] +platform = atmelavr +board = megaatmega2560 +framework = arduino +;lib_ldf_mode = chain+ +build_flags = !echo -n "-DPIO_SRC_REV="$(git log --pretty=format:%h_%ad -1 --date=short) +lib_deps = + https://github.com/anklimov/Arduino-Temperature-Control-Library.git + https://github.com/anklimov/DS2482_OneWire + https://github.com/anklimov/DmxSimple + https://github.com/anklimov/httpClient + https://github.com/anklimov/aJson + https://github.com/anklimov/CmdArduino + https://github.com/anklimov/ModbusMaster + https://github.com/anklimov/DMXSerial + https://github.com/anklimov/Ethernet + https://github.com/anklimov/Ethernet2 + https://github.com/PaulStoffregen/SPI.git + https://github.com/knolleary/pubsubclient.git + https://github.com/anklimov/Artnet.git + FastLED + EEPROM + + +[env:esp8266] +platform = espressif8266 +framework = arduino +board = nodemcuv2 +lib_ldf_mode = chain+ +build_flags = !echo -n "-DPIO_SRC_REV="$(git log --pretty=format:%h_%ad -1 --date=short) +lib_deps = + https://github.com/anklimov/Arduino-Temperature-Control-Library.git + https://github.com/anklimov/DS2482_OneWire + https://github.com/anklimov/ESP-Dmx + https://github.com/arduino-libraries/ArduinoHttpClient + https://github.com/anklimov/aJson + https://github.com/anklimov/CmdArduino + https://github.com/anklimov/ModbusMaster + https://github.com/anklimov/DMXSerial + https://github.com/knolleary/pubsubclient.git + https://github.com/anklimov/Artnet.git + FastLED diff --git a/platformio.ini b/platformio.ini index fc788b3..3b56a76 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,7 +13,7 @@ src_dir = lighthub default_envs = ; ****** UNCOMMENT single environment name for target platform below ******* ; Arduino Mega (without onewire) + Ethernet shield Wiznet 5100 -; mega2560slim-5100 + mega2560slim-5100 ; Arduino Mega + Ethernet shield Wiznet 5100 ; mega2560-5100 @@ -28,7 +28,7 @@ default_envs = ; due-5100 ; Generic DUE - due +; due ; Arduino DUE + Ethernet shield Wiznet 5500 ; due-5500 diff --git a/prepareDue.bat b/prepareDue.bat index 04fa9e5..b847b11 100644 --- a/prepareDue.bat +++ b/prepareDue.bat @@ -1 +1,2 @@ -cscript //NoLogo sed.vbs "s/void USART0_Handler(void)/void USART0_Handler(void ) __attribute__((weak)); void USART0_Handler(void )/" < %HOMEPATH%\.platformio\packages\framework-arduinosam\variants\arduino_due_x\variant.cpp +cscript.exe //nologo sed.vbs "s/void USART0_Handler(void)/void USART0_Handler(void ) __attribute__((weak)); void USART0_Handler(void )/" < %HOMEPATH%\.platformio\packages\framework-arduino-sam\variants\arduino_due_x\variant.cpp >variant.cpp +rem move variant.cpp %HOMEPATH%\.platformio\packages\framework-arduino-sam\variants\arduino_due_x\ \ No newline at end of file diff --git a/sed.vbs b/sed.vbs index 1a8dbb1..1e2a1aa 100644 --- a/sed.vbs +++ b/sed.vbs @@ -1,9 +1,10 @@ Dim pat, patparts, rxp, inp pat = WScript.Arguments(0) patparts = Split(pat,"/") +WScript.Echo "//"+ patparts(1) +"=>"+ patparts(2) Set rxp = new RegExp rxp.Global = True -rxp.Multiline = False +rxp.Multiline = True rxp.Pattern = patparts(1) Do While Not WScript.StdIn.AtEndOfStream inp = WScript.StdIn.ReadLine() diff --git a/variant.cpp b/variant.cpp new file mode 100644 index 0000000..d39a9ea --- /dev/null +++ b/variant.cpp @@ -0,0 +1,454 @@ +//void USART0_Handler(void)=>void USART0_Handler(void ) __attribute__((weak)); void USART0_Handler(void ) +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" + +/* + * DUE Board pin | PORT | Label + * ----------------+--------+------- + * 0 | PA8 | "RX0" + * 1 | PA9 | "TX0" + * 2 TIOA0 | PB25 | + * 3 TIOA7 | PC28 | + * 4 NPCS1 | PA29 | + * TIOB6 | PC26 | + * 5 TIOA6 | PC25 | + * 6 PWML7 | PC24 | + * 7 PWML6 | PC23 | + * 8 PWML5 | PC22 | + * 9 PWML4 | PC21 | + * 10 NPCS0 | PA28 | + * TIOB7 | PC29 | + * 11 TIOA8 | PD7 | + * 12 TIOB8 | PD8 | + * 13 TIOB0 | PB27 | LED AMBER "L" + * 14 TXD3 | PD4 | "TX3" + * 15 RXD3 | PD5 | "RX3" + * 16 TXD1 | PA13 | "TX2" + * 17 RXD1 | PA12 | "RX2" + * 18 TXD0 | PA11 | "TX1" + * 19 RXD0 | PA10 | "RX1" + * 20 | PB12 | "SDA" + * 21 | PB13 | "SCL" + * 22 | PB26 | + * 23 | PA14 | + * 24 | PA15 | + * 25 | PD0 | + * 26 | PD1 | + * 27 | PD2 | + * 28 | PD3 | + * 29 | PD6 | + * 30 | PD9 | + * 31 | PA7 | + * 32 | PD10 | + * 33 | PC1 | + * 34 | PC2 | + * 35 | PC3 | + * 36 | PC4 | + * 37 | PC5 | + * 38 | PC6 | + * 39 | PC7 | + * 40 | PC8 | + * 41 | PC9 | + * 42 | PA19 | + * 43 | PA20 | + * 44 | PC19 | + * 45 | PC18 | + * 46 | PC17 | + * 47 | PC16 | + * 48 | PC15 | + * 49 | PC14 | + * 50 | PC13 | + * 51 | PC12 | + * 52 NPCS2 | PB21 | + * 53 | PB14 | + * 54 | PA16 | "A0" + * 55 | PA24 | "A1" + * 56 | PA23 | "A2" + * 57 | PA22 | "A3" + * 58 TIOB2 | PA6 | "A4" + * 69 | PA4 | "A5" + * 60 TIOB1 | PA3 | "A6" + * 61 TIOA1 | PA2 | "A7" + * 62 | PB17 | "A8" + * 63 | PB18 | "A9" + * 64 | PB19 | "A10" + * 65 | PB20 | "A11" + * 66 | PB15 | "DAC0" + * 67 | PB16 | "DAC1" + * 68 | PA1 | "CANRX" + * 69 | PA0 | "CANTX" + * 70 | PA17 | "SDA1" + * 71 | PA18 | "SCL1" + * 72 | PC30 | LED AMBER "RX" + * 73 | PA21 | LED AMBER "TX" + * 74 MISO | PA25 | + * 75 MOSI | PA26 | + * 76 SCLK | PA27 | + * 77 NPCS0 | PA28 | + * 78 NPCS3 | PB23 | unconnected! + * + * USB pin | PORT + * ----------------+-------- + * ID | PB11 + * VBOF | PB10 + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Pins descriptions + */ +extern const PinDescription g_APinDescription[]= +{ + // 0 .. 53 - Digital pins + // ---------------------- + // 0/1 - UART (Serial) + { PIOA, PIO_PA8A_URXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // URXD + { PIOA, PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // UTXD + + // 2 + { PIOB, PIO_PB25B_TIOA0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHA0 }, // TIOA0 + { PIOC, PIO_PC28B_TIOA7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA7 }, // TIOA7 + { PIOC, PIO_PC26B_TIOB6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB6 }, // TIOB6 + + // 5 + { PIOC, PIO_PC25B_TIOA6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA6 }, // TIOA6 + { PIOC, PIO_PC24B_PWML7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH7, NOT_ON_TIMER }, // PWML7 + { PIOC, PIO_PC23B_PWML6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH6, NOT_ON_TIMER }, // PWML6 + { PIOC, PIO_PC22B_PWML5, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH5, NOT_ON_TIMER }, // PWML5 + { PIOC, PIO_PC21B_PWML4, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH4, NOT_ON_TIMER }, // PWML4 + // 10 + { PIOC, PIO_PC29B_TIOB7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB7 }, // TIOB7 + { PIOD, PIO_PD7B_TIOA8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA8 }, // TIOA8 + { PIOD, PIO_PD8B_TIOB8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB8 }, // TIOB8 + + // 13 - AMBER LED + { PIOB, PIO_PB27B_TIOB0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHB0 }, // TIOB0 + + // 14/15 - USART3 (Serial3) + { PIOD, PIO_PD4B_TXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD3 + { PIOD, PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD3 + + // 16/17 - USART1 (Serial2) + { PIOA, PIO_PA13A_TXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD1 + { PIOA, PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD1 + + // 18/19 - USART0 (Serial1) + { PIOA, PIO_PA11A_TXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD0 + { PIOA, PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD0 + + // 20/21 - TWI1 + { PIOB, PIO_PB12A_TWD1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD1 - SDA0 + { PIOB, PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK1 - SCL0 + + // 22 + { PIOB, PIO_PB26, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 22 + { PIOA, PIO_PA14, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 23 + { PIOA, PIO_PA15, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 24 + { PIOD, PIO_PD0, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 25 + + // 26 + { PIOD, PIO_PD1, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 26 + { PIOD, PIO_PD2, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 27 + { PIOD, PIO_PD3, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 28 + { PIOD, PIO_PD6, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 29 + + // 30 + { PIOD, PIO_PD9, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 30 + { PIOA, PIO_PA7, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 31 + { PIOD, PIO_PD10, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 32 + { PIOC, PIO_PC1, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 33 + + // 34 + { PIOC, PIO_PC2, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 34 + { PIOC, PIO_PC3, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 35 + { PIOC, PIO_PC4, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 36 + { PIOC, PIO_PC5, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 37 + + // 38 + { PIOC, PIO_PC6, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 38 + { PIOC, PIO_PC7, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 39 + { PIOC, PIO_PC8, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 40 + { PIOC, PIO_PC9, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 41 + + // 42 + { PIOA, PIO_PA19, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 42 + { PIOA, PIO_PA20, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 43 + { PIOC, PIO_PC19, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 44 + { PIOC, PIO_PC18, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 45 + + // 46 + { PIOC, PIO_PC17, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 46 + { PIOC, PIO_PC16, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 47 + { PIOC, PIO_PC15, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 48 + { PIOC, PIO_PC14, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 49 + + // 50 + { PIOC, PIO_PC13, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 50 + { PIOC, PIO_PC12, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 51 + { PIOB, PIO_PB21, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 52 + { PIOB, PIO_PB14, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 53 + + + // 54 .. 65 - Analog pins + // ---------------------- + { PIOA, PIO_PA16X1_AD7, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC7, NOT_ON_PWM, NOT_ON_TIMER }, // AD0 + { PIOA, PIO_PA24X1_AD6, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC1, ADC6, NOT_ON_PWM, NOT_ON_TIMER }, // AD1 + { PIOA, PIO_PA23X1_AD5, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC2, ADC5, NOT_ON_PWM, NOT_ON_TIMER }, // AD2 + { PIOA, PIO_PA22X1_AD4, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC3, ADC4, NOT_ON_PWM, NOT_ON_TIMER }, // AD3 + // 58 + { PIOA, PIO_PA6X1_AD3, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC4, ADC3, NOT_ON_PWM, TC0_CHB2 }, // AD4 + { PIOA, PIO_PA4X1_AD2, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC5, ADC2, NOT_ON_PWM, NOT_ON_TIMER }, // AD5 + { PIOA, PIO_PA3X1_AD1, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC6, ADC1, NOT_ON_PWM, TC0_CHB1 }, // AD6 + { PIOA, PIO_PA2X1_AD0, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC7, ADC0, NOT_ON_PWM, TC0_CHA1 }, // AD7 + // 62 + { PIOB, PIO_PB17X1_AD10, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC8, ADC10, NOT_ON_PWM, NOT_ON_TIMER }, // AD8 + { PIOB, PIO_PB18X1_AD11, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC9, ADC11, NOT_ON_PWM, NOT_ON_TIMER }, // AD9 + { PIOB, PIO_PB19X1_AD12, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC10, ADC12, NOT_ON_PWM, NOT_ON_TIMER }, // AD10 + { PIOB, PIO_PB20X1_AD13, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC11, ADC13, NOT_ON_PWM, NOT_ON_TIMER }, // AD11 + + // 66/67 - DAC0/DAC1 + { PIOB, PIO_PB15X1_DAC0, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC12, DA0, NOT_ON_PWM, NOT_ON_TIMER }, // DAC0 + { PIOB, PIO_PB16X1_DAC1, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC13, DA1, NOT_ON_PWM, NOT_ON_TIMER }, // DAC1 + + // 68/69 - CANRX0/CANTX0 + { PIOA, PIO_PA1A_CANRX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC14, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX + { PIOA, PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC15, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX + + // 70/71 - TWI0 + { PIOA, PIO_PA17A_TWD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD0 - SDA1 + { PIOA, PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK0 - SCL1 + + // 72/73 - LEDs + { PIOC, PIO_PC30, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER RXL + { PIOA, PIO_PA21, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER TXL + + // 74/75/76 - SPI + { PIOA, PIO_PA25A_SPI0_MISO,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MISO + { PIOA, PIO_PA26A_SPI0_MOSI,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MOSI + { PIOA, PIO_PA27A_SPI0_SPCK,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // SPCK + + // 77 - SPI CS0 + { PIOA, PIO_PA28A_SPI0_NPCS0,ID_PIOA,PIO_PERIPH_A,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS0 + + // 78 - SPI CS3 (unconnected) + { PIOB, PIO_PB23B_SPI0_NPCS3,ID_PIOB,PIO_PERIPH_B,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS3 + + // 79 .. 84 - "All pins" masks + + // 79 - TWI0 all pins + { PIOA, PIO_PA17A_TWD0|PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 80 - TWI1 all pins + { PIOB, PIO_PB12A_TWD1|PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 81 - UART (Serial) all pins + { PIOA, PIO_PA8A_URXD|PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 82 - USART0 (Serial1) all pins + { PIOA, PIO_PA11A_TXD0|PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 83 - USART1 (Serial2) all pins + { PIOA, PIO_PA13A_TXD1|PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 84 - USART3 (Serial3) all pins + { PIOD, PIO_PD4B_TXD3|PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + + // 85 - USB + { PIOB, PIO_PB11A_UOTGID|PIO_PB10A_UOTGVBOF, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF + + // 86 - SPI CS2 + { PIOB, PIO_PB21B_SPI0_NPCS2, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS2 + + // 87 - SPI CS1 + { PIOA, PIO_PA29A_SPI0_NPCS1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS1 + + // 88/89 - CANRX1/CANTX1 (same physical pin for 66/53) + { PIOB, PIO_PB15A_CANRX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX1 + { PIOB, PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX1 + + // 90 .. 91 - "All CAN pins" masks + // 90 - CAN0 all pins + { PIOA, PIO_PA1A_CANRX0|PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + // 91 - CAN1 all pins + { PIOB, PIO_PB15A_CANRX1|PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, + + // END + { NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER } +} ; + + +uint8_t g_pinStatus[PINS_COUNT] = {0}; + +#ifdef __cplusplus +} +#endif + +/* + * UART objects + */ +RingBuffer rx_buffer1; +RingBuffer tx_buffer1; + +UARTClass Serial(UART, UART_IRQn, ID_UART, &rx_buffer1, &tx_buffer1); +void serialEvent() __attribute__((weak)); +void serialEvent() { } + +// IT handlers +void UART_Handler(void) +{ + Serial.IrqHandler(); +} + +// ---------------------------------------------------------------------------- +/* + * USART objects + */ +RingBuffer rx_buffer2; +RingBuffer rx_buffer3; +RingBuffer rx_buffer4; +RingBuffer tx_buffer2; +RingBuffer tx_buffer3; +RingBuffer tx_buffer4; + +USARTClass Serial1(USART0, USART0_IRQn, ID_USART0, &rx_buffer2, &tx_buffer2); +void serialEvent1() __attribute__((weak)); +void serialEvent1() { } +USARTClass Serial2(USART1, USART1_IRQn, ID_USART1, &rx_buffer3, &tx_buffer3); +void serialEvent2() __attribute__((weak)); +void serialEvent2() { } +USARTClass Serial3(USART3, USART3_IRQn, ID_USART3, &rx_buffer4, &tx_buffer4); +void serialEvent3() __attribute__((weak)); +void serialEvent3() { } + +// IT handlers +void USART0_Handler(void) +{ + Serial1.IrqHandler(); +} + +void USART1_Handler(void) +{ + Serial2.IrqHandler(); +} + +void USART3_Handler(void) +{ + Serial3.IrqHandler(); +} + +// ---------------------------------------------------------------------------- + +void serialEventRun(void) +{ + if (Serial.available()) serialEvent(); + if (Serial1.available()) serialEvent1(); + if (Serial2.available()) serialEvent2(); + if (Serial3.available()) serialEvent3(); +} + +// ---------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +void __libc_init_array(void); + +void init( void ) +{ + SystemInit(); + + // Set Systick to 1ms interval, common to all SAM3 variants + if (SysTick_Config(SystemCoreClock / 1000)) + { + // Capture error + while (true); + } + + // Initialize C library + __libc_init_array(); + + // Disable pull-up on every pin + for (unsigned i = 0; i < PINS_COUNT; i++) + digitalWrite(i, LOW); + + // Enable parallel access on PIO output data registers + PIOA->PIO_OWER = 0xFFFFFFFF; + PIOB->PIO_OWER = 0xFFFFFFFF; + PIOC->PIO_OWER = 0xFFFFFFFF; + PIOD->PIO_OWER = 0xFFFFFFFF; + + // Initialize Serial port U(S)ART pins + PIO_Configure( + g_APinDescription[PINS_UART].pPort, + g_APinDescription[PINS_UART].ulPinType, + g_APinDescription[PINS_UART].ulPin, + g_APinDescription[PINS_UART].ulPinConfiguration); + digitalWrite(0, HIGH); // Enable pullup for RX0 + PIO_Configure( + g_APinDescription[PINS_USART0].pPort, + g_APinDescription[PINS_USART0].ulPinType, + g_APinDescription[PINS_USART0].ulPin, + g_APinDescription[PINS_USART0].ulPinConfiguration); + PIO_Configure( + g_APinDescription[PINS_USART1].pPort, + g_APinDescription[PINS_USART1].ulPinType, + g_APinDescription[PINS_USART1].ulPin, + g_APinDescription[PINS_USART1].ulPinConfiguration); + PIO_Configure( + g_APinDescription[PINS_USART3].pPort, + g_APinDescription[PINS_USART3].ulPinType, + g_APinDescription[PINS_USART3].ulPin, + g_APinDescription[PINS_USART3].ulPinConfiguration); + + // Initialize USB pins + PIO_Configure( + g_APinDescription[PINS_USB].pPort, + g_APinDescription[PINS_USB].ulPinType, + g_APinDescription[PINS_USB].ulPin, + g_APinDescription[PINS_USB].ulPinConfiguration); + + // Initialize CAN pins + PIO_Configure( + g_APinDescription[PINS_CAN0].pPort, + g_APinDescription[PINS_CAN0].ulPinType, + g_APinDescription[PINS_CAN0].ulPin, + g_APinDescription[PINS_CAN0].ulPinConfiguration); + PIO_Configure( + g_APinDescription[PINS_CAN1].pPort, + g_APinDescription[PINS_CAN1].ulPinType, + g_APinDescription[PINS_CAN1].ulPin, + g_APinDescription[PINS_CAN1].ulPinConfiguration); + + // Initialize Analog Controller + pmc_enable_periph_clk(ID_ADC); + adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST); + adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1); + adc_configure_trigger(ADC, ADC_TRIG_SW, 0); // Disable hardware trigger. + adc_disable_interrupt(ADC, 0xFFFFFFFF); // Disable all ADC interrupts. + adc_disable_all_channel(ADC); + + // Initialize analogOutput module + analogOutputInit(); +} + +#ifdef __cplusplus +} +#endif +