diff --git a/0BUILD b/0BUILD index c6780a5..160de7f 100644 --- a/0BUILD +++ b/0BUILD @@ -2,7 +2,7 @@ - + $(project_name) $(project_vmajor).$(project_vminor).$(project_vpatchlevel) @@ -51,6 +51,8 @@ $(includedir)/aqhome/$(package) $(datadir)/$(package) + /var/www + + signal.h sys/stat.h diff --git a/apps/aqhome-cgi/0BUILD b/apps/aqhome-cgi/0BUILD index 1cc8bdf..3fc42e3 100644 --- a/apps/aqhome-cgi/0BUILD +++ b/apps/aqhome-cgi/0BUILD @@ -3,7 +3,7 @@ - + $(gwenhywfar_cflags) @@ -55,6 +55,7 @@ $(gwenhywfar_libs) -lm + $(aqcgi_libs) @@ -117,6 +118,7 @@ aqhome aqhcgi_service + aqhcgi_modules @@ -127,6 +129,7 @@ service + modules diff --git a/apps/aqhome-cgi/README b/apps/aqhome-cgi/README new file mode 100644 index 0000000..9a1da88 --- /dev/null +++ b/apps/aqhome-cgi/README @@ -0,0 +1,23 @@ + + +Modules: +- login +- signup +- main +- devices + - list + - show?name="nodes/12345678" + - add + - edit + - delete +- values +- rooms + +- users + - list + - show?alias="admin" + - add + - edit + - delete + +- dashboards diff --git a/apps/aqhome-cgi/main.c b/apps/aqhome-cgi/main.c index b9676a7..b02433b 100644 --- a/apps/aqhome-cgi/main.c +++ b/apps/aqhome-cgi/main.c @@ -1,11 +1,181 @@ +#include "./service_file.h" +#include "aqhome-cgi/modules/mroot.h" +#include "aqhome/aqhome.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + + +#define AQHOME_CGI_LOGFILE "/var/www/aqhome-cgi/log/aqhome-cgi.log" + +#define AQHOME_CGI_DEFAULT_STATIC_FILES "0-build/services/static" +#define AQHOME_CGI_DEFAULT_RUNTIME_FILES "0-build/services/runtime" + + + +void _handleRequest(AQCGI_REQUEST *rq, const char *sPathStaticFiles, const char *sPathRuntimeFiles); +int _handlePath(AQH_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles); +AQH_MODULE *_loadModule(AQH_SERVICE *sv, AQCGI_REQUEST *rq, AQH_MODULE *mParent, const char *sModuleName); +static void logStart(void); int main(int argc, char **argv) { + GWEN_GUI *gui; + AQCGI_REQUEST *rq; + + GWEN_Init(); + gui=GWEN_NoGui_new(); + GWEN_Gui_SetGui(gui); + + logStart(); + GWEN_Logger_Open(GWEN_LOGDOMAIN, "gwenhywfar", AQHOME_CGI_LOGFILE, GWEN_LoggerType_File, GWEN_LoggerFacility_Daemon); + GWEN_Logger_Open(AQH_LOGDOMAIN, "aqhome", AQHOME_CGI_LOGFILE, GWEN_LoggerType_File, GWEN_LoggerFacility_Daemon); + GWEN_Logger_Open(AQCGI_LOGDOMAIN, "aqcgi", AQHOME_CGI_LOGFILE, GWEN_LoggerType_File, GWEN_LoggerFacility_Daemon); + GWEN_Logger_Open(NULL, "aqhome-cgi", AQHOME_CGI_LOGFILE, GWEN_LoggerType_File, GWEN_LoggerFacility_Daemon); + + GWEN_Logger_SetLevel(GWEN_LOGDOMAIN, GWEN_LoggerLevel_Debug); + GWEN_Logger_SetLevel(AQCGI_LOGDOMAIN, GWEN_LoggerLevel_Debug); + GWEN_Logger_SetLevel(NULL, GWEN_LoggerLevel_Debug); + + DBG_ERROR(NULL, "Init CGI"); + AQCGI_Init(); + + GWEN_Logger_Close(GWEN_LOGDOMAIN); + GWEN_Logger_Open(GWEN_LOGDOMAIN, "gwenhywfar", AQHOME_CGI_LOGFILE, GWEN_LoggerType_File, GWEN_LoggerFacility_Daemon); + + GWEN_Logger_SetLevel(GWEN_LOGDOMAIN, GWEN_LoggerLevel_Debug); + GWEN_Logger_SetLevel(AQCGI_LOGDOMAIN, GWEN_LoggerLevel_Debug); + GWEN_Logger_SetLevel(NULL, GWEN_LoggerLevel_Debug); + + rq=AQCGI_ReadRequest(); + if (rq) { + const char *sPathStaticFiles; + const char *sPathRuntimeFiles; + + sPathStaticFiles=getenv("AQHOME_STATIC_FILES"); + if (!(sPathStaticFiles && *sPathStaticFiles)) + sPathStaticFiles=AQHOME_CGI_DEFAULT_STATIC_FILES; + + sPathRuntimeFiles=getenv("AQHOME_RUNTIME_FILES"); + if (!(sPathRuntimeFiles && *sPathRuntimeFiles)) + sPathRuntimeFiles=AQHOME_CGI_DEFAULT_RUNTIME_FILES; + + _handleRequest(rq, sPathStaticFiles, sPathRuntimeFiles); + } + else { + fprintf(stdout, "Content-type: text/plain\n\n"); + fprintf(stdout, "Error: No Request!\n"); + return 0; + } + + AQCGI_Fini(); + return 0; } + +void _handleRequest(AQCGI_REQUEST *rq, const char *sPathStaticFiles, const char *sPathRuntimeFiles) +{ + AQH_SERVICE *sv; + int rv; + + sv=AQH_ServiceFiles_new(sPathRuntimeFiles); + + rv=_handlePath(sv, rq, sPathStaticFiles); + if (rv<0) { + } + AQH_Service_free(sv); +} + + + +int _handlePath(AQH_SERVICE *sv, AQCGI_REQUEST *rq, const char *sPathStaticFiles) +{ + AQH_MODULE *mRoot; + AQH_MODULE *mParent; + const GWEN_STRINGLIST *sl; + + mRoot=AQH_ModRoot_new(sv, sPathStaticFiles); + mParent=mRoot; + + sl=AQCGI_Request_GetStringlistPath(rq); + if (sl) { + GWEN_STRINGLISTENTRY *se; + + se=GWEN_StringList_FirstEntry(sl); + while(se) { + GWEN_STRINGLISTENTRY *seNext; + const char *s; + + seNext=GWEN_StringListEntry_Next(se); + s=GWEN_StringListEntry_Data(se); + if (s && *s) { + if (seNext) { + AQH_MODULE *m; + + DBG_ERROR(NULL, "Entry: %s (%s)", s, seNext?"not last":"last"); + m=AQH_ModService_LoadSubModule(mParent, rq, s); + if (m==NULL) { + AQH_Module_free(mRoot); + AQCGI_SendResponseWithStatus(rq, 404, "Not found"); + return GWEN_ERROR_GENERIC; + } + mParent=m; + } + else { + int rv; + + /* last, let module handle remaining part */ + rv=AQH_ModService_HandleRequest(mParent, rq, s); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + AQH_Module_free(mRoot); + return rv; + } + break; + } + } + + se=seNext; + } + AQH_Module_free(mRoot); + return 0; + } + else { + AQH_Module_free(mRoot); + return GWEN_ERROR_GENERIC; + } +} + + + +void logStart() +{ + FILE *f; + + f=fopen(AQHOME_CGI_LOGFILE, "a+"); + if (f!=NULL) { + fprintf(f, "Started.\n"); + fclose(f); + } +} + + + + + diff --git a/apps/aqhome-cgi/modules/0BUILD b/apps/aqhome-cgi/modules/0BUILD new file mode 100644 index 0000000..ac02ab6 --- /dev/null +++ b/apps/aqhome-cgi/modules/0BUILD @@ -0,0 +1,84 @@ + + + + + + + + $(gwenhywfar_cflags) + -I$(topsrcdir) + -I$(topbuilddir) + -I$(topsrcdir)/apps + -I$(topbuilddir)/apps + -I$(builddir) + -I$(srcdir) + + + + --include=$(builddir) + --include=$(srcdir) + + + + + + $(visibility_cflags) + + + + --api=AQHOME_API + + + + + + + + + + + + + + + + + + $(local/built_headers_pub) + + + + + mservice.h + mroot.h + + + + + mservice_p.h + mroot_p.h + + + + + $(local/typefiles) + + mservice.c + mroot.c + + + + + + + + + + + + static + + + + + diff --git a/apps/aqhome-cgi/modules/mroot.c b/apps/aqhome-cgi/modules/mroot.c new file mode 100644 index 0000000..24e4375 --- /dev/null +++ b/apps/aqhome-cgi/modules/mroot.c @@ -0,0 +1,246 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "./mroot_p.h" + +#include "aqhome-cgi/service/module.h" + +#include +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defs and enums + * ------------------------------------------------------------------------------------------------ + */ + +/* ------------------------------------------------------------------------------------------------ + * global vars + * ------------------------------------------------------------------------------------------------ + */ + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sModuleName); +static int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sLastPathElem); +static int _handleRqLogin(AQH_MODULE *m, AQCGI_REQUEST *rq); +static int _handleRqLoginPost(AQH_MODULE *m, AQCGI_REQUEST *rq); +static AQH_USER *_getAndCheckUser(AQH_MODULE *m, AQCGI_REQUEST *rq); + + +/* ------------------------------------------------------------------------------------------------ + * code + * ------------------------------------------------------------------------------------------------ + */ + +AQH_MODULE *AQH_ModRoot_new(AQH_SERVICE *sv, const char *baseFolder) +{ + AQH_MODULE *m; + + m=AQH_ModService_new(sv, baseFolder); + AQH_ModService_SetHandleRequestFn(m, _handleRequest); + AQH_ModService_SetLoadSubModuleFn(m, _loadSubModule); + + return m; +} + + + +AQH_MODULE *_loadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sModuleName) +{ + return NULL; +} + + + +int _handleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sLastPathElem) +{ + if (strcasecmp(sLastPathElem, "login")==0) + return _handleRqLogin(m, rq); + else if (strcasecmp(sLastPathElem, "signup")==0) { + AQCGI_SendResponseWithStatus(rq, 501, "Not Implemented"); + return GWEN_ERROR_NOT_IMPLEMENTED; + } + else if (strcasecmp(sLastPathElem, "confirm")==0) { + AQCGI_SendResponseWithStatus(rq, 501, "Not Implemented"); + return GWEN_ERROR_NOT_IMPLEMENTED; + } + else { + AQCGI_SendResponseWithStatus(rq, 404, "Not Found"); + return GWEN_ERROR_NOT_IMPLEMENTED; + } +} + + + +int _handleRqLogin(AQH_MODULE *m, AQCGI_REQUEST *rq) +{ + int rv; + + if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_GET) + rv=AQH_ModService_RespondWithFile(m, rq, "en", "login.html"); + else if (AQCGI_Request_GetRequestMethod(rq)==AQCGI_REQUEST_METHOD_POST) + rv=_handleRqLoginPost(m, rq); + else { + DBG_ERROR(NULL, "Invalid request method %d", AQCGI_Request_GetRequestMethod(rq)); + AQCGI_SendResponseWithStatus(rq, 405, "Method No Allowed"); + return GWEN_ERROR_INVALID; + } + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } + return 0; +} + + + +int _handleRqLoginPost(AQH_MODULE *m, AQCGI_REQUEST *rq) +{ + AQH_SERVICE *sv; + AQH_USER *user; + AQH_SESSION *session; + GWEN_BUFFER *dbuf; + GWEN_TIMESTAMP *ts; + int rv; + + DBG_ERROR(NULL, "Handling request"); + sv=AQH_ModService_GetService(m); + user=_getAndCheckUser(m, rq); + if (user==NULL) { + DBG_INFO(NULL, "here"); + return GWEN_ERROR_GENERIC; + } + + ts=GWEN_Timestamp_NowInLocalTime(); + AQH_User_SetTimestampLastLogin(user, ts); + DBG_ERROR(NULL, "Saving user"); + rv=AQH_Service_SaveUser(sv, user); + if (rv<0) { + DBG_ERROR(NULL, "Error saving user \"%s\"", AQH_User_GetAlias(user)); + AQCGI_SendResponseWithStatus(rq, 500, "Internal Error"); + AQH_User_free(user); + return rv; + } + + /* generate session */ + DBG_ERROR(NULL, "Generating session"); + dbuf=GWEN_Buffer_new(0, 64, 0, 1); + AQCGI_GenerateSessionId(dbuf); + session=AQH_Session_new(); + AQH_Session_SetTimestampCreation(session, ts); + AQH_Session_SetTimestampLastAccess(session, ts); + AQH_Session_SetUid(session, GWEN_Buffer_GetStart(dbuf)); + GWEN_Buffer_free(dbuf); + AQH_Session_SetUserAlias(session, AQH_User_GetAlias(user)); + rv=AQH_Service_AddSession(sv, session); + if (rv<0) { + DBG_ERROR(NULL, "Error adding session for user \"%s\"", AQH_User_GetAlias(user)); + AQCGI_SendResponseWithStatus(rq, 500, "Internal Error"); + AQH_Session_free(session); + AQH_User_free(user); + return GWEN_ERROR_INTERNAL; + } + + /* add Set-Cookie header */ + dbuf=GWEN_Buffer_new(0, 256, 0, 1); + GWEN_Buffer_AppendArgs(dbuf, "Set-Cookie: session=%s; max-age=3600", AQH_Session_GetUid(session)); + AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(dbuf)); + + /* finish */ + AQCGI_SendResponseWithStatus(rq, 200, "Ok"); + AQH_Session_free(session); + AQH_User_free(user); + + return 0; +} + + + +AQH_USER *_getAndCheckUser(AQH_MODULE *m, AQCGI_REQUEST *rq) +{ + GWEN_DB_NODE *dbPost; + + dbPost=AQCGI_Request_GetDbPostBody(rq); + if (dbPost) { + AQH_SERVICE *sv; + const char *sUserName; + const char *sPasswd; + AQH_USER *user; + const char *hashedPaswd; + GWEN_BUFFER *buf; + + sv=AQH_ModService_GetService(m); + sUserName=GWEN_DB_GetCharValue(dbPost, "userid", 0, NULL); + sPasswd=GWEN_DB_GetCharValue(dbPost, "password", 0, NULL); + if (!(sUserName && *sUserName && sPasswd && *sPasswd)) { + DBG_ERROR(NULL, "Either user name or password missing"); + AQCGI_SendResponseWithStatus(rq, 400, "Bad Request"); + return NULL; + } + + DBG_ERROR(NULL, "Loading user \"%s\" (%p)", sUserName, sv); + user=AQH_Service_LoadUser(sv, sUserName); + if (user==NULL) { + DBG_ERROR(NULL, "User \"%s\" not found", sUserName); + AQCGI_SendResponseWithStatus(rq, 403, "Forbidden"); + return NULL; + } + DBG_ERROR(NULL, "Loaded user \"%s\"", sUserName); + + if (AQH_User_GetState(user)!=AQH_UserState_Active) { + DBG_ERROR(NULL, "User \"%s\" not active", sUserName); + AQCGI_SendResponseWithStatus(rq, 403, "Forbidden"); + AQH_User_free(user); + return NULL; + } + + hashedPaswd=AQH_User_GetHashedPassword(user); + if (!(hashedPaswd && *hashedPaswd)) { + DBG_ERROR(NULL, "User \"%s\" has no hashed password", sUserName); + AQCGI_SendResponseWithStatus(rq, 403, "Forbidden"); + AQH_User_free(user); + return NULL; + } + buf=GWEN_Buffer_new(0, 256, 0, 1); + AQCGI_HashMd256ToBuffer(sPasswd, buf); + DBG_ERROR(NULL, "Hashed password: [%s]", GWEN_Buffer_GetStart(buf)); + if (strcasecmp(GWEN_Buffer_GetStart(buf), hashedPaswd)!=0) { + DBG_ERROR(NULL, "Bad password for user \"%s\"", sUserName); + AQCGI_SendResponseWithStatus(rq, 403, "Forbidden"); + GWEN_Buffer_free(buf); + AQH_User_free(user); + return NULL; + } + GWEN_Buffer_free(buf); + + DBG_ERROR(NULL, "User \"%s\" accepted", sUserName); + return user; + } + else { + DBG_ERROR(NULL, "No POST data"); + AQCGI_SendResponseWithStatus(rq, 400, "Bad Request"); + return NULL; + } +} + + + + + + + diff --git a/apps/aqhome-cgi/modules/mroot.h b/apps/aqhome-cgi/modules/mroot.h new file mode 100644 index 0000000..377a6fb --- /dev/null +++ b/apps/aqhome-cgi/modules/mroot.h @@ -0,0 +1,27 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOME_CGI_MROOT_H +#define AQHOME_CGI_MROOT_H + +#include + +#include + +#include + + +AQH_MODULE *AQH_ModRoot_new(AQH_SERVICE *sv, const char *baseFolder); + +AQH_MODULE *AQH_ModRoot_LoadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sModuleName); +int AQH_ModRoot_HandleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sLastPathElem); + + + +#endif + diff --git a/apps/aqhome-cgi/modules/mroot_p.h b/apps/aqhome-cgi/modules/mroot_p.h new file mode 100644 index 0000000..eae16f9 --- /dev/null +++ b/apps/aqhome-cgi/modules/mroot_p.h @@ -0,0 +1,18 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOME_CGI_MROOT_P_H +#define AQHOME_CGI_MROOT_P_H + +#include "aqhome-cgi/modules/mroot.h" + + + + +#endif + diff --git a/apps/aqhome-cgi/modules/mservice.c b/apps/aqhome-cgi/modules/mservice.c new file mode 100644 index 0000000..7d1c9dd --- /dev/null +++ b/apps/aqhome-cgi/modules/mservice.c @@ -0,0 +1,291 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "./mservice_p.h" + +#include "aqhome-cgi/service/module.h" + +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defs and enums + * ------------------------------------------------------------------------------------------------ + */ + +#define AQH_MOD_SERVICE_HEADERFILE "header.html" +#define AQH_MOD_SERVICE_FOOTERFILE "footer.html" + + + +/* ------------------------------------------------------------------------------------------------ + * global vars + * ------------------------------------------------------------------------------------------------ + */ + +GWEN_INHERIT(AQH_MODULE, AQH_MOD_SERVICE) + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static void GWENHYWFAR_CB _freeData(void *bp, void *p); + + + +/* ------------------------------------------------------------------------------------------------ + * code + * ------------------------------------------------------------------------------------------------ + */ + +AQH_MODULE *AQH_ModService_new(AQH_SERVICE *sv, const char *baseFolder) +{ + AQH_MODULE *m; + AQH_MOD_SERVICE *xm; + + m=AQH_Module_new(); + GWEN_NEW_OBJECT(AQH_MOD_SERVICE, xm); + GWEN_INHERIT_SETDATA(AQH_MODULE, AQH_MOD_SERVICE, m, xm, _freeData); + + xm->service=sv; + xm->baseFolder=(baseFolder && *baseFolder)?strdup(baseFolder):NULL; + + return m; +} + + + +void _freeData(GWEN_UNUSED void *bp, void *p) +{ + AQH_MOD_SERVICE *xm; + + xm=(AQH_MOD_SERVICE*) p; + free(xm->baseFolder); + GWEN_FREE_OBJECT(xm); +} + + + +AQH_SERVICE *AQH_ModService_GetService(const AQH_MODULE *m) +{ + if (m) { + AQH_MOD_SERVICE *xm; + + xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); + if (xm) { + return xm->service; + } + } + return NULL; +} + + + +const char *AQH_ModService_GetBaseFolder(const AQH_MODULE *m) +{ + if (m) { + AQH_MOD_SERVICE *xm; + + xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); + if (xm) { + return xm->baseFolder; + } + } + return NULL; +} + + + +void AQH_ModService_SetHandleRequestFn(AQH_MODULE *m, AQH_MODSERVICE_HANDLEREQUEST_FN fn) +{ + if (m) { + AQH_MOD_SERVICE *xm; + + xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); + if (xm) { + xm->handleRequestFn=fn; + } + } +} + + + +void AQH_ModService_SetLoadSubModuleFn(AQH_MODULE *m, AQH_MODSERVICE_LOADSUBMODULE_FN fn) +{ + if (m) { + AQH_MOD_SERVICE *xm; + + xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); + if (xm) { + xm->loadSubModuleFn=fn; + } + } +} + + + +int AQH_ModService_AddHeader(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf) +{ + if (m && dbuf) { + AQH_MODULE *mParent; + + mParent=AQH_Module_Tree2_GetParent(m); + if (mParent) { + int rv; + + rv=AQH_ModService_AddHeader(mParent, lang, dbuf); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } + } + return AQH_ModService_ReadStaticFile(m, lang, AQH_MOD_SERVICE_HEADERFILE, dbuf); + } + DBG_ERROR(NULL, "Argument missing"); + return GWEN_ERROR_INVALID; +} + + + +int AQH_ModService_AddFooter(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf) +{ + if (m && dbuf) { + AQH_MODULE *mParent; + int rv; + + rv=AQH_ModService_ReadStaticFile(m, lang, AQH_MOD_SERVICE_FOOTERFILE, dbuf); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } + + mParent=AQH_Module_Tree2_GetParent(m); + if (mParent) { + int rv; + + rv=AQH_ModService_AddFooter(mParent, lang, dbuf); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } + } + return 0; + } + else { + DBG_ERROR(NULL, "Argument missing"); + return GWEN_ERROR_INVALID; + } +} + + + +int AQH_ModService_RespondWithFile(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *lang, const char *sFilename) +{ + GWEN_BUFFER *buf; + int rv; + + buf=GWEN_Buffer_new(0, 256, 0, 1); + rv=AQH_ModService_AddHeader(m, lang, buf); + if (rv<0) { + AQCGI_SendResponseWithStatus(rq, 500, "Internal error"); + GWEN_Buffer_free(buf); + return GWEN_ERROR_INTERNAL; + } + rv=AQH_ModService_ReadStaticFile(m, lang, sFilename, buf); + if (rv<0) { + AQCGI_SendResponseWithStatus(rq, 500, "Internal error"); + GWEN_Buffer_free(buf); + return GWEN_ERROR_INTERNAL; + } + rv=AQH_ModService_AddFooter(m, lang, buf); + if (rv<0) { + AQCGI_SendResponseWithStatus(rq, 500, "Internal error"); + GWEN_Buffer_free(buf); + return GWEN_ERROR_INTERNAL; + } + AQCGI_Request_SetBufferResponseBody(rq, buf); + AQCGI_Request_AddResponseHeaderData(rq, "Content-type: text/html"); + AQCGI_SendResponseWithStatus(rq, 200, "Ok"); + + return 0; +} + + + +int AQH_ModService_HandleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sLastPathElem) +{ + if (m) { + AQH_MOD_SERVICE *xm; + + xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); + if (xm && xm->handleRequestFn) + return xm->handleRequestFn(m, rq, sLastPathElem); + } + return GWEN_ERROR_NOT_IMPLEMENTED; +} + + + +AQH_MODULE *AQH_ModService_LoadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sModuleName) +{ + if (m) { + AQH_MOD_SERVICE *xm; + + xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); + if (xm && xm->loadSubModuleFn) + return xm->loadSubModuleFn(m, rq, sModuleName); + } + return NULL; +} + + + +int AQH_ModService_ReadStaticFile(AQH_MODULE *m, const char *lang, const char *filename, GWEN_BUFFER *dbuf) +{ + if (m && filename && dbuf) { + AQH_MOD_SERVICE *xm; + + xm=GWEN_INHERIT_GETDATA(AQH_MODULE, AQH_MOD_SERVICE, m); + if (xm) { + GWEN_BUFFER *fbuf; + int rv; + + fbuf=GWEN_Buffer_new(0, 256, 0, 1); + GWEN_Buffer_AppendString(fbuf, xm->baseFolder); + GWEN_Buffer_AppendString(fbuf, GWEN_DIR_SEPARATOR_S); + GWEN_Buffer_AppendString(fbuf, (lang && *lang)?lang:"en"); + GWEN_Buffer_AppendString(fbuf, GWEN_DIR_SEPARATOR_S); + GWEN_Buffer_AppendString(fbuf, filename); + DBG_ERROR(NULL, "Reading file \"%s\"", GWEN_Buffer_GetStart(fbuf)); + rv=GWEN_SyncIo_Helper_ReadFile(GWEN_Buffer_GetStart(fbuf), dbuf); + if (rv<0) { + DBG_ERROR(NULL, "Read(%s): %d", GWEN_Buffer_GetStart(fbuf), rv); + GWEN_Buffer_free(fbuf); + return rv; + } + GWEN_Buffer_free(fbuf); + return 0; + } + } + DBG_ERROR(NULL, "Any arg is missing (or is not a AQH_MOD_SERVICE object)"); + return GWEN_ERROR_INTERNAL; +} + + + + + diff --git a/apps/aqhome-cgi/modules/mservice.h b/apps/aqhome-cgi/modules/mservice.h new file mode 100644 index 0000000..6bc7024 --- /dev/null +++ b/apps/aqhome-cgi/modules/mservice.h @@ -0,0 +1,46 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOME_CGI_MSERVICE_H +#define AQHOME_CGI_MSERVICE_H + +#include +#include + +#include + +#include + + +typedef int (*AQH_MODSERVICE_HANDLEREQUEST_FN)(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sLastPathElem); +typedef AQH_MODULE* (*AQH_MODSERVICE_LOADSUBMODULE_FN)(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sModuleName); + + + +AQH_MODULE *AQH_ModService_new(AQH_SERVICE *sv, const char *baseFolder); + +AQH_SERVICE *AQH_ModService_GetService(const AQH_MODULE *m); +const char *AQH_ModService_GetBaseFolder(const AQH_MODULE *m); + + +int AQH_ModService_AddHeader(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf); +int AQH_ModService_AddFooter(AQH_MODULE *m, const char *lang, GWEN_BUFFER *dbuf); + +AQH_MODULE *AQH_ModService_LoadSubModule(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sModuleName); +int AQH_ModService_HandleRequest(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *sLastPathElem); + +int AQH_ModService_RespondWithFile(AQH_MODULE *m, AQCGI_REQUEST *rq, const char *lang, const char *sFilename); +int AQH_ModService_ReadStaticFile(AQH_MODULE *m, const char *lang, const char *filename, GWEN_BUFFER *dbuf); + + +void AQH_ModService_SetHandleRequestFn(AQH_MODULE *m, AQH_MODSERVICE_HANDLEREQUEST_FN fn); +void AQH_ModService_SetLoadSubModuleFn(AQH_MODULE *m, AQH_MODSERVICE_LOADSUBMODULE_FN fn); + + +#endif + diff --git a/apps/aqhome-cgi/modules/mservice_p.h b/apps/aqhome-cgi/modules/mservice_p.h new file mode 100644 index 0000000..45a460a --- /dev/null +++ b/apps/aqhome-cgi/modules/mservice_p.h @@ -0,0 +1,27 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOME_CGI_MSERVICE_P_H +#define AQHOME_CGI_MSERVICE_P_H + +#include "aqhome-cgi/modules/mservice.h" + + +typedef struct AQH_MOD_SERVICE AQH_MOD_SERVICE; +struct AQH_MOD_SERVICE { + AQH_SERVICE *service; + char *baseFolder; + + AQH_MODSERVICE_HANDLEREQUEST_FN handleRequestFn; + AQH_MODSERVICE_LOADSUBMODULE_FN loadSubModuleFn; +}; + + + +#endif + diff --git a/avr/devices/x03/0BUILD b/apps/aqhome-cgi/modules/static/0BUILD similarity index 70% rename from avr/devices/x03/0BUILD rename to apps/aqhome-cgi/modules/static/0BUILD index b317b73..1bdbf2d 100644 --- a/avr/devices/x03/0BUILD +++ b/apps/aqhome-cgi/modules/static/0BUILD @@ -1,11 +1,7 @@ - - uart - ccs811 + en - - diff --git a/apps/aqhome-cgi/modules/static/en/0BUILD b/apps/aqhome-cgi/modules/static/en/0BUILD new file mode 100644 index 0000000..d99dbf2 --- /dev/null +++ b/apps/aqhome-cgi/modules/static/en/0BUILD @@ -0,0 +1,13 @@ + + + + + + header.html + footer.html + login.html + + + + + diff --git a/apps/aqhome-cgi/modules/static/en/footer.html b/apps/aqhome-cgi/modules/static/en/footer.html new file mode 100644 index 0000000..6c663b9 --- /dev/null +++ b/apps/aqhome-cgi/modules/static/en/footer.html @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/apps/aqhome-cgi/modules/static/en/header.html b/apps/aqhome-cgi/modules/static/en/header.html new file mode 100644 index 0000000..be438c3 --- /dev/null +++ b/apps/aqhome-cgi/modules/static/en/header.html @@ -0,0 +1,17 @@ + + + + + + + + + + + + +AqHome + + + + diff --git a/apps/aqhome-cgi/modules/static/en/login.html b/apps/aqhome-cgi/modules/static/en/login.html new file mode 100644 index 0000000..1927e5b --- /dev/null +++ b/apps/aqhome-cgi/modules/static/en/login.html @@ -0,0 +1,25 @@ + +
+

AqHome

+

Enter your login credentials

+ +
+ + + + + +
+ +
+
+ +

Not registered? + + Create an account + +

+
+ + + \ No newline at end of file diff --git a/apps/aqhome-cgi/service/user.t2d b/apps/aqhome-cgi/service/user.t2d index a9ff05a..946dad2 100644 --- a/apps/aqhome-cgi/service/user.t2d +++ b/apps/aqhome-cgi/service/user.t2d @@ -54,6 +54,10 @@ Waiting for approval by admin + + User active + + diff --git a/apps/aqhome-cgi/service_file.c b/apps/aqhome-cgi/service_file.c index b91ac87..371900e 100644 --- a/apps/aqhome-cgi/service_file.c +++ b/apps/aqhome-cgi/service_file.c @@ -70,6 +70,8 @@ static int _addGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *s static int _deleteGroup(AQH_SERVICE *sv, const char *groupName, const char *subGroupName); static GWEN_STRINGLIST *_listGroup(AQH_SERVICE *sv, const char *groupName); +//static void _logGroup(const char *groupName, const char *subGroupName, GWEN_DB_NODE *db); + /* ------------------------------------------------------------------------------------------------ @@ -169,6 +171,9 @@ int _saveUser(AQH_SERVICE *sv, AQH_USER *user) GWEN_DB_Group_free(db); return rv; } + + //_logGroup(AQH_SERVICE_FILE_GROUP_USERS, s, db); + rv=_saveGroupLocked(sv, AQH_SERVICE_FILE_GROUP_USERS, s, db); if (rv<0) { DBG_ERROR(NULL, "here (%d)", rv); @@ -414,6 +419,7 @@ GWEN_STRINGLIST *_listSessions(AQH_SERVICE *sv) GWEN_DB_NODE *_loadGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *subGroupName) { + DBG_ERROR(NULL, "Lock and load group %s/%s", groupName, subGroupName); if (sv && groupName && subGroupName) { AQH_SERVICE_FILE *xs; @@ -422,17 +428,20 @@ GWEN_DB_NODE *_loadGroupLocked(AQH_SERVICE *sv, const char *groupName, const cha GWEN_DB_NODE *db=NULL; int rv; + DBG_ERROR(NULL, "Locking group %s/%s", groupName, subGroupName); rv=GWEN_ConfigMgr_LockGroup(xs->configMgr, groupName, subGroupName); if (rv<0) { DBG_ERROR(NULL, "Error locking group \"%s/%s\": %d", groupName, subGroupName, rv); return NULL; } + DBG_ERROR(NULL, "Loading group %s/%s", groupName, subGroupName); rv=GWEN_ConfigMgr_GetGroup(xs->configMgr, groupName, subGroupName, &db); if (rv<0) { DBG_ERROR(NULL, "Error reading group \"%s/%s\": %d", groupName, subGroupName, rv); GWEN_ConfigMgr_UnlockGroup(xs->configMgr, groupName, subGroupName); return NULL; } + DBG_ERROR(NULL, "Unlocking group %s/%s", groupName, subGroupName); rv=GWEN_ConfigMgr_UnlockGroup(xs->configMgr, groupName, subGroupName); if (rv<0) { DBG_ERROR(NULL, "Error unlocking group \"%s/%s\": %d", groupName, subGroupName, rv); @@ -442,6 +451,9 @@ GWEN_DB_NODE *_loadGroupLocked(AQH_SERVICE *sv, const char *groupName, const cha return db; } } + else { + DBG_ERROR(NULL, "Missing argument"); + } return NULL; } @@ -454,25 +466,26 @@ int _saveGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *subGrou xs=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_SERVICE_FILE, sv); if (xs) { - GWEN_DB_NODE *db=NULL; int rv; + DBG_ERROR(NULL, "Locking group %s/%s", groupName, subGroupName); rv=GWEN_ConfigMgr_LockGroup(xs->configMgr, groupName, subGroupName); if (rv<0) { DBG_ERROR(NULL, "Error locking group \"%s/%s\": %d", groupName, subGroupName, rv); return rv; } + DBG_ERROR(NULL, "Writing group %s/%s", groupName, subGroupName); rv=GWEN_ConfigMgr_SetGroup(xs->configMgr, groupName, subGroupName, db); if (rv<0) { DBG_ERROR(NULL, "Error writing group \"%s/%s\": %d", groupName, subGroupName, rv); return rv; } + DBG_ERROR(NULL, "Unlocking group %s/%s", groupName, subGroupName); rv=GWEN_ConfigMgr_UnlockGroup(xs->configMgr, groupName, subGroupName); if (rv<0) { DBG_ERROR(NULL, "Error unlocking group \"%s/%s\": %d", groupName, subGroupName, rv); - GWEN_DB_Group_free(db); return rv; } @@ -491,7 +504,6 @@ int _addGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *subGroup xs=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_SERVICE_FILE, sv); if (xs) { - GWEN_DB_NODE *db=NULL; int rv; rv=GWEN_ConfigMgr_HasGroup(xs->configMgr, groupName, subGroupName); @@ -515,7 +527,6 @@ int _addGroupLocked(AQH_SERVICE *sv, const char *groupName, const char *subGroup rv=GWEN_ConfigMgr_UnlockGroup(xs->configMgr, groupName, subGroupName); if (rv<0) { DBG_ERROR(NULL, "Error unlocking group \"%s/%s\": %d", groupName, subGroupName, rv); - GWEN_DB_Group_free(db); return rv; } @@ -577,3 +588,24 @@ GWEN_STRINGLIST *_listGroup(AQH_SERVICE *sv, const char *groupName) } + +#if 0 +void _logGroup(const char *groupName, const char *subGroupName, GWEN_DB_NODE *db) +{ + if (db) { + GWEN_BUFFER *dbuf; + + dbuf=GWEN_Buffer_new(0, 256, 0, 1); + GWEN_DB_WriteToBuffer(db, dbuf, GWEN_DB_FLAGS_DEFAULT); + DBG_ERROR(NULL, "Group %s/%s:\n%s", groupName?groupName:"", subGroupName?subGroupName:"", + GWEN_Buffer_GetStart(dbuf)); + GWEN_Buffer_free(dbuf); + } + else { + DBG_ERROR(NULL, "Group %s/%s empty", groupName?groupName:"", subGroupName?subGroupName:""); + } +} +#endif + + + diff --git a/apps/aqhome-cgi/service_file.h b/apps/aqhome-cgi/service_file.h index 8135d5d..85e1c44 100644 --- a/apps/aqhome-cgi/service_file.h +++ b/apps/aqhome-cgi/service_file.h @@ -13,6 +13,7 @@ #include "aqhome-cgi/service/service.h" +AQH_SERVICE *AQH_ServiceFiles_new(const char *baseFolder); diff --git a/apps/aqhome-data/s_getdatapoints.c b/apps/aqhome-data/s_getdatapoints.c index f2db538..fd9993e 100644 --- a/apps/aqhome-data/s_getdatapoints.c +++ b/apps/aqhome-data/s_getdatapoints.c @@ -1,6 +1,6 @@ /**************************************************************************** * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. * * The license for this file can be found in the file COPYING which you * should have received along with this file. @@ -33,8 +33,8 @@ * ------------------------------------------------------------------------------------------------ */ -#define AQHOMEDATA_HANDLEGETDATAPOINTS_MAXTABLEENTRIES 2048 -#define AQHOMEDATA_HANDLEGETDATAPOINTS_MAXDATAPOINTS 1024 +#define AQHOMEDATA_HANDLEGETDATAPOINTS_MAXTABLEENTRIES 1024 +#define AQHOMEDATA_HANDLEGETDATAPOINTS_MAXDATAPOINTS 512 /* ------------------------------------------------------------------------------------------------ @@ -44,13 +44,15 @@ static int _getAndSendDataPoints(AQH_STORAGE *storage, AQH_OBJECT *ep, const AQH_VALUE *value, + int mode, uint64_t tsBegin, uint64_t tsEnd, uint64_t num, uint32_t refMsgId); -static int _getAndSendDataPointsNoNum(AQH_STORAGE *storage, AQH_OBJECT *ep, const AQH_VALUE *value, uint64_t tsBegin, uint64_t tsEnd, +static int _getAndSendDataPointsPeriod(AQH_STORAGE *storage, AQH_OBJECT *ep, const AQH_VALUE *value, + uint64_t tsBegin, uint64_t tsEnd, uint64_t num, uint32_t refMsgId); -static int _getAndSendDataPointsWithNum(AQH_STORAGE *storage, AQH_OBJECT *ep, const AQH_VALUE *value, uint64_t num, uint32_t refMsgId); +static int _getAndSendDataPointsFirst(AQH_STORAGE *storage, AQH_OBJECT *ep, const AQH_VALUE *value, uint64_t num, uint32_t refMsgId); +static int _getAndSendDataPointsLast(AQH_STORAGE *storage, AQH_OBJECT *ep, const AQH_VALUE *value, uint64_t num, uint32_t refMsgId); static void _sendDataPointsResponse(AQH_OBJECT *ep, const AQH_VALUE *value, const uint64_t *tablePtr, uint32_t refMsgId); -static void _getAndSendLastDatapoint(AQH_STORAGE *storage, AQH_OBJECT *ep, const AQH_VALUE *value, uint32_t refMsgId); @@ -79,16 +81,18 @@ void AqHomeDataServer_HandleGetDataPoints(AQH_OBJECT *o, AQH_OBJECT *ep, const A uint64_t tsBegin; uint64_t tsEnd; uint64_t numRequested; + int mode; tsBegin=AQH_Tag16_GetTagDataAsUint64(tagList, AQH_MSGDATA_GETDATA_TAGS_BEGIN, 0); tsEnd=AQH_Tag16_GetTagDataAsUint64(tagList, AQH_MSGDATA_GETDATA_TAGS_END, 0); numRequested=AQH_Tag16_GetTagDataAsUint64(tagList, AQH_MSGDATA_GETDATA_TAGS_NUM, 0); + mode=AQH_Tag16_GetTagDataAsUint64(tagList, AQH_MSGDATA_GETDATA_TAGS_MODE, AQH_MSGDATA_GETDATA_MODE_FIRST); value=AQH_Storage_GetValueByNameForSystem(xo->storage, valueName); if (value) { int resultCode; - resultCode=_getAndSendDataPoints(xo->storage, ep, value, tsBegin, tsEnd, numRequested, refMsgId); + resultCode=_getAndSendDataPoints(xo->storage, ep, value, mode, tsBegin, tsEnd, numRequested, refMsgId); AqHomeDataServer_SendResponseResultToEndpoint(ep, refMsgId, resultCode); } else { @@ -114,30 +118,31 @@ void AqHomeDataServer_HandleGetDataPoints(AQH_OBJECT *o, AQH_OBJECT *ep, const A int _getAndSendDataPoints(AQH_STORAGE *storage, AQH_OBJECT *ep, const AQH_VALUE *value, + int mode, uint64_t tsBegin, uint64_t tsEnd, uint64_t num, uint32_t refMsgId) { - if (num==0) - return _getAndSendDataPointsNoNum(storage, ep, value, tsBegin, tsEnd, refMsgId); - else if (num==1) { - _getAndSendLastDatapoint(storage, ep, value, refMsgId); - return AQH_MSGDATA_RESULT_SUCCESS; + switch(mode) { + case AQH_MSGDATA_GETDATA_MODE_FIRST: return _getAndSendDataPointsFirst(storage, ep, value, num, refMsgId); + case AQH_MSGDATA_GETDATA_MODE_PERIOD: return _getAndSendDataPointsPeriod(storage, ep, value, tsBegin, tsEnd, num, refMsgId); + default: + case AQH_MSGDATA_GETDATA_MODE_LAST: return _getAndSendDataPointsLast(storage, ep, value, num, refMsgId); } - else - return _getAndSendDataPointsWithNum(storage, ep, value, num, refMsgId); } -int _getAndSendDataPointsNoNum(AQH_STORAGE *storage, AQH_OBJECT *ep, - const AQH_VALUE *value, uint64_t tsBegin, uint64_t tsEnd, - uint32_t refMsgId) +int _getAndSendDataPointsPeriod(AQH_STORAGE *storage, AQH_OBJECT *ep, + const AQH_VALUE *value, uint64_t tsBegin, uint64_t tsEnd, uint64_t num, + uint32_t refMsgId) { uint64_t valueId; uint64_t *tablePtr; valueId=AQH_Value_GetId(value); - tablePtr=AQH_Storage_GetDataPoints(storage, valueId, tsBegin, tsEnd, AQHOMEDATA_HANDLEGETDATAPOINTS_MAXTABLEENTRIES); + if (num==0 || num>AQHOMEDATA_HANDLEGETDATAPOINTS_MAXTABLEENTRIES) + num=AQHOMEDATA_HANDLEGETDATAPOINTS_MAXTABLEENTRIES; + tablePtr=AQH_Storage_GetDataPoints(storage, valueId, tsBegin, tsEnd, num); if (tablePtr) { _sendDataPointsResponse(ep, value, tablePtr, refMsgId); free(tablePtr); @@ -151,9 +156,9 @@ int _getAndSendDataPointsNoNum(AQH_STORAGE *storage, AQH_OBJECT *ep, -int _getAndSendDataPointsWithNum(AQH_STORAGE *storage, AQH_OBJECT *ep, - const AQH_VALUE *value, uint64_t num, - uint32_t refMsgId) +int _getAndSendDataPointsLast(AQH_STORAGE *storage, AQH_OBJECT *ep, + const AQH_VALUE *value, uint64_t num, + uint32_t refMsgId) { uint64_t valueId; uint64_t *tablePtr; @@ -175,6 +180,30 @@ int _getAndSendDataPointsWithNum(AQH_STORAGE *storage, AQH_OBJECT *ep, +int _getAndSendDataPointsFirst(AQH_STORAGE *storage, AQH_OBJECT *ep, + const AQH_VALUE *value, uint64_t num, + uint32_t refMsgId) +{ + uint64_t valueId; + uint64_t *tablePtr; + + if (num>AQHOMEDATA_HANDLEGETDATAPOINTS_MAXDATAPOINTS) + num=AQHOMEDATA_HANDLEGETDATAPOINTS_MAXDATAPOINTS; + valueId=AQH_Value_GetId(value); + tablePtr=AQH_Storage_GetFirstNDataPoints(storage, valueId, num); + if (tablePtr) { + _sendDataPointsResponse(ep, value, tablePtr, refMsgId); + free(tablePtr); + return AQH_MSGDATA_RESULT_SUCCESS; + } + else { + DBG_INFO(NULL, "No matching datapoints for value \"%s\"", AQH_Value_GetNameForSystem(value)); + return AQH_MSGDATA_RESULT_ERROR_NODATA; + } +} + + + void _sendDataPointsResponse(AQH_OBJECT *ep, const AQH_VALUE *value, const uint64_t *tablePtr, uint32_t refMsgId) @@ -193,36 +222,3 @@ void _sendDataPointsResponse(AQH_OBJECT *ep, -void _getAndSendLastDatapoint(AQH_STORAGE *storage, AQH_OBJECT *ep, - const AQH_VALUE *value, uint32_t refMsgId) -{ - int rv; - uint64_t timestamp=0; - double data=0.0; - - rv=AQH_Storage_GetLastDataPoint(storage, AQH_Value_GetId(value), ×tamp, &data); - if (rv<0) { - int resultCode; - - switch(rv) { - case GWEN_ERROR_INVALID: resultCode=AQH_MSGDATA_RESULT_ERROR_INVALID; break; - case GWEN_ERROR_NO_DATA: resultCode=AQH_MSGDATA_RESULT_ERROR_NODATA; break; - default: resultCode=AQH_MSGDATA_RESULT_ERROR_GENERIC; break; - } - AqHomeDataServer_SendResponseResultToEndpoint(ep, refMsgId, resultCode); - } - else { - AQH_MESSAGE *outMsg; - - outMsg=AQH_IpcdMessageMultiData_newForOne(AQH_MSGTYPE_IPC_DATA_GETDATA_RSP, - AQH_Endpoint_GetNextMessageId(ep), refMsgId, - value, timestamp, data); - AQH_Endpoint_AddMsgOut(ep, outMsg); - } -} - - - - - - diff --git a/apps/aqhome-data/s_getvalues.c b/apps/aqhome-data/s_getvalues.c index ac592af..be430ce 100644 --- a/apps/aqhome-data/s_getvalues.c +++ b/apps/aqhome-data/s_getvalues.c @@ -13,13 +13,16 @@ #include "./s_getvalues.h" #include "./server_p.h" +#include "aqhome/aqhome.h" #include "aqhome/ipc2/endpoint.h" #include "aqhome/msg/ipc/m_ipc.h" #include "aqhome/msg/ipc/data/m_ipcd.h" +#include "aqhome/msg/ipc/data/m_ipcd_getvalues.h" #include "aqhome/msg/ipc/data/m_ipcd_values.h" #include "aqhome/msg/ipc/m_ipc_result.h" #include "aqhome/msg/ipc/m_ipc_tag16.h" +#include #include @@ -38,7 +41,10 @@ * ------------------------------------------------------------------------------------------------ */ -static void _sendValueList(AQH_OBJECT *ep, const AQH_VALUE_LIST *vl, uint32_t flags, uint32_t refMsgId); +static AQH_VALUE_LIST *_getMatchingValueList(AQHOME_SERVER *xo, const GWEN_TAG16_LIST *tagList); +static void _sendValueList(AQH_OBJECT *ep, const AQH_VALUE_LIST *vl, uint32_t refMsgId); +static void _sendValueListMsg(AQH_OBJECT *ep, const AQH_VALUE_LIST *vl, uint32_t flags, uint32_t refMsgId); +static int _valueMatches(const AQH_VALUE *v, const char *deviceName, int modality); @@ -47,64 +53,100 @@ static void _sendValueList(AQH_OBJECT *ep, const AQH_VALUE_LIST *vl, uint32_t fl * ------------------------------------------------------------------------------------------------ */ -void AqHomeDataServer_HandleGetValues(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSAGE *msg, GWEN_UNUSED const GWEN_TAG16_LIST *tagList) +void AqHomeDataServer_HandleGetValues(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList) { AQHOME_SERVER *xo; xo=AqHomeDataServer_GetServerData(o); if (xo) { - const AQH_VALUE_LIST *origValueList; - + AQH_VALUE_LIST *valueList; uint32_t refMsgId; refMsgId=AQH_IpcMessage_GetMsgId(msg); DBG_INFO(NULL, "HandleGetValues"); - origValueList=AQH_Storage_GetValueList(xo->storage); - if (origValueList) { - DBG_INFO(NULL, "Have a list of %d values", AQH_Value_List_GetCount(origValueList)); - if (AQH_Value_List_GetCount(origValueList)=AQHOMEDATA_VALUESPERMSG) { - DBG_INFO(NULL, "Sending %d values", AQH_Value_List_GetCount(tmpValueList)); - _sendValueList(ep, tmpValueList, next?0:AQH_MSGDATA_VALUES_FLAGS_LASTMSG, refMsgId); - AQH_Value_List_Clear(tmpValueList); - } - v=next; - } - if (AQH_Value_List_GetCount(tmpValueList)) { - DBG_INFO(NULL, "Sending %d values", AQH_Value_List_GetCount(tmpValueList)); - _sendValueList(ep, tmpValueList, AQH_MSGDATA_VALUES_FLAGS_LASTMSG, refMsgId); /* send remaining */ - } - AQH_Value_List_free(tmpValueList); - } + valueList=_getMatchingValueList(xo, tagList); + if (valueList) { + _sendValueList(ep, valueList, refMsgId); + AQH_Value_List_free(valueList); } else { /* empty list */ - _sendValueList(ep, NULL, AQH_MSGDATA_VALUES_FLAGS_LASTMSG, refMsgId); + _sendValueListMsg(ep, NULL, AQH_MSGDATA_VALUES_FLAGS_LASTMSG, refMsgId); } } } -void _sendValueList(AQH_OBJECT *ep, const AQH_VALUE_LIST *vl, uint32_t flags, uint32_t refMsgId) +AQH_VALUE_LIST *_getMatchingValueList(AQHOME_SERVER *xo, const GWEN_TAG16_LIST *tagList) +{ + const AQH_VALUE_LIST *origValueList; + AQH_VALUE_LIST *tmpValueList=NULL; + char *deviceName; + int modality; + + deviceName=tagList?AQH_Tag16_GetTagDataAsNewString(tagList, AQH_MSGDATA_GETVALUES_TAGS_DEVICENAME, NULL):NULL; + modality=tagList?AQH_Tag16_GetTagDataAsUint64(tagList, AQH_MSGDATA_GETVALUES_TAGS_MODALITY, 0):0; + + origValueList=AQH_Storage_GetValueList(xo->storage); + if (origValueList) { + const AQH_VALUE *v; + + tmpValueList=AQH_Value_List_new(); + v=AQH_Value_List_First(origValueList); + while(v) { + if (_valueMatches(v, deviceName, modality)) { + AQH_VALUE *copyOfValue; + + copyOfValue=AQH_Value_dup(v); + AQH_Value_List_Add(copyOfValue, tmpValueList); + } + v=AQH_Value_List_Next(v); + } + if (AQH_Value_List_GetCount(tmpValueList)<1) { + AQH_Value_List_free(tmpValueList); + tmpValueList=NULL; + } + } + free(deviceName); + + return tmpValueList; +} + + + +void _sendValueList(AQH_OBJECT *ep, const AQH_VALUE_LIST *vl, uint32_t refMsgId) +{ + AQH_VALUE_LIST *tmpValueList; + const AQH_VALUE *v; + + tmpValueList=AQH_Value_List_new(); + v=AQH_Value_List_First(vl); + while(v) { + const AQH_VALUE *next; + AQH_VALUE *copyOfValue; + + next=AQH_Value_List_Next(v); + copyOfValue=AQH_Value_dup(v); + AQH_Value_List_Add(copyOfValue, tmpValueList); + if (AQH_Value_List_GetCount(tmpValueList)>=AQHOMEDATA_VALUESPERMSG) { + DBG_INFO(NULL, "Sending %d values", AQH_Value_List_GetCount(tmpValueList)); + _sendValueListMsg(ep, tmpValueList, next?0:AQH_MSGDATA_VALUES_FLAGS_LASTMSG, refMsgId); + AQH_Value_List_Clear(tmpValueList); + } + v=next; + } + if (AQH_Value_List_GetCount(tmpValueList)) { + DBG_INFO(NULL, "Sending %d values", AQH_Value_List_GetCount(tmpValueList)); + _sendValueListMsg(ep, tmpValueList, AQH_MSGDATA_VALUES_FLAGS_LASTMSG, refMsgId); /* send remaining */ + } + AQH_Value_List_free(tmpValueList); +} + + + +void _sendValueListMsg(AQH_OBJECT *ep, const AQH_VALUE_LIST *vl, uint32_t flags, uint32_t refMsgId) { AQH_MESSAGE *msg; @@ -115,3 +157,27 @@ void _sendValueList(AQH_OBJECT *ep, const AQH_VALUE_LIST *vl, uint32_t flags, ui +int _valueMatches(const AQH_VALUE *v, const char *deviceName, int modality) +{ + if (modality!=AQH_ValueModality_Unknown) { + int valModality; + + valModality=AQH_Value_GetModality(v); + if (valModality!=modality) + return 0; + } + if (deviceName && *deviceName) { + const char *s; + + s=AQH_Value_GetDeviceNameForSystem(v); + if (s && *s && GWEN_Text_ComparePattern(s, deviceName, 0)==-1) + return 0; + } + + return 1; +} + + + + + diff --git a/apps/aqhome-nodes/r_getnodes.c b/apps/aqhome-nodes/r_getnodes.c index 28c8d8d..cfc791e 100644 --- a/apps/aqhome-nodes/r_getnodes.c +++ b/apps/aqhome-nodes/r_getnodes.c @@ -54,7 +54,7 @@ void AQH_NodeServer_HandleGetNodes(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESS AQH_Endpoint_GetNextMessageId(ep), AQH_IpcMessage_GetMsgId(msg), niNext?0:AQH_MSGNODE_GETDEVICES_RSP_FLAGS_LASTMSG, ni); AQH_Endpoint_AddMsgOut(ep, outMsg); - DBG_ERROR(NULL, "Messages in clients out queue: %d", AQH_Message_List_GetCount(AQH_Endpoint_GetMsgOutList(ep))); + DBG_DEBUG(NULL, "Messages in clients out queue: %d", AQH_Message_List_GetCount(AQH_Endpoint_GetMsgOutList(ep))); ni=niNext; } } diff --git a/apps/aqhome-nodes/server.c b/apps/aqhome-nodes/server.c index 320f612..2e191e9 100644 --- a/apps/aqhome-nodes/server.c +++ b/apps/aqhome-nodes/server.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -122,7 +123,9 @@ static void _forwardTtyMsgToBroker(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH static void _forwardValueMessageToBroker(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); static void _forwardDataFromSendStatsMsgToBroker(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); static void _forwardDataFromRecvStatsMsgToBroker(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); +static void _forwardDataFromMemStatsMsgToBroker(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); static void _forwardTtyMsgToClients(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg); +static void _publishIntWithIdx(AQH_NODE_SERVER *xo, uint32_t uid, const char *vPath, int idx, int vModality, const char *vUnits, int v); static void _publishInt(AQH_NODE_SERVER *xo, uint32_t uid, const char *vPath, int vModality, const char *vUnits, int v); static void _publishDouble(AQH_NODE_SERVER *xo, uint32_t uid, const char *vPath, int vModality, const char *vUnits, double v); static void _setDeviceName(AQH_VALUE *value, uint32_t uid); @@ -827,9 +830,11 @@ void _forwardTtyMsgToBroker(AQH_OBJECT *o, AQH_NODE_SERVER *xo, const AQH_MESSAG code=AQH_NodeMessage_GetMsgType(msg); switch(code) { - case AQH_MSG_TYPE_VALUE_REPORT: _forwardValueMessageToBroker(o, xo, msg); break; + case AQH_MSG_TYPE_VALUE_REPORT: _forwardValueMessageToBroker(o, xo, msg); break; case AQH_MSG_TYPE_COMSENDSTATS: _forwardDataFromSendStatsMsgToBroker(xo, msg); break; case AQH_MSG_TYPE_COMRECVSTATS: _forwardDataFromRecvStatsMsgToBroker(xo, msg); break; + case AQH_MSG_TYPE_MEMSTATS: _forwardDataFromMemStatsMsgToBroker(xo, msg); break; + default: break; } } @@ -898,24 +903,21 @@ void _forwardDataFromSendStatsMsgToBroker(AQH_NODE_SERVER *xo, const AQH_MESSAGE packetsOutInt=AQH_SendStatsMessage_GetPacketsOut(msg); if (packetsOutInt) { uint32_t uid; - double packetsOut; - double collisions; - double busy; - double collisionsPercentage=0.0; - double busyPercentage=0.0; + int devNum; uid=AQH_SendStatsMessage_GetUid(msg); - packetsOut=/*(double)*/ packetsOutInt; - collisions=/*(double)*/ AQH_SendStatsMessage_GetCollisions(msg); - busy=/*(double)*/ AQH_SendStatsMessage_GetBusyErrors(msg); + devNum=AQH_SendStatsMessage_GetInterface(msg); - collisionsPercentage=collisions*100.0/packetsOut; - busyPercentage=busy*100.0/packetsOut; - - _publishInt( xo, uid, "net/packetsOut", 0, NULL, packetsOutInt); - _publishInt( xo, uid, "net/collisions", 0, NULL, (int) AQH_SendStatsMessage_GetCollisions(msg)); - _publishDouble(xo, uid, "net/collisionsPercent", 0, "%", collisionsPercentage); - _publishDouble(xo, uid, "net/busyPercent", 0, "%", busyPercentage); + if (devNum==0) { + _publishInt(xo, uid, "net/packetsOut", 0, NULL, packetsOutInt); + _publishInt(xo, uid, "net/collisions", 0, NULL, (int) AQH_SendStatsMessage_GetCollisions(msg)); + _publishInt(xo, uid, "net/busy", 0, NULL, (int) AQH_SendStatsMessage_GetBusyErrors(msg)); + } + else { + _publishIntWithIdx(xo, uid, "net/packetsOut", devNum, 0, NULL, packetsOutInt); + _publishIntWithIdx(xo, uid, "net/collisions", devNum, 0, NULL, (int) AQH_SendStatsMessage_GetCollisions(msg)); + _publishIntWithIdx(xo, uid, "net/busy", devNum, 0, NULL, (int) AQH_SendStatsMessage_GetBusyErrors(msg)); + } } } @@ -928,30 +930,56 @@ void _forwardDataFromRecvStatsMsgToBroker(AQH_NODE_SERVER *xo, const AQH_MESSAGE packetsInInt=AQH_RecvStatsMessage_GetPacketsIn(msg); if (packetsInInt) { uint32_t uid; - double packetsIn; - double crcErrors; - double ioErrors; - double crcErrorsPercentage=0.0; - double ioErrorsPercentage=0.0; + int devNum; - uid=AQH_SendStatsMessage_GetUid(msg); - packetsIn=/*(double)*/ packetsInInt; - crcErrors=/*(double)*/AQH_RecvStatsMessage_GetCrcErrors(msg); - ioErrors=/*(double)*/AQH_RecvStatsMessage_GetIoErrors(msg); + uid=AQH_RecvStatsMessage_GetUid(msg); + devNum=AQH_RecvStatsMessage_GetInterface(msg); - crcErrorsPercentage=crcErrors*100.0/packetsIn; - ioErrorsPercentage=ioErrors*100.0/packetsIn; - - _publishInt( xo, uid, "net/packetsIn", 0, NULL, packetsInInt); - _publishInt( xo, uid, "net/crcerrors", 0, NULL, (int) AQH_RecvStatsMessage_GetCrcErrors(msg)); - _publishInt( xo, uid, "net/ioerrors", 0, NULL, (int) AQH_RecvStatsMessage_GetIoErrors(msg)); - _publishDouble(xo, uid, "net/crcerrorsPercent", 0, "%", crcErrorsPercentage); - _publishDouble(xo, uid, "net/ioerrorsPercent", 0, "%", ioErrorsPercentage); + if (devNum==0) { + _publishInt(xo, uid, "net/packetsIn", 0, NULL, packetsInInt); + _publishInt(xo, uid, "net/crcErrors", 0, NULL, (int) AQH_RecvStatsMessage_GetCrcErrors(msg)); + _publishInt(xo, uid, "net/ioErrors", 0, NULL, (int) AQH_RecvStatsMessage_GetIoErrors(msg)); + _publishInt(xo, uid, "net/nobufferErrors", 0, NULL, (int) AQH_RecvStatsMessage_GetNoBufferErrors(msg)); + _publishInt(xo, uid, "net/msgSizeErrors", 0, NULL, (int) AQH_RecvStatsMessage_GetMsgSizeErrors(msg)); + _publishInt(xo, uid, "net/missed", 0, NULL, (int) AQH_RecvStatsMessage_GetMissed(msg)); + } + else { + _publishIntWithIdx(xo, uid, "net/packetsIn", devNum, 0, NULL, packetsInInt); + _publishIntWithIdx(xo, uid, "net/crcErrors", devNum, 0, NULL, (int) AQH_RecvStatsMessage_GetCrcErrors(msg)); + _publishIntWithIdx(xo, uid, "net/ioErrors", devNum, 0, NULL, (int) AQH_RecvStatsMessage_GetIoErrors(msg)); + _publishIntWithIdx(xo, uid, "net/nobufferErrors", devNum, 0, NULL, (int) AQH_RecvStatsMessage_GetNoBufferErrors(msg)); + _publishIntWithIdx(xo, uid, "net/msgSizeErrors", devNum, 0, NULL, (int) AQH_RecvStatsMessage_GetMsgSizeErrors(msg)); + _publishIntWithIdx(xo, uid, "net/missed", devNum, 0, NULL, (int) AQH_RecvStatsMessage_GetMissed(msg)); + } } } +void _forwardDataFromMemStatsMsgToBroker(AQH_NODE_SERVER *xo, const AQH_MESSAGE *msg) +{ + uint32_t uid; + + uid=AQH_MemStatsMessage_GetUid(msg); + + _publishInt( xo, uid, "mem/buffersUsed", 0, NULL, AQH_MemStatsMessage_GetBuffersUsed(msg)); + _publishInt( xo, uid, "mem/maxBuffersUsed", 0, NULL, AQH_MemStatsMessage_GetMaxBuffersUsed(msg)); +} + + + +void _publishIntWithIdx(AQH_NODE_SERVER *xo, uint32_t uid, const char *vPath, int idx, int vModality, const char *vUnits, int v) +{ + GWEN_BUFFER *tbuf; + + tbuf=GWEN_Buffer_new(0, 256, 0, 1); + GWEN_Buffer_AppendArgs(tbuf, "%s%d", vPath, idx); + _publishInt(xo, uid, GWEN_Buffer_GetStart(tbuf), vModality, vUnits, v); + GWEN_Buffer_free(tbuf); +} + + + void _publishInt(AQH_NODE_SERVER *xo, uint32_t uid, const char *vPath, int vModality, const char *vUnits, int v) { _publishDouble(xo, uid, vPath, vModality, vUnits, /*(double)*/ v); diff --git a/apps/aqhome-tool/data/0BUILD b/apps/aqhome-tool/data/0BUILD index 4af2354..ed2824c 100644 --- a/apps/aqhome-tool/data/0BUILD +++ b/apps/aqhome-tool/data/0BUILD @@ -37,9 +37,13 @@ getdevices.h adddata.h getdatapoints.h + getfirstdata.h + getlastdata.h + getperioddata.h setdata.h moddevice.h watch.h + devicestate.h @@ -49,9 +53,13 @@ getdevices.c adddata.c getdatapoints.c + getfirstdata.c + getlastdata.c + getperioddata.c setdata.c moddevice.c watch.c + devicestate.c diff --git a/apps/aqhome-tool/data/devicestate.c b/apps/aqhome-tool/data/devicestate.c new file mode 100644 index 0000000..2b7a9b8 --- /dev/null +++ b/apps/aqhome-tool/data/devicestate.c @@ -0,0 +1,265 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "./devicestate.h" +#include "../utils.h" + +#include "aqhome/aqhome.h" +#include "aqhome/dataclient/client.h" +#include "aqhome/msg/ipc/m_ipc.h" +#include "aqhome/msg/ipc/m_ipc_result.h" +#include "aqhome/msg/ipc/data/m_ipcd.h" +#include "aqhome/msg/ipc/data/m_ipcd_getdata.h" +#include "aqhome/msg/ipc/data/m_ipcd_multidata.h" +#include "aqhome/dataclient/client.h" + +#include +#include +#include +#include +#include + +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defs + * ------------------------------------------------------------------------------------------------ + */ + +#define I18S(msg) msg +#define I18N(msg) GWEN_I18N_Translate(PACKAGE, msg) + +#define A_ARG GWEN_ARGS_FLAGS_HAS_ARGUMENT +#define A_END (GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST) +#define A_CHAR GWEN_ArgsType_Char +#define A_INT GWEN_ArgsType_Int + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static int _runCommand(AQH_DATACLIENT *dc); +static void _handleDevice(AQH_DATACLIENT *dc, const AQH_DEVICE *device); +static void _handleValue(AQH_DATACLIENT *dc, const AQH_VALUE *value); +static void _printDataPoints(const uint64_t *dataPoints, uint32_t numValues); +static void _printSingleDataPoint(uint64_t timestamp, double data); + + + + +/* ------------------------------------------------------------------------------------------------ + * code + * ------------------------------------------------------------------------------------------------ + */ + +int AQH_Tool_DeviceState(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv) +{ + AQH_EVENT_LOOP *eventLoop; + AQH_DATACLIENT *dc; + int rv; + const GWEN_ARGS args[]= { + /* flags type name min max s long short_descr, long_descr */ + { A_ARG, A_CHAR, "brokerAddress", 0, 1, "t", "tcpaddress", I18S("TCP address to connect to [127.0.0.1]"), NULL}, + { A_ARG, A_INT, "brokerPort", 0, 1, "P", "tcpport", I18S("Specify the TCP port to listen on"), NULL}, + { A_ARG, A_INT, "timeout", 0, 1, "T", NULL, I18S("Specify timeout in seconds for response"), NULL}, + { A_ARG, A_CHAR, "brokerClientId", 0, 1, "c", "clientid", I18S("Specify CLIENTID"), NULL}, + { A_ARG, A_CHAR, "userId", 0, 1, "u", "userid", I18S("Specify user id"), NULL}, + { A_ARG, A_CHAR, "password", 0, 1, "p", "password", I18S("Specify service password"), NULL}, + { A_ARG, A_CHAR, "device", 1, 1, "d", "device", I18S("device name"), NULL}, + { A_ARG, A_CHAR, "valueName", 0, 1, "N", "valuename", I18S("Value name for device(e.g. LIGHT)"), NULL}, + { A_ARG, A_INT, "numOfDatapoints", 0, 1, "n", NULL, I18S("Get up to n datapoints"), NULL}, + { A_END, A_INT, "help", 0, 0, "h", "help", I18S("Show this help screen"), NULL} + }; + + eventLoop=AQH_EventLoop_new(); + dc=AQH_DataClient_new(eventLoop, AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION); + + rv=AQH_DataClient_ReadLocalArgs(dc, dbGlobalArgs, args, argc, argv); + if (rv<0) { + DBG_ERROR(NULL, "here (%d)", rv); + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 2; + } + + rv=AQH_DataClient_ConnectWithArgs(dc, 0); + if (rv<0) { + DBG_ERROR(NULL, "Error connecting (%d)", rv); + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 2; + } + + rv=_runCommand(dc); + if (rv<0) { + DBG_ERROR(NULL, "Error running (%d)", rv); + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 2; + } + + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 0; +} + + + +int _runCommand(AQH_DATACLIENT *dc) +{ + GWEN_DB_NODE *dbLocalArgs; + const char *deviceName; + AQH_DEVICE_LIST *deviceList; + AQH_DEVICE *device; + + dbLocalArgs=AQH_DataClient_GetDbLocalArgs(dc); + deviceName=GWEN_DB_GetCharValue(dbLocalArgs, "device", 0, "*"); + + deviceList=AQH_DataClient_GetDevices(dc); + if (deviceList==NULL) { + DBG_ERROR(NULL, "Error getting devices"); + return GWEN_ERROR_GENERIC; + } + + device=AQH_Device_List_First(deviceList); + while(device) { + const char *s; + + s=AQH_Device_GetNameForSystem(device); + if (s && *s && -1!=GWEN_Text_ComparePattern(s, deviceName, 0)) { + _handleDevice(dc, device); + } + + device=AQH_Device_List_Next(device); + } + + AQH_Device_List_free(deviceList); + + return 0; +} + + + +void _handleDevice(AQH_DATACLIENT *dc, const AQH_DEVICE *device) +{ + AQH_VALUE_LIST *valueList; + const char *devName; + const char *roomName; + const char *location; + const char *descr; + + devName=AQH_Device_GetNameForSystem(device); + roomName=AQH_Device_GetRoomName(device); + location=AQH_Device_GetLocation(device); + descr=AQH_Device_GetDescription(device); + + fprintf(stdout, "%s (room: %s, loc: %s, descr: %s)\n", + devName, + roomName?roomName:"--", + location?location:"--", + descr?descr:"--"); + valueList=AQH_DataClient_GetValues(dc, devName, 0); + if (valueList) { + const AQH_VALUE *value; + + value=AQH_Value_List_First(valueList); + while(value) { + if (AQH_Value_GetValueType(value)==AQH_ValueType_Sensor) + _handleValue(dc, value); + value=AQH_Value_List_Next(value); + } + } + + AQH_Value_List_free(valueList); +} + + + +void _handleValue(AQH_DATACLIENT *dc, const AQH_VALUE *value) +{ + GWEN_DB_NODE *dbLocalArgs; + const char *wantedValueName; + const char *valueName; + int numDataPoints; + + dbLocalArgs=AQH_DataClient_GetDbLocalArgs(dc); + numDataPoints=GWEN_DB_GetIntValue(dbLocalArgs, "numOfDatapoints", 0, 5); + wantedValueName=GWEN_DB_GetCharValue(dbLocalArgs, "valueName", 0, "*"); + + valueName=AQH_Value_GetName(value); + if (valueName && + -1==GWEN_Text_ComparePattern(valueName, "stats_*", 0) && + -1!=GWEN_Text_ComparePattern(valueName, wantedValueName, 0)) { + const char *valueNameForSystem; + uint64_t *dataPoints; + uint64_t recvdNum; + + valueNameForSystem=AQH_Value_GetNameForSystem(value); + fprintf(stdout, " %s: ", valueName?valueName:""); + + dataPoints=malloc(numDataPoints*sizeof(uint64_t)*2); + + recvdNum=AQH_DataClient_GetLastData(dc, valueNameForSystem, dataPoints, numDataPoints); + if (recvdNum>0) + _printDataPoints(dataPoints, recvdNum); + + free(dataPoints); + fprintf(stdout, "\n"); + } +} + + + +void _printDataPoints(const uint64_t *dataPoints, uint32_t numValues) +{ + uint32_t i; + + for(i=0; i + + + +int AQH_Tool_DeviceState(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv); + + +#endif + diff --git a/apps/aqhome-tool/data/getdatapoints.c b/apps/aqhome-tool/data/getdatapoints.c index cb4c57d..5e77bee 100644 --- a/apps/aqhome-tool/data/getdatapoints.c +++ b/apps/aqhome-tool/data/getdatapoints.c @@ -10,7 +10,7 @@ # include #endif -#include "./getvalues.h" +#include "./getdatapoints.h" #include "../client.h" #include "../utils.h" @@ -52,7 +52,6 @@ static AQH_MESSAGE *_createRequestMessage(AQH_OBJECT *o, uint32_t msgId); static int _handleResponseMessage(AQH_OBJECT *o, const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList, int first); static void _handleDataResponse(const GWEN_TAG16_LIST *tagList, int printMean, int printDiff); -static uint64_t _getTimeStampFromString(const char *s); @@ -110,18 +109,23 @@ AQH_MESSAGE *_createRequestMessage(GWEN_UNUSED AQH_OBJECT *o, uint32_t msgId) dbArgs=AQH_ToolClient_GetDbLocalArgs(o); valueName=GWEN_DB_GetCharValue(dbArgs, "valueName", 0, NULL); num=GWEN_DB_GetIntValue(dbArgs, "numOfLastDatapoints", 0, 0); - tsBegin=_getTimeStampFromString(GWEN_DB_GetCharValue(dbArgs, "tsBegin", 0, NULL)); + tsBegin=Utils_GetTimeStampFromString(GWEN_DB_GetCharValue(dbArgs, "tsBegin", 0, NULL)); if (tsBegin==(uint64_t) (-1)) { DBG_ERROR(NULL, "Bad begin timestamp"); return NULL; } - tsEnd=_getTimeStampFromString(GWEN_DB_GetCharValue(dbArgs, "tsEnd", 0, NULL)); + tsEnd=Utils_GetTimeStampFromString(GWEN_DB_GetCharValue(dbArgs, "tsEnd", 0, NULL)); if (tsEnd==(uint64_t) (-1)) { DBG_ERROR(NULL, "Bad end timestamp"); return NULL; } - return AQH_IpcdMessageGetData_new(AQH_MSGTYPE_IPC_DATA_GETDATA_REQ, msgId, 0, valueName, tsBegin, tsEnd, num); + // TODO: use "mode" correctly + return AQH_IpcdMessageGetData_new(AQH_MSGTYPE_IPC_DATA_GETDATA_REQ, + msgId, 0, + AQH_MSGDATA_GETDATA_MODE_LAST, + valueName, + tsBegin, tsEnd, num); } @@ -178,45 +182,3 @@ void _handleDataResponse(const GWEN_TAG16_LIST *tagList, int printMean, int prin -uint64_t _getTimeStampFromString(const char *s) -{ - if (s && *s) { - if (*s=='-') { - uint64_t x=0; - uint64_t now=time(NULL); - - s++; - while(*s && isdigit(*s)) { - unsigned int i; - - i=*(s++)-'0'; - x*=10; - x+=i; - } - if (*s) { - switch(*s) { - case 0: - case 'm': x*=60; break; - case 'h': x*=(60*60); break; - case 'd': x*=(60*60*24); break; - default: break; - } - } - return (now-x); - } - else { - unsigned long int x; - - if (1!=sscanf(s, "%lu", &x)) { - DBG_ERROR(NULL, "ERROR: Invalid timestamp"); - return (uint64_t) (-1); - } - return (uint64_t) x; - } - } - return 0; -} - - - - diff --git a/apps/aqhome-tool/data/getfirstdata.c b/apps/aqhome-tool/data/getfirstdata.c new file mode 100644 index 0000000..35f54c6 --- /dev/null +++ b/apps/aqhome-tool/data/getfirstdata.c @@ -0,0 +1,153 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "./getfirstdata.h" +#include "../utils.h" + +#include "aqhome/dataclient/client.h" +#include "aqhome/msg/ipc/m_ipc.h" +#include "aqhome/msg/ipc/m_ipc_result.h" +#include "aqhome/msg/ipc/data/m_ipcd.h" +#include "aqhome/msg/ipc/data/m_ipcd_getdata.h" +#include "aqhome/msg/ipc/data/m_ipcd_multidata.h" +#include "aqhome/dataclient/client.h" + +#include +#include +#include +#include + +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defs + * ------------------------------------------------------------------------------------------------ + */ + +#define I18S(msg) msg +#define I18N(msg) GWEN_I18N_Translate(PACKAGE, msg) + +#define A_ARG GWEN_ARGS_FLAGS_HAS_ARGUMENT +#define A_END (GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST) +#define A_CHAR GWEN_ArgsType_Char +#define A_INT GWEN_ArgsType_Int + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static int _runCommand(AQH_DATACLIENT *dc); + + + + +/* ------------------------------------------------------------------------------------------------ + * code + * ------------------------------------------------------------------------------------------------ + */ + +int AQH_Tool_GetFirstData(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv) +{ + AQH_EVENT_LOOP *eventLoop; + AQH_DATACLIENT *dc; + int rv; + const GWEN_ARGS args[]= { + /* flags type name min max s long short_descr, long_descr */ + { A_ARG, A_CHAR, "brokerAddress", 0, 1, "t", "tcpaddress", I18S("TCP address to connect to [127.0.0.1]"), NULL}, + { A_ARG, A_INT, "brokerPort", 0, 1, "P", "tcpport", I18S("Specify the TCP port to listen on"), NULL}, + { A_ARG, A_INT, "timeout", 0, 1, "T", NULL, I18S("Specify timeout in seconds for response"), NULL}, + { A_ARG, A_CHAR, "brokerClientId", 0, 1, "c", "clientid", I18S("Specify CLIENTID"), NULL}, + { A_ARG, A_CHAR, "userId", 0, 1, "u", "userid", I18S("Specify user id"), NULL}, + { A_ARG, A_CHAR, "password", 0, 1, "p", "password", I18S("Specify service password"), NULL}, + { A_ARG, A_CHAR, "valueName", 1, 1, "N", "valuename", I18S("Value name (e.g. server/temp/system)"), NULL}, + { A_ARG, A_INT, "numOfDatapoints", 0, 1, "n", NULL, I18S("Get up to n datapoints"), NULL}, + { 0, A_INT, "printMean", 0, 1, "M", "mean", I18S("Print mean value of data received"), NULL}, + { 0, A_INT, "printDiff", 0, 1, "D", "diff", I18S("Print diff last-first value"), NULL}, + { A_END, A_INT, "help", 0, 0, "h", "help", I18S("Show this help screen"), NULL} + }; + + eventLoop=AQH_EventLoop_new(); + dc=AQH_DataClient_new(eventLoop, AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION); + + rv=AQH_DataClient_ReadLocalArgs(dc, dbGlobalArgs, args, argc, argv); + if (rv<0) { + DBG_ERROR(NULL, "here (%d)", rv); + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 2; + } + + rv=AQH_DataClient_ConnectWithArgs(dc, 0); + if (rv<0) { + DBG_ERROR(NULL, "Error connecting (%d)", rv); + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 2; + } + + rv=_runCommand(dc); + if (rv<0) { + DBG_ERROR(NULL, "Error running (%d)", rv); + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 2; + } + + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 0; +} + + + +int _runCommand(AQH_DATACLIENT *dc) +{ + GWEN_DB_NODE *dbLocalArgs; + const char *valueName; + uint64_t num; + int printMean; + int printDiff; + + dbLocalArgs=AQH_DataClient_GetDbLocalArgs(dc); + valueName=GWEN_DB_GetCharValue(dbLocalArgs, "valueName", 0, NULL); + num=GWEN_DB_GetIntValue(dbLocalArgs, "numOfDatapoints", 0, 1); + printMean=GWEN_DB_GetIntValue(dbLocalArgs, "printMean", 0, 0); + printDiff=GWEN_DB_GetIntValue(dbLocalArgs, "printDiff", 0, 0); + + if (num>0) { + uint64_t *dataPoints; + uint64_t recvdNum; + + dataPoints=malloc(num*sizeof(uint64_t)*2); + + recvdNum=AQH_DataClient_GetFirstData(dc, valueName, dataPoints, num); + if (recvdNum>0) { + if (printMean) + Utils_PrintMeanData(dataPoints, recvdNum, NULL); + else if (printDiff) + Utils_PrintDiffData(dataPoints, recvdNum, NULL); + else + Utils_PrintDataPoints(dataPoints, recvdNum, NULL); + } + free(dataPoints); + } + + return 0; +} + + + diff --git a/apps/aqhome-tool/data/getfirstdata.h b/apps/aqhome-tool/data/getfirstdata.h new file mode 100644 index 0000000..17f25e5 --- /dev/null +++ b/apps/aqhome-tool/data/getfirstdata.h @@ -0,0 +1,21 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOME_TOOL_GETFIRSTDATA_H +#define AQHOME_TOOL_GETFIRSTDATA_H + + +#include + + + +int AQH_Tool_GetFirstData(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv); + + +#endif + diff --git a/apps/aqhome-tool/data/getlastdata.c b/apps/aqhome-tool/data/getlastdata.c new file mode 100644 index 0000000..d68fe2f --- /dev/null +++ b/apps/aqhome-tool/data/getlastdata.c @@ -0,0 +1,153 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "./getlastdata.h" +#include "../utils.h" + +#include "aqhome/dataclient/client.h" +#include "aqhome/msg/ipc/m_ipc.h" +#include "aqhome/msg/ipc/m_ipc_result.h" +#include "aqhome/msg/ipc/data/m_ipcd.h" +#include "aqhome/msg/ipc/data/m_ipcd_getdata.h" +#include "aqhome/msg/ipc/data/m_ipcd_multidata.h" +#include "aqhome/dataclient/client.h" + +#include +#include +#include +#include + +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defs + * ------------------------------------------------------------------------------------------------ + */ + +#define I18S(msg) msg +#define I18N(msg) GWEN_I18N_Translate(PACKAGE, msg) + +#define A_ARG GWEN_ARGS_FLAGS_HAS_ARGUMENT +#define A_END (GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST) +#define A_CHAR GWEN_ArgsType_Char +#define A_INT GWEN_ArgsType_Int + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static int _runCommand(AQH_DATACLIENT *dc); + + + + +/* ------------------------------------------------------------------------------------------------ + * code + * ------------------------------------------------------------------------------------------------ + */ + +int AQH_Tool_GetLastData(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv) +{ + AQH_EVENT_LOOP *eventLoop; + AQH_DATACLIENT *dc; + int rv; + const GWEN_ARGS args[]= { + /* flags type name min max s long short_descr, long_descr */ + { A_ARG, A_CHAR, "brokerAddress", 0, 1, "t", "tcpaddress", I18S("TCP address to connect to [127.0.0.1]"), NULL}, + { A_ARG, A_INT, "brokerPort", 0, 1, "P", "tcpport", I18S("Specify the TCP port to listen on"), NULL}, + { A_ARG, A_INT, "timeout", 0, 1, "T", NULL, I18S("Specify timeout in seconds for response"), NULL}, + { A_ARG, A_CHAR, "brokerClientId", 0, 1, "c", "clientid", I18S("Specify CLIENTID"), NULL}, + { A_ARG, A_CHAR, "userId", 0, 1, "u", "userid", I18S("Specify user id"), NULL}, + { A_ARG, A_CHAR, "password", 0, 1, "p", "password", I18S("Specify service password"), NULL}, + { A_ARG, A_CHAR, "valueName", 1, 1, "N", "valuename", I18S("Value name (e.g. server/temp/system)"), NULL}, + { A_ARG, A_INT, "numOfDatapoints", 0, 1, "n", NULL, I18S("Get up to n datapoints"), NULL}, + { 0, A_INT, "printMean", 0, 1, "M", "mean", I18S("Print mean value of data received"), NULL}, + { 0, A_INT, "printDiff", 0, 1, "D", "diff", I18S("Print diff last-first value"), NULL}, + { A_END, A_INT, "help", 0, 0, "h", "help", I18S("Show this help screen"), NULL} + }; + + eventLoop=AQH_EventLoop_new(); + dc=AQH_DataClient_new(eventLoop, AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION); + + rv=AQH_DataClient_ReadLocalArgs(dc, dbGlobalArgs, args, argc, argv); + if (rv<0) { + DBG_ERROR(NULL, "here (%d)", rv); + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 2; + } + + rv=AQH_DataClient_ConnectWithArgs(dc, 0); + if (rv<0) { + DBG_ERROR(NULL, "Error connecting (%d)", rv); + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 2; + } + + rv=_runCommand(dc); + if (rv<0) { + DBG_ERROR(NULL, "Error running (%d)", rv); + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 2; + } + + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 0; +} + + + +int _runCommand(AQH_DATACLIENT *dc) +{ + GWEN_DB_NODE *dbLocalArgs; + const char *valueName; + uint64_t num; + int printMean; + int printDiff; + + dbLocalArgs=AQH_DataClient_GetDbLocalArgs(dc); + valueName=GWEN_DB_GetCharValue(dbLocalArgs, "valueName", 0, NULL); + num=GWEN_DB_GetIntValue(dbLocalArgs, "numOfDatapoints", 0, 1); + printMean=GWEN_DB_GetIntValue(dbLocalArgs, "printMean", 0, 0); + printDiff=GWEN_DB_GetIntValue(dbLocalArgs, "printDiff", 0, 0); + + if (num>0) { + uint64_t *dataPoints; + uint64_t recvdNum; + + dataPoints=malloc(num*sizeof(uint64_t)*2); + + recvdNum=AQH_DataClient_GetLastData(dc, valueName, dataPoints, num); + if (recvdNum>0) { + if (printMean) + Utils_PrintMeanData(dataPoints, recvdNum, NULL); + else if (printDiff) + Utils_PrintDiffData(dataPoints, recvdNum, NULL); + else + Utils_PrintDataPoints(dataPoints, recvdNum, NULL); + } + free(dataPoints); + } + + return 0; +} + + + diff --git a/apps/aqhome-tool/data/getlastdata.h b/apps/aqhome-tool/data/getlastdata.h new file mode 100644 index 0000000..40b7d86 --- /dev/null +++ b/apps/aqhome-tool/data/getlastdata.h @@ -0,0 +1,21 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOME_TOOL_GETLASTDATA_H +#define AQHOME_TOOL_GETLASTDATA_H + + +#include + + + +int AQH_Tool_GetLastData(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv); + + +#endif + diff --git a/apps/aqhome-tool/data/getperioddata.c b/apps/aqhome-tool/data/getperioddata.c new file mode 100644 index 0000000..4fe2a0c --- /dev/null +++ b/apps/aqhome-tool/data/getperioddata.c @@ -0,0 +1,167 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "./getperioddata.h" +#include "../utils.h" + +#include "aqhome/dataclient/client.h" +#include "aqhome/msg/ipc/m_ipc.h" +#include "aqhome/msg/ipc/m_ipc_result.h" +#include "aqhome/msg/ipc/data/m_ipcd.h" +#include "aqhome/msg/ipc/data/m_ipcd_getdata.h" +#include "aqhome/msg/ipc/data/m_ipcd_multidata.h" +#include "aqhome/dataclient/client.h" + +#include +#include +#include +#include + +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defs + * ------------------------------------------------------------------------------------------------ + */ + +#define I18S(msg) msg +#define I18N(msg) GWEN_I18N_Translate(PACKAGE, msg) + +#define A_ARG GWEN_ARGS_FLAGS_HAS_ARGUMENT +#define A_END (GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST) +#define A_CHAR GWEN_ArgsType_Char +#define A_INT GWEN_ArgsType_Int + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static int _runCommand(AQH_DATACLIENT *dc); + + + + +/* ------------------------------------------------------------------------------------------------ + * code + * ------------------------------------------------------------------------------------------------ + */ + +int AQH_Tool_GetPeriodData(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv) +{ + AQH_EVENT_LOOP *eventLoop; + AQH_DATACLIENT *dc; + int rv; + const GWEN_ARGS args[]= { + /* flags type name min max s long short_descr, long_descr */ + { A_ARG, A_CHAR, "brokerAddress", 0, 1, "t", "tcpaddress", I18S("TCP address to connect to [127.0.0.1]"), NULL}, + { A_ARG, A_INT, "brokerPort", 0, 1, "P", "tcpport", I18S("Specify the TCP port to listen on"), NULL}, + { A_ARG, A_INT, "timeout", 0, 1, "T", NULL, I18S("Specify timeout in seconds for response"), NULL}, + { A_ARG, A_CHAR, "brokerClientId", 0, 1, "c", "clientid", I18S("Specify CLIENTID"), NULL}, + { A_ARG, A_CHAR, "userId", 0, 1, "u", "userid", I18S("Specify user id"), NULL}, + { A_ARG, A_CHAR, "password", 0, 1, "p", "password", I18S("Specify service password"), NULL}, + { A_ARG, A_CHAR, "valueName", 1, 1, "N", "valuename", I18S("Value name (e.g. server/temp/system)"), NULL}, + { A_ARG, A_INT, "numOfDatapoints", 0, 1, "n", NULL, I18S("Get up to n datapoints"), NULL}, + { A_ARG, A_CHAR, "tsBegin", 0, 1, "tb", "tsbegin", I18S("Timestamp range begin"), NULL}, + { A_ARG, A_CHAR, "tsEnd", 0, 1, "te", "tsend", I18S("Timestamp range end"), NULL}, + { 0, A_INT, "printMean", 0, 1, "M", "mean", I18S("Print mean value of data received"), NULL}, + { 0, A_INT, "printDiff", 0, 1, "D", "diff", I18S("Print diff last-first value"), NULL}, + { A_END, A_INT, "help", 0, 0, "h", "help", I18S("Show this help screen"), NULL} + }; + + eventLoop=AQH_EventLoop_new(); + dc=AQH_DataClient_new(eventLoop, AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION); + + rv=AQH_DataClient_ReadLocalArgs(dc, dbGlobalArgs, args, argc, argv); + if (rv<0) { + DBG_ERROR(NULL, "here (%d)", rv); + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 2; + } + + rv=AQH_DataClient_ConnectWithArgs(dc, 0); + if (rv<0) { + DBG_ERROR(NULL, "Error connecting (%d)", rv); + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 2; + } + + rv=_runCommand(dc); + if (rv<0) { + DBG_ERROR(NULL, "Error running (%d)", rv); + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 2; + } + + AQH_DataClient_free(dc); + AQH_EventLoop_free(eventLoop); + return 0; +} + + + +int _runCommand(AQH_DATACLIENT *dc) +{ + GWEN_DB_NODE *dbLocalArgs; + const char *valueName; + uint64_t num; + uint64_t tsBegin; + uint64_t tsEnd; + int printMean; + int printDiff; + + dbLocalArgs=AQH_DataClient_GetDbLocalArgs(dc); + valueName=GWEN_DB_GetCharValue(dbLocalArgs, "valueName", 0, NULL); + num=GWEN_DB_GetIntValue(dbLocalArgs, "numOfDatapoints", 0, 1); + tsBegin=Utils_GetTimeStampFromString(GWEN_DB_GetCharValue(dbLocalArgs, "tsBegin", 0, NULL)); + if (tsBegin==(uint64_t) (-1)) { + DBG_ERROR(NULL, "Bad begin timestamp"); + return 1; + } + tsEnd=Utils_GetTimeStampFromString(GWEN_DB_GetCharValue(dbLocalArgs, "tsEnd", 0, NULL)); + if (tsEnd==(uint64_t) (-1)) { + DBG_ERROR(NULL, "Bad end timestamp"); + return 1; + } + printMean=GWEN_DB_GetIntValue(dbLocalArgs, "printMean", 0, 0); + printDiff=GWEN_DB_GetIntValue(dbLocalArgs, "printDiff", 0, 0); + + if (num>0) { + uint64_t *dataPoints; + uint64_t recvdNum; + + dataPoints=malloc(num*sizeof(uint64_t)*2); + + recvdNum=AQH_DataClient_GetPeriodData(dc, valueName, dataPoints, num, tsBegin, tsEnd); + if (recvdNum>0) { + if (printMean) + Utils_PrintMeanData(dataPoints, recvdNum, NULL); + else if (printDiff) + Utils_PrintDiffData(dataPoints, recvdNum, NULL); + else + Utils_PrintDataPoints(dataPoints, recvdNum, NULL); + } + free(dataPoints); + } + + return 0; +} + + + diff --git a/apps/aqhome-tool/data/getperioddata.h b/apps/aqhome-tool/data/getperioddata.h new file mode 100644 index 0000000..77e7e0f --- /dev/null +++ b/apps/aqhome-tool/data/getperioddata.h @@ -0,0 +1,21 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOME_TOOL_GETPERIODDATA_H +#define AQHOME_TOOL_GETPERIODDATA_H + + +#include + + + +int AQH_Tool_GetPeriodData(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv); + + +#endif + diff --git a/apps/aqhome-tool/data/getvalues.c b/apps/aqhome-tool/data/getvalues.c index c91d0ea..7af66a3 100644 --- a/apps/aqhome-tool/data/getvalues.c +++ b/apps/aqhome-tool/data/getvalues.c @@ -14,10 +14,12 @@ #include "../client.h" #include "../utils.h" +#include "aqhome/aqhome.h" #include "aqhome/msg/ipc/m_ipc.h" #include "aqhome/msg/ipc/m_ipc_result.h" #include "aqhome/msg/ipc/data/m_ipcd.h" #include "aqhome/msg/ipc/data/m_ipcd_values.h" +#include "aqhome/msg/ipc/data/m_ipcd_getvalues.h" #include #include @@ -67,6 +69,8 @@ int AQH_Tool_GetValues(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv) { A_ARG, A_INT, "timeout", 0, 1, "T", NULL, I18S("Specify timeout in seconds for response"), NULL}, { A_ARG, A_CHAR, "brokerClientId", 0, 1, "c", "clientid", I18S("Specify CLIENTID"), NULL}, { A_ARG, A_CHAR, "userId", 0, 1, "u", "userid", I18S("Specify user id"), NULL}, + { A_ARG, A_CHAR, "device", 0, 1, "d", "device", I18S("device name to match"), NULL}, + { A_ARG, A_CHAR, "modality", 0, 1, "m", NULL, I18S("Modality to match"), NULL}, { A_ARG, A_CHAR, "password", 0, 1, "p", "password", I18S("Specify service password"), NULL}, { 0, A_INT, "printHeader", 0, 1, "H", "printheader", I18S("Print header if given"), NULL}, { A_END, A_INT, "help", 0, 0, "h", "help", I18S("Show this help screen"), NULL} @@ -90,11 +94,23 @@ int AQH_Tool_GetValues(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv) AQH_MESSAGE *_createRequestMessage(GWEN_UNUSED AQH_OBJECT *o, uint32_t msgId) { - return AQH_IpcMessage_new(AQH_IPC_PROTOCOL_DATA_ID, - AQH_IPC_PROTOCOL_DATA_VERSION, - AQH_MSGTYPE_IPC_DATA_GETVALUES_REQ, - msgId, 0, - 0, NULL); + GWEN_DB_NODE *dbArgs; + const char *deviceName; + const char *s; + int modality; + + dbArgs=AQH_ToolClient_GetDbLocalArgs(o); + deviceName=GWEN_DB_GetCharValue(dbArgs, "device", 0, NULL); + s=GWEN_DB_GetCharValue(dbArgs, "modality", 0, NULL); + if (s && *s) { + modality=AQH_ValueModality_fromString(s); + if (modality==AQH_ValueModality_Unknown) { + } + } + else + modality=AQH_ValueModality_Unknown; + + return AQH_IpcdMessageGetValues_new(AQH_MSGTYPE_IPC_DATA_GETVALUES_REQ, msgId, 0, deviceName, modality); } diff --git a/apps/aqhome-tool/main.c b/apps/aqhome-tool/main.c index a062873..ba251fe 100644 --- a/apps/aqhome-tool/main.c +++ b/apps/aqhome-tool/main.c @@ -1,6 +1,6 @@ /**************************************************************************** * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. * * The license for this file can be found in the file COPYING which you * should have received along with this file. @@ -17,9 +17,13 @@ #include "./data/getdevices.h" #include "./data/adddata.h" #include "./data/getdatapoints.h" +#include "./data/getfirstdata.h" +#include "./data/getlastdata.h" +#include "./data/getperioddata.h" #include "./data/setdata.h" #include "./data/moddevice.h" #include "./data/watch.h" +#include "./data/devicestate.h" #include #include @@ -92,9 +96,13 @@ int main(int argc, char **argv) GWEN_FE_DAH("adddata", AQH_Tool_AddDataPoint, I18N("Send a datapoint to the data server")), GWEN_FE_DAH("addjsondata", AQH_Tool_AddDataPoint, I18N("(same as adddata)")), GWEN_FE_DAH("getdata", AQH_Tool_GetDataPoints, I18N("Request list of datapoints for a value on the data server")), + GWEN_FE_DAH("getfirstdata", AQH_Tool_GetFirstData, I18N("Request first datapoints for a value on the data server")), + GWEN_FE_DAH("getlastdata", AQH_Tool_GetLastData, I18N("Request last datapoints for a value on the data server")), + GWEN_FE_DAH("getperioddata", AQH_Tool_GetPeriodData, I18N("Request datapoints from a date range for a value on the data server")), GWEN_FE_DAH("setdata", AQH_Tool_SetData, I18N("Set data for a value on the data server (e.g. a switch or thermostat)")), GWEN_FE_DAH("moddevice", AQH_Tool_ModDevice, I18N("Modify a device on the data server")), GWEN_FE_DAH("watch", AQH_Tool_Watch, I18N("Watch and print changes of values on the data server")), + GWEN_FE_DAH("devicestate", AQH_Tool_DeviceState, I18N("Show state of devices")), GWEN_FE_END(), }; const GWEN_FUNCS *func; diff --git a/apps/aqhome-tool/utils.c b/apps/aqhome-tool/utils.c index 9c9b718..5c7ddf1 100644 --- a/apps/aqhome-tool/utils.c +++ b/apps/aqhome-tool/utils.c @@ -19,6 +19,7 @@ #include "aqhome/msg/ipc/nodes/m_ipcn_setaccmsggrps.h" #include "aqhome/ipc2/tcp_object.h" #include "aqhome/ipc2/ipc_client.h" +#include "aqhome/dataclient/client.h" #include @@ -27,6 +28,7 @@ #include #include +#include #define UTILS_IPC_ENDPOINT_DEFAULT_MSGSIZE 4096 @@ -361,4 +363,47 @@ void Utils_PrintValue(const AQH_VALUE *value, int printHeader) +uint64_t Utils_GetTimeStampFromString(const char *s) +{ + if (s && *s) { + if (*s=='-') { + uint64_t x=0; + uint64_t now=time(NULL); + + s++; + while(*s && isdigit(*s)) { + unsigned int i; + + i=*(s++)-'0'; + x*=10; + x+=i; + } + if (*s) { + switch(*s) { + case 0: + case 'm': x*=60; break; + case 'h': x*=(60*60); break; + case 'd': x*=(60*60*24); break; + default: break; + } + } + return (now-x); + } + else { + unsigned long int x; + + if (1!=sscanf(s, "%lu", &x)) { + DBG_ERROR(NULL, "ERROR: Invalid timestamp"); + return (uint64_t) (-1); + } + return (uint64_t) x; + } + } + return 0; +} + + + + + diff --git a/apps/aqhome-tool/utils.h b/apps/aqhome-tool/utils.h index 125c31d..9c001bf 100644 --- a/apps/aqhome-tool/utils.h +++ b/apps/aqhome-tool/utils.h @@ -41,6 +41,8 @@ void Utils_PrintValue(const AQH_VALUE *value, int printHeader); AQH_DEVICE *Utils_DeviceFromArgs(GWEN_DB_NODE *dbArgs); +uint64_t Utils_GetTimeStampFromString(const char *s); + #endif diff --git a/aqhome-cgi.sh b/aqhome-cgi.sh new file mode 100644 index 0000000..32a3a70 --- /dev/null +++ b/aqhome-cgi.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# AQHOME_LOGLEVEL=info LD_LIBRARY_PATH="../../aqhome/:$LD_LIBRARY_PATH" ./aqhomed -l aqhome.log -db aqhome.db -ma 127.0.0.1 + +# export AQHOME_LOGLEVEL=info +export LD_LIBRARY_PATH="0-build/aqhome/:$LD_LIBRARY_PATH" + +# aqhomed -l /var/log/aqhome.log -db /var/cache/aqhome/nodes.db -ma 192.168.117.192 -mp 1883 -t 127.0.0.1 -W /var/cache/aqhome + +# 0-build/apps/aqhomed/aqhomed -l aqhome.log -db aqhome.db -ma 192.168.117.192 -mp 1883 -t 127.0.0.1 -p aqhomed.pid + +# 0-build/apps/aqhomed/aqhomed -l aqhome.log -db aqhome.db -p aqhomed.pid -W /tmp/aqhome/aqhomed -ma 192.168.117.192 -mp 1883 -t 127.0.0.1 --mqttclientid=AQHOMEMQTTLOGTEST1 +0-build/apps/aqhome-cgi/aqhome-cgi +#0-build/apps/aqhome-nodes/aqhome-nodes -l aqhome-nodes.log -db aqhome-nodes.db -p aqhome-nodes.pid -t 127.0.0.1 -ba 127.0.0.1 "$@" diff --git a/aqhome/0BUILD b/aqhome/0BUILD index d33f5d3..fbb58e8 100644 --- a/aqhome/0BUILD +++ b/aqhome/0BUILD @@ -69,6 +69,7 @@ hexfile data events2 + dataclient
@@ -79,6 +80,7 @@ aqhhexfile aqhdata aqhevents2 + aqhdataclient diff --git a/aqhome/aqhome.c b/aqhome/aqhome.c index 473444d..8987a43 100644 --- a/aqhome/aqhome.c +++ b/aqhome/aqhome.c @@ -267,6 +267,8 @@ int AQH_ValueModality_fromString(const char *s) return AQH_ValueModality_TVOC; else if (strcasecmp(s, "stats")==0) return AQH_ValueModality_Stats; + else if (strcasecmp(s, "light")==0) + return AQH_ValueModality_Light; } return AQH_ValueModality_Unknown; } @@ -285,6 +287,7 @@ const char *AQH_ValueModality_toString(int i) case AQH_ValueModality_Co2: return "co2"; case AQH_ValueModality_TVOC: return "tvoc"; case AQH_ValueModality_Stats: return "stats"; + case AQH_ValueModality_Light: return "light"; case AQH_ValueModality_Unknown: default: return "unknown"; } diff --git a/aqhome/aqhome.h b/aqhome/aqhome.h index 185ca2e..cc6a85b 100644 --- a/aqhome/aqhome.h +++ b/aqhome/aqhome.h @@ -45,7 +45,8 @@ enum { AQH_ValueModality_Motion, AQH_ValueModality_Co2, AQH_ValueModality_TVOC, - AQH_ValueModality_Stats + AQH_ValueModality_Stats, + AQH_ValueModality_Light }; diff --git a/aqhome/data/storage.c b/aqhome/data/storage.c index 74a8a65..8315828 100644 --- a/aqhome/data/storage.c +++ b/aqhome/data/storage.c @@ -23,7 +23,7 @@ #define AQH_STORAGE_DATAPOINTS_STEPS 128 - +#define AQH_STORAGE_MAXOPENFILES 128 /* ------------------------------------------------------------------------------------------------ @@ -305,6 +305,17 @@ AQH_STORAGE_GETLASTDATAPOINT_FN AQH_Storage_SetGetLastDatapointFn(AQH_STORAGE *s +AQH_STORAGE_GETFIRSTNDATAPOINTS_FN AQH_Storage_SetGetFirstNDatapointsFn(AQH_STORAGE *sto, AQH_STORAGE_GETFIRSTNDATAPOINTS_FN fn) +{ + AQH_STORAGE_GETFIRSTNDATAPOINTS_FN oldFn; + + oldFn=sto->getFirstNDatapointsFn; + sto->getFirstNDatapointsFn=fn; + return oldFn; +} + + + AQH_STORAGE_GETLASTNDATAPOINTS_FN AQH_Storage_SetGetLastNDatapointsFn(AQH_STORAGE *sto, AQH_STORAGE_GETLASTNDATAPOINTS_FN fn) { AQH_STORAGE_GETLASTNDATAPOINTS_FN oldFn; @@ -383,8 +394,8 @@ int AQH_Storage_AddDatapoint(AQH_STORAGE *sto, uint64_t valueId, uint64_t timest } - -uint64_t *AQH_Storage_GetDataPoints(AQH_STORAGE *sto, uint64_t valueId, uint64_t fromTime, uint64_t toTime, uint64_t maxArrayLen) +uint64_t *AQH_Storage_GetDataPoints(AQH_STORAGE *sto, uint64_t valueId, uint64_t fromTime, uint64_t toTime, + uint64_t maxDataPointsRequested) { AQH_DATAFILE *df; uint64_t numEntries; @@ -399,13 +410,9 @@ uint64_t *AQH_Storage_GetDataPoints(AQH_STORAGE *sto, uint64_t valueId, uint64_t return NULL; } numEntries=AQH_DataFile_GetNumberOfEntries(df); - if (fromTime==0 && toTime==0) - arrayLen=(numEntries*2)+1; - else - arrayLen=(AQH_STORAGE_DATAPOINTS_STEPS*2)+1; - if (arrayLen>maxArrayLen+1) - arrayLen=maxArrayLen+1; - + if (maxDataPointsRequested>numEntries) + maxDataPointsRequested=numEntries; + arrayLen=(maxDataPointsRequested*2)+1; arrayPtr=(uint64_t*) malloc(arrayLen*sizeof(uint64_t)); if (arrayPtr==NULL) { DBG_ERROR(AQH_LOGDOMAIN, "Not enough memory for %lu entries", (unsigned long int) arrayLen); @@ -427,30 +434,11 @@ uint64_t *AQH_Storage_GetDataPoints(AQH_STORAGE *sto, uint64_t valueId, uint64_t } if ((fromTime==0 || ts>=fromTime) && (toTime==0 || ts<=toTime)) { - if ((arrayPos+1)>maxArrayLen) { + if ((arrayPos+1)>arrayLen) { DBG_INFO(AQH_LOGDOMAIN, "Limit for number of returned entries reached"); break; } - if (arrayPos+1>=arrayLen) { - uint64_t newArrayLen; - void *p; - newArrayLen=arrayLen+(AQH_STORAGE_DATAPOINTS_STEPS*2); - if (newArrayLen>maxArrayLen+1) - newArrayLen=maxArrayLen+1; - if (newArrayLen==arrayLen) { - DBG_INFO(AQH_LOGDOMAIN, "Limit for number of returned entries reached"); - break; - } - p=realloc((void*) arrayPtr, newArrayLen*sizeof(uint64_t)); - if (p==NULL) { - DBG_ERROR(AQH_LOGDOMAIN, "Not enough memory for %lu entries", (unsigned long int) arrayLen+AQH_STORAGE_DATAPOINTS_STEPS); - free(arrayPtr); - return NULL; - } - arrayPtr=(uint64_t*) p; - arrayLen=newArrayLen; - } arrayPtr[arrayPos++]=ts; arrayPtr[arrayPos++]=u.i; } @@ -468,6 +456,67 @@ uint64_t *AQH_Storage_GetDataPoints(AQH_STORAGE *sto, uint64_t valueId, uint64_t +uint64_t *AQH_Storage_GetFirstNDataPoints(AQH_STORAGE *sto, uint64_t valueId, uint64_t maxDataPointsRequested) +{ + AQH_DATAFILE *df; + uint64_t numEntries; + uint64_t numOfDataEntries; + uint64_t arrayLen; + uint64_t arrayPos; + uint64_t *arrayPtr; + uint64_t firstRecord; + uint64_t i; + + df=_getDataFileByValueId(sto, valueId); + if (df==NULL) { + DBG_ERROR(AQH_LOGDOMAIN, "No file for value id %lu", (unsigned long int) valueId); + return NULL; + } + numEntries=AQH_DataFile_GetNumberOfEntries(df); + numOfDataEntries=numEntries-1; /* first entry is reserved, don't count it here */ + if (numOfDataEntries<1) { + DBG_INFO(AQH_LOGDOMAIN, "No data records for value id %lu", (unsigned long int) valueId); + return NULL; + } + firstRecord=1; + if (numOfDataEntries>maxDataPointsRequested) /* more entries in file than requested */ + arrayLen=(maxDataPointsRequested*2)+1; /* +1 because the first array entry contains the number of entries */ + else + arrayLen=(numOfDataEntries*2)+1; + + arrayPtr=(uint64_t*) malloc(arrayLen*sizeof(uint64_t)); + if (arrayPtr==NULL) { + DBG_ERROR(AQH_LOGDOMAIN, "Not enough memory for %lu entries", (unsigned long int) arrayLen); + return NULL; + } + arrayPos=1; + + for (i=firstRecord; i=arrayLen) { + DBG_INFO(AQH_LOGDOMAIN, "Requested number of entries reached"); + break; + } + arrayPtr[arrayPos++]=ts; + arrayPtr[arrayPos++]=u.i; + } /* for */ + + arrayPtr[0]=arrayPos-1; + return arrayPtr; +} + + + uint64_t *AQH_Storage_GetLastNDataPoints(AQH_STORAGE *sto, uint64_t valueId, uint64_t maxDataPointsRequested) { AQH_DATAFILE *df; @@ -601,6 +650,16 @@ AQH_DATAFILE *_getDataFileByValueId(AQH_STORAGE *sto, uint64_t valueId) DBG_ERROR(AQH_LOGDOMAIN, "Error opening/creating datafile for valueId \"%lu\"", (unsigned long int) valueId); return NULL; } + if (AQH_DataFile_List_GetCount(sto->dataFileList)>=AQH_STORAGE_MAXOPENFILES) { + AQH_DATAFILE *dfLast; + + dfLast=AQH_DataFile_List_Last(sto->dataFileList); + if (dfLast) { + AQH_DataFile_Close(dfLast); + AQH_DataFile_List_Del(dfLast); + AQH_DataFile_free(dfLast); + } + } DBG_DEBUG(AQH_LOGDOMAIN, "Adding datafile for valueId \"%lu\" to list", (unsigned long int) valueId); AQH_DataFile_List_Add(df, sto->dataFileList); } @@ -612,8 +671,17 @@ AQH_DATAFILE *_getDataFileByValueId(AQH_STORAGE *sto, uint64_t valueId) AQH_DATAFILE *_findDataFileByValueId(const AQH_STORAGE *sto, uint64_t valueId) { - if (sto && sto->dataFileList) - return AQH_DataFile_List_GetByValueId(sto->dataFileList, valueId); + if (sto && sto->dataFileList) { + AQH_DATAFILE *df; + + df=AQH_DataFile_List_GetByValueId(sto->dataFileList, valueId); + if (df) { + /* move to front of list */ + AQH_DataFile_List_Del(df); + AQH_DataFile_List_Insert(df, sto->dataFileList); + return df; + } + } return NULL; } diff --git a/aqhome/data/storage.h b/aqhome/data/storage.h index c23152f..d30b257 100644 --- a/aqhome/data/storage.h +++ b/aqhome/data/storage.h @@ -53,6 +53,8 @@ typedef uint64_t *(*AQH_STORAGE_GETDATAPOINTS_FN)(AQH_STORAGE *sto, uint64_t val uint64_t maxArrayLen); typedef int (*AQH_STORAGE_GETFIRSTDATAPOINT_FN)(AQH_STORAGE *sto, uint64_t valueId, uint64_t *pTimestamp, double *pValue); typedef int (*AQH_STORAGE_GETLASTDATAPOINT_FN)(AQH_STORAGE *sto, uint64_t valueId, uint64_t *pTimestamp, double *pValue); + +typedef uint64_t *(*AQH_STORAGE_GETFIRSTNDATAPOINTS_FN)(AQH_STORAGE *sto, uint64_t valueId, uint64_t maxDataPointsRequested); typedef uint64_t *(*AQH_STORAGE_GETLASTNDATAPOINTS_FN)(AQH_STORAGE *sto, uint64_t valueId, uint64_t maxDataPointsRequested); @@ -96,6 +98,8 @@ AQHOME_API uint64_t *AQH_Storage_GetDataPoints(AQH_STORAGE *sto, uint64_t valueI uint64_t maxArrayLen); AQHOME_API int AQH_Storage_GetFirstDataPoint(AQH_STORAGE *sto, uint64_t valueId, uint64_t *pTimestamp, double *pValue); AQHOME_API int AQH_Storage_GetLastDataPoint(AQH_STORAGE *sto, uint64_t valueId, uint64_t *pTimestamp, double *pValue); + +AQHOME_API uint64_t *AQH_Storage_GetFirstNDataPoints(AQH_STORAGE *sto, uint64_t valueId, uint64_t maxDataPointsRequested); AQHOME_API uint64_t *AQH_Storage_GetLastNDataPoints(AQH_STORAGE *sto, uint64_t valueId, uint64_t maxDataPointsRequested); @@ -105,6 +109,8 @@ AQHOME_API AQH_STORAGE_ADDDATAPOINT_FN AQH_Storage_SetAddDatapointFn(AQH_STORAGE AQHOME_API AQH_STORAGE_GETDATAPOINTS_FN AQH_Storage_SetGetDatapointsFn(AQH_STORAGE *sto, AQH_STORAGE_GETDATAPOINTS_FN fn); AQHOME_API AQH_STORAGE_GETFIRSTDATAPOINT_FN AQH_Storage_SetGetFirstDatapointFn(AQH_STORAGE *sto, AQH_STORAGE_GETFIRSTDATAPOINT_FN fn); AQHOME_API AQH_STORAGE_GETLASTDATAPOINT_FN AQH_Storage_SetGetLastDatapointFn(AQH_STORAGE *sto, AQH_STORAGE_GETLASTDATAPOINT_FN fn); + +AQHOME_API AQH_STORAGE_GETFIRSTNDATAPOINTS_FN AQH_Storage_SetGetFirstNDatapointsFn(AQH_STORAGE *sto, AQH_STORAGE_GETFIRSTNDATAPOINTS_FN fn); AQHOME_API AQH_STORAGE_GETLASTNDATAPOINTS_FN AQH_Storage_SetGetLastNDatapointsFn(AQH_STORAGE *sto, AQH_STORAGE_GETLASTNDATAPOINTS_FN fn); diff --git a/aqhome/data/storage_p.h b/aqhome/data/storage_p.h index 0cc5701..c8cad6b 100644 --- a/aqhome/data/storage_p.h +++ b/aqhome/data/storage_p.h @@ -47,6 +47,7 @@ struct AQH_STORAGE { AQH_STORAGE_GETFIRSTDATAPOINT_FN getFirstDatapointFn; AQH_STORAGE_GETLASTDATAPOINT_FN getLastDatapointFn; AQH_STORAGE_GETLASTNDATAPOINTS_FN getLastNDatapointsFn; + AQH_STORAGE_GETFIRSTNDATAPOINTS_FN getFirstNDatapointsFn; }; diff --git a/aqhome/dataclient/0BUILD b/aqhome/dataclient/0BUILD new file mode 100644 index 0000000..5300f9d --- /dev/null +++ b/aqhome/dataclient/0BUILD @@ -0,0 +1,81 @@ + + + + + + + + $(gwenhywfar_cflags) + $(aqdatabase_cflags) + -I$(topsrcdir) + -I$(topbuilddir) + + + + --include=$(builddir) + --include=$(srcdir) + --include=$(aqdatabase_AQDATABASE_TYPEMAKERDIR)/c + + + + + + $(visibility_cflags) + + + + --api=AQHOME_API + + + + + + + + + + + + + + + + + + $(local/built_headers_pub) + + + + + client.h + + + + + client_p.h + + + + + $(local/typefiles) + + client.c + + + + + + + + + + + + + + + + + + + diff --git a/aqhome/dataclient/client.c b/aqhome/dataclient/client.c new file mode 100644 index 0000000..578db7b --- /dev/null +++ b/aqhome/dataclient/client.c @@ -0,0 +1,555 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "./client_p.h" + +#include "aqhome/aqhome.h" +#include "aqhome/msg/ipc/m_ipc.h" +#include "aqhome/msg/ipc/m_ipc_tag16.h" +#include "aqhome/msg/ipc/m_ipc_result.h" +#include "aqhome/msg/ipc/data/m_ipcd.h" +#include "aqhome/msg/ipc/nodes/m_ipcn.h" +#include "aqhome/msg/ipc/m_ipc_connect.h" +#include "aqhome/msg/ipc/data/m_ipcd_devices.h" +#include "aqhome/msg/ipc/data/m_ipcd_values.h" +#include "aqhome/msg/ipc/data/m_ipcd_getvalues.h" +#include "aqhome/msg/ipc/data/m_ipcd_getdata.h" +#include "aqhome/msg/ipc/data/m_ipcd_multidata.h" +#include "aqhome/msg/ipc/data/m_ipcd_setdata.h" +#include "aqhome/ipc2/tcp_object.h" +#include "aqhome/ipc2/ipc_client.h" +#include + +#include +#include +#include +#include +#include + + +#define AQH_DATA_CLIENT_DEFAULT_CMD_TIMEOUT 5 + + + +static int _connectEndpoint(AQH_DATACLIENT *dc, const char *addr, int port, uint32_t flags); +static int _exchangeConnectMsgs(AQH_DATACLIENT *dc, const char *userId, const char *passwd, const char *clientId, uint32_t flags); +static uint64_t _getFirstOrLastData(AQH_DATACLIENT *dc, const char *valueName, uint64_t *dataPtr, uint64_t maxNum, int mode); +static uint64_t _handleDataResponses(AQH_DATACLIENT *dc, uint64_t *dataPtr, uint64_t maxNum, uint32_t msgId); +static int _handleResult(AQH_DATACLIENT *dc, uint32_t msgId); + + + + + + +AQH_DATACLIENT *AQH_DataClient_new(AQH_EVENT_LOOP *eventLoop, uint8_t protoId, uint8_t protoVer) +{ + AQH_DATACLIENT *dc; + + GWEN_NEW_OBJECT(AQH_DATACLIENT, dc); + + dc->eventLoop=eventLoop; + dc->protoId=protoId; + dc->protoVer=protoVer; + dc->timeoutInSeconds=AQH_DATA_CLIENT_DEFAULT_CMD_TIMEOUT; + + return dc; +} + + + +void AQH_DataClient_free(AQH_DATACLIENT *dc) +{ + if (dc) { + AQH_Object_free(dc->ipcEndpoint); + GWEN_FREE_OBJECT(dc); + } +} + + + +int AQH_DataClient_ReadLocalArgs(AQH_DATACLIENT *dc, + GWEN_DB_NODE *dbGlobalArgs, const GWEN_ARGS *args, + int argc, char **argv) +{ + if (dc) { + int rv; + + GWEN_DB_Group_free(dc->dbLocalArgs); + dc->dbLocalArgs=GWEN_DB_GetGroup(dbGlobalArgs, GWEN_DB_FLAGS_DEFAULT, "local"); + rv=GWEN_Args_Check(argc, argv, 1, GWEN_ARGS_MODE_ALLOW_FREEPARAM, args, dc->dbLocalArgs); + if (rv==GWEN_ARGS_RESULT_ERROR) { + fprintf(stderr, "ERROR: Could not parse arguments\n"); + return 1; + } + else if (rv==GWEN_ARGS_RESULT_HELP) { + GWEN_BUFFER *ubuf; + + ubuf=GWEN_Buffer_new(0, 1024, 0, 1); + if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) { + fprintf(stderr, "ERROR: Could not create help string\n"); + return 1; + } + fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf)); + GWEN_Buffer_free(ubuf); + return 1; + } + dc->timeoutInSeconds=GWEN_DB_GetIntValue(dc->dbLocalArgs, "timeout", 0, 5); + + AQH_MergeConfigFileIntoConfig(dc->dbLocalArgs, "ConfigFile"); + return 0; + } + return GWEN_ERROR_INVALID; +} + + + +GWEN_DB_NODE *AQH_DataClient_GetDbLocalArgs(const AQH_DATACLIENT *dc) +{ + return dc?dc->dbLocalArgs:NULL; +} + + + +int AQH_DataClient_Connect(AQH_DATACLIENT *dc, + const char *addr, int port, + const char *userId, const char *passwd, + const char *clientId, + uint32_t flags) +{ + if (dc) { + int rv; + + AQH_Object_free(dc->ipcEndpoint); + dc->ipcEndpoint=NULL; + + rv=_connectEndpoint(dc, addr, port, 0 /* connection flags */); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } + + rv=_exchangeConnectMsgs(dc, userId, passwd, clientId, flags); + if (rv<0) { + AQH_Object_free(dc->ipcEndpoint); + dc->ipcEndpoint=NULL; + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } + return 0; + } + return GWEN_ERROR_INVALID; +} + + + +int AQH_DataClient_Disconnect(AQH_DATACLIENT *dc) +{ + if (dc) { + AQH_Object_free(dc->ipcEndpoint); + dc->ipcEndpoint=NULL; + return 0; + } + return GWEN_ERROR_INVALID; +} + + + +void AQH_DataClient_SetTimeout(AQH_DATACLIENT *dc, int i) +{ + if (dc) { + dc->timeoutInSeconds=i; + } +} + + + +AQH_DEVICE_LIST *AQH_DataClient_GetDevices(AQH_DATACLIENT *dc) +{ + if (dc) { + AQH_MESSAGE *msgOut; + AQH_MESSAGE *msgIn; + uint32_t msgId; + AQH_DEVICE_LIST *fullDeviceList; + + fullDeviceList=AQH_Device_List_new(); + msgId=++(dc->lastMsgId); + msgOut=AQH_IpcMessage_new(dc->protoId, dc->protoVer, AQH_MSGTYPE_IPC_DATA_GETDEVICES_REQ, msgId, 0, 0, NULL); + AQH_Endpoint_AddMsgOut(dc->ipcEndpoint, msgOut); + + while( (msgIn=AQH_IpcEndpoint_WaitForResponseMsg(dc->ipcEndpoint, msgId, dc->timeoutInSeconds)) ) { + GWEN_TAG16_LIST *tagList; + + tagList=AQH_IpcMessageTag16_ParsePayload(msgIn, 0); + if (tagList) { + uint16_t code; + + code=AQH_IpcMessage_GetCode(msgIn); + if (code==AQH_MSGTYPE_IPC_DATA_GETDEVICES_RSP) { + AQH_DEVICE_LIST *deviceList; + + deviceList=AQH_IpcdMessageDevices_ReadDeviceList(tagList); + if (deviceList) { + AQH_Device_List_AddList(fullDeviceList, deviceList); + AQH_Device_List_free(deviceList); + } + if (AQH_IpcdMessageDevices_GetFlags(tagList) & AQH_MSGDATA_DEVICES_FLAGS_LASTMSG) { + GWEN_Tag16_List_free(tagList); + AQH_Message_free(msgIn); + break; + } + } + else if (code==AQH_MSGTYPE_IPC_DATA_RESULT) { + DBG_ERROR(NULL, "Server Error: %d", AQH_IpcMessageResult_GetResult(tagList)); + GWEN_Tag16_List_free(tagList); + AQH_Message_free(msgIn); + AQH_Device_List_free(fullDeviceList); + return NULL; + } + else { + DBG_INFO(NULL, "Ignoring message \"%d\"", code); + } + GWEN_Tag16_List_free(tagList); + } + AQH_Message_free(msgIn); + } /* while */ + + if (AQH_Device_List_GetCount(fullDeviceList)>0) + return fullDeviceList; + AQH_Device_List_free(fullDeviceList); + } + return NULL; +} + + + +AQH_VALUE_LIST *AQH_DataClient_GetValues(AQH_DATACLIENT *dc, const char *deviceName, int modality) +{ + if (dc) { + AQH_MESSAGE *msgOut; + AQH_MESSAGE *msgIn; + uint32_t msgId; + AQH_VALUE_LIST *fullValueList; + + fullValueList=AQH_Value_List_new(); + msgId=++(dc->lastMsgId); + msgOut=AQH_IpcdMessageGetValues_new(AQH_MSGTYPE_IPC_DATA_GETVALUES_REQ, msgId, 0, deviceName, modality); + AQH_Endpoint_AddMsgOut(dc->ipcEndpoint, msgOut); + + while( (msgIn=AQH_IpcEndpoint_WaitForResponseMsg(dc->ipcEndpoint, msgId, dc->timeoutInSeconds)) ) { + GWEN_TAG16_LIST *tagList; + + tagList=AQH_IpcMessageTag16_ParsePayload(msgIn, 0); + if (tagList) { + uint16_t code; + + code=AQH_IpcMessage_GetCode(msgIn); + if (code==AQH_MSGTYPE_IPC_DATA_GETVALUES_RSP) { + AQH_VALUE_LIST *valueList; + + valueList=AQH_IpcdMessageValues_ReadValueList(tagList); + if (valueList) { + AQH_Value_List_AddList(fullValueList, valueList); + AQH_Value_List_free(valueList); + } + if (AQH_IpcdMessageValues_GetFlags(tagList) & AQH_MSGDATA_VALUES_FLAGS_LASTMSG) { + GWEN_Tag16_List_free(tagList); + AQH_Message_free(msgIn); + break; + } + } + else if (code==AQH_MSGTYPE_IPC_DATA_RESULT) { + DBG_ERROR(NULL, "Server Error: %d", AQH_IpcMessageResult_GetResult(tagList)); + GWEN_Tag16_List_free(tagList); + AQH_Message_free(msgIn); + AQH_Value_List_free(fullValueList); + return NULL; + } + else { + DBG_INFO(NULL, "Ignoring message \"%d\"", code); + } + GWEN_Tag16_List_free(tagList); + } + AQH_Message_free(msgIn); + } /* while */ + + if (AQH_Value_List_GetCount(fullValueList)>0) + return fullValueList; + AQH_Value_List_free(fullValueList); + } + return NULL; +} + + + +uint64_t AQH_DataClient_GetFirstData(AQH_DATACLIENT *dc, const char *valueName, uint64_t *dataPtr, uint64_t maxNum) +{ + return _getFirstOrLastData(dc, valueName, dataPtr, maxNum, AQH_MSGDATA_GETDATA_MODE_FIRST); +} + + + +uint64_t AQH_DataClient_GetLastData(AQH_DATACLIENT *dc, const char *valueName, uint64_t *dataPtr, uint64_t maxNum) +{ + return _getFirstOrLastData(dc, valueName, dataPtr, maxNum, AQH_MSGDATA_GETDATA_MODE_LAST); +} + + + +uint64_t AQH_DataClient_GetPeriodData(AQH_DATACLIENT *dc, const char *valueName, + uint64_t *dataPtr, uint64_t maxNum, + uint64_t tsBegin, uint64_t tsEnd) +{ + if (dc) { + AQH_MESSAGE *msgOut; + uint32_t msgId; + + msgId=++(dc->lastMsgId); + msgOut=AQH_IpcdMessageGetData_new(AQH_MSGTYPE_IPC_DATA_GETDATA_REQ, + msgId, 0, + AQH_MSGDATA_GETDATA_MODE_PERIOD, + valueName, tsBegin, tsEnd, maxNum); + AQH_Endpoint_AddMsgOut(dc->ipcEndpoint, msgOut); + + return _handleDataResponses(dc, dataPtr, maxNum, msgId); + } + return 0; +} + + + +int AQH_DataClient_SetData(AQH_DATACLIENT *dc, const AQH_VALUE *v, const char *data) +{ + if (dc) { + AQH_MESSAGE *msgOut; + uint32_t msgId; + + msgId=++(dc->lastMsgId); + msgOut=AQH_IpcdMessageSetData_new(AQH_MSGTYPE_IPC_DATA_SETDATA, msgId, 0, v, data); + AQH_Endpoint_AddMsgOut(dc->ipcEndpoint, msgOut); + + return _handleResult(dc, msgId); + } + + return GWEN_ERROR_INVALID; +} + + + +int AQH_DataClient_UpdateData(AQH_DATACLIENT *dc, const AQH_VALUE *v, uint64_t timeStamp, double dataPoint) +{ + if (dc) { + AQH_MESSAGE *msgOut; + uint32_t msgId; + + msgId=++(dc->lastMsgId); + msgOut=AQH_IpcdMessageMultiData_newForOne(AQH_MSGTYPE_IPC_DATA_UPDATEDATA, msgId, 0, v, timeStamp, dataPoint); + AQH_Endpoint_AddMsgOut(dc->ipcEndpoint, msgOut); + + return _handleResult(dc, msgId); + } + + return GWEN_ERROR_INVALID; +} + + + + + + +int _connectEndpoint(AQH_DATACLIENT *dc, const char *addr, int port, uint32_t flags) +{ + if (dc) { + AQH_OBJECT *ep; + int fd; + + fd=AQH_TcpObject_CreateConnectedSocket(addr, port); + if (fd<0) { + DBG_ERROR(NULL, "Error connecting to broker server %s:%d", addr, port); + return GWEN_ERROR_IO; + } + + ep=AQH_IpcClientObject_new(dc->eventLoop, fd); + assert(ep); + AQH_Endpoint_AddFlags(ep, flags); + dc->ipcEndpoint=ep; + return 0; + } + + return GWEN_ERROR_INVALID; +} + + + +int _exchangeConnectMsgs(AQH_DATACLIENT *dc, const char *userId, const char *passwd, const char *clientId, uint32_t flags) +{ + AQH_MESSAGE *msgOut; + uint32_t msgId; + + DBG_INFO(NULL, "Sending connect message for proto=%d.%d", dc->protoId, dc->protoVer); + msgId=AQH_Endpoint_GetNextMessageId(dc->ipcEndpoint); + msgOut=AQH_IpcMessageConnect_new(dc->protoId, dc->protoVer, + AQH_MSGTYPE_IPC_CONNECT_REQ, + msgId, 0, + clientId, userId, passwd, flags); + AQH_Endpoint_AddMsgOut(dc->ipcEndpoint, msgOut); + return AQH_IpcEndpoint_WaitForResultMsg(dc->ipcEndpoint, + dc->protoId, dc->protoVer, AQH_MSGTYPE_IPC_RESULT, + msgId, dc->timeoutInSeconds); +} + + + +uint64_t _getFirstOrLastData(AQH_DATACLIENT *dc, const char *valueName, uint64_t *dataPtr, uint64_t maxNum, int mode) +{ + if (dc) { + AQH_MESSAGE *msgOut; + uint32_t msgId; + + msgId=++(dc->lastMsgId); + msgOut=AQH_IpcdMessageGetData_new(AQH_MSGTYPE_IPC_DATA_GETDATA_REQ, + msgId, 0, + mode, + valueName, 0, 0, maxNum); + AQH_Endpoint_AddMsgOut(dc->ipcEndpoint, msgOut); + + return _handleDataResponses(dc, dataPtr, maxNum, msgId); + } + return 0; +} + + + +uint64_t _handleDataResponses(AQH_DATACLIENT *dc, uint64_t *dataPtr, uint64_t maxNum, uint32_t msgId) +{ + AQH_MESSAGE *msgIn; + uint64_t fullNumberOfPoints=0; + + while( (msgIn=AQH_IpcEndpoint_WaitForResponseMsg(dc->ipcEndpoint, msgId, dc->timeoutInSeconds)) ) { + GWEN_TAG16_LIST *tagList; + + tagList=AQH_IpcMessageTag16_ParsePayload(msgIn, 0); + if (tagList) { + uint16_t code; + + code=AQH_IpcMessage_GetCode(msgIn); + if (code==AQH_MSGTYPE_IPC_DATA_GETDATA_RSP) { + const uint64_t *recvDataPtr; + uint64_t recvNumberOfPoints; + + AQH_IpcdMessageMultiData_ReadDatapoints(tagList, &recvDataPtr, &recvNumberOfPoints); + if (recvNumberOfPoints) { + uint64_t i; + + for (i=0; iipcEndpoint, msgId, dc->timeoutInSeconds)) ) { + GWEN_TAG16_LIST *tagList; + + tagList=AQH_IpcMessageTag16_ParsePayload(msgIn, 0); + if (tagList) { + uint16_t code; + + code=AQH_IpcMessage_GetCode(msgIn); + if (code==AQH_MSGTYPE_IPC_DATA_RESULT) { + int result; + + result=AQH_IpcMessageResult_GetResult(tagList); + DBG_INFO(NULL, "Server result: %d", result); + GWEN_Tag16_List_free(tagList); + AQH_Message_free(msgIn); + if (result!=AQH_MSGDATA_RESULT_SUCCESS) { + DBG_INFO(NULL, "here (%d)", result); + return GWEN_ERROR_GENERIC; + } + return 0; + } + else { + DBG_INFO(NULL, "Ignoring message \"%d\"", code); + } + GWEN_Tag16_List_free(tagList); + } + AQH_Message_free(msgIn); + } /* while */ + + return GWEN_ERROR_TIMEOUT; +} + + + + +int AQH_DataClient_ConnectWithArgs(AQH_DATACLIENT *dc, uint32_t flags) +{ + const char *brokerAddress; + int brokerPort; + const char *userId; + const char *passwd; + const char *clientId; + int rv; + + brokerAddress=GWEN_DB_GetCharValue(dc->dbLocalArgs, "brokerAddress", 0, NULL); + if (!(brokerAddress && *brokerAddress)) + brokerAddress=GWEN_DB_GetCharValue(dc->dbLocalArgs, "ConfigFile/brokerAddress", 0, "127.0.0.1"); + + brokerPort=GWEN_DB_GetIntValue(dc->dbLocalArgs, "brokerPort", 0, -1); + if (brokerPort<0) + brokerPort=GWEN_DB_GetIntValue(dc->dbLocalArgs, "ConfigFile/brokerPort", 0, 1899); + + userId=GWEN_DB_GetCharValue(dc->dbLocalArgs, "userId", 0, NULL); + passwd=GWEN_DB_GetCharValue(dc->dbLocalArgs, "password", 0, NULL); + clientId=GWEN_DB_GetCharValue(dc->dbLocalArgs, "brokerClientId", 0, NULL); + + rv=AQH_DataClient_Connect(dc, brokerAddress, brokerPort, userId, passwd, clientId, flags); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + return rv; + } + + return 0; +} + diff --git a/aqhome/dataclient/client.h b/aqhome/dataclient/client.h new file mode 100644 index 0000000..05db794 --- /dev/null +++ b/aqhome/dataclient/client.h @@ -0,0 +1,57 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOME_DATA_CLIENT_H +#define AQHOME_DATA_CLIENT_H + +#include +#include +#include +#include + +#include + + +typedef struct AQH_DATACLIENT AQH_DATACLIENT; + + +AQHOME_API AQH_DATACLIENT *AQH_DataClient_new(AQH_EVENT_LOOP *eventLoop, uint8_t protoId, uint8_t protoVer); +AQHOME_API void AQH_DataClient_free(AQH_DATACLIENT *dc); + +AQHOME_API void AQH_DataClient_SetTimeout(AQH_DATACLIENT *dc, int i); + + +AQHOME_API int AQH_DataClient_Connect(AQH_DATACLIENT *dc, + const char *addr, int port, + const char *userId, const char *passwd, + const char *clientId, + uint32_t flags); +AQHOME_API int AQH_DataClient_Disconnect(AQH_DATACLIENT *dc); + + +AQHOME_API AQH_DEVICE_LIST *AQH_DataClient_GetDevices(AQH_DATACLIENT *dc); +AQHOME_API AQH_VALUE_LIST *AQH_DataClient_GetValues(AQH_DATACLIENT *dc, const char *deviceName, int modality); + +AQHOME_API uint64_t AQH_DataClient_GetFirstData(AQH_DATACLIENT *dc, const char *valueName, uint64_t *dataPtr, uint64_t maxNum); +AQHOME_API uint64_t AQH_DataClient_GetLastData(AQH_DATACLIENT *dc, const char *valueName, uint64_t *dataPtr, uint64_t maxNum); +AQHOME_API uint64_t AQH_DataClient_GetPeriodData(AQH_DATACLIENT *dc, const char *valueName, + uint64_t *dataPtr, uint64_t maxNum, + uint64_t tsBegin, uint64_t tsEnd); + +AQHOME_API int AQH_DataClient_SetData(AQH_DATACLIENT *dc, const AQH_VALUE *v, const char *data); +AQHOME_API int AQH_DataClient_UpdateData(AQH_DATACLIENT *dc, const AQH_VALUE *v, uint64_t timeStamp, double dataPoint); + + +AQHOME_API int AQH_DataClient_ReadLocalArgs(AQH_DATACLIENT *dc, + GWEN_DB_NODE *dbGlobalArgs, const GWEN_ARGS *argDescrs, + int argc, char **argv); +AQHOME_API int AQH_DataClient_ConnectWithArgs(AQH_DATACLIENT *dc, uint32_t flags); +AQHOME_API GWEN_DB_NODE *AQH_DataClient_GetDbLocalArgs(const AQH_DATACLIENT *dc); + + +#endif diff --git a/aqhome/dataclient/client_p.h b/aqhome/dataclient/client_p.h new file mode 100644 index 0000000..b62eadd --- /dev/null +++ b/aqhome/dataclient/client_p.h @@ -0,0 +1,32 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQHOME_DATA_CLIENT_P_H +#define AQHOME_DATA_CLIENT_P_H + +#include "aqhome/dataclient/client.h" + + +struct AQH_DATACLIENT { + AQH_EVENT_LOOP *eventLoop; + + AQH_OBJECT *ipcEndpoint; + int timeoutInSeconds; + + uint8_t protoId; + uint8_t protoVer; + + uint32_t lastMsgId; + + GWEN_DB_NODE *dbLocalArgs; + +}; + + + +#endif diff --git a/aqhome/events2/fdobject.c b/aqhome/events2/fdobject.c index 211706a..d66ac04 100644 --- a/aqhome/events2/fdobject.c +++ b/aqhome/events2/fdobject.c @@ -14,6 +14,7 @@ #include #include +#include //#include #include @@ -170,6 +171,7 @@ int AQH_FdObject_Read(AQH_OBJECT *o, uint8_t *ptrBuffer, uint32_t lenBuffer) else if (rv>0) { /* data received */ DBG_DEBUG(AQH_LOGDOMAIN, "Received %d bytes", (int) rv); +// GWEN_Text_LogString((const char*) ptrBuffer, rv, NULL, GWEN_LoggerLevel_Error); return (int) rv; } else { diff --git a/aqhome/ipc2/ipc_endpoint.c b/aqhome/ipc2/ipc_endpoint.c index dcca205..d8dfd9e 100644 --- a/aqhome/ipc2/ipc_endpoint.c +++ b/aqhome/ipc2/ipc_endpoint.c @@ -79,7 +79,7 @@ AQH_MESSAGE *AQH_IpcEndpoint_WaitForResponseMsg(AQH_OBJECT *ipcEndpoint, uint32_ uint16_t code; code=AQH_IpcMessage_GetCode(msg); - DBG_ERROR(NULL, "Received unexpected message %d (%x), ignoring", code, code); + DBG_DEBUG(NULL, "Received unexpected message %d (%x), ignoring", code, code); AQH_Message_free(msg); } } diff --git a/aqhome/ipc2/ipc_msgreader.c b/aqhome/ipc2/ipc_msgreader.c index 3c4b78c..6f46ca6 100644 --- a/aqhome/ipc2/ipc_msgreader.c +++ b/aqhome/ipc2/ipc_msgreader.c @@ -24,7 +24,7 @@ #define AQH_MSG_READER_HEADER_SIZE 4 #define AQH_MSG_READER_MINMSGSIZE 12 -#define AQH_MSG_READER_MAXMSGSIZE 10240 +#define AQH_MSG_READER_MAXMSGSIZE 20480 diff --git a/aqhome/ipc2/tcpd_object.c b/aqhome/ipc2/tcpd_object.c index b0ed405..6153ff0 100644 --- a/aqhome/ipc2/tcpd_object.c +++ b/aqhome/ipc2/tcpd_object.c @@ -176,17 +176,17 @@ int _handleSocketReady(AQH_OBJECT *o) { AQH_TCPD_OBJECT *xo; - DBG_INFO(NULL, "Socket ready"); + DBG_DEBUG(NULL, "Socket ready"); xo=GWEN_INHERIT_GETDATA(AQH_OBJECT, AQH_TCPD_OBJECT, o); if (xo) { int clientSk; clientSk=_acceptConnection(xo->fdSocket); if (clientSk<0) { - DBG_ERROR(AQH_LOGDOMAIN, "here (%d)", clientSk); + DBG_INFO(AQH_LOGDOMAIN, "here (%d)", clientSk); } else { - DBG_INFO(AQH_LOGDOMAIN, "New connection"); + DBG_NOTICE(AQH_LOGDOMAIN, "New connection"); if (0==AQH_Object_EmitSignal(o, AQH_TCPD_OBJECT_SIGNAL_NEWCONN, clientSk, NULL)) { DBG_ERROR(AQH_LOGDOMAIN, "New connection not handled"); close(clientSk); diff --git a/aqhome/msg/ipc/data/0BUILD b/aqhome/msg/ipc/data/0BUILD index 3962eb1..527384b 100644 --- a/aqhome/msg/ipc/data/0BUILD +++ b/aqhome/msg/ipc/data/0BUILD @@ -51,6 +51,7 @@ m_ipcd_values.h m_ipcd_getdata.h m_ipcd_setdata.h + m_ipcd_getvalues.h @@ -67,6 +68,7 @@ m_ipcd_values.c m_ipcd_getdata.c m_ipcd_setdata.c + m_ipcd_getvalues.c diff --git a/aqhome/msg/ipc/data/m_ipcd_getdata.c b/aqhome/msg/ipc/data/m_ipcd_getdata.c index 47b85cb..dcfd0bf 100644 --- a/aqhome/msg/ipc/data/m_ipcd_getdata.c +++ b/aqhome/msg/ipc/data/m_ipcd_getdata.c @@ -28,6 +28,8 @@ * ------------------------------------------------------------------------------------------------ */ +static const char *_modeToChar(int mode); + /* ------------------------------------------------------------------------------------------------ @@ -37,6 +39,7 @@ AQH_MESSAGE *AQH_IpcdMessageGetData_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, + int mode, const char *valueName, uint64_t tsBegin, uint64_t tsEnd, uint64_t num) { AQH_MESSAGE *msg; @@ -49,6 +52,7 @@ AQH_MESSAGE *AQH_IpcdMessageGetData_new(uint16_t code, GWEN_Tag16_WriteUint64TagToBuffer(AQH_MSGDATA_GETDATA_TAGS_BEGIN, tsBegin, buf); GWEN_Tag16_WriteUint64TagToBuffer(AQH_MSGDATA_GETDATA_TAGS_END, tsEnd, buf); GWEN_Tag16_WriteUint64TagToBuffer(AQH_MSGDATA_GETDATA_TAGS_NUM, num, buf); + GWEN_Tag16_WriteUint64TagToBuffer(AQH_MSGDATA_GETDATA_TAGS_MODE, mode, buf); msg=AQH_IpcMessage_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId, GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf)); @@ -64,19 +68,22 @@ void AQH_IpcdMessageGetData_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG1 char *valueName; uint64_t tsBegin; uint64_t tsEnd; + uint64_t mode; valueName=tagList?AQH_Tag16_GetTagDataAsNewString(tagList, AQH_MSGDATA_GETDATA_TAGS_NAME, NULL):NULL; tsBegin=tagList?AQH_Tag16_GetTagDataAsUint64(tagList, AQH_MSGDATA_GETDATA_TAGS_BEGIN, 0):0; tsEnd=tagList?AQH_Tag16_GetTagDataAsUint64(tagList, AQH_MSGDATA_GETDATA_TAGS_END, 0):0; + mode=tagList?AQH_Tag16_GetTagDataAsUint64(tagList, AQH_MSGDATA_GETDATA_TAGS_MODE, 0):0; GWEN_Buffer_AppendArgs(dbuf, - "GETDATA(%s) %s (code=%d, proto=%d, proto version=%d, name=%s, tsBegin=%lu, tsEnd=%lu)\n", + "GETDATA(%s) %s (code=%d, proto=%d, proto version=%d, name=%s, mode=%s, tsBegin=%lu, tsEnd=%lu)\n", AQH_IpcdMessage_MsgTypeToChar(AQH_IpcMessage_GetCode(msg)), sText?sText:"", AQH_IpcMessage_GetCode(msg), AQH_IpcMessage_GetProtoId(msg), AQH_IpcMessage_GetProtoVersion(msg), - valueName?valueName:"", + valueName?valueName:"", + _modeToChar(mode), (unsigned long int) tsBegin, (unsigned long int) tsEnd); free(valueName); @@ -85,3 +92,15 @@ void AQH_IpcdMessageGetData_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG1 +const char *_modeToChar(int mode) +{ + switch(mode) { + case AQH_MSGDATA_GETDATA_MODE_FIRST: return "first"; + case AQH_MSGDATA_GETDATA_MODE_LAST: return "last"; + case AQH_MSGDATA_GETDATA_MODE_PERIOD: return "period"; + default: return "unknown"; + } +} + + + diff --git a/aqhome/msg/ipc/data/m_ipcd_getdata.h b/aqhome/msg/ipc/data/m_ipcd_getdata.h index 46ea85d..3993cb7 100644 --- a/aqhome/msg/ipc/data/m_ipcd_getdata.h +++ b/aqhome/msg/ipc/data/m_ipcd_getdata.h @@ -24,10 +24,20 @@ #define AQH_MSGDATA_GETDATA_TAGS_BEGIN 0x0020 #define AQH_MSGDATA_GETDATA_TAGS_END 0x0021 #define AQH_MSGDATA_GETDATA_TAGS_NUM 0x0022 +#define AQH_MSGDATA_GETDATA_TAGS_MODE 0x0023 + + +enum { + AQH_MSGDATA_GETDATA_MODE_FIRST=0, + AQH_MSGDATA_GETDATA_MODE_LAST, + AQH_MSGDATA_GETDATA_MODE_PERIOD +}; + AQHOME_API AQH_MESSAGE *AQH_IpcdMessageGetData_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, + int mode, const char *valueName, uint64_t tsBegin, uint64_t tsEnd, uint64_t num); AQHOME_API void AQH_IpcdMessageGetData_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList, diff --git a/aqhome/msg/ipc/data/m_ipcd_getvalues.c b/aqhome/msg/ipc/data/m_ipcd_getvalues.c new file mode 100644 index 0000000..d90e0b1 --- /dev/null +++ b/aqhome/msg/ipc/data/m_ipcd_getvalues.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include "aqhome/msg/ipc/data/m_ipcd_getvalues.h" +#include "aqhome/msg/ipc/m_ipc_tag16.h" +#include "aqhome/msg/ipc/data/m_ipcd.h" +#include "aqhome/msg/ipc/m_ipc.h" + +#include +#include +#include +#include + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + + + +/* ------------------------------------------------------------------------------------------------ + * implementation + * ------------------------------------------------------------------------------------------------ + */ + +AQH_MESSAGE *AQH_IpcdMessageGetValues_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, + const char *deviceName, int modality) +{ + AQH_MESSAGE *msg; + GWEN_BUFFER *buf; + + buf=GWEN_Buffer_new(0, 256, 0, 1); + + if (deviceName && *deviceName) + GWEN_Tag16_WriteStringTagToBuffer(AQH_MSGDATA_GETVALUES_TAGS_DEVICENAME, deviceName, buf); + GWEN_Tag16_WriteUint64TagToBuffer(AQH_MSGDATA_GETVALUES_TAGS_MODALITY, modality, buf); + + msg=AQH_IpcMessage_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId, + GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf)); + GWEN_Buffer_free(buf); + return msg; +} + + + +void AQH_IpcdMessageGetValues_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList, + GWEN_BUFFER *dbuf, const char *sText) +{ + char *deviceName; + uint64_t modality; + + deviceName=tagList?AQH_Tag16_GetTagDataAsNewString(tagList, AQH_MSGDATA_GETVALUES_TAGS_DEVICENAME, NULL):NULL; + modality=tagList?AQH_Tag16_GetTagDataAsUint64(tagList, AQH_MSGDATA_GETVALUES_TAGS_MODALITY, 0):0; + + GWEN_Buffer_AppendArgs(dbuf, + "GETVALUES(%s) %s (code=%d, proto=%d, proto version=%d, device=%s, modality=%s)\n", + AQH_IpcdMessage_MsgTypeToChar(AQH_IpcMessage_GetCode(msg)), + sText?sText:"", + AQH_IpcMessage_GetCode(msg), + AQH_IpcMessage_GetProtoId(msg), + AQH_IpcMessage_GetProtoVersion(msg), + deviceName?deviceName:"", + AQH_ValueModality_toString(modality)); + free(deviceName); +} + + + + diff --git a/aqhome/msg/ipc/data/m_ipcd_getvalues.h b/aqhome/msg/ipc/data/m_ipcd_getvalues.h new file mode 100644 index 0000000..9680eae --- /dev/null +++ b/aqhome/msg/ipc/data/m_ipcd_getvalues.h @@ -0,0 +1,36 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQH_M_IPCD_GETVALUES_H +#define AQH_M_IPCD_GETVALUES_H + + + +#include +#include +#include + +#include +#include + + + +#define AQH_MSGDATA_GETVALUES_TAGS_DEVICENAME 0x0001 +#define AQH_MSGDATA_GETVALUES_TAGS_MODALITY 0x0002 + + + +AQHOME_API AQH_MESSAGE *AQH_IpcdMessageGetValues_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, + const char *deviceName, int modality); + +AQHOME_API void AQH_IpcdMessageGetValues_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList, + GWEN_BUFFER *dbuf, const char *sText); + + + +#endif diff --git a/aqhome/msg/node/0BUILD b/aqhome/msg/node/0BUILD index 595ef36..43d0bc1 100644 --- a/aqhome/msg/node/0BUILD +++ b/aqhome/msg/node/0BUILD @@ -62,6 +62,7 @@ m_flashend.h m_flashready.h m_flashresponse.h + m_range.h @@ -89,6 +90,7 @@ m_flashend.c m_flashready.c m_flashresponse.c + m_range.c diff --git a/aqhome/msg/node/m_memstats.c b/aqhome/msg/node/m_memstats.c index bbbf073..719c7c9 100644 --- a/aqhome/msg/node/m_memstats.c +++ b/aqhome/msg/node/m_memstats.c @@ -19,8 +19,8 @@ -#define AQH_MSG_OFFS_MEMSTATS_SECONDS 0 /* 4 bytes */ -#define AQH_MSG_OFFS_MEMSTATS_UID 4 /* 4 bytes */ +#define AQH_MSG_OFFS_MEMSTATS_UID 0 /* 4 bytes */ +#define AQH_MSG_OFFS_MEMSTATS_SECONDS 4 /* 4 bytes */ #define AQH_MSG_OFFS_MEMSTATS_STACKUSAGE 8 /* 2 bytes */ #define AQH_MSG_OFFS_MEMSTATS_BUFFERSUSED 10 /* 1 byte */ #define AQH_MSG_OFFS_MEMSTATS_MAXBUFFERSUSED 11 /* 1 byte */ diff --git a/aqhome/msg/node/m_node.c b/aqhome/msg/node/m_node.c index 3959207..f345b4a 100644 --- a/aqhome/msg/node/m_node.c +++ b/aqhome/msg/node/m_node.c @@ -28,6 +28,7 @@ #include "aqhome/msg/node/m_flashend.h" #include "aqhome/msg/node/m_flashready.h" #include "aqhome/msg/node/m_flashresponse.h" +#include "aqhome/msg/node/m_range.h" #include @@ -212,6 +213,7 @@ const char *AQH_NodeMessage_MsgTypeToChar(uint8_t i) case AQH_MSG_TYPE_CLAIM_ADDRESS: return "ClaimAddress"; case AQH_MSG_TYPE_DENY_ADDRESS: return "DenyAddress"; case AQH_MSG_TYPE_ADDRESS_RANGE: return "Range"; + case AQH_MSG_TYPE_REENUM: return "Reenum"; case AQH_MSG_TYPE_FLASH_START: return "FlashStart"; case AQH_MSG_TYPE_FLASH_END: return "FlashEnd"; @@ -246,6 +248,8 @@ void AQH_NodeMessage_DumpSpecificToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *d case AQH_MSG_TYPE_HAVE_ADDRESS: AQH_AddrMessage_DumpToBuffer(msg, dbuf, sText); break; case AQH_MSG_TYPE_CLAIM_ADDRESS: AQH_AddrMessage_DumpToBuffer(msg, dbuf, sText); break; case AQH_MSG_TYPE_DENY_ADDRESS: AQH_AddrMessage_DumpToBuffer(msg, dbuf, sText); break; + case AQH_MSG_TYPE_ADDRESS_RANGE: AQH_RangeMessage_DumpToBuffer(msg, dbuf, sText); break; + case AQH_MSG_TYPE_REENUM: AQH_RangeMessage_DumpToBuffer(msg, dbuf, sText); break; case AQH_MSG_TYPE_FLASH_START: AQH_FlashStartMessage_DumpToBuffer(msg, dbuf, sText); break; case AQH_MSG_TYPE_FLASH_END: AQH_FlashEndMessage_DumpToBuffer(msg, dbuf, sText); break; @@ -266,7 +270,6 @@ void AQH_NodeMessage_DumpSpecificToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *d case AQH_MSG_TYPE_DEBUG: case AQH_MSG_TYPE_TWIBUSMEMBER: - case AQH_MSG_TYPE_ADDRESS_RANGE: default: AQH_NodeMessage_DumpToBuffer(msg, dbuf, sText); break; } } diff --git a/aqhome/msg/node/m_node.h b/aqhome/msg/node/m_node.h index ba9acb2..954d7c7 100644 --- a/aqhome/msg/node/m_node.h +++ b/aqhome/msg/node/m_node.h @@ -29,8 +29,8 @@ #define AQH_MSG_TYPE_PING 10 #define AQH_MSG_TYPE_PONG 11 -#define AQH_MSG_TYPE_COMSENDSTATS 20 -#define AQH_MSG_TYPE_COMRECVSTATS 21 +#define AQH_MSG_TYPE_COMSENDSTATS 22 +#define AQH_MSG_TYPE_COMRECVSTATS 23 #define AQH_MSG_TYPE_TWIBUSMEMBER 30 #define AQH_MSG_TYPE_DEBUG 40 #define AQH_MSG_TYPE_VALUE 50 /* deprecated */ @@ -40,6 +40,7 @@ #define AQH_MSG_TYPE_CLAIM_ADDRESS 62 #define AQH_MSG_TYPE_DENY_ADDRESS 63 #define AQH_MSG_TYPE_ADDRESS_RANGE 64 +#define AQH_MSG_TYPE_REENUM 65 #define AQH_MSG_TYPE_FLASH_START 70 #define AQH_MSG_TYPE_FLASH_END 71 diff --git a/aqhome/msg/node/m_range.c b/aqhome/msg/node/m_range.c new file mode 100644 index 0000000..fa898c6 --- /dev/null +++ b/aqhome/msg/node/m_range.c @@ -0,0 +1,61 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + + + +#include "aqhome/msg/node/m_range.h" +#include "aqhome/msg/node/m_node.h" + +#include + + +#define AQH_MSG_OFFS_RANGE_UID 0 /* 4 bytes */ +#define AQH_MSG_OFFS_RANGE_BEGIN 4 /* 1 bytes */ +#define AQH_MSG_OFFS_RANGE_END 5 /* 1 bytes */ + + + +uint32_t AQH_RangeMessage_GetUid(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RANGE_UID, 0); +} + + + +uint8_t AQH_RangeMessage_GetRangeBegin(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RANGE_BEGIN, 0); +} + + + +uint8_t AQH_RangeMessage_GetRangeEnd(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RANGE_END, 0); +} + + + +void AQH_RangeMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText) +{ + GWEN_Buffer_AppendArgs(dbuf, + "0x%02x->0x%02x: RANGE(%s) %s (uid=0x%08x, begin=0x%x, end=0x%x)\n", + AQH_NodeMessage_GetSourceAddress(msg), + AQH_NodeMessage_GetDestAddress(msg), + AQH_NodeMessage_MsgTypeToChar(AQH_NodeMessage_GetMsgType(msg)), + sText, + (unsigned int) AQH_RangeMessage_GetUid(msg), + AQH_RangeMessage_GetRangeBegin(msg), + AQH_RangeMessage_GetRangeEnd(msg)); +} + + diff --git a/aqhome/msg/node/m_range.h b/aqhome/msg/node/m_range.h new file mode 100644 index 0000000..a77120e --- /dev/null +++ b/aqhome/msg/node/m_range.h @@ -0,0 +1,30 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQH_M_RANGE_H +#define AQH_M_RANGE_H + + +#include +#include + +#include + + +/* This message is used for message types ClaimAddr, DenyAddr, HaveAddr */ + +AQHOME_API uint32_t AQH_RangeMessage_GetUid(const AQH_MESSAGE *msg); +AQHOME_API uint8_t AQH_RangeMessage_GetAddr(const AQH_MESSAGE *msg); +AQHOME_API uint8_t AQH_RangeMessage_GetRangeBegin(const AQH_MESSAGE *msg); +AQHOME_API uint8_t AQH_RangeMessage_GetRangeEnd(const AQH_MESSAGE *msg); + +AQHOME_API void AQH_RangeMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText); + + + +#endif diff --git a/aqhome/msg/node/m_recvstats.c b/aqhome/msg/node/m_recvstats.c index bd0a02e..d1c00f8 100644 --- a/aqhome/msg/node/m_recvstats.c +++ b/aqhome/msg/node/m_recvstats.c @@ -18,13 +18,21 @@ #include -#define AQH_MSG_OFFS_RECVSTATS_UID 0 /* 4 bytes */ -#define AQH_MSG_OFFS_RECVSTATS_PACKETSIN 4 /* 2 bytes */ -#define AQH_MSG_OFFS_RECVSTATS_CRCERRORS 6 /* 2 bytes */ -#define AQH_MSG_OFFS_RECVSTATS_IOERRORS 8 /* 2 bytes */ -#define AQH_MSG_OFFS_RECVSTATS_NOBUFFER 10 /* 2 bytes */ -#define AQH_MSG_OFFS_RECVSTATS_HANDLED 12 /* 2 bytes */ -#define AQH_MSG_OFFS_RECVSTATS_MISSED 14 /* 2 bytes */ +#define AQH_MSG_OFFS_RECVSTATS_UID 0 /* 4 bytes */ +#define AQH_MSG_OFFS_RECVSTATS_IFACE 4 /* 1 byte */ +#define AQH_MSG_OFFS_RECVSTATS_PACKETSIN 5 /* 2 bytes */ +#define AQH_MSG_OFFS_RECVSTATS_CRCERRORS 7 /* 2 bytes */ +#define AQH_MSG_OFFS_RECVSTATS_IOERRORS 9 /* 2 bytes */ +#define AQH_MSG_OFFS_RECVSTATS_NOBUFFER 11 /* 2 bytes */ +#define AQH_MSG_OFFS_RECVSTATS_MSGSIZEERRORS 13 /* 2 bytes */ +#define AQH_MSG_OFFS_RECVSTATS_MISSED 15 /* 2 bytes */ + + + +uint8_t AQH_RecvStatsMessage_GetInterface(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_IFACE, 0); +} @@ -63,9 +71,9 @@ uint16_t AQH_RecvStatsMessage_GetNoBufferErrors(const AQH_MESSAGE *msg) -uint16_t AQH_RecvStatsMessage_GetHandled(const AQH_MESSAGE *msg) +uint16_t AQH_RecvStatsMessage_GetMsgSizeErrors(const AQH_MESSAGE *msg) { - return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_HANDLED, 0); + return AQH_Message_ReadUint16At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_RECVSTATS_MSGSIZEERRORS, 0); } @@ -80,17 +88,18 @@ uint16_t AQH_RecvStatsMessage_GetMissed(const AQH_MESSAGE *msg) void AQH_RecvStatsMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText) { GWEN_Buffer_AppendArgs(dbuf, - "0x%02x->0x%02x: RECVSTATS %s " - "(uid=0x%08x, in=%d, crc errs=%d, io errs=%d, nobuf errs=%d, handled=%d, missed=%d)\n", + "0x%02x->0x%02x: RECVSTATS %s" + "(uid=0x%08x, dev=%d, in=%d, eCrc=%d, eIo=%d, eNobuf=%d, eMsgSize=%d, eMissed=%d)\n", AQH_NodeMessage_GetSourceAddress(msg), AQH_NodeMessage_GetDestAddress(msg), sText, (unsigned int) AQH_RecvStatsMessage_GetUid(msg), + AQH_RecvStatsMessage_GetInterface(msg), AQH_RecvStatsMessage_GetPacketsIn(msg), AQH_RecvStatsMessage_GetCrcErrors(msg), AQH_RecvStatsMessage_GetIoErrors(msg), AQH_RecvStatsMessage_GetNoBufferErrors(msg), - AQH_RecvStatsMessage_GetHandled(msg), + AQH_RecvStatsMessage_GetMsgSizeErrors(msg), AQH_RecvStatsMessage_GetMissed(msg)); } diff --git a/aqhome/msg/node/m_recvstats.h b/aqhome/msg/node/m_recvstats.h index d83d04a..c6dcbbe 100644 --- a/aqhome/msg/node/m_recvstats.h +++ b/aqhome/msg/node/m_recvstats.h @@ -17,12 +17,13 @@ +AQHOME_API uint8_t AQH_RecvStatsMessage_GetInterface(const AQH_MESSAGE *msg); AQHOME_API uint32_t AQH_RecvStatsMessage_GetUid(const AQH_MESSAGE *msg); AQHOME_API uint16_t AQH_RecvStatsMessage_GetPacketsIn(const AQH_MESSAGE *msg); AQHOME_API uint16_t AQH_RecvStatsMessage_GetCrcErrors(const AQH_MESSAGE *msg); AQHOME_API uint16_t AQH_RecvStatsMessage_GetIoErrors(const AQH_MESSAGE *msg); AQHOME_API uint16_t AQH_RecvStatsMessage_GetNoBufferErrors(const AQH_MESSAGE *msg); -AQHOME_API uint16_t AQH_RecvStatsMessage_GetHandled(const AQH_MESSAGE *msg); +AQHOME_API uint16_t AQH_RecvStatsMessage_GetMsgSizeErrors(const AQH_MESSAGE *msg); AQHOME_API uint16_t AQH_RecvStatsMessage_GetMissed(const AQH_MESSAGE *msg); AQHOME_API void AQH_RecvStatsMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf, const char *sText); diff --git a/aqhome/msg/node/m_sendstats.c b/aqhome/msg/node/m_sendstats.c index adb436f..6f81dec 100644 --- a/aqhome/msg/node/m_sendstats.c +++ b/aqhome/msg/node/m_sendstats.c @@ -1,6 +1,6 @@ /**************************************************************************** * This file is part of the project AqHome. - * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * AqHome (c) by 2025 Martin Preuss, all rights reserved. * * The license for this file can be found in the file COPYING which you * should have received along with this file. @@ -19,9 +19,17 @@ #define AQH_MSG_OFFS_SENDSTATS_UID 0 /* 4 bytes */ -#define AQH_MSG_OFFS_SENDSTATS_PACKETSOUT 4 /* 2 bytes */ -#define AQH_MSG_OFFS_SENDSTATS_COLLISIONS 6 /* 2 bytes */ -#define AQH_MSG_OFFS_SENDSTATS_BUSY 8 /* 2 bytes */ +#define AQH_MSG_OFFS_SENDSTATS_IFACE 4 /* 1 byte */ +#define AQH_MSG_OFFS_SENDSTATS_PACKETSOUT 5 /* 2 bytes */ +#define AQH_MSG_OFFS_SENDSTATS_COLLISIONS 7 /* 2 bytes */ +#define AQH_MSG_OFFS_SENDSTATS_BUSY 9 /* 2 bytes */ + + + +uint8_t AQH_SendStatsMessage_GetInterface(const AQH_MESSAGE *msg) +{ + return AQH_Message_ReadUint8At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_SENDSTATS_IFACE, 0); +} @@ -57,11 +65,12 @@ void AQH_SendStatsMessage_DumpToBuffer(const AQH_MESSAGE *msg, GWEN_BUFFER *dbuf { if (msg) GWEN_Buffer_AppendArgs(dbuf, - "0x%02x->0x%02x: SENDSTATS %s (uid=0x%08x, out=%d, collisions=%d, busy line=%d)\n", + "0x%02x->0x%02x: SENDSTATS %s (uid=0x%08x, dev=%d, out=%d, collisions=%d, busy line=%d)\n", AQH_NodeMessage_GetSourceAddress(msg), AQH_NodeMessage_GetDestAddress(msg), sText, (unsigned int) AQH_SendStatsMessage_GetUid(msg), + AQH_SendStatsMessage_GetInterface(msg), AQH_SendStatsMessage_GetPacketsOut(msg), AQH_SendStatsMessage_GetCollisions(msg), AQH_SendStatsMessage_GetBusyErrors(msg)); diff --git a/aqhome/msg/node/m_sendstats.h b/aqhome/msg/node/m_sendstats.h index a90e00d..70ef73d 100644 --- a/aqhome/msg/node/m_sendstats.h +++ b/aqhome/msg/node/m_sendstats.h @@ -17,6 +17,7 @@ +AQHOME_API uint8_t AQH_SendStatsMessage_GetInterface(const AQH_MESSAGE *msg); AQHOME_API uint32_t AQH_SendStatsMessage_GetUid(const AQH_MESSAGE *msg); AQHOME_API uint16_t AQH_SendStatsMessage_GetPacketsOut(const AQH_MESSAGE *msg); AQHOME_API uint16_t AQH_SendStatsMessage_GetCollisions(const AQH_MESSAGE *msg); diff --git a/aqhome/msg/node/m_value.c b/aqhome/msg/node/m_value.c index 01a0f58..a8cf759 100644 --- a/aqhome/msg/node/m_value.c +++ b/aqhome/msg/node/m_value.c @@ -12,6 +12,7 @@ +#include "aqhome/aqhome.h" #include "aqhome/msg/node/m_value.h" #include "aqhome/msg/node/m_node.h" @@ -102,19 +103,7 @@ uint16_t AQH_ValueMessage_GetValueDenom(const AQH_MESSAGE *msg) const char *AQH_ValueMessage_GetValueTypeName(const AQH_MESSAGE *msg) { - uint8_t t; - - t=AQH_ValueMessage_GetValueType(msg); - switch(t) { - case AQH_MSG_VALUE_TYPE_TEMP: return "temperature"; - case AQH_MSG_VALUE_TYPE_HUMIDITY: return "humidity"; - case AQH_MSG_VALUE_TYPE_DOOR: return "door_window"; - case AQH_MSG_VALUE_TYPE_MOTION: return "motion"; - case AQH_MSG_VALUE_TYPE_CO2: return "CO2"; - case AQH_MSG_VALUE_TYPE_TVOC: return "TVOC"; - default: break; - } - return "unknown"; + return AQH_ValueModality_toString(AQH_ValueMessage_GetValueType(msg)); } diff --git a/avr/apps/0BUILD b/avr/apps/0BUILD index 0e4cf4b..3db3ca4 100644 --- a/avr/apps/0BUILD +++ b/avr/apps/0BUILD @@ -9,6 +9,9 @@ network reportsensors stats + router + hub + forwarder diff --git a/avr/devices/n22/0BUILD b/avr/apps/forwarder/0BUILD similarity index 68% rename from avr/devices/n22/0BUILD rename to avr/apps/forwarder/0BUILD index be449f6..593fe80 100644 --- a/avr/devices/n22/0BUILD +++ b/avr/apps/forwarder/0BUILD @@ -3,15 +3,13 @@ - boot - main - defs.asm - README + main.asm + diff --git a/avr/apps/forwarder/main.asm b/avr/apps/forwarder/main.asm new file mode 100644 index 0000000..c7a5696 --- /dev/null +++ b/avr/apps/forwarder/main.asm @@ -0,0 +1,359 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +; *************************************************************************** +; defines + +; --------------------------------------------------------------------------- +; network interfaces + +.equ NETDEV0_IFACENUM = 1 +.equ NETDEV1_IFACENUM = 2 + + + +; *************************************************************************** +; data + +.dseg + +; nothing so far + + + +; *************************************************************************** +; code + +.cseg + +; --------------------------------------------------------------------------- +; @routine AppForwarder_Init @global + +AppForwarder_Init: + ; set interface number for NETDEV0 + ldi r16, NETDEV0_IFACENUM + sts netInterfaceData+NET_IFACE_OFFS_IFACENUM, r16 + ; set interface number for NETDEV1 + ldi r16, NETDEV1_IFACENUM + sts netInterfaceData2+NET_IFACE_OFFS_IFACENUM, r16 + sec + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine AppForwarder_EveryDay @global +; +; @clobbers R16, R17, X + +AppForwarder_EveryDay: + ldi yl, LOW(netInterfaceData) + ldi yh, HIGH(netInterfaceData) + bigcall NET_Interface_ResetStats ; (R16, R17, X) + + ldi yl, LOW(netInterfaceData2) + ldi yh, HIGH(netInterfaceData2) + bigcall NET_Interface_ResetStats ; (R16, R17, X) + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine AppForwarder_Run @global +; +; Read messages from either interface and forward to the other one. + +AppForwarder_Run: + rjmp appForwarderCheckRecvdMsg +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderCheckRecvdMsg +; +; Read messages from either interface and forward to the other one. +; @return CFLAG set if something done, cleared otherwise +; @clobbers any + +appForwarderCheckRecvdMsg: + rcall NET_PeekNextIncomingMsgNum ; check read queue (bufNum->r16) + brcc appForwarderCheckRecvdMsg_ret ; no msg, jmp + rcall NET_Buffer_Locate ; (R17) + push r16 + ld r16, X ; read buffer header + andi r16, 0x0f ; keep interface number (in low nibble) + rcall appForwarderGetDeviceByIfaceNum ; Y=src interface (R17) + pop r16 + brcc appForwarderCheckRecvdMsg_ret ; interface not found + adiw xh:xl, 1 ; point to message begin + + push r16 + rcall appForwarderHandleMsgAnyDev ; check for message we should handle (ping etc) + pop r16 + + ; let system handle incoming messages + push r16 + rcall appForwarderLetSysHandleMsg + pop r16 + + ; forward to other interface + ldd r17, Y+NET_IFACE_OFFS_IFACENUM + rcall appForwarderSendToOtherDev + brcc appForwarderCheckRecvdMsg_ret ; could not add, jmp + rcall NET_GetNextIncomingMsgNum ; take off the queue + sec +appForwarderCheckRecvdMsg_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderHandleMsgAnyDev @global +; +; @param Y pointer to source interface for the message +; @param X pointer to received message +; @return CFLAG set if msg handled, cleared otherwise +; @clobbers any, !X + +appForwarderHandleMsgAnyDev: + push xl + push xh + rcall appForwarderHandleMsgAnyDev_savedX + pop xh + pop xl + rjmp appForwarderHandleMsgAnyDev_end +appForwarderHandleMsgAnyDev_savedX: + adiw xh:xl, NETMSG_OFFS_CMD ; maybe move ping/reboot handling to all/main.asm? + ld r16, X + sbiw xh:xl, NETMSG_OFFS_CMD + cpi r16, NETMSG_CMD_REBOOT_REQUEST + breq appForwarderHandleMsgAnyDev_handleRebootMsg + cpi r16, NETMSG_CMD_PING + breq appForwarderHandleMsgAnyDev_handlePingMsg + cpi r16, NETMSG_CMD_CLAIM_ADDRESS + breq appForwarderHandleMsgAnyDev_handleClaimAddr + rjmp appForwarderHandleMsgAnyDev_clcRet +appForwarderHandleMsgAnyDev_handleRebootMsg: + rcall appForwarderHandleRebootRequest + ret +appForwarderHandleMsgAnyDev_handlePingMsg: + rcall appForwarderHandlePingRequest + clc + ret +appForwarderHandleMsgAnyDev_handleClaimAddr: + rcall appForwarderHandleClaimAddrRequest + clc + ret +appForwarderHandleMsgAnyDev_clcRet: + clc +appForwarderHandleMsgAnyDev_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderHandleClaimAddrRequest +; +; @param X pointer to received message +; @param Y pointer to source interface for the message +; @clobbers + +appForwarderHandleClaimAddrRequest: + rcall NETMSG_Address_Read ; R18=cmd, R19=addr(R18, R19) + lds r16, netInterfaceData+NET_IFACE_OFFS_ADDRESS + cp r19, r16 + brne appForwarderHandleClaimAddrRequest_ret + ldi r18, NETMSG_CMD_DENY_ADDRESS ; deny addr + rcall appForwarderSendAddrMsg ; (R16, R17, R18, R19, R20, R21, X, Y) +appForwarderHandleClaimAddrRequest_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderSendAddrMsg +; +; @param R18 command +; @param R19 address to send +; @param Y pointer to interface to send to +; @clobbers R16 (R17, R18, R19, R20, R21, X, Y) + +appForwarderSendAddrMsg: + bigcall NET_Buffer_Alloc ; (R16, R17, X) + brcc appForwarderSendAddrMsg_end + push r16 + adiw xh:xl, 1 + bigcall NETMSG_Address_Write ; (R16, R17, R18, R19, R20, R21) + sbiw xh:xl, 1 + pop r16 + bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) +appForwarderSendAddrMsg_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderHandleRebootRequest +; +; Doesn't return if reboot msg is valid. +; +; @param X pointer to received message + +appForwarderHandleRebootRequest: + rcall NETMSG_RebootRequestRead + brcc appForwarderHandleRebootRequest_end + ; reboot + cli + bigjmp BOOTLOADER_ADDR +appForwarderHandleRebootRequest_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderHandlePingRequest +; +; @param X pointer to received message +; @param Y pointer to source interface for the message + +appForwarderHandlePingRequest: + ld r17, X + lds r16, (netInterfaceData+NET_IFACE_OFFS_ADDRESS) + cp r16, r17 + breq appForwarderHandlePingRequest_forMe + cpi r17, 0xff + breq appForwarderHandlePingRequest_forMe + clc + rjmp appForwarderHandlePingRequest_end +appForwarderHandlePingRequest_forMe: + adiw xh:xl, NETMSG_OFFS_SRCADDR + ld r17, X + sbiw xh:xl, NETMSG_OFFS_SRCADDR + push r17 + bigcall NET_Buffer_Alloc ; (R16, R17, X) + pop r17 + brcc appForwarderHandlePingRequest_end ; jmp on error + push r16 ; buffer num + mov r16, r17 ; DEST addr + adiw xh:xl, 1 + bigcall NETMSG_Pong_Write ; (R16, R17, R18, R19, R20, X) + sbiw xh:xl, 1 + pop r16 ; buffer num + bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) +appForwarderHandlePingRequest_end: + ret + + + + + +; --------------------------------------------------------------------------- +; @routine appForwarderLetSysHandleMsg +; +; @param X pointer to msg to handle (point behind the buffer header!) +; @param Y pointer to source interface for the message +; @clobbers any, !X + +appForwarderLetSysHandleMsg: + ld r16, X + cpi r16, 0xff + breq appForwarderLetSysHandleMsg_forMe + lds r17, netInterfaceData+NET_IFACE_OFFS_ADDRESS + cp r16, r17 + brne appForwarderLetSysHandleMsg_end +appForwarderLetSysHandleMsg_forMe: + push xl + push xh + rcall onMessageReceived + pop xh + pop xl + push xl + push xh + rcall mainModulesOnPacketReceived + pop xh + pop xl + push xl + push xh + rcall mainAppsOnPacketReceived + pop xh + pop xl +appForwarderLetSysHandleMsg_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderSendToOtherDev +; @param r16 buffer num +; @param r17 src interface num + +appForwarderSendToOtherDev: + ldi yl, LOW(netInterfaceData) + ldi yh, HIGH(netInterfaceData) + ldd r18, Y+NET_IFACE_OFFS_IFACENUM + andi r18, 0x0f + cp r18, r17 + breq appForwarderSendToAllDevsBut_check2 + bigcall NET_Interface_AddOutgoingMsgNum ; (R17, R18, X) + rjmp appForwarderSendToOtherDev_ret +appForwarderSendToAllDevsBut_check2: + ldi yl, LOW(netInterfaceData2) + ldi yh, HIGH(netInterfaceData2) + ldd r18, Y+NET_IFACE_OFFS_IFACENUM + andi r18, 0x0f + cp r18, r17 + breq appForwarderSendToOtherDev_ret + bigcall NET_Interface_AddOutgoingMsgNum ; (R17, R18, X) +appForwarderSendToOtherDev_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appForwarderGetDeviceByIfaceNum +; +; @param r16 interface number +; @return CFLAG set if interface found (cleared otherwise) +; @return Y pointer to interface with given number +; @clobbers r17 + +appForwarderGetDeviceByIfaceNum: + ldi yl, LOW(netInterfaceData) + ldi yh, HIGH(netInterfaceData) + ldd r17, Y+NET_IFACE_OFFS_IFACENUM + cp r16, r17 + breq appForwarderGetDeviceByIfaceNum_secRet + ldi yl, LOW(netInterfaceData2) + ldi yh, HIGH(netInterfaceData2) + ldd r17, Y+NET_IFACE_OFFS_IFACENUM + cp r16, r17 + breq appForwarderGetDeviceByIfaceNum_secRet + clc + rjmp appForwarderGetDeviceByIfaceNum_ret +appForwarderGetDeviceByIfaceNum_secRet: + sec +appForwarderGetDeviceByIfaceNum_ret: + ret +; @end + + + + diff --git a/avr/apps/hub/0BUILD b/avr/apps/hub/0BUILD new file mode 100644 index 0000000..593fe80 --- /dev/null +++ b/avr/apps/hub/0BUILD @@ -0,0 +1,15 @@ + + + + + + + + + main.asm + + + + + + diff --git a/avr/apps/hub/main.asm b/avr/apps/hub/main.asm new file mode 100644 index 0000000..fd8aac3 --- /dev/null +++ b/avr/apps/hub/main.asm @@ -0,0 +1,715 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +; *************************************************************************** +; defines + +; --------------------------------------------------------------------------- +; network interfaces + + + + +; *************************************************************************** +; data + +.dseg + +appHubDataBegin: + appHubRangeBegin: .byte 1 + appHubRangeEnd: .byte 1 +appHubDataEnd: + + + + +; *************************************************************************** +; code + +.cseg + +; --------------------------------------------------------------------------- +; @routine AppHub_Init @global + +AppHub_Init: + ldi xh, HIGH(appHubDataBegin) + ldi xl, LOW(appHubDataBegin) + clr r16 + ldi r17, (appHubDataEnd-appHubDataBegin) + rcall Utils_FillSram + + ; set device address and interface number in all interfaces + ldi r16, 0xf0 ; hub address + ldi r17, 1 ; first interface number + rcall appHubAllSetAddrIfaceNumAndRange ; (R17, R19, R20, Y) + + ; TODO: read ranges from EEPROM + ; TODO: send range msg to all interfaces + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine AppHub_Run @global +; +; Read messages from any interface, handle them and probably forward to the other +; interfaces. +; @return CFLAG set if something done, cleared otherwise +; @clobbers all + +AppHub_Run: + rjmp appHubCheckRecvdMsg +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubGetDeviceByIfaceNum +; +; @param r16 interface number +; @clobbers r17, r19, r20, Y + +appHubGetDeviceByIfaceNum: + ldi r19, COM_PORTS + ldi yl, LOW(com2w0_iface) ; first interface + ldi yh, HIGH(com2w0_iface) +appHubGetDeviceByIfaceNum_loop: + ldd r17, Y+NET_IFACE_OFFS_IFACENUM + cp r16, r17 + sec ; mark "found" + breq appHubGetDeviceByIfaceNum_ret + ldi r20, COM2W_IFACE_SIZE + add yl, r20 + adc yh, r20 + sub yh, r20 + dec r19 + brne appHubGetDeviceByIfaceNum_loop + clc ; mark "not found" +appHubGetDeviceByIfaceNum_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubAllSetAddrIfaceNumAndRange +; +; @clobbers R17, R18, R19, R20, Y + +appHubAllSetAddrIfaceNumAndRange: + ldi r19, COM_PORTS + ldi yl, LOW(com2w0_iface) ; first interface + ldi yh, HIGH(com2w0_iface) + ldi r18, 0x10 +appHubAllSetAddrIfaceNumAndRange_loop: + ; set address + std Y+NET_IFACE_OFFS_ADDRESS, r16 + ; set interface number + std Y+NET_IFACE_OFFS_IFACENUM, r17 + inc r17 + ; set default range (step of 16) + std Y+NET_IFACE_OFFS_RANGE_BEGIN, r18 + subi r18, -15 + std Y+NET_IFACE_OFFS_RANGE_END, r18 + inc r18 + ; next interface + ldi r20, COM2W_IFACE_SIZE + add yl, r20 + adc yh, r20 + sub yh, r20 + dec r19 + brne appHubAllSetAddrIfaceNumAndRange_loop + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubSendRangeMsg +; +; @param R18 msg code +; @param Y pointer to interface data +; @return CFLAG set if message enqueued, cleared on error +; @clobbers (R16, R17, R18, R19, R20, R21, R24, R25, X) + +appHubSendRangeMsg: + bigcall NET_Buffer_Alloc ; (R16, R17, X) + brcc appHubSendRangeMsg_end + push r16 + ldd r20, Y+NET_IFACE_OFFS_RANGE_BEGIN + ldd r21, Y+NET_IFACE_OFFS_RANGE_END + adiw xh:xl, 1 + bigcall NETMSG_Range_Write ; (R16, R17, R18, R19, R20, R21) + sbiw xh:xl, 1 + pop r16 + rcall appHubSendMsg ; (R16, R17, R18, R24, R25, X) +appHubSendRangeMsg_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubSendDenyAddrR19 +; +; @param R19 address to send +; @clobbers R16, R17, R18, R19, R20, R21, X, Y + +appHubSendDenyAddrR19: + ldi r18, NETMSG_CMD_DENY_ADDRESS ; deny addr + rjmp appHubSendAddrMsg ; (R16, R17, R18, R19, R20, R21, X, Y) +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubSendAddrMsg +; +; @param R18 command +; @param R19 address to send +; @clobbers R16 (R17, R18, R19, R20, R21, X, Y) + +appHubSendAddrMsg: + bigcall NET_Buffer_Alloc ; (R16, R17, X) + brcc appHubSendAddrMsg_end + push r16 + adiw xh:xl, 1 + bigcall NETMSG_Address_Write ; (R16, R17, R18, R19, R20, R21) + sbiw xh:xl, 1 + pop r16 + rcall appHubSendMsg ; (R16, R17, R18, R24, R25, X) +appHubSendAddrMsg_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubSendValueResponse +; +; @param R17 value id +; @param R19:R18 value +; @param R21:R20 denom (e.g. 100, meaning value must be divided by 100) +; @param R23 command +; @param R25:R24 ref msg id +; @return CFLAG on success, cleared on error +; @clobbers r22 (r16, r17, r18, r19, r20, r21, r23, r24, r25, X) + +appHubSendValueResponse: + push r17 + rcall NET_Buffer_Alloc ; (R16, R17, X) + pop r17 + brcc appHubSendValueResponse_end ; jmp on error + push r16 ; buffer num + ldi r16, 0xff ; DEST addr + clr r22 ; value type + adiw xh:xl, 1 + rcall NETMSG_ValueWriteResponse ; (R16, R17, R18, R19, R20, R21, R23, R24, R25) + sbiw xh:xl, 1 + pop r16 ; buffer num + rcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) +appHubSendValueResponse_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubSendMsg +; +; @param R16 num of allocated buffer +; @param Y pointer to interface data +; @param X msg to send (points to start of allocated buffer, e.g. buffer header) +; @return CFLAG set if message enqueued, cleared on error +; @clobbers R16 (R17, R18, R24, R25, X) + +appHubSendMsg: + bigcall NET_Interface_AddOutgoingMsgNum ; (R17, R18, X) + brcs appHubSendMsg_end + bigcall NET_Buffer_ReleaseByNum ; (R16, X) + ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW + rcall NET_Interface_IncCounter16 ; (R24, R25) + clc +appHubSendMsg_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubAllResetStats +; +; @clobbers r19, r20, Y (r16, r17, X) + +appHubAllResetStats: + ldi r19, COM_PORTS + ldi yl, LOW(com2w0_iface) ; first interface + ldi yh, HIGH(com2w0_iface) +appHubAllResetStats_loop: + bigcall NET_Interface_ResetStats ; (R16, R17, X) + + ldi r20, COM2W_IFACE_SIZE + add yl, r20 + adc yh, r20 + sub yh, r20 + dec r19 + brne appHubAllResetStats_loop + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine AppHub_EveryDay @global +; +; @clobbers R16, R17, X + +AppHub_EveryDay: + rcall appHubAllResetStats + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubSendMsgToAllOthers +; +; @param R16 buffer number +; @param X buffer pointer +; @clobbers r17, r19, r20, r24, r25 (r16, r18, X) + +appHubSendMsgToAllOthers: + ld r24, X + andi r24, 0x0f ; get sender interface num + ldi r19, COM_PORTS ; number of ports + ldi yl, LOW(com2w0_iface) ; first interface + ldi yh, HIGH(com2w0_iface) +appHubSendMsgToAllOthers_loop: + ldd r25, Y+NET_IFACE_OFFS_IFACENUM + cp r24, r25 ; same interface? + breq appHubSendMsgToAllOthers_next + ; current iface is not source, send and inc ref counter + bigcall NET_Interface_AddOutgoingMsgNum ; (R17, R18, X) + brcs appHubSendMsgToAllOthers_added + ; inc error counter + push r24 + mov r17, r16 ; save r16 + ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW + bigcall NET_Interface_IncCounter16 ; (R24, R25) + mov r16, r17 ; restore r16 + pop r24 + rjmp appHubSendMsgToAllOthers_next +appHubSendMsgToAllOthers_added: + mov r17, r16 ; save r16 + bigcall NET_Buffer_IncRef ; (r16) + mov r16, r17 ; restore r16 +appHubSendMsgToAllOthers_next: + ldi r20, COM2W_IFACE_SIZE + add yl, r20 + adc yh, r20 + sub yh, r20 + dec r19 + brne appHubSendMsgToAllOthers_loop + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubHandleMsgLocally +; +; @param X pointer to received buffer (points to header byte) +; @param Y pointer to IFACE data from which msg was received +; @clobbers all, !X + +appHubHandleMsgLocally: + push xl + push xh + rcall appHubHandleMsgLocally_savedX + pop xh + pop xl + rjmp appHubHandleMsgLocally_ret +appHubHandleMsgLocally_savedX: + ; get message type + adiw xh:xl, NETMSG_OFFS_CMD+1 ; account for header byte + ld r16, X + sbiw xh:xl, NETMSG_OFFS_CMD+1 + cpi r16, NETMSG_CMD_PING + breq appHubHandleMsgLocally_handlePingMsg + cpi r16, NETMSG_CMD_REBOOT_REQUEST + breq appHubHandleMsgLocally_handleRebootMsg + cpi r16, NETMSG_CMD_VALUE_SET + breq appHubHandleMsgLocally_handleSetValue + rjmp appHubHandleMsgLocally_ret +appHubHandleMsgLocally_handlePingMsg: + rjmp appHubHandlePingMsg +appHubHandleMsgLocally_handleRebootMsg: + rjmp appHubHandleRebootMsg +appHubHandleMsgLocally_handleSetValue: + rjmp appHubHandleSetValueMsg +appHubHandleMsgLocally_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubHandlePingMsg +; +; @param X pointer to received message +; @clobbers any, !X, !Y + +appHubHandlePingMsg: + adiw xh:xl, NETMSG_OFFS_DESTADDR+1 + ld r17, X + sbiw xh:xl, NETMSG_OFFS_DESTADDR+1 + ldd r16, Y+NET_IFACE_OFFS_ADDRESS + cp r16, r17 + breq appHubHandlePingMsg_forMe + cpi r17, 0xff + breq appHubHandlePingMsg_forMe + clc + rjmp appHubHandlePingMsg_end +appHubHandlePingMsg_forMe: + adiw xh:xl, NETMSG_OFFS_SRCADDR+1 + ld r17, X + sbiw xh:xl, NETMSG_OFFS_SRCADDR+1 + push r17 + bigcall NET_Buffer_Alloc ; (R16, R17, X) + pop r17 + brcc appHubHandlePingMsg_end ; jmp on error + push r16 ; buffer num + mov r16, r17 ; DEST addr + adiw xh:xl, 1 + bigcall NETMSG_Pong_Write ; (R16, R17, R18, R19, R20, X) + sbiw xh:xl, 1 + pop r16 ; buffer num + bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) +appHubHandlePingMsg_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubHandleRebootMsg +; +; Doesn't return if reboot msg is valid. +; +; @param X pointer to received message + +appHubHandleRebootMsg: + rcall NETMSG_RebootRequestRead + brcc appHubHandleRebootMsg_end + ; reboot + cli + bigjmp BOOTLOADER_ADDR +appHubHandleRebootMsg_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubHandleSetValueMsg +; +; @param X pointer to received message +; @param Y pointer to IFACE data from which msg was received +; @clobbers all, !Y + +appHubHandleSetValueMsg: + adiw xh:xl, NETMSG_OFFS_DESTADDR+1 + ld r17, X + sbiw xh:xl, NETMSG_OFFS_DESTADDR+1 + ldd r16, Y+NET_IFACE_OFFS_ADDRESS + cp r16, r17 + breq appHubHandleSetValueMsg_forMe + cpi r17, 0xff + breq appHubHandleSetValueMsg_forMe + rjmp appHubHandleSetValueMsg_ret +appHubHandleSetValueMsg_forMe: + rcall NETMSG_ValueRead ; (none) + cpi r17, VALUE_ID_HUB_SETRANGE1 + brcs appHubHandleSetValueMsg_ret + cpi r17, VALUE_ID_HUB_SETRANGE8+1 + brcc appHubHandleSetValueMsg_ret +appHubHandleSetValueMsg_setRange: + push yl + push yh + subi r17, (VALUE_ID_HUB_SETRANGE1-1) + push r18 + push r19 + ; send ACK back the same interface the request came from + push r17 ; interface number + ldi r23, NETMSG_CMD_VALUE_SET_ACK + rcall appHubSendValueResponse ; r22 (r16, r17, r18, r19, r20, r21, r23, r24, r25, X) + pop r16 ; pop interface number to r16 (from r17) + rcall appHubGetDeviceByIfaceNum ; Y=interface to modify (r17, r19, r20) + pop r19 + pop r18 + ; modify interface + std Y+NET_IFACE_OFFS_RANGE_BEGIN, r18 + std Y+NET_IFACE_OFFS_RANGE_END, r19 + ; TODO: store new config + + ; let subnodes of modified interface re-eunumerate + ldi r18, NETMSG_CMD_REENUM + rcall appHubSendRangeMsg ; (R16, R17, R18, R19, R20, R21, X) + pop yh + pop yl + +appHubHandleSetValueMsg_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubHandleRoutingMsg +; +; @param X pointer to received buffer (points to header byte) +; @param Y pointer to IFACE data from which msg was received +; @clobbers all, !X + +appHubHandleRoutingMsg: + push xl + push xh + rcall appHubHandleRoutingMsg_savedX + pop xh + pop xl + rjmp appHubHandleRoutingMsg_ret +appHubHandleRoutingMsg_savedX: + ; get message type + adiw xh:xl, NETMSG_OFFS_CMD+1 ; account for header byte + ld r16, X + sbiw xh:xl, NETMSG_OFFS_CMD+1 + cpi r16, NETMSG_CMD_NEED_ADDRESS + breq appHubHandleRoutingMsg_handleNeedAddress + cpi r16, NETMSG_CMD_CLAIM_ADDRESS + breq appHubHandleRoutingMsg_handleClaimAddress + clc + rjmp appHubHandleRoutingMsg_ret +appHubHandleRoutingMsg_handleNeedAddress: + rcall appHubHandleNeedAddressMsg + rjmp appHubHandleRoutingMsg_secRet +appHubHandleRoutingMsg_handleClaimAddress: + rcall appHubHandleClaimAddressMsg +appHubHandleRoutingMsg_secRet: + sec +appHubHandleRoutingMsg_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubHandleNeedAddressMsg +; +; @param X pointer to received message +; @param Y pointer to IFACE data from which msg was received +; @clobbers all, !Y + +appHubHandleNeedAddressMsg: + ldi r18, NETMSG_CMD_ADDRESS_RANGE + rcall appHubSendRangeMsg ; (R16, R17, R18, R19, R20, R21, X) + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubHandleClaimAddressMsg +; +; @param X pointer to received message +; @param Y pointer to IFACE data from which msg was received +; @clobbers all, !Y + +appHubHandleClaimAddressMsg: + rcall NETMSG_Address_Read ; R18=cmd, R19=addr(R18, R19) + rcall appHubIsR19InRange + brcs appHubHandleClaimAddressMsg_end + ; is not in subnet range, deny + rcall appHubSendDenyAddrR19 ; (R16, R17, R18, R19, R20, R21, X) +appHubHandleClaimAddressMsg_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubIsR19InRange +; +; @param R19 address to check against range +; @param Y pointer to IFACE data +; @clobbers R16 + +appHubIsR19InRange: + ldd r16, Y+NET_IFACE_OFFS_RANGE_BEGIN + cp r19, r16 + brcs appHubIsR19InRangeClcRet + ldd r16, Y+NET_IFACE_OFFS_RANGE_END + cp r16, r19 + brcs appHubIsR19InRangeClcRet + sec + rjmp appHubIsR19InRange_end +appHubIsR19InRangeClcRet: + clc +appHubIsR19InRange_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubCheckRecvdMsg +; +; Read messages from any interface and forward to the other ones. +; +; @return CFLAG set if something done, cleared otherwise + +appHubCheckRecvdMsg: + rcall NET_PeekNextIncomingMsgNum ; check read queue (R16=bufNum) + brcc appHubCheckRecvdMsg_end ; no msg, jmp + rcall NET_Buffer_Locate ; (R17) + rcall appHubHandleRecvdMsg ; (all, !X) + rcall NET_GetNextIncomingMsgNum ; take off the queue + rcall NET_Buffer_ReleaseByNum ; (R16, X) + sec ; we had a message, so something was done +appHubCheckRecvdMsg_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appHubHandleRecvdMsg +; +; @param R16 buffer number +; @param X pointer to received message +; @clobbers all, !X + +appHubHandleRecvdMsg: + mov r18, r16 + ld r16, X + andi r16, 0x0f + rcall appHubGetDeviceByIfaceNum ; Y=source iface (r17, r19, r20) + brcc appHubHandleRecvdMsg_ret + ; filter out routing msgs + push yl + push yh + push r18 + rcall appHubHandleRoutingMsg ; (all, !X) + pop r18 + pop yh + pop yl + brcs appHubHandleRecvdMsg_ret + ; check for PING, SETVALUE etc + push r18 + push yl + push yh + rcall appHubHandleMsgLocally ; (all, !X) + pop yh + pop yl + ; let other apps and modules handle message + push xl + push xh + bigcall mainHandleMessages + pop xh + pop xl + pop r18 + ; forward message to all other interfaces + mov r16, r18 ; buffer number + push xl + push xh + rcall appHubSendMsgToAllOthers ; (r17, r19, r20, r24, r25 (r16, r18, X) + pop xh + pop xl +appHubHandleRecvdMsg_ret: + ret +; @end + + + + + + + + + + + + + + + + +; --------------------------------------------------------------------------- +; @routine appHubWriteConfToEeprom +; +; @clobbers R16, X (R17) + +appHubWriteConfToEeprom: + ; write range begin + ldi xl, LOW(EEPROM_OFFS_ROUTER_RANGE_BEGIN) + ldi xh, HIGH(EEPROM_OFFS_ROUTER_RANGE_BEGIN) + lds r16, appHubRangeBegin + rcall Eeprom_WriteByteIfChanged ; (R17) + brcc appHubWriteConfToEeprom_end + + ; write range end + ldi xl, LOW(EEPROM_OFFS_ROUTER_RANGE_END) + ldi xh, HIGH(EEPROM_OFFS_ROUTER_RANGE_END) + lds r16, appHubRangeEnd + rcall Eeprom_WriteByteIfChanged ; (R17) +appHubWriteConfToEeprom_end: + ret +; @end + + +#if 0 +; --------------------------------------------------------------------------- +; @routine appHubReadConfFromEeprom +; +; @clobbers R16, X (R17) + +appHubReadConfFromEeprom: + ; read range begin + ldi xl, LOW(EEPROM_OFFS_ROUTER_RANGE_BEGIN) + ldi xh, HIGH(EEPROM_OFFS_ROUTER_RANGE_BEGIN) + rcall Eeprom_ReadByte + brcc appHubReadConfFromEeprom_end + cpi r16, 0xff + breq appHubReadConfFromEeprom_okay ; not set, jmp + cpi r16, 2 ; range should at least start at 2 to assign 1 to router + brcs appHubReadConfFromEeprom_okay + sts appHubRangeBegin, r16 + dec r16 + sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r16 ; use addr rangeBegin-1 for router itself + sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r16 ; use same address for both interfaces to save on addresses + + ; read range end + ldi xl, LOW(EEPROM_OFFS_ROUTER_RANGE_END) + ldi xh, HIGH(EEPROM_OFFS_ROUTER_RANGE_END) + rcall Eeprom_ReadByte + brcc appHubReadConfFromEeprom_end + cpi r16, 0xff + breq appHubReadConfFromEeprom_okay + sts appHubRangeEnd, r16 +appHubReadConfFromEeprom_okay: + sec +appHubReadConfFromEeprom_end: + ret +; @end +#endif + + + diff --git a/avr/apps/network/main.asm b/avr/apps/network/main.asm index d440e20..e4fc8cc 100644 --- a/avr/apps/network/main.asm +++ b/avr/apps/network/main.asm @@ -100,12 +100,30 @@ AppNetwork_Every100ms_jump: +; --------------------------------------------------------------------------- +; @routine AppNetwork_EveryDay @global +; +; @clobbers R16, R17, X + +AppNetwork_EveryDay: + bigjmp NET_Interface_ResetStats ; (R16, R17, X) +; @end + + + ; --------------------------------------------------------------------------- ; @routine AppNetwork_HandleMsg @global ; ; @param X pointer to received message AppNetwork_HandleMsg: + push xl + push xh + rcall AppNetwork_HandleMsg_savedX + pop xh + pop xl + rjmp AppNetwork_HandleMsg_end +AppNetwork_HandleMsg_savedX: adiw xh:xl, NETMSG_OFFS_CMD ld r16, X sbiw xh:xl, NETMSG_OFFS_CMD @@ -113,18 +131,25 @@ AppNetwork_HandleMsg: breq AppNetwork_HandleMsg_handleRebootMsg cpi r16, NETMSG_CMD_PING breq AppNetwork_HandleMsg_handlePingMsg + cpi r16, NETMSG_CMD_REENUM + breq AppNetwork_HandleMsg_handleReenumMsg cpi r16, NETMSG_CMD_NEED_ADDRESS brcs AppNetwork_HandleMsg_clcRet ; lower than "HAVE_NEED" cpi r16, NETMSG_CMD_ADDRESS_RANGE breq AppNetwork_HandleMsg_handleRangeMsg brcc AppNetwork_HandleMsg_clcRet ; higher or equal to "ADDR_RANGE" rjmp AppNetwork_HandleMsg_handleAddrMsg +AppNetwork_HandleMsg_handleReenumMsg: + rjmp appNetworkHandleReeunumRequest AppNetwork_HandleMsg_handleRangeMsg: - ; TODO + bigcall NETMSG_Range_Read + std Y+NET_IFACE_OFFS_RANGE_BEGIN, r20 + std Y+NET_IFACE_OFFS_RANGE_END, r21 + std Y+NET_IFACE_OFFS_ADDRESS, r20 rjmp AppNetwork_HandleMsg_clcRet AppNetwork_HandleMsg_handleAddrMsg: - rcall NETMSG_Address_Read ; R18=cmd, R19=addr(R18, R19) + bigcall NETMSG_Address_Read ; R18=cmd, R19=addr(R18, R19) mov r16, r18 subi r16, NETMSG_CMD_NEED_ADDRESS ldi zl, LOW(appNetworkMsgTable) @@ -134,21 +159,13 @@ AppNetwork_HandleMsg_handleAddrMsg: sub zh, r16 ijmp AppNetwork_HandleMsg_handleRebootMsg: - push xl - push xh - rcall appNetworkHandleRebootRequest - pop xh - pop xl + rcall appNetworkHandleRebootRequest ret AppNetwork_HandleMsg_handlePingMsg: - push xl - push xh - rcall appNetworkHandlePingRequest - pop xh - pop xl - ret + rjmp appNetworkHandlePingRequest AppNetwork_HandleMsg_clcRet: clc +AppNetwork_HandleMsg_end: ret ; @end @@ -161,7 +178,7 @@ AppNetwork_HandleMsg_clcRet: appNetworkHandleRebootRequest: rcall NETMSG_RebootRequestRead - brcc appNetworkHandleRebootRequest_end + brcc appNetworkHandleRebootRequest_end ; uid doesn't match ; reboot cli bigjmp BOOTLOADER_ADDR @@ -172,26 +189,56 @@ appNetworkHandleRebootRequest_end: appNetworkHandlePingRequest: + ld r17, X + lds r16, (netInterfaceData+NET_IFACE_OFFS_ADDRESS) + cp r16, r17 + breq appNetworkHandlePingRequest_forMe + cpi r17, 0xff + breq appNetworkHandlePingRequest_forMe + clc + rjmp appNetworkHandlePingRequest_end +appNetworkHandlePingRequest_forMe: adiw xh:xl, NETMSG_OFFS_SRCADDR ld r17, X push r17 - rcall NET_Buffer_Alloc ; (R16, R17, X) + bigcall NET_Buffer_Alloc ; (R16, R17, X) pop r17 - brcc appNetworkHandlePingRequest_end ; jmp on error - push r16 ; buffer num - mov r16, r17 ; DEST addr + brcc appNetworkHandlePingRequest_end ; jmp on error + push r16 ; buffer num + mov r16, r17 ; DEST addr adiw xh:xl, 1 ldi yl, LOW(netInterfaceData) ldi yh, HIGH(netInterfaceData) - rcall NETMSG_Pong_Write ; (R16, R17, R18, R19, R20, X) + bigcall NETMSG_Pong_Write ; (R16, R17, R18, R19, R20, X) sbiw xh:xl, 1 - pop r16 ; buffer num - rcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) + pop r16 ; buffer num + bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) appNetworkHandlePingRequest_end: ret +appNetworkHandleReeunumRequest: + push xl + push xh + rcall Utils_ReadUid ; r21:r20:r19:r18=uid (r16, X) + pop xh + pop xl + rcall NETMSG_Range_Read ; r20=range begin, r21=range end (none) + ldi r16, APP_NETWORK_STATE_INITIALWAIT + std Y+NET_IFACE_OFFS_STATUS, r16 + cpi r18, 20 + brcc appNetworkHandleReeunumRequest_setWait + subi r18, -20 ; minimum 2s +appNetworkHandleReeunumRequest_setWait: + std Y+NET_IFACE_OFFS_STATETIMER, r18 ; use lowest byte of uid as wat time + std Y+NET_IFACE_OFFS_RANGE_BEGIN, r20 + std Y+NET_IFACE_OFFS_RANGE_END, r21 + ret +; @end + + + appNetworkTimerTable: rjmp appNetworkHandleStateInitialWait rjmp appNetworkHandleStateNeedAddress @@ -238,20 +285,11 @@ appNetworkHandleStateHaveAddress2: std Y+NET_IFACE_OFFS_STATUS, r16 ldi r16, APP_NETWORK_TIMER_100MS std Y+NET_IFACE_OFFS_STATETIMER, r16 - ldd r16, Y+NET_IFACE_OFFS_RANGE_BEGIN ; set interface address - ldd r17, Y+NET_IFACE_OFFS_ADDRESS - cp r16, r17 - breq appNetworkHandleStateHaveAddress2_end ; store new address in IFACE and in EEPROM - std Y+NET_IFACE_OFFS_ADDRESS, r16 - push r15 - in r15, SREG - cli - ldi xl, LOW(EEPROM_OFFS_COMADDR) - ldi xh, HIGH(EEPROM_OFFS_COMADDR) - bigcall Utils_WriteEepromIncr ; write address to EEPROM - out SREG, r15 - pop r15 + ldd r16, Y+NET_IFACE_OFFS_ADDRESS + ldi xl, LOW(EEPROM_OFFS_COMADDR) + ldi xh, HIGH(EEPROM_OFFS_COMADDR) + bigcall Eeprom_WriteByteIfChanged ; write address to EEPROM (R17) appNetworkHandleStateHaveAddress2_end: ret @@ -269,7 +307,7 @@ appNetworkHandleStateUp: ; @clobbers R16, R19 (R17, R18, R20, R21, X) appNetworkSendMsgNextState: - ldd r19, Y+NET_IFACE_OFFS_RANGE_BEGIN + ldd r19, Y+NET_IFACE_OFFS_ADDRESS rcall appNetworkSendAddrMsg ; (R16, R17, R18, R19, R20, R21, X) brcc appNetworkSendMsgNextState_retry ldd r16, Y+NET_IFACE_OFFS_STATUS @@ -334,9 +372,9 @@ appNetworkHandleMsgClaimAddr: cp r19, r16 brne appNetworkHandleMsgClaimAddr_end ; not our address ldd r16, Y+NET_IFACE_OFFS_STATUS - cpi r16, APP_NETWORK_STATE_UP ; up? - brne appNetworkHandleMsgClaimAddr_end ; nope, ignore - ; network is up, someone claimed our address, deny it + cpi r16, APP_NETWORK_STATE_CLAIMADDRESS1 + brcs appNetworkHandleMsgClaimAddr_end ; nope, ignore + ; network is somewhat up, someone claimed our address, deny it ldi r18, NETMSG_CMD_DENY_ADDRESS ; deny our addr ldd r19, Y+NET_IFACE_OFFS_ADDRESS rjmp appNetworkSendAddrMsg @@ -358,12 +396,12 @@ appNetworkHandleMsgDenyAddr: cpi r16, APP_NETWORK_STATE_UP breq appNetworkHandleMsgDenyAddr_end ; ignore (our network stack is up) ; still setting up address, check whether the last one is denied now - ldd r16, Y+NET_IFACE_OFFS_RANGE_BEGIN + ldd r16, Y+NET_IFACE_OFFS_ADDRESS cp r19, r16 ; our claimed address? brne appNetworkHandleMsgDenyAddr_end ; nope, jump ; try next address (if any left) ldd r17, Y+NET_IFACE_OFFS_RANGE_END - inc r16 ; RANGE_BEGIN+1 + inc r16 ; next address cp r17, r16 ; smaller than or equal to RANGE_END? brcc appNetworkHandleMsgDenyAddr_claimNext ; out of addresses, start completely new after some waiting time @@ -373,7 +411,7 @@ appNetworkHandleMsgDenyAddr: rjmp appNetworkHandleMsgDenyAddr_end appNetworkHandleMsgDenyAddr_claimNext: ; send CLAIM_ADDR for next address (new state: APP_NETWORK_STATE_NEEDADDRESS+1) - std Y+NET_IFACE_OFFS_RANGE_BEGIN, r16 + std Y+NET_IFACE_OFFS_ADDRESS, r16 ldi r16, APP_NETWORK_STATE_NEEDADDRESS std Y+NET_IFACE_OFFS_STATUS, r16 ldi r18, NETMSG_CMD_CLAIM_ADDRESS @@ -393,16 +431,16 @@ appNetworkHandleMsgDenyAddr_end: ; @clobbers R16 (R17, R18, R19, R20, R21, X) appNetworkSendAddrMsg: - rcall NET_Buffer_Alloc ; (R16, R17, X) + bigcall NET_Buffer_Alloc ; (R16, R17, X) brcc appNetworkSendAddrMsg_end adiw xh:xl, 1 push r16 - rcall NETMSG_Address_Write ; (R16, R17, R18, R19, R20, R21) + bigcall NETMSG_Address_Write ; (R16, R17, R18, R19, R20, R21) pop r16 sbiw xh:xl, 1 - rcall NET_Interface_AddOutgoingMsgNum ; (R17, R18, X) + bigcall NET_Interface_AddOutgoingMsgNum ; (R17, R18, X) brcs appNetworkSendAddrMsg_end - rcall NET_Buffer_ReleaseByNum ; (R16, X) + bigcall NET_Buffer_ReleaseByNum ; (R16, X) clc appNetworkSendAddrMsg_end: ret @@ -424,6 +462,7 @@ appNetworkResetState: std Y+NET_IFACE_OFFS_STATETIMER, r16 ldi r16, APP_NETWORK_ADDRESS_RANGE_BEGIN std Y+NET_IFACE_OFFS_RANGE_BEGIN, r16 + std Y+NET_IFACE_OFFS_ADDRESS, r16 rcall appNetworkGetAddressFromEeprom ; R16=addr (R15, X) tst r16 breq appNetworkResetState_setRangeEnd diff --git a/avr/apps/network/stats.asm b/avr/apps/network/stats.asm index 2b2d6bb..f7c35be 100644 --- a/avr/apps/network/stats.asm +++ b/avr/apps/network/stats.asm @@ -18,14 +18,20 @@ ; @clobbers R16, X (R17, R18, R19, R20, R21, Z) AppNetwork_SendTxdStats: - rcall NET_Buffer_Alloc ; (R16, R17, X) + bigcall NET_Buffer_Alloc ; (R16, R17, X) brcc AppNetwork_SendTxdStats_end push r16 adiw xh:xl, 1 - rcall NETMSG_SendStats_Write ; (R16, R17, R18, R19, R20, R21, Z) + bigcall NETMSG_SendStats_Write ; (R16, R17, R18, R19, R20, R21, Z) sbiw xh:xl, 1 pop r16 - rcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) + push yl + push yh + ldi yl, LOW(netInterfaceData) + ldi yh, HIGH(netInterfaceData) + bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) + pop yh + pop yl AppNetwork_SendTxdStats_end: ret ; @end @@ -35,18 +41,24 @@ AppNetwork_SendTxdStats_end: ; --------------------------------------------------------------------------- ; @routine AppNetwork_SendRxdStats -; @param Y network interface to work with +; @param Y network interface whose stats to send ; @clobbers R16, X (R17, R18, R19, R20, R21, Z) AppNetwork_SendRxdStats: - rcall NET_Buffer_Alloc ; (R16, R17, X) + bigcall NET_Buffer_Alloc ; (R16, R17, X) brcc AppNetwork_SendRxdStats_end push r16 adiw xh:xl, 1 - rcall NETMSG_RecvStats_Write ; (R16, R17, R18, R19, R20, R21, Z) + bigcall NETMSG_RecvStats_Write ; (R16, R17, R18, R19, R20, R21, Z) sbiw xh:xl, 1 pop r16 - rcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) + push yl + push yh + ldi yl, LOW(netInterfaceData) + ldi yh, HIGH(netInterfaceData) + bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) + pop yh + pop yl AppNetwork_SendRxdStats_end: ret ; @end @@ -54,20 +66,25 @@ AppNetwork_SendRxdStats_end: ; --------------------------------------------------------------------------- -; @routine AppNetwork_SendRxdStats +; @routine AppNetwork_SendMemStats -; @param Y network interface to work with ; @clobbers R16, X (R17, R18, R19, R20, R21, Z) AppNetwork_SendMemStats: - rcall NET_Buffer_Alloc ; (R16, R17, X) + bigcall NET_Buffer_Alloc ; (R16, R17, X) brcc AppNetwork_SendMemStats_end push r16 adiw xh:xl, 1 - rcall NETMSG_MemStats_Write ; (R16, R17, R18, R19, R20, R21) + bigcall NETMSG_MemStats_Write ; (R16, R17, R18, R19, R20, R21) sbiw xh:xl, 1 pop r16 - rcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) + push yl + push yh + ldi yl, LOW(netInterfaceData) + ldi yh, HIGH(netInterfaceData) + bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) + pop yh + pop yl AppNetwork_SendMemStats_end: ret ; @end @@ -81,14 +98,14 @@ AppNetwork_SendMemStats_end: ; @clobbers R16, X (R17, R18, R19, R20, R21, Z) AppNetwork_SendDevice: - rcall NET_Buffer_Alloc ; (R16, R17, X) + bigcall NET_Buffer_Alloc ; (R16, R17, X) brcc AppNetwork_SendDevice_end push r16 adiw xh:xl, 1 - rcall NETMSG_Device_Write ; (R16, R17, R18, R19, R20, R21, Z) + bigcall NETMSG_Device_Write ; (R16, R17, R18, R19, R20, R21, Z) sbiw xh:xl, 1 pop r16 - rcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) + bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) AppNetwork_SendDevice_end: ret ; @end diff --git a/avr/apps/reportsensors/main.asm b/avr/apps/reportsensors/main.asm index 6f4751e..51b9a25 100644 --- a/avr/apps/reportsensors/main.asm +++ b/avr/apps/reportsensors/main.asm @@ -11,7 +11,7 @@ ; *************************************************************************** ; defines -.equ APP_REPORT_SENSORS_INTERVAL_SECS = 60 +.equ APP_REPORT_SENSORS_INTERVAL_SECS = 120 @@ -78,35 +78,45 @@ AppReportSensors_OnEverySecond_store: #ifdef MODULES_SI7021 cpi r16, 1 breq AppReportSensors_OnEverySecond_measureValue1 - cpi r16, 19 + cpi r16, 11 breq AppReportSensors_OnEverySecond_measureValue2 - cpi r16, 39 + cpi r16, 16 breq AppReportSensors_OnEverySecond_sendValue1 - cpi r16, 49 + cpi r16, 21 breq AppReportSensors_OnEverySecond_sendValue2 #endif #ifdef MODULES_SGP40 - cpi r16, 27 + cpi r16, 32 breq AppReportSensors_OnEverySecond_measureValue4 - cpi r16, 55 + cpi r16, 42 breq AppReportSensors_OnEverySecond_sendValue4 #endif #ifdef MODULES_SGP30 - cpi r16, 29 - breq AppReportSensors_OnEverySecond_measureValue5 - cpi r16, 57 + cpi r16, 53 breq AppReportSensors_OnEverySecond_sendValue5 - cpi r16, 59 + cpi r16, 63 breq AppReportSensors_OnEverySecond_sendValue6 #endif #ifdef MODULES_DS18B20 - cpi r16, 9 + cpi r16, 84 breq AppReportSensors_OnEverySecond_sendValue3 #endif +#ifdef MODULES_CCS811 + cpi r16, 94 + breq AppReportSensors_OnEverySecond_sendCCS811_TVOC + cpi r16, 104 + breq AppReportSensors_OnEverySecond_sendCCS811_CO2 +#endif + +#ifdef MODULES_BRIGHTNESS + cpi r16, 97 + breq AppReportSensors_OnEverySecond_sendBrightness +#endif + ret #ifdef MODULES_SI7021 @@ -133,13 +143,23 @@ AppReportSensors_OnEverySecond_sendValue3: #endif #ifdef MODULES_SGP30 - AppReportSensors_OnEverySecond_measureValue5: - rjmp SGP30_Measure - AppReportSensors_OnEverySecond_sendValue5: - rjmp SGP30_SendTVOC - ret - AppReportSensors_OnEverySecond_sendValue6: - rjmp SGP30_SendCO2 + AppReportSensors_OnEverySecond_sendValue5: + rjmp SGP30_SendTVOC + ret + AppReportSensors_OnEverySecond_sendValue6: + rjmp SGP30_SendCO2 +#endif + +#ifdef MODULES_CCS811 +AppReportSensors_OnEverySecond_sendCCS811_TVOC: + rjmp CCS811_SendTVOC +AppReportSensors_OnEverySecond_sendCCS811_CO2: + rjmp CCS811_SendCO2 +#endif + +#ifdef MODULES_BRIGHTNESS +AppReportSensors_OnEverySecond_sendBrightness: + rjmp Brightness_Send #endif ; @end diff --git a/avr/apps/router/0BUILD b/avr/apps/router/0BUILD new file mode 100644 index 0000000..593fe80 --- /dev/null +++ b/avr/apps/router/0BUILD @@ -0,0 +1,15 @@ + + + + + + + + + main.asm + + + + + + diff --git a/avr/apps/router/main.asm b/avr/apps/router/main.asm new file mode 100644 index 0000000..b077898 --- /dev/null +++ b/avr/apps/router/main.asm @@ -0,0 +1,579 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +; *************************************************************************** +; defines + +; --------------------------------------------------------------------------- +; network interfaces + +.equ NETDEV0_IFACENUM = 1 +.equ NETDEV1_IFACENUM = 2 + + + +; *************************************************************************** +; data + +.dseg + +appRouterDataBegin: + appRouterRangeBegin: .byte 1 + appRouterRangeEnd: .byte 1 +appRouterDataEnd: + + + + +; *************************************************************************** +; code + +.cseg + +; --------------------------------------------------------------------------- +; @routine AppRouter_Init @global + +AppRouter_Init: + ldi xh, HIGH(appRouterDataBegin) + ldi xl, LOW(appRouterDataBegin) + clr r16 + ldi r17, (appRouterDataEnd-appRouterDataBegin) + rcall Utils_FillSram + +#ifndef APP_ROUTER_NO_ADDR_MGR + ldi r16, 0xe0 ; default range from 0xe0-0xef (will be changed later) + sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r16 ; use first address for router itself + sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r16 ; use same address for both interfaces to save on addresses + inc r16 + sts appRouterRangeBegin, r16 ; range from router+1 + ldi r16, 0xef + sts appRouterRangeEnd, r16 + + rcall appRouterReadConfFromEeprom ; try to read config from EEPROM +#endif + + ; set interface number for NETDEV0 + ldi r16, NETDEV0_IFACENUM + sts netInterfaceData+NET_IFACE_OFFS_IFACENUM, r16 + ; set interface number for NETDEV1 + ldi r16, NETDEV1_IFACENUM + sts netInterfaceData2+NET_IFACE_OFFS_IFACENUM, r16 + +#ifndef APP_ROUTER_NO_ADDR_MGR + ldi r18, NETMSG_CMD_ADDRESS_RANGE + rcall appRouterSendRangeMsgToDev1 +#endif + + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine AppRouter_EveryDay @global +; +; @clobbers R16, R17, X + +AppRouter_EveryDay: + ldi yl, LOW(netInterfaceData) + ldi yh, HIGH(netInterfaceData) + bigcall NET_Interface_ResetStats ; (R16, R17, X) + + ldi yl, LOW(netInterfaceData2) + ldi yh, HIGH(netInterfaceData2) + bigcall NET_Interface_ResetStats ; (R16, R17, X) + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine AppRouter_Run @global +; +; Read messages from either interface and forward to the other one. + +AppRouter_Run: + rjmp appRouterCheckRecvdMsg +; @end + + + +; --------------------------------------------------------------------------- +; @routine appRouterHandleMsgAnyDev @global +; +; @param X pointer to received message +; @return CFLAG set if msg handled, cleared otherwise +; @clobbers any, !X + +appRouterHandleMsgAnyDev: + push xl + push xh + rcall appRouterHandleMsgAnyDev_savedX + pop xh + pop xl + rjmp appRouterHandleMsgAnyDev_end +appRouterHandleMsgAnyDev_savedX: + adiw xh:xl, NETMSG_OFFS_CMD ; maybe move ping/reboot handling to all/main.asm? + ld r16, X + sbiw xh:xl, NETMSG_OFFS_CMD + cpi r16, NETMSG_CMD_REBOOT_REQUEST + breq appRouterHandleMsgAnyDev_handleRebootMsg + cpi r16, NETMSG_CMD_PING + breq appRouterHandleMsgAnyDev_handlePingMsg + cpi r16, NETMSG_CMD_VALUE_SET + breq appRouterHandleMsgAnyDev_handleSetValue + rjmp appRouterHandleMsgAnyDev_clcRet +appRouterHandleMsgAnyDev_handleRebootMsg: + rcall appRouterHandleRebootRequest + ret +appRouterHandleMsgAnyDev_handlePingMsg: + rcall appRouterHandlePingRequest + clc + ret +appRouterHandleMsgAnyDev_handleSetValue: + rcall NETMSG_ValueRead ; (none) + cpi r17, VALUE_ID_ROUTER_SETRANGE + breq appRouterHandleMsgAnyDev_handleSetRange + rjmp appRouterHandleMsgAnyDev_clcRet +appRouterHandleMsgAnyDev_handleSetRange: +#ifndef APP_ROUTER_NO_ADDR_MGR + sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r18 ; use first address for router itself + sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r18 ; use same address for both interfaces to save on addresses + inc r18 ; start range after router + sts appRouterRangeBegin, r18 + sts appRouterRangeEnd, r19 + ; send ACK + ldi r23, NETMSG_CMD_VALUE_SET_ACK + rcall Main_SendValueResponse ; (clobbers all, including Y) + ; let subnodes re-eunumerate + ldi r18, NETMSG_CMD_REENUM + rcall appRouterSendRangeMsgToDev1 ; (R16, R17, R18, R19, R20, R21, X, Y) + rcall appRouterWriteConfToEeprom ; (r16, r17, X) +#endif + sec + ret +appRouterHandleMsgAnyDev_clcRet: + clc +appRouterHandleMsgAnyDev_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appRouterHandleDev1Msg @global +; +; Handle messages from controlled subnet. +; +; @param X pointer to received message +; @return CFLAG set if msg handled, cleared otherwise +; @clobbers any, !X + +appRouterHandleDev1Msg: +#ifndef APP_ROUTER_NO_ADDR_MGR + push xl + push xh + rcall appRouterHandleDev1Msg_savedX + pop xh + pop xl + rjmp appRouterHandleDev1Msg_end +appRouterHandleDev1Msg_savedX: + adiw xh:xl, NETMSG_OFFS_CMD + ld r16, X + sbiw xh:xl, NETMSG_OFFS_CMD + cpi r16, NETMSG_CMD_NEED_ADDRESS + breq appRouterHandleDev1Msg_handleNeedAddr + cpi r16, NETMSG_CMD_CLAIM_ADDRESS + breq appRouterHandleDev1Msg_handleClaimAddr + ; add more here + ldi r16, 0 + rjmp appRouterHandleDev1Msg_clcRet +appRouterHandleDev1Msg_handleNeedAddr: + ldi r18, NETMSG_CMD_ADDRESS_RANGE + rcall appRouterSendRangeMsgToDev1 ; (R16, R17, R18, R19, R20, R21, X, Y) + sec + rjmp appRouterHandleDev1Msg_end +appRouterHandleDev1Msg_handleClaimAddr: + rcall NETMSG_Address_Read ; R18=cmd, R19=addr(R18, R19) + rcall appRouterIsR19InRange + brcs appRouterHandleDev1Msg_end + ; is not in subnet range, deny + rcall appRouterSendDenyAddrR19ToDev1 ; (R16, R17, R18, R19, R20, R21, X, Y) + sec + rjmp appRouterHandleDev1Msg_end +#endif +appRouterHandleDev1Msg_clcRet: + clc +appRouterHandleDev1Msg_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appRouterIsR19InRange +; +; @param R19 address to check against range +; @clobbers R16 + +appRouterIsR19InRange: + lds r16, appRouterRangeBegin + cp r19, r16 + brcs appRouterIsR19InRangeClcRet + lds r16, appRouterRangeEnd + cp r16, r19 + brcs appRouterIsR19InRangeClcRet + sec + rjmp appRouterIsR19InRange_end +appRouterIsR19InRangeClcRet: + clc +appRouterIsR19InRange_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appRouterSendDenyAddrR19ToDev1 +; +; @param R19 address to send +; @clobbers R16, R17, R18, R19, R20, R21, X, Y + +appRouterSendDenyAddrR19ToDev1: + ldi r18, NETMSG_CMD_DENY_ADDRESS ; deny addr + rjmp appRouterSendAddrMsgToDev1 ; (R16, R17, R18, R19, R20, R21, X, Y) +; @end + + + +; --------------------------------------------------------------------------- +; @routine appRouterSendAddrMsgToDev1 +; +; @param R18 command +; @param R19 address to send +; @clobbers R16 (R17, R18, R19, R20, R21, X, Y) + +appRouterSendAddrMsgToDev1: + bigcall NET_Buffer_Alloc ; (R16, R17, X) + brcc appRouterSendAddrMsgToDev1_end + push r16 + adiw xh:xl, 1 + bigcall NETMSG_Address_Write ; (R16, R17, R18, R19, R20, R21) + sbiw xh:xl, 1 + pop r16 + rcall appRouterSendMsgToDev1 ; (R16, R17, R18, R24, R25, X, Y) +appRouterSendAddrMsgToDev1_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appRouterSendRangeMsgToDev1 +; +; @param R18 msg code +; @return CFLAG set if message enqueued, cleared on error +; @clobbers (R16, R17, R18, R19, R20, R21, R24, R25, X, Y) + +appRouterSendRangeMsgToDev1: + bigcall NET_Buffer_Alloc ; (R16, R17, X) + brcc appRouterSendRangeMsgToDev1_end + push r16 + lds r20, appRouterRangeBegin + lds r21, appRouterRangeEnd + adiw xh:xl, 1 + bigcall NETMSG_Range_Write ; (R16, R17, R18, R19, R20, R21) + sbiw xh:xl, 1 + pop r16 + rcall appRouterSendMsgToDev1 ; (R16, R17, R18, R24, R25, X, Y) +appRouterSendRangeMsgToDev1_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appRouterSendMsgToDev1 +; +; @param R16 num of allocated buffer +; @param X msg to send (points to start of allocated buffer, e.g. buffer header) +; @return CFLAG set if message enqueued, cleared on error +; @clobbers Y (R16, R17, R18, R24, R25, X) + +appRouterSendMsgToDev1: + ldi yl, LOW(netInterfaceData2) + ldi yh, HIGH(netInterfaceData2) + bigcall NET_Interface_AddOutgoingMsgNum ; (R17, R18, X) + brcs appRouterSendMsgToDev1_end + bigcall NET_Buffer_ReleaseByNum ; (R16, X) + ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW + rcall NET_Interface_IncCounter16 ; (R24, R25) + clc +appRouterSendMsgToDev1_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appRouterHandleRebootRequest +; +; Doesn't return if reboot msg is valid. +; +; @param X pointer to received message + +appRouterHandleRebootRequest: + rcall NETMSG_RebootRequestRead + brcc appRouterHandleRebootRequest_end + ; reboot + cli + bigjmp BOOTLOADER_ADDR +appRouterHandleRebootRequest_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine appRouterHandlePingRequest +; +; @param X pointer to received message + +appRouterHandlePingRequest: + ld r17, X + lds r16, (netInterfaceData+NET_IFACE_OFFS_ADDRESS) + cp r16, r17 + breq appRouterHandlePingRequest_forMe + cpi r17, 0xff + breq appRouterHandlePingRequest_forMe + clc + rjmp appRouterHandlePingRequest_end +appRouterHandlePingRequest_forMe: + adiw xh:xl, NETMSG_OFFS_SRCADDR + ld r17, X + sbiw xh:xl, NETMSG_OFFS_SRCADDR + push r17 + bigcall NET_Buffer_Alloc ; (R16, R17, X) + pop r17 + brcc appRouterHandlePingRequest_end ; jmp on error + push r16 ; buffer num + mov r16, r17 ; DEST addr + adiw xh:xl, 1 + ldi yl, LOW(netInterfaceData) + ldi yh, HIGH(netInterfaceData) + bigcall NETMSG_Pong_Write ; (R16, R17, R18, R19, R20, X) + sbiw xh:xl, 1 + pop r16 ; buffer num + bigcall NET_Interface_AddOrReleaseOutMsg ; (R16, R17, R18, X) +appRouterHandlePingRequest_end: + ret + + + +; --------------------------------------------------------------------------- +; @routine appRouterCheckRecvdMsg +; +; Read messages from either interface and forward to the other one. +; +; @return CFLAG set if something done, cleared otherwise + +appRouterCheckRecvdMsg: + rcall NET_PeekNextIncomingMsgNum ; check read queue (bufNum->r16) + brcc appRouterCheckRecvdMsg_end ; no msg, jmp + rcall NET_Buffer_Locate ; (R17) + rcall appRouterHandleRouterMsgWithHdr ; filter out router msgs + brcs appRouterCheckRecvdMsg_removeMsg ; handled by router code, don't forward + ; let system handle incoming messages + adiw xh:xl, 1 + rcall appRouterLetSysHandleMsg + sbiw xh:xl, 1 + + ; forward to other interface + ld r17, X + andi r17, (1<
diff --git a/avr/common/eeprom-r.asm b/avr/common/eeprom-r.asm new file mode 100644 index 0000000..85447f6 --- /dev/null +++ b/avr/common/eeprom-r.asm @@ -0,0 +1,80 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AQH_AVR_COMMON_EEPROM_R_H +#define AQH_AVR_COMMON_EEPROM_R_H + + + +; --------------------------------------------------------------------------- +; @routine Eeprom_ReadByte +; +; Read a byte from EEPROM (see example in ATtiny24/44/84 manual p.19). +; +; @param X EEPROM Address to read from +; @return CFLAG set if address okay, cleared if out of range +; @return R16 byte read +; @return X EEPROM Address incremented +; @clobbers none + +Eeprom_ReadByte: + rcall Eeprom_CheckAddr + brcs Eeprom_ReadByte_addrOk + ret +Eeprom_ReadByte_addrOk: + ; call routine with IRQs disabled + push r15 + inr r15, SREG + cli + rcall Eeprom_ReadByte_noirq + outr SREG, r15 + pop r15 + sec + ret +Eeprom_ReadByte_noirq: + ; wait until EEPROM ready +Eeprom_ReadByte_waitLoop: +.ifdef EEPE + sbic EECR, EEPE ; wait for previous write to complete (if any) +.else + sbic EECR, EEWE ; wait for previous write to complete (if any) +.endif + rjmp Eeprom_ReadByte_waitLoop +; read from EEPROM + out EEARH, xh ; set EEPROM address + out EEARL, xl + sbi EECR, EERE ; start EEPROM read by writing EERE + in r16, EEDR ; read data from data register + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine Eeprom_CheckAddr +; +; +; @param X EEPROM Address to validate +; @return CFLAG set if address okay, cleared if out of range +; @clobbers r16 + +Eeprom_CheckAddr: + mov r16, xl + subi r16, LOW(EEPROMEND) + mov r16, xh + sbci r16, HIGH(EEPROMEND) + ret +; @end + + + + +#endif ; AQH_AVR_COMMON_EEPROM_R_H + + diff --git a/avr/common/eeprom-w.asm b/avr/common/eeprom-w.asm new file mode 100644 index 0000000..02d87a2 --- /dev/null +++ b/avr/common/eeprom-w.asm @@ -0,0 +1,100 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AQH_AVR_COMMON_EEPROM_W_H +#define AQH_AVR_COMMON_EEPROM_W_H + + +; --------------------------------------------------------------------------- +; Utils_WriteEepromIncr +; +; Write a byte to EEPROM (see example in ATtiny24/44/84 manual p.18). +; +; @param R16 byte to write +; @param X EEPROM Address to write to +; @return CFLAG set if data written, cleared on error +; @clobbers R17 + +Eeprom_WriteByte: + mov r17, r16 + rcall Eeprom_CheckAddr ; (r16) + mov r16, r17 + brcs Eeprom_WriteByte_addrOk + ret +Eeprom_WriteByte_addrOk: + ; call routine with IRQs disabled + push r15 + inr r15, SREG + cli + rcall Eeprom_WriteByte_noirq + outr SREG, r15 + pop r15 + sec + ret +Eeprom_WriteByte_noirq: + ; wait for EEPROM to be ready +Eeprom_WriteByte_waitLoop: +.ifdef EEPE + sbic EECR, EEPE ; wait for previous write to complete (if any) +.else + sbic EECR, EEWE ; wait for previous write to complete (if any) +.endif + rjmp Eeprom_WriteByte_waitLoop + ; write data +.ifdef EEPM1 + ldi r17, (0<NEXT to NULL + std Y+LIST_OFFS_NEXT_LO, r16 + std Y+LIST_OFFS_NEXT_HI, r16 + ret +; @end + + + ; --------------------------------------------------------------------------- ; @routine List_GetNextObject @global ; @param Y pointer to object -; @return X pointer to parent object +; @return X pointer to successor object ; @clobbers none List_GetNextObject: @@ -101,13 +116,13 @@ List_GetPredecessorFor: cp r16, yl brne List_GetPredecessorFor_next cp r17, yh - breq List_GetLastObject_haveIt + breq List_GetPredecessorFor_haveIt List_GetPredecessorFor_next: mov xl, r16 mov xh, r17 rjmp List_GetPredecessorFor List_GetPredecessorFor_haveIt: - sbiw xh:xl, 1 + sbiw xh:xl, 2 List_GetPredecessorFor_ret: ret ; @end @@ -127,8 +142,14 @@ List_AddObject: rcall List_GetLastObject ; (r16, r17, X, Y) pop yh pop yl - st X+, yl ; WID_OFFS_WNEXT_LO - st X+, yh ; WID_OFFS_WNEXT_HI + mov r16, xl + or r16, xh + clc + breq List_AddObject_ret + st X+, yl ; LIST_OFFS_NEXT_LO + st X+, yh ; LIST_OFFS_NEXT_HI + sec +List_AddObject_ret: ret ; @end @@ -163,4 +184,68 @@ List_UnlinkObject_ret: +; --------------------------------------------------------------------------- +; @routine List_UnlinkAllObjects + +; @param Y pointer to first object in a list +; @clobbers r16, r17, r18, Y + +List_UnlinkAllObjects: + clr r18 +List_UnlinkAllObjects_loop: + ldd r16, Y+LIST_OFFS_NEXT_LO + ldd r17, Y+LIST_OFFS_NEXT_HI + std Y+LIST_OFFS_NEXT_LO, r18 + std Y+LIST_OFFS_NEXT_HI, r18 + mov yl, r16 + mov yh, r17 + or r16, r17 + brne List_UnlinkAllObjects_loop + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine List_ForEveryObject +; +; Calls the given function for every object until it +; returns with a set carry flag or until the full list +; is handled. +; Registers that can be used by the given function are all +; except R16, R18 and R19 (those are used by this routine). +; +; @param Y pointer to first object in a list +; @param Z routine to call for every object +; @clobbers r16, r17, r18, r19, X, Y (r24, r25) + +List_ForEveryObject: +List_ForEveryObject_loop: + ldd r18, Y+LIST_OFFS_NEXT_LO ; next + ldd r19, Y+LIST_OFFS_NEXT_HI ; next + clr r16 + std Y+LIST_OFFS_NEXT_LO, r16 + std Y+LIST_OFFS_NEXT_HI, r16 + push r18 ; next + push r19 ; next + rcall List_ForEveryObject_callZ + pop r19 ; next + pop r18 ; next + brcs List_ForEveryObject_ret + mov yl, r18 + mov yh, r19 + or r18, r19 + brne List_ForEveryObject_loop +List_ForEveryObject_ret: + ret +List_ForEveryObject_callZ: + ijmp +; @end + + + + + + + #endif ; AQH_AVR_COMMON_LIST_H diff --git a/avr/common/list_t.asm b/avr/common/list_t.asm new file mode 100644 index 0000000..5fa22cf --- /dev/null +++ b/avr/common/list_t.asm @@ -0,0 +1,240 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AQH_AVR_COMMON_LIST_T_H +#define AQH_AVR_COMMON_LIST_T_H + + + +.equ LIST_TEST_OBJECT_OFFS_LIST = 0 +.equ LIST_TEST_OBJECT_OFFS_VALUE1 = LIST_SIZE +.equ LIST_TEST_OBJECT_OFFS_VALUE2 = LIST_SIZE+1 +.equ LIST_TEST_OBJECT_SIZE = LIST_SIZE+2 + + + + +.dseg + +listTest_list: .byte 2 +listTest_object1: .byte LIST_TEST_OBJECT_SIZE +listTest_object2: .byte LIST_TEST_OBJECT_SIZE +listTest_object3: .byte LIST_TEST_OBJECT_SIZE + + + +.cseg + + +; --------------------------------------------------------------------------- +; @routine listTest_Object_Init +; @param Y pointer to object to init +; @param r18 value 1 +; @param r19 value 2 + +listTest_Object_Init: + bigcall List_InitObject ; (R16) + std Y+LIST_TEST_OBJECT_OFFS_VALUE1, r18 + std Y+LIST_TEST_OBJECT_OFFS_VALUE2, r19 + ret +; @end + + + +listTest1: + ldi yl, LOW(listTest_object1) + ldi yh, HIGH(listTest_object1) + ldi r18, 1 + ldi r19, 2 + rcall listTest_Object_Init + sts listTest_list, yl + sts listTest_list+1, yh + mov xl, yl ; X=listTest_object1 + mov xh, yh + + ldi yl, LOW(listTest_object2) + ldi yh, HIGH(listTest_object2) + ldi r18, 3 + ldi r19, 4 + rcall listTest_Object_Init + + ; X=object 1, Y=object 2 + bigcall List_AddObject ; (r16, r17, x) + + lds yl, listTest_list + lds yh, listTest_list+1 + + ldd r16, Y+LIST_TEST_OBJECT_OFFS_VALUE1 + cpi r16, 1 + ldi r16, 1 + brne listTest1_error + ldd r16, Y+LIST_TEST_OBJECT_OFFS_VALUE2 + cpi r16, 2 + ldi r16, 2 + brne listTest1_error + + bigcall List_GetNextObject + ldi r16, 3 + cpi xl, LOW(listTest_object2) + brne listTest1_error + cpi xh, HIGH(listTest_object2) + brne listTest1_error + + mov yl, xl + mov yh, xh + ldd r16, Y+LIST_TEST_OBJECT_OFFS_VALUE1 + cpi r16, 3 + ldi r16, 4 + brne listTest1_error + ldd r16, Y+LIST_TEST_OBJECT_OFFS_VALUE2 + cpi r16, 4 + ldi r16, 5 + brne listTest1_error + + bigcall List_GetNextObject + mov r16, xh + or r16, xl + ldi r16, 6 + brne listTest1_error + sec + ret +listTest1_error: + clc + ret +; @end + + + +listTest2: + lds xl, listTest_list + lds xh, listTest_list+1 + + ldi yl, LOW(listTest_object3) + ldi yh, HIGH(listTest_object3) + ldi r18, 5 + ldi r19, 6 + rcall listTest_Object_Init + + ; X=object 1, Y=object 2 + bigcall List_AddObject ; (r16, r17, x) + + mov xl, yl + mov xh, yh + bigcall List_GetLastObject + ldi r16, 1 + cpi xl, LOW(listTest_object3) + brne listTest2_error + cpi xh, HIGH(listTest_object3) + brne listTest2_error + + mov yl, xl + mov yh, xh + ldd r16, Y+LIST_TEST_OBJECT_OFFS_VALUE1 + cpi r16, 5 + ldi r16, 2 + brne listTest2_error + ldd r16, Y+LIST_TEST_OBJECT_OFFS_VALUE2 + cpi r16, 6 + ldi r16, 3 + brne listTest2_error + + sec + ret +listTest2_error: + clc + ret +; @end + + + +listTest3: + lds xl, listTest_list + lds xh, listTest_list+1 + ldi yl, LOW(listTest_object2) + ldi yh, HIGH(listTest_object2) + bigcall List_UnlinkObject + + lds yl, listTest_list + lds yh, listTest_list+1 + + ldd r16, Y+LIST_TEST_OBJECT_OFFS_VALUE1 + cpi r16, 1 + ldi r16, 1 + brne listTest3_error + ldd r16, Y+LIST_TEST_OBJECT_OFFS_VALUE2 + cpi r16, 2 + ldi r16, 2 + brne listTest3_error + + bigcall List_GetNextObject + ldi r16, 3 + cpi xl, LOW(listTest_object3) + brne listTest3_error + cpi xh, HIGH(listTest_object3) + brne listTest3_error + + mov yl, xl + mov yh, xh + ldd r16, Y+LIST_TEST_OBJECT_OFFS_VALUE1 + cpi r16, 5 + ldi r16, 4 + brne listTest3_error + ldd r16, Y+LIST_TEST_OBJECT_OFFS_VALUE2 + cpi r16, 6 + ldi r16, 5 + brne listTest3_error + + bigcall List_GetNextObject + mov r16, xh + or r16, xl + ldi r16, 6 + brne listTest3_error + sec + ret +listTest3_error: + clc + ret +; @end + + + +listTest4: + lds xl, listTest_list + lds xh, listTest_list+1 + ldi yl, LOW(listTest_object3) + ldi yh, HIGH(listTest_object3) + bigcall List_UnlinkObject + + lds yl, listTest_list + lds yh, listTest_list+1 + + ldd r16, Y+LIST_TEST_OBJECT_OFFS_VALUE1 + cpi r16, 1 + ldi r16, 1 + brne listTest4_error + ldd r16, Y+LIST_TEST_OBJECT_OFFS_VALUE2 + cpi r16, 2 + ldi r16, 2 + brne listTest4_error + + bigcall List_GetNextObject + mov r16, xh + or r16, xl + ldi r16, 6 + brne listTest4_error + sec + ret +listTest4_error: + clc + ret +; @end + + + +#endif diff --git a/avr/common/m_fixedbuffers.asm b/avr/common/m_fixedbuffers.asm index b2831e1..9ad97a3 100644 --- a/avr/common/m_fixedbuffers.asm +++ b/avr/common/m_fixedbuffers.asm @@ -52,7 +52,7 @@ l_loop: brcs l_loop rjmp l_end ; use cleared CFLAG l_foundfree: - ldi r16, 0x80 ; mark as used + ldi r16, 0x10 ; mark as used st X, r16 mov r16, r17 sec ; set CFLAG, return bufnum in r16, pointre in X diff --git a/avr/common/ringbuffer_y.asm b/avr/common/ringbuffer_y.asm index e4e2ec9..b887b3c 100644 --- a/avr/common/ringbuffer_y.asm +++ b/avr/common/ringbuffer_y.asm @@ -120,7 +120,7 @@ RingBufferY_Reset: ; ; @return CFLAG on success, cleared on error ; @return r16 byte read -; @param Y pointer to start of interface data +; @param Y base address of ringbuffer struct ; @clobbers R17, R18, X RingBufferY_ReadByteGuarded: diff --git a/avr/common/tree.asm b/avr/common/tree.asm index 38e197a..d30465e 100644 --- a/avr/common/tree.asm +++ b/avr/common/tree.asm @@ -17,10 +17,10 @@ ; defs .equ TREE_OFFS_LIST = 0 -.equ TREE_OFFS_WPARENT_LO = TREE_OFFS_LIST+LIST_SIZE -.equ TREE_OFFS_WPARENT_HI = TREE_OFFS_LIST+LIST_SIZE+1 -.equ TREE_OFFS_WCHILD_LO = TREE_OFFS_LIST+LIST_SIZE+2 -.equ TREE_OFFS_WCHILD_HI = TREE_OFFS_LIST+LIST_SIZE+3 +.equ TREE_OFFS_PARENT_LO = TREE_OFFS_LIST+LIST_SIZE +.equ TREE_OFFS_PARENT_HI = TREE_OFFS_LIST+LIST_SIZE+1 +.equ TREE_OFFS_CHILD_LO = TREE_OFFS_LIST+LIST_SIZE+2 +.equ TREE_OFFS_CHILD_HI = TREE_OFFS_LIST+LIST_SIZE+3 .equ TREE_SIZE = TREE_OFFS_LIST+LIST_SIZE+4 @@ -42,10 +42,10 @@ Tree_InitObject: rcall List_InitObject ; (R16) clr r16 ; clear this->TREE data - std Y+TREE_OFFS_LIST+TREE_OFFS_WPARENT_LO, r16 - std Y+TREE_OFFS_LIST+TREE_OFFS_WPARENT_HI, r16 - std Y+TREE_OFFS_LIST+TREE_OFFS_WCHILD_LO, r16 - std Y+TREE_OFFS_LIST+TREE_OFFS_WCHILD_HI, r16 + std Y+TREE_OFFS_LIST+TREE_OFFS_PARENT_LO, r16 + std Y+TREE_OFFS_LIST+TREE_OFFS_PARENT_HI, r16 + std Y+TREE_OFFS_LIST+TREE_OFFS_CHILD_LO, r16 + std Y+TREE_OFFS_LIST+TREE_OFFS_CHILD_HI, r16 ret ; @end @@ -59,8 +59,8 @@ Tree_InitObject: ; @clobbers none Tree_GetParentObject: - ldd xl, Y+TREE_OFFS_WPARENT_LO - ldd xh, Y+TREE_OFFS_WPARENT_HI + ldd xl, Y+TREE_OFFS_PARENT_LO + ldd xh, Y+TREE_OFFS_PARENT_HI ret ; @end @@ -74,13 +74,46 @@ Tree_GetParentObject: ; @clobbers none Tree_GetFirstChildObject: - ldd xl, Y+TREE_OFFS_WCHILD_LO - ldd xh, Y+TREE_OFFS_WCHILD_HI + ldd xl, Y+TREE_OFFS_CHILD_LO + ldd xh, Y+TREE_OFFS_CHILD_HI ret ; @end +; --------------------------------------------------------------------------- +; @routine Tree_GetLastChildObject @global + +; @param Y pointer to object +; @return X pointer to last child object +; @clobbers none + +Tree_GetLastChildObject: + ldd xl, Y+TREE_OFFS_CHILD_LO + ldd xh, Y+TREE_OFFS_CHILD_HI + mov r16, xl + or r16, xh + breq Tree_GetLastChildObject_ret + rcall List_GetLastObject +Tree_GetLastChildObject_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine Tree_GetNextSibling @global + +; @param Y pointer to object +; @return X pointer to successor object +; @clobbers none + +Tree_GetNextSibling: + rjmp List_GetNextObject +; @end + + + ; --------------------------------------------------------------------------- ; @routine Tree_GetObjectBelow @global @@ -101,7 +134,7 @@ treeGetObjectBelow: mov r16, xl or r16, xh brne treeGetObjectBelow_ret ; got one - rcall List_GetNextObject + rcall Tree_GetNextSibling mov r16, xl or r16, xh brne treeGetObjectBelow_ret ; got one @@ -122,27 +155,27 @@ treeGetObjectBelow_ret: ; --------------------------------------------------------------------------- ; @routine Tree_AddChildObject @global -; @param X pointer to parent to add to ; @param Y pointer to object to add +; @param X pointer to parent to add to ; @clobbers r16, r17, r18, x Tree_AddChildObject: - std Y+TREE_OFFS_WPARENT_LO, xl ; immediately store parent pointer - std Y+TREE_OFFS_WPARENT_HI, xh - adiw xh:xl, TREE_OFFS_WCHILD_LO + std Y+TREE_OFFS_PARENT_LO, xl ; immediately store parent pointer + std Y+TREE_OFFS_PARENT_HI, xh + adiw xh:xl, TREE_OFFS_CHILD_LO ; read pointer to first child ld r16, X+ ld r17, X mov r18, r16 or r18, r17 brne Tree_AddChildObject_addToChildList - st X, yh ; no child, set THIS as first + st X, yh ; no child, set THIS as first st -X, yl - sbiw xh:xl, WID_OFFS_TREE+TREE_OFFS_WCHILD_LO + sbiw xh:xl, TREE_OFFS_CHILD_LO ret Tree_AddChildObject_addToChildList: - mov xl, r16 + mov xl, r16 ; X=first child mov xh, r17 - rjmp List_AddObject + rjmp List_AddObject ; add Y as new object ; @end @@ -154,17 +187,17 @@ Tree_AddChildObject_addToChildList: ; @clobbers r16, r17, x Tree_UnlinkObject: - ldd xl, Y+TREE_OFFS_WPARENT_LO - ldd xh, Y+TREE_OFFS_WPARENT_HI + ldd xl, Y+TREE_OFFS_PARENT_LO + ldd xh, Y+TREE_OFFS_PARENT_HI mov r16, xl or r16, xh breq Tree_UnlinkObject_ret ; not part of a tree - adiw xh:xl, TREE_OFFS_WCHILD_LO ; get parent's first child to R17:R16 + adiw xh:xl, TREE_OFFS_CHILD_LO ; get parent's first child to R17:R16 ld r16, X+ ld r17, X cp r16, yl ; same as THIS? brne Tree_UnlinkObject_inList ; nope, need to check childList - cp r17, yh + cp r17, yh ; same as THIS? brne Tree_UnlinkObject_inList ; nope, need to check childList ldd r16, Y+TREE_OFFS_LIST+LIST_OFFS_NEXT_HI ; is first child, set this->NEXT as new first child st X, r16 @@ -177,8 +210,8 @@ Tree_UnlinkObject_inList: rcall List_UnlinkObject ; (R16, R17, X) Tree_UnlinkObject_clrParentAndSibling: clr r16 ; clear this->PARENT - std Y+TREE_OFFS_LIST+TREE_OFFS_WPARENT_LO, r16 - std Y+TREE_OFFS_LIST+TREE_OFFS_WPARENT_HI, r16 + std Y+TREE_OFFS_PARENT_LO, r16 + std Y+TREE_OFFS_PARENT_HI, r16 std Y+LIST_OFFS_NEXT_LO, r16 std Y+LIST_OFFS_NEXT_HI, r16 ; clear this->NEXT Tree_UnlinkObject_ret: @@ -188,5 +221,6 @@ Tree_UnlinkObject_ret: + #endif ; AQH_AVR_COMMON_TREE_H diff --git a/avr/common/tree_t.asm b/avr/common/tree_t.asm new file mode 100644 index 0000000..8bdfa51 --- /dev/null +++ b/avr/common/tree_t.asm @@ -0,0 +1,381 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +.equ TREE_TEST_OBJECT_OFFS_LIST = 0 +.equ TREE_TEST_OBJECT_OFFS_VALUE1 = TREE_SIZE +.equ TREE_TEST_OBJECT_OFFS_VALUE2 = TREE_SIZE+1 +.equ TREE_TEST_OBJECT_SIZE = TREE_SIZE+2 + + + +.dseg + +testTree_root: .byte TREE_TEST_OBJECT_SIZE +testTree_child1: .byte TREE_TEST_OBJECT_SIZE +testTree_child2: .byte TREE_TEST_OBJECT_SIZE +testTree_child3: .byte TREE_TEST_OBJECT_SIZE + + + + +.cseg + + +; --------------------------------------------------------------------------- +; @routine treeTest_Object_Init +; @param Y pointer to object to init +; @param r18 value 1 +; @param r19 value 2 + +treeTest_Object_Init: + bigcall Tree_InitObject ; (R16) + std Y+TREE_TEST_OBJECT_OFFS_VALUE1, r18 + std Y+TREE_TEST_OBJECT_OFFS_VALUE2, r19 + ret +; @end + + + +treeTest1: + ldi yl, LOW(testTree_root) + ldi yh, HIGH(testTree_root) + ldi r18, 1 + ldi r19, 2 + rcall treeTest_Object_Init + mov xl, yl + mov xh, yh + + rcall treeTestCreateAndAddChild1 + ldi r16, 1 ; error code + brcc treeTest1_error + + rcall treeTestCreateAndAddChild2 + ldi r16, 2 ; error code + brcc treeTest1_error + + rcall treeTestCreateAndAddChild3 + ldi r16, 3 ; error code + brcc treeTest1_error + + ldi yl, LOW(testTree_root) + ldi yh, HIGH(testTree_root) + bigcall Tree_GetFirstChildObject + ldi r16, 4 ; error code + cpi xl, LOW(testTree_child1) + brne treeTest1_error + cpi xh, HIGH(testTree_child1) + brne treeTest1_error + + mov yl, xl + mov yh, xh + ldd r16, Y+TREE_TEST_OBJECT_OFFS_VALUE1 + cpi r16, 3 + ldi r16, 5 ; error code + brne treeTest1_error + ldd r16, Y+TREE_TEST_OBJECT_OFFS_VALUE2 + cpi r16, 4 + ldi r16, 6 ; error code + brne treeTest1_error + + rcall treeTestNextSiblingIs2 + ldi r16, 7 ; error code + brcc treeTest1_error + + rcall treeTestNextSiblingIs3 + ldi r16, 8 ; error code + brcc treeTest1_error + + rcall treeTestNextSiblingIsNull + ldi r16, 9 ; error code + brcc treeTest1_error + + sec + ret + +treeTest1_error: + clc + ret +; @end + + + +treeTest2: + ldi yl, LOW(testTree_child2) + ldi yh, HIGH(testTree_child2) + bigcall Tree_UnlinkObject + + rcall treeTestCheckParentNull + ldi r16, 1 ; error code + brcc treeTest2_error + + bigcall Tree_GetNextSibling + mov r16, xl + or r16, xh + ldi r16, 2 ; error code + brne treeTest2_error + + ldi yl, LOW(testTree_root) + ldi yh, HIGH(testTree_root) + bigcall Tree_GetFirstChildObject + ldi r16, 3 ; error code + cpi xl, LOW(testTree_child1) + brne treeTest2_error + cpi xh, HIGH(testTree_child1) + brne treeTest2_error + mov yl, xl + mov yh, xh + + rcall treeTestNextSiblingIs3 + ldi r16, 4 ; error code + brcc treeTest2_error + + sec + ret +treeTest2_error: + clc + ret +; @end + + + +treeTest3: + ldi yl, LOW(testTree_child1) + ldi yh, HIGH(testTree_child1) + bigcall Tree_UnlinkObject + + rcall treeTestCheckParentNull + ldi r16, 1 ; error code + brcc treeTest3_error + + bigcall Tree_GetNextSibling + mov r16, xl + or r16, xh + ldi r16, 2 ; error code + brne treeTest3_error + + ldi yl, LOW(testTree_root) + ldi yh, HIGH(testTree_root) + bigcall Tree_GetFirstChildObject + ldi r16, 3 ; error code + cpi xl, LOW(testTree_child3) + brne treeTest3_error + cpi xh, HIGH(testTree_child3) + brne treeTest3_error + mov yl, xl + mov yh, xh + + rcall treeTestNextSiblingIsNull + ldi r16, 4 ; error code + brcc treeTest3_error + + sec + ret +treeTest3_error: + clc + ret +; @end + + + +treeTest4: + ldi yl, LOW(testTree_child1) + ldi yh, HIGH(testTree_child1) + ldi xl, LOW(testTree_root) + ldi xh, HIGH(testTree_root) + bigcall Tree_AddChildObject + + rcall treeTestCheckParentRoot + ldi r16, 1 ; error code + brcc treeTest4_error + + ldi yl, LOW(testTree_root) + ldi yh, HIGH(testTree_root) + bigcall Tree_GetFirstChildObject + ldi r16, 2 ; error code + cpi xl, LOW(testTree_child3) + brne treeTest4_error + cpi xh, HIGH(testTree_child3) + brne treeTest4_error + mov yl, xl + mov yh, xh + + rcall treeTestNextSiblingIs1 + ldi r16, 3 ; error code + brcc treeTest4_error + + rcall treeTestNextSiblingIsNull + ldi r16, 4 ; error code + brcc treeTest4_error + + sec + ret +treeTest4_error: + clc + ret +; @end + + + + + + +treeTestCreateAndAddChild1: + ldi yl, LOW(testTree_child1) + ldi yh, HIGH(testTree_child1) + ldi r18, 3 + ldi r19, 4 + rcall treeTest_Object_Init + + ldi xl, LOW(testTree_root) + ldi xh, HIGH(testTree_root) + bigcall Tree_AddChildObject + + rcall treeTestCheckParentRoot + brcc treeTestCreateAndAddChild1_error + sec + ret +treeTestCreateAndAddChild1_error: + clc + ret + + + +treeTestCreateAndAddChild2: + ldi yl, LOW(testTree_child2) + ldi yh, HIGH(testTree_child2) + ldi r18, 5 + ldi r19, 6 + rcall treeTest_Object_Init + + ldi xl, LOW(testTree_root) + ldi xh, HIGH(testTree_root) + bigcall Tree_AddChildObject + + rcall treeTestCheckParentRoot + brcc treeTestCreateAndAddChild2_error + sec + ret +treeTestCreateAndAddChild2_error: + clc + ret + + + +treeTestCreateAndAddChild3: + ldi yl, LOW(testTree_child3) + ldi yh, HIGH(testTree_child3) + ldi r18, 7 + ldi r19, 8 + rcall treeTest_Object_Init + + ldi xl, LOW(testTree_root) + ldi xh, HIGH(testTree_root) + bigcall Tree_AddChildObject + + rcall treeTestCheckParentRoot + brcc treeTestCreateAndAddChild3_error + sec + ret +treeTestCreateAndAddChild3_error: + clc + ret + + + + +treeTestCheckParentNull: + bigcall Tree_GetParentObject + mov r16, xl + or r16, xh + brne treeTestCheckParentNull_error + sec + ret +treeTestCheckParentNull_error: + clc + ret + + + +treeTestCheckParentRoot: + bigcall Tree_GetParentObject + cpi xl, LOW(testTree_root) + brne treeTestCheckParentRoot_error + cpi xh, HIGH(testTree_root) + brne treeTestCheckParentRoot_error + sec + ret +treeTestCheckParentRoot_error: + clc + ret + + + +treeTestNextSiblingIs1: + bigcall Tree_GetNextSibling + cpi xl, LOW(testTree_child1) + brne treeTestNextSiblingIs1_error + cpi xh, HIGH(testTree_child1) + brne treeTestNextSiblingIs1_error + mov yl, xl + mov yh, xh + sec + ret +treeTestNextSiblingIs1_error: + clc + ret + + + + +treeTestNextSiblingIs2: + bigcall Tree_GetNextSibling + cpi xl, LOW(testTree_child2) + brne treeTestNextSiblingIs2_error + cpi xh, HIGH(testTree_child2) + brne treeTestNextSiblingIs2_error + mov yl, xl + mov yh, xh + sec + ret +treeTestNextSiblingIs2_error: + clc + ret + + +treeTestNextSiblingIs3: + bigcall Tree_GetNextSibling + cpi xl, LOW(testTree_child3) + brne treeTestNextSiblingIs3_error + cpi xh, HIGH(testTree_child3) + brne treeTestNextSiblingIs3_error + mov yl, xl + mov yh, xh + sec + ret +treeTestNextSiblingIs3_error: + clc + ret + + + +treeTestNextSiblingIsNull: + bigcall Tree_GetNextSibling + mov r16, xl + or r16, xh + brne treeTestNextSiblingIsNull_error + sec + ret +treeTestNextSiblingIsNull_error: + clc + ret + + + diff --git a/avr/common/utils_io.asm b/avr/common/utils_io.asm index e9f3a1f..4ce16f5 100644 --- a/avr/common/utils_io.asm +++ b/avr/common/utils_io.asm @@ -7,29 +7,6 @@ ; * Please see toplevel file COPYING of that project for license details. * ; *************************************************************************** -#if 0 -; M_IO_READ DEST, SRC -.macro M_IO_READ -.if @1 < 64 - in @0, @1 -.else - lds @0, @1 -.endif -.endmacro - - - -; M_IO_WRITE DEST, SRC -.macro M_IO_WRITE -.if @0 < 64 - out @0, @1 -.else - sts @0, @1 -.endif -.endmacro - -#endif - ; inr DEST, SRC .macro inr diff --git a/avr/common/wait_50us.asm b/avr/common/wait_50us.asm index 33c4d41..19ade01 100644 --- a/avr/common/wait_50us.asm +++ b/avr/common/wait_50us.asm @@ -18,7 +18,8 @@ ; @clobbers r22 Utils_WaitFor50MicroSecs: - Utils_WaitNanoSecs 50000, 7, r22 ; wait for 50us (minus RCALL and RET) + Utils_WaitNanoSecs 25000, 0, r22 ; wait for 25us + Utils_WaitNanoSecs 25000, 7, r22 ; wait for 25us (minus RCALL and RET) ret ; @end diff --git a/avr/devices/0BUILD b/avr/devices/0BUILD index c8e68b1..81d626e 100644 --- a/avr/devices/0BUILD +++ b/avr/devices/0BUILD @@ -26,14 +26,19 @@ all c01 c02 + n14 n16 - n20 n21 - n22 - n23 n24 n25 + n26 + n27 + n28 + r05 + r06 + s03 t03 + t04
diff --git a/avr/devices/all/apps.asm b/avr/devices/all/apps.asm index 4ed10ef..ca63ec3 100644 --- a/avr/devices/all/apps.asm +++ b/avr/devices/all/apps.asm @@ -29,6 +29,18 @@ initApps: bigcall AppNetwork_Init #endif +#ifdef APPS_ROUTER + bigcall AppRouter_Init +#endif + +#ifdef APPS_HUB + bigcall AppHub_Init +#endif + +#ifdef APPS_FORWARDER + bigcall AppForwarder_Init +#endif + #ifdef APPS_MOTION bigcall AppMotion_Init #endif @@ -62,9 +74,37 @@ initApps: ; runApps: + clr r16 +#ifdef APPS_ROUTER + push r16 + bigcall AppRouter_Run + pop r16 + sbci r16, 0 ; decrease r16 only if CFLAG set +#endif + +#ifdef APPS_HUB + push r16 + bigcall AppHub_Run + pop r16 + sbci r16, 0 ; decrease r16 only if CFLAG set +#endif + +#ifdef APPS_FORWARDER + push r16 + bigcall AppForwarder_Run + pop r16 + sbci r16, 0 ; decrease r16 only if CFLAG set +#endif ; add more modules here + + tst r16 + clc + breq runApps_end + sec +runApps_end: ret +; @end diff --git a/avr/devices/all/defs.asm b/avr/devices/all/defs.asm index 181bb72..db5392e 100644 --- a/avr/devices/all/defs.asm +++ b/avr/devices/all/defs.asm @@ -20,6 +20,7 @@ .equ AQHOME_VALUETYPE_CO2 = 7 .equ AQHOME_VALUETYPE_TVOC = 8 .equ AQHOME_VALUETYPE_STATS = 9 +.equ AQHOME_VALUETYPE_LIGHT = 10 ; Value Ids @@ -31,11 +32,21 @@ .equ AQHOME_VALUEID_STATS_ERRS_NOBUF = 0xe4 .equ AQHOME_VALUEID_STATS_ERRS_COLLISIONS = 0xe5 .equ AQHOME_VALUEID_STATS_ERRS_BUSY = 0xe6 -.equ AQHOME_VALUEID_STATS_HEAP_USED = 0xe7 -.equ AQHOME_VALUEID_STATS_HEAP_FREE = 0xe8 - +.equ AQHOME_VALUEID_STATS_ERRS_MSGSIZE = 0xe7 +.equ AQHOME_VALUEID_STATS_ERRS_MISSED = 0xe8 +.equ AQHOME_VALUEID_STATS_PACKETS_IN2 = 0xe9 +.equ AQHOME_VALUEID_STATS_PACKETS_OUT2 = 0xea +.equ AQHOME_VALUEID_STATS_ERRS_CONTENT2 = 0xeb +.equ AQHOME_VALUEID_STATS_ERRS_IO2 = 0xec +.equ AQHOME_VALUEID_STATS_ERRS_NOBUF2 = 0xed +.equ AQHOME_VALUEID_STATS_ERRS_COLLISIONS2 = 0xee +.equ AQHOME_VALUEID_STATS_ERRS_BUSY2 = 0xef +.equ AQHOME_VALUEID_STATS_ERRS_MSGSIZE2 = 0xf0 +.equ AQHOME_VALUEID_STATS_ERRS_MISSED2 = 0xf1 +.equ AQHOME_VALUEID_STATS_HEAP_USED = 0xf2 +.equ AQHOME_VALUEID_STATS_HEAP_FREE = 0xf3 ; --------------------------------------------------------------------------- @@ -46,6 +57,12 @@ +.equ TLV_OFFS_LEN = 0 +.equ TLV_OFFS_TYPE = 1 +.equ TLV_OFFS_VALUE = 2 + + + ; --------------------------------------------------------------------------- ; EEPROM positions @@ -65,5 +82,18 @@ .equ EEPROM_OFFS_MAL_CONF_SRC2_VALUEID = 19 ; 1 byte .equ EEPROM_OFFS_MAL_CONF_RGBWVALUE = 20 ; 4 bytes -; next is 24 +.equ EEPROM_OFFS_ROUTER_RANGE_BEGIN = 24 ; 1 byte +.equ EEPROM_OFFS_ROUTER_RANGE_END = 25 ; 1 byte +; next is 26 + + +.equ EEPROM_OFFS_TLV = 32 ; begin TLV area here + + + + +.equ EEPROM_TLV_ROUTER_RANGE = 0x10 ; 2 bytes (range begin, range end) + + + diff --git a/avr/devices/all/hw_m644p.asm b/avr/devices/all/hw_m644p.asm index ccb7f71..f681530 100644 --- a/avr/devices/all/hw_m644p.asm +++ b/avr/devices/all/hw_m644p.asm @@ -103,13 +103,11 @@ systemSetupTimer0: ; setup timer for IRQ every 100ms ldi r16, 1 sts baseTimerModuleReloadValue, r16 sts baseTimerModuleTickCounter, r16 -.endif -; ; Settings for clock 8Mhz ; use timer0 with OCR0=78 (irq every 9.984 millisecs), baseTimerModuleReloadValue 10 ; -.if clock == 8000000 +.elif clock == 8000000 ; CMP interrupt about every 10ms ldi r16, 78-1 outr OCR0A, r16 @@ -117,6 +115,24 @@ systemSetupTimer0: ; setup timer for IRQ every 100ms ldi r16, 10 sts baseTimerModuleReloadValue, r16 sts baseTimerModuleTickCounter, r16 +.elif clock == 10000000 + ; CMP-A interrupt about every 10ms + ldi r16, 98-1 ; (10,000,000/1024)/10 = 97.65625 + outr OCR0A, r16 + + ldi r16, 10 + sts baseTimerModuleReloadValue, r16 + sts baseTimerModuleTickCounter, r16 +.elif clock == 20000000 + ; CMP-A interrupt about every 5ms + ldi r16, 98-1 + outr OCR0A, r16 + + ldi r16, 20 + sts baseTimerModuleReloadValue, r16 + sts baseTimerModuleTickCounter, r16 +.else + .error "Unhandled clock frequency" .endif ldi r16, (1< - - - - - - - - - - - - diff --git a/avr/devices/c01/main/main.asm b/avr/devices/c01/main/main.asm index e902a03..06f527f 100644 --- a/avr/devices/c01/main/main.asm +++ b/avr/devices/c01/main/main.asm @@ -21,6 +21,7 @@ .include "./data.asm" .include "devices/all/defs.asm" +.include "common/calls.asm" .include "common/utils_wait.asm" .include "common/utils_io.asm" diff --git a/avr/devices/c02/aqua_c02.xml b/avr/devices/c02/aqua_c02.xml index 521b5d0..bb9caa6 100644 --- a/avr/devices/c02/aqua_c02.xml +++ b/avr/devices/c02/aqua_c02.xml @@ -7,18 +7,6 @@ - - - - - - - - - - - - diff --git a/avr/devices/c02/main/main.asm b/avr/devices/c02/main/main.asm index 94a7317..dd1c8fc 100644 --- a/avr/devices/c02/main/main.asm +++ b/avr/devices/c02/main/main.asm @@ -33,20 +33,13 @@ ; --------------------------------------------------------------------------- ; generic +.equ STACK_SIZE = 256 + .equ NET_BUFFERS_NUM = 8 .equ NET_BUFFERS_SIZE = 32 -; --------------------------------------------------------------------------- -; heap - -.equ HEAP_START = SRAM_START+0x200 -.equ HEAP_SIZE = SRAM_SIZE-HEAP_START - - - - ; --------------------------------------------------------------------------- ; firmware settings including list of modules used @@ -61,9 +54,8 @@ #define MODULES_UART_BITBANG #define MODULES_SPI_HW #define MODULES_ILI9341 -;#define MODULES_FONT_8X8 -#define MODULES_FONT_6X8 -;#define MODULES_UART_BITBANG +#define MODULES_FONT +#define MODULES_WIN ;#define MODULES_TWI_MASTER ;#define MODULES_LCD ;#define LCD_MINIMAL_FONT @@ -175,6 +167,7 @@ irqNotSet: ; @routine onSystemStart onSystemStart: + bigcall test ret ; @end @@ -226,8 +219,18 @@ onEveryLoop: .include "devices/all/hw_m644p.asm" .include "devices/all/includes.asm" -.include "common/debug.asm" +;.include "common/debug.asm" +;.include "modules/lcd2/font/font2.asm" +;.include "modules/lcd2/font/font3.asm" +;.include "modules/lcd2/font/font16x26.asm" +;.include "modules/lcd2/font/font4.asm" +;.include "modules/lcd2/font/font12x16.asm" +.include "modules/lcd2/font/font5.asm" +.include "modules/lcd2/font/font12x20.asm" +;.include "common/list_t.asm" +.include "common/tree_t.asm" +.include "common/divide.asm" ; --------------------------------------------------------------------------- @@ -238,3 +241,210 @@ onEveryLoop: + + +; @param %0 X +; @param %1 Y +; @param %2 W +; @param %3 H +.macro M_FILL_RECT + ldi r16, LOW(@0) ; X0 + mov r4, r16 + ldi r16, HIGH(@0) + mov r5, r16 + + ldi r16, LOW(@1) ; Y0 + mov r6, r16 + ldi r16, HIGH(@1) + mov r7, r16 + + ldi r16, LOW(@2) ; W + mov r8, r16 + ldi r16, HIGH(@2) + mov r9, r16 + + ldi r16, LOW(@3) ; H + mov r10, r16 + ldi r16, HIGH(@3) + mov r11, r16 + + bigcall ILI9341_FillRect +.endmacro + + + + +test: + ; set foreground (r3:r2) +; 0bRRRRRGGGGGGBBBBB + ldi r16, 0b11111111 + mov r3, r16 + ldi r16, 0b11111111 ; white + mov r2, r16 + M_FILL_RECT 0, 0, 319, 239 + + ; set foreground (r3:r2) + ldi r16, 0b00000000 + mov r3, r16 + ldi r16, 0b00011111 ; blue + mov r2, r16 + M_FILL_RECT 0, 0, 319, 32 + + ; set background (r1:r0) + mov r0, r2 + mov r1, r3 + + ; set foreground (r3:r2) + ldi r16, 0b11111111 + mov r3, r16 + ldi r16, 0b11111111 ; white + mov r2, r16 + +; set Xpos + ldi r16, LOW(10) + mov r4, r16 + ldi r16, HIGH(10) + mov r5, r16 + +; setYpos + ldi r16, LOW(3) + mov r6, r16 + ldi r16, HIGH(3) + mov r7, r16 + +; set font +; ldi zl, LOW(font3_16x26*2) +; ldi zh, HIGH(font3_16x26*2) + ldi zl, LOW(font5_12x20*2) + ldi zh, HIGH(font5_12x20*2) + +; set buffer + ldi xl, LOW(glyphBuffer) + ldi xh, HIGH(glyphBuffer) + +; write characters + ldi r16, 'A' + bigcall ili9341_WriteCharacterX1At + + ldi r16, 'Q' + bigcall ili9341_WriteCharacterX1At + + ldi r16, 'H' + bigcall ili9341_WriteCharacterX1At + + ldi r16, 'O' + bigcall ili9341_WriteCharacterX1At + + ldi r16, 'M' + bigcall ili9341_WriteCharacterX1At + + ldi r16, 'E' + bigcall ili9341_WriteCharacterX1At + +#if 0 + push xl + push xh + rcall listTest1 + pop xh + pop xl + brcc test_error + ldi r16, '!' + bigcall ili9341_WriteCharacterX1At + + push xl + push xh + rcall listTest2 + pop xh + pop xl + brcc test_error + ldi r16, '!' + bigcall ili9341_WriteCharacterX1At + + push xl + push xh + rcall listTest3 + pop xh + pop xl + brcc test_error + ldi r16, '!' + bigcall ili9341_WriteCharacterX1At + + push xl + push xh + rcall listTest4 + pop xh + pop xl + brcc test_error + ldi r16, '!' + bigcall ili9341_WriteCharacterX1At +#endif + + +#if 1 + push xl + push xh + rcall treeTest1 + pop xh + pop xl + brcc test_error + ldi r16, '!' + bigcall ili9341_WriteCharacterX1At + + push xl + push xh + rcall treeTest2 + pop xh + pop xl + brcc test_error + ldi r16, '!' + bigcall ili9341_WriteCharacterX1At + + push xl + push xh + rcall treeTest3 + pop xh + pop xl + brcc test_error + ldi r16, '!' + bigcall ili9341_WriteCharacterX1At + + push xl + push xh + rcall treeTest4 + pop xh + pop xl + brcc test_error + ldi r16, '!' + bigcall ili9341_WriteCharacterX1At + + +#endif + + ret + +test_error: + ldi r17, '0' + add r16, r17 + bigcall ili9341_WriteCharacterX1At + + + ret + + + +helloWorld: .db "Hello World", 0 + + + + + + +.dseg + +glyphBuffer: .byte 1024 +heapStart: + + +.equ HEAP_START = heapStart +.equ HEAP_SIZE = (SRAM_SIZE-STACK_SIZE)-HEAP_START + diff --git a/avr/devices/n00/0BUILD b/avr/devices/n00/0BUILD deleted file mode 100644 index aaaaf7e..0000000 --- a/avr/devices/n00/0BUILD +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n00_main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n00_boot.asm - - - - - - - - - - - n00_defs.asm - - - - - - diff --git a/avr/devices/n00/n00_boot.asm b/avr/devices/n00/n00_boot.asm deleted file mode 100644 index 209cd84..0000000 --- a/avr/devices/n00/n00_boot.asm +++ /dev/null @@ -1,143 +0,0 @@ -; *************************************************************************** -; Source file for base system node on AtTiny 84 -; -; This is for the maintenance system (i.e. the flash loader). -; -; All definitions and changes should go into this file. -; *************************************************************************** - -.equ clock=1000000 ; Define the clock frequency - -.nolist -.include "include/tn84def.inc" ; Define device ATtiny84 -.list - -.include "./n00_defs.asm" -.include "defs_all.asm" - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - -.include "common/utils_wait.asm" -.include "modules/com2/defs.asm" -.include "modules/comproto/defs.asm" - - - -; --------------------------------------------------------------------------- -; firmware settings - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - - -; --------------------------------------------------------------------------- -; LED - -.equ LED_DDR = DDRA -.equ LED_PORT = PORTA -.equ LED_PIN = PINA -.equ LED_PINNUM = PORTA3 - - -; *************************************************************************** -; code segment - -.cseg -.org 0x0000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors -; rjmp start ; Reset vector - rjmp main ; Reset vector - reti ; EXT_INT0 - reti ; PCI0 - reti ; PCI1 - reti ; WATCHDOG - reti ; ICP1 - reti ; OC1A - reti ; OC1B - reti ; OVF1 - reti ; OC0A - reti ; OC0B - reti ; OVF0 - reti ; ACI - reti ; ADCC - reti ; ERDY - reti ; USI_STR - reti ; USI_OVF - - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db 'N', 0 -devInfoVersion: .db 0, 1 ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main ; will be overwritten when flashing - - - -; *************************************************************************** -; main code - - -.org BOOTLOADER_ADDR - - -main: - rjmp bootLoader ; this routine is in modules/flash/proto.asm - - - - -; *************************************************************************** -; includes - -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" - -.include "modules/flash/defs.asm" -.include "modules/flash/eeprom.asm" -.include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" -.include "modules/flash/flash1p.asm" -.include "modules/flash/flashprocess.asm" -.include "modules/flash/wait.asm" -.include "modules/bootloader/main.asm" -.include "modules/network/msg/defs.asm" -.include "modules/network/msg/crc.asm" - - - -systemSetSpeed: -.if clock == 8000000 - ldi r16, (1< - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n06_main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n06_boot.asm - - - - - - - - - - - n06_defs.asm - - - - - - diff --git a/avr/devices/n06/n06_defs.asm b/avr/devices/n06/n06_defs.asm deleted file mode 100644 index 5ffd5d4..0000000 --- a/avr/devices/n06/n06_defs.asm +++ /dev/null @@ -1,139 +0,0 @@ -; *************************************************************************** -; copyright : (C) 2023 by Martin Preuss -; email : martin@libchipcard.de -; -; *************************************************************************** -; * This file is part of the project "AqHome". * -; * Please see toplevel file COPYING of that project for license details. * -; *************************************************************************** - - -; *************************************************************************** -; -; AtTiny84 -; -------- -; VCC 1 14 GND -; PB0 2 13 PA0 -; CNY70-K PB1 3 12 PA1 COM-DATA -; /RESET PB3 4 11 PA2 -; AUX PB2 5 10 PA3 LED -; COM_ATTN PA7 6 9 PA4 TWI-SCL -; TWI-SDA PA6 7 8 PA5 CNY70-C -; -------- -; -; *************************************************************************** - - - -.equ BOOTLOADER_ADDR = 0xd00 - -.equ FIRMWARE_VARIANT_BOOT = 0 -.equ FIRMWARE_VARIANT_TEMP_WINDOW = 1 - -.equ DEVICEINFO_ID = 'N' -.equ DEVICEINFO_VERSION = 6 -.equ DEVICEINFO_REVISION = 4 - - - - -; --------------------------------------------------------------------------- -; LED module - -.equ LED_SIMPLE_ONTIME = 2 -.equ LED_SIMPLE_OFFTIME = 30 -.equ LED_SIMPLE_DDR = DDRA -.equ LED_SIMPLE_PORT = PORTA -.equ LED_SIMPLE_PINNUM = PORTA3 - - - -; --------------------------------------------------------------------------- -; COM module - -.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400 -.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter - -.equ COM_DATA_DDR = DDRA -.equ COM_DATA_OUTPUT = PORTA -.equ COM_DATA_INPUT = PINA -.equ COM_DATA_PIN = PORTA1 - -.equ COM_ATTN_DDR = DDRA -.equ COM_ATTN_INPUT = PINA -.equ COM_ATTN_OUTPUT = PORTA -.equ COM_ATTN_PIN = PORTA7 - -.equ COM_IRQ_ADDR_ATTN = PCMSK0 -.equ COM_IRQ_BIT_ATTN = PCINT7 ; bit 7 in PCMSK0 -.equ COM_IRQ_GIFR_ATTN = PCIF0 -.equ COM_IRQ_GIMSK_ATTN = PCIE0 - - - -; --------------------------------------------------------------------------- -; TWI master module - -;.equ TWI_BIT_LENGTH = 10000 ; 100000 and 200000 works for display: 10000, 100000, 200000 -.equ TWI_BIT_LENGTH = 1 ; 10, 100, 500, 100000 and 200000 works for display: 10000, 100000, 200000 - -.equ TWI_DDR_SCL = DDRA -.equ TWI_PORT_SCL = PORTA -.equ TWI_PIN_SCL = PINA -.equ TWI_PINNUM_SCL = PORTA4 - -.equ TWI_DDR_SDA = DDRA -.equ TWI_PORT_SDA = PORTA -.equ TWI_PIN_SDA = PINA -.equ TWI_PINNUM_SDA = PORTA6 - - - -; --------------------------------------------------------------------------- -; LCD module - -.equ LCD_TWI_ADDRESS = 0x3c - - - -; --------------------------------------------------------------------------- -; BMP 280 - -.equ BMP280_ADDR = 0x76 - - - -; --------------------------------------------------------------------------- -; SI 7021 - -.equ SI7021_ADDR = 0x40 - - - -; --------------------------------------------------------------------------- -; ADC/CNY70 - - -.equ CNY70_PORT_LED = PORTB -.equ CNY70_DDR_LED = DDRB -.equ CNY70_PINNUM_LED = PORTB1 - -.equ CNY70_PORT_ADC = PORTA ; adc5 -.equ CNY70_DDR_ADC = DDRA -.equ CNY70_PINNUM_ADC = PORTA5 -.equ CNY70_MUX_ADC = MUX5 - - - -; --------------------------------------------------------------------------- -; 1-Wire Master -; - -.equ OWI_DDR = DDRB -.equ OWI_PORTOUT = PORTB -.equ OWI_PORTIN = PINB -.equ OWI_PINNUM = PORTB2 - - - - diff --git a/avr/devices/n06/n06_main.asm b/avr/devices/n06/n06_main.asm deleted file mode 100644 index 8b4283f..0000000 --- a/avr/devices/n06/n06_main.asm +++ /dev/null @@ -1,363 +0,0 @@ -; *************************************************************************** -; copyright : (C) 2024 by Martin Preuss -; email : martin@libchipcard.de -; -; *************************************************************************** -; * This file is part of the project "AqHome". * -; * Please see toplevel file COPYING of that project for license details. * -; *************************************************************************** - - - - -; *************************************************************************** -; Source file for temperature sensor node on AtTiny 84 -; -; This is for the full system (i.e. not the boot loader). -; -; All definitions and changes should go into this file. -; -; -; *************************************************************************** - - -.equ clock=1000000 ; Define the clock frequency - - - -.nolist -.include "include/tn84def.inc" ; Define device ATtiny84 -.list - -.include "n06_defs.asm" -.include "defs_all.asm" - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - - -.include "common/utils_wait.asm" - - -; --------------------------------------------------------------------------- -; firmware settings including list of modules used - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - -#define MODULES_TIMER -#define MODULES_COM -#define MODULES_COM_WITH_ADDR_PROTO -;#define MODULES_LED -#define MODULES_LED_SIMPLE -#define MODULES_TWI_MASTER -;#define MODULES_LCD -#define LCD_MINIMAL_FONT -#define MODULES_SI7021 -#define MODULES_STATS -;#define MODULES_CNY70 -;#define MODULES_REED - - - -; --------------------------------------------------------------------------- -; defines for values - -.equ VALUE_ID_SI7021_TEMP = 0x01 -.equ VALUE_ID_SI7021_HUM = 0x02 - -.equ VALUE_ID_ADC = 0x03 -.equ VALUE_ID_REED1 = 0x04 -.equ VALUE_ID_REED2 = 0x05 - - - -; *************************************************************************** -; code segment - -.cseg -.org 000000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors (will be removed as soon as we can flash data over COM) - -; rjmp main ; Reset vector - rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system - reti ; EXT_INT0 - rjmp uartBitbangIsrPcint0 ; PCI0 - reti ; PCI1 - reti ; WATCHDOG - reti ; ICP1 - reti ; OC1A - reti ; OC1B - reti ; OVF1 - rjmp baseTimerIrqOC0A ; OC0A - reti ; OC0B - reti ; OVF0 - reti ; ACI - reti ; ADCC - reti ; ERDY - reti ; USI_STR - reti ; USI_OVF - - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db DEVICEINFO_ID, 0 -devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main - - -; *************************************************************************** -; includes - -.include "common/utils.asm" -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" -.include "common/crc8.asm" - -.include "modules/basetimer/main.asm" - -#ifdef MODULES_TIMER - .include "modules/timer/main.asm" -#endif -#ifdef MODULES_LED -.include "modules/led/main.asm" -#endif -#ifdef MODULES_LED_SIMPLE -.include "modules/led_simple/main.asm" -#endif -#ifdef MODULES_COM - .include "modules/com2/defs.asm" - .include "modules/com2/main.asm" - .include "modules/com2/buffer.asm" - .include "modules/uart_bitbang/defs.asm" - .include "modules/uart_bitbang/main.asm" - .include "modules/uart_bitbang/bytelevel.asm" - .include "modules/uart_bitbang/packetlevel.asm" - #ifdef MODULES_COM_WITH_ADDR_PROTO - .include "modules/comproto/defs.asm" - .include "modules/comproto/main.asm" - .include "modules/comproto/addr.asm" - .include "modules/comproto/msg_recvstats.asm" - .include "modules/comproto/msg_sendstats.asm" - .include "modules/comproto/msg_sysstats.asm" - .include "modules/comproto/msg_memstats.asm" - .include "modules/comproto/msg_pong.asm" - .include "modules/comproto/msg_value.asm" - .include "modules/comproto/msg_device.asm" - .include "modules/comproto/msg_reboot.asm" - #endif -#endif -#ifdef MODULES_TWI_MASTER - .include "modules/twimaster/main.asm" -#endif -#ifdef MODULES_LCD - .include "modules/lcd/main.asm" -#endif -#ifdef MODULES_SI7021 - .include "modules/si7021/main.asm" -#endif -#ifdef MODULES_STATS - .include "modules/stats/main.asm" -#endif -#ifdef MODULES_CNY70 - .include "modules/cny70/main.asm" -#endif -#ifdef MODULES_REED - .include "modules/reed/main.asm" -#endif - - - -; *************************************************************************** -; data in SRAM - -.dseg - - -#ifdef MODULES_LCD - sramTimerWriteStats: .byte 2 -#endif -sramTimerEnqueueValues: .byte 2 -#ifdef MODULES_SI7021 - sramTimerSI7021Measure: .byte 2 - sramTimerSI7021SendTemp: .byte 2 - sramTimerSI7021SendHumidity: .byte 2 -#endif -#ifdef MODULES_CNY70 - sramTimerCny70SendAdc: .byte 2 -#endif -#ifdef MODULES_LCD - sramPeriodicalLcdMark: .byte 2 -#endif - - -; *************************************************************************** -; data in FLASH - -.cseg - -ledA3Flash: .db DDRA+0x20, PORTA+0x20, PINA+0x20, (1< - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n11_main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n11_boot.asm - - - - - - - - - - - n11_defs.asm - - - - - - diff --git a/avr/devices/n11/n11_boot.asm b/avr/devices/n11/n11_boot.asm deleted file mode 100644 index 5db7a4d..0000000 --- a/avr/devices/n11/n11_boot.asm +++ /dev/null @@ -1,142 +0,0 @@ -; *************************************************************************** -; Source file for base system node on AtTiny 84 -; -; This is for the maintenance system (i.e. the flash loader). -; -; All definitions and changes should go into this file. -; *************************************************************************** - -.equ clock=1000000 ; Define the clock frequency - -.nolist -.include "include/tn84def.inc" ; Define device ATtiny84 -.list - -.include "n11_defs.asm" -.include "defs_all.asm" - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - -.include "common/utils_wait.asm" -.include "modules/com2/defs.asm" -.include "modules/comproto/defs.asm" - - - -; --------------------------------------------------------------------------- -; firmware settings - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - - -; --------------------------------------------------------------------------- -; LED - -.equ LED_DDR = DDRA -.equ LED_PORT = PORTA -.equ LED_PIN = PINA -.equ LED_PINNUM = PORTA3 - - -; *************************************************************************** -; code segment - -.cseg -.org 0x0000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors -; rjmp start ; Reset vector - rjmp main ; Reset vector - reti ; EXT_INT0 - reti ; PCI0 - reti ; PCI1 - reti ; WATCHDOG - reti ; ICP1 - reti ; OC1A - reti ; OC1B - reti ; OVF1 - reti ; OC0A - reti ; OC0B - reti ; OVF0 - reti ; ACI - reti ; ADCC - reti ; ERDY - reti ; USI_STR - reti ; USI_OVF - - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db DEVICEINFO_ID, 0 -devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main ; will be overwritten when flashing - - - -; *************************************************************************** -; main code - - -.org BOOTLOADER_ADDR - - -main: - rjmp bootLoader ; this routine is in modules/flash/proto.asm - - - - -; *************************************************************************** -; includes - -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" - -.include "modules/flash/defs.asm" -.include "modules/flash/eeprom.asm" -.include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" -.include "modules/flash/flash1p.asm" -.include "modules/flash/flashprocess.asm" -.include "modules/flash/wait.asm" -.include "modules/bootloader/main.asm" -.include "modules/network/msg/defs.asm" -.include "modules/network/msg/crc.asm" - - - -systemSetSpeed: -.if clock == 8000000 - ldi r16, (1< - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n12_main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n12_boot.asm - - - - - - - - - - - n12_defs.asm - - - - - - diff --git a/avr/devices/n12/n12_defs.asm b/avr/devices/n12/n12_defs.asm deleted file mode 100644 index e9d5825..0000000 --- a/avr/devices/n12/n12_defs.asm +++ /dev/null @@ -1,175 +0,0 @@ -; *************************************************************************** -; copyright : (C) 2024 by Martin Preuss -; email : martin@libchipcard.de -; -; *************************************************************************** -; * This file is part of the project "AqHome". * -; * Please see toplevel file COPYING of that project for license details. * -; *************************************************************************** - -; *************************************************************************** -; -; AtTiny84 -; -------- -; VCC 1 14 GND -; [PCINT8] REED_IN1 PB0 2 13 PA0 COM-DATA -; [PCINT9] REED_IN2 PB1 3 12 PA1 COM_ATTN [PCINT1] -; /RESET PB3 4 11 PA2 TWI-SDA -; [KEY1] PB2 5 10 PA3 TWI-SCL -; LED PA7 6 9 PA4 [USCK/SCL] -; [DI/SDA/OC1A] PA6 7 8 PA5 REED_OUT [DO/OC1B] -; -------- -; -; *************************************************************************** - - - -.equ BOOTLOADER_ADDR = 0xd00 - - -.equ FIRMWARE_VARIANT_BOOT = 0 -.equ FIRMWARE_VARIANT_TEMP_WINDOW = 1 - -.equ DEVICEINFO_ID = 'N' -.equ DEVICEINFO_VERSION = 12 -.equ DEVICEINFO_REVISION = 0 - - -; --------------------------------------------------------------------------- -; LED module - -.equ LED_SIMPLE_ONTIME = 3 -.equ LED_SIMPLE_OFFTIME = 30 -.equ LED_SIMPLE_DDR = DDRA -.equ LED_SIMPLE_PORT = PORTA -.equ LED_SIMPLE_PINNUM = PORTA7 - - - -; --------------------------------------------------------------------------- -; COM module - -.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400 -.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter - -.equ COM_DATA_DDR = DDRA -.equ COM_DATA_OUTPUT = PORTA -.equ COM_DATA_INPUT = PINA -.equ COM_DATA_PIN = PORTA0 - -.equ COM_ATTN_DDR = DDRA -.equ COM_ATTN_INPUT = PINA -.equ COM_ATTN_OUTPUT = PORTA -.equ COM_ATTN_PIN = PORTA1 - - -.equ COM_IRQ_ADDR_ATTN = PCMSK0 -.equ COM_IRQ_BIT_ATTN = 1 ; bit 1 in PCMSK0 -.equ COM_IRQ_GIFR_ATTN = PCIF0 -.equ COM_IRQ_GIMSK_ATTN = PCIE0 - - -; --------------------------------------------------------------------------- -; TWI master module - -.equ TWI_BIT_LENGTH = 1 ; 100000 and 200000 works for display: 10000, 100000, 200000 - -.equ TWI_DDR_SCL = DDRA -.equ TWI_PORT_SCL = PORTA -.equ TWI_PIN_SCL = PINA -.equ TWI_PINNUM_SCL = PORTA3 - -.equ TWI_DDR_SDA = DDRA -.equ TWI_PORT_SDA = PORTA -.equ TWI_PIN_SDA = PINA -.equ TWI_PINNUM_SDA = PORTA2 - - -; --------------------------------------------------------------------------- -; LCD module - -.equ LCD_TWI_ADDRESS = 0x3c - - - -; --------------------------------------------------------------------------- -; BMP 280 - -.equ BMP280_ADDR = 0x76 - - - -; --------------------------------------------------------------------------- -; SI 7021 - -.equ SI7021_ADDR = 0x40 - - - -; --------------------------------------------------------------------------- -; ADC/CNY70 - - -.equ CNY70_PORT_LED = PORTB -.equ CNY70_DDR_LED = DDRB -.equ CNY70_PINNUM_LED = PORTB1 - -.equ CNY70_PORT_ADC = PORTA ; adc5 -.equ CNY70_DDR_ADC = DDRB -.equ CNY70_PINNUM_ADC = PORTA5 -.equ CNY70_MUX_ADC = MUX5 -.equ CNY70_ADCSRB_ADC = ADC5D - - - - -; --------------------------------------------------------------------------- -; Reed -; - -.equ REEDOUT1_DDR = DDRA -.equ REEDOUT1_PORT = PORTA -.equ REEDOUT1_PIN = PINA -.equ REEDOUT1_PINNUM = PORTA5 - -.equ REED1_DDR = DDRB -.equ REED1_PORT = PORTB -.equ REED1_PIN = PINB -.equ REED1_PINNUM = PORTB0 - -.equ REED2_DDR = DDRB -.equ REED2_PORT = PORTB -.equ REED2_PIN = PINB -.equ REED2_PINNUM = PORTB1 - - - -; --------------------------------------------------------------------------- -; 1-Wire Master -; - -.equ OWI_DDR = DDRB -.equ OWI_PORTOUT = PORTB -.equ OWI_PORTIN = PINB -.equ OWI_PINNUM = PORTB2 - - -; --------------------------------------------------------------------------- -; SK6812 - -.equ SK6812_DDR = DDRA -.equ SK6812_PORT = PORTA -.equ SK6812_PINNUM = PORTA5 - - - -; --------------------------------------------------------------------------- -; debug - -.equ DEBUG_LED_DDR = DDRA -.equ DEBUG_LED_PORT_OUT = PORTA -.equ DEBUG_LED_PORT_IN = PINA -.equ DEBUG_LED_PINNUM = PORTA5 - - - diff --git a/avr/devices/n12/n12_main.asm b/avr/devices/n12/n12_main.asm deleted file mode 100644 index 1f95e0f..0000000 --- a/avr/devices/n12/n12_main.asm +++ /dev/null @@ -1,480 +0,0 @@ -; *************************************************************************** -; copyright : (C) 2023 by Martin Preuss -; email : martin@libchipcard.de -; -; *************************************************************************** -; * This file is part of the project "AqHome". * -; * Please see toplevel file COPYING of that project for license details. * -; *************************************************************************** - - -; *************************************************************************** -; Source file for temperature sensor node on AtTiny 84 -; -; This is for the full system (i.e. not the boot loader). -; *************************************************************************** - -.equ clock=8000000 ; Define the clock frequency - - - -.nolist -.include "include/tn84def.inc" ; Define device ATtiny84 -.list - -.include "n12_defs.asm" -.include "defs_all.asm" - -.include "common/utils_wait.asm" ; wait macro - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; firmware settings including list of modules used - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - -#define MODULES_TIMER -#define MODULES_COM -#define MODULES_COM_WITH_ADDR_PROTO -;#define MODULES_LED -#define MODULES_LED_SIMPLE -;#define MODULES_TWI_MASTER -;#define MODULES_LCD -;#define LCD_MINIMAL_FONT -;#define MODULES_SI7021 -#define MODULES_STATS -;#define MODULES_CNY70 -;#define MODULES_REED -;#define MODULES_OWI_MASTER -;#define MODULES_DS18B20 -#define MODULES_SK6812 - - - -; --------------------------------------------------------------------------- -; defines for modules - -.equ VALUE_ID_SI7021_TEMP = 0x01 -.equ VALUE_ID_SI7021_HUM = 0x02 - -.equ VALUE_ID_ADC = 0x03 -.equ VALUE_ID_REED1 = 0x04 -.equ VALUE_ID_REED2 = 0x05 - -.equ VALUE_ID_REED_CONF = 0x81 -.equ VALUE_ID_LED_NUMLEDS = 0x82 -.equ VALUE_ID_LED_RGBW_VALUE = 0x83 - - - -; *************************************************************************** -; code segment - -.cseg -.org 000000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors - -; rjmp main ; Reset vector - rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system - reti ; EXT_INT0 - rjmp uartBitbangIsrPcint0 ; PCI0 - reti ; PCI1 - reti ; WATCHDOG - reti ; ICP1 - reti ; OC1A - reti ; OC1B - reti ; OVF1 - rjmp baseTimerIrqOC0A ; OC0A - reti ; OC0B - reti ; OVF0 - reti ; ACI - reti ; ADCC - reti ; ERDY - reti ; USI_STR - reti ; USI_OVF - - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db DEVICEINFO_ID, 0 -devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main - - -; *************************************************************************** -; includes - -.include "common/utils.asm" -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" -.include "common/crc8.asm" - -.include "modules/basetimer/main.asm" - -#ifdef MODULES_TIMER - .include "modules/timer/main.asm" -#endif -#ifdef MODULES_LED -.include "modules/led/main.asm" -#endif -#ifdef MODULES_LED_SIMPLE -.include "modules/led_simple/main.asm" -#endif -#ifdef MODULES_COM - .include "modules/com2/defs.asm" - .include "modules/com2/main.asm" - .include "modules/com2/buffer.asm" - .include "modules/uart_bitbang/defs.asm" - .include "modules/uart_bitbang/main.asm" - .include "modules/uart_bitbang/bytelevel.asm" - .include "modules/uart_bitbang/packetlevel.asm" - #ifdef MODULES_COM_WITH_ADDR_PROTO - .include "modules/comproto/defs.asm" - .include "modules/comproto/main.asm" - .include "modules/comproto/addr.asm" - .include "modules/comproto/msg_recvstats.asm" - .include "modules/comproto/msg_sendstats.asm" - .include "modules/comproto/msg_sysstats.asm" - .include "modules/comproto/msg_memstats.asm" - .include "modules/comproto/msg_pong.asm" - .include "modules/comproto/msg_value.asm" - .include "modules/comproto/msg_device.asm" - .include "modules/comproto/msg_reboot.asm" - #endif -#endif -#ifdef MODULES_TWI_MASTER - .include "modules/twimaster/main.asm" -#endif -#ifdef MODULES_LCD - .include "modules/lcd/main.asm" -#endif -#ifdef MODULES_SI7021 - .include "modules/si7021/main.asm" -#endif -#ifdef MODULES_STATS - .include "modules/stats/main.asm" -#endif -#ifdef MODULES_CNY70 - .include "modules/cny70/main.asm" -#endif -#ifdef MODULES_REED - .include "modules/reed/main.asm" -#endif -#ifdef MODULES_OWI_MASTER - .include "modules/owimaster/main.asm" -#endif -#ifdef MODULES_DS18B20 - .include "modules/ds18b20/main.asm" -#endif -#ifdef MODULES_SK6812 - .include "modules/sk6812/main.asm" -#endif - - -; *************************************************************************** -; data in SRAM - -.dseg - - -#ifdef MODULES_LCD - sramTimerWriteStats: .byte 2 -#endif -sramTimerEnqueueValues: .byte 2 -#ifdef MODULES_SI7021 - sramTimerSI7021Measure: .byte 2 - sramTimerSI7021SendTemp: .byte 2 - sramTimerSI7021SendHumidity: .byte 2 -#endif -#ifdef MODULES_CNY70 - sramTimerCny70SendAdc: .byte 2 -#endif -#ifdef MODULES_LCD - sramPeriodicalLcdMark: .byte 2 -#endif -#ifdef MODULES_DS18B20 - sramDs18b20Timer: .byte 2 - sramSendDs18b20TempTimer: .byte 2 -#endif - - -; *************************************************************************** -; data in FLASH - -.cseg - -#ifdef MODULES_LED -ledA3Flash: .db DDRA+0x20, PORTA+0x20, PINA+0x20, (1< - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n14_main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n14_boot.asm - - - - - - + boot + main + + aqua_n14.xml + + + - n14_defs.asm + defs.asm + README - diff --git a/avr/devices/n22/README b/avr/devices/n14/README similarity index 89% rename from avr/devices/n22/README rename to avr/devices/n14/README index 131998f..b7094ea 100644 --- a/avr/devices/n22/README +++ b/avr/devices/n14/README @@ -1,10 +1,11 @@ -N22 +N14 === - Role: LED strip controller - MCU: AtTiny85 - Connection: RJ45 +- UART: uart_bitbang2 - Periphery: - LED strip connection (SK6812) - OWI interface diff --git a/devices/nodes/aqua_n14.xml b/avr/devices/n14/aqua_n14.xml similarity index 90% rename from devices/nodes/aqua_n14.xml rename to avr/devices/n14/aqua_n14.xml index 827e291..b59ccfa 100644 --- a/devices/nodes/aqua_n14.xml +++ b/avr/devices/n14/aqua_n14.xml @@ -14,6 +14,8 @@ + + diff --git a/avr/devices/n23/boot/0BUILD b/avr/devices/n14/boot/0BUILD similarity index 87% rename from avr/devices/n23/boot/0BUILD rename to avr/devices/n14/boot/0BUILD index d266259..de971dd 100644 --- a/avr/devices/n23/boot/0BUILD +++ b/avr/devices/n14/boot/0BUILD @@ -2,7 +2,7 @@ - + -I $(builddir) diff --git a/avr/devices/n22/boot/boot.asm b/avr/devices/n14/boot/boot.asm similarity index 97% rename from avr/devices/n22/boot/boot.asm rename to avr/devices/n14/boot/boot.asm index 2acc025..175be30 100644 --- a/avr/devices/n22/boot/boot.asm +++ b/avr/devices/n14/boot/boot.asm @@ -19,6 +19,7 @@ .include "devices/all/defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "common/utils_wait.asm" .include "modules/com2/defs.asm" .include "modules/comproto/defs.asm" @@ -98,8 +99,7 @@ main: .include "modules/flash/defs.asm" .include "modules/flash/eeprom.asm" .include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" +.include "modules/flash/io_com2w.asm" .include "modules/flash/flashxp.asm" .include "modules/flash/flash1p.asm" .include "modules/flash/flashprocess.asm" diff --git a/avr/devices/n14/n14_defs.asm b/avr/devices/n14/defs.asm similarity index 85% rename from avr/devices/n14/n14_defs.asm rename to avr/devices/n14/defs.asm index 39a9b12..b450626 100644 --- a/avr/devices/n14/n14_defs.asm +++ b/avr/devices/n14/defs.asm @@ -1,5 +1,5 @@ ; *************************************************************************** -; copyright : (C) 2024 by Martin Preuss +; copyright : (C) 2025 by Martin Preuss ; email : martin@libchipcard.de ; ; *************************************************************************** @@ -39,6 +39,7 @@ .equ LED_SIMPLE_OFFTIME = 30 .equ LED_SIMPLE_DDR = DDRB .equ LED_SIMPLE_PORT = PORTB +.equ LED_SIMPLE_PORTIN = PINB .equ LED_SIMPLE_PINNUM = PORTB4 @@ -54,15 +55,15 @@ .equ COM_DATA_OUTPUT = PORTB .equ COM_DATA_PIN = PORTB1 -.equ COM_ATTN_DDR = DDRB -.equ COM_ATTN_INPUT = PINB -.equ COM_ATTN_OUTPUT = PORTB -.equ COM_ATTN_PIN = PORTB2 +.equ COM_CLK_DDR = DDRB +.equ COM_CLK_INPUT = PINB +.equ COM_CLK_OUTPUT = PORTB +.equ COM_CLK_PIN = PORTB2 -.equ COM_IRQ_ADDR_ATTN = PCMSK -.equ COM_IRQ_BIT_ATTN = PCINT2 ; bit 2 in PCMSK0 (PCINT2) -.equ COM_IRQ_GIFR_ATTN = PCIF -.equ COM_IRQ_GIMSK_ATTN = PCIE +.equ COM_IRQ_ADDR_CLK = PCMSK +.equ COM_IRQ_BIT_CLK = PCINT2 ; bit 2 in PCMSK0 (PCINT2) +.equ COM_IRQ_GIFR_CLK = PCIF +.equ COM_IRQ_GIMSK_CLK = PCIE diff --git a/avr/devices/n22/main/0BUILD b/avr/devices/n14/main/0BUILD similarity index 86% rename from avr/devices/n22/main/0BUILD rename to avr/devices/n14/main/0BUILD index 38ed80d..47e39ec 100644 --- a/avr/devices/n22/main/0BUILD +++ b/avr/devices/n14/main/0BUILD @@ -2,7 +2,7 @@ - + -I $(builddir) diff --git a/avr/devices/n22/main/main.asm b/avr/devices/n14/main/main.asm similarity index 92% rename from avr/devices/n22/main/main.asm rename to avr/devices/n14/main/main.asm index 40d0b99..b05ccfe 100644 --- a/avr/devices/n22/main/main.asm +++ b/avr/devices/n14/main/main.asm @@ -29,6 +29,7 @@ .include "devices/all/defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "common/utils_wait.asm" @@ -39,8 +40,9 @@ ; --------------------------------------------------------------------------- ; generic -.equ NET_BUFFERS_NUM = 6 -.equ NET_BUFFERS_SIZE = 32 +.equ NET_BUFFERS_NUM = 6 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) @@ -50,7 +52,7 @@ #define MODULES_CLOCK #define MODULES_LED_SIMPLE #define MODULES_NETWORK -#define MODULES_UART_BITBANG +#define MODULES_COM2W #define MODULES_OWI_MASTER #define MODULES_DS18B20 #define MODULES_SK6812 @@ -98,7 +100,7 @@ rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system reti ; EXT_INT0 - rjmp UART_BitBang_PcintIsr ; PCI0 + rjmp com2wPcintIsr ; PCI0 reti ; OC1A reti ; OVF1 reti ; OVF0 @@ -199,7 +201,9 @@ onEveryLoop: ; --------------------------------------------------------------------------- ; defines for network interface -.equ netInterfaceData = uart_bitbang_iface +.equ netInterfaceData = com2w_iface + + diff --git a/avr/devices/n14/n14_boot.asm b/avr/devices/n14/n14_boot.asm deleted file mode 100644 index fe7d310..0000000 --- a/avr/devices/n14/n14_boot.asm +++ /dev/null @@ -1,209 +0,0 @@ -; *************************************************************************** -; Source file for base system node on AtTiny 85 -; -; This is for the maintenance system (i.e. the flash loader). -; -; All definitions and changes should go into this file. -; -; -; *************************************************************************** - -.equ clock=1000000 ; Define the clock frequency - -.nolist -.include "include/tn85def.inc" ; Define device ATtiny85 -.list - -.include "n14_defs.asm" -.include "defs_all.asm" - - -#define COM_ACCEPT_ALL_DEST - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - -.include "common/utils_wait.asm" -.include "modules/com2/defs.asm" -.include "modules/comproto/defs.asm" - - -; --------------------------------------------------------------------------- -; firmware settings - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - -; --------------------------------------------------------------------------- -; LED - -.equ LED_DDR = DDRB -.equ LED_PORT = PORTB -.equ LED_PIN = PINB -.equ LED_PINNUM = PORTB4 - - - -; *************************************************************************** -; code segment - -.cseg -.org 0x0000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors - rjmp main ; Reset vector - reti ; EXT_INT0 - reti ; PCI0 - reti ; OC1A - reti ; OVF1 - reti ; OVF0 - reti ; ERDY - reti ; ACI - reti ; ADCC - reti ; OC1B - reti ; OC0A - reti ; OC0B - reti ; WATCHDOG - reti ; USI_STR - reti ; USI_OVF - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db DEVICEINFO_ID, 0 -devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main ; will be overwritten when flashing - - - -; *************************************************************************** -; main code - - -.org BOOTLOADER_ADDR - - -main: - rjmp bootLoader ; this routine is in modules/flash/proto.asm - - - - -; *************************************************************************** -; includes - -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" - -.include "modules/flash/defs.asm" -.include "modules/flash/eeprom.asm" -.include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" -.include "modules/flash/flash1p.asm" -.include "modules/flash/flashprocess.asm" -.include "modules/flash/wait.asm" -.include "modules/bootloader/main.asm" -.include "modules/network/msg/defs.asm" -.include "modules/network/msg/crc.asm" - - - -systemSetSpeed: -.if clock == 8000000 - ldi r16, (1< - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n15_main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n15_boot.asm - - - - - - - - - - - n15_defs.asm - - - - - - diff --git a/avr/devices/n15/n15_boot.asm b/avr/devices/n15/n15_boot.asm deleted file mode 100644 index b64771d..0000000 --- a/avr/devices/n15/n15_boot.asm +++ /dev/null @@ -1,178 +0,0 @@ -; *************************************************************************** -; Source file for base system node on AtTiny 84 -; -; This is for the maintenance system (i.e. the flash loader). -; -; All definitions and changes should go into this file. -; *************************************************************************** - -.equ clock=1000000 ; Define the clock frequency - -.nolist -.include "include/tn84def.inc" ; Define device ATtiny84 -.list - -.include "n15_defs.asm" -.include "defs_all.asm" - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - -.include "common/utils_wait.asm" -.include "modules/com2/defs.asm" -.include "modules/comproto/defs.asm" - - - -; --------------------------------------------------------------------------- -; firmware settings - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - - -; --------------------------------------------------------------------------- -; LED - -.equ LED_DDR = DDRA -.equ LED_PORT = PORTA -.equ LED_PIN = PINA -.equ LED_PINNUM = PORTA3 - - -; *************************************************************************** -; code segment - -.cseg -.org 0x0000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors -; rjmp start ; Reset vector - rjmp main ; Reset vector - reti ; EXT_INT0 - reti ; PCI0 - reti ; PCI1 - reti ; WATCHDOG - reti ; ICP1 - reti ; OC1A - reti ; OC1B - reti ; OVF1 - reti ; OC0A - reti ; OC0B - reti ; OVF0 - reti ; ACI - reti ; ADCC - reti ; ERDY - reti ; USI_STR - reti ; USI_OVF - - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db DEVICEINFO_ID, 0 -devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main ; will be overwritten when flashing - - - -; *************************************************************************** -; main code - - -.org BOOTLOADER_ADDR - - -main: - rjmp bootLoader ; this routine is in modules/flash/proto.asm - - - - -; *************************************************************************** -; includes - -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" - -.include "modules/flash/defs.asm" -.include "modules/flash/eeprom.asm" -.include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" -.include "modules/flash/flash1p.asm" -.include "modules/flash/flashprocess.asm" -.include "modules/flash/wait.asm" -.include "modules/bootloader/main.asm" -.include "modules/network/msg/defs.asm" -.include "modules/network/msg/crc.asm" - - - -systemSetSpeed: -.if clock == 8000000 - ldi r16, (1< + + aqua_n16.xml + + defs.asm README diff --git a/avr/devices/n16/aqua_n16.xml b/avr/devices/n16/aqua_n16.xml new file mode 100644 index 0000000..6a574de --- /dev/null +++ b/avr/devices/n16/aqua_n16.xml @@ -0,0 +1,17 @@ + + + AQUA + N + 16 + + + + + + + + + + + + diff --git a/avr/devices/n16/boot/boot.asm b/avr/devices/n16/boot/boot.asm index 74bd935..8096bff 100644 --- a/avr/devices/n16/boot/boot.asm +++ b/avr/devices/n16/boot/boot.asm @@ -17,6 +17,7 @@ .include "devices/all/defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "common/utils_wait.asm" ;.include "modules/com2/defs.asm" ;.include "modules/comproto/defs.asm" @@ -99,8 +100,7 @@ main: .include "modules/flash/defs.asm" .include "modules/flash/eeprom.asm" .include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" +.include "modules/flash/io_com2w.asm" .include "modules/flash/flash1p.asm" .include "modules/flash/flashxp.asm" .include "modules/flash/flashprocess.asm" diff --git a/avr/devices/n16/defs.asm b/avr/devices/n16/defs.asm index f5e1371..0340b5f 100644 --- a/avr/devices/n16/defs.asm +++ b/avr/devices/n16/defs.asm @@ -17,7 +17,7 @@ ; PIR PB1 3 12 PA1 COM-DATA ; /RESET PB3 4 11 PA2 TCRT1000_Input ; PB2 5 10 PA3 LED -; COM_ATTN PA7 6 9 PA4 TWI-SCL +; COM_CLK PA7 6 9 PA4 TWI-SCL ; TWI-SDA PA6 7 8 PA5 ; -------- ; @@ -59,15 +59,15 @@ .equ COM_DATA_OUTPUT = PORTA .equ COM_DATA_PIN = PORTA1 -.equ COM_ATTN_DDR = DDRA -.equ COM_ATTN_INPUT = PINA -.equ COM_ATTN_OUTPUT = PORTA -.equ COM_ATTN_PIN = PORTA7 +.equ COM_CLK_DDR = DDRA +.equ COM_CLK_INPUT = PINA +.equ COM_CLK_OUTPUT = PORTA +.equ COM_CLK_PIN = PORTA7 -.equ COM_IRQ_ADDR_ATTN = PCMSK0 -.equ COM_IRQ_BIT_ATTN = PCINT7 ; bit 7 in PCMSK0 -.equ COM_IRQ_GIFR_ATTN = PCIF0 -.equ COM_IRQ_GIMSK_ATTN = PCIE0 +.equ COM_IRQ_ADDR_CLK = PCMSK0 +.equ COM_IRQ_BIT_CLK = PCINT7 ; bit 7 in PCMSK0 +.equ COM_IRQ_GIFR_CLK = PCIF0 +.equ COM_IRQ_GIMSK_CLK = PCIE0 diff --git a/avr/devices/n16/main/main.asm b/avr/devices/n16/main/main.asm index 353b3b1..531361f 100644 --- a/avr/devices/n16/main/main.asm +++ b/avr/devices/n16/main/main.asm @@ -36,6 +36,7 @@ .include "devices/all/defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "common/utils_wait.asm" @@ -46,8 +47,9 @@ ; --------------------------------------------------------------------------- ; generic -.equ NET_BUFFERS_NUM = 6 -.equ NET_BUFFERS_SIZE = 32 +.equ NET_BUFFERS_NUM = 6 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) @@ -57,7 +59,7 @@ #define MODULES_CLOCK #define MODULES_LED_SIMPLE #define MODULES_NETWORK -#define MODULES_UART_BITBANG +#define MODULES_COM2W #define MODULES_TWI_MASTER ;#define MODULES_LCD ;#define LCD_MINIMAL_FONT @@ -107,7 +109,7 @@ ; rjmp main ; Reset vector rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system reti ; EXT_INT0 - rjmp UART_BitBang_PcintIsr ; PCI0 + rjmp com2wPcintIsr ; PCI0 reti ; PCI1 reti ; WATCHDOG reti ; ICP1 @@ -202,7 +204,7 @@ onEveryLoop: ; --------------------------------------------------------------------------- ; defines for network interface -.equ netInterfaceData = uart_bitbang_iface +.equ netInterfaceData = com2w_iface diff --git a/avr/devices/n17/0BUILD b/avr/devices/n17/0BUILD deleted file mode 100644 index 1f404e9..0000000 --- a/avr/devices/n17/0BUILD +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n17_main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - n17_boot.asm - - - - - - - - - - - n17_defs.asm - - - - - - diff --git a/avr/devices/n17/n17_boot.asm b/avr/devices/n17/n17_boot.asm deleted file mode 100644 index 3730141..0000000 --- a/avr/devices/n17/n17_boot.asm +++ /dev/null @@ -1,178 +0,0 @@ -; *************************************************************************** -; Source file for base system node on AtTiny 84 -; -; This is for the maintenance system (i.e. the flash loader). -; -; All definitions and changes should go into this file. -; *************************************************************************** - -.equ clock=1000000 ; Define the clock frequency - -.nolist -.include "include/tn84def.inc" ; Define device ATtiny84 -.list - -.include "n17_defs.asm" -.include "defs_all.asm" - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - -.include "common/utils_wait.asm" -.include "modules/com2/defs.asm" -.include "modules/comproto/defs.asm" - - - -; --------------------------------------------------------------------------- -; firmware settings - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - - -; --------------------------------------------------------------------------- -; LED - -.equ LED_DDR = DDRA -.equ LED_PORT = PORTA -.equ LED_PIN = PINA -.equ LED_PINNUM = PORTA3 - - -; *************************************************************************** -; code segment - -.cseg -.org 0x0000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors -; rjmp start ; Reset vector - rjmp main ; Reset vector - reti ; EXT_INT0 - reti ; PCI0 - reti ; PCI1 - reti ; WATCHDOG - reti ; ICP1 - reti ; OC1A - reti ; OC1B - reti ; OVF1 - reti ; OC0A - reti ; OC0B - reti ; OVF0 - reti ; ACI - reti ; ADCC - reti ; ERDY - reti ; USI_STR - reti ; USI_OVF - - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db DEVICEINFO_ID, 0 -devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main ; will be overwritten when flashing - - - -; *************************************************************************** -; main code - - -.org BOOTLOADER_ADDR - - -main: - rjmp bootLoader ; this routine is in modules/flash/proto.asm - - - - -; *************************************************************************** -; includes - -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" - -.include "modules/flash/defs.asm" -.include "modules/flash/eeprom.asm" -.include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" -.include "modules/flash/flash1p.asm" -.include "modules/flash/flashprocess.asm" -.include "modules/flash/wait.asm" -.include "modules/bootloader/main.asm" -.include "modules/network/msg/defs.asm" -.include "modules/network/msg/crc.asm" - - - -systemSetSpeed: -.if clock == 8000000 - ldi r16, (1< - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - boot.asm - - - - - - - - - - - defs.asm - - - - - - diff --git a/avr/devices/n18/boot.asm b/avr/devices/n18/boot.asm deleted file mode 100644 index d201486..0000000 --- a/avr/devices/n18/boot.asm +++ /dev/null @@ -1,140 +0,0 @@ -; *************************************************************************** -; Source file for base system node on AtTiny 85 -; -; This is for the maintenance system (i.e. the flash loader). -; -; All definitions and changes should go into this file. -; -; -; *************************************************************************** - -.equ clock=1000000 ; Define the clock frequency - -.nolist -.include "include/tn85def.inc" ; Define device ATtiny85 -.list - -.include "./defs.asm" -.include "defs_all.asm" - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - -.include "common/utils_wait.asm" -.include "modules/com2/defs.asm" -.include "modules/comproto/defs.asm" - - -; --------------------------------------------------------------------------- -; firmware settings - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - -; --------------------------------------------------------------------------- -; LED - -.equ LED_DDR = DDRB -.equ LED_PORT = PORTB -.equ LED_PIN = PINB -.equ LED_PINNUM = PORTB3 - - - -; *************************************************************************** -; code segment - -.cseg -.org 0x0000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors - rjmp main ; Reset vector - reti ; EXT_INT0 - reti ; PCI0 - reti ; OC1A - reti ; OVF1 - reti ; OVF0 - reti ; ERDY - reti ; ACI - reti ; ADCC - reti ; OC1B - reti ; OC0A - reti ; OC0B - reti ; WATCHDOG - reti ; USI_STR - reti ; USI_OVF - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db DEVICEINFO_ID, 0 -devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main ; will be overwritten when flashing - - - -; *************************************************************************** -; main code - - -.org BOOTLOADER_ADDR - - -main: - rjmp bootLoader ; this routine is in modules/flash/proto.asm - - - - -; *************************************************************************** -; includes - -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" - -.include "modules/flash/defs.asm" -.include "modules/flash/eeprom.asm" -.include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" -.include "modules/flash/flash1p.asm" -.include "modules/flash/flashprocess.asm" -.include "modules/flash/wait.asm" -.include "modules/bootloader/main.asm" -.include "modules/network/msg/defs.asm" -.include "modules/network/msg/crc.asm" - - - -systemSetSpeed: -.if clock == 8000000 - ldi r16, (1< - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - boot.asm - - - - - - - - - - - defs.asm - - - - - - diff --git a/avr/devices/n19/boot.asm b/avr/devices/n19/boot.asm deleted file mode 100644 index d201486..0000000 --- a/avr/devices/n19/boot.asm +++ /dev/null @@ -1,140 +0,0 @@ -; *************************************************************************** -; Source file for base system node on AtTiny 85 -; -; This is for the maintenance system (i.e. the flash loader). -; -; All definitions and changes should go into this file. -; -; -; *************************************************************************** - -.equ clock=1000000 ; Define the clock frequency - -.nolist -.include "include/tn85def.inc" ; Define device ATtiny85 -.list - -.include "./defs.asm" -.include "defs_all.asm" - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - -.include "common/utils_wait.asm" -.include "modules/com2/defs.asm" -.include "modules/comproto/defs.asm" - - -; --------------------------------------------------------------------------- -; firmware settings - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - -; --------------------------------------------------------------------------- -; LED - -.equ LED_DDR = DDRB -.equ LED_PORT = PORTB -.equ LED_PIN = PINB -.equ LED_PINNUM = PORTB3 - - - -; *************************************************************************** -; code segment - -.cseg -.org 0x0000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors - rjmp main ; Reset vector - reti ; EXT_INT0 - reti ; PCI0 - reti ; OC1A - reti ; OVF1 - reti ; OVF0 - reti ; ERDY - reti ; ACI - reti ; ADCC - reti ; OC1B - reti ; OC0A - reti ; OC0B - reti ; WATCHDOG - reti ; USI_STR - reti ; USI_OVF - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db DEVICEINFO_ID, 0 -devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main ; will be overwritten when flashing - - - -; *************************************************************************** -; main code - - -.org BOOTLOADER_ADDR - - -main: - rjmp bootLoader ; this routine is in modules/flash/proto.asm - - - - -; *************************************************************************** -; includes - -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" - -.include "modules/flash/defs.asm" -.include "modules/flash/eeprom.asm" -.include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" -.include "modules/flash/flash1p.asm" -.include "modules/flash/flashprocess.asm" -.include "modules/flash/wait.asm" -.include "modules/bootloader/main.asm" -.include "modules/network/msg/defs.asm" -.include "modules/network/msg/crc.asm" - - - -systemSetSpeed: -.if clock == 8000000 - ldi r16, (1< - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - boot.asm - - - - - - - - - - - defs.asm - README - - - - - - diff --git a/avr/devices/n21/0BUILD b/avr/devices/n21/0BUILD index be449f6..8416b5b 100644 --- a/avr/devices/n21/0BUILD +++ b/avr/devices/n21/0BUILD @@ -11,7 +11,11 @@ defs.asm README - + + + aqua_n21.xml + + diff --git a/devices/nodes/aqua_n16.xml b/avr/devices/n21/aqua_n21.xml similarity index 77% rename from devices/nodes/aqua_n16.xml rename to avr/devices/n21/aqua_n21.xml index 11c8f22..f3ff989 100644 --- a/devices/nodes/aqua_n16.xml +++ b/avr/devices/n21/aqua_n21.xml @@ -1,17 +1,17 @@ - + AQUA N - 16 + 21 + - diff --git a/avr/devices/n21/boot/boot.asm b/avr/devices/n21/boot/boot.asm index c05a918..cd8ec3e 100644 --- a/avr/devices/n21/boot/boot.asm +++ b/avr/devices/n21/boot/boot.asm @@ -17,6 +17,7 @@ .include "devices/all/defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "common/utils_wait.asm" @@ -98,8 +99,7 @@ main: .include "modules/flash/defs.asm" .include "modules/flash/eeprom.asm" .include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" +.include "modules/flash/io_com2w.asm" .include "modules/flash/flash1p.asm" .include "modules/flash/flashxp.asm" .include "modules/flash/flashprocess.asm" diff --git a/avr/devices/n21/defs.asm b/avr/devices/n21/defs.asm index 2b5eb92..c4f08f2 100644 --- a/avr/devices/n21/defs.asm +++ b/avr/devices/n21/defs.asm @@ -17,7 +17,7 @@ ; PIR PB1 3 12 PA1 COM-DATA ; /RESET PB3 4 11 PA2 TCRT1000_Input ; AUX-B2 PB2 5 10 PA3 LED -; COM_ATTN PA7 6 9 PA4 TWI-SCL +; COM_CLK PA7 6 9 PA4 TWI-SCL ; TWI-SDA PA6 7 8 PA5 ; -------- ; @@ -48,6 +48,16 @@ +; --------------------------------------------------------------------------- +; LED activity module + +.equ LED_ACTIVITY_DDR = DDRA +.equ LED_ACTIVITY_PORT = PORTA +.equ LED_ACTIVITY_PORTIN = PINA +.equ LED_ACTIVITY_PINNUM = PORTA3 + + + ; --------------------------------------------------------------------------- ; COM module @@ -59,15 +69,15 @@ .equ COM_DATA_OUTPUT = PORTA .equ COM_DATA_PIN = PORTA1 -.equ COM_ATTN_DDR = DDRA -.equ COM_ATTN_INPUT = PINA -.equ COM_ATTN_OUTPUT = PORTA -.equ COM_ATTN_PIN = PORTA7 +.equ COM_CLK_DDR = DDRA +.equ COM_CLK_INPUT = PINA +.equ COM_CLK_OUTPUT = PORTA +.equ COM_CLK_PIN = PORTA7 -.equ COM_IRQ_ADDR_ATTN = PCMSK0 -.equ COM_IRQ_BIT_ATTN = PCINT7 ; bit 7 in PCMSK0 -.equ COM_IRQ_GIFR_ATTN = PCIF0 -.equ COM_IRQ_GIMSK_ATTN = PCIE0 +.equ COM_IRQ_ADDR_CLK = PCMSK0 +.equ COM_IRQ_BIT_CLK = PCINT7 ; bit 7 in PCMSK0 +.equ COM_IRQ_GIFR_CLK = PCIF0 +.equ COM_IRQ_GIMSK_CLK = PCIE0 diff --git a/avr/devices/n21/main/main.asm b/avr/devices/n21/main/main.asm index 15e3068..6b6639a 100644 --- a/avr/devices/n21/main/main.asm +++ b/avr/devices/n21/main/main.asm @@ -36,6 +36,7 @@ .include "devices/all/defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "common/utils_wait.asm" @@ -46,8 +47,9 @@ ; --------------------------------------------------------------------------- ; generic -.equ NET_BUFFERS_NUM = 6 -.equ NET_BUFFERS_SIZE = 32 +.equ NET_BUFFERS_NUM = 10 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) @@ -57,9 +59,10 @@ ; #define MODULES_TIMER #define MODULES_CLOCK -#define MODULES_LED_SIMPLE +;#define MODULES_LED_SIMPLE +#define MODULES_LED_ACTIVITY #define MODULES_NETWORK -#define MODULES_UART_BITBANG +#define MODULES_COM2W #define MODULES_TWI_MASTER ;#define MODULES_LCD ;#define LCD_MINIMAL_FONT @@ -112,7 +115,7 @@ ; rjmp main ; Reset vector rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system reti ; EXT_INT0 - rjmp UART_BitBang_PcintIsr ; PCI0 + rjmp com2wPcintIsr ; PCI0 reti ; PCI1 reti ; WATCHDOG reti ; ICP1 @@ -173,7 +176,6 @@ onMessageReceived: onEvery100ms: onEverySecond: -onEveryMinute: onEveryHour: onEveryDay: ret @@ -181,6 +183,15 @@ onEveryDay: +onEveryMinute: +; lds r16, tcrt1kLastValue +; ldi r17, VALUE_ID_ADC +; ldi r22, AQHOME_VALUETYPE_UNKNOWN ; VALUE TYPE +; rcall Main_Send8BitValueReport + ret + + + ; --------------------------------------------------------------------------- ; @routine onEveryLoop ; @@ -205,6 +216,6 @@ onEveryLoop: ; --------------------------------------------------------------------------- ; defines for network interface -.equ netInterfaceData = uart_bitbang_iface +.equ netInterfaceData = com2w_iface diff --git a/avr/devices/n22/.gitignore b/avr/devices/n22/.gitignore deleted file mode 100644 index 8e0618c..0000000 --- a/avr/devices/n22/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.eep.hex -*.obj diff --git a/avr/devices/n22/defs.asm b/avr/devices/n22/defs.asm deleted file mode 100644 index e42cb38..0000000 --- a/avr/devices/n22/defs.asm +++ /dev/null @@ -1,88 +0,0 @@ -; *************************************************************************** -; copyright : (C) 2024 by Martin Preuss -; email : martin@libchipcard.de -; -; *************************************************************************** -; * This file is part of the project "AqHome". * -; * Please see toplevel file COPYING of that project for license details. * -; *************************************************************************** - -; *************************************************************************** -; -; AtTiny85 -; -------- -; /RESET PB5 1 8 VCC -; OWI PB3 2 7 PB2 COM-ATTN -; LED PB4 3 6 PB1 COM-DATA -; GND 4 5 PB0 LEDSTRIP -; -------- -; -; *************************************************************************** - - - -.equ BOOTLOADER_ADDR = 0xd00 - - -.equ FIRMWARE_VARIANT_BOOT = 0 -.equ FIRMWARE_VARIANT_LEDSTRIPS = 1 - -.equ DEVICEINFO_ID = 'N' -.equ DEVICEINFO_VERSION = 22 -.equ DEVICEINFO_REVISION = 0 - - -; --------------------------------------------------------------------------- -; LED module - -.equ LED_SIMPLE_ONTIME = 1 -.equ LED_SIMPLE_OFFTIME = 50 -.equ LED_SIMPLE_DDR = DDRB -.equ LED_SIMPLE_PORT = PORTB -.equ LED_SIMPLE_PORTIN = PINB -.equ LED_SIMPLE_PINNUM = PORTB4 - - - -; --------------------------------------------------------------------------- -; COM module - -.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400 -.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter - -.equ COM_DATA_DDR = DDRB -.equ COM_DATA_INPUT = PINB -.equ COM_DATA_OUTPUT = PORTB -.equ COM_DATA_PIN = PORTB1 - -.equ COM_ATTN_DDR = DDRB -.equ COM_ATTN_INPUT = PINB -.equ COM_ATTN_OUTPUT = PORTB -.equ COM_ATTN_PIN = PORTB2 - -.equ COM_IRQ_ADDR_ATTN = PCMSK -.equ COM_IRQ_BIT_ATTN = PCINT2 ; bit 2 in PCMSK0 (PCINT2) -.equ COM_IRQ_GIFR_ATTN = PCIF -.equ COM_IRQ_GIMSK_ATTN = PCIE - - - -; --------------------------------------------------------------------------- -; 1-Wire Master -; - -.equ OWI_DDR = DDRB -.equ OWI_PORTOUT = PORTB -.equ OWI_PORTIN = PINB -.equ OWI_PINNUM = PORTB3 - - -; --------------------------------------------------------------------------- -; SK6812 - -.equ SK6812_DDR = DDRB -.equ SK6812_PORT = PORTB -.equ SK6812_PINNUM = PORTB0 - - - diff --git a/avr/devices/n23/.gitignore b/avr/devices/n23/.gitignore deleted file mode 100644 index 8e0618c..0000000 --- a/avr/devices/n23/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.eep.hex -*.obj diff --git a/avr/devices/n23/aqua_n23.xml b/avr/devices/n23/aqua_n23.xml deleted file mode 100644 index 0f049f9..0000000 --- a/avr/devices/n23/aqua_n23.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - AQUA - N - 23 - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/avr/devices/n24/README b/avr/devices/n24/README index 1fc1534..10328b6 100644 --- a/avr/devices/n24/README +++ b/avr/devices/n24/README @@ -5,6 +5,7 @@ N24 - Role: Air quality and climate sensors - MCU: AtTiny84 - Connection: RJ45 +- Predecessor: N23, N19 - Periphery: - PIR sensor (AMN31112) - TWI interface diff --git a/avr/devices/n24/aqua_n24.xml b/avr/devices/n24/aqua_n24.xml index 7552f11..489d1a1 100644 --- a/avr/devices/n24/aqua_n24.xml +++ b/avr/devices/n24/aqua_n24.xml @@ -5,26 +5,15 @@ 24 - - - - - - + + + + + + + - - - - - - - - - - - - - + diff --git a/avr/devices/n24/boot/boot.asm b/avr/devices/n24/boot/boot.asm index 767f207..f867d2b 100644 --- a/avr/devices/n24/boot/boot.asm +++ b/avr/devices/n24/boot/boot.asm @@ -26,6 +26,7 @@ .include "../defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "devices/all/defs.asm" @@ -122,8 +123,7 @@ main: .include "modules/flash/defs.asm" .include "modules/flash/eeprom.asm" .include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" +.include "modules/flash/io_com2w.asm" .include "modules/flash/flash1p.asm" .include "modules/flash/flashxp.asm" .include "modules/flash/flashprocess.asm" diff --git a/avr/devices/n24/defs.asm b/avr/devices/n24/defs.asm index 6c82232..1e7d5cb 100644 --- a/avr/devices/n24/defs.asm +++ b/avr/devices/n24/defs.asm @@ -13,11 +13,11 @@ ; AtTiny84 ; -------- ; VCC 1 14 GND -; AUX-PB0 PB0 2 13 PA0 AUX-PA0 +; AUX-PB0 PB0 2 13 PA0 LUM ; PIR PB1 3 12 PA1 COM-DATA ; /RESET PB3 4 11 PA2 AUX-PA2 ; PB2 5 10 PA3 LED -; COM_ATTN PA7 6 9 PA4 TWI-SCL +; COM_CLK PA7 6 9 PA4 TWI-SCL ; TWI-SDA PA6 7 8 PA5 ; -------- ; @@ -59,15 +59,15 @@ .equ COM_DATA_OUTPUT = PORTA .equ COM_DATA_PIN = PORTA1 -.equ COM_ATTN_DDR = DDRA -.equ COM_ATTN_INPUT = PINA -.equ COM_ATTN_OUTPUT = PORTA -.equ COM_ATTN_PIN = PORTA7 +.equ COM_CLK_DDR = DDRA +.equ COM_CLK_INPUT = PINA +.equ COM_CLK_OUTPUT = PORTA +.equ COM_CLK_PIN = PORTA7 -.equ COM_IRQ_ADDR_ATTN = PCMSK0 -.equ COM_IRQ_BIT_ATTN = PCINT7 ; bit 7 in PCMSK0 -.equ COM_IRQ_GIFR_ATTN = PCIF0 -.equ COM_IRQ_GIMSK_ATTN = PCIE0 +.equ COM_IRQ_ADDR_CLK = PCMSK0 +.equ COM_IRQ_BIT_CLK = PCINT7 ; bit 7 in PCMSK0 +.equ COM_IRQ_GIFR_CLK = PCIF0 +.equ COM_IRQ_GIMSK_CLK = PCIE0 @@ -146,3 +146,14 @@ +; --------------------------------------------------------------------------- +; Brightness + + +.equ BRIGHTNESS_ADC_PORT = PORTA ; adc0 +.equ BRIGHTNESS_ADC_DDR = DDRA +.equ BRIGHTNESS_ADC_PIN = PORTA0 +.equ BRIGHTNESS_ADC_MUX = 0 + + + diff --git a/avr/devices/n24/main/main.asm b/avr/devices/n24/main/main.asm index 2b0b7b7..242d8c7 100644 --- a/avr/devices/n24/main/main.asm +++ b/avr/devices/n24/main/main.asm @@ -36,6 +36,7 @@ .include "version.asm" .include "devices/all/defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "common/utils_wait.asm" @@ -46,8 +47,9 @@ ; --------------------------------------------------------------------------- ; generic -.equ NET_BUFFERS_NUM = 6 -.equ NET_BUFFERS_SIZE = 32 +.equ NET_BUFFERS_NUM = 6 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) .equ PROGRAM_SENSOR_INTERVAL_SECS = 60 .equ PROGRAM_STATS_INTERVAL_MINS = 10 @@ -61,7 +63,7 @@ #define MODULES_CLOCK #define MODULES_LED_SIMPLE #define MODULES_NETWORK -#define MODULES_UART_BITBANG +#define MODULES_COM2W #define MODULES_TWI_MASTER ;#define MODULES_LCD ;#define LCD_MINIMAL_FONT @@ -73,6 +75,7 @@ ;#define MODULES_DS18B20 #define MODULES_MOTION ;#define MODULES_CCS811 +#define MODULES_BRIGHTNESS #define APPS_NETWORK #define APPS_MOTION @@ -96,6 +99,8 @@ .equ VALUE_ID_SGP30_TVOC = 0x09 .equ VALUE_ID_SGP30_CO2 = 0x0a +.equ VALUE_ID_BRIGHTNESS = 0x0b + ;.equ VALUE_ID_REED_CONF = 0x81 .equ VALUE_ID_DEBUG = 0x7f @@ -120,7 +125,7 @@ ; rjmp main ; Reset vector rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system reti ; EXT_INT0 - rjmp UART_BitBang_PcintIsr ; PCI0 + rjmp com2wPcintIsr ; PCI0 reti ; PCI1 reti ; WATCHDOG reti ; ICP1 @@ -215,7 +220,7 @@ onEveryLoop: ; --------------------------------------------------------------------------- ; defines for network interface -.equ netInterfaceData = uart_bitbang_iface +.equ netInterfaceData = com2w_iface diff --git a/avr/devices/n25/aqua_n25.xml b/avr/devices/n25/aqua_n25.xml index 27a2a63..87b925a 100644 --- a/avr/devices/n25/aqua_n25.xml +++ b/avr/devices/n25/aqua_n25.xml @@ -5,29 +5,17 @@ 25 - + - - + + - - - - + + + + - - - - - - - - - - - - - + diff --git a/avr/devices/n25/boot/boot.asm b/avr/devices/n25/boot/boot.asm index d0987a0..df06de6 100644 --- a/avr/devices/n25/boot/boot.asm +++ b/avr/devices/n25/boot/boot.asm @@ -19,6 +19,7 @@ .include "devices/all/defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "common/utils_wait.asm" @@ -99,8 +100,7 @@ main: .include "modules/flash/defs.asm" .include "modules/flash/eeprom.asm" .include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" +.include "modules/flash/io_com2w.asm" .include "modules/flash/flashxp.asm" .include "modules/flash/flash1p.asm" .include "modules/flash/flashprocess.asm" diff --git a/avr/devices/n25/defs.asm b/avr/devices/n25/defs.asm index 093348b..fa508c6 100644 --- a/avr/devices/n25/defs.asm +++ b/avr/devices/n25/defs.asm @@ -16,8 +16,8 @@ ; PB1 3 12 PA1 COM-DATA ; PB3 4 11 PA2 ; PB2 5 10 PA3 LED -; COM_ATTN PA7 6 9 PA4 LED_CLK -; LED_DATA PA6 7 8 PA5 +; COM_CLK PA7 6 9 PA4 LED_CLK +; LED_DATA PA6 7 8 PA5 LED_Mode (0 for SPI) ; -------- ; ; *************************************************************************** @@ -58,15 +58,15 @@ .equ COM_DATA_OUTPUT = PORTA .equ COM_DATA_PIN = PORTA1 -.equ COM_ATTN_DDR = DDRA -.equ COM_ATTN_INPUT = PINA -.equ COM_ATTN_OUTPUT = PORTA -.equ COM_ATTN_PIN = PORTA7 +.equ COM_CLK_DDR = DDRA +.equ COM_CLK_INPUT = PINA +.equ COM_CLK_OUTPUT = PORTA +.equ COM_CLK_PIN = PORTA7 -.equ COM_IRQ_ADDR_ATTN = PCMSK0 -.equ COM_IRQ_BIT_ATTN = PCINT7 ; bit 7 in PCMSK0 (PCINT7) -.equ COM_IRQ_GIFR_ATTN = PCIF0 -.equ COM_IRQ_GIMSK_ATTN = PCIE0 +.equ COM_IRQ_ADDR_CLK = PCMSK0 +.equ COM_IRQ_BIT_CLK = PCINT7 ; bit 7 in PCMSK0 (PCINT7) +.equ COM_IRQ_GIFR_CLK = PCIF0 +.equ COM_IRQ_GIMSK_CLK = PCIE0 @@ -80,6 +80,16 @@ .equ OWI_PINNUM = PORTB0 + +; --------------------------------------------------------------------------- +; LED mode pin + +.equ LED_MODE_DDR = DDRA +.equ LED_MODE_PORTOUT = PORTA +.equ LED_MODE_PORTIN = PINA +.equ LED_MODE_PINNUM = PORTA5 + + ; --------------------------------------------------------------------------- ; SK6812 diff --git a/avr/devices/n25/main/main.asm b/avr/devices/n25/main/main.asm index 1cb6359..139400a 100644 --- a/avr/devices/n25/main/main.asm +++ b/avr/devices/n25/main/main.asm @@ -29,6 +29,7 @@ .include "devices/all/defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "common/utils_wait.asm" @@ -39,8 +40,9 @@ ; --------------------------------------------------------------------------- ; generic -.equ NET_BUFFERS_NUM = 6 -.equ NET_BUFFERS_SIZE = 32 +.equ NET_BUFFERS_NUM = 6 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) @@ -51,7 +53,7 @@ #define MODULES_CLOCK #define MODULES_LED_SIMPLE #define MODULES_NETWORK -#define MODULES_UART_BITBANG +#define MODULES_COM2W #define MODULES_OWI_MASTER #define MODULES_DS18B20 #define MODULES_SK6812 @@ -99,11 +101,7 @@ rjmp BOOTLOADER_ADDR ; 1: Reset vector ; use this for flashed system reti ; 2: EXT_INT0 -#ifdef MODULES_UART_BITBANG - rjmp UART_BitBang_PcintIsr ; 3: PCI0 -#else - reti ; 3: PCI0 -#endif + rjmp com2wPcintIsr ; 3: PCI0 reti ; 4: PCI1 reti ; 5: WDT reti ; 6: TIM1_CAPT @@ -208,9 +206,7 @@ onEveryLoop: ; --------------------------------------------------------------------------- ; defines for network interface -#ifdef MODULES_UART_BITBANG -.equ netInterfaceData = uart_bitbang_iface -#endif +.equ netInterfaceData = com2w_iface diff --git a/avr/devices/n00/.gitignore b/avr/devices/n26/.gitignore similarity index 100% rename from avr/devices/n00/.gitignore rename to avr/devices/n26/.gitignore diff --git a/avr/devices/n26/0BUILD b/avr/devices/n26/0BUILD new file mode 100644 index 0000000..8736df4 --- /dev/null +++ b/avr/devices/n26/0BUILD @@ -0,0 +1,22 @@ + + + + + + boot + main + + + + aqua_n26.xml + + + + defs.asm + README + + + + + + diff --git a/avr/devices/n26/README b/avr/devices/n26/README new file mode 100644 index 0000000..b39e95d --- /dev/null +++ b/avr/devices/n26/README @@ -0,0 +1,11 @@ + +N26 +=== + +- Role: Air quality sensors +- MCU: AtTiny84 +- Connection: RJ45 +- Periphery: + - TWI interface + - SGP-30/40 air quality sensor + diff --git a/avr/devices/n26/aqua_n26.xml b/avr/devices/n26/aqua_n26.xml new file mode 100644 index 0000000..c163295 --- /dev/null +++ b/avr/devices/n26/aqua_n26.xml @@ -0,0 +1,14 @@ + + + AQUA + N + 26 + + + + + + + + + diff --git a/avr/devices/n22/boot/0BUILD b/avr/devices/n26/boot/0BUILD similarity index 87% rename from avr/devices/n22/boot/0BUILD rename to avr/devices/n26/boot/0BUILD index 068003c..db6350e 100644 --- a/avr/devices/n22/boot/0BUILD +++ b/avr/devices/n26/boot/0BUILD @@ -2,7 +2,7 @@ - + -I $(builddir) diff --git a/avr/devices/n23/boot/boot.asm b/avr/devices/n26/boot/boot.asm similarity index 78% rename from avr/devices/n23/boot/boot.asm rename to avr/devices/n26/boot/boot.asm index 39bb493..f867d2b 100644 --- a/avr/devices/n23/boot/boot.asm +++ b/avr/devices/n26/boot/boot.asm @@ -1,3 +1,13 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + ; *************************************************************************** ; Source file for base system node on AtTiny 84 ; @@ -14,10 +24,10 @@ .include "version.asm" .include "../defs.asm" -.include "devices/all/defs.asm" .include "common/calls.asm" -.include "common/utils_wait.asm" +.include "common/utils_io.asm" +.include "devices/all/defs.asm" #define COM_ACCEPT_ALL_DEST @@ -27,6 +37,20 @@ ; *************************************************************************** ; defines +; --------------------------------------------------------------------------- +; generic + +.include "common/utils_wait.asm" +.include "modules/com2/defs.asm" +.include "modules/comproto/defs.asm" + + + +; --------------------------------------------------------------------------- +; firmware settings + + + ; --------------------------------------------------------------------------- ; LED @@ -99,8 +123,7 @@ main: .include "modules/flash/defs.asm" .include "modules/flash/eeprom.asm" .include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" +.include "modules/flash/io_com2w.asm" .include "modules/flash/flash1p.asm" .include "modules/flash/flashxp.asm" .include "modules/flash/flashprocess.asm" diff --git a/avr/devices/n17/n17_defs.asm b/avr/devices/n26/defs.asm similarity index 68% rename from avr/devices/n17/n17_defs.asm rename to avr/devices/n26/defs.asm index 6af27ce..6909188 100644 --- a/avr/devices/n17/n17_defs.asm +++ b/avr/devices/n26/defs.asm @@ -1,5 +1,5 @@ ; *************************************************************************** -; copyright : (C) 2023 by Martin Preuss +; copyright : (C) 2025 by Martin Preuss ; email : martin@libchipcard.de ; ; *************************************************************************** @@ -13,11 +13,11 @@ ; AtTiny84 ; -------- ; VCC 1 14 GND -; PB0 2 13 PA0 AUX-A0 -; PIR PB1 3 12 PA1 COM-DATA +; PB0 2 13 PA0 Brightness +; PB1 3 12 PA1 COM-DATA ; /RESET PB3 4 11 PA2 -; AUX-B2 PB2 5 10 PA3 LED -; COM_ATTN PA7 6 9 PA4 TWI-SCL +; PB2 5 10 PA3 LED +; COM_CLK PA7 6 9 PA4 TWI-SCL ; TWI-SDA PA6 7 8 PA5 ; -------- ; @@ -31,7 +31,7 @@ .equ FIRMWARE_VARIANT_TEMP_WINDOW = 1 .equ DEVICEINFO_ID = 'N' -.equ DEVICEINFO_VERSION = 17 +.equ DEVICEINFO_VERSION = 26 .equ DEVICEINFO_REVISION = 0 @@ -40,13 +40,22 @@ ; LED module .equ LED_SIMPLE_ONTIME = 1 ; shorter -.equ LED_SIMPLE_OFFTIME = 50 ; longer +.equ LED_SIMPLE_OFFTIME = 99 ; longer .equ LED_SIMPLE_DDR = DDRA .equ LED_SIMPLE_PORT = PORTA .equ LED_SIMPLE_PORTIN = PINA .equ LED_SIMPLE_PINNUM = PORTA3 +; --------------------------------------------------------------------------- +; LED Activity module + +.equ LED_ACTIVITY_DDR = DDRA +.equ LED_ACTIVITY_PORT = PORTA +.equ LED_ACTIVITY_PORTIN = PINA +.equ LED_ACTIVITY_PINNUM = PORTA3 + + ; --------------------------------------------------------------------------- ; COM module @@ -59,15 +68,15 @@ .equ COM_DATA_OUTPUT = PORTA .equ COM_DATA_PIN = PORTA1 -.equ COM_ATTN_DDR = DDRA -.equ COM_ATTN_INPUT = PINA -.equ COM_ATTN_OUTPUT = PORTA -.equ COM_ATTN_PIN = PORTA7 +.equ COM_CLK_DDR = DDRA +.equ COM_CLK_INPUT = PINA +.equ COM_CLK_OUTPUT = PORTA +.equ COM_CLK_PIN = PORTA7 -.equ COM_IRQ_ADDR_ATTN = PCMSK0 -.equ COM_IRQ_BIT_ATTN = PCINT7 ; bit 7 in PCMSK0 -.equ COM_IRQ_GIFR_ATTN = PCIF0 -.equ COM_IRQ_GIMSK_ATTN = PCIE0 +.equ COM_IRQ_ADDR_CLK = PCMSK0 +.equ COM_IRQ_BIT_CLK = PCINT7 ; bit 7 in PCMSK0 +.equ COM_IRQ_GIFR_CLK = PCIF0 +.equ COM_IRQ_GIMSK_CLK = PCIE0 @@ -90,38 +99,10 @@ ; --------------------------------------------------------------------------- -; LCD module +; SGB 30 -.equ LCD_TWI_ADDRESS = 0x3c +.equ SGP30_ADDR = 0x58 -; --------------------------------------------------------------------------- -; SI 7021 - -.equ SI7021_ADDR = 0x40 - - - -; --------------------------------------------------------------------------- -; 1-Wire Master -; - -.equ OWI_DDR = DDRB -.equ OWI_PORTOUT = PORTB -.equ OWI_PORTIN = PINB -.equ OWI_PINNUM = PORTB2 - - - -; --------------------------------------------------------------------------- -; Motion Sensor -; - -.equ MOTION_DDR = DDRB -.equ MOTION_INPUT = PINB -.equ MOTION_OUTPUT = PORTB -.equ MOTION_PIN = PORTB1 - - diff --git a/avr/devices/n23/main/0BUILD b/avr/devices/n26/main/0BUILD similarity index 86% rename from avr/devices/n23/main/0BUILD rename to avr/devices/n26/main/0BUILD index 5c8b3a6..da8fa0a 100644 --- a/avr/devices/n23/main/0BUILD +++ b/avr/devices/n26/main/0BUILD @@ -2,7 +2,7 @@ - + -I $(builddir) diff --git a/avr/devices/n23/main/data.asm b/avr/devices/n26/main/data.asm similarity index 100% rename from avr/devices/n23/main/data.asm rename to avr/devices/n26/main/data.asm diff --git a/avr/devices/n23/main/main.asm b/avr/devices/n26/main/main.asm similarity index 89% rename from avr/devices/n23/main/main.asm rename to avr/devices/n26/main/main.asm index f2f9b29..b35bdac 100644 --- a/avr/devices/n23/main/main.asm +++ b/avr/devices/n26/main/main.asm @@ -1,5 +1,5 @@ ; *************************************************************************** -; copyright : (C) 2024 by Martin Preuss +; copyright : (C) 2025 by Martin Preuss ; email : martin@libchipcard.de ; ; *************************************************************************** @@ -30,12 +30,13 @@ .include "include/tn84def.inc" ; Define device ATtiny84 .list -.include "version.asm" .include "../defs.asm" .include "./data.asm" +.include "version.asm" .include "devices/all/defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "common/utils_wait.asm" @@ -47,7 +48,8 @@ ; generic .equ NET_BUFFERS_NUM = 6 -.equ NET_BUFFERS_SIZE = 32 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) .equ PROGRAM_SENSOR_INTERVAL_SECS = 60 .equ PROGRAM_STATS_INTERVAL_MINS = 10 @@ -60,22 +62,24 @@ ; #define MODULES_TIMER #define MODULES_CLOCK #define MODULES_LED_SIMPLE +;#define MODULES_LED_ACTIVITY #define MODULES_NETWORK -#define MODULES_UART_BITBANG +;#define MODULES_UART_BITBANG +#define MODULES_COM2W #define MODULES_TWI_MASTER ;#define MODULES_LCD ;#define LCD_MINIMAL_FONT -#define MODULES_SI7021 +;#define MODULES_SI7021 #define MODULES_SGP30 ;#define MODULES_SGP40 ;#define MODULES_STATS ;#define MODULES_OWI_MASTER ;#define MODULES_DS18B20 -#define MODULES_MOTION +;#define MODULES_MOTION ;#define MODULES_CCS811 #define APPS_NETWORK -#define APPS_MOTION +;#define APPS_MOTION #define APPS_REPORTSENSORS #define APPS_STATS @@ -84,20 +88,9 @@ ; --------------------------------------------------------------------------- ; defines for values -.equ VALUE_ID_SI7021_TEMP = 0x01 -.equ VALUE_ID_SI7021_HUM = 0x02 - -.equ VALUE_ID_ADC = 0x03 -;.equ VALUE_ID_DS18B20_TEMP = 0x06 -.equ VALUE_ID_MOTION = 0x07 - -.equ VALUE_ID_SGP40_TVOC = 0x08 - .equ VALUE_ID_SGP30_TVOC = 0x09 .equ VALUE_ID_SGP30_CO2 = 0x0a -;.equ VALUE_ID_REED_CONF = 0x81 - .equ VALUE_ID_DEBUG = 0x7f .equ VALUE_ID_LEDSIMPLE_TIMING = 0x88 @@ -120,7 +113,7 @@ ; rjmp main ; Reset vector rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system reti ; EXT_INT0 - rjmp UART_BitBang_PcintIsr ; PCI0 + rjmp com2wPcintIsr ; PCI0 reti ; PCI1 reti ; WATCHDOG reti ; ICP1 @@ -215,7 +208,7 @@ onEveryLoop: ; --------------------------------------------------------------------------- ; defines for network interface -.equ netInterfaceData = uart_bitbang_iface +.equ netInterfaceData = com2w_iface diff --git a/avr/devices/n06/.gitignore b/avr/devices/n27/.gitignore similarity index 100% rename from avr/devices/n06/.gitignore rename to avr/devices/n27/.gitignore diff --git a/avr/devices/n27/0BUILD b/avr/devices/n27/0BUILD new file mode 100644 index 0000000..081044b --- /dev/null +++ b/avr/devices/n27/0BUILD @@ -0,0 +1,22 @@ + + + + + + boot + main + + + + aqua_n27.xml + + + + defs.asm + README + + + + + + diff --git a/avr/devices/n20/README b/avr/devices/n27/README similarity index 64% rename from avr/devices/n20/README rename to avr/devices/n27/README index 60505df..b878152 100644 --- a/avr/devices/n20/README +++ b/avr/devices/n27/README @@ -1,13 +1,13 @@ -N20 +N27 === -- Role: Air quality and climate sensors +- Role: Climate sensors - MCU: AtTiny84 - Connection: RJ45 +- Predecessor: N24, N23, N19 - Periphery: - PIR sensor (AMN31112) - TWI interface - SI7021 temperature and humidity sensor - - CCS811 air quality sensor - + diff --git a/avr/devices/n27/aqua_n27.xml b/avr/devices/n27/aqua_n27.xml new file mode 100644 index 0000000..5ec46d0 --- /dev/null +++ b/avr/devices/n27/aqua_n27.xml @@ -0,0 +1,16 @@ + + + AQUA + N + 27 + + + + + + + + + + + diff --git a/avr/devices/n27/boot/0BUILD b/avr/devices/n27/boot/0BUILD new file mode 100644 index 0000000..444ac6f --- /dev/null +++ b/avr/devices/n27/boot/0BUILD @@ -0,0 +1,32 @@ + + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + boot.asm + + + + + + + + + + + + + + + + diff --git a/avr/devices/n06/n06_boot.asm b/avr/devices/n27/boot/boot.asm similarity index 78% rename from avr/devices/n06/n06_boot.asm rename to avr/devices/n27/boot/boot.asm index cf83e97..f867d2b 100644 --- a/avr/devices/n06/n06_boot.asm +++ b/avr/devices/n27/boot/boot.asm @@ -1,3 +1,13 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + ; *************************************************************************** ; Source file for base system node on AtTiny 84 ; @@ -12,8 +22,15 @@ .include "include/tn84def.inc" ; Define device ATtiny84 .list -.include "./n06_defs.asm" -.include "defs_all.asm" +.include "version.asm" +.include "../defs.asm" + +.include "common/calls.asm" +.include "common/utils_io.asm" +.include "devices/all/defs.asm" + + +#define COM_ACCEPT_ALL_DEST @@ -32,10 +49,6 @@ ; --------------------------------------------------------------------------- ; firmware settings -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - ; --------------------------------------------------------------------------- @@ -96,8 +109,7 @@ firmwareStart: rjmp main ; will be overwritten when flashing main: - rjmp bootLoader ; this routine is in modules/flash/proto.asm - + rjmp bootLoader ; this routine is in modules/bootloader/main.asm @@ -111,15 +123,17 @@ main: .include "modules/flash/defs.asm" .include "modules/flash/eeprom.asm" .include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" +.include "modules/flash/io_com2w.asm" .include "modules/flash/flash1p.asm" +.include "modules/flash/flashxp.asm" .include "modules/flash/flashprocess.asm" .include "modules/flash/wait.asm" .include "modules/bootloader/main.asm" .include "modules/network/msg/defs.asm" .include "modules/network/msg/crc.asm" +;.include "common/debug.asm" + systemSetSpeed: @@ -140,3 +154,4 @@ systemSetSpeed: + diff --git a/avr/devices/n23/defs.asm b/avr/devices/n27/defs.asm similarity index 76% rename from avr/devices/n23/defs.asm rename to avr/devices/n27/defs.asm index 0373b4a..346503b 100644 --- a/avr/devices/n23/defs.asm +++ b/avr/devices/n27/defs.asm @@ -1,5 +1,5 @@ ; *************************************************************************** -; copyright : (C) 2023 by Martin Preuss +; copyright : (C) 2025 by Martin Preuss ; email : martin@libchipcard.de ; ; *************************************************************************** @@ -13,11 +13,11 @@ ; AtTiny84 ; -------- ; VCC 1 14 GND -; PB0 2 13 PA0 AUX-A0 +; AUX-PB0 PB0 2 13 PA0 LUM ; PIR PB1 3 12 PA1 COM-DATA -; /RESET PB3 4 11 PA2 -; AUX-B2 PB2 5 10 PA3 LED -; COM_ATTN PA7 6 9 PA4 TWI-SCL +; /RESET PB3 4 11 PA2 AUX-PA2 +; PB2 5 10 PA3 LED +; COM_CLK PA7 6 9 PA4 TWI-SCL ; TWI-SDA PA6 7 8 PA5 ; -------- ; @@ -31,7 +31,7 @@ .equ FIRMWARE_VARIANT_TEMP_WINDOW = 1 .equ DEVICEINFO_ID = 'N' -.equ DEVICEINFO_VERSION = 23 +.equ DEVICEINFO_VERSION = 27 .equ DEVICEINFO_REVISION = 0 @@ -40,7 +40,7 @@ ; LED module .equ LED_SIMPLE_ONTIME = 1 ; shorter -.equ LED_SIMPLE_OFFTIME = 50 ; longer +.equ LED_SIMPLE_OFFTIME = 99 ; longer .equ LED_SIMPLE_DDR = DDRA .equ LED_SIMPLE_PORT = PORTA .equ LED_SIMPLE_PORTIN = PINA @@ -48,6 +48,16 @@ +; --------------------------------------------------------------------------- +; LED Activity module + +.equ LED_ACTIVITY_DDR = DDRA +.equ LED_ACTIVITY_PORT = PORTA +.equ LED_ACTIVITY_PORTIN = PINA +.equ LED_ACTIVITY_PINNUM = PORTA3 + + + ; --------------------------------------------------------------------------- ; COM module @@ -59,15 +69,15 @@ .equ COM_DATA_OUTPUT = PORTA .equ COM_DATA_PIN = PORTA1 -.equ COM_ATTN_DDR = DDRA -.equ COM_ATTN_INPUT = PINA -.equ COM_ATTN_OUTPUT = PORTA -.equ COM_ATTN_PIN = PORTA7 +.equ COM_CLK_DDR = DDRA +.equ COM_CLK_INPUT = PINA +.equ COM_CLK_OUTPUT = PORTA +.equ COM_CLK_PIN = PORTA7 -.equ COM_IRQ_ADDR_ATTN = PCMSK0 -.equ COM_IRQ_BIT_ATTN = PCINT7 ; bit 7 in PCMSK0 -.equ COM_IRQ_GIFR_ATTN = PCIF0 -.equ COM_IRQ_GIMSK_ATTN = PCIE0 +.equ COM_IRQ_ADDR_CLK = PCMSK0 +.equ COM_IRQ_BIT_CLK = PCINT7 ; bit 7 in PCMSK0 +.equ COM_IRQ_GIFR_CLK = PCIF0 +.equ COM_IRQ_GIMSK_CLK = PCIE0 @@ -89,13 +99,6 @@ -; --------------------------------------------------------------------------- -; LCD module - -.equ LCD_TWI_ADDRESS = 0x3c - - - ; --------------------------------------------------------------------------- ; SI 7021 @@ -146,3 +149,14 @@ +; --------------------------------------------------------------------------- +; Brightness + + +.equ BRIGHTNESS_ADC_PORT = PORTA ; adc0 +.equ BRIGHTNESS_ADC_DDR = DDRA +.equ BRIGHTNESS_ADC_PIN = PORTA0 +.equ BRIGHTNESS_ADC_MUX = 0 + + + diff --git a/avr/devices/n27/main/0BUILD b/avr/devices/n27/main/0BUILD new file mode 100644 index 0000000..20ac543 --- /dev/null +++ b/avr/devices/n27/main/0BUILD @@ -0,0 +1,34 @@ + + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + main.asm + + + + + + + + + + + + data.asm + + + + + + diff --git a/avr/devices/n27/main/data.asm b/avr/devices/n27/main/data.asm new file mode 100644 index 0000000..31ccc2f --- /dev/null +++ b/avr/devices/n27/main/data.asm @@ -0,0 +1,14 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +.dseg + + diff --git a/avr/devices/n27/main/main.asm b/avr/devices/n27/main/main.asm new file mode 100644 index 0000000..dbaecad --- /dev/null +++ b/avr/devices/n27/main/main.asm @@ -0,0 +1,228 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + + +; *************************************************************************** +; Source file for temperature sensor node on AtTiny 84 +; +; This is for the full system (i.e. not the boot loader). +; +; All definitions and changes should go into this file. +; +; +; *************************************************************************** + + +.equ clock=1000000 ; Define the clock frequency +;.equ clock=8000000 ; Define the clock frequency + + + +.nolist +.include "include/tn84def.inc" ; Define device ATtiny84 +.list + +.include "../defs.asm" +.include "./data.asm" + +.include "version.asm" +.include "devices/all/defs.asm" +.include "common/calls.asm" +.include "common/utils_io.asm" +.include "common/utils_wait.asm" + + + +; *************************************************************************** +; defines + +; --------------------------------------------------------------------------- +; generic + +.equ NET_BUFFERS_NUM = 6 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) + +.equ PROGRAM_SENSOR_INTERVAL_SECS = 60 +.equ PROGRAM_STATS_INTERVAL_MINS = 10 + + + +; --------------------------------------------------------------------------- +; firmware settings including list of modules used + +; #define MODULES_TIMER +#define MODULES_CLOCK +#define MODULES_LED_SIMPLE +;#define MODULES_LED_ACTIVITY +#define MODULES_NETWORK +;#define MODULES_UART_BITBANG +#define MODULES_COM2W +#define MODULES_TWI_MASTER +;#define MODULES_LCD +;#define LCD_MINIMAL_FONT +#define MODULES_SI7021 +;#define MODULES_SGP30 +;#define MODULES_SGP40 +;#define MODULES_STATS +;#define MODULES_OWI_MASTER +;#define MODULES_DS18B20 +#define MODULES_MOTION +;#define MODULES_CCS811 +#define MODULES_BRIGHTNESS + +#define APPS_NETWORK +#define APPS_MOTION +#define APPS_REPORTSENSORS +#define APPS_STATS + + + +; --------------------------------------------------------------------------- +; defines for values + +.equ VALUE_ID_SI7021_TEMP = 0x01 +.equ VALUE_ID_SI7021_HUM = 0x02 + +.equ VALUE_ID_ADC = 0x03 +;.equ VALUE_ID_DS18B20_TEMP = 0x06 +.equ VALUE_ID_MOTION = 0x07 + +.equ VALUE_ID_SGP40_TVOC = 0x08 + +.equ VALUE_ID_SGP30_TVOC = 0x09 +.equ VALUE_ID_SGP30_CO2 = 0x0a + +.equ VALUE_ID_BRIGHTNESS = 0x0b + +;.equ VALUE_ID_REED_CONF = 0x81 + +.equ VALUE_ID_DEBUG = 0x7f + +.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88 + + + + + +; *************************************************************************** +; code segment + +.cseg +.org 000000 + + + +; --------------------------------------------------------------------------- +; Reset and interrupt vectors (will be removed as soon as we can flash data over COM) + +; rjmp main ; Reset vector + rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system + reti ; EXT_INT0 + rjmp com2wPcintIsr ; PCI0 + reti ; PCI1 + reti ; WATCHDOG + reti ; ICP1 + reti ; OC1A + reti ; OC1B + reti ; OVF1 + rjmp baseTimerIrqOC0A ; OC0A + reti ; OC0B + reti ; OVF0 + reti ; ACI + reti ; ADCC + reti ; ERDY + reti ; USI_STR + reti ; USI_OVF + + +devInfoBlock: ; 12 bytes +devInfoManufacturer: .db 'A', 'Q', 'U', 'A' +devInfoId: .db DEVICEINFO_ID, 0 +devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision +firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR + .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL + + + +; --------------------------------------------------------------------------- +; @routine firmwareStart @global + +firmwareStart: + rjmp main +; @end + + + +; --------------------------------------------------------------------------- +; @routine onSystemStart + +onSystemStart: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onMessageReceived +; +; Called on every message received + +onMessageReceived: + clc + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onEvery100ms +; +; Called every 100ms. Add your routine calls here. No arguments, no results. + +onEvery100ms: +onEverySecond: +onEveryMinute: +onEveryHour: +onEveryDay: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onEveryLoop +; +; Called on every loop (i.e. after awakening from sleep). +; +onEveryLoop: + ret +; @end + + + + + +; *************************************************************************** +; includes + +.include "devices/all/hw_tn84.asm" +.include "devices/all/includes.asm" + + + +; --------------------------------------------------------------------------- +; defines for network interface + +.equ netInterfaceData = com2w_iface + + + diff --git a/avr/devices/n11/.gitignore b/avr/devices/n28/.gitignore similarity index 100% rename from avr/devices/n11/.gitignore rename to avr/devices/n28/.gitignore diff --git a/avr/devices/n28/0BUILD b/avr/devices/n28/0BUILD new file mode 100644 index 0000000..a2d9bae --- /dev/null +++ b/avr/devices/n28/0BUILD @@ -0,0 +1,21 @@ + + + + + + boot + main + + + + defs.asm + README + + + + aqua_n28.xml + + + + + diff --git a/avr/devices/n23/README b/avr/devices/n28/README similarity index 52% rename from avr/devices/n23/README rename to avr/devices/n28/README index b1a7c94..c6733c4 100644 --- a/avr/devices/n23/README +++ b/avr/devices/n28/README @@ -1,13 +1,13 @@ -N23 +N28 === -- Role: Air quality and climate sensors +- Role: Door sensor with temp sensor - MCU: AtTiny84 - Connection: RJ45 +- Predecessor: N21, N16 - Periphery: - - PIR sensor (AMN31112) + - door sensor (TCRT1000) - TWI interface - SI7021 temperature and humidity sensor - - CCS811 air quality sensor - + \ No newline at end of file diff --git a/avr/devices/n28/aqua_n28.xml b/avr/devices/n28/aqua_n28.xml new file mode 100644 index 0000000..1c13607 --- /dev/null +++ b/avr/devices/n28/aqua_n28.xml @@ -0,0 +1,16 @@ + + + AQUA + N + 28 + + + + + + + + + + + diff --git a/avr/devices/n28/boot/0BUILD b/avr/devices/n28/boot/0BUILD new file mode 100644 index 0000000..95d031c --- /dev/null +++ b/avr/devices/n28/boot/0BUILD @@ -0,0 +1,32 @@ + + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + boot.asm + + + + + + + + + + + + + + + + diff --git a/avr/devices/n20/boot.asm b/avr/devices/n28/boot/boot.asm similarity index 96% rename from avr/devices/n20/boot.asm rename to avr/devices/n28/boot/boot.asm index 919d3d2..cd8ec3e 100644 --- a/avr/devices/n20/boot.asm +++ b/avr/devices/n28/boot/boot.asm @@ -13,10 +13,11 @@ .list .include "version.asm" -.include "./defs.asm" +.include "../defs.asm" .include "devices/all/defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "common/utils_wait.asm" @@ -24,6 +25,7 @@ ; *************************************************************************** ; defines + ; --------------------------------------------------------------------------- ; LED @@ -86,6 +88,7 @@ main: + ; *************************************************************************** ; includes @@ -96,8 +99,7 @@ main: .include "modules/flash/defs.asm" .include "modules/flash/eeprom.asm" .include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" +.include "modules/flash/io_com2w.asm" .include "modules/flash/flash1p.asm" .include "modules/flash/flashxp.asm" .include "modules/flash/flashprocess.asm" @@ -107,7 +109,6 @@ main: .include "modules/network/msg/crc.asm" - systemSetSpeed: .if clock == 8000000 ldi r16, (1< + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + main.asm + + + + + + + + + + + + data.asm + + + + + + diff --git a/avr/devices/n28/main/data.asm b/avr/devices/n28/main/data.asm new file mode 100644 index 0000000..31ccc2f --- /dev/null +++ b/avr/devices/n28/main/data.asm @@ -0,0 +1,14 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +.dseg + + diff --git a/avr/devices/n20/main.asm b/avr/devices/n28/main/main.asm similarity index 85% rename from avr/devices/n20/main.asm rename to avr/devices/n28/main/main.asm index 1f720e8..39a6848 100644 --- a/avr/devices/n20/main.asm +++ b/avr/devices/n28/main/main.asm @@ -1,5 +1,5 @@ ; *************************************************************************** -; copyright : (C) 2024 by Martin Preuss +; copyright : (C) 2025 by Martin Preuss ; email : martin@libchipcard.de ; ; *************************************************************************** @@ -31,10 +31,12 @@ .list .include "version.asm" -.include "./defs.asm" -.include "devices/all/defs.asm" +.include "../defs.asm" +.include "./data.asm" +.include "devices/all/defs.asm" .include "common/calls.asm" +.include "common/utils_io.asm" .include "common/utils_wait.asm" @@ -45,8 +47,10 @@ ; --------------------------------------------------------------------------- ; generic -.equ NET_BUFFERS_NUM = 4 -.equ NET_BUFFERS_SIZE = 32 +.equ NET_BUFFERS_NUM = 10 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) + @@ -55,9 +59,10 @@ ; #define MODULES_TIMER #define MODULES_CLOCK -#define MODULES_LED_SIMPLE +;#define MODULES_LED_SIMPLE +#define MODULES_LED_ACTIVITY #define MODULES_NETWORK -#define MODULES_UART_BITBANG +#define MODULES_COM2W #define MODULES_TWI_MASTER ;#define MODULES_LCD ;#define LCD_MINIMAL_FONT @@ -66,12 +71,12 @@ ;#define MODULES_OWI_MASTER ;#define MODULES_DS18B20 ;#define MODULES_MOTION -;#define MODULES_TCRT1000 +#define MODULES_TCRT1000 ;#define MODULES_CCS811 #define APPS_NETWORK ;#define APPS_MOTION -;#define APPS_DOOR +#define APPS_DOOR #define APPS_REPORTSENSORS #define APPS_STATS @@ -88,14 +93,10 @@ ;.equ VALUE_ID_REED2 = 0x05 ;.equ VALUE_ID_DS18B20_TEMP = 0x06 .equ VALUE_ID_MOTION = 0x07 - -.equ VALUE_ID_CO2 = 0x08 -.equ VALUE_ID_TVOC = 0x09 +.equ VALUE_ID_TCRT1K = 0x08 ;.equ VALUE_ID_REED_CONF = 0x81 -.equ VALUE_ID_DEBUG = 0x7f - .equ VALUE_ID_LEDSIMPLE_TIMING = 0x88 @@ -114,7 +115,7 @@ ; rjmp main ; Reset vector rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system reti ; EXT_INT0 - rjmp UART_BitBang_PcintIsr ; PCI0 + rjmp com2wPcintIsr ; PCI0 reti ; PCI1 reti ; WATCHDOG reti ; ICP1 @@ -175,7 +176,6 @@ onMessageReceived: onEvery100ms: onEverySecond: -onEveryMinute: onEveryHour: onEveryDay: ret @@ -183,6 +183,15 @@ onEveryDay: +onEveryMinute: +; lds r16, tcrt1kLastValue +; ldi r17, VALUE_ID_ADC +; ldi r22, AQHOME_VALUETYPE_UNKNOWN ; VALUE TYPE +; rcall Main_Send8BitValueReport + ret + + + ; --------------------------------------------------------------------------- ; @routine onEveryLoop ; @@ -202,21 +211,11 @@ onEveryLoop: .include "devices/all/hw_tn84.asm" .include "devices/all/includes.asm" -;.include "common/debug.asm" - - ; --------------------------------------------------------------------------- ; defines for network interface -.equ netInterfaceData = uart_bitbang_iface - - - - - - - +.equ netInterfaceData = com2w_iface diff --git a/avr/devices/r02/.gitignore b/avr/devices/r02/.gitignore deleted file mode 100644 index 8e0618c..0000000 --- a/avr/devices/r02/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.eep.hex -*.obj diff --git a/avr/devices/r02/0BUILD b/avr/devices/r02/0BUILD deleted file mode 100644 index c82f090..0000000 --- a/avr/devices/r02/0BUILD +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - boot.asm - - - - - - - - - - - defs.asm - - - - - - diff --git a/avr/devices/r02/boot.asm b/avr/devices/r02/boot.asm deleted file mode 100644 index 5fb6ebe..0000000 --- a/avr/devices/r02/boot.asm +++ /dev/null @@ -1,163 +0,0 @@ -; *************************************************************************** -; Source file for base system node on AtTiny 84 -; -; This is for the maintenance system (i.e. the flash loader). -; -; All definitions and changes should go into this file. -; *************************************************************************** - -.equ clock=1000000 ; Define the clock frequency - -.nolist -.include "include/tn841def.inc" ; Define device ATtiny841 -.list - -.include "./defs.asm" -.include "defs_all.asm" - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - -.include "common/utils_wait.asm" -.include "modules/com2/defs.asm" -.include "modules/comproto/defs.asm" - - - -; --------------------------------------------------------------------------- -; firmware settings - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - - -; --------------------------------------------------------------------------- -; LED - -.equ LED_DDR = DDRB -.equ LED_PORT = PORTB -.equ LED_PIN = PINB -.equ LED_PINNUM = PORTB2 - - -; *************************************************************************** -; code segment - -.cseg -.org 0x0000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors -; rjmp start ; Reset vector - rjmp main ; Reset vector - reti ; EXT_INT0 - reti ; PCI0 - reti ; PCI1 - reti ; WATCHDOG - reti ; ICP1 - reti ; OC1A - reti ; OC1B - reti ; OVF1 - reti ; OC0A - reti ; OC0B - reti ; OVF0 - reti ; ACI - reti ; ADCC - reti ; ERDY - reti ; USI_STR - reti ; USI_OVF - - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db 'R', 0 -devInfoVersion: .db 2, 0 ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main ; will be overwritten when flashing - - - -; *************************************************************************** -; main code - - -.org BOOTLOADER_ADDR - - -main: -; rjmp debugStop - rjmp bootLoader ; this routine is in modules/flash/proto.asm - - - - -; *************************************************************************** -; includes - -.include "modules/uart_bitbang/bytelevel.asm" -.include "modules/uart_bitbang/packetlevel.asm" -.include "modules/com2/crc.asm" -.include "common/crc8.asm" -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" -.include "modules/flash/bootloader.asm" -.include "modules/flash/flash.asm" -.include "modules/flash/recv.asm" -.include "modules/flash/send.asm" -.include "modules/flash/wait.asm" -.include "modules/flash/hdl_flash_start.asm" -.include "modules/flash/hdl_flash_data.asm" -.include "modules/flash/hdl_flash_end.asm" -.include "modules/flash/flash_rsp.asm" -.include "modules/flash/flash_ready.asm" - - -#if 1 -debugStop: - cli - sbi LED_SIMPLE_DDR, LED_SIMPLE_PINNUM ; out - cbi LED_SIMPLE_PORT, LED_SIMPLE_PINNUM ; on - - cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input - cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN - - ldi r18, 0 -test_loop1: - ldi r16, 100 -test_loop2: - ldi r17, 100 -test_loop3: - Utils_WaitNanoSecs 10000, 0, r22 - dec r17 - brne test_loop3 - dec r16 - brne test_loop2 - sbi LED_SIMPLE_PORTIN, LED_SIMPLE_PINNUM ; toggle - inc r18 - mov r19, r18 - andi r19, 1 - brne test1 - sbi COM_ATTN_DDR, COM_ATTN_PIN - cbi COM_ATTN_OUTPUT, COM_ATTN_PIN - rjmp test_loop1 -test1: - cbi COM_ATTN_DDR, COM_ATTN_PIN - cbi COM_ATTN_OUTPUT, COM_ATTN_PIN - - rjmp test_loop1 -#endif - - - diff --git a/avr/devices/r02/main.asm b/avr/devices/r02/main.asm deleted file mode 100644 index cd2e59c..0000000 --- a/avr/devices/r02/main.asm +++ /dev/null @@ -1,448 +0,0 @@ -; *************************************************************************** -; copyright : (C) 2024 by Martin Preuss -; email : martin@libchipcard.de -; -; *************************************************************************** -; * This file is part of the project "AqHome". * -; * Please see toplevel file COPYING of that project for license details. * -; *************************************************************************** - - - - -; *************************************************************************** -; Source file for temperature sensor node on AtTiny 84 -; -; This is for the full system (i.e. not the boot loader). -; -; All definitions and changes should go into this file. -; -; -; *************************************************************************** - - -.equ clock=1000000 ; Define the clock frequency -;.equ clock=8000000 ; Define the clock frequency - - - -.nolist -.include "include/tn841def.inc" ; Define device ATtiny841 -.list - -.include "./defs.asm" -.include "defs_all.asm" - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - - -.include "common/utils_wait.asm" - - -; --------------------------------------------------------------------------- -; firmware settings including list of modules used - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - -#define MODULES_TIMER -#define MODULES_COM -#define MODULES_COM_WITH_ADDR_PROTO -;#define MODULES_LED -#define MODULES_LED_SIMPLE -;#define MODULES_TWI_MASTER -;#define MODULES_LCD -#define LCD_MINIMAL_FONT -;#define MODULES_SI7021 -#define MODULES_STATS -;#define MODULES_CNY70 -;#define MODULES_REED -#define MODULES_OWI_MASTER -;#define MODULES_DS18B20 -;#define MODULES_MOTION - - - -; *************************************************************************** -; code segment - -.cseg -.org 000000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors (will be removed as soon as we can flash data over COM) - -; rjmp main ; Reset vector - rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system - reti ; EXT_INT0 - rjmp uartBitbangIsrPcint0 ; PCI0 - reti ; PCI1 - reti ; WATCHDOG - reti ; ICP1 - reti ; OC1A - reti ; OC1B - reti ; OVF1 - rjmp baseTimerIrqOC0A ; OC0A - reti ; OC0B - reti ; OVF0 - reti ; ACI - reti ; ADCC - reti ; ERDY - reti ; USI_STR - reti ; USI_OVF - - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db 'R', 0 -devInfoVersion: .db 2, 0 ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main - - -; *************************************************************************** -; includes - -.include "common/utils.asm" -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" -.include "common/crc8.asm" - -.include "modules/basetimer/main.asm" - -#ifdef MODULES_TIMER - .include "modules/timer/main.asm" -#endif -#ifdef MODULES_LED -.include "modules/led/main.asm" -#endif -#ifdef MODULES_LED_SIMPLE -.include "modules/led_simple/main.asm" -#endif -#ifdef MODULES_COM - .include "modules/com2/defs.asm" - .include "modules/com2/main.asm" - .include "modules/com2/buffer.asm" - .include "modules/uart_bitbang/defs.asm" - .include "modules/uart_bitbang/main.asm" - .include "modules/uart_bitbang/bytelevel.asm" - .include "modules/uart_bitbang/packetlevel.asm" - #ifdef MODULES_COM_WITH_ADDR_PROTO - .include "modules/comproto/defs.asm" - .include "modules/comproto/main.asm" - .include "modules/comproto/addr.asm" - .include "modules/comproto/msg_recvstats.asm" - .include "modules/comproto/msg_sendstats.asm" - .include "modules/comproto/msg_sysstats.asm" - .include "modules/comproto/msg_memstats.asm" - .include "modules/comproto/msg_pong.asm" - .include "modules/comproto/msg_value.asm" - .include "modules/comproto/msg_device.asm" - .include "modules/comproto/msg_reboot.asm" - #endif - #ifdef MODULES_LCD - .include "modules/com2/screen.asm" - .include "modules/comproto/screen.asm" - #endif -#endif -#ifdef MODULES_TWI_MASTER - .include "modules/twimaster/main.asm" -#endif -#ifdef MODULES_OWI_MASTER - .include "modules/owimaster/main.asm" -#endif -#ifdef MODULES_LCD - .include "modules/lcd/main.asm" -#endif -#ifdef MODULES_SI7021 - .include "modules/si7021/main.asm" -#endif -#ifdef MODULES_DS18B20 - .include "modules/ds18b20/main.asm" -#endif -#ifdef MODULES_STATS - .include "modules/stats/main.asm" -#endif -#ifdef MODULES_CNY70 - .include "modules/cny70/main.asm" -#endif -#ifdef MODULES_REED - .include "modules/reed/main.asm" -#endif - -#ifdef MODULES_MOTION - .include "modules/motion/main.asm" -#endif - -; test -;#include "modules/uart_irq/defs.asm" -;#include "modules/uart_irq/iface.asm" -;#include "modules/uart_irq/iface1.asm" - - -; *************************************************************************** -; data in SRAM - -.dseg - -programRamBegin: -#ifdef MODULES_LCD - screenCounter: .byte 1 -#endif - -programRamEnd: - - - -#ifdef MODULES_LCD - sramTimerWriteStats: .byte 2 - sramTimerScreen: .byte 2 -#endif -#ifdef MODULES_SI7021 - sramTimerSI7021Measure: .byte 2 - sramTimerSI7021SendTemp: .byte 2 - sramTimerSI7021SendHumidity: .byte 2 -#endif -#ifdef MODULES_CNY70 - sramTimerCny70SendAdc: .byte 2 -#endif -#ifdef MODULES_LCD - sramPeriodicalLcdMark: .byte 2 -#endif -#ifdef MODULES_DS18B20 - sramDs18b20Timer: .byte 2 - sramSendDs18b20TempTimer: .byte 2 -#endif - - -; *************************************************************************** -; data in FLASH - -.cseg - - - -; --------------------------------------------------------------------------- -; timer list - - -timerList: -; SRAM variable/counter routine flags secs (0=don't start or restart) -#ifdef MODULES_COM_WITH_ADDR_PROTO - .dw cproAddresModeTimer, CPRO_Address_OnTimer, 0, 0 ; (no restart) -#endif -#ifdef MODULES_STATS - .dw statsSendTimer, Stats_Timer, TIMER_FLAGS_IF_ADDR, 9000 ; every 15m -#endif -#ifdef MODULES_LCD -; .dw sramPeriodicalLcdMark, periodicalLcdMark, 0, 20 ; every 2s -; .dw sramTimerWriteStats, writeStats, 0, 100 - .dw sramTimerScreen, printScreen, TIMER_FLAGS_IF_ADDR, 50 ; every 5s -#endif -#ifdef MODULES_SI7021 - .dw sramTimerSI7021Measure, SI7021_OnTimer, 0, 300 ; every 30s - .dw sramTimerSI7021SendTemp, sendSI7021Temp, TIMER_FLAGS_IF_ADDR, 600 ; every 60s - .dw sramTimerSI7021SendHumidity, sendSI7021Humidity, TIMER_FLAGS_IF_ADDR, 600 ; every 60s -#endif -#ifdef MODULES_CNY70 - .dw sramTimerCny70SendAdc, CNY70_OnTimer, TIMER_FLAGS_IF_ADDR, 50 ; every 5s -#endif -#ifdef MODULES_DS18B20 - .dw sramDs18b20Timer, Ds18b20_OnTimer, 0, 300 ; every 30s - .dw sramSendDs18b20TempTimer, sendDs18b20Temp, TIMER_FLAGS_IF_ADDR, 600 ; every 60s -#endif - .dw 0 ; end of list - - - - - -.include "main_all.asm" - - - -systemSetSpeed: -.if clock == 8000000 - ldi r16, (1< + + + + + boot + main + test + + + + defs.asm + README + + + + aqua_r05.xml + + + + + + diff --git a/avr/devices/r05/README b/avr/devices/r05/README new file mode 100644 index 0000000..004d17a --- /dev/null +++ b/avr/devices/r05/README @@ -0,0 +1,13 @@ + +R05 +=== + +- Role: Router +- MCU: AtTiny841 +- Connection: RJ45 +- Predecessor: R04 +- UART: comonuart0 (uart_hw2), comonuart1 (uart_hw2) +- Periphery: + - OWI interface + - DS18B20 temperature sensor + diff --git a/avr/devices/r05/aqua_r05.xml b/avr/devices/r05/aqua_r05.xml new file mode 100644 index 0000000..f03902f --- /dev/null +++ b/avr/devices/r05/aqua_r05.xml @@ -0,0 +1,14 @@ + + + AQUA + R + 5 + + + + + + + + + diff --git a/avr/devices/r05/boot/0BUILD b/avr/devices/r05/boot/0BUILD new file mode 100644 index 0000000..3a65629 --- /dev/null +++ b/avr/devices/r05/boot/0BUILD @@ -0,0 +1,32 @@ + + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + boot.asm + + + + + + + + + + + + + + + + diff --git a/avr/devices/r05/boot/boot.asm b/avr/devices/r05/boot/boot.asm new file mode 100644 index 0000000..d86fa14 --- /dev/null +++ b/avr/devices/r05/boot/boot.asm @@ -0,0 +1,151 @@ +; *************************************************************************** +; Source file for base system node on AtTiny 84 +; +; This is for the maintenance system (i.e. the flash loader). +; +; All definitions and changes should go into this file. +; *************************************************************************** + +;.equ clock=1000000 ; Define the clock frequency +.equ clock=8000000 ; Define the clock frequency + +.nolist +.include "include/tn841def.inc" ; Define device ATtiny841 +.list + +.include "version.asm" +.include "../defs.asm" +.include "devices/all/defs.asm" + +.include "common/calls.asm" +.include "common/utils_wait.asm" + + + +; *************************************************************************** +; defines + + +;#define COM_ACCEPT_ALL_DEST 1 + + + +; --------------------------------------------------------------------------- +; LED + +.equ LED_DDR = DDRB +.equ LED_PORT = PORTB +.equ LED_PIN = PINB +.equ LED_PINNUM = PORTB2 + + +; *************************************************************************** +; code segment + +.cseg +.org 0x0000 + + + +; --------------------------------------------------------------------------- +; Reset and interrupt vectors + + rjmp main ; 1: RESET Reset vector use this for flashed system + reti ; 2: INT0 External Interrupt Request 0 + reti ; 3: PCINT0 Pin Change Interrupt 0 + reti ; 4: PCINT1 Pin Change Interrupt 1 + reti ; 5: WDT Watchdog Time-out + reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event + reti ; 7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A + reti ; 8: TIM1_COMPB (OC1B) Timer/Counter1 Compare Match B + reti ; 9: TIM1_OVF (OVF1) Timer/Counter1 Overflow + reti ; 10: TIM0_COMPA (OC0A) Timer/Counter0 Compare Match A + reti ; 11: TIM0_COMPB (OC0B) Timer/Counter0 Compare Match B + reti ; 12: TIM0_OVF (OVF0) Timer/Counter0 Overflow + reti ; 13: ANA_COMP0 Analog Comparator 0 + reti ; 14: ADC_READY ADC Conversion Complete + reti ; 15: EE_RDY (ERDY) EEPROM Ready + reti ; 16: ANA_COMP1 Analog Comparator 1 + reti ; 17: TIM2_CAPT Timer/Counter2 Capture Event + reti ; 18: TIM2_COMPA (OC2A) Timer/Counter2 Compare Match A + reti ; 19: TIM2_COMPB (OC2B) Timer/Counter2 Compare Match B + reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow + reti ; 21: SPI SPI Serial Transfer Complete + reti ; 22: USART0_RXS USART0 Rx Start + reti ; 23: USART0_RXC USART0 Rx Complete + reti ; 24: USART0_DRE USART0 Data Register Empty + reti ; 25: USART0_TXC USART0 Tx Complete + reti ; 26: USART1_RXS USART1 Rx Start + reti ; 27: USART1_RXC USART1 Rx Complete + reti ; 28: USART1_DRE USART1 Data Register Empty + reti ; 29: USART1_TXC USART1 Tx Complete + reti ; 30: TWI Two-Wire-Interface + reti ; 31: RESERVED reserved + + + +devInfoBlock: ; 12 bytes +devInfoManufacturer: .db 'A', 'Q', 'U', 'A' +devInfoId: .db DEVICEINFO_ID, 0 +devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision +firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR + .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL + +firmwareStart: + rjmp main ; will be overwritten when flashing + + + +; *************************************************************************** +; main code + + +.org BOOTLOADER_ADDR + + +main: + rjmp bootLoader ; this routine is in modules/bootloader/main.asm + + + + +; *************************************************************************** +; includes + +.include "common/utils_wait_fixed.asm" +.include "common/utils_copy_from_flash.asm" +.include "common/utils_copy_sdram.asm" + +.include "modules/flash/defs.asm" +.include "modules/flash/eeprom.asm" +.include "modules/flash/io.asm" +.include "modules/flash/io_attn.asm" +.include "modules/flash/io_bitbang.asm" +.include "modules/flash/flashxp.asm" +.include "modules/flash/flash4p.asm" +.include "modules/flash/flashprocess.asm" +.include "modules/flash/wait.asm" +.include "modules/bootloader/main.asm" +.include "modules/network/msg/defs.asm" +.include "modules/network/msg/crc.asm" + + + +systemSetSpeed: +.if clock == 1000000 + ldi r17, 0xd8 + ldi r16, (1< + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + main.asm + + + + + + + + + + + + + + + + + diff --git a/avr/devices/r05/main/main.asm b/avr/devices/r05/main/main.asm new file mode 100644 index 0000000..01ec7f5 --- /dev/null +++ b/avr/devices/r05/main/main.asm @@ -0,0 +1,220 @@ +; *************************************************************************** +; copyright : (C) 2024 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + + +; *************************************************************************** +; Source file for temperature sensor node on AtTiny 84 +; +; This is for the full system (i.e. not the boot loader). +; +; All definitions and changes should go into this file. +; +; +; *************************************************************************** + + +;.equ clock=1000000 ; Define the clock frequency +.equ clock=8000000 ; Define the clock frequency + +;#define WITH_LCD + +.nolist +.include "include/tn841def.inc" ; Define device ATtiny841 +.list + +.include "../defs.asm" +.include "version.asm" +;.include "defs_all.asm" + +.include "devices/all/defs.asm" + +.include "common/calls.asm" +.include "common/utils_wait.asm" +.include "common/utils_io.asm" + + + +; *************************************************************************** +; defines + +; --------------------------------------------------------------------------- +; generic + +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) + + +; --------------------------------------------------------------------------- +; firmware settings including list of modules used + + +#define MAIN_WITHOUT_MSG_HANDLING ; message handling in AppRouter! +#define APP_STATS_NETDEV2 ; send stats for 2nd device +#define COM_ACCEPT_ALL_DEST ; accept all messages! + +#define MODULES_CLOCK +#define MODULES_LED_SIMPLE +#ifdef WITH_LCD + #define MODULES_TWI_MASTER ; using TWI display for debugging + #define MODULES_LCD + #define LCD_MINIMAL_FONT +#else ; decrease code when using display +; #define MODULES_OWI_MASTER +; #define MODULES_DS18B20 + #define APPS_STATS +#endif +#define MODULES_NETWORK +#define MODULES_COMONUART0 +;#define MODULES_COMONUART1 +#define MODULES_COM2W1 +;#define APPS_NETWORK +#define APPS_ROUTER + + +.equ NET_BUFFERS_NUM = 10 + + + +; --------------------------------------------------------------------------- +; defines for values + +.equ VALUE_ID_DS18B20_TEMP = 0x06 + +.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88 +.equ VALUE_ID_ROUTER_SETRANGE = 0x89 + + +; *************************************************************************** +; code segment + +.cseg +.org 000000 + + + +; --------------------------------------------------------------------------- +; Reset and interrupt vectors + + rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system + reti ; 2: INT0 External Interrupt Request 0 + rjmp ComOnUart0_AttnChangeIsr ; 3: PCINT0 Pin Change Interrupt 0 + rjmp COM2W1_ClkChangeIsr ; 4: PCINT1 Pin Change Interrupt 1 + reti ; 5: WDT Watchdog Time-out + reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event + reti ; 7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A + reti ; 8: TIM1_COMPB (OC1B) Timer/Counter1 Compare Match B + reti ; 9: TIM1_OVF (OVF1) Timer/Counter1 Overflow + rjmp baseTimerIrqOC0A ; 10: TIM0_COMPA (OC0A) Timer/Counter0 Compare Match A + reti ; 11: TIM0_COMPB (OC0B) Timer/Counter0 Compare Match B + reti ; 12: TIM0_OVF (OVF0) Timer/Counter0 Overflow + reti ; 13: ANA_COMP0 Analog Comparator 0 + reti ; 14: ADC_READY ADC Conversion Complete + reti ; 15: EE_RDY (ERDY) EEPROM Ready + reti ; 16: ANA_COMP1 Analog Comparator 1 + reti ; 17: TIM2_CAPT Timer/Counter2 Capture Event + reti ; 18: TIM2_COMPA (OC2A) Timer/Counter2 Compare Match A + reti ; 19: TIM2_COMPB (OC2B) Timer/Counter2 Compare Match B + reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow + reti ; 21: SPI SPI Serial Transfer Complete + reti ; 22: USART0_RXS USART0 Rx Start + rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete + reti ; 24: USART0_DRE USART0 Data Register Empty + reti ; 25: USART0_TXC USART0 Tx Complete + reti ; 26: USART1_RXS USART1 Rx Start + reti ; 27: USART1_RXC USART1 Rx Complete + reti ; 28: USART1_DRE USART1 Data Register Empty + reti ; 29: USART1_TXC USART1 Tx Complete + reti ; 30: TWI Two-Wire-Interface + reti ; 31: RESERVED reserved + + + +devInfoBlock: ; 12 bytes +devInfoManufacturer: .db 'A', 'Q', 'U', 'A' +devInfoId: .db DEVICEINFO_ID, 0 +devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision +firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR + .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL + + + +; --------------------------------------------------------------------------- +; @routine firmwareStart @global + +firmwareStart: + rjmp main +; @end + + + +; --------------------------------------------------------------------------- +; @routine onSystemStart + +onSystemStart: + ret +; @end + + + + + + + +onEvery100ms: +onEverySecond: +onEveryMinute: +onEveryHour: +onEveryDay: + ret + + + +; --------------------------------------------------------------------------- +; @routine onEveryLoop +; +; Called on every loop (i.e. after awakening from sleep). + +onEveryLoop: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onMessageReceived +; +; Called on every message received + +onMessageReceived: + clc + ret +; @end + + + + +; *************************************************************************** +; includes + +.include "devices/all/hw_tn841.asm" +.include "devices/all/includes.asm" + + + + +; --------------------------------------------------------------------------- +; defines for network interface + +.equ netInterfaceData = comOnUart0_iface +.equ netInterfaceData2 = com2w1_iface + + + diff --git a/avr/devices/r05/test/0BUILD b/avr/devices/r05/test/0BUILD new file mode 100644 index 0000000..809ed0f --- /dev/null +++ b/avr/devices/r05/test/0BUILD @@ -0,0 +1,33 @@ + + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + main.asm + + + + + + + + + + + + + + + + + diff --git a/avr/devices/r05/test/main.asm b/avr/devices/r05/test/main.asm new file mode 100644 index 0000000..3a090fc --- /dev/null +++ b/avr/devices/r05/test/main.asm @@ -0,0 +1,244 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + + +; *************************************************************************** +; Source file for temperature sensor node on AtTiny 84 +; +; This is for the full system (i.e. not the boot loader). +; +; All definitions and changes should go into this file. +; +; +; *************************************************************************** + + +;.equ clock=1000000 ; Define the clock frequency +.equ clock=8000000 ; Define the clock frequency + + +.nolist +.include "include/tn841def.inc" ; Define device ATtiny841 +.list + +.include "../defs.asm" +.include "version.asm" +;.include "defs_all.asm" + +.include "devices/all/defs.asm" + +.include "common/calls.asm" +.include "common/utils_wait.asm" +.include "common/utils_io.asm" + + + +; *************************************************************************** +; defines + +; --------------------------------------------------------------------------- +; generic + +.equ COMONUART0_IFACENUM = 1 +.equ COMONUART1_IFACENUM = 2 + +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) + + +; --------------------------------------------------------------------------- +; firmware settings including list of modules used + + +;#define MAIN_WITHOUT_MSG_HANDLING ; we do message handling ourselfes +;#define APP_STATS_NETDEV2 +#define COM_ACCEPT_ALL_DEST ; accept all messages! + +#define MODULES_CLOCK +;#define MODULES_COM +;#define MODULES_COM_WITH_ADDR_PROTO +;#define MODULES_LED +#define MODULES_LED_SIMPLE +;#define MODULES_TWI_MASTER +;#define MODULES_LCD +;#define LCD_MINIMAL_FONT +;#define MODULES_SI7021 +;#define MODULES_STATS +;#define MODULES_CNY70 +;#define MODULES_REED +#define MODULES_OWI_MASTER +#define MODULES_DS18B20 +;#define MODULES_MOTION +#define MODULES_NETWORK +;#define MODULES_TTYONUART1 +#define MODULES_COMONUART0 +;#define MODULES_COMONUART1 + +#define APPS_STATS +#define APPS_NETWORK +#define APPS_REPORTSENSORS + + + +.equ NET_BUFFERS_NUM = 8 + +.equ UART_HW_MSGNUMINBUF_SIZE = 8 +.equ UART_HW_MSGNUMOUTBUF_SIZE = 8 + + + +; --------------------------------------------------------------------------- +; defines for values + +.equ VALUE_ID_DS18B20_TEMP = 0x06 + +.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88 + + +; *************************************************************************** +; code segment + +.cseg +.org 000000 + + + +; --------------------------------------------------------------------------- +; Reset and interrupt vectors + + rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system + reti ; 2: INT0 External Interrupt Request 0 + rjmp ComOnUart0_AttnChangeIsr ; 3: PCINT0 Pin Change Interrupt 0 +; reti ; 3: PCINT0 Pin Change Interrupt 0 +; rjmp ComOnUart1_AttnChangeIsr ; 4: PCINT1 Pin Change Interrupt 1 + reti ; 4: PCINT1 Pin Change Interrupt 1 + reti ; 5: WDT Watchdog Time-out + reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event + reti ; 7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A + reti ; 8: TIM1_COMPB (OC1B) Timer/Counter1 Compare Match B + reti ; 9: TIM1_OVF (OVF1) Timer/Counter1 Overflow + rjmp baseTimerIrqOC0A ; 10: TIM0_COMPA (OC0A) Timer/Counter0 Compare Match A + reti ; 11: TIM0_COMPB (OC0B) Timer/Counter0 Compare Match B + reti ; 12: TIM0_OVF (OVF0) Timer/Counter0 Overflow + reti ; 13: ANA_COMP0 Analog Comparator 0 + reti ; 14: ADC_READY ADC Conversion Complete + reti ; 15: EE_RDY (ERDY) EEPROM Ready + reti ; 16: ANA_COMP1 Analog Comparator 1 + reti ; 17: TIM2_CAPT Timer/Counter2 Capture Event + reti ; 18: TIM2_COMPA (OC2A) Timer/Counter2 Compare Match A + reti ; 19: TIM2_COMPB (OC2B) Timer/Counter2 Compare Match B + reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow + reti ; 21: SPI SPI Serial Transfer Complete + reti ; 22: USART0_RXS USART0 Rx Start + rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete +; reti ; 23: USART0_RXC USART0 Rx Complete +; rjmp ComOnUart0_TxUdreIsr ; 24: USART0_DRE USART0 Data Register Empty + reti ; 24: USART0_DRE USART0 Data Register Empty +; rjmp ComOnUart0_TxCharIsr ; 25: USART0_TXC USART0 Tx Complete + reti ; 25: USART0_TXC USART0 Tx Complete + reti ; 26: USART1_RXS USART1 Rx Start +; rjmp ComOnUart1_RxCharIsr ; 27: USART1_RXC USART1 Rx Complete + reti ; 27: USART1_RXC USART1 Rx Complete + reti ; 28: USART1_DRE USART1 Data Register Empty + reti ; 29: USART1_TXC USART1 Tx Complete + reti ; 30: TWI Two-Wire-Interface + reti ; 31: RESERVED reserved + + + +devInfoBlock: ; 12 bytes +devInfoManufacturer: .db 'A', 'Q', 'U', 'A' +devInfoId: .db DEVICEINFO_ID, 0 +devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision +firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR + .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL + + + +; --------------------------------------------------------------------------- +; @routine firmwareStart @global + +firmwareStart: + rjmp main +; @end + + + +; --------------------------------------------------------------------------- +; @routine onSystemStart + +onSystemStart: + ; set interface number for UART0 + ldi r16, COMONUART0_IFACENUM + sts comOnUart0_iface+NET_IFACE_OFFS_IFACENUM, r16 + ; set interface number for UART1 +; ldi r16, COMONUART1_IFACENUM +; sts comOnUart1_iface+NET_IFACE_OFFS_IFACENUM, r16 + + ret +; @end + + + + + + + +onEvery100ms: +onEverySecond: +onEveryMinute: +onEveryHour: +onEveryDay: + ret + + + + +; --------------------------------------------------------------------------- +; @routine onEveryLoop +; +; Called on every loop (i.e. after awakening from sleep). + +onEveryLoop: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onMessageReceived +; +; Called on every message received + +onMessageReceived: + clc + ret +; @end + + + +; *************************************************************************** +; includes + +.include "devices/all/hw_tn841.asm" +.include "devices/all/includes.asm" + +.include "common/debug.asm" + + + +; --------------------------------------------------------------------------- +; defines for network interface + +.equ netInterfaceData = comOnUart0_iface +;.equ netInterfaceData2 = comOnUart1_iface + + diff --git a/avr/devices/n15/.gitignore b/avr/devices/r06/.gitignore similarity index 100% rename from avr/devices/n15/.gitignore rename to avr/devices/r06/.gitignore diff --git a/avr/devices/r06/0BUILD b/avr/devices/r06/0BUILD new file mode 100644 index 0000000..ef47309 --- /dev/null +++ b/avr/devices/r06/0BUILD @@ -0,0 +1,22 @@ + + + + + + boot + main + + + + aqua_r06.xml + + + + defs.asm + README + + + + + + diff --git a/avr/devices/r06/README b/avr/devices/r06/README new file mode 100644 index 0000000..684bdcc --- /dev/null +++ b/avr/devices/r06/README @@ -0,0 +1,11 @@ + +R06 +=== + +- Role: Router +- MCU: AtTiny841 +- Connection: RJ45 +- Predecessor: R05, R04 +- COM: com2wg +- Periphery: + - TWI interface diff --git a/avr/devices/r06/aqua_r06.xml b/avr/devices/r06/aqua_r06.xml new file mode 100644 index 0000000..212b756 --- /dev/null +++ b/avr/devices/r06/aqua_r06.xml @@ -0,0 +1,11 @@ + + + AQUA + R + 6 + + + + + + diff --git a/avr/devices/r06/boot/0BUILD b/avr/devices/r06/boot/0BUILD new file mode 100644 index 0000000..ebf4780 --- /dev/null +++ b/avr/devices/r06/boot/0BUILD @@ -0,0 +1,32 @@ + + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + boot.asm + + + + + + + + + + + + + + + + diff --git a/avr/devices/n12/n12_boot.asm b/avr/devices/r06/boot/boot.asm similarity index 74% rename from avr/devices/n12/n12_boot.asm rename to avr/devices/r06/boot/boot.asm index 58f20d8..de9617c 100644 --- a/avr/devices/n12/n12_boot.asm +++ b/avr/devices/r06/boot/boot.asm @@ -1,11 +1,19 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + ; *************************************************************************** ; Source file for base system node on AtTiny 84 ; ; This is for the maintenance system (i.e. the flash loader). ; ; All definitions and changes should go into this file. -; -; ; *************************************************************************** .equ clock=1000000 ; Define the clock frequency @@ -14,8 +22,15 @@ .include "include/tn84def.inc" ; Define device ATtiny84 .list -.include "n12_defs.asm" -.include "defs_all.asm" +.include "version.asm" +.include "../defs.asm" + +.include "common/calls.asm" +.include "common/utils_io.asm" +.include "devices/all/defs.asm" + + +#define COM_ACCEPT_ALL_DEST @@ -30,22 +45,19 @@ .include "modules/comproto/defs.asm" + ; --------------------------------------------------------------------------- ; firmware settings -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 ; --------------------------------------------------------------------------- ; LED -.equ LED_DDR = DDRA -.equ LED_PORT = PORTA -.equ LED_PIN = PINA -.equ LED_PINNUM = PORTA7 - +.equ LED_DDR = DDRB ; LED0 +.equ LED_PORT = PORTB +.equ LED_PIN = PINB +.equ LED_PINNUM = PORTB0 ; *************************************************************************** @@ -97,8 +109,7 @@ firmwareStart: rjmp main ; will be overwritten when flashing main: - rjmp bootLoader ; this routine is in modules/flash/proto.asm - + rjmp bootLoader ; this routine is in modules/bootloader/main.asm @@ -112,15 +123,17 @@ main: .include "modules/flash/defs.asm" .include "modules/flash/eeprom.asm" .include "modules/flash/io.asm" -.include "modules/flash/io_attn.asm" -.include "modules/flash/io_bitbang.asm" +.include "modules/flash/io_com2w.asm" .include "modules/flash/flash1p.asm" +.include "modules/flash/flashxp.asm" .include "modules/flash/flashprocess.asm" .include "modules/flash/wait.asm" .include "modules/bootloader/main.asm" .include "modules/network/msg/defs.asm" .include "modules/network/msg/crc.asm" +;.include "common/debug.asm" + systemSetSpeed: diff --git a/avr/devices/n15/n15_defs.asm b/avr/devices/r06/defs.asm similarity index 56% rename from avr/devices/n15/n15_defs.asm rename to avr/devices/r06/defs.asm index 8dff325..e952453 100644 --- a/avr/devices/n15/n15_defs.asm +++ b/avr/devices/r06/defs.asm @@ -1,5 +1,5 @@ ; *************************************************************************** -; copyright : (C) 2023 by Martin Preuss +; copyright : (C) 2025 by Martin Preuss ; email : martin@libchipcard.de ; ; *************************************************************************** @@ -13,12 +13,12 @@ ; AtTiny84 ; -------- ; VCC 1 14 GND -; PB0 2 13 PA0 REED_OUT -; PIR PB1 3 12 PA1 COM-DATA -; /RESET PB3 4 11 PA2 REED_IN1 -; [KEY1] PB2 5 10 PA3 LED -; COM_ATTN PA7 6 9 PA4 TWI-SCL -; TWI-SDA PA6 7 8 PA5 REED_IN2 +; LED0 PB0 2 13 PA0 COM-CLK0 +; LED1 PB1 3 12 PA1 COM-CLK1 +; /RESET PB3 4 11 PA2 COM-DATA0 +; PB2 5 10 PA3 COM-DATA1 +; PA7 6 9 PA4 +; TWI-SDA PA6 7 8 PA5 TWI-SCL ; -------- ; ; *************************************************************************** @@ -30,8 +30,8 @@ .equ FIRMWARE_VARIANT_BOOT = 0 .equ FIRMWARE_VARIANT_TEMP_WINDOW = 1 -.equ DEVICEINFO_ID = 'N' -.equ DEVICEINFO_VERSION = 15 +.equ DEVICEINFO_ID = 'R' +.equ DEVICEINFO_VERSION = 6 .equ DEVICEINFO_REVISION = 0 @@ -39,35 +39,55 @@ ; --------------------------------------------------------------------------- ; LED module -.equ LED_SIMPLE_ONTIME = 2 -.equ LED_SIMPLE_OFFTIME = 30 -.equ LED_SIMPLE_DDR = DDRA -.equ LED_SIMPLE_PORT = PORTA -.equ LED_SIMPLE_PORTIN = PINA -.equ LED_SIMPLE_PINNUM = PORTA3 +.equ LED_SIMPLE_ONTIME = 1 ; shorter +.equ LED_SIMPLE_OFFTIME = 50 ; longer +.equ LED_SIMPLE_DDR = DDRB +.equ LED_SIMPLE_PORT = PORTB +.equ LED_SIMPLE_PORTIN = PINB +.equ LED_SIMPLE_PINNUM = PORTB0 ; --------------------------------------------------------------------------- ; COM module -.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400 -.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter +;.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400 +;.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter + +.equ COM_IRQ_ADDR_CLK = PCMSK0 +.equ COM_IRQ_GIFR_CLK = PCIF0 +.equ COM_IRQ_GIMSK_CLK = PCIE0 .equ COM_DATA_DDR = DDRA .equ COM_DATA_INPUT = PINA .equ COM_DATA_OUTPUT = PORTA -.equ COM_DATA_PIN = PORTA1 +.equ COM_DATA_PIN = PORTA2 -.equ COM_ATTN_DDR = DDRA -.equ COM_ATTN_INPUT = PINA -.equ COM_ATTN_OUTPUT = PORTA -.equ COM_ATTN_PIN = PORTA7 +.equ COM_CLK_DDR = DDRA +.equ COM_CLK_INPUT = PINA +.equ COM_CLK_OUTPUT = PORTA +.equ COM_CLK_PIN = PORTA0 -.equ COM_IRQ_ADDR_ATTN = PCMSK0 -.equ COM_IRQ_BIT_ATTN = PCINT7 ; bit 7 in PCMSK0 -.equ COM_IRQ_GIFR_ATTN = PCIF0 -.equ COM_IRQ_GIMSK_ATTN = PCIE0 +.equ COM_LED_DDR = DDRB +.equ COM_LED_INPUT = PINB +.equ COM_LED_OUTPUT = PORTB +.equ COM_LED_PIN = PORTB0 + + +.equ COM_IRQ_ADDR_M_CLK = GIMSK +.equ COM_IRQ_BIT_M_CLK = PCIE0 +.equ COM_IRQ_ADDR_F_CLK = GIFR +.equ COM_IRQ_BIT_F_CLK = PCIE0 + +.equ COM_PORTS = 2 + +.equ COM_MASK_CLK0 = (1< + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + main.asm + + + + + + + + + + + + data.asm + + + + + + diff --git a/avr/devices/r06/main/data.asm b/avr/devices/r06/main/data.asm new file mode 100644 index 0000000..31ccc2f --- /dev/null +++ b/avr/devices/r06/main/data.asm @@ -0,0 +1,14 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +.dseg + + diff --git a/avr/devices/r06/main/main.asm b/avr/devices/r06/main/main.asm new file mode 100644 index 0000000..a1ffb17 --- /dev/null +++ b/avr/devices/r06/main/main.asm @@ -0,0 +1,231 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + + +; *************************************************************************** +; Source file for temperature sensor node on AtTiny 84 +; +; This is for the full system (i.e. not the boot loader). +; +; All definitions and changes should go into this file. +; +; +; *************************************************************************** + + +;.equ clock=1000000 ; Define the clock frequency +.equ clock=8000000 ; Define the clock frequency + + + +.nolist +.include "include/tn84def.inc" ; Define device ATtiny84 +.list + +.include "../defs.asm" +.include "./data.asm" + +.include "version.asm" +.include "devices/all/defs.asm" +.include "common/calls.asm" +.include "common/utils_io.asm" +.include "common/utils_wait.asm" + + + +; *************************************************************************** +; defines + +; --------------------------------------------------------------------------- +; generic + +.equ NET_BUFFERS_NUM = 6 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) +.equ COM2WN_IO_RINGBUFFER_SIZE = 128 + +.equ PROGRAM_SENSOR_INTERVAL_SECS = 60 +.equ PROGRAM_STATS_INTERVAL_MINS = 10 + + + +; --------------------------------------------------------------------------- +; firmware settings including list of modules used + +#define COM_ACCEPT_ALL_DEST ; accept all messages! + +; #define MODULES_TIMER +#define MODULES_CLOCK +#define MODULES_LED_SIMPLE +#define MODULES_NETWORK +;#define MODULES_UART_BITBANG +#define MODULES_COM2WN +;#define MODULES_TWI_MASTER +;#define MODULES_LCD +;#define LCD_MINIMAL_FONT +;#define MODULES_SI7021 +;#define MODULES_SGP30 +;#define MODULES_SGP40 +;#define MODULES_STATS +;#define MODULES_OWI_MASTER +;#define MODULES_DS18B20 +;#define MODULES_MOTION +;#define MODULES_CCS811 +;#define MODULES_BRIGHTNESS + +;#define APPS_NETWORK +;#define APPS_MOTION +;#define APPS_REPORTSENSORS +#define APPS_STATS + + + +; --------------------------------------------------------------------------- +; defines for values + +.equ VALUE_ID_SI7021_TEMP = 0x01 +.equ VALUE_ID_SI7021_HUM = 0x02 + +.equ VALUE_ID_ADC = 0x03 +;.equ VALUE_ID_DS18B20_TEMP = 0x06 +.equ VALUE_ID_MOTION = 0x07 + +.equ VALUE_ID_SGP40_TVOC = 0x08 + +.equ VALUE_ID_SGP30_TVOC = 0x09 +.equ VALUE_ID_SGP30_CO2 = 0x0a + +.equ VALUE_ID_BRIGHTNESS = 0x0b + +;.equ VALUE_ID_REED_CONF = 0x81 + +.equ VALUE_ID_DEBUG = 0x7f + +.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88 + + + + + +; *************************************************************************** +; code segment + +.cseg +.org 000000 + + + +; --------------------------------------------------------------------------- +; Reset and interrupt vectors (will be removed as soon as we can flash data over COM) + +; rjmp main ; Reset vector + rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system + reti ; EXT_INT0 + rjmp COM2WN_ClkChangeIsr ; PCI0 + reti ; PCI1 + reti ; WATCHDOG + reti ; ICP1 + reti ; OC1A + reti ; OC1B + reti ; OVF1 + rjmp baseTimerIrqOC0A ; OC0A + reti ; OC0B + reti ; OVF0 + reti ; ACI + reti ; ADCC + reti ; ERDY + reti ; USI_STR + reti ; USI_OVF + + +devInfoBlock: ; 12 bytes +devInfoManufacturer: .db 'A', 'Q', 'U', 'A' +devInfoId: .db DEVICEINFO_ID, 0 +devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision +firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR + .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL + + + +; --------------------------------------------------------------------------- +; @routine firmwareStart @global + +firmwareStart: + rjmp main +; @end + + + +; --------------------------------------------------------------------------- +; @routine onSystemStart + +onSystemStart: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onMessageReceived +; +; Called on every message received + +onMessageReceived: + clc + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onEvery100ms +; +; Called every 100ms. Add your routine calls here. No arguments, no results. + +onEvery100ms: +onEverySecond: +onEveryMinute: +onEveryHour: +onEveryDay: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onEveryLoop +; +; Called on every loop (i.e. after awakening from sleep). +; +onEveryLoop: + ret +; @end + + + + + +; *************************************************************************** +; includes + +.include "devices/all/hw_tn84.asm" +.include "devices/all/includes.asm" + + + +; --------------------------------------------------------------------------- +; defines for network interface + +;.equ netInterfaceData = uart_bitbang_iface +.equ netInterfaceData = com2w0_iface + + + diff --git a/avr/devices/n17/.gitignore b/avr/devices/s03/.gitignore similarity index 100% rename from avr/devices/n17/.gitignore rename to avr/devices/s03/.gitignore diff --git a/avr/devices/n23/0BUILD b/avr/devices/s03/0BUILD similarity index 92% rename from avr/devices/n23/0BUILD rename to avr/devices/s03/0BUILD index bed977a..0829603 100644 --- a/avr/devices/n23/0BUILD +++ b/avr/devices/s03/0BUILD @@ -8,7 +8,7 @@ - aqua_n23.xml + aqua_s03.xml diff --git a/avr/devices/s03/README b/avr/devices/s03/README new file mode 100644 index 0000000..b6eff6d --- /dev/null +++ b/avr/devices/s03/README @@ -0,0 +1,9 @@ + +S03 +=== + +- Role: Router +- MCU: AtMega 644P +- Connection: RJ45 +- Periphery: + diff --git a/avr/devices/s03/aqua_s03.xml b/avr/devices/s03/aqua_s03.xml new file mode 100644 index 0000000..6e9685a --- /dev/null +++ b/avr/devices/s03/aqua_s03.xml @@ -0,0 +1,12 @@ + + + AQUA + S + 3 + + + + + + + diff --git a/avr/devices/s03/boot/0BUILD b/avr/devices/s03/boot/0BUILD new file mode 100644 index 0000000..2dae797 --- /dev/null +++ b/avr/devices/s03/boot/0BUILD @@ -0,0 +1,32 @@ + + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + boot.asm + + + + + + + + + + + + + + + + diff --git a/avr/devices/s03/boot/boot.asm b/avr/devices/s03/boot/boot.asm new file mode 100644 index 0000000..18e3064 --- /dev/null +++ b/avr/devices/s03/boot/boot.asm @@ -0,0 +1,159 @@ +; *************************************************************************** +; Source file for base system node on AtMega 644P +; +; This is for the maintenance system (i.e. the flash loader). +; +; All definitions and changes should go into this file. +; *************************************************************************** + +.equ clock=20000000 ; Define the clock frequency + +.nolist +.include "include/m644Pdef.inc" ; Define device ATmega644P +.list + +.include "../defs.asm" +.include "devices/all/defs.asm" + +.include "common/calls.asm" +.include "common/utils_wait.asm" +.include "common/utils_io.asm" + + + +; *************************************************************************** +; defines + +; --------------------------------------------------------------------------- +; generic + + +.equ NET_BUFFERS_NUM = 6 +.equ NET_BUFFERS_SIZE = 32 + + + +; --------------------------------------------------------------------------- +; firmware settings + +.equ FIRMWARE_VERSION_MAJOR = 0 +.equ FIRMWARE_VERSION_MINOR = 0 +.equ FIRMWARE_VERSION_PATCHLEVEL = 1 + + + +; --------------------------------------------------------------------------- +; LED + +.equ LED_DDR = DDRB +.equ LED_PORT = PORTB +.equ LED_PIN = PINB +.equ LED_PINNUM = PORTB0 + + + + + +; *************************************************************************** +; code segment + +.cseg +.org 0x0000 + + + +; --------------------------------------------------------------------------- +; Reset and interrupt vectors + jmp main ; 1: Reset vector RESET + jmp irqNotSet ; 2: INT0 External Interrupt Request 0 + jmp irqNotSet ; 3: INT1 External Interrupt Request 1 + jmp irqNotSet ; 4: INT2 External Interrupt Request 2 + jmp irqNotSet ; 5: PCINT0 Pin Change Interrupt Request 0 + jmp irqNotSet ; 6: PCINT1 Pin Change Interrupt Request 1 + jmp irqNotSet ; 7: PCINT2 Pin Change Interrupt Request 2 + jmp irqNotSet ; 8: PCINT3 Pin Change Interrupt Request 3 + jmp irqNotSet ; 9: WDT Watchdog Time-out Interrupt + jmp irqNotSet ; 10: TIMER2_COMPA Timer/Counter2 Compare Match A + jmp irqNotSet ; 11: TIMER2_COMPB Timer/Counter2 Compare Match B + jmp irqNotSet ; 12: TIMER2_OVF Timer/Counter2 Overflow + jmp irqNotSet ; 13: TIMER1_CAPT Timer/Counter1 Capture Event + jmp irqNotSet ; 14: TIMER1_COMPA Timer/Counter1 Compare Match A + jmp irqNotSet ; 15: TIMER1_COMPB Timer/Counter1 Compare Match B + jmp irqNotSet ; 16: TIMER1_OVF Timer/Counter1 Overflow + jmp irqNotSet ; 17: TIMER0_COMPA Timer/Counter0 Compare Match A + jmp irqNotSet ; 18: TIMER0_COMPB Timer/Counter0 Compare Match B + jmp irqNotSet ; 19: TIMER0_OVF Timer/Counter0 Overflow + jmp irqNotSet ; 20: SPI_STC Serial Transfer Complete + jmp irqNotSet ; 21: USART0_RXC USART0 Rx Complete + jmp irqNotSet ; 22: USART0_UDRE USART0 Data Register Empty + jmp irqNotSet ; 23: USART0_TXC USART0 Tx Complete + jmp irqNotSet ; 24: ANA_COMP Analog Comparator + jmp irqNotSet ; 25: ADC ADC Conversion Complete + jmp irqNotSet ; 26: EE_RDY EEPROM Ready + jmp irqNotSet ; 27: TWI 2-Wire Interface + jmp irqNotSet ; 28: SPM_RDY Store Program Memory Ready + + + +; --------------------------------------------------------------------------- +; Device Info Block + +devInfoBlock: ; 12 bytes +devInfoManufacturer: .db 'A', 'Q', 'U', 'A' +devInfoId: .db DEVICEINFO_ID, 0 +devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision +firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR + .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL + +firmwareStart: + jmp main ; will be overwritten when flashing + +irqNotSet: + reti + + + +; *************************************************************************** +; main code + + +.org BOOTLOADER_ADDR + + +main: +; ldi r16, 0xb0 ; orig: a0 +; out OSCCAL, r16 + jmp bootLoader ; this routine is in modules/bootloader/main.asm + + + +; *************************************************************************** +; includes + +.include "common/wait_10us.asm" +.include "common/utils_copy_from_flash.asm" +.include "common/utils_copy_sdram.asm" + +.include "modules/flash/defs.asm" +.include "modules/flash/eeprom.asm" +.include "modules/flash/io.asm" +.include "modules/flash/io_com2w.asm" +.include "modules/flash/flash1pmega.asm" +.include "modules/flash/flashxp.asm" +.include "modules/flash/flashprocess.asm" +.include "modules/flash/wait.asm" +.include "modules/bootloader/main.asm" +.include "modules/network/msg/defs.asm" +.include "modules/network/msg/crc.asm" + +;.include "common/debug.asm" + + + +systemSetSpeed: + ; speed not changeable at runtime on this device + ret + + + + diff --git a/avr/devices/s03/defs.asm b/avr/devices/s03/defs.asm new file mode 100644 index 0000000..2079869 --- /dev/null +++ b/avr/devices/s03/defs.asm @@ -0,0 +1,137 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +; *************************************************************************** +; +; AtMega644 +; -------- +; LED PB0 1 40 PA0 COM0-CLK +; PB1 2 39 PA1 COM1-CLK +; PB2 3 38 PA2 COM2-CLK +; PB3 4 37 PA3 COM3-CLK +; PB4 5 36 PA4 COM4-CLK +; MOSI PB5 6 35 PA5 COM5-CLK +; MISO PB6 7 34 PA6 COM6-CLK +; SCK PB7 8 33 PA7 COM7-CLK +; /RESET 9 32 AREF +; VCC 10 31 GND +; GND 11 30 AVCC +; XTAL2 12 29 PC7 COM7-DATA +; XTAL1 13 28 PC6 COM6-DATA +; COM0-LED PD0 14 27 PC5 COM5-DATA +; COM1-LED PD1 15 26 PC4 COM4-DATA +; COM2-LED PD2 16 25 PC3 COM3-DATA +; COM3-LED PD3 17 24 PC2 COM2-DATA +; COM4-LED PD4 18 23 PC1 COM1-DATA +; COM5-LED PD5 19 22 PC0 COM0-DATA +; COM6-LED PD6 20 21 COM7-LED +; -------- +; +; *************************************************************************** + + + +.equ BOOTLOADER_ADDR = 0x7c00 + +.equ FIRMWARE_VARIANT_BOOT = 0 +.equ FIRMWARE_VARIANT_TEMP_WINDOW = 1 + +.equ DEVICEINFO_ID = 'S' +.equ DEVICEINFO_VERSION = 3 +.equ DEVICEINFO_REVISION = 0 + + + +; --------------------------------------------------------------------------- +; LED module + +.equ LED_SIMPLE_ONTIME = 1 ; shorter +.equ LED_SIMPLE_OFFTIME = 50 ; longer +.equ LED_SIMPLE_DDR = DDRB +.equ LED_SIMPLE_PORT = PORTB +.equ LED_SIMPLE_PORTIN = PINB +.equ LED_SIMPLE_PINNUM = PORTB0 + + + +; --------------------------------------------------------------------------- +; LED activity module + +.equ LED_ACTIVITY_DDR = DDRB +.equ LED_ACTIVITY_PORT = PORTB +.equ LED_ACTIVITY_PORTIN = PINB +.equ LED_ACTIVITY_PINNUM = PORTB1 + + + +; --------------------------------------------------------------------------- +; COM module + +.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400 +.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter + +.equ COM_DATA_DDR = DDRC +.equ COM_DATA_INPUT = PINC +.equ COM_DATA_OUTPUT = PORTC +.equ COM_DATA_PIN = PORTC6 + +.equ COM_CLK_DDR = DDRA +.equ COM_CLK_INPUT = PINA +.equ COM_CLK_OUTPUT = PORTA +.equ COM_CLK_PIN = PORTA6 + +.equ COM_IRQ_ADDR_M_CLK = PCICR +.equ COM_IRQ_BIT_M_CLK = PCIE0 + +.equ COM_IRQ_ADDR_F_CLK = PCIFR +.equ COM_IRQ_BIT_F_CLK = PCIF0 + +.equ COM_IRQ_ADDR_CLK = PCMSK0 + + + +.equ COM_PORTS = 8 + +.equ COM_MASK_CLK0 = (1< + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + main.asm + + + + + + + + + + + + data.asm + + + + + + diff --git a/avr/devices/s03/main/data.asm b/avr/devices/s03/main/data.asm new file mode 100644 index 0000000..31ccc2f --- /dev/null +++ b/avr/devices/s03/main/data.asm @@ -0,0 +1,14 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +.dseg + + diff --git a/avr/devices/s03/main/main.asm b/avr/devices/s03/main/main.asm new file mode 100644 index 0000000..2f82a98 --- /dev/null +++ b/avr/devices/s03/main/main.asm @@ -0,0 +1,249 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +;.equ clock=1000000 ; Define the clock frequency +.equ clock=20000000 ; Define the clock frequency + + + +.nolist +.include "include/m644Pdef.inc" ; Define device ATmega644P +.list + +.include "version.asm" +.include "../defs.asm" +.include "./data.asm" + +.include "devices/all/defs.asm" +.include "common/calls.asm" +.include "common/utils_wait.asm" +.include "common/utils_io.asm" + + + +; *************************************************************************** +; defines + +; --------------------------------------------------------------------------- +; generic + +.equ NET_BUFFERS_NUM = 96 +.equ NET_MSGNUMINBUF_SIZE = 64 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 16 ; max buffer nums in ringbuffer (per interface outbound) +.equ COM2WN_IO_RINGBUFFER_SIZE = 240 + + + +; --------------------------------------------------------------------------- +; firmware settings including list of modules used + +#define MAIN_WITHOUT_MSG_HANDLING ; message handling done here +#define APP_STATS_NETDEV2 +#define COM_ACCEPT_ALL_DEST ; accept all messages! + +; #define MODULES_TIMER +#define MODULES_CLOCK +;#define MODULES_XRAM +;#define MODULES_HEAP +#define MODULES_LED_SIMPLE +#define MODULES_LED_ACTIVITY +#define MODULES_NETWORK +#define MODULES_COM2WN +;#define MODULES_COMONUART0 +;#define MODULES_UART_HW +;#define MODULES_UART_BITBANG +;#define MODULES_SPI_HW +;#define MODULES_ILI9341 +;#define MODULES_FONT +;#define MODULES_WIN +;#define MODULES_TWI_MASTER +;#define MODULES_LCD +;#define LCD_MINIMAL_FONT +;#define MODULES_SI7021 +;#define MODULES_SGP30 +;#define MODULES_SGP40 +;#define MODULES_STATS +;#define MODULES_OWI_MASTER +;#define MODULES_DS18B20 +;#define MODULES_MOTION +;#define MODULES_CCS811 + +;#define APPS_NETWORK +;#define APPS_MOTION +;#define APPS_REPORTSENSORS +#define APPS_STATS +#define APPS_HUB + + + +; --------------------------------------------------------------------------- +; defines for values + +.equ VALUE_ID_HUB_SETRANGE1 = 0x11 +.equ VALUE_ID_HUB_SETRANGE2 = 0x12 +.equ VALUE_ID_HUB_SETRANGE3 = 0x13 +.equ VALUE_ID_HUB_SETRANGE4 = 0x14 +.equ VALUE_ID_HUB_SETRANGE5 = 0x15 +.equ VALUE_ID_HUB_SETRANGE6 = 0x16 +.equ VALUE_ID_HUB_SETRANGE7 = 0x17 +.equ VALUE_ID_HUB_SETRANGE8 = 0x18 + +.equ VALUE_ID_DEBUG = 0x7f + +.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88 + + + + + +; *************************************************************************** +; code segment + +.cseg +.org 000000 + + + +; --------------------------------------------------------------------------- +; Reset and interrupt vectors + jmp BOOTLOADER_ADDR ; 1: Reset vector RESET + jmp irqNotSet ; 2: INT0 External Interrupt Request 0 + jmp irqNotSet ; 3: INT1 External Interrupt Request 1 + jmp irqNotSet ; 4: INT2 External Interrupt Request 2 + jmp COM2WN_ClkChangeIsr ; 5: PCINT0 Pin Change Interrupt Request 0 + jmp irqNotSet ; 6: PCINT1 Pin Change Interrupt Request 1 + jmp irqNotSet ; 7: PCINT2 Pin Change Interrupt Request 2 + jmp irqNotSet ; 8: PCINT3 Pin Change Interrupt Request 3 + jmp irqNotSet ; 9: WDT Watchdog Time-out Interrupt + jmp irqNotSet ; 10: TIMER2_COMPA Timer/Counter2 Compare Match A + jmp irqNotSet ; 11: TIMER2_COMPB Timer/Counter2 Compare Match B + jmp irqNotSet ; 12: TIMER2_OVF Timer/Counter2 Overflow + jmp irqNotSet ; 13: TIMER1_CAPT Timer/Counter1 Capture Event + jmp irqNotSet ; 14: TIMER1_COMPA Timer/Counter1 Compare Match A + jmp irqNotSet ; 15: TIMER1_COMPB Timer/Counter1 Compare Match B + jmp irqNotSet ; 16: TIMER1_OVF Timer/Counter1 Overflow + jmp baseTimerIrqOC0A ; 17: TIMER0_COMPA Timer/Counter0 Compare Match A + jmp irqNotSet ; 18: TIMER0_COMPB Timer/Counter0 Compare Match B + jmp irqNotSet ; 19: TIMER0_OVF Timer/Counter0 Overflow + jmp irqNotSet ; 20: SPI_STC Serial Transfer Complete + jmp irqNotSet ; 21: USART0_RXC USART0 Rx Complete + jmp irqNotSet ; 22: USART0_UDRE USART0 Data Register Empty + jmp irqNotSet ; 23: USART0_TXC USART0 Tx Complete + jmp irqNotSet ; 24: ANA_COMP Analog Comparator + jmp irqNotSet ; 25: ADC ADC Conversion Complete + jmp irqNotSet ; 26: EE_RDY EEPROM Ready + jmp irqNotSet ; 27: TWI 2-Wire Interface + jmp irqNotSet ; 28: SPM_RDY Store Program Memory Ready + + + +devInfoBlock: ; 12 bytes +devInfoManufacturer: .db 'A', 'Q', 'U', 'A' +devInfoId: .db DEVICEINFO_ID, 0 +devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision +firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR + .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL + + + +; --------------------------------------------------------------------------- +; @routine firmwareStart @global + +firmwareStart: + rjmp main +; @end + + +irqNotSet: + reti + + + +; --------------------------------------------------------------------------- +; @routine onSystemStart + +onSystemStart: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onMessageReceived +; +; Called on every message received + +onMessageReceived: + clc + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onEvery100ms +; +; Called every 100ms. Add your routine calls here. No arguments, no results. + +onEvery100ms: +onEverySecond: +onEveryMinute: +onEveryHour: +onEveryDay: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onEveryLoop +; +; Called on every loop (i.e. after awakening from sleep). +; +onEveryLoop: + ret +; @end + + + + + +; *************************************************************************** +; includes + +.include "devices/all/hw_m644p.asm" +.include "devices/all/includes.asm" + +;.include "modules/network/msg/device-w.asm" +;.include "common/debug.asm" + +;.include "modules/lcd2/font/font2.asm" +;.include "modules/lcd2/font/font3.asm" +;.include "modules/lcd2/font/font16x26.asm" +;.include "modules/lcd2/font/font4.asm" +;.include "modules/lcd2/font/font12x16.asm" +;.include "modules/lcd2/font/font5.asm" +;.include "modules/lcd2/font/font12x20.asm" +;.include "common/list_t.asm" +;.include "common/tree_t.asm" +;.include "common/divide.asm" + + +; --------------------------------------------------------------------------- +; defines for network interface + +;.equ netInterfaceData = netUartIface +;.equ netInterfaceData = uart_bitbang_iface +.equ netInterfaceData = com2w6_iface +.equ netInterfaceData2 = com2w5_iface + + + + + diff --git a/avr/devices/t03/0BUILD b/avr/devices/t03/0BUILD index dc4c439..ba832c8 100644 --- a/avr/devices/t03/0BUILD +++ b/avr/devices/t03/0BUILD @@ -5,8 +5,14 @@ boot main + test + uartfd + + aqua_t03.xml + + defs.asm README diff --git a/avr/devices/t03/README b/avr/devices/t03/README index e69de29..58c57bc 100644 --- a/avr/devices/t03/README +++ b/avr/devices/t03/README @@ -0,0 +1,13 @@ + +T03 +=== + +- Role: COM-PC-Interface +- MCU: AtTiny841 +- Connection: RJ45 +- Predecessor: none +- UART: comonuart0 (uart_hw2), ttyonuart1 (uart_hw) +- Periphery: + - OWI interface + - DS18B20 temperature sensor + diff --git a/devices/nodes/aqua_t03.xml b/avr/devices/t03/aqua_t03.xml similarity index 100% rename from devices/nodes/aqua_t03.xml rename to avr/devices/t03/aqua_t03.xml diff --git a/avr/devices/t03/defs.asm b/avr/devices/t03/defs.asm index 75a19f4..d5a774a 100644 --- a/avr/devices/t03/defs.asm +++ b/avr/devices/t03/defs.asm @@ -13,9 +13,9 @@ ; AtTiny 841 ; ------- ; VCC 1 14 GND -; PB0 2 13 PA0 ATTN0 -; PB1 3 12 PA1 TXD0 (UART0) -; /RESET PB3 4 11 PA2 RXD0 (UART0) +; PB0 2 13 PA0 COM-CLK +; PB1 3 12 PA1 +; /RESET PB3 4 11 PA2 COM-DATA ; LED PB2 5 10 PA3 ; 1-wire PA7 6 9 PA4 RXD1 (UART1) [SCK, PRG] ; [MOSI,PRG] SDA (I2C) PA6 7 8 PA5 TXD1 (UART1) [MISO, PRG] @@ -49,21 +49,72 @@ +; --------------------------------------------------------------------------- +; LED signal module + +.equ LED_SIGNAL_DDR = DDRB +.equ LED_SIGNAL_PORT = PORTB +.equ LED_SIGNAL_PORTIN = PINB +.equ LED_SIGNAL_PINNUM = PORTB2 + + + +; --------------------------------------------------------------------------- +; LED activity module + +.equ LED_ACTIVITY_DDR = DDRB +.equ LED_ACTIVITY_PORT = PORTB +.equ LED_ACTIVITY_PORTIN = PINB +.equ LED_ACTIVITY_PINNUM = PORTB2 + + + ; --------------------------------------------------------------------------- ; COM module .equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400 -.equ COM_ATTN_DDR = DDRA -.equ COM_ATTN_INPUT = PINA -.equ COM_ATTN_OUTPUT = PORTA -.equ COM_ATTN_PUE = PUEA -.equ COM_ATTN_PIN = PORTA0 +.equ COM_ATTN0_DDR = DDRA +.equ COM_ATTN0_INPUT = PINA +.equ COM_ATTN0_OUTPUT = PORTA +.equ COM_ATTN0_PUE = PUEA +.equ COM_ATTN0_PIN = PORTA0 -.equ COM_IRQ_ADDR_ATTN = PCMSK0 -.equ COM_IRQ_BIT_ATTN = PCINT0 ; bit 0 in PCMSK0 -.equ COM_IRQ_GIFR_ATTN = PCIF0 -.equ COM_IRQ_GIMSK_ATTN = PCIE0 +.equ COM_IRQ_ADDR_ATTN0 = PCMSK0 +.equ COM_IRQ_BIT_ATTN0 = PCINT0 ; bit 0 in PCMSK0 +.equ COM_IRQ_GIFR_ATTN0 = PCIF0 +.equ COM_IRQ_GIMSK_ATTN0 = PCIE0 + +; compatibility +.equ COM_ATTN_DDR = COM_ATTN0_DDR +.equ COM_ATTN_INPUT = COM_ATTN0_INPUT +.equ COM_ATTN_OUTPUT = COM_ATTN0_OUTPUT +.equ COM_ATTN_PUE = COM_ATTN0_PUE +.equ COM_ATTN_PIN = COM_ATTN0_PIN + +.equ COM_IRQ_ADDR_ATTN = COM_IRQ_ADDR_ATTN0 +.equ COM_IRQ_BIT_ATTN = COM_IRQ_BIT_ATTN0 +.equ COM_IRQ_GIFR_ATTN = COM_IRQ_GIFR_ATTN0 +.equ COM_IRQ_GIMSK_ATTN = COM_IRQ_GIMSK_ATTN0 + + + +.equ COM_DATA_DDR = DDRA +.equ COM_DATA_INPUT = PINA +.equ COM_DATA_OUTPUT = PORTA +.equ COM_DATA_PUE = PUEA +.equ COM_DATA_PIN = PORTA2 + +.equ COM_CLK_DDR = DDRA +.equ COM_CLK_INPUT = PINA +.equ COM_CLK_OUTPUT = PORTA +.equ COM_CLK_PUE = PUEA +.equ COM_CLK_PIN = PORTA0 + +.equ COM_IRQ_ADDR_CLK = PCMSK0 +.equ COM_IRQ_BIT_CLK = PCINT0 ; bit 0 in PCMSK0 +.equ COM_IRQ_GIFR_CLK = PCIF0 +.equ COM_IRQ_GIMSK_CLK = PCIE0 diff --git a/avr/devices/t03/main/main.asm b/avr/devices/t03/main/main.asm index 6dcb305..3512966 100644 --- a/avr/devices/t03/main/main.asm +++ b/avr/devices/t03/main/main.asm @@ -47,12 +47,17 @@ ; --------------------------------------------------------------------------- ; generic +.equ COMONUART0_IFACENUM = 1 +.equ TTYONUART1_IFACENUM = 2 + ; --------------------------------------------------------------------------- ; firmware settings including list of modules used #define MAIN_WITHOUT_MSG_HANDLING ; we do message handling ourselfes +#define APP_STATS_NETDEV2 +#define COM_ACCEPT_ALL_DEST ; accept all messages! #define MODULES_CLOCK ;#define MODULES_COM @@ -70,23 +75,26 @@ ;#define MODULES_DS18B20 ;#define MODULES_MOTION #define MODULES_NETWORK +#define MODULES_COM2W +;#define MODULES_COMONUART0 #define MODULES_TTYONUART1 -#define MODULES_COMONUART0 #define APPS_STATS +#define APPS_NETWORK -.equ NET_BUFFERS_NUM = 8 -.equ NET_BUFFERS_SIZE = 32 +.equ NET_BUFFERS_NUM = 10 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) -.equ UART_HW_MSGNUMINBUF_SIZE = 8 -.equ UART_HW_MSGNUMOUTBUF_SIZE = 8 ; --------------------------------------------------------------------------- ; defines for values +.equ VALUE_ID_DS18B20_TEMP = 0x06 + .equ VALUE_ID_LEDSIMPLE_TIMING = 0x88 @@ -103,7 +111,7 @@ rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system reti ; 2: INT0 External Interrupt Request 0 - rjmp ComOnUart0_AttnChangeIsr ; 3: PCINT0 Pin Change Interrupt 0 + rjmp com2wPcintIsr ; 3: PCINT0 Pin Change Interrupt 0 reti ; 4: PCINT1 Pin Change Interrupt 1 reti ; 5: WDT Watchdog Time-out reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event @@ -123,9 +131,9 @@ reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow reti ; 21: SPI SPI Serial Transfer Complete reti ; 22: USART0_RXS USART0 Rx Start - rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete - rjmp ComOnUart0_TxUdreIsr ; 24: USART0_DRE USART0 Data Register Empty - rjmp ComOnUart0_TxCharIsr ; 25: USART0_TXC USART0 Tx Complete + reti ; 23: USART0_RXC USART0 Rx Complete + reti ; 24: USART0_DRE USART0 Data Register Empty + reti ; 25: USART0_TXC USART0 Tx Complete reti ; 26: USART1_RXS USART1 Rx Start rjmp TtyOnUart1_RxCharIsr ; 27: USART1_RXC USART1 Rx Complete rjmp TtyOnUart1_TxUdreIsr ; 28: USART1_DRE USART1 Data Register Empty @@ -157,15 +165,18 @@ firmwareStart: ; @routine onSystemStart onSystemStart: + ; set interface number for UART0 + ldi r16, COMONUART0_IFACENUM + sts netInterfaceData2+NET_IFACE_OFFS_IFACENUM, r16 + ; set interface number for UART1 + ldi r16, TTYONUART1_IFACENUM + sts ttyOnUart1_iface+NET_IFACE_OFFS_IFACENUM, r16 + ret ; @end - - - - onEvery100ms: onEverySecond: onEveryMinute: @@ -213,16 +224,14 @@ checkRecvdMsg: push xl push xh adiw xh:xl, 1 - rcall onMessageReceived - rcall mainModulesOnPacketReceived - rcall mainAppsOnPacketReceived + rcall letSysHandleMsg pop xh pop xl pop r16 ; forward to other interface ld r17, X - andi r17, (NET_IFACE_BUFFER_IFACENUM1_BIT | NET_IFACE_BUFFER_IFACENUM0_BIT) + andi r17, (1< + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + main.asm + + + + + + + + + + + + + + + + + diff --git a/avr/devices/t03/test/main.asm b/avr/devices/t03/test/main.asm new file mode 100644 index 0000000..3aeae6c --- /dev/null +++ b/avr/devices/t03/test/main.asm @@ -0,0 +1,259 @@ +; *************************************************************************** +; copyright : (C) 2024 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + + +; *************************************************************************** +; Source file for temperature sensor node on AtTiny 84 +; +; This is for the full system (i.e. not the boot loader). +; +; All definitions and changes should go into this file. +; +; +; *************************************************************************** + + +;.equ clock=1000000 ; Define the clock frequency +.equ clock=8000000 ; Define the clock frequency + + +.nolist +.include "include/tn841def.inc" ; Define device ATtiny841 +.list + +.include "../defs.asm" +.include "version.asm" +;.include "defs_all.asm" + +.include "devices/all/defs.asm" + +.include "common/calls.asm" +.include "common/utils_wait.asm" +.include "common/utils_io.asm" + + + +; *************************************************************************** +; defines + +; --------------------------------------------------------------------------- +; generic + +.equ COMONUART0_IFACENUM = 1 +.equ TTYONUART1_IFACENUM = 2 + + +; --------------------------------------------------------------------------- +; firmware settings including list of modules used + + +#define MAIN_WITHOUT_MSG_HANDLING ; we do message handling ourselfes +#define APP_STATS_NETDEV2 +#define APP_ROUTER_NO_ADDR_MGR +#define COM_ACCEPT_ALL_DEST ; accept all messages! + +#define MODULES_CLOCK +;#define MODULES_COM +;#define MODULES_COM_WITH_ADDR_PROTO +;#define MODULES_LED +#define MODULES_LED_SIMPLE +;#define MODULES_TWI_MASTER +;#define MODULES_LCD +;#define LCD_MINIMAL_FONT +;#define MODULES_SI7021 +;#define MODULES_STATS +;#define MODULES_CNY70 +;#define MODULES_REED +;#define MODULES_OWI_MASTER +;#define MODULES_DS18B20 +;#define MODULES_MOTION +#define MODULES_NETWORK +#define MODULES_COM2W +;#define MODULES_COMONUART0 +#define MODULES_TTYONUART1 +#define APPS_STATS +;#define APPS_NETWORK +#define APPS_ROUTER + + + +.equ NET_BUFFERS_NUM = 10 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) + +.equ UART_HW_MSGNUMINBUF_SIZE = 8 +.equ UART_HW_MSGNUMOUTBUF_SIZE = 8 + + + +; --------------------------------------------------------------------------- +; defines for values + +.equ VALUE_ID_DS18B20_TEMP = 0x06 + +.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88 +.equ VALUE_ID_ROUTER_SETRANGE = 0x89 + + + +.equ COM_DATA0_DDR = COM_DATA_DDR +.equ COM_DATA0_INPUT = COM_DATA_INPUT +.equ COM_DATA0_OUTPUT = COM_DATA_OUTPUT +.equ COM_DATA0_PUE = COM_DATA_PUE +.equ COM_DATA0_PIN = COM_DATA_PIN + +.equ COM_CLK0_DDR = COM_CLK_DDR +.equ COM_CLK0_INPUT = COM_CLK_INPUT +.equ COM_CLK0_OUTPUT = COM_CLK_OUTPUT +.equ COM_CLK0_PUE = COM_CLK_PUE +.equ COM_CLK0_PIN = COM_CLK_PIN + +.equ COM_IRQ_ADDR_CLK0 = COM_IRQ_ADDR_CLK +.equ COM_IRQ_BIT_CLK0 = COM_IRQ_BIT_CLK +.equ COM_IRQ_GIFR_CLK0 = COM_IRQ_GIFR_CLK +.equ COM_IRQ_GIMSK_CLK0 = COM_IRQ_GIMSK_CLK + + +; *************************************************************************** +; code segment + +.cseg +.org 000000 + + + +; --------------------------------------------------------------------------- +; Reset and interrupt vectors + + rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system + reti ; 2: INT0 External Interrupt Request 0 + rjmp com2wPcintIsr ; 3: PCINT0 Pin Change Interrupt 0 + reti ; 4: PCINT1 Pin Change Interrupt 1 + reti ; 5: WDT Watchdog Time-out + reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event + reti ; 7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A + reti ; 8: TIM1_COMPB (OC1B) Timer/Counter1 Compare Match B + reti ; 9: TIM1_OVF (OVF1) Timer/Counter1 Overflow + rjmp baseTimerIrqOC0A ; 10: TIM0_COMPA (OC0A) Timer/Counter0 Compare Match A + reti ; 11: TIM0_COMPB (OC0B) Timer/Counter0 Compare Match B + reti ; 12: TIM0_OVF (OVF0) Timer/Counter0 Overflow + reti ; 13: ANA_COMP0 Analog Comparator 0 + reti ; 14: ADC_READY ADC Conversion Complete + reti ; 15: EE_RDY (ERDY) EEPROM Ready + reti ; 16: ANA_COMP1 Analog Comparator 1 + reti ; 17: TIM2_CAPT Timer/Counter2 Capture Event + reti ; 18: TIM2_COMPA (OC2A) Timer/Counter2 Compare Match A + reti ; 19: TIM2_COMPB (OC2B) Timer/Counter2 Compare Match B + reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow + reti ; 21: SPI SPI Serial Transfer Complete + reti ; 22: USART0_RXS USART0 Rx Start +; rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete + reti ; 23: USART0_RXC USART0 Rx Complete + reti ; 24: USART0_DRE USART0 Data Register Empty + reti ; 25: USART0_TXC USART0 Tx Complete + reti ; 26: USART1_RXS USART1 Rx Start + rjmp TtyOnUart1_RxCharIsr ; 27: USART1_RXC USART1 Rx Complete + rjmp TtyOnUart1_TxUdreIsr ; 28: USART1_DRE USART1 Data Register Empty + rjmp TtyOnUart1_TxCharIsr ; 29: USART1_TXC USART1 Tx Complete + reti ; 30: TWI Two-Wire-Interface + reti ; 31: RESERVED reserved + + + +devInfoBlock: ; 12 bytes +devInfoManufacturer: .db 'A', 'Q', 'U', 'A' +devInfoId: .db DEVICEINFO_ID, 0 +devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision +firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR + .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL + + + +; --------------------------------------------------------------------------- +; @routine firmwareStart @global + +firmwareStart: + rjmp main +; @end + + + +; --------------------------------------------------------------------------- +; @routine onSystemStart + +onSystemStart: + ldi r16, 0xf0 + sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r16 + sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r16 + ret +; @end + + + +onEvery100ms: +onEverySecond: +onEveryMinute: +onEveryHour: +onEveryDay: + ret + + + +; --------------------------------------------------------------------------- +; @routine onEveryLoop +; +; Called on every loop (i.e. after awakening from sleep). + +onEveryLoop: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onMessageReceived +; +; Called on every message received + +onMessageReceived: + clc + ret +; @end + + + + + + +; *************************************************************************** +; includes + +.include "devices/all/hw_tn841.asm" +.include "devices/all/includes.asm" +.include "common/debug.asm" + + + + +; --------------------------------------------------------------------------- +; defines for network interface + +.equ netInterfaceData = ttyOnUart1_iface +.equ netInterfaceData2 = com2w_iface + + +; debug +push r18 + push r19 + rcall LedSimple_SetFastTiming + pop r19 +pop r18 + diff --git a/avr/devices/t03/uartfd/0BUILD b/avr/devices/t03/uartfd/0BUILD new file mode 100644 index 0000000..7e9dd5c --- /dev/null +++ b/avr/devices/t03/uartfd/0BUILD @@ -0,0 +1,33 @@ + + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + main.asm + + + + + + + + + + + + + + + + + diff --git a/avr/devices/t03/uartfd/main.asm b/avr/devices/t03/uartfd/main.asm new file mode 100644 index 0000000..5ce57ac --- /dev/null +++ b/avr/devices/t03/uartfd/main.asm @@ -0,0 +1,267 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + + +; *************************************************************************** +; Source file for temperature sensor node on AtTiny 84 +; +; This is for the full system (i.e. not the boot loader). +; +; All definitions and changes should go into this file. +; +; +; *************************************************************************** + + +;.equ clock=1000000 ; Define the clock frequency +.equ clock=8000000 ; Define the clock frequency + + +.nolist +.include "include/tn841def.inc" ; Define device ATtiny841 +.list + +.include "../defs.asm" +.include "version.asm" +;.include "defs_all.asm" + +.include "devices/all/defs.asm" + +.include "common/calls.asm" +.include "common/utils_wait.asm" +.include "common/utils_io.asm" + + + +; *************************************************************************** +; defines + +; --------------------------------------------------------------------------- +; generic + +.equ COMONUART0_IFACENUM = 1 +.equ TTYONUART1_IFACENUM = 2 + + +; debug + +;.equ T03_FLAGS_ALLOC = 0x01 +;.equ T03_FLAGS_I1_SKIPPING = 0x02 +;.equ T03_FLAGS_I1_RESTARTED = 0x04 +;.equ T03_FLAGS_ADDIN = 0x08 +;.equ T03_FLAGS_I1_ADDOUT = 0x10 +;.equ T03_FLAGS_I2_ADDOUT = 0x20 + + + +; --------------------------------------------------------------------------- +; firmware settings including list of modules used + + +#define MAIN_WITHOUT_MSG_HANDLING ; we do message handling ourselfes +#define APP_STATS_NETDEV2 +#define APP_ROUTER_NO_ADDR_MGR +#define COM_ACCEPT_ALL_DEST ; accept all messages! + +#define MODULES_CLOCK +;#define MODULES_COM +;#define MODULES_COM_WITH_ADDR_PROTO +;#define MODULES_LED +;#define MODULES_LED_SIMPLE +;#define MODULES_LED_SIGNAL +#define MODULES_LED_ACTIVITY +;#define MODULES_TWI_MASTER +;#define MODULES_LCD +;#define LCD_MINIMAL_FONT +;#define MODULES_SI7021 +;#define MODULES_STATS +;#define MODULES_CNY70 +;#define MODULES_REED +;#define MODULES_OWI_MASTER +;#define MODULES_DS18B20 +;#define MODULES_MOTION +#define MODULES_NETWORK +#define MODULES_COM2W +;#define MODULES_COMONUART0 +;#define MODULES_TTYONUART1 +#define MODULES_UARTFD1 +#define APPS_STATS +;#define APPS_NETWORK +;#define APPS_ROUTER +#define APPS_FORWARDER + + + +.equ NET_BUFFERS_NUM = 10 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) + +.equ UART_HW_MSGNUMINBUF_SIZE = 8 +.equ UART_HW_MSGNUMOUTBUF_SIZE = 8 + + + +; --------------------------------------------------------------------------- +; defines for values + +.equ VALUE_ID_DS18B20_TEMP = 0x06 + +.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88 +.equ VALUE_ID_ROUTER_SETRANGE = 0x89 + + + +.equ COM_DATA0_DDR = COM_DATA_DDR +.equ COM_DATA0_INPUT = COM_DATA_INPUT +.equ COM_DATA0_OUTPUT = COM_DATA_OUTPUT +.equ COM_DATA0_PUE = COM_DATA_PUE +.equ COM_DATA0_PIN = COM_DATA_PIN + +.equ COM_CLK0_DDR = COM_CLK_DDR +.equ COM_CLK0_INPUT = COM_CLK_INPUT +.equ COM_CLK0_OUTPUT = COM_CLK_OUTPUT +.equ COM_CLK0_PUE = COM_CLK_PUE +.equ COM_CLK0_PIN = COM_CLK_PIN + +.equ COM_IRQ_ADDR_CLK0 = COM_IRQ_ADDR_CLK +.equ COM_IRQ_BIT_CLK0 = COM_IRQ_BIT_CLK +.equ COM_IRQ_GIFR_CLK0 = COM_IRQ_GIFR_CLK +.equ COM_IRQ_GIMSK_CLK0 = COM_IRQ_GIMSK_CLK + + +; *************************************************************************** +; code segment + +.cseg +.org 000000 + + + +; --------------------------------------------------------------------------- +; Reset and interrupt vectors + + rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system + reti ; 2: INT0 External Interrupt Request 0 + rjmp com2wPcintIsr ; 3: PCINT0 Pin Change Interrupt 0 + reti ; 4: PCINT1 Pin Change Interrupt 1 + reti ; 5: WDT Watchdog Time-out + reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event + reti ; 7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A + reti ; 8: TIM1_COMPB (OC1B) Timer/Counter1 Compare Match B + reti ; 9: TIM1_OVF (OVF1) Timer/Counter1 Overflow + rjmp baseTimerIrqOC0A ; 10: TIM0_COMPA (OC0A) Timer/Counter0 Compare Match A + reti ; 11: TIM0_COMPB (OC0B) Timer/Counter0 Compare Match B + reti ; 12: TIM0_OVF (OVF0) Timer/Counter0 Overflow + reti ; 13: ANA_COMP0 Analog Comparator 0 + reti ; 14: ADC_READY ADC Conversion Complete + reti ; 15: EE_RDY (ERDY) EEPROM Ready + reti ; 16: ANA_COMP1 Analog Comparator 1 + reti ; 17: TIM2_CAPT Timer/Counter2 Capture Event + reti ; 18: TIM2_COMPA (OC2A) Timer/Counter2 Compare Match A + reti ; 19: TIM2_COMPB (OC2B) Timer/Counter2 Compare Match B + reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow + reti ; 21: SPI SPI Serial Transfer Complete + reti ; 22: USART0_RXS USART0 Rx Start +; rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete + reti ; 23: USART0_RXC USART0 Rx Complete + reti ; 24: USART0_DRE USART0 Data Register Empty + reti ; 25: USART0_TXC USART0 Tx Complete + reti ; 26: USART1_RXS USART1 Rx Start + rjmp UARTFD1_RxCharIsr ; 27: USART1_RXC USART1 Rx Complete + rjmp UARTFD1_TxUdreIsr ; 28: USART1_DRE USART1 Data Register Empty + rjmp UARTFD1_TxCharIsr ; 29: USART1_TXC USART1 Tx Complete + reti ; 30: TWI Two-Wire-Interface + reti ; 31: RESERVED reserved + + + +devInfoBlock: ; 12 bytes +devInfoManufacturer: .db 'A', 'Q', 'U', 'A' +devInfoId: .db DEVICEINFO_ID, 0 +devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision +firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR + .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL + + + +; --------------------------------------------------------------------------- +; @routine firmwareStart @global + +firmwareStart: + rjmp main +; @end + + + +; --------------------------------------------------------------------------- +; @routine onSystemStart + +onSystemStart: + ldi r16, 0xf0 + sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r16 + sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r16 + ret +; @end + + + +onEvery100ms: +onEverySecond: +onEveryMinute: +onEveryHour: +onEveryDay: + ret + + + +; --------------------------------------------------------------------------- +; @routine onEveryLoop +; +; Called on every loop (i.e. after awakening from sleep). + +onEveryLoop: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onMessageReceived +; +; Called on every message received + +onMessageReceived: + clc + ret +; @end + + + + + + +; *************************************************************************** +; includes + +.include "devices/all/hw_tn841.asm" +.include "devices/all/includes.asm" +.include "common/debug.asm" + + + + +; --------------------------------------------------------------------------- +; defines for network interface + +.equ netInterfaceData = uartFd1_iface +.equ netInterfaceData2 = com2w_iface + + diff --git a/avr/devices/n18/.gitignore b/avr/devices/t04/.gitignore similarity index 100% rename from avr/devices/n18/.gitignore rename to avr/devices/t04/.gitignore diff --git a/avr/devices/t04/0BUILD b/avr/devices/t04/0BUILD new file mode 100644 index 0000000..2775440 --- /dev/null +++ b/avr/devices/t04/0BUILD @@ -0,0 +1,22 @@ + + + + + + boot + main + + + + aqua_t04.xml + + + + defs.asm + README + + + + + + diff --git a/avr/devices/t04/README b/avr/devices/t04/README new file mode 100644 index 0000000..0d2ffb6 --- /dev/null +++ b/avr/devices/t04/README @@ -0,0 +1,13 @@ + +T04 +=== + +- Role: COM-PC-Interface +- MCU: AtTiny841 +- Connection: RJ45 +- Predecessor: none +- UART: UARTFD0, COM2W +- Periphery: + - OWI interface + - DS18B20 temperature sensor + diff --git a/avr/devices/t04/aqua_t04.xml b/avr/devices/t04/aqua_t04.xml new file mode 100644 index 0000000..4f7ffd9 --- /dev/null +++ b/avr/devices/t04/aqua_t04.xml @@ -0,0 +1,11 @@ + + + AQUA + T + 4 + + + + + + diff --git a/avr/devices/t04/boot/0BUILD b/avr/devices/t04/boot/0BUILD new file mode 100644 index 0000000..e5e0cd5 --- /dev/null +++ b/avr/devices/t04/boot/0BUILD @@ -0,0 +1,32 @@ + + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + boot.asm + + + + + + + + + + + + + + + + diff --git a/avr/devices/t04/boot/boot.asm b/avr/devices/t04/boot/boot.asm new file mode 100644 index 0000000..2f9fa66 --- /dev/null +++ b/avr/devices/t04/boot/boot.asm @@ -0,0 +1,150 @@ +; *************************************************************************** +; Source file for base system node on AtTiny 84 +; +; This is for the maintenance system (i.e. the flash loader). +; +; All definitions and changes should go into this file. +; *************************************************************************** + +;.equ clock=1000000 ; Define the clock frequency +.equ clock=8000000 ; Define the clock frequency + +.nolist +.include "include/tn841def.inc" ; Define device ATtiny841 +.list + +.include "version.asm" +.include "../defs.asm" +.include "devices/all/defs.asm" + +.include "common/calls.asm" +.include "common/utils_wait.asm" + + + +; *************************************************************************** +; defines + + +;#define COM_ACCEPT_ALL_DEST 1 + + + +; --------------------------------------------------------------------------- +; LED + +.equ LED_DDR = DDRB +.equ LED_PORT = PORTB +.equ LED_PIN = PINB +.equ LED_PINNUM = PORTB2 + + +; *************************************************************************** +; code segment + +.cseg +.org 0x0000 + + + +; --------------------------------------------------------------------------- +; Reset and interrupt vectors + + rjmp main ; 1: RESET Reset vector use this for flashed system + reti ; 2: INT0 External Interrupt Request 0 + reti ; 3: PCINT0 Pin Change Interrupt 0 + reti ; 4: PCINT1 Pin Change Interrupt 1 + reti ; 5: WDT Watchdog Time-out + reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event + reti ; 7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A + reti ; 8: TIM1_COMPB (OC1B) Timer/Counter1 Compare Match B + reti ; 9: TIM1_OVF (OVF1) Timer/Counter1 Overflow + reti ; 10: TIM0_COMPA (OC0A) Timer/Counter0 Compare Match A + reti ; 11: TIM0_COMPB (OC0B) Timer/Counter0 Compare Match B + reti ; 12: TIM0_OVF (OVF0) Timer/Counter0 Overflow + reti ; 13: ANA_COMP0 Analog Comparator 0 + reti ; 14: ADC_READY ADC Conversion Complete + reti ; 15: EE_RDY (ERDY) EEPROM Ready + reti ; 16: ANA_COMP1 Analog Comparator 1 + reti ; 17: TIM2_CAPT Timer/Counter2 Capture Event + reti ; 18: TIM2_COMPA (OC2A) Timer/Counter2 Compare Match A + reti ; 19: TIM2_COMPB (OC2B) Timer/Counter2 Compare Match B + reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow + reti ; 21: SPI SPI Serial Transfer Complete + reti ; 22: USART0_RXS USART0 Rx Start + reti ; 23: USART0_RXC USART0 Rx Complete + reti ; 24: USART0_DRE USART0 Data Register Empty + reti ; 25: USART0_TXC USART0 Tx Complete + reti ; 26: USART1_RXS USART1 Rx Start + reti ; 27: USART1_RXC USART1 Rx Complete + reti ; 28: USART1_DRE USART1 Data Register Empty + reti ; 29: USART1_TXC USART1 Tx Complete + reti ; 30: TWI Two-Wire-Interface + reti ; 31: RESERVED reserved + + + +devInfoBlock: ; 12 bytes +devInfoManufacturer: .db 'A', 'Q', 'U', 'A' +devInfoId: .db DEVICEINFO_ID, 0 +devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision +firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR + .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL + +firmwareStart: + rjmp main ; will be overwritten when flashing + + + +; *************************************************************************** +; main code + + +.org BOOTLOADER_ADDR + + +main: + rjmp bootLoader ; this routine is in modules/bootloader/main.asm + + + + +; *************************************************************************** +; includes + +.include "common/utils_wait_fixed.asm" +.include "common/utils_copy_from_flash.asm" +.include "common/utils_copy_sdram.asm" +.include "modules/flash/defs.asm" +.include "modules/flash/eeprom.asm" +.include "modules/flash/io.asm" +.include "modules/flash/io_uart0.asm" +.include "modules/flash/io_uart_all.asm" +.include "modules/flash/flashxp.asm" +.include "modules/flash/flash4p.asm" +.include "modules/flash/flashprocess.asm" +.include "modules/flash/wait.asm" +.include "modules/bootloader/main.asm" +.include "modules/network/msg/defs.asm" +.include "modules/network/msg/crc.asm" + + + +systemSetSpeed: +.if clock == 1000000 + ldi r17, 0xd8 + ldi r16, (1< + + + + + + + -I $(builddir) + -I $(srcdir) + -I $(topsrcdir)/avr + -I $(topbuilddir)/avr + + + + + main.asm + + + + + + + + + + + + + + + + + diff --git a/avr/devices/t04/main/main.asm b/avr/devices/t04/main/main.asm new file mode 100644 index 0000000..b292af4 --- /dev/null +++ b/avr/devices/t04/main/main.asm @@ -0,0 +1,246 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + + +; *************************************************************************** +; Source file for temperature sensor node on AtTiny 84 +; +; This is for the full system (i.e. not the boot loader). +; +; All definitions and changes should go into this file. +; +; +; *************************************************************************** + + +;.equ clock=1000000 ; Define the clock frequency +.equ clock=8000000 ; Define the clock frequency + + +.nolist +.include "include/tn841def.inc" ; Define device ATtiny841 +.list + +.include "../defs.asm" +.include "version.asm" +;.include "defs_all.asm" + +.include "devices/all/defs.asm" + +.include "common/calls.asm" +.include "common/utils_wait.asm" +.include "common/utils_io.asm" + + + +; *************************************************************************** +; defines + +; --------------------------------------------------------------------------- +; generic + +.equ COMONUART0_IFACENUM = 1 +.equ TTYONUART0_IFACENUM = 2 + + +; debug + +;.equ T03_FLAGS_ALLOC = 0x01 +;.equ T03_FLAGS_I1_SKIPPING = 0x02 +;.equ T03_FLAGS_I1_RESTARTED = 0x04 +;.equ T03_FLAGS_ADDIN = 0x08 +;.equ T03_FLAGS_I1_ADDOUT = 0x10 +;.equ T03_FLAGS_I2_ADDOUT = 0x20 + + + +; --------------------------------------------------------------------------- +; firmware settings including list of modules used + + +#define MAIN_WITHOUT_MSG_HANDLING ; we do message handling ourselfes +#define COM_ACCEPT_ALL_DEST ; accept all messages! +#define APP_STATS_NETDEV2 +#define APP_ROUTER_NO_ADDR_MGR + +#define MODULES_CLOCK +;#define MODULES_COM +;#define MODULES_COM_WITH_ADDR_PROTO +;#define MODULES_LED +;#define MODULES_LED_SIMPLE +;#define MODULES_LED_SIGNAL +#define MODULES_LED_ACTIVITY +;#define MODULES_TWI_MASTER +;#define MODULES_LCD +;#define LCD_MINIMAL_FONT +;#define MODULES_SI7021 +;#define MODULES_STATS +;#define MODULES_CNY70 +;#define MODULES_REED +;#define MODULES_OWI_MASTER +;#define MODULES_DS18B20 +;#define MODULES_MOTION +#define MODULES_NETWORK +#define MODULES_COM2W +;#define MODULES_COMONUART0 +;#define MODULES_TTYONUART1 +#define MODULES_UARTFD0 +#define APPS_STATS +;#define APPS_NETWORK +;#define APPS_ROUTER +#define APPS_FORWARDER + + + +.equ NET_BUFFERS_NUM = 10 +.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) + + + + +; --------------------------------------------------------------------------- +; defines for values + +.equ VALUE_ID_DS18B20_TEMP = 0x06 + +.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88 +.equ VALUE_ID_ROUTER_SETRANGE = 0x89 + + + +; *************************************************************************** +; code segment + +.cseg +.org 000000 + + + +; --------------------------------------------------------------------------- +; Reset and interrupt vectors + + rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system + reti ; 2: INT0 External Interrupt Request 0 + rjmp com2wPcintIsr ; 3: PCINT0 Pin Change Interrupt 0 + reti ; 4: PCINT1 Pin Change Interrupt 1 + reti ; 5: WDT Watchdog Time-out + reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event + reti ; 7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A + reti ; 8: TIM1_COMPB (OC1B) Timer/Counter1 Compare Match B + reti ; 9: TIM1_OVF (OVF1) Timer/Counter1 Overflow + rjmp baseTimerIrqOC0A ; 10: TIM0_COMPA (OC0A) Timer/Counter0 Compare Match A + reti ; 11: TIM0_COMPB (OC0B) Timer/Counter0 Compare Match B + reti ; 12: TIM0_OVF (OVF0) Timer/Counter0 Overflow + reti ; 13: ANA_COMP0 Analog Comparator 0 + reti ; 14: ADC_READY ADC Conversion Complete + reti ; 15: EE_RDY (ERDY) EEPROM Ready + reti ; 16: ANA_COMP1 Analog Comparator 1 + reti ; 17: TIM2_CAPT Timer/Counter2 Capture Event + reti ; 18: TIM2_COMPA (OC2A) Timer/Counter2 Compare Match A + reti ; 19: TIM2_COMPB (OC2B) Timer/Counter2 Compare Match B + reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow + reti ; 21: SPI SPI Serial Transfer Complete + reti ; 22: USART0_RXS USART0 Rx Start + rjmp UARTFD0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete + rjmp UARTFD0_TxUdreIsr ; 24: USART0_DRE USART0 Data Register Empty + rjmp UARTFD0_TxCharIsr ; 25: USART0_TXC USART0 Tx Complete + reti ; 26: USART1_RXS USART1 Rx Start + reti ; 27: USART1_RXC USART1 Rx Complete + reti ; 28: USART1_DRE USART1 Data Register Empty + reti ; 29: USART1_TXC USART1 Tx Complete + reti ; 30: TWI Two-Wire-Interface + reti ; 31: RESERVED reserved + + + +devInfoBlock: ; 12 bytes +devInfoManufacturer: .db 'A', 'Q', 'U', 'A' +devInfoId: .db DEVICEINFO_ID, 0 +devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision +firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR + .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL + + + +; --------------------------------------------------------------------------- +; @routine firmwareStart @global + +firmwareStart: + rjmp main +; @end + + + +; --------------------------------------------------------------------------- +; @routine onSystemStart + +onSystemStart: + ldi r16, 0xf0 + sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r16 + sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r16 + ret +; @end + + + +onEvery100ms: +onEverySecond: +onEveryMinute: +onEveryHour: +onEveryDay: + ret + + + +; --------------------------------------------------------------------------- +; @routine onEveryLoop +; +; Called on every loop (i.e. after awakening from sleep). + +onEveryLoop: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine onMessageReceived +; +; Called on every message received + +onMessageReceived: + clc + ret +; @end + + + + + + +; *************************************************************************** +; includes + +.include "devices/all/hw_tn841.asm" +.include "devices/all/includes.asm" +.include "common/debug.asm" + + + + +; --------------------------------------------------------------------------- +; defines for network interface + +.equ netInterfaceData = uartFd0_iface +.equ netInterfaceData2 = com2w_iface + + diff --git a/avr/devices/x03/ccs811/0BUILD b/avr/devices/x03/ccs811/0BUILD deleted file mode 100644 index 6329fc6..0000000 --- a/avr/devices/x03/ccs811/0BUILD +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - boot.asm - - - - - - - - - - - defs.asm - - - - - - diff --git a/avr/devices/x03/ccs811/boot.asm b/avr/devices/x03/ccs811/boot.asm deleted file mode 100644 index b887867..0000000 --- a/avr/devices/x03/ccs811/boot.asm +++ /dev/null @@ -1,124 +0,0 @@ -; *************************************************************************** -; Source file for base system node on AtTiny 85 -; -; This is for the maintenance system (i.e. the flash loader). -; -; All definitions and changes should go into this file. -; -; -; *************************************************************************** - -.equ clock=1000000 ; Define the clock frequency - -.nolist -.include "include/tn84def.inc" ; Define device ATtiny84 -.list - -.include "./defs.asm" -.include "defs_all.asm" - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - -.include "common/utils_wait.asm" -.include "modules/com2/defs.asm" -.include "modules/comproto/defs.asm" - - -; --------------------------------------------------------------------------- -; firmware settings - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - -; --------------------------------------------------------------------------- -; LED - -.equ LED_DDR = DDRA -.equ LED_PORT = PORTA -.equ LED_PIN = PINA -.equ LED_PINNUM = PORTA3 - - - -; *************************************************************************** -; code segment - -.cseg -.org 0x0000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors - rjmp main ; Reset vector - reti ; EXT_INT0 - reti ; PCI0 - reti ; OC1A - reti ; OVF1 - reti ; OVF0 - reti ; ERDY - reti ; ACI - reti ; ADCC - reti ; OC1B - reti ; OC0A - reti ; OC0B - reti ; WATCHDOG - reti ; USI_STR - reti ; USI_OVF - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db 'N', 0 -devInfoVersion: .db 14, 0 ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main ; will be overwritten when flashing - - - -; *************************************************************************** -; main code - - -.org BOOTLOADER_ADDR - - -main: - rjmp bootLoader ; this routine is in modules/flash/proto.asm - - - - -; *************************************************************************** -; includes - -.include "modules/uart_bitbang/bytelevel.asm" -.include "modules/uart_bitbang/packetlevel.asm" -.include "modules/com2/crc.asm" -.include "common/crc8.asm" -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" -.include "modules/flash/bootloader.asm" -.include "modules/flash/flash.asm" -.include "modules/flash/recv.asm" -.include "modules/flash/send.asm" -.include "modules/flash/wait.asm" -.include "modules/flash/hdl_flash_start.asm" -.include "modules/flash/hdl_flash_data.asm" -.include "modules/flash/hdl_flash_end.asm" -.include "modules/flash/flash_rsp.asm" -.include "modules/flash/flash_ready.asm" - - - - diff --git a/avr/devices/x03/ccs811/defs.asm b/avr/devices/x03/ccs811/defs.asm deleted file mode 100644 index 9d7ae13..0000000 --- a/avr/devices/x03/ccs811/defs.asm +++ /dev/null @@ -1,134 +0,0 @@ -; *************************************************************************** -; copyright : (C) 2023 by Martin Preuss -; email : martin@libchipcard.de -; -; *************************************************************************** -; * This file is part of the project "AqHome". * -; * Please see toplevel file COPYING of that project for license details. * -; *************************************************************************** - - -; *************************************************************************** -; -; AtTiny84 -; -------- -; VCC 1 14 GND -; PB0 2 13 PA0 AUX-A0 -; PIR PB1 3 12 PA1 COM-DATA -; /RESET PB3 4 11 PA2 -; AUX-B2 PB2 5 10 PA3 LED -; COM_ATTN PA7 6 9 PA4 TWI-SCL -; TWI-SDA PA6 7 8 PA5 -; -------- -; -; *************************************************************************** - - - -.equ BOOTLOADER_ADDR = 0xd00 - -.equ FIRMWARE_VARIANT_BOOT = 0 -.equ FIRMWARE_VARIANT_MAIN = 1 - - - -; --------------------------------------------------------------------------- -; LED module - -.equ LED_SIMPLE_ONTIME = 1 ; shorter -.equ LED_SIMPLE_OFFTIME = 50 ; longer -.equ LED_SIMPLE_DDR = DDRA -.equ LED_SIMPLE_PORT = PORTA -.equ LED_SIMPLE_PORTIN = PINA -.equ LED_SIMPLE_PINNUM = PORTA3 - - -.equ LED_DEBUG_DDR = DDRA -.equ LED_DEBUG_PORT = PORTA -.equ LED_DEBUG_PORTIN = PINA -.equ LED_DEBUG_PINNUM = PORTA5 - - - -; --------------------------------------------------------------------------- -; COM module - -.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400 -.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter - -.equ COM_DATA_DDR = DDRA -.equ COM_DATA_INPUT = PINA -.equ COM_DATA_OUTPUT = PORTA -.equ COM_DATA_PIN = PORTA1 - -.equ COM_ATTN_DDR = DDRA -.equ COM_ATTN_INPUT = PINA -.equ COM_ATTN_OUTPUT = PORTA -.equ COM_ATTN_PIN = PORTA7 - -.equ COM_IRQ_ADDR_ATTN = PCMSK0 -.equ COM_IRQ_BIT_ATTN = PCINT7 ; bit 7 in PCMSK0 -.equ COM_IRQ_GIFR_ATTN = PCIF0 -.equ COM_IRQ_GIMSK_ATTN = PCIE0 - - - -; --------------------------------------------------------------------------- -; TWI master module - -;.equ TWI_BIT_LENGTH = 10000 ; 100000 and 200000 works for display: 10000, 100000, 200000 -.equ TWI_BIT_LENGTH = 1 ; 10, 100, 500, 100000 and 200000 works for display: 10000, 100000, 200000 - -.equ TWI_DDR_SCL = DDRA -.equ TWI_PORT_SCL = PORTA -.equ TWI_PIN_SCL = PINA -.equ TWI_PINNUM_SCL = PORTA4 - -.equ TWI_DDR_SDA = DDRA -.equ TWI_PORT_SDA = PORTA -.equ TWI_PIN_SDA = PINA -.equ TWI_PINNUM_SDA = PORTA6 - - - -; --------------------------------------------------------------------------- -; LCD module - -.equ LCD_TWI_ADDRESS = 0x3c - - - -; --------------------------------------------------------------------------- -; SI 7021 - -.equ SI7021_ADDR = 0x40 - - - -; --------------------------------------------------------------------------- -; 1-Wire Master -; - -.equ OWI_DDR = DDRB -.equ OWI_PORTOUT = PORTB -.equ OWI_PORTIN = PINB -.equ OWI_PINNUM = PORTB2 - - - -; --------------------------------------------------------------------------- -; Motion Sensor -; - -.equ MOTION_DDR = DDRB -.equ MOTION_INPUT = PINB -.equ MOTION_OUTPUT = PORTB -.equ MOTION_PIN = PORTB1 - - - - -.equ CCS811_ADDR = 0x5a ; or 0x5b - - - diff --git a/avr/devices/x03/ccs811/main.asm b/avr/devices/x03/ccs811/main.asm deleted file mode 100644 index a6d0463..0000000 --- a/avr/devices/x03/ccs811/main.asm +++ /dev/null @@ -1,344 +0,0 @@ -; *************************************************************************** -; copyright : (C) 2024 by Martin Preuss -; email : martin@libchipcard.de -; -; *************************************************************************** -; * This file is part of the project "AqHome". * -; * Please see toplevel file COPYING of that project for license details. * -; *************************************************************************** - - -; *************************************************************************** -; Source file for LED controller node on AtTiny 85 -; -; This is for the full system (i.e. not the boot loader). -; *************************************************************************** - -.equ clock=1000000 ; Define the clock frequency - - - -.nolist -.include "include/tn84def.inc" ; Define device ATtiny84 -.list - -.include "./defs.asm" -.include "defs_all.asm" -.include "common/utils_wait.asm" ; wait macro - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; firmware settings including list of modules used - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - -#define MODULES_TIMER -#define MODULES_COM -#define MODULES_COM_WITH_ADDR_PROTO -#define MODULES_LED_SIMPLE -#define MODULES_TWI_MASTER -;#define MODULES_SI7021 -#define MODULES_STATS -; #define MODULES_OWI_MASTER -; #define MODULES_DS18B20 -; #define MODULES_SK6812 -; #define MODULES_MOTION_LIGHT - -; #define COM_ACCEPT_ALL_DEST -#define MODULES_CCS811 - - -; --------------------------------------------------------------------------- -; defines for modules - -.equ VALUE_ID_CO2 = 0x07 -.equ VALUE_ID_TVOC = 0x08 - -.equ VALUE_ID_DEBUG = 0x7f - -;.equ VALUE_ID_SI7021_TEMP = 0x01 -;.equ VALUE_ID_SI7021_HUM = 0x02 - -;.equ VALUE_ID_ADC = 0x03 -;.equ VALUE_ID_REED1 = 0x04 -;.equ VALUE_ID_REED2 = 0x05 -;.equ VALUE_ID_DS18B20_TEMP = 0x06 - -;.equ VALUE_ID_LED_NUMLEDS = 0x82 -;.equ VALUE_ID_LED_RGBW_VALUE = 0x83 -;.equ VALUE_ID_MAL_RGBW_VALUE = 0x84 -;.equ VALUE_ID_MAL_ONTIME = 0x85 -;.equ VALUE_ID_MAL_SOURCE1 = 0x86 -;.equ VALUE_ID_MAL_SOURCE2 = 0x87 - - -; *************************************************************************** -; code segment - -.cseg -.org 000000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors - - rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system - reti ; EXT_INT0 - rjmp uartBitbangIsrPcint0 ; PCI0 - reti ; OC1A - reti ; OVF1 - reti ; OVF0 - reti ; ERDY - reti ; ACI - reti ; ADCC - reti ; OC1B - rjmp baseTimerIrqOC0A ; OC0A - reti ; OC0B - reti ; WATCHDOG - reti ; USI_STR - reti ; USI_OVF - - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db 'N', 0 -devInfoVersion: .db 18, 0 ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_MAIN, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main - - -; *************************************************************************** -; includes - -.include "common/utils.asm" -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" -.include "common/crc8.asm" - -.include "modules/basetimer/main.asm" - -#ifdef MODULES_TIMER - .include "modules/timer/main.asm" -#endif -#ifdef MODULES_LED_SIMPLE -.include "modules/led_simple/main.asm" -#endif -#ifdef MODULES_COM - .include "modules/com2/defs.asm" - .include "modules/com2/main.asm" - .include "modules/com2/buffer.asm" - #ifdef MODULES_STATS - .include "modules/comproto/msg_recvstats.asm" - .include "modules/comproto/msg_sendstats.asm" - .include "modules/comproto/msg_sysstats.asm" - .include "modules/comproto/msg_memstats.asm" - #endif - .include "modules/comproto/msg_pong.asm" - .include "modules/comproto/msg_value.asm" - .include "modules/comproto/msg_device.asm" - .include "modules/comproto/msg_reboot.asm" - .include "modules/uart_bitbang/defs.asm" - .include "modules/uart_bitbang/main.asm" - .include "modules/uart_bitbang/bytelevel.asm" - .include "modules/uart_bitbang/packetlevel.asm" - #ifdef MODULES_COM_WITH_ADDR_PROTO - .include "modules/comproto/defs.asm" - .include "modules/comproto/main.asm" - .include "modules/comproto/addr.asm" - #endif -#endif -#ifdef MODULES_STATS - .include "modules/stats/main.asm" -#endif -#ifdef MODULES_TWI_MASTER - .include "modules/twimaster/main.asm" -#endif -#ifdef MODULES_OWI_MASTER - .include "modules/owimaster/main.asm" -#endif -#ifdef MODULES_SI7021 - .include "modules/si7021/main.asm" -#endif -#ifdef MODULES_DS18B20 - .include "modules/ds18b20/main.asm" -#endif -#ifdef MODULES_SK6812 - .include "modules/sk6812/main.asm" -#endif -#ifdef MODULES_MOTION_LIGHT - .include "modules/ma_light/main.asm" -#endif -#ifdef MODULES_CCS811 - .include "modules/ccs811/main.asm" -#endif - - - -; *************************************************************************** -; data in SRAM - -.dseg - - -#ifdef MODULES_DS18B20 - sramDs18b20Timer: .byte 2 - sramSendDs18b20TempTimer: .byte 2 -#endif - - -; *************************************************************************** -; data in FLASH - -.cseg - - - -; --------------------------------------------------------------------------- -; timer list - - -timerList: -; SRAM variable/counter routine flags secs (0=don't start or restart) -#ifdef MODULES_COM_WITH_ADDR_PROTO - .dw cproAddresModeTimer, CPRO_Address_OnTimer, 0, 0 ; (no restart) -#endif -#ifdef MODULES_STATS - .dw statsSendTimer, Stats_Timer, TIMER_FLAGS_IF_ADDR, 9000 ; every 15m -#endif -#ifdef MODULES_DS18B20 - .dw sramDs18b20Timer, Ds18b20_OnTimer, 0, 300 ; every 30s - .dw sramSendDs18b20TempTimer, sendDs18b20Temp, TIMER_FLAGS_IF_ADDR, 600 ; every 60s -#endif - .dw 0 ; end of list - - - - - -.include "main_all.asm" - - -; --------------------------------------------------------------------------- -; Called early on system startup. No arguments, no results. - -systemSetSpeed: -.if clock == 8000000 - ldi r16, (1< - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - main.asm - - - - - - - - - - - -I $(builddir) - -I $(srcdir) - -I $(topsrcdir)/avr - -I $(topbuilddir)/avr - - - - - boot.asm - - - - - - - - - - - defs.asm - - - - - - diff --git a/avr/devices/x03/uart/boot.asm b/avr/devices/x03/uart/boot.asm deleted file mode 100644 index 8e833a4..0000000 --- a/avr/devices/x03/uart/boot.asm +++ /dev/null @@ -1,162 +0,0 @@ -; *************************************************************************** -; Source file for base system node on AtTiny 84 -; -; This is for the maintenance system (i.e. the flash loader). -; -; All definitions and changes should go into this file. -; *************************************************************************** - -.equ clock=1000000 ; Define the clock frequency - -.nolist -.include "include/tn84def.inc" ; Define device ATtiny84 -.list - -.include "defs_all.asm" -.include "./defs.asm" - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - -.include "common/utils_wait.asm" -.include "modules/com2/defs.asm" -.include "modules/comproto/defs.asm" - - - -; --------------------------------------------------------------------------- -; firmware settings - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - - -; --------------------------------------------------------------------------- -; LED - -.equ LED_DDR = DDRA -.equ LED_PORT = PORTA -.equ LED_PIN = PINA -.equ LED_PINNUM = PORTA3 - - -; *************************************************************************** -; code segment - -.cseg -.org 0x0000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors -; rjmp start ; Reset vector - rjmp main ; Reset vector - reti ; EXT_INT0 - reti ; PCI0 - reti ; PCI1 - reti ; WATCHDOG - reti ; ICP1 - reti ; OC1A - reti ; OC1B - reti ; OVF1 - reti ; OC0A - reti ; OC0B - reti ; OVF0 - reti ; ACI - reti ; ADCC - reti ; ERDY - reti ; USI_STR - reti ; USI_OVF - - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db 'X', 0 -devInfoVersion: .db 3, 0 ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_BOOT, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main ; will be overwritten when flashing - - - -; *************************************************************************** -; main code - - -.org BOOTLOADER_ADDR - - -main: - rjmp bootLoader ; this routine is in modules/flash/proto.asm - - - - -; *************************************************************************** -; includes - -.include "modules/uart_bitbang/bytelevel.asm" -.include "modules/uart_bitbang/packetlevel.asm" -.include "modules/com2/crc.asm" -.include "common/crc8.asm" -.include "common/utils_wait_fixed.asm" -.include "common/utils_copy_from_flash.asm" -.include "common/utils_copy_sdram.asm" -.include "modules/flash/bootloader.asm" -.include "modules/flash/flash.asm" -.include "modules/flash/recv.asm" -.include "modules/flash/send.asm" -.include "modules/flash/wait.asm" -.include "modules/flash/hdl_flash_start.asm" -.include "modules/flash/hdl_flash_data.asm" -.include "modules/flash/hdl_flash_end.asm" -.include "modules/flash/flash_rsp.asm" -.include "modules/flash/flash_ready.asm" - - -#if 0 -debugStop: - cli - sbi LED_SIMPLE_DDR, LED_SIMPLE_PINNUM ; out - cbi LED_SIMPLE_PORT, LED_SIMPLE_PINNUM ; on - - cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input - cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN - - ldi r18, 0 -test_loop1: - ldi r16, 100 -test_loop2: - ldi r17, 100 -test_loop3: - Utils_WaitNanoSecs 10000, 0, r22 - dec r17 - brne test_loop3 - dec r16 - brne test_loop2 - sbi LED_SIMPLE_PORTIN, LED_SIMPLE_PINNUM ; toggle - inc r18 - mov r19, r18 - andi r19, 1 - brne test1 - sbi COM_ATTN_DDR, COM_ATTN_PIN - cbi COM_ATTN_OUTPUT, COM_ATTN_PIN - rjmp test_loop1 -test1: - cbi COM_ATTN_DDR, COM_ATTN_PIN - cbi COM_ATTN_OUTPUT, COM_ATTN_PIN - - rjmp test_loop1 -#endif - - - diff --git a/avr/devices/x03/uart/defs.asm b/avr/devices/x03/uart/defs.asm deleted file mode 100644 index df7903b..0000000 --- a/avr/devices/x03/uart/defs.asm +++ /dev/null @@ -1,72 +0,0 @@ -; *************************************************************************** -; copyright : (C) 2023 by Martin Preuss -; email : martin@libchipcard.de -; -; *************************************************************************** -; * This file is part of the project "AqHome". * -; * Please see toplevel file COPYING of that project for license details. * -; *************************************************************************** - - -; *************************************************************************** -; -; AtTiny84 -; -------- -; VCC 1 14 GND -; PB0 2 13 PA0 COM_ATTN1 -; PB1 3 12 PA1 COM-DATA1 -; /RESET PB3 4 11 PA2 -; COM_ATTN2 PB2 5 10 PA3 LED -; COM_DATA2 PA7 6 9 PA4 -; PA6 7 8 PA5 -; -------- -; -; *************************************************************************** - - - -.equ BOOTLOADER_ADDR = 0xd00 - -.equ FIRMWARE_VARIANT_BOOT = 0 -.equ FIRMWARE_VARIANT_ROUTER = 1 - - - -; --------------------------------------------------------------------------- -; LED module - -.equ LED_SIMPLE_DDR = DDRA -.equ LED_SIMPLE_PORT = PORTA -.equ LED_SIMPLE_PORTIN = PINA -.equ LED_SIMPLE_PINNUM = PORTA3 - - - -; --------------------------------------------------------------------------- -; COM module - -.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400 -.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter - -.equ COM_DATA_DDR = DDRA -.equ COM_DATA_INPUT = PINA -.equ COM_DATA_OUTPUT = PORTA -.equ COM_DATA_PIN = PORTA1 - -.equ COM_ATTN_DDR = DDRA -.equ COM_ATTN_INPUT = PINA -.equ COM_ATTN_OUTPUT = PORTA -.equ COM_ATTN_PIN = PORTA0 - -.equ COM_DATA2_DDR = DDRA -.equ COM_DATA2_INPUT = PINA -.equ COM_DATA2_OUTPUT = PORTA -.equ COM_DATA2_PIN = PORTA7 - -.equ COM_ATTN2_DDR = DDRB -.equ COM_ATTN2_INPUT = PINB -.equ COM_ATTN2_OUTPUT = PORTB -.equ COM_ATTN2_PIN = PORTB2 - - - diff --git a/avr/devices/x03/uart/main.asm b/avr/devices/x03/uart/main.asm deleted file mode 100644 index 1606d2c..0000000 --- a/avr/devices/x03/uart/main.asm +++ /dev/null @@ -1,221 +0,0 @@ -; *************************************************************************** -; copyright : (C) 2024 by Martin Preuss -; email : martin@libchipcard.de -; -; *************************************************************************** -; * This file is part of the project "AqHome". * -; * Please see toplevel file COPYING of that project for license details. * -; *************************************************************************** - - - - -; *************************************************************************** -; Source file for temperature sensor node on AtTiny 84 -; -; This is for the full system (i.e. not the boot loader). -; -; All definitions and changes should go into this file. -; -; -; *************************************************************************** - - -; .equ clock=1000000 ; Define the clock frequency -.equ clock=8000000 ; Define the clock frequency - - - -.nolist -.include "include/tn84def.inc" ; Define device ATtiny84 -.list - -.include "defs_all.asm" -.include "./defs.asm" - - - -; *************************************************************************** -; defines - -; --------------------------------------------------------------------------- -; generic - - -.include "common/utils_wait.asm" - - -; --------------------------------------------------------------------------- -; firmware settings including list of modules used - -.equ FIRMWARE_VERSION_MAJOR = 0 -.equ FIRMWARE_VERSION_MINOR = 0 -.equ FIRMWARE_VERSION_PATCHLEVEL = 1 - - - - -; *************************************************************************** -; code segment - -.cseg -.org 000000 - - - -; --------------------------------------------------------------------------- -; Reset and interrupt vectors (will be removed as soon as we can flash data over COM) - -; rjmp main ; Reset vector - rjmp BOOTLOADER_ADDR ; Reset vector ; use this for flashed system - reti ; EXT_INT0 - reti ; PCI0 - reti ; PCI1 - reti ; WATCHDOG - reti ; ICP1 - reti ; OC1A - reti ; OC1B - reti ; OVF1 - rjmp uartIrqIsrOC0A ; OC0A - reti ; OC0B - reti ; OVF0 - reti ; ACI - reti ; ADCC - reti ; ERDY - reti ; USI_STR - reti ; USI_OVF - - -devInfoBlock: ; 12 bytes -devInfoManufacturer: .db 'A', 'Q', 'U', 'A' -devInfoId: .db 'X', 0 -devInfoVersion: .db 3, 0 ; version, revision -firmwareVersion: .db FIRMWARE_VARIANT_ROUTER, FIRMWARE_VERSION_MAJOR - .db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL - -firmwareStart: rjmp main - - -; *************************************************************************** -; includes - -.include "common/utils.asm" -.include "common/utils_wait_fixed.asm" -;.include "common/utils_copy_from_flash.asm" -;.include "common/utils_copy_sdram.asm" -.include "common/crc8.asm" - -#include "modules/uart_irq/defs.asm" -#include "modules/uart_irq/iface.asm" -#include "modules/uart_irq/iface1.asm" -#include "modules/uart_irq/iface2.asm" - - -; *************************************************************************** -; data in SRAM - -.dseg - -programRamBegin: -ledTimer: .byte 1 -programRamEnd: - - - -; *************************************************************************** -; data in FLASH - -.cseg - - -main: - ldi xh, HIGH(programRamBegin) - ldi xl, LOW(programRamBegin) - clr r16 - ldi r17, (programRamEnd-programRamBegin) - rcall Utils_FillSram - rcall init - sbi LED_SIMPLE_DDR, LED_SIMPLE_PINNUM ; out - cbi LED_SIMPLE_PORT, LED_SIMPLE_PINNUM ; on - clr r16 - sts ledTimer, r16 - sei -main_loop: -; rcall writeTestByteToIface2 -; rcall copyFromIface1To2 -; brcc main_sleep -; rjmp main_loop - -main_sleep: - ; only modify SE, SM1 and SM0 - cli - in r16, MCUCR - ldi r17, (1< diff --git a/avr/modules/brightness/0BUILD b/avr/modules/brightness/0BUILD new file mode 100644 index 0000000..c3dec70 --- /dev/null +++ b/avr/modules/brightness/0BUILD @@ -0,0 +1,12 @@ + + + + + + main.asm + send.asm + + + + + diff --git a/avr/modules/brightness/main.asm b/avr/modules/brightness/main.asm new file mode 100644 index 0000000..2ef0eab --- /dev/null +++ b/avr/modules/brightness/main.asm @@ -0,0 +1,133 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +.equ BRIGHTNESS_INTERVAL = 97 + +.equ BRIGHTNESS_FLAGS_VALID_BIT = 7 + + +; *************************************************************************** +; data + +.dseg + +brightnessDataBegin: + brightnessTimer: .byte 1 + brightnessFlags: .byte 1 + brightnessLastValue: .byte 2 +brightnessDataEnd: + + + + +; *************************************************************************** +; code + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine Brightness_Init +; +; Init module. +; +; @return CFLAG always set + +Brightness_Init: + ; preset SRAM data area + ldi xh, HIGH(brightnessDataBegin) + ldi xl, LOW(brightnessDataBegin) + clr r16 + ldi r17, (brightnessDataEnd-brightnessDataBegin) + rcall Utils_FillSram + + ; setup pins + cbi BRIGHTNESS_ADC_PORT, BRIGHTNESS_ADC_PIN ; disable internal pullup for ADC + cbi BRIGHTNESS_ADC_DDR, BRIGHTNESS_ADC_PIN ; set ADC port as input + + ldi r16, BRIGHTNESS_ADC_MUX ; select input pin, use Vcc as reference voltage + out ADMUX, r16 + ldi r16, (0 << ADLAR) + out ADCSRB, r16 + ldi r16, (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0) ; enable, prescaler 8 + out ADCSRA, r16 + + ldi r16, BRIGHTNESS_INTERVAL + sts brightnessTimer, r16 + + sec + ret + + + +Brightness_Fini: + sec + ret + + + +; --------------------------------------------------------------------------- +; @routine Brightness_Every100ms @global +; + +Brightness_Every100ms: + lds r16, brightnessTimer + dec r16 + breq Brightness_Every100ms_readValue + sts brightnessTimer, r16 + cpi r16, 1 + breq Brightness_Every100ms_startMeasure + ret +Brightness_Every100ms_startMeasure: + sbi ADCSRA, ADSC ; start conversion + ret +Brightness_Every100ms_readValue: + sbic ADCSRA, ADSC + ret ; return if bit still set, leave brightnessTimer at "1" + ; conversion complete, read value + ldi r16, BRIGHTNESS_INTERVAL ; restart timer + sts brightnessTimer, r16 + in r16, ADCL + in r17, ADCH ; read value from ADC + sts brightnessLastValue, r16 + sts brightnessLastValue+1, r17 + ; convert to 1/0 + lds r17, brightnessFlags + sbr r17, (1< 1000000 +; begin version for > 1000000 Hz + ldi r22, clock/1000000 +com2wWaitForClockHighMulti10Us_loop0: + push r20 +com2wWaitForClockHighMulti10Us_loop: ; 10 cycles per loop + sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken) + sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken) + sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken) + nop ; +1 + dec r20 ; +1 + brne com2wWaitForClockHighMulti10Us_loop ; +2 if TRUE, +1 if FALSE + pop r20 + dec r22 ; +1 + brne com2wWaitForClockHighMulti10Us_loop0 ; +1 if FALSE, +2 if TRUE + clc ; +1 + ret ; +4 +com2wWaitForClockHighMulti10Us_stateReached: + pop r20 + sec ; +1 + ret ; +4 +; end version for > 1000000 Hz +.elif clock < 1000000 + .error "Clock speed too low" +.else +; begin version for 1000000 Hz +com2wWaitForClockHighMulti10Us_loop: ; 10 cycles per loop + sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken) + sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken) + sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken) + nop ; +1 + dec r20 ; +1 + brne com2wWaitForClockHighMulti10Us_loop ; +2 if TRUE, +1 if FALSE + clc ; +1 + ret ; +4 +com2wWaitForClockHighMulti10Us_stateReached: + sec ; +1 + ret ; +4 +; end version for 1000000 Hz +.endif +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wWaitForClockLowMulti10Us +; +; Wait for low CLK +; +; @param R20 multiple of 10us to wait (e.g. "2" for "20" us) +; @return CFLAG set if okay (state reached), cleared on error +; @clobbers: r20, r22 + +com2wWaitForClockLowMulti10Us: +.if clock > 1000000 +; begin version for > 1000000 Hz + ldi r22, clock/1000000 +com2wWaitForClockLowMulti10Us_loop0: + push r20 +com2wWaitForClockLowMulti10Us_loop: ; 10 cycles per loop + sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken) + sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken) + sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken) + nop ; +1 + dec r20 ; +1 + brne com2wWaitForClockLowMulti10Us_loop ; +2 if TRUE, +1 if FALSE + pop r20 + dec r22 ; +1 + brne com2wWaitForClockLowMulti10Us_loop0 ; +1 if FALSE, +2 if TRUE + clc ; +1 + ret ; +4 +com2wWaitForClockLowMulti10Us_stateReached: + pop r20 + sec ; +1 + ret ; +4 +; end version for > 1000000 Hz +.elif clock < 1000000 + .error "Clock speed too low" +.else +; begin version for 1000000 Hz +com2wWaitForClockLowMulti10Us_loop: ; 10 cycles per loop + sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken) + sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken) + sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken) + nop ; +1 + dec r20 ; +1 + brne com2wWaitForClockLowMulti10Us_loop ; +2 if TRUE, +1 if FALSE + clc ; +1 + ret ; +4 +com2wWaitForClockLowMulti10Us_stateReached: + sec ; +1 + ret ; +4 +; end version for 1000000 Hz +.endif +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wWaitTime1 +; +; waits for longer period (e.g. 30ns) +; +; @clobbers R22 + +com2wWaitTime1: + Utils_WaitNanoSecs COM2W_WAITTIME1, 7, r22 ; wait for longer time (minus RCALL and RET) + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wWaitTime2 +; +; waits for shorter period (e.g. 10ns) +; +; @clobbers R22 + +com2wWaitTime2: + Utils_WaitNanoSecs COM2W_WAITTIME2, 7, r22 ; wait for shorter time (minus RCALL and RET) + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wPcintIsr @global @isr +; +; ISR for PCINT0/1 +; +; @clobbers: none + +com2wPcintIsr: + push r15 + in r15, SREG + sbic COM_CLK_INPUT, COM_CLK_PIN + rjmp com2wPcintIsr_end + ; low, read packet + push r16 + push r17 + push r18 + push r19 + push r20 + push r21 + push r22 + push r24 + push r25 + push xl + push xh + push yl + push yh + ldi yl, LOW(com2w_iface) + ldi yh, HIGH(com2w_iface) + rcall com2wReceiveNextPkg ; (R16, R17, R18, R19, R20, R21, R22, R24, R25, X) + pop yh + pop yl + pop xh + pop xl + pop r25 + pop r24 + pop r22 + pop r21 + pop r20 + pop r19 + pop r18 + pop r17 + pop r16 +com2wPcintIsr_end: + out SREG, r15 + pop r15 + reti +; @end + + + +#endif ; AVR_MODULES_COM2W_COM2W_H + diff --git a/avr/modules/com2w/com2w0.asm b/avr/modules/com2w/com2w0.asm new file mode 100644 index 0000000..24a3b28 --- /dev/null +++ b/avr/modules/com2w/com2w0.asm @@ -0,0 +1,657 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AVR_MODULES_COM2W_COM2W0_H +#define AVR_MODULES_COM2W_COM2W0_H + + +.dseg + +com2w0_iface: .byte COM2W_IFACE_SIZE + + + +.cseg + + + + +; --------------------------------------------------------------------------- +; @routine COM2W0_Init +; +; @clobbers + +COM2W0_Init: + ldi yl, LOW(com2w0_iface) + ldi yh, HIGH(com2w0_iface) + rcall NET_Interface_Init ; (R16, R17, X) + ldi r16, COM2W_MODE_IDLE + rcall com2wSetMode ; (R17) + + ; setup CLK line (as input, disable internal pull-up resistor) + cbi COM_CLK0_DDR, COM_CLK0_PIN ; set CLK as input +.ifdef COM_CLK0_PUE + inr r16, COM_CLK0_PUE + cbr r16, (1<0 +com2w0_iface: .byte COM2W_IFACE_SIZE +.endif + +.if COM_PORTS >1 +com2w1_iface: .byte COM2W_IFACE_SIZE +.endif + +.if COM_PORTS >2 +com2w2_iface: .byte COM2W_IFACE_SIZE +.endif + +.if COM_PORTS >3 +com2w3_iface: .byte COM2W_IFACE_SIZE +.endif + +.if COM_PORTS >4 +com2w4_iface: .byte COM2W_IFACE_SIZE +.endif + +.if COM_PORTS >5 +com2w5_iface: .byte COM2W_IFACE_SIZE +.endif + +.if COM_PORTS >6 +com2w6_iface: .byte COM2W_IFACE_SIZE +.endif + +.if COM_PORTS >7 +com2w7_iface: .byte COM2W_IFACE_SIZE +.endif + + + + +#endif ; AVR_MODULES_COM2W_COM2WN_DATA_H + diff --git a/avr/modules/com2w/com2wn_init.asm b/avr/modules/com2w/com2wn_init.asm new file mode 100644 index 0000000..f9f97a9 --- /dev/null +++ b/avr/modules/com2w/com2wn_init.asm @@ -0,0 +1,114 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AVR_MODULES_COM2W_COM2WN_INIT_H +#define AVR_MODULES_COM2W_COM2WN_INIT_H + + +; WORK IN PROGRESS + + +; --------------------------------------------------------------------------- +; @macro mCOM2WN_INIT +; +; @param @0 interface number (beginning with 0) + +.macro mCOM2WN_INIT + ldi yl, LOW(com2w@0_iface) + ldi yh, HIGH(com2w@0_iface) + rcall com2wnInit + ldi r16, COM_MASK_CLK@0 + std Y+COM2W_IFACE_OFFS_PINMASK_CLK, r16 + ldi r16, COM_MASK_DATA@0 + std Y+COM2W_IFACE_OFFS_PINMASK_DATA, r16 + ldi r16, COM_MASK_IRQ@0 + std Y+COM2W_IFACE_OFFS_PINMASK_IRQ, r16 +.endmacro +; @end + + + + + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine COM2WN_Init +; + +COM2WN_Init: + ldi r16, 0xff ; start with all clock lines hi + sts com2wnIoCurrentClockStates, r16 + sts com2wnIoLastClockStates, r16 + + clr r16 + sts com2wnIoFlags, r16 + sts com2wnIoDisabledClockMask, r16 + + ldi yl, LOW(com2wnIoRingBuffer) + ldi yh, HIGH(com2wnIoRingBuffer) + ldi r16, COM2WN_IO_RINGBUFFER_SIZE + rcall RingBufferY_Init ; (R17) + +.if COM_PORTS >0 + mCOM2WN_INIT 0 +.endif +.if COM_PORTS >1 + mCOM2WN_INIT 1 +.endif + +.if COM_PORTS >2 + mCOM2WN_INIT 2 +.endif +.if COM_PORTS >3 + mCOM2WN_INIT 3 +.endif + +.if COM_PORTS >4 + mCOM2WN_INIT 4 +.endif +.if COM_PORTS >5 + mCOM2WN_INIT 5 +.endif + +.if COM_PORTS >6 + mCOM2WN_INIT 6 +.endif +.if COM_PORTS >7 + mCOM2WN_INIT 7 +.endif + + rcall com2wnSetupIrq + + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wInit +; + +com2wnInit: + rcall NET_Interface_Init ; (R16, R17, X) + ldi r16, COM2W_MODE_IDLE + rcall com2wSetMode ; (R17) + + rcall com2wSetupLines + rcall com2wnEnableClkIrq + ret +; @end + + + +#endif ; AVR_MODULES_COM2W_COM2WN_INIT_H + + diff --git a/avr/modules/com2w/com2wn_io.asm b/avr/modules/com2w/com2wn_io.asm new file mode 100644 index 0000000..43e9f8d --- /dev/null +++ b/avr/modules/com2w/com2wn_io.asm @@ -0,0 +1,165 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AVR_MODULES_COM2W_COM2WN_IO_H +#define AVR_MODULES_COM2W_COM2WN_IO_H + + +; WORK IN PROGRESS + + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine com2wSetupLines + +com2wSetupLines: + ; setup CLK line (as input, disable internal pull-up resistor) + rcall com2wClkSetHigh + +.ifdef COM_CLK_PUE + ldd r16, Y+COM2W_IFACE_OFFS_PINMASK_CLK + com r16 + inr r17, COM_CLK_PUE + and r17, r16 + outr COM_CLK_PUE, r17 +.endif + + ; setup DATA line (as input, disable internal pull-up resistor) + rcall com2wnDataSetHigh +.ifdef COM_DATA_PUE + ldd r16, Y+COM2W_IFACE_OFFS_PINMASK_DATA + com r16 + inr r17, COM_DATA_PUE + and r17, r16 + outr COM_DATA_PUE, r17 +.endif + + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wClkSetHigh +; +; @clobbers none + +com2wClkSetHigh: + push r16 + push r17 + ldd r16, Y+COM2W_IFACE_OFFS_PINMASK_CLK + ; clear bit in io reg (AND with complement) + com r16 + inr r17, COM_CLK_DDR + and r17, r16 + outr COM_CLK_DDR, r17 ; make pin input +.ifndef COM_CLK_PUE + inr r17, COM_CLK_OUTPUT + and r17, r16 ; disable pullup + outr COM_CLK_OUTPUT, r17 +.endif + pop r17 + pop r16 + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wnClkSetLow +; +; @param Y pointer to interface data in SRAM +; @clobbers none + +com2wnClkSetLow: + push r16 + push r17 + ldd r16, Y+COM2W_IFACE_OFFS_PINMASK_CLK + ; set bit in io reg + inr r17, COM_CLK_DDR + or r17, r16 + outr COM_CLK_DDR, r17 ; make pin output + + com r16 + inr r17, COM_CLK_OUTPUT + and r17, r16 + outr COM_CLK_OUTPUT, r17 ; set pin low + + pop r17 + pop r16 + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wnDataSetHigh +; +; @param Y pointer to interface data in SRAM +; @clobbers none + +com2wnDataSetHigh: + push r16 + push r17 + ldd r16, Y+COM2W_IFACE_OFFS_PINMASK_DATA + ; clear bit in io reg (AND with complement) + com r16 + inr r17, COM_DATA_DDR + and r17, r16 + outr COM_DATA_DDR, r17 ; make pin input +.ifndef COM_DATA_PUE + inr r17, COM_DATA_OUTPUT + and r17, r16 ; disable pullup + outr COM_DATA_OUTPUT, r17 +.endif + pop r17 + pop r16 + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wnDataSetLow +; +; @param Y pointer to interface data in SRAM +; @clobbers none + +com2wnDataSetLow: + push r16 + push r17 + ldd r16, Y+COM2W_IFACE_OFFS_PINMASK_DATA + ; set bit in io reg + inr r17, COM_DATA_DDR + or r17, r16 + outr COM_DATA_DDR, r17 ; make pin output + + com r16 + inr r17, COM_DATA_OUTPUT + and r17, r16 + outr COM_DATA_OUTPUT, r17 ; set pin low + + pop r17 + pop r16 + ret +; @end + + + + + + + + + +#endif ; AVR_MODULES_COM2W_COM2WN_IO_H + diff --git a/avr/modules/com2w/com2wn_irq.asm b/avr/modules/com2w/com2wn_irq.asm new file mode 100644 index 0000000..db5409c --- /dev/null +++ b/avr/modules/com2w/com2wn_irq.asm @@ -0,0 +1,180 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AVR_MODULES_COM2W_COM2WN_IRQ_H +#define AVR_MODULES_COM2W_COM2WN_IRQ_H + + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine com2wnSetupIrq +; + +com2wnSetupIrq: + ; setup pin-change interrupt for CLK + rcall com2wnEnableClkIrq + + ; enable PCIEn irq + inr r16, COM_IRQ_ADDR_M_CLK ; enable pin change irq PCIEn + sbr r16, (1< 1000000 +; begin version for > 1000000 Hz + push r19 + ldi r19, LOW(clock/1000000) + ldd r22, Y+COM2W_IFACE_OFFS_PINMASK_CLK ; +2 +com2wWaitForClockHighMulti10Us_loop0: + push r20 +com2wWaitForClockHighMulti10Us_loop: ; 10 cycles per loop + inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port) + and r16, r22 ; +1 + brne com2wWaitForClockHighMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE + + inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port) + and r16, r22 ; +1 + brne com2wWaitForClockHighMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE + + nop ; +1 + + dec r20 ; +1 + brne com2wWaitForClockHighMulti10Us_loop ; +2 if TRUE, +1 if FALSE + pop r20 + dec r19 ; +1 + brne com2wWaitForClockHighMulti10Us_loop0 ; +1 if FALSE, +2 if TRUE + pop r19 + clc ; +1 + ret ; +4 +com2wWaitForClockHighMulti10Us_stateReached: + pop r20 + pop r19 + sec ; +1 + ret ; +4 +; end version for > 1000000 Hz +.elif clock < 1000000 + .error "Clock speed too low" +.else +; begin version for 1000000 Hz + ldd r22, Y+COM2W_IFACE_OFFS_PINMASK_CLK ; +2 +com2wWaitForClockHighMulti10Us_loop: ; 10 cycles per loop + inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port) + and r16, r22 ; +1 + brne com2wWaitForClockHighMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE + + inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port) + and r16, r22 ; +1 + brne com2wWaitForClockHighMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE + + nop ; +1 + + dec r20 ; +1 + brne com2wWaitForClockHighMulti10Us_loop ; +2 if TRUE, +1 if FALSE + clc ; +1 + ret ; +4 +com2wWaitForClockHighMulti10Us_stateReached: + sec ; +1 + ret ; +4 +; end version for 1000000 Hz +.endif +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wWaitForClockLowMulti10Us +; +; Wait for low CLK +; +; @param R20 multiple of 10us to wait (e.g. "2" for "20" us) +; @return CFLAG set if okay (state reached), cleared on error +; @clobbers: r16, r20, r22 + +com2wWaitForClockLowMulti10Us: +.if clock > 1000000 +; begin version for > 1000000 Hz + push r19 + ldi r19, LOW(clock/1000000) + ldd r22, Y+COM2W_IFACE_OFFS_PINMASK_CLK ; +2 +com2wWaitForClockLowMulti10Us_loop0: + push r20 +com2wWaitForClockLowMulti10Us_loop: ; 10 cycles per loop + inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port) + and r16, r22 ; +1 + breq com2wWaitForClockLowMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE + + inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port) + and r16, r22 ; +1 + breq com2wWaitForClockLowMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE + + nop ; +1 + + dec r20 ; +1 + brne com2wWaitForClockLowMulti10Us_loop ; +2 if TRUE, +1 if FALSE + pop r20 + dec r19 ; +1 + brne com2wWaitForClockLowMulti10Us_loop0 ; +1 if FALSE, +2 if TRUE + pop r19 + clc ; +1 + ret ; +4 +com2wWaitForClockLowMulti10Us_stateReached: + pop r20 + pop r19 + sec ; +1 + ret ; +4 +; end version for > 1000000 Hz +.elif clock < 1000000 + .error "Clock speed too low" +.else +; begin version for 1000000 Hz + ldd r22, Y+COM2W_IFACE_OFFS_PINMASK_CLK ; +2 +com2wWaitForClockLowMulti10Us_loop: ; 10 cycles per loop + inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port) + and r16, r22 ; +1 + breq com2wWaitForClockLowMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE + + inr r16, COM_CLK_INPUT ; +1 (if low port, +2 if high port) + and r16, r22 ; +1 + breq com2wWaitForClockLowMulti10Us_stateReached ; +1 if FALSE, +2 if TRUE + + nop ; +1 + + dec r20 ; +1 + brne com2wWaitForClockLowMulti10Us_loop ; +2 if TRUE, +1 if FALSE + clc ; +1 + ret ; +4 +com2wWaitForClockLowMulti10Us_stateReached: + sec ; +1 + ret ; +4 +; end version for 1000000 Hz +.endif + + + + + + +#endif ; AVR_MODULES_COM2W_COM2WN_WAIT_H + + diff --git a/avr/modules/com2w/common.asm b/avr/modules/com2w/common.asm new file mode 100644 index 0000000..7576912 --- /dev/null +++ b/avr/modules/com2w/common.asm @@ -0,0 +1,244 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +#ifndef AVR_MODULES_COM2W_COMMON_H +#define AVR_MODULES_COM2W_COMMON_H + + + +; --------------------------------------------------------------------------- +; @routine com2wPeriodically @global +; +; @clobbers R16, Y + +com2wPeriodically: + push r15 + in r15, SREG + cli + rcall NET_Interface_Periodically + ldd r16, Y+COM2W_IFACE_OFFS_MODECOUNTER + inc r16 + breq com2wPeriodically_end + std Y+COM2W_IFACE_OFFS_MODECOUNTER, r16 +com2wPeriodically_end: + out SREG, r15 + pop r15 + ret +; @end + + + + + +; --------------------------------------------------------------------------- +; @routine com2wSetMode +; +; Doesn't change processor status flags! +; +; @param R16 mode +; @clobbers R17 + +com2wSetMode: + push r15 + in r15, SREG + cli + ldd r17, Y+COM2W_IFACE_OFFS_MODE + cp r16, r17 + breq com2wSetMode_end + std Y+COM2W_IFACE_OFFS_MODE, r16 + clr r17 + std Y+COM2W_IFACE_OFFS_MODECOUNTER, r17 +com2wSetMode_end: + out SREG, r15 + pop r15 + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wStartReading +; +; @param Y pointer to interface data in SRAM +; @clobbers R16, R17, X + +com2wStartReading: + mov xl, yl + mov xh, yh + adiw xh:xl, COM2W_IFACE_OFFS_BUFFER + std Y+COM2W_IFACE_OFFS_BUFPOS_LOW, xl + std Y+COM2W_IFACE_OFFS_BUFPOS_HIGH, xh + ldi r16, COM2W_BUFFER_SIZE + std Y+COM2W_IFACE_OFFS_BUFLEFT, r16 + clr r16 + std Y+COM2W_IFACE_OFFS_BUFUSED, r16 + ldi r16, COM2W_MODE_READING + rcall com2wSetMode ; (R17) + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wByteRecvd +; +; @param r16 byte received +; @param Y pointer to interface data +; @return CFLAG set if okay, cleared on error +; @clobbers r16, r17, r18, X + +com2wByteRecvd: + ldd xl, Y+COM2W_IFACE_OFFS_BUFPOS_LOW + ldd xh, Y+COM2W_IFACE_OFFS_BUFPOS_HIGH + ldd r17, Y+COM2W_IFACE_OFFS_BUFLEFT + ldd r18, Y+COM2W_IFACE_OFFS_BUFUSED + tst r17 + breq com2wByteRecvd_overflow + st X+, r16 + std Y+COM2W_IFACE_OFFS_BUFPOS_LOW, xl + std Y+COM2W_IFACE_OFFS_BUFPOS_HIGH, xh + inc r18 + std Y+COM2W_IFACE_OFFS_BUFUSED, r18 + dec r17 + std Y+COM2W_IFACE_OFFS_BUFLEFT, r17 + breq com2wByteRecvd_msgComplete + cpi r18, 2 + sec + brne com2wByteRecvd_end + + ; determine msg size + inc r16 ; last byte was payload length, add byte for crc + cp r17, r16 ; compare remaining length against remaining space + brcs com2wByteRecvd_eMsgSize + std Y+COM2W_IFACE_OFFS_BUFLEFT, r16 + tst r16 + sec + brne com2wByteRecvd_end +com2wByteRecvd_msgComplete: + push r19 ; pushing these registers is now only needed *here* for every + push r20 ; message received. Otherwise they would have been pushed + push r24 ; on every bit adding much more execution time to the + push r25 ; irq service routine + push zl + push zh + rcall com2wMsgReceived ; (R16, R17, R18, R19, R20, R24, R25, X, Z) + pop zh + pop zl + pop r25 + pop r24 + pop r20 + pop r19 + rjmp com2wByteRecvd_end +com2wByteRecvd_overflow: + ldi r16, NET_IFACE_OFFS_ERR_MISSED_LOW + rjmp com2wByteRecvd_error +com2wByteRecvd_eMsgSize: + + ldi r16, NET_IFACE_OFFS_ERR_MSGSIZE_LOW +com2wByteRecvd_error: + push r24 + push r25 + rcall NET_Interface_IncCounter16 ; (R24, R25) + pop r25 + pop r24 + ldi r16, COM2W_MODE_SKIPPING ; error, enter skipping mode + rcall com2wSetMode + clc +com2wByteRecvd_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wMsgReceived +; +; @param Y pointer to interface data in SRAM +; @return CFLAG set if okay, cleared on error +; @clobbers R16, R17, R18, X, Z (R19, R20, R24, R25) + +com2wMsgReceived: + mov xl, yl + mov xh, yh + adiw xh:xl, COM2W_IFACE_OFFS_BUFFER + mov zl, xl ; Z=buffer in IFACE + mov zh, xh + rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X) + brcc com2wMsgReceived_econtent + ; msg valid, alloc buffer + rcall NET_Buffer_Alloc ; X=buffer, R16=bufnum (R16, R17, X) + brcc com2wMsgReceived_enobuf + mov r18, r16 ; buffer num + rcall NET_Interface_SetIfaceNumInBuffer ; (R16, R17) + adiw xh:xl, 1 ; skip buffer header + ldd r17, Y+COM2W_IFACE_OFFS_BUFUSED ; always is at least 2 here +com2wMsgReceived_copyLoop: + ld r16, Z+ + st X+, r16 + dec r17 + brne com2wMsgReceived_copyLoop + mov r16, r18 ; buffer num + rcall NET_AddIncomingMsgNum ; (R17, R18, X) + brcc com2wMsgReceived_enoadd + ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW + rcall NET_Interface_IncCounter16 ; (R24, R25) + sec + rjmp com2wMsgReceived_setIdleAndEnd +com2wMsgReceived_enoadd: + rcall NET_Buffer_ReleaseByNum + rjmp com2wMsgReceived_enobuf +com2wMsgReceived_enobuf: + ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW + rjmp com2wMsgReceived_err +com2wMsgReceived_econtent: + ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW +com2wMsgReceived_err: + rcall NET_Interface_IncCounter16 ; (R24, R25) + clc +com2wMsgReceived_setIdleAndEnd: + ldi r16, COM2W_MODE_IDLE + rcall com2wSetMode ; (R17, doesn't change CFLAG!) +com2wMsgReceived_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wWaitTime1 +; +; waits for longer period (e.g. 30ns) +; +; @clobbers R22 + +com2wWaitTime1: + Utils_WaitNanoSecs COM2W_WAITTIME1, 7, r22 ; wait for longer time (minus RCALL and RET) + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wWaitTime2 +; +; waits for shorter period (e.g. 10ns) +; +; @clobbers R22 + +com2wWaitTime2: + Utils_WaitNanoSecs COM2W_WAITTIME2, 7, r22 ; wait for shorter time (minus RCALL and RET) + ret +; @end + + + + +#endif ; AVR_MODULES_COM2W_COMMON_H + diff --git a/avr/modules/com2w/defs.asm b/avr/modules/com2w/defs.asm new file mode 100644 index 0000000..56b9a12 --- /dev/null +++ b/avr/modules/com2w/defs.asm @@ -0,0 +1,78 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AVR_MODULES_COM2W_DEFS_H +#define AVR_MODULES_COM2W_DEFS_H + + +.equ COM2W_WAITTIME1 = 25000 +.equ COM2W_WAITTIME2 = 15000 + +.equ COM2W_SKIPPING_MAXREADCOUNTER = 1 +.equ COM2W_SKIPPING_MAXMODECOUNTER = 20 ; stay max 2s in skipping mode + +.equ COM2W_READING_MAXREADCOUNTER = 1 +.equ COM2W_READING_MAXMODECOUNTER = 20 ; stay max 2s in reading mode + + +; +; .equ COM2W_DATA0_DDR = DDRA +; .equ COM2W_DATA0_INPUT = PINA +; .equ COM2W_DATA0_OUTPUT = PORTA +; .equ COM2W_DATA0_PUE = PUEA +; .equ COM2W_DATA0_PIN = PORTA2 +; +; .equ COM2W_CLK0_DDR = DDRA +; .equ COM2W_CLK0_INPUT = PINA +; .equ COM2W_CLK0_OUTPUT = PORTA +; .equ COM2W_CLK0_PUE = PUEA +; .equ COM2W_CLK0_PIN = PORTA0 + +; .equ COM2W_IRQ_ADDR_CLK0 = PCMSK0 +; .equ COM2W_IRQ_BIT_CLK0 = PCINT0 ; bit 0 in PCMSK0 +; .equ COM2W_IRQ_GIFR_CLK0 = PCIF0 +; .equ COM2W_IRQ_GIMSK_CLK0 = PCIE0 + + + + +.equ COM2W_BUFFER_SIZE = NET_BUFFERS_SIZE-1 + +.equ COM2W_IO_RINGBUFFER_SIZE = 128 +.equ COM2W_IO_FLAGS_BIT_OVR = 7 + +.equ COM2W_MODE_IDLE = 0 +.equ COM2W_MODE_READING = 1 +.equ COM2W_MODE_SKIPPING = 2 +.equ COM2W_MODE_WRITING = 3 +.equ COM2W_MODE_NUM = 4 + + +.equ COM2W_IFACE_OFFS_BEGIN = NET_IFACE_SIZE +.equ COM2W_IFACE_OFFS_PINMASK_CLK = COM2W_IFACE_OFFS_BEGIN +.equ COM2W_IFACE_OFFS_PINMASK_DATA = COM2W_IFACE_OFFS_BEGIN+1 +.equ COM2W_IFACE_OFFS_PINMASK_IRQ = COM2W_IFACE_OFFS_BEGIN+2 +.equ COM2W_IFACE_OFFS_CURRBYTE = COM2W_IFACE_OFFS_BEGIN+3 +.equ COM2W_IFACE_OFFS_BITCOUNTER = COM2W_IFACE_OFFS_BEGIN+4 +.equ COM2W_IFACE_OFFS_MODE = COM2W_IFACE_OFFS_BEGIN+5 +.equ COM2W_IFACE_OFFS_MODECOUNTER = COM2W_IFACE_OFFS_BEGIN+6 +.equ COM2W_IFACE_OFFS_BUFPOS_LOW = COM2W_IFACE_OFFS_BEGIN+7 +.equ COM2W_IFACE_OFFS_BUFPOS_HIGH = COM2W_IFACE_OFFS_BEGIN+8 +.equ COM2W_IFACE_OFFS_BUFUSED = COM2W_IFACE_OFFS_BEGIN+9 +.equ COM2W_IFACE_OFFS_BUFLEFT = COM2W_IFACE_OFFS_BEGIN+10 +.equ COM2W_IFACE_OFFS_BUFFER = COM2W_IFACE_OFFS_BEGIN+11 + +.equ COM2W_IFACE_SIZE = COM2W_IFACE_OFFS_BUFFER+COM2W_BUFFER_SIZE + + + + +#endif ; AVR_MODULES_COM2W_DEFS_H + + diff --git a/avr/modules/comproto/MESSAGES b/avr/modules/comproto/MESSAGES index 1f1b0dd..b0172ae 100644 --- a/avr/modules/comproto/MESSAGES +++ b/avr/modules/comproto/MESSAGES @@ -165,10 +165,11 @@ Offset Length Meaning 2 1 command code 3 1 source address --------------------------------------------------------- - 4 4 UID of the sending node - 8 2 packets out - 10 2 collisions - 12 2 line busy errors + 4 1 Interface number + 5 4 UID of the sending node + 9 2 packets out + 11 2 collisions + 13 2 line busy errors --------------------------------------------------------- 14 1 CRC8 byte @@ -185,15 +186,16 @@ Offset Length Meaning 2 1 command code 3 1 source address --------------------------------------------------------- - 4 4 UID of the sending node - 8 2 packets in - 10 2 content errors (invalid msg length, CRC errors) - 12 2 io errors - 14 2 no buffer errors - 16 2 handled packets - 18 2 missed packets + 4 1 Interface number + 5 4 UID of the sending node + 9 2 packets in + 11 2 content errors (invalid msg length, CRC errors) + 13 2 io errors + 15 2 no buffer errors + 17 2 handled packets + 19 2 missed packets --------------------------------------------------------- - 20 1 CRC8 byte + 21 1 CRC8 byte @@ -306,10 +308,10 @@ Offset Length Meaning 2 1 command code 3 1 source address --------------------------------------------------------- - 4 2 msg id/ref msg id - 6 n data bytes + 4 4 ROM address + 8 n data bytes --------------------------------------------------------- - 6+n 1 CRC8 byte + 8+n 1 CRC8 byte diff --git a/avr/modules/flash/0BUILD b/avr/modules/flash/0BUILD index 53f3762..d6e181c 100644 --- a/avr/modules/flash/0BUILD +++ b/avr/modules/flash/0BUILD @@ -9,6 +9,7 @@ flash4p.asm flashxp.asm flashprocess.asm + io_stub.asm io.asm io_attn.asm io_bitbang.asm diff --git a/avr/modules/flash/io_com2w.asm b/avr/modules/flash/io_com2w.asm new file mode 100644 index 0000000..cfc9fe1 --- /dev/null +++ b/avr/modules/flash/io_com2w.asm @@ -0,0 +1,551 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AVR_MODULES_FLASH_IO_COM2W_H +#define AVR_MODULES_FLASH_IO_COM2W_H + + + +.equ COM2W_WAITTIME1 = 25000 +.equ COM2W_WAITTIME2 = 15000 + + + + +; *************************************************************************** +; code + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine ioRawInit +; +; Init raw message subsystem. +; + +ioRawInit: + ; setup CLK line (as input, disable internal pull-up resistor) + cbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as input +.ifdef COM_CLK_PUE + inr r16, COM_CLK_PUE + cbr r16, (1< 1000000 +; begin version for > 1000000 Hz + ldi r22, clock/1000000 +com2wWaitForClockLowMulti10Us_loop0: + push r20 +com2wWaitForClockLowMulti10Us_loop: ; 10 cycles per loop + sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken) + sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken) + sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken) + nop ; +1 + dec r20 ; +1 + brne com2wWaitForClockLowMulti10Us_loop ; +2 if TRUE, +1 if FALSE + pop r20 + dec r22 ; +1 + brne com2wWaitForClockLowMulti10Us_loop0 ; +1 if FALSE, +2 if TRUE + clc ; +1 + ret ; +4 +com2wWaitForClockLowMulti10Us_stateReached: + pop r20 + sec ; +1 + ret ; +4 +; end version for > 1000000 Hz +.elif clock < 1000000 + .error "Clock speed too low" +.else +; begin version for 1000000 Hz +com2wWaitForClockLowMulti10Us_loop: ; 10 cycles per loop + sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken) + sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken) + sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockLowMulti10Us_stateReached ; (+2 if taken) + nop ; +1 + dec r20 ; +1 + brne com2wWaitForClockLowMulti10Us_loop ; +2 if TRUE, +1 if FALSE + clc ; +1 + ret ; +4 +com2wWaitForClockLowMulti10Us_stateReached: + sec ; +1 + ret ; +4 +; end version for 1000000 Hz +.endif +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wWaitForClockHighMulti10Us +; +; Wait for high CLK +; +; @param R20 multiple of 10us to wait (e.g. "2" for "20" us) +; @return CFLAG set if okay (state reached), cleared on error +; @clobbers: r20, r22 + +com2wWaitForClockHighMulti10Us: +.if clock > 1000000 +; begin version for > 1000000 Hz + ldi r22, clock/1000000 +com2wWaitForClockHighMulti10Us_loop0: + push r20 +com2wWaitForClockHighMulti10Us_loop: ; 10 cycles per loop + sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken) + sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken) + sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken) + nop ; +1 + dec r20 ; +1 + brne com2wWaitForClockHighMulti10Us_loop ; +2 if TRUE, +1 if FALSE + pop r20 + dec r22 ; +1 + brne com2wWaitForClockHighMulti10Us_loop0 ; +1 if FALSE, +2 if TRUE + clc ; +1 + ret ; +4 +com2wWaitForClockHighMulti10Us_stateReached: + pop r20 + sec ; +1 + ret ; +4 +; end version for > 1000000 Hz +.elif clock < 1000000 + .error "Clock speed too low" +.else +; begin version for 1000000 Hz +com2wWaitForClockHighMulti10Us_loop: ; 10 cycles per loop + sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken) + sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken) + sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken + rjmp com2wWaitForClockHighMulti10Us_stateReached ; (+2 if taken) + nop ; +1 + dec r20 ; +1 + brne com2wWaitForClockHighMulti10Us_loop ; +2 if TRUE, +1 if FALSE + clc ; +1 + ret ; +4 +com2wWaitForClockHighMulti10Us_stateReached: + sec ; +1 + ret ; +4 +; end version for 1000000 Hz +.endif +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wWaitTime1 +; +; waits for longer period (e.g. 30ns) +; +; @clobbers R22 + +com2wWaitTime1: + Utils_WaitNanoSecs COM2W_WAITTIME1, 7, r22 ; wait for longer time (minus RCALL and RET) + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine com2wWaitTime2 +; +; waits for shorter period (e.g. 10ns) +; +; @clobbers R22 + +com2wWaitTime2: + Utils_WaitNanoSecs COM2W_WAITTIME2, 7, r22 ; wait for shorter time (minus RCALL and RET) + ret +; @end + + + + +#endif ; AVR_MODULES_FLASH_IO_COM2W_H + diff --git a/avr/modules/flash/io_stub.asm b/avr/modules/flash/io_stub.asm new file mode 100644 index 0000000..d0a892c --- /dev/null +++ b/avr/modules/flash/io_stub.asm @@ -0,0 +1,60 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +; *************************************************************************** +; code + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine ioRawInit +; +; Init raw message subsystem. +; + +ioRawInit: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine ioRawSendMsg +; +; Send a message +; + +ioRawSendMsg: + ret +; @end + + + + +; --------------------------------------------------------------------------- +; @routine ioRawWaitForValidMsg +; +; Wait for valid incoming msg +; +; @return CFLAG set if okay (packet received), cleared on error + +ioRawWaitForValidMsg: + ret +; @end + + + + + + + diff --git a/avr/modules/flash/io_uart0.asm b/avr/modules/flash/io_uart0.asm new file mode 100644 index 0000000..8934246 --- /dev/null +++ b/avr/modules/flash/io_uart0.asm @@ -0,0 +1,31 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +.equ UART_REG_UDR = UDR0 +.equ UART_REG_UCSRA = UCSR0A +.equ UART_REG_UCSRB = UCSR0B +.equ UART_REG_UCSRC = UCSR0C +.equ UART_REG_UBRRL = UBRR0L +.equ UART_REG_UBRRH = UBRR0H + +.equ UART_BIT_UCSZ0 = UCSZ00 +.equ UART_BIT_UDRE = UDRE0 +.equ UART_BIT_RXC = RXC0 +.equ UART_BIT_TXC = TXC0 +.equ UART_BIT_FE = FE0 +.equ UART_BIT_DOR = DOR0 +.equ UART_BIT_UPE = UPE0 +.equ UART_BIT_RXEN = RXEN0 +.equ UART_BIT_TXEN = TXEN0 + + + + diff --git a/avr/modules/flash/io_uart_all.asm b/avr/modules/flash/io_uart_all.asm index 118d900..e772ba5 100644 --- a/avr/modules/flash/io_uart_all.asm +++ b/avr/modules/flash/io_uart_all.asm @@ -46,13 +46,6 @@ ioRawInit: ori r16, (1< diff --git a/avr/modules/lcd2/font/defs.asm b/avr/modules/lcd2/font/defs.asm index d2908c3..4a24aeb 100644 --- a/avr/modules/lcd2/font/defs.asm +++ b/avr/modules/lcd2/font/defs.asm @@ -11,13 +11,22 @@ #define AVR_MODULES_FONT_DEFS -.equ FONT_OFFS_RENDERFN_LOW = 0 -.equ FONT_OFFS_RENDERFN_HI = 1 -.equ FONT_OFFS_DATASIZE = 2 ; one byte used, one byte reserved -.equ FONT_OFFS_WIDTH = 4 -.equ FONT_OFFS_HEIGHT = 5 -.equ FONT_OFFS_FIRSTCHAR = 6 -.equ FONT_OFFS_NUMCHARS = 7 +.equ FONT_OFFS_HANDLERFN_LOW = 0 +.equ FONT_OFFS_HANDLERFN_HI = 1 +.equ FONT_OFFS_DATASIZE = 2 ; one byte used, one byte reserved +.equ FONT_OFFS_WIDTH = 4 +.equ FONT_OFFS_HEIGHT = 5 +.equ FONT_OFFS_FIRSTCHAR = 6 +.equ FONT_OFFS_NUMCHARS = 7 + + + +.equ FONT_FN_RENDER = 0 +.equ FONT_FN_GETCHARWIDTH = 1 +.equ FONT_FN_GETCHARHEIGHT = 2 +.equ FONT_FN_GETSTRINGWIDTH = 3 +.equ FONT_FN_GETSTRINGHEIGHT = 4 +.equ FONT_FN_NEXT = 5 diff --git a/avr/modules/lcd2/font/font1.asm b/avr/modules/lcd2/font/font1.asm index 7fd4710..908b2a0 100644 --- a/avr/modules/lcd2/font/font1.asm +++ b/avr/modules/lcd2/font/font1.asm @@ -26,7 +26,7 @@ font1_8x8: ; header - .dw font8x8MonoRenderCharacter ; renderFn + .dw font6x8MonoHandlerFn ; handlerFn .db 128, 0 ; needed buffer size .db 8, 8 ; width, height of chars .db 32, 64 ; first char, num of chars in font diff --git a/avr/modules/lcd2/font/font12x16.asm b/avr/modules/lcd2/font/font12x16.asm new file mode 100644 index 0000000..4e10f93 --- /dev/null +++ b/avr/modules/lcd2/font/font12x16.asm @@ -0,0 +1,117 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +; *************************************************************************** +; code + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine font12x16MonoHandlerFn +; +; Handler for 12x16 Mono Fonts +; + +font12x16MonoHandlerFn: + cpi r23, FONT_FN_RENDER + breq font12x16MonoRenderCharacter + rjmp FONT_GenericHandler +; @end + + + +; --------------------------------------------------------------------------- +; @routine font12x16RenderCharacter + +; @param R16 character to write +; @param R1:R0 background color +; @param R3:R2 foreground color +; @param Z pointer to font +; @param X pointer to RAM to store data to +; @param r18 char width in pixel +; @param r19 char height in pixel +; @clobbers r17, r18, r23, r24, r25, x + +font12x16MonoRenderCharacter: + push zl + push zh + rcall font12x16GetCharPosInFont ; (r17, r24, r25, z) + ldi r25, 16 ; 16 bytes height +font12x16MonoRenderCharacter_loop1: + ldi r24, 12 ; 16 bits + ldi r23, 8 + lpm r17, Z+ +font12x16MonoRenderCharacter_loop2: + dec r23 + brne font12x16MonoRenderCharacter_haveByte + lpm r17, Z+ + ldi r23, 8 +font12x16MonoRenderCharacter_haveByte: + lsr r17 + brcs font12x16MonoRenderCharacter_writeForeground + st X+, r0 + st X+, r1 + rjmp font12x16MonoRenderCharacter_loop2end +font12x16MonoRenderCharacter_writeForeground: + st X+, r2 + st X+, r3 +font12x16MonoRenderCharacter_loop2end: + dec r24 + brne font12x16MonoRenderCharacter_loop2 + dec r25 + brne font12x16MonoRenderCharacter_loop1 + ldi r18, 12 + ldi r19, 16 + pop zh + pop zl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine font12x16GetCharPosInFont + +; @param R16 character to write +; @param Z pointer to font +; @return Z pointer to begin of char data +; @clobbers r17, r24, r25, z + +font12x16GetCharPosInFont: + mov r24, r16 + adiw zh:zl, FONT_OFFS_FIRSTCHAR + lpm r24, Z+ ; first char num + lpm r25, Z+ ; num of chars + sub r16, r24 + brcs font12x16GetCharPosInFont_ret + cp r16, r25 + brcc font12x16GetCharPosInFont_ret + mov r25, r16 ; x256 + clr r24 + + lsr r25 ; x128 + ror r24 + + lsr r25 ; x64 + ror r24 + + lsr r25 ; x32 + ror r24 + + add zl, r24 + adc zh, r25 +font12x16GetCharPosInFont_ret: + ret +; @end + + + diff --git a/avr/modules/lcd2/font/font12x20.asm b/avr/modules/lcd2/font/font12x20.asm new file mode 100644 index 0000000..73ac5bb --- /dev/null +++ b/avr/modules/lcd2/font/font12x20.asm @@ -0,0 +1,129 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +; *************************************************************************** +; code + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine font12x20MonoHandlerFn +; +; Handler for 12x20 Mono Fonts +; + +font12x20MonoHandlerFn: + cpi r23, FONT_FN_RENDER + breq font12x20MonoRenderCharacter + bigjmp FONT_GenericHandler +; @end + + + + +; --------------------------------------------------------------------------- +; @routine font12x20RenderCharacter + +; @param R16 character to write +; @param R1:R0 background color +; @param R3:R2 foreground color +; @param Z pointer to font +; @param X pointer to RAM to store data to +; @param r18 char width in pixel +; @param r19 char height in pixel +; @clobbers r17, r18, r23, r24, r25, x + +font12x20MonoRenderCharacter: + push zl + push zh + rcall font12x20GetCharPosInFont ; (r17, r24, r25, z) + ldi r25, 20 ; 20 bytes height +font12x20MonoRenderCharacter_loop1: + ldi r24, 12 ; 16 bits + ldi r23, 8 + lpm r17, Z+ +font12x20MonoRenderCharacter_loop2: + dec r23 + brne font12x20MonoRenderCharacter_haveByte + lpm r17, Z+ + ldi r23, 8 +font12x20MonoRenderCharacter_haveByte: + lsr r17 + brcs font12x20MonoRenderCharacter_writeForeground + st X+, r0 + st X+, r1 + rjmp font12x20MonoRenderCharacter_loop2end +font12x20MonoRenderCharacter_writeForeground: + st X+, r2 + st X+, r3 +font12x20MonoRenderCharacter_loop2end: + dec r24 + brne font12x20MonoRenderCharacter_loop2 + dec r25 + brne font12x20MonoRenderCharacter_loop1 + ldi r18, 12 + ldi r19, 20 + pop zh + pop zl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine font12x20GetCharPosInFont + +; @param R16 character to write +; @param Z pointer to font +; @return Z pointer to begin of char data +; @clobbers r17, r24, r25, z + +font12x20GetCharPosInFont: + mov r24, r16 + adiw zh:zl, FONT_OFFS_FIRSTCHAR + lpm r24, Z+ ; first char num + lpm r25, Z+ ; num of chars + sub r16, r24 + brcs font12x20GetCharPosInFont_ret + cp r16, r25 + brcc font12x20GetCharPosInFont_ret + + mov r24, r16 + clr r25 + + lsl r24 ; x2 + rol r25 + + lsl r24 ; x4 + rol r25 + + add r24, r16 ; x5 + adc r25, r16 + sub r25, r16 + + lsl r24 ; x10 + rol r25 + + lsl r24 ; x20 + rol r25 + + lsl r24 ; x40 + rol r25 + + add zl, r24 + adc zh, r25 +font12x20GetCharPosInFont_ret: + ret +; @end + + + diff --git a/avr/modules/lcd2/font/font16x26.asm b/avr/modules/lcd2/font/font16x26.asm new file mode 100644 index 0000000..445e841 --- /dev/null +++ b/avr/modules/lcd2/font/font16x26.asm @@ -0,0 +1,123 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +; *************************************************************************** +; code + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine font16x26MonoHandlerFn +; +; Handler for 16x26 Mono Fonts +; + +font16x26MonoHandlerFn: + cpi r23, FONT_FN_RENDER + breq font16x26MonoRenderCharacter + rjmp FONT_GenericHandler +; @end + + + + +; --------------------------------------------------------------------------- +; @routine font16x26RenderCharacter + +; @param R16 character to write +; @param R1:R0 background color +; @param R3:R2 foreground color +; @param Z pointer to font +; @param X pointer to RAM to store data to +; @param r18 char width in pixel +; @param r19 char height in pixel +; @clobbers r17, r18, r24, r25, x + +font16x26MonoRenderCharacter: + push zl + push zh + rcall font16x26GetCharPosInFont ; (r17, r24, r25, z) + ldi r25, 26 ; 26 bytes height +font16x26MonoRenderCharacter_loop1: + ldi r24, 16 ; 16 bits +font16x26MonoRenderCharacter_loop2: + mov r23, r24 + andi r23, 7 + brne font16x26MonoRenderCharacter_haveByte + lpm r17, Z+ +font16x26MonoRenderCharacter_haveByte: + lsr r17 + brcs font16x26MonoRenderCharacter_writeForeground + st X+, r0 + st X+, r1 + rjmp font16x26MonoRenderCharacter_loop2end +font16x26MonoRenderCharacter_writeForeground: + st X+, r2 + st X+, r3 +font16x26MonoRenderCharacter_loop2end: + dec r24 + brne font16x26MonoRenderCharacter_loop2 + dec r25 + brne font16x26MonoRenderCharacter_loop1 + ldi r18, 16 + ldi r19, 26 + pop zh + pop zl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine font16x26GetCharPosInFont + +; @param R16 character to write +; @param Z pointer to font +; @return Z pointer to begin of char data +; @clobbers r17, r24, r25, z + +font16x26GetCharPosInFont: + mov r24, r16 + adiw zh:zl, FONT_OFFS_FIRSTCHAR + lpm r24, Z+ ; first char num + lpm r25, Z+ ; num of chars + sub r16, r24 + brcs font16x26GetCharPosInFont_ret + cp r16, r25 + brcc font16x26GetCharPosInFont_ret + mov r24, r16 + clr r25 + lsl r24 ; x2 + rol r25 + add r24, r16 ; x3 + adc r25, r16 + sub r25, r16 + lsl r24 ; x6 + rol r25 + lsl r24 ; x12 + rol r25 + add r24, r16 ; x13 + adc r25, r16 + sub r25, r16 + lsl r24 ; x26 + rol r25 + lsl r24 ; x52 + rol r25 + + add zl, r24 + adc zh, r25 +font16x26GetCharPosInFont_ret: + ret +; @end + + + diff --git a/avr/modules/lcd2/font/font2.asm b/avr/modules/lcd2/font/font2.asm index 6c6ec79..973b932 100644 --- a/avr/modules/lcd2/font/font2.asm +++ b/avr/modules/lcd2/font/font2.asm @@ -26,12 +26,11 @@ font2_6x8: ; header - .dw font6x8MonoRenderCharacter ; renderFn + .dw font6x8MonoHandlerFn ; handlerFn .db 96, 0 ; needed buffer size .db 6, 8 ; width, height of chars - .db 32, 65 ; first char, num of chars in font + .db 32, 224 ; first char, num of chars in font ; data (6x8_horizontal_LSB_2) -font: .db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x20 .db 0x08,0x1C,0x1C,0x08,0x08,0x00,0x08,0x00, ; 0x21 .db 0x36,0x36,0x12,0x00,0x00,0x00,0x00,0x00, ; 0x22 @@ -97,83 +96,162 @@ font: .db 0x08,0x14,0x22,0x00,0x00,0x00,0x00,0x00, ; 0x5E .db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F, ; 0x5F .db 0x0C,0x0C,0x08,0x00,0x00,0x00,0x00,0x00, ; 0x60 - - - - - - - - - - - -#if 0 -.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x20 -.db 0x20,0x70,0x70,0x20,0x20,0x00,0x20,0x00, ; 0x21 -.db 0xD8,0xD8,0x48,0x00,0x00,0x00,0x00,0x00, ; 0x22 -.db 0x00,0x50,0xF8,0x50,0x50,0xF8,0x50,0x00, ; 0x23 -.db 0x10,0x70,0x08,0x30,0x40,0x38,0x20,0x00, ; 0x24 -.db 0x98,0x98,0x40,0x20,0x10,0xC8,0xC8,0x00, ; 0x25 -.db 0x10,0x28,0x28,0x10,0xA8,0x48,0xB0,0x00, ; 0x26 -.db 0x30,0x30,0x10,0x00,0x00,0x00,0x00,0x00, ; 0x27 -.db 0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x00, ; 0x28 -.db 0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x00, ; 0x29 -.db 0x00,0x50,0x70,0xF8,0x70,0x50,0x00,0x00, ; 0x2A -.db 0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00, ; 0x2B -.db 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x10, ; 0x2C -.db 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, ; 0x2D -.db 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00, ; 0x2E -.db 0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00, ; 0x2F -.db 0x70,0x88,0xC8,0xA8,0x98,0x88,0x70,0x00, ; 0x30 -.db 0x20,0x30,0x20,0x20,0x20,0x20,0x70,0x00, ; 0x31 -.db 0x70,0x88,0x80,0x60,0x10,0x08,0xF8,0x00, ; 0x32 -.db 0x70,0x88,0x80,0x70,0x80,0x88,0x70,0x00, ; 0x33 -.db 0x40,0x60,0x50,0x48,0xF8,0x40,0x40,0x00, ; 0x34 -.db 0xF8,0x08,0x08,0x78,0x80,0x88,0x70,0x00, ; 0x35 -.db 0x60,0x10,0x08,0x78,0x88,0x88,0x70,0x00, ; 0x36 -.db 0xF8,0x80,0x40,0x20,0x10,0x10,0x10,0x00, ; 0x37 -.db 0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00, ; 0x38 -.db 0x70,0x88,0x88,0xF0,0x80,0x40,0x30,0x00, ; 0x39 -.db 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x00, ; 0x3A -.db 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x10, ; 0x3B -.db 0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00, ; 0x3C -.db 0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00, ; 0x3D -.db 0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x00, ; 0x3E -.db 0x70,0x88,0x80,0x60,0x20,0x00,0x20,0x00, ; 0x3F -.db 0x70,0x88,0xE8,0xA8,0xE8,0x08,0x70,0x00, ; 0x40 -.db 0x70,0x88,0x88,0x88,0xF8,0x88,0x88,0x00, ; 0x41 -.db 0x78,0x88,0x88,0x78,0x88,0x88,0x78,0x00, ; 0x42 -.db 0x70,0x88,0x08,0x08,0x08,0x88,0x70,0x00, ; 0x43 -.db 0x78,0x88,0x88,0x88,0x88,0x88,0x78,0x00, ; 0x44 -.db 0xF8,0x08,0x08,0x78,0x08,0x08,0xF8,0x00, ; 0x45 -.db 0xF8,0x08,0x08,0x78,0x08,0x08,0x08,0x00, ; 0x46 -.db 0x70,0x88,0x08,0xE8,0x88,0x88,0xF0,0x00, ; 0x47 -.db 0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00, ; 0x48 -.db 0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00, ; 0x49 -.db 0x80,0x80,0x80,0x80,0x88,0x88,0x70,0x00, ; 0x4A -.db 0x88,0x48,0x28,0x18,0x28,0x48,0x88,0x00, ; 0x4B -.db 0x08,0x08,0x08,0x08,0x08,0x08,0xF8,0x00, ; 0x4C -.db 0x88,0xD8,0xA8,0x88,0x88,0x88,0x88,0x00, ; 0x4D -.db 0x88,0x98,0xA8,0xC8,0x88,0x88,0x88,0x00, ; 0x4E -.db 0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00, ; 0x4F -.db 0x78,0x88,0x88,0x78,0x08,0x08,0x08,0x00, ; 0x50 -.db 0x70,0x88,0x88,0x88,0xA8,0x48,0xB0,0x00, ; 0x51 -.db 0x78,0x88,0x88,0x78,0x48,0x88,0x88,0x00, ; 0x52 -.db 0x70,0x88,0x08,0x70,0x80,0x88,0x70,0x00, ; 0x53 -.db 0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x00, ; 0x54 -.db 0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00, ; 0x55 -.db 0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00, ; 0x56 -.db 0x88,0x88,0xA8,0xA8,0xA8,0xA8,0x50,0x00, ; 0x57 -.db 0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00, ; 0x58 -.db 0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x00, ; 0x59 -.db 0x78,0x40,0x20,0x10,0x08,0x08,0x78,0x00, ; 0x5A -.db 0x70,0x10,0x10,0x10,0x10,0x10,0x70,0x00, ; 0x5B -.db 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00, ; 0x5C -.db 0x70,0x40,0x40,0x40,0x40,0x40,0x70,0x00, ; 0x5D -.db 0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00, ; 0x5E -.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, ; 0x5F -.db 0x30,0x30,0x20,0x00,0x00,0x00,0x00,0x00, ; 0x60 -#endif - - +.db 0x00,0x00,0x1C,0x20,0x3C,0x22,0x3C,0x00, ; 0x61 +.db 0x02,0x02,0x1E,0x22,0x22,0x22,0x1E,0x00, ; 0x62 +.db 0x00,0x00,0x1C,0x22,0x02,0x22,0x1C,0x00, ; 0x63 +.db 0x20,0x20,0x3C,0x22,0x22,0x22,0x3C,0x00, ; 0x64 +.db 0x00,0x00,0x1C,0x22,0x1E,0x02,0x1C,0x00, ; 0x65 +.db 0x18,0x04,0x04,0x1E,0x04,0x04,0x04,0x00, ; 0x66 +.db 0x00,0x00,0x3C,0x22,0x22,0x3C,0x20,0x1C, ; 0x67 +.db 0x02,0x02,0x0E,0x12,0x12,0x12,0x12,0x00, ; 0x68 +.db 0x08,0x00,0x08,0x08,0x08,0x08,0x18,0x00, ; 0x69 +.db 0x10,0x00,0x18,0x10,0x10,0x10,0x12,0x0C, ; 0x6A +.db 0x02,0x02,0x12,0x0A,0x06,0x0A,0x12,0x00, ; 0x6B +.db 0x08,0x08,0x08,0x08,0x08,0x08,0x18,0x00, ; 0x6C +.db 0x00,0x00,0x16,0x2A,0x2A,0x22,0x22,0x00, ; 0x6D +.db 0x00,0x00,0x0E,0x12,0x12,0x12,0x12,0x00, ; 0x6E +.db 0x00,0x00,0x1C,0x22,0x22,0x22,0x1C,0x00, ; 0x6F +.db 0x00,0x00,0x1E,0x22,0x22,0x22,0x1E,0x02, ; 0x70 +.db 0x00,0x00,0x3C,0x22,0x22,0x22,0x3C,0x20, ; 0x71 +.db 0x00,0x00,0x1A,0x24,0x04,0x04,0x0E,0x00, ; 0x72 +.db 0x00,0x00,0x1C,0x02,0x1C,0x20,0x1C,0x00, ; 0x73 +.db 0x00,0x04,0x1E,0x04,0x04,0x14,0x08,0x00, ; 0x74 +.db 0x00,0x00,0x12,0x12,0x12,0x1A,0x14,0x00, ; 0x75 +.db 0x00,0x00,0x22,0x22,0x22,0x14,0x08,0x00, ; 0x76 +.db 0x00,0x00,0x22,0x22,0x2A,0x3E,0x14,0x00, ; 0x77 +.db 0x00,0x00,0x12,0x12,0x0C,0x12,0x12,0x00, ; 0x78 +.db 0x00,0x00,0x12,0x12,0x12,0x1C,0x08,0x06, ; 0x79 +.db 0x00,0x00,0x1E,0x10,0x0C,0x02,0x1E,0x00, ; 0x7A +.db 0x18,0x04,0x04,0x06,0x04,0x04,0x18,0x00, ; 0x7B +.db 0x08,0x08,0x08,0x00,0x08,0x08,0x08,0x00, ; 0x7C +.db 0x0C,0x10,0x10,0x30,0x10,0x10,0x0C,0x00, ; 0x7D +.db 0x14,0x0A,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x7E +.db 0x08,0x1C,0x36,0x22,0x22,0x3E,0x00,0x00, ; 0x7F +.db 0x1C,0x22,0x02,0x02,0x22,0x1C,0x08,0x0C, ; 0x80 +.db 0x12,0x00,0x12,0x12,0x12,0x1A,0x14,0x00, ; 0x81 +.db 0x30,0x00,0x1C,0x22,0x1E,0x02,0x1C,0x00, ; 0x82 +.db 0x1C,0x00,0x1C,0x20,0x3C,0x22,0x3C,0x00, ; 0x83 +.db 0x14,0x00,0x1C,0x20,0x3C,0x22,0x3C,0x00, ; 0x84 +.db 0x0C,0x00,0x1C,0x20,0x3C,0x22,0x3C,0x00, ; 0x85 +.db 0x1C,0x14,0x1C,0x20,0x3C,0x22,0x3C,0x00, ; 0x86 +.db 0x00,0x1C,0x22,0x02,0x22,0x1C,0x08,0x0C, ; 0x87 +.db 0x1C,0x00,0x1C,0x22,0x1E,0x02,0x1C,0x00, ; 0x88 +.db 0x14,0x00,0x1C,0x22,0x1E,0x02,0x1C,0x00, ; 0x89 +.db 0x0C,0x00,0x1C,0x22,0x1E,0x02,0x1C,0x00, ; 0x8A +.db 0x14,0x00,0x08,0x08,0x08,0x08,0x18,0x00, ; 0x8B +.db 0x1C,0x00,0x08,0x08,0x08,0x08,0x18,0x00, ; 0x8C +.db 0x04,0x00,0x08,0x08,0x08,0x08,0x18,0x00, ; 0x8D +.db 0x14,0x00,0x08,0x14,0x22,0x3E,0x22,0x00, ; 0x8E +.db 0x1C,0x14,0x1C,0x36,0x22,0x3E,0x22,0x00, ; 0x8F +.db 0x30,0x00,0x3E,0x02,0x1E,0x02,0x3E,0x00, ; 0x90 +.db 0x00,0x00,0x1E,0x28,0x3E,0x0A,0x3C,0x00, ; 0x91 +.db 0x3C,0x0A,0x0A,0x3E,0x0A,0x0A,0x3A,0x00, ; 0x92 +.db 0x1C,0x00,0x0C,0x12,0x12,0x12,0x0C,0x00, ; 0x93 +.db 0x14,0x00,0x0C,0x12,0x12,0x12,0x0C,0x00, ; 0x94 +.db 0x06,0x00,0x0C,0x12,0x12,0x12,0x0C,0x00, ; 0x95 +.db 0x1C,0x00,0x12,0x12,0x12,0x1A,0x14,0x00, ; 0x96 +.db 0x06,0x00,0x12,0x12,0x12,0x1A,0x14,0x00, ; 0x97 +.db 0x14,0x00,0x12,0x12,0x12,0x1C,0x08,0x06, ; 0x98 +.db 0x12,0x0C,0x12,0x12,0x12,0x12,0x0C,0x00, ; 0x99 +.db 0x14,0x00,0x12,0x12,0x12,0x12,0x0C,0x00, ; 0x9A +.db 0x00,0x00,0x20,0x1C,0x1A,0x16,0x0E,0x01, ; 0x9B +.db 0x18,0x24,0x04,0x1E,0x04,0x24,0x3A,0x00, ; 0x9C +.db 0x3C,0x32,0x2A,0x2A,0x2A,0x26,0x1E,0x00, ; 0x9D +.db 0x00,0x22,0x14,0x08,0x14,0x22,0x00,0x00, ; 0x9E +.db 0x10,0x28,0x08,0x1C,0x08,0x08,0x0A,0x04, ; 0x9F +.db 0x18,0x00,0x1C,0x20,0x3C,0x22,0x3C,0x00, ; 0xA0 +.db 0x18,0x00,0x08,0x08,0x08,0x08,0x18,0x00, ; 0xA1 +.db 0x18,0x00,0x0C,0x12,0x12,0x12,0x0C,0x00, ; 0xA2 +.db 0x18,0x00,0x12,0x12,0x12,0x1A,0x14,0x00, ; 0xA3 +.db 0x14,0x0A,0x00,0x0E,0x12,0x12,0x12,0x00, ; 0xA4 +.db 0x14,0x0A,0x00,0x12,0x16,0x1A,0x12,0x00, ; 0xA5 +.db 0x1C,0x20,0x3C,0x22,0x3C,0x00,0x3C,0x00, ; 0xA6 +.db 0x0C,0x12,0x12,0x12,0x0C,0x00,0x1E,0x00, ; 0xA7 +.db 0x08,0x00,0x08,0x0C,0x02,0x22,0x1C,0x00, ; 0xA8 +.db 0x1E,0x29,0x35,0x2D,0x35,0x21,0x1E,0x00, ; 0xA9 +.db 0x00,0x00,0x3F,0x20,0x20,0x00,0x00,0x00, ; 0xAA +.db 0x02,0x12,0x0A,0x1C,0x22,0x10,0x38,0x00, ; 0xAB +.db 0x02,0x12,0x0A,0x34,0x2A,0x38,0x20,0x00, ; 0xAC +.db 0x08,0x00,0x08,0x08,0x1C,0x1C,0x08,0x00, ; 0xAD +.db 0x00,0x00,0x24,0x12,0x24,0x00,0x00,0x00, ; 0xAE +.db 0x00,0x00,0x12,0x24,0x12,0x00,0x00,0x00, ; 0xAF +.db 0x2A,0x00,0x15,0x00,0x2A,0x00,0x15,0x00, ; 0xB0 +.db 0x2A,0x15,0x2A,0x15,0x2A,0x15,0x2A,0x15, ; 0xB1 +.db 0x15,0x3F,0x2A,0x3F,0x15,0x3F,0x2A,0x3F, ; 0xB2 +.db 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08, ; 0xB3 +.db 0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08, ; 0xB4 +.db 0x18,0x00,0x08,0x14,0x22,0x3E,0x22,0x00, ; 0xB5 +.db 0x1C,0x00,0x08,0x14,0x22,0x3E,0x22,0x00, ; 0xB6 +.db 0x0C,0x00,0x08,0x14,0x22,0x3E,0x22,0x00, ; 0xB7 +.db 0x1E,0x21,0x2D,0x25,0x2D,0x21,0x1E,0x00, ; 0xB8 +.db 0x0A,0x0B,0x08,0x0B,0x0A,0x0A,0x0A,0x0A, ; 0xB9 +.db 0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A, ; 0xBA +.db 0x00,0x0F,0x08,0x0B,0x0A,0x0A,0x0A,0x0A, ; 0xBB +.db 0x0A,0x0B,0x08,0x0F,0x00,0x00,0x00,0x00, ; 0xBC +.db 0x00,0x08,0x1C,0x02,0x02,0x1C,0x08,0x00, ; 0xBD +.db 0x22,0x14,0x08,0x3E,0x08,0x3E,0x08,0x00, ; 0xBE +.db 0x00,0x00,0x00,0x0F,0x08,0x08,0x08,0x08, ; 0xBF +.db 0x08,0x08,0x08,0x38,0x00,0x00,0x00,0x00, ; 0xC0 +.db 0x08,0x08,0x08,0x3F,0x00,0x00,0x00,0x00, ; 0xC1 +.db 0x00,0x00,0x00,0x3F,0x08,0x08,0x08,0x08, ; 0xC2 +.db 0x08,0x08,0x08,0x38,0x08,0x08,0x08,0x08, ; 0xC3 +.db 0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00, ; 0xC4 +.db 0x08,0x08,0x08,0x3F,0x08,0x08,0x08,0x08, ; 0xC5 +.db 0x28,0x14,0x1C,0x20,0x3C,0x22,0x3C,0x00, ; 0xC6 +.db 0x28,0x14,0x08,0x14,0x22,0x3E,0x22,0x00, ; 0xC7 +.db 0x0A,0x3A,0x02,0x3E,0x00,0x00,0x00,0x00, ; 0xC8 +.db 0x00,0x3E,0x02,0x3A,0x0A,0x0A,0x0A,0x0A, ; 0xC9 +.db 0x0A,0x3B,0x00,0x3F,0x00,0x00,0x00,0x00, ; 0xCA +.db 0x00,0x3F,0x00,0x3B,0x0A,0x0A,0x0A,0x0A, ; 0xCB +.db 0x0A,0x3A,0x02,0x3A,0x0A,0x0A,0x0A,0x0A, ; 0xCC +.db 0x00,0x3F,0x00,0x3F,0x00,0x00,0x00,0x00, ; 0xCD +.db 0x0A,0x3B,0x00,0x3B,0x0A,0x0A,0x0A,0x0A, ; 0xCE +.db 0x22,0x1C,0x22,0x22,0x22,0x1C,0x22,0x00, ; 0xCF +.db 0x0C,0x02,0x04,0x08,0x1C,0x12,0x0C,0x00, ; 0xD0 +.db 0x1C,0x24,0x24,0x2E,0x24,0x24,0x1C,0x00, ; 0xD1 +.db 0x1C,0x00,0x3E,0x02,0x1E,0x02,0x3E,0x00, ; 0xD2 +.db 0x14,0x00,0x3E,0x02,0x1E,0x02,0x3E,0x00, ; 0xD3 +.db 0x0C,0x00,0x3E,0x02,0x1E,0x02,0x3E,0x00, ; 0xD4 +.db 0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00, ; 0xD5 +.db 0x18,0x00,0x1C,0x08,0x08,0x08,0x1C,0x00, ; 0xD6 +.db 0x1C,0x00,0x1C,0x08,0x08,0x08,0x1C,0x00, ; 0xD7 +.db 0x14,0x00,0x1C,0x08,0x08,0x08,0x1C,0x00, ; 0xD8 +.db 0x08,0x08,0x08,0x0F,0x00,0x00,0x00,0x00, ; 0xD9 +.db 0x00,0x00,0x00,0x38,0x08,0x08,0x08,0x08, ; 0xDA +.db 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, ; 0xDB +.db 0x00,0x00,0x00,0x00,0x3F,0x3F,0x3F,0x3F, ; 0xDC +.db 0x08,0x08,0x08,0x00,0x08,0x08,0x08,0x00, ; 0xDD +.db 0x0C,0x00,0x1C,0x08,0x08,0x08,0x1C,0x00, ; 0xDE +.db 0x3F,0x3F,0x3F,0x3F,0x00,0x00,0x00,0x00, ; 0xDF +.db 0x18,0x0C,0x12,0x12,0x12,0x12,0x0C,0x00, ; 0xE0 +.db 0x00,0x0E,0x12,0x0E,0x12,0x12,0x0E,0x02, ; 0xE1 +.db 0x1C,0x0C,0x12,0x12,0x12,0x12,0x0C,0x00, ; 0xE2 +.db 0x06,0x0C,0x12,0x12,0x12,0x12,0x0C,0x00, ; 0xE3 +.db 0x14,0x0A,0x00,0x0C,0x12,0x12,0x0C,0x00, ; 0xE4 +.db 0x14,0x0A,0x0C,0x12,0x12,0x12,0x0C,0x00, ; 0xE5 +.db 0x00,0x00,0x12,0x12,0x12,0x0E,0x02,0x02, ; 0xE6 +.db 0x00,0x06,0x02,0x0E,0x12,0x0E,0x02,0x06, ; 0xE7 +.db 0x06,0x02,0x0E,0x12,0x12,0x0E,0x02,0x06, ; 0xE8 +.db 0x18,0x00,0x12,0x12,0x12,0x12,0x0C,0x00, ; 0xE9 +.db 0x1C,0x00,0x12,0x12,0x12,0x12,0x0C,0x00, ; 0xEA +.db 0x06,0x00,0x12,0x12,0x12,0x12,0x0C,0x00, ; 0xEB +.db 0x18,0x00,0x12,0x12,0x12,0x1C,0x08,0x06, ; 0xEC +.db 0x18,0x00,0x22,0x14,0x08,0x08,0x08,0x00, ; 0xED +.db 0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xEE +.db 0x0C,0x0C,0x04,0x00,0x00,0x00,0x00,0x00, ; 0xEF +.db 0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00, ; 0xF0 +.db 0x00,0x08,0x1C,0x08,0x00,0x1C,0x00,0x00, ; 0xF1 +.db 0x00,0x00,0x3E,0x00,0x00,0x3E,0x00,0x00, ; 0xF2 +.db 0x03,0x16,0x0B,0x34,0x2A,0x38,0x20,0x00, ; 0xF3 +.db 0x3C,0x2A,0x2A,0x2C,0x28,0x28,0x28,0x00, ; 0xF4 +.db 0x1C,0x22,0x0C,0x14,0x18,0x22,0x1C,0x00, ; 0xF5 +.db 0x00,0x08,0x00,0x3E,0x00,0x08,0x00,0x00, ; 0xF6 +.db 0x00,0x00,0x00,0x1C,0x18,0x00,0x00,0x00, ; 0xF7 +.db 0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00, ; 0xF8 +.db 0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x00, ; 0xF9 +.db 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00, ; 0xFA +.db 0x04,0x06,0x04,0x04,0x00,0x00,0x00,0x00, ; 0xFB +.db 0x0E,0x04,0x0C,0x06,0x00,0x00,0x00,0x00, ; 0xFC +.db 0x06,0x08,0x04,0x0E,0x00,0x00,0x00,0x00, ; 0xFD +.db 0x00,0x00,0x1E,0x1E,0x1E,0x1E,0x00,0x00, ; 0xFE +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ; 0xFF diff --git a/avr/modules/lcd2/font/font3.asm b/avr/modules/lcd2/font/font3.asm new file mode 100644 index 0000000..92c1396 --- /dev/null +++ b/avr/modules/lcd2/font/font3.asm @@ -0,0 +1,257 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +; *************************************************************************** +; This is a font from the project LCD_fonts at +; https://github.com/basti79/LCD-fonts.git +; which in turn is based on a post by Benedikt K. in a forum post on +; https://www.mikrocontroller.net/topic/54860 +; *************************************************************************** + + + +; *************************************************************************** +; code + +.cseg + + + +font3_16x26: +; header + .dw font16x26MonoHandlerFn ; handlerFn + .dw 832 ; needed buffer size + .db 16, 26 ; width, height of chars + .db 32, 224 ; first char, num of chars in font +; data (16x26_horizontal_LSB_2) +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x20 +.db 0x00,0x00,0x00,0x00,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x21 +.db 0x00,0x00,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x10,0x04,0x10,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x22 +.db 0x00,0x00,0x00,0x00,0x80,0x31,0x80,0x31,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xFC,0x7F,0xFC,0x7F,0x60,0x0C,0x60,0x06,0x30,0x06,0xFE,0x3F,0xFE,0x3F,0x18,0x03,0x18,0x03,0x18,0x03,0x18,0x03,0x8C,0x01,0x8C,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x23 +.db 0x00,0x03,0x00,0x03,0xC0,0x1F,0xF0,0x3F,0x70,0x23,0x38,0x03,0x38,0x03,0x38,0x03,0x78,0x03,0xF0,0x03,0xE0,0x03,0x80,0x07,0x00,0x1F,0x00,0x1F,0x00,0x3B,0x00,0x3B,0x00,0x3B,0x00,0x3B,0x18,0x1B,0xF8,0x1F,0xE0,0x0F,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x24 +.db 0x00,0x00,0x00,0x00,0x3C,0xC0,0x66,0x60,0xC3,0x30,0xC3,0x18,0xC3,0x18,0xC3,0x0C,0xC3,0x06,0x66,0x03,0x3C,0x03,0x80,0x01,0xC0,0x3C,0xC0,0x66,0x60,0xC3,0x30,0xC3,0x18,0xC3,0x18,0xC3,0x0C,0xC3,0x06,0x66,0x03,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x25 +.db 0x00,0x00,0x00,0x00,0xE0,0x03,0xF0,0x07,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x06,0x70,0x07,0xF0,0x01,0xF8,0x00,0xFC,0xE0,0xCE,0xE1,0xC7,0xE3,0x87,0x63,0x07,0x67,0x07,0x7E,0x0F,0x3E,0x1E,0x3C,0xFC,0x7F,0xF0,0xF3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x26 +.db 0x00,0x00,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x27 +.db 0x00,0x00,0x00,0x18,0x00,0x1E,0x00,0x0F,0x80,0x03,0xC0,0x01,0xE0,0x00,0xE0,0x00,0xE0,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xC0,0x01,0x80,0x03,0x00,0x0F,0x00,0x1E,0x00,0x18,0x00,0x00, ; 0x28 +.db 0x00,0x00,0x0C,0x00,0x3C,0x00,0x78,0x00,0xE0,0x00,0xC0,0x01,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x80,0x03,0x80,0x03,0x80,0x03,0xC0,0x01,0xE0,0x00,0x78,0x00,0x3C,0x00,0x0C,0x00,0x00,0x00, ; 0x29 +.db 0x00,0x00,0x00,0x00,0x80,0x03,0x80,0x03,0x80,0x03,0x98,0x1B,0x7C,0x3E,0x30,0x0C,0x40,0x02,0xE0,0x07,0x70,0x0E,0x38,0x1C,0x20,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x2A +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xFE,0x7F,0xFE,0x7F,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x2B +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x03,0x00,0x03,0x80,0x03,0x80,0x01,0xC0,0x00,0x00,0x00, ; 0x2C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x1F,0xF8,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x2D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x2E +.db 0x00,0x00,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x80,0x01,0x80,0x01,0xC0,0x00,0xC0,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x00,0x00, ; 0x2F +.db 0x00,0x00,0x00,0x00,0xE0,0x03,0xF0,0x07,0x38,0x0E,0x1C,0x1C,0x1C,0x1C,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1C,0x1C,0x1C,0x1C,0x38,0x0E,0xF0,0x07,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x30 +.db 0x00,0x00,0x00,0x00,0x00,0x03,0xE0,0x03,0xFC,0x03,0x8C,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0xFC,0x7F,0xFC,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x31 +.db 0x00,0x00,0x00,0x00,0xF0,0x03,0xFC,0x07,0x0C,0x0E,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x0E,0x00,0x0E,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0x70,0x00,0x30,0x00,0x38,0x00,0x1C,0x00,0xFC,0x1F,0xFC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x32 +.db 0x00,0x00,0x00,0x00,0xF0,0x03,0xF8,0x0F,0x08,0x1E,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x0C,0x00,0x06,0xE0,0x03,0xE0,0x07,0x00,0x0F,0x00,0x1E,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1E,0x08,0x0F,0xF8,0x07,0xF8,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x33 +.db 0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0F,0x80,0x0F,0x80,0x0F,0xC0,0x0E,0xE0,0x0E,0x60,0x0E,0x30,0x0E,0x18,0x0E,0x18,0x0E,0x0C,0x0E,0x06,0x0E,0xFE,0x7F,0xFE,0x7F,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x34 +.db 0x00,0x00,0x00,0x00,0xF0,0x3F,0xF0,0x3F,0xF0,0x3F,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0xF0,0x03,0xF0,0x0F,0x00,0x1E,0x00,0x3C,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x3C,0x10,0x1E,0xF0,0x0F,0xF0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x35 +.db 0x00,0x00,0x00,0x00,0x80,0x1F,0xE0,0x3F,0xF0,0x20,0x70,0x00,0x38,0x00,0x38,0x00,0x1C,0x00,0x9C,0x0F,0xDC,0x1F,0x7C,0x3C,0x3C,0x78,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x38,0x70,0x38,0x38,0x70,0x38,0xF0,0x1F,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x36 +.db 0x00,0x00,0x00,0x00,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x02,0x00,0x03,0x80,0x01,0x80,0x01,0xC0,0x00,0xC0,0x00,0x60,0x00,0x60,0x00,0x70,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x37 +.db 0x00,0x00,0x00,0x00,0xC0,0x07,0xF0,0x0F,0x78,0x1E,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x78,0x0C,0xF0,0x0F,0xE0,0x03,0xF0,0x0F,0x38,0x1F,0x18,0x1E,0x1C,0x3C,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x38,0x1C,0xF0,0x0F,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x38 +.db 0x00,0x00,0x00,0x00,0xC0,0x07,0xF0,0x1F,0x38,0x1C,0x38,0x38,0x1C,0x38,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x3C,0x78,0x78,0x7C,0xF0,0x77,0xE0,0x73,0x00,0x70,0x00,0x38,0x00,0x38,0x00,0x1C,0x08,0x1E,0xF8,0x0F,0xF0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x39 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x3A +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x03,0x00,0x03,0x80,0x03,0x80,0x01,0xC0,0x00,0x00,0x00, ; 0x3B +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x70,0x00,0x3C,0x00,0x0F,0xC0,0x03,0xF0,0x00,0x3C,0x00,0x3C,0x00,0xF0,0x00,0xC0,0x03,0x00,0x0F,0x00,0x3C,0x00,0x70,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x3C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x3D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x0E,0x00,0x3C,0x00,0xF0,0x00,0xC0,0x03,0x00,0x0F,0x00,0x3C,0x00,0x3C,0x00,0x0F,0xC0,0x03,0xF0,0x00,0x3C,0x00,0x0E,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x3E +.db 0x00,0x00,0x00,0x00,0xF8,0x07,0xFC,0x1F,0x0C,0x3C,0x0C,0x38,0x00,0x38,0x00,0x38,0x00,0x1C,0x00,0x1E,0x00,0x0F,0x80,0x07,0x80,0x03,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x3F +.db 0x00,0x00,0x00,0x00,0xC0,0x0F,0xE0,0x1F,0x70,0x38,0x18,0x30,0x1C,0x3E,0x0C,0x31,0x8E,0x31,0xC6,0x30,0xC6,0x30,0xC6,0x38,0xC6,0x38,0xC6,0x3C,0xC6,0x34,0x8E,0xF7,0x8C,0xF3,0x1C,0x00,0x38,0x08,0xF0,0x0F,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x40 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x03,0xE0,0x03,0x60,0x07,0x60,0x07,0x70,0x06,0x30,0x0E,0x38,0x0E,0x38,0x1C,0x18,0x1C,0xFC,0x3F,0xFC,0x3F,0x0E,0x38,0x0E,0x70,0x0E,0x70,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x41 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x07,0xFC,0x0F,0x1C,0x1E,0x1C,0x1C,0x1C,0x1C,0x1C,0x0E,0xFC,0x07,0xFC,0x07,0x1C,0x1E,0x1C,0x3C,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x3C,0xFC,0x1F,0xFC,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x42 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x1F,0xF0,0x3F,0x78,0x30,0x3C,0x00,0x1C,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1C,0x00,0x3C,0x00,0x78,0x20,0xF0,0x3F,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x43 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x07,0xFC,0x0F,0x1C,0x3C,0x1C,0x38,0x1C,0x78,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x38,0x1C,0x38,0x1C,0x1E,0xFC,0x0F,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x44 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x3F,0xF8,0x3F,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x1F,0xF8,0x1F,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x7F,0xF8,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x45 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x7F,0xF8,0x7F,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x3F,0xF8,0x3F,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x46 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x1F,0xF0,0x3F,0x78,0x30,0x3C,0x00,0x1C,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x3F,0x0E,0x3F,0x0E,0x38,0x1C,0x38,0x3C,0x38,0x78,0x38,0xF0,0x3F,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x47 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0xFC,0x3F,0xFC,0x3F,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x48 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x1F,0xFC,0x1F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xFC,0x1F,0xFC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x49 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0xF8,0x0F,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x04,0x07,0xFC,0x03,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x4A +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x78,0x1C,0x3C,0x1C,0x1E,0x1C,0x0F,0x1C,0x07,0x9C,0x03,0xDC,0x01,0xFC,0x00,0xDC,0x01,0xDC,0x03,0x9C,0x07,0x1C,0x0F,0x1C,0x1E,0x1C,0x3C,0x1C,0x78,0x1C,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x4B +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x3F,0xF8,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x4C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x38,0x1E,0x3C,0x1E,0x3C,0x1E,0x3C,0x36,0x36,0x36,0x36,0x36,0x36,0x66,0x32,0x66,0x33,0x66,0x33,0xC6,0x31,0xC6,0x31,0xC6,0x31,0x06,0x30,0x06,0x30,0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x4D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x30,0x1C,0x30,0x3C,0x30,0x7C,0x30,0x7C,0x30,0xFC,0x30,0xEC,0x31,0xCC,0x31,0xCC,0x33,0x8C,0x37,0x0C,0x3F,0x0C,0x3E,0x0C,0x3E,0x0C,0x3C,0x0C,0x38,0x0C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x4E +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0xF0,0x0F,0x38,0x1C,0x1C,0x38,0x1C,0x38,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x1C,0x38,0x1C,0x38,0x38,0x1C,0xF0,0x0F,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x4F +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x1F,0xF8,0x3F,0x38,0x78,0x38,0x70,0x38,0x70,0x38,0x70,0x38,0x78,0x38,0x3C,0xF8,0x1F,0xF8,0x07,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x50 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0xF0,0x0F,0x38,0x1C,0x1C,0x38,0x1C,0x38,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x1C,0x38,0x1C,0x38,0x38,0x1C,0xF0,0x0F,0xE0,0x07,0x00,0x1E,0x00,0x78,0x00,0xF0,0x00,0x40,0x00,0x00, ; 0x51 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x07,0xFC,0x0F,0x1C,0x1E,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x0E,0xFC,0x07,0xFC,0x03,0x9C,0x07,0x1C,0x07,0x1C,0x0F,0x1C,0x1E,0x1C,0x3C,0x1C,0x38,0x1C,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x52 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0xF8,0x1F,0x3C,0x18,0x1C,0x00,0x1C,0x00,0x3C,0x00,0xF8,0x00,0xF0,0x07,0xC0,0x1F,0x00,0x3E,0x00,0x38,0x00,0x38,0x00,0x38,0x0C,0x1C,0xFC,0x1F,0xF0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x53 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x7F,0xFF,0x7F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x54 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x3C,0x78,0x38,0x38,0xF0,0x1F,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x55 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x0E,0x70,0x0E,0x70,0x1C,0x70,0x1C,0x38,0x3C,0x38,0x38,0x38,0x38,0x1C,0x70,0x1C,0x70,0x0C,0xE0,0x0E,0xE0,0x0E,0xE0,0x07,0xC0,0x07,0xC0,0x07,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x56 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x03,0xC0,0x07,0xC0,0x86,0x61,0xC6,0x63,0xC6,0x63,0xC6,0x63,0xC6,0x63,0x4E,0x76,0x6C,0x36,0x6C,0x36,0x6C,0x36,0x2C,0x3E,0x3C,0x3C,0x3C,0x1C,0x3C,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x57 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0xE0,0x3C,0x70,0x78,0x38,0x78,0x1C,0xF0,0x0E,0xE0,0x07,0xC0,0x03,0xC0,0x03,0xC0,0x07,0xE0,0x07,0x60,0x0F,0x30,0x1E,0x18,0x3C,0x1C,0x38,0x0E,0x78,0x07,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x58 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x0E,0x70,0x1C,0x30,0x1C,0x18,0x38,0x1C,0x78,0x0E,0x70,0x07,0xE0,0x03,0xE0,0x03,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x59 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x3F,0xFC,0x3F,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x80,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0xFE,0x3F,0xFE,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x5A +.db 0x00,0x00,0xC0,0x3F,0xC0,0x3F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x3F,0xC0,0x3F,0x00,0x00, ; 0x5B +.db 0x00,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0xC0,0x00,0xC0,0x00,0x80,0x01,0x80,0x01,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x00, ; 0x5C +.db 0x00,0x00,0xFC,0x03,0xFC,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0xFC,0x03,0xFC,0x03,0x00,0x00, ; 0x5D +.db 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x80,0x03,0x80,0x03,0xC0,0x03,0xC0,0x06,0xE0,0x06,0x60,0x0C,0x30,0x0C,0x30,0x18,0x18,0x18,0x18,0x18,0x0C,0x30,0x0C,0x30,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x5E +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x5F +.db 0xC0,0x01,0x80,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x60 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0xF8,0x0F,0x18,0x1E,0x00,0x1C,0x00,0x1C,0xE0,0x1F,0xF0,0x1F,0x38,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x3C,0x1E,0xF8,0x7B,0xF0,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x61 +.db 0x00,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x9C,0x07,0xDC,0x1F,0x7C,0x1C,0x3C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x1C,0x3C,0x1E,0xFC,0x0F,0xCC,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x62 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x1F,0xF0,0x3F,0x78,0x20,0x38,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x3C,0x00,0x38,0x00,0xF8,0x20,0xF0,0x3F,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x63 +.db 0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0xC0,0x73,0xF0,0x7F,0x78,0x7C,0x38,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x3C,0x78,0x38,0x7C,0xF0,0x77,0xE0,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x64 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x07,0xF0,0x0F,0x78,0x1C,0x38,0x38,0x1C,0x38,0x1C,0x38,0xFC,0x3F,0xFC,0x3F,0x1C,0x00,0x1C,0x00,0x38,0x00,0x78,0x20,0xF0,0x3F,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x65 +.db 0x00,0x00,0x00,0xFF,0x80,0xFF,0xC0,0x03,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xFC,0x7F,0xFC,0x7F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x66 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x73,0xF0,0x7F,0x78,0x7C,0x38,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x3C,0x78,0x38,0x7C,0xF0,0x77,0xE0,0x73,0x00,0x70,0x00,0x38,0x18,0x3C,0xF8,0x1F,0xF0,0x07, ; 0x67 +.db 0x00,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x0F,0xDC,0x1F,0x7C,0x3C,0x3C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x68 +.db 0x00,0x00,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0xFC,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x69 +.db 0x00,0x00,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0xF8,0x0F,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x04,0x07,0xFC,0x07,0xF8,0x01, ; 0x6A +.db 0x00,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x3C,0x38,0x1E,0x38,0x0E,0x38,0x0F,0xB8,0x07,0xB8,0x03,0xF8,0x03,0xB8,0x03,0xB8,0x07,0x38,0x0F,0x38,0x0E,0x38,0x1E,0x38,0x3C,0x38,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x6B +.db 0x00,0x00,0xF8,0x07,0xF8,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x6C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCE,0x31,0xEE,0x79,0xFE,0x7F,0x9E,0x77,0x9E,0x73,0x8E,0x73,0x8E,0x73,0x8E,0x73,0x8E,0x73,0x8E,0x73,0x8E,0x73,0x8E,0x73,0x8E,0x73,0x8E,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x6D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x0F,0xDC,0x1F,0x7C,0x3C,0x3C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x6E +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0xF8,0x0F,0x3C,0x1E,0x1C,0x1C,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1C,0x1C,0x3C,0x1E,0xF8,0x0F,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x6F +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9C,0x07,0xDC,0x1F,0x7C,0x1C,0x3C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x1C,0x3C,0x1E,0xFC,0x0F,0x9C,0x07,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00, ; 0x70 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x39,0xF8,0x3F,0x3C,0x3E,0x1C,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1E,0x3C,0x1C,0x3E,0xF8,0x3B,0xF0,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38, ; 0x71 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x3E,0x70,0x3F,0xF0,0x31,0xF0,0x30,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x72 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0xF0,0x1F,0x78,0x10,0x38,0x00,0x38,0x00,0xF8,0x01,0xF0,0x07,0x80,0x1F,0x00,0x3C,0x00,0x38,0x00,0x38,0x18,0x3C,0xF8,0x1F,0xF0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x73 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0xE0,0x00,0xFC,0x3F,0xFC,0x3F,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x01,0xC0,0x3F,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x74 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x3C,0x3C,0x3E,0xF8,0x3B,0xF0,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x75 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x70,0x1C,0x38,0x1C,0x38,0x3C,0x38,0x38,0x18,0x38,0x1C,0x70,0x1C,0x70,0x0C,0xE0,0x0E,0xE0,0x0E,0xE0,0x06,0xC0,0x07,0xC0,0x07,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x76 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x87,0xC3,0x87,0x43,0xC6,0x63,0xC6,0x63,0x46,0x62,0x6E,0x66,0x6E,0x26,0x6C,0x36,0x2C,0x36,0x3C,0x3C,0x3C,0x3C,0x3C,0x1C,0x18,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x77 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x30,0x3C,0x18,0x78,0x0C,0x70,0x0E,0xF0,0x06,0xE0,0x03,0xC0,0x03,0xC0,0x03,0xE0,0x07,0x70,0x0F,0x30,0x0E,0x38,0x1E,0x1C,0x3C,0x0E,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x78 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x70,0x1C,0x30,0x1C,0x38,0x38,0x18,0x38,0x1C,0x78,0x1C,0x70,0x0E,0xF0,0x0E,0xE0,0x07,0xE0,0x07,0xC0,0x03,0xC0,0x03,0xC0,0x01,0x80,0x01,0xC0,0x01,0xC0,0x00,0xE0,0x00,0x7C,0x00,0x3C,0x00, ; 0x79 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x3F,0xFC,0x3F,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0xFC,0x3F,0xFC,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x7A +.db 0x00,0x00,0x00,0x1F,0x80,0x1F,0xC0,0x03,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0xC0,0x01,0xF8,0x00,0xF8,0x00,0xC0,0x01,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x03,0x80,0x1F,0x00,0x1F,0x00,0x00, ; 0x7B +.db 0x00,0x00,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x00,0x00, ; 0x7C +.db 0x00,0x00,0x7C,0x00,0xFC,0x00,0xE0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xC0,0x01,0x80,0x0F,0x80,0x0F,0xC0,0x01,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xE0,0x01,0xFC,0x00,0x7C,0x00,0x00,0x00, ; 0x7D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x60,0xFC,0x63,0xC6,0x3F,0x06,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x7E +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF8,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x7F +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x1F,0xF0,0x3F,0x78,0x30,0x3C,0x00,0x1C,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1C,0x00,0x3C,0x00,0x78,0x20,0xF0,0x3F,0xC0,0x1F,0x00,0x02,0x00,0x07,0x00,0x0C,0x00,0x0C,0x80,0x07, ; 0x80 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x06,0x30,0x06,0x00,0x00,0x00,0x00,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x3C,0x3C,0x3E,0xF8,0x3B,0xF0,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x81 +.db 0x00,0x00,0x00,0x0C,0x00,0x06,0x00,0x03,0x80,0x01,0x00,0x00,0x00,0x00,0xC0,0x07,0xF0,0x0F,0x78,0x1C,0x38,0x38,0x1C,0x38,0x1C,0x38,0xFC,0x3F,0xFC,0x3F,0x1C,0x00,0x1C,0x00,0x38,0x00,0x78,0x20,0xF0,0x3F,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x82 +.db 0x00,0x00,0xC0,0x01,0x60,0x03,0x30,0x06,0x18,0x0C,0x00,0x00,0x00,0x00,0xE0,0x07,0xF8,0x0F,0x18,0x1E,0x00,0x1C,0x00,0x1C,0xE0,0x1F,0xF0,0x1F,0x38,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x3C,0x1E,0xF8,0x7B,0xF0,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x83 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x0C,0x60,0x0C,0x00,0x00,0x00,0x00,0xE0,0x07,0xF8,0x0F,0x18,0x1E,0x00,0x1C,0x00,0x1C,0xE0,0x1F,0xF0,0x1F,0x38,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x3C,0x1E,0xF8,0x7B,0xF0,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x84 +.db 0x00,0x00,0x30,0x00,0x60,0x00,0xC0,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0xE0,0x07,0xF8,0x0F,0x18,0x1E,0x00,0x1C,0x00,0x1C,0xE0,0x1F,0xF0,0x1F,0x38,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x3C,0x1E,0xF8,0x7B,0xF0,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x85 +.db 0xC0,0x01,0x20,0x02,0x20,0x02,0x20,0x02,0xC0,0x01,0x00,0x00,0x00,0x00,0xE0,0x07,0xF8,0x0F,0x18,0x1E,0x00,0x1C,0x00,0x1C,0xE0,0x1F,0xF0,0x1F,0x38,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x3C,0x1E,0xF8,0x7B,0xF0,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x86 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x1F,0xF0,0x3F,0x78,0x20,0x38,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x3C,0x00,0x38,0x00,0xF8,0x20,0xF0,0x3F,0xC0,0x1F,0x00,0x01,0x80,0x03,0x00,0x06,0x00,0x06,0xC0,0x03, ; 0x87 +.db 0x00,0x00,0xC0,0x01,0x60,0x03,0x30,0x06,0x18,0x0C,0x00,0x00,0x00,0x00,0xC0,0x07,0xF0,0x0F,0x78,0x1C,0x38,0x38,0x1C,0x38,0x1C,0x38,0xFC,0x3F,0xFC,0x3F,0x1C,0x00,0x1C,0x00,0x38,0x00,0x78,0x20,0xF0,0x3F,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x88 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x0C,0x60,0x0C,0x00,0x00,0x00,0x00,0xC0,0x07,0xF0,0x0F,0x78,0x1C,0x38,0x38,0x1C,0x38,0x1C,0x38,0xFC,0x3F,0xFC,0x3F,0x1C,0x00,0x1C,0x00,0x38,0x00,0x78,0x20,0xF0,0x3F,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x89 +.db 0x00,0x00,0x30,0x00,0x60,0x00,0xC0,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0xC0,0x07,0xF0,0x0F,0x78,0x1C,0x38,0x38,0x1C,0x38,0x1C,0x38,0xFC,0x3F,0xFC,0x3F,0x1C,0x00,0x1C,0x00,0x38,0x00,0x78,0x20,0xF0,0x3F,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x8A +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x06,0x30,0x06,0x00,0x00,0x00,0x00,0xFC,0x03,0xFC,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x8B +.db 0x00,0x00,0x80,0x03,0xC0,0x06,0x60,0x0C,0x30,0x18,0x00,0x00,0x00,0x00,0xFC,0x03,0xFC,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x8C +.db 0x00,0x00,0x60,0x00,0xC0,0x00,0x80,0x01,0x00,0x03,0x00,0x00,0x00,0x00,0xFC,0x03,0xFC,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x8D +.db 0x30,0x0C,0x30,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x03,0xE0,0x03,0x60,0x07,0x60,0x07,0x70,0x06,0x30,0x0E,0x38,0x0E,0x38,0x1C,0x18,0x1C,0xFC,0x3F,0xFC,0x3F,0x0E,0x38,0x0E,0x70,0x0E,0x70,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x8E +.db 0x80,0x03,0x40,0x04,0x40,0x04,0x40,0x04,0x80,0x03,0x80,0x03,0xC0,0x07,0xC0,0x07,0xE0,0x06,0x60,0x0E,0x60,0x0E,0x70,0x0C,0x30,0x1C,0x38,0x1C,0x38,0x38,0xFC,0x3F,0xFC,0x3F,0x1C,0x70,0x0E,0x70,0x0E,0x70,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x8F +.db 0x00,0x0E,0x00,0x07,0x80,0x03,0x00,0x00,0x00,0x00,0xF8,0x3F,0xF8,0x3F,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x1F,0xF8,0x1F,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x7F,0xF8,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x90 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x3C,0xFC,0x7F,0x80,0x67,0x80,0xE3,0x80,0xE3,0xF0,0xFF,0xFC,0xFF,0x9C,0x03,0x8E,0x03,0x8E,0x03,0x8E,0x03,0x9E,0x87,0xFC,0xFF,0x78,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x91 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3F,0xC0,0x3F,0xC0,0x07,0xE0,0x07,0x60,0x07,0x60,0x07,0x70,0x07,0x30,0x3F,0x38,0x3F,0x18,0x07,0x1C,0x07,0xFC,0x07,0xFC,0x07,0x06,0x07,0x06,0x7F,0x03,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x92 +.db 0x00,0x00,0xC0,0x01,0x60,0x03,0x30,0x06,0x18,0x0C,0x00,0x00,0x00,0x00,0xE0,0x03,0xF8,0x0F,0x3C,0x1E,0x1C,0x1C,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1C,0x1C,0x3C,0x1E,0xF8,0x0F,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x93 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x06,0x30,0x06,0x00,0x00,0x00,0x00,0xE0,0x03,0xF8,0x0F,0x3C,0x1E,0x1C,0x1C,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1C,0x1C,0x3C,0x1E,0xF8,0x0F,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x94 +.db 0x00,0x00,0x30,0x00,0x60,0x00,0xC0,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0xE0,0x03,0xF8,0x0F,0x3C,0x1E,0x1C,0x1C,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1C,0x1C,0x3C,0x1E,0xF8,0x0F,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x95 +.db 0x00,0x00,0xC0,0x01,0x60,0x03,0x30,0x06,0x18,0x0C,0x00,0x00,0x00,0x00,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x3C,0x3C,0x3E,0xF8,0x3B,0xF0,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x96 +.db 0x00,0x00,0x30,0x00,0x60,0x00,0xC0,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x3C,0x3C,0x3E,0xF8,0x3B,0xF0,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x97 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x06,0x30,0x06,0x00,0x00,0x00,0x00,0x1E,0x70,0x1C,0x30,0x1C,0x38,0x38,0x18,0x38,0x1C,0x78,0x1C,0x70,0x0E,0xF0,0x0E,0xE0,0x07,0xE0,0x07,0xC0,0x03,0xC0,0x03,0xC0,0x01,0x80,0x01,0xC0,0x01,0xC0,0x00,0xE0,0x00,0x7C,0x00,0x3C,0x00, ; 0x98 +.db 0x30,0x0C,0x30,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0xF0,0x0F,0x38,0x1C,0x1C,0x38,0x1C,0x38,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x1C,0x38,0x1C,0x38,0x38,0x1C,0xF0,0x0F,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x99 +.db 0x60,0x18,0x60,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x3C,0x78,0x38,0x38,0xF0,0x1F,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x9A +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x33,0xF8,0x1F,0x3C,0x1E,0x1C,0x1E,0x0E,0x3B,0x0E,0x39,0x8E,0x39,0xCE,0x38,0x6E,0x38,0x6E,0x38,0x3C,0x1C,0x3C,0x1E,0xFC,0x0F,0xE6,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x9B +.db 0x00,0x00,0x00,0x00,0x00,0x3E,0x80,0x3F,0x80,0x03,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xF0,0x0F,0xF0,0x0F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xE0,0x00,0x70,0x00,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x9C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x67,0xF0,0x3F,0x38,0x1C,0x1C,0x3C,0x1C,0x3C,0x0E,0x76,0x0E,0x73,0x8E,0x71,0x8E,0x71,0xCE,0x70,0x6E,0x70,0x3C,0x38,0x3C,0x38,0x38,0x1C,0xFC,0x0F,0xE6,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x9D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x20,0x0E,0x70,0x1C,0x38,0x38,0x1C,0x70,0x0E,0xE0,0x07,0xC0,0x03,0xC0,0x03,0xE0,0x07,0x70,0x0E,0x38,0x1C,0x1C,0x38,0x0E,0x70,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x9E +.db 0x00,0x00,0x00,0x3F,0x80,0x3F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xF8,0x1F,0xF8,0x1F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xFE,0x00,0x7E,0x00, ; 0x9F +.db 0x00,0x00,0x00,0x06,0x00,0x03,0x80,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0xF8,0x0F,0x18,0x1E,0x00,0x1C,0x00,0x1C,0xE0,0x1F,0xF0,0x1F,0x38,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x3C,0x1E,0xF8,0x7B,0xF0,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA0 +.db 0x00,0x00,0x00,0x06,0x00,0x03,0x80,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0xFC,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA1 +.db 0x00,0x00,0x00,0x06,0x00,0x03,0x80,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0xF8,0x0F,0x3C,0x1E,0x1C,0x1C,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1C,0x1C,0x3C,0x1E,0xF8,0x0F,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA2 +.db 0x00,0x00,0x00,0x06,0x00,0x03,0x80,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x3C,0x3C,0x3E,0xF8,0x3B,0xF0,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA3 +.db 0x00,0x00,0x00,0x00,0xE0,0x0C,0xF0,0x0F,0x30,0x07,0x00,0x00,0x00,0x00,0x1C,0x0F,0xDC,0x1F,0x7C,0x3C,0x3C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA4 +.db 0xE0,0x0C,0xF0,0x0F,0x30,0x07,0x00,0x00,0x00,0x00,0x1C,0x30,0x1C,0x30,0x3C,0x30,0x7C,0x30,0x7C,0x30,0xFC,0x30,0xEC,0x31,0xCC,0x31,0xCC,0x33,0x8C,0x37,0x0C,0x3F,0x0C,0x3E,0x0C,0x3E,0x0C,0x3C,0x0C,0x38,0x0C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA5 +.db 0x00,0x00,0x00,0x00,0xE0,0x03,0xF0,0x07,0x10,0x06,0xE0,0x07,0xF0,0x07,0x38,0x06,0x18,0x06,0x18,0x07,0xF8,0x1F,0xF0,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA6 +.db 0x00,0x00,0x00,0x00,0xE0,0x07,0xF0,0x0F,0x38,0x1C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0x1C,0xF0,0x0F,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA7 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x80,0x03,0x80,0x03,0x80,0x03,0xC0,0x01,0xE0,0x01,0xF0,0x00,0x78,0x00,0x38,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x30,0x3C,0x30,0xF8,0x3F,0xE0,0x1F, ; 0xA8 +.db 0x00,0x00,0x00,0x00,0xE0,0x03,0x10,0x04,0xE8,0x09,0x24,0x12,0x24,0x12,0xE4,0x11,0x24,0x11,0x24,0x11,0x28,0x0B,0x10,0x04,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA9 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0xFE,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAA +.db 0x00,0x00,0x00,0x00,0x1F,0x0C,0x1F,0x06,0x1C,0x06,0x1C,0x03,0x1C,0x03,0x9C,0x01,0x9C,0x01,0xDC,0x00,0xDC,0x00,0x7C,0x3C,0x30,0xFE,0x30,0xE0,0x18,0xE0,0x18,0x70,0x0C,0x38,0x0C,0x0C,0x06,0x06,0x06,0xFE,0x03,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAB +.db 0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x0C,0x1C,0x0C,0x1C,0x06,0x1C,0x06,0x1C,0x03,0x1C,0x03,0x9C,0x01,0x9C,0x01,0xDC,0x38,0x60,0x3C,0x60,0x3A,0x30,0x39,0xB0,0x39,0xD8,0x38,0xD8,0xFF,0x0C,0x38,0x0C,0x38,0x06,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAC +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01, ; 0xAD +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0xE0,0x38,0x70,0x1C,0x38,0x0E,0x1C,0x07,0x0C,0x03,0x8E,0x03,0x1C,0x07,0x38,0x0E,0x70,0x1C,0xE0,0x38,0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAE +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x01,0x9C,0x03,0x38,0x07,0x70,0x0E,0xE0,0x1C,0xC0,0x39,0xC0,0x18,0xE0,0x1C,0x70,0x0E,0x38,0x07,0x9C,0x03,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAF +.db 0xE7,0x1C,0xE7,0x1C,0xE7,0x1C,0x00,0x00,0x00,0x00,0xE7,0x1C,0xE7,0x1C,0xE7,0x1C,0x00,0x00,0x00,0x00,0xE7,0x1C,0xE7,0x1C,0xE7,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x1C,0xE7,0x1C,0xE7,0x1C,0x00,0x00,0x00,0x00,0xE7,0x1C,0xE7,0x1C,0xE7,0x1C,0x00,0x00,0x00,0x00, ; 0xB0 +.db 0x38,0xE7,0x38,0xE7,0x38,0xE7,0xE7,0x1C,0xE7,0x1C,0xFF,0xFF,0x38,0xE7,0x38,0xE7,0xE7,0x1C,0xE7,0x1C,0xFF,0xFF,0x38,0xE7,0x38,0xE7,0xE7,0x1C,0xE7,0x1C,0xE7,0x1C,0x38,0xE7,0x38,0xE7,0xFF,0xFF,0xE7,0x1C,0xE7,0x1C,0x38,0xE7,0x38,0xE7,0xFF,0xFF,0xE7,0x1C,0xE7,0x1C, ; 0xB1 +.db 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0x1C,0xE7,0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0x1C,0xE7,0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0x1C,0xE7,0x1C,0xE7,0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0x1C,0xE7,0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0x1C,0xE7,0x1C, ; 0xB2 +.db 0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01, ; 0xB3 +.db 0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xFF,0x01,0xFF,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01, ; 0xB4 +.db 0x00,0x07,0x80,0x03,0xC0,0x01,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x03,0xE0,0x03,0x60,0x07,0x60,0x07,0x70,0x06,0x30,0x0E,0x38,0x0E,0x38,0x1C,0x18,0x1C,0xFC,0x3F,0xFC,0x3F,0x0E,0x38,0x0E,0x70,0x0E,0x70,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xB5 +.db 0xE0,0x03,0x70,0x07,0x38,0x0E,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x03,0xE0,0x03,0x60,0x07,0x60,0x07,0x70,0x06,0x30,0x0E,0x38,0x0E,0x38,0x1C,0x18,0x1C,0xFC,0x3F,0xFC,0x3F,0x0E,0x38,0x0E,0x70,0x0E,0x70,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xB6 +.db 0xE0,0x00,0xC0,0x01,0x80,0x03,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x03,0xE0,0x03,0x60,0x07,0x60,0x07,0x70,0x06,0x30,0x0E,0x38,0x0E,0x38,0x1C,0x18,0x1C,0xFC,0x3F,0xFC,0x3F,0x0E,0x38,0x0E,0x70,0x0E,0x70,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xB7 +.db 0x00,0x00,0x00,0x00,0xE0,0x0F,0xF0,0x1F,0x38,0x38,0x1C,0x70,0x8C,0x6F,0xEE,0xEF,0x66,0xC8,0x36,0xC0,0x36,0xC0,0x36,0xC0,0x36,0xC0,0x36,0xC0,0x66,0xC8,0xEE,0xEF,0x8C,0x67,0x1C,0x70,0x38,0x38,0xF0,0x1F,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xB8 +.db 0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x7F,0x06,0x7F,0x06,0x00,0x06,0x00,0x06,0x7F,0x06,0x7F,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06, ; 0xB9 +.db 0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06, ; 0xBA +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0xFF,0x07,0x00,0x06,0x00,0x06,0x7F,0x06,0x7F,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06, ; 0xBB +.db 0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x7F,0x06,0x7F,0x06,0x00,0x06,0x00,0x06,0xFF,0x07,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xBC +.db 0x00,0x00,0x00,0x00,0x80,0x01,0x80,0x01,0xC0,0x0F,0xF0,0x0F,0xB8,0x09,0xB8,0x01,0x9C,0x01,0x9C,0x01,0x9C,0x01,0x9C,0x01,0x9C,0x01,0x9C,0x01,0x9C,0x01,0xB8,0x01,0xF8,0x09,0xF0,0x0F,0xE0,0x07,0x80,0x01,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xBD +.db 0x00,0x00,0x00,0x00,0x0E,0xE0,0x1C,0x60,0x38,0x30,0x38,0x30,0x70,0x18,0xE0,0x0C,0xE0,0x0C,0xC0,0x07,0x80,0x03,0xF8,0x3F,0xF8,0x3F,0x80,0x03,0x80,0x03,0x80,0x03,0xF8,0x3F,0xF8,0x3F,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xBE +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0xFF,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01, ; 0xBF +.db 0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0xFF,0x80,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC0 +.db 0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC1 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01, ; 0xC2 +.db 0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0xFF,0x80,0xFF,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01, ; 0xC3 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC4 +.db 0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xFF,0xFF,0xFF,0xFF,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01, ; 0xC5 +.db 0x00,0x00,0x00,0x00,0xE0,0x0C,0xF0,0x0F,0x30,0x07,0x00,0x00,0x00,0x00,0xE0,0x07,0xF8,0x0F,0x18,0x1E,0x00,0x1C,0x00,0x1C,0xE0,0x1F,0xF0,0x1F,0x38,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x3C,0x1E,0xF8,0x7B,0xF0,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC6 +.db 0xE0,0x0C,0xF0,0x0F,0x30,0x07,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x03,0xE0,0x03,0x60,0x07,0x60,0x07,0x70,0x06,0x30,0x0E,0x38,0x0E,0x38,0x1C,0x18,0x1C,0xFC,0x3F,0xFC,0x3F,0x0E,0x38,0x0E,0x70,0x0E,0x70,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC7 +.db 0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0xFE,0x60,0xFE,0x60,0x00,0x60,0x00,0xE0,0xFF,0xE0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC8 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xE0,0xFF,0x60,0x00,0x60,0x00,0x60,0xFE,0x60,0xFE,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06, ; 0xC9 +.db 0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x7F,0xFE,0x7F,0xFE,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xCA +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x7F,0xFE,0x7F,0xFE,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06, ; 0xCB +.db 0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0xFE,0x60,0xFE,0x60,0x00,0x60,0x00,0x60,0xFE,0x60,0xFE,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06, ; 0xCC +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xCD +.db 0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x7F,0xFE,0x7F,0xFE,0x00,0x00,0x00,0x00,0x7F,0xFE,0x7F,0xFE,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x06, ; 0xCE +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x20,0xCC,0x33,0xF8,0x1F,0x30,0x0C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x30,0x0C,0xF8,0x1F,0xCC,0x33,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xCF +.db 0x00,0x00,0x1E,0x03,0xFE,0x03,0xF0,0x01,0xF0,0x03,0x18,0x07,0x00,0x0E,0xE0,0x0F,0xF8,0x1F,0x3C,0x1E,0x1C,0x3C,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1C,0x1C,0x3C,0x1E,0xF8,0x0F,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD0 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x07,0xFC,0x0F,0x1C,0x3C,0x1C,0x38,0x1C,0x78,0x1C,0x70,0x1C,0x70,0xFF,0x70,0xFF,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x38,0x1C,0x38,0x1C,0x1E,0xFC,0x0F,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD1 +.db 0xC0,0x07,0xE0,0x0E,0x70,0x1C,0x00,0x00,0x00,0x00,0xF8,0x3F,0xF8,0x3F,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x1F,0xF8,0x1F,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x7F,0xF8,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD2 +.db 0x60,0x18,0x60,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x3F,0xF8,0x3F,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x1F,0xF8,0x1F,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x7F,0xF8,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD3 +.db 0xC0,0x01,0x80,0x03,0x00,0x07,0x00,0x00,0x00,0x00,0xF8,0x3F,0xF8,0x3F,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x1F,0xF8,0x1F,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x7F,0xF8,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD4 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0xFC,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD5 +.db 0x00,0x07,0x80,0x03,0xC0,0x01,0x00,0x00,0x00,0x00,0xFC,0x1F,0xFC,0x1F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xFC,0x1F,0xFC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD6 +.db 0xE0,0x03,0x70,0x07,0x38,0x0E,0x00,0x00,0x00,0x00,0xFC,0x1F,0xFC,0x1F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xFC,0x1F,0xFC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD7 +.db 0x30,0x0C,0x30,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x1F,0xFC,0x1F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xFC,0x1F,0xFC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD8 +.db 0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xFF,0x01,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD9 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x80,0xFF,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01, ; 0xDA +.db 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, ; 0xDB +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, ; 0xDC +.db 0x00,0x00,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x00,0x00, ; 0xDD +.db 0xE0,0x00,0xC0,0x01,0x80,0x03,0x00,0x00,0x00,0x00,0xFC,0x1F,0xFC,0x1F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xFC,0x1F,0xFC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xDE +.db 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xDF +.db 0x00,0x07,0x80,0x03,0xC0,0x01,0x00,0x00,0x00,0x00,0xE0,0x07,0xF0,0x0F,0x38,0x1C,0x1C,0x38,0x1C,0x38,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x1C,0x38,0x1C,0x38,0x38,0x1C,0xF0,0x0F,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE0 +.db 0x00,0x00,0xF0,0x03,0xF8,0x07,0x3C,0x0E,0x1C,0x0E,0x1C,0x0E,0x1C,0x06,0x1C,0x07,0x9C,0x03,0x9C,0x03,0x9C,0x03,0x9C,0x07,0x1C,0x0F,0x1C,0x1E,0x1C,0x3C,0x1C,0x78,0x1C,0x70,0x1C,0x70,0x9C,0x70,0x9C,0x3F,0x1C,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE1 +.db 0xE0,0x03,0x70,0x07,0x38,0x0E,0x00,0x00,0x00,0x00,0xE0,0x07,0xF0,0x0F,0x38,0x1C,0x1C,0x38,0x1C,0x38,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x1C,0x38,0x1C,0x38,0x38,0x1C,0xF0,0x0F,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE2 +.db 0xE0,0x00,0xC0,0x01,0x80,0x03,0x00,0x00,0x00,0x00,0xE0,0x07,0xF0,0x0F,0x38,0x1C,0x1C,0x38,0x1C,0x38,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x1C,0x38,0x1C,0x38,0x38,0x1C,0xF0,0x0F,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE3 +.db 0x00,0x00,0x00,0x00,0xE0,0x0C,0xF0,0x0F,0x30,0x07,0x00,0x00,0x00,0x00,0xE0,0x03,0xF8,0x0F,0x3C,0x1E,0x1C,0x1C,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1C,0x1C,0x3C,0x1E,0xF8,0x0F,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE4 +.db 0xE0,0x0C,0xF0,0x0F,0x30,0x07,0x00,0x00,0x00,0x00,0xE0,0x07,0xF0,0x0F,0x38,0x1C,0x1C,0x38,0x1C,0x38,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x1C,0x38,0x1C,0x38,0x38,0x1C,0xF0,0x0F,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE5 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x3C,0x3C,0x7C,0x3E,0xFC,0x3B,0xDC,0x7B,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00, ; 0xE6 +.db 0x00,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x9C,0x07,0xDC,0x1F,0x7C,0x1C,0x3C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x1C,0x3C,0x1E,0xFC,0x0F,0x9C,0x07,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00, ; 0xE7 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0xF8,0x1F,0xF8,0x3F,0x38,0x78,0x38,0x70,0x38,0x70,0x38,0x70,0x38,0x78,0x38,0x3C,0xF8,0x1F,0xF8,0x07,0x38,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE8 +.db 0x00,0x07,0x80,0x03,0xC0,0x01,0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x3C,0x78,0x38,0x38,0xF0,0x1F,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE9 +.db 0xE0,0x03,0x70,0x07,0x38,0x0E,0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x3C,0x78,0x38,0x38,0xF0,0x1F,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xEA +.db 0xE0,0x00,0xC0,0x01,0x80,0x03,0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x3C,0x78,0x38,0x38,0xF0,0x1F,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xEB +.db 0x00,0x00,0x00,0x06,0x00,0x03,0x80,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0x1E,0x70,0x1C,0x30,0x1C,0x38,0x38,0x18,0x38,0x1C,0x78,0x1C,0x70,0x0E,0xF0,0x0E,0xE0,0x07,0xE0,0x07,0xC0,0x03,0xC0,0x03,0xC0,0x01,0x80,0x01,0xC0,0x01,0xC0,0x00,0xE0,0x00,0x7C,0x00,0x3C,0x00, ; 0xEC +.db 0x00,0x07,0x80,0x03,0xC0,0x01,0x00,0x00,0x00,0x00,0x07,0xE0,0x0E,0x70,0x1C,0x30,0x1C,0x18,0x38,0x1C,0x78,0x0E,0x70,0x07,0xE0,0x03,0xE0,0x03,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xED +.db 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xEE +.db 0x80,0x03,0xC0,0x01,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xEF +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x1F,0xF8,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF0 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xFE,0x7F,0xFE,0x7F,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x00,0x00,0x00,0x00,0xFE,0x7F,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF1 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF, ; 0xF2 +.db 0x00,0x00,0x00,0x00,0x7E,0xE0,0xFE,0x70,0xE0,0x38,0xE0,0x38,0x3C,0x1C,0x7C,0x1C,0xE0,0x0E,0xE0,0x07,0xFE,0x07,0xBE,0x3B,0xC0,0x3D,0xC0,0x3B,0xE0,0x39,0xF0,0x39,0xF0,0x38,0xF8,0xFF,0x38,0x38,0x1C,0x38,0x0E,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF3 +.db 0x00,0x00,0x00,0x00,0xF8,0x1F,0xFC,0x1F,0xFE,0x18,0xFE,0x18,0xFE,0x18,0xFE,0x18,0xFE,0x18,0xFC,0x18,0xF8,0x18,0xF0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0x00,0x00, ; 0xF4 +.db 0x00,0x00,0x00,0x00,0xC0,0x1F,0xF0,0x1F,0x78,0x10,0x38,0x00,0x38,0x00,0x78,0x00,0xF0,0x01,0xE0,0x07,0xF0,0x0F,0x30,0x1E,0x38,0x3C,0x38,0x38,0x78,0x38,0xF0,0x19,0xE0,0x0F,0x80,0x0F,0x00,0x1E,0x00,0x3C,0x00,0x38,0x00,0x38,0x18,0x3C,0xF8,0x1F,0xE0,0x07,0x00,0x00, ; 0xF5 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x3F,0xFE,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF6 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x00,0x06,0x00,0x06,0xC0,0x03, ; 0xF7 +.db 0x00,0x00,0x00,0x00,0xE0,0x00,0x10,0x01,0x10,0x01,0x10,0x01,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF8 +.db 0x30,0x0C,0x30,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF9 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFA +.db 0x00,0x00,0x00,0x00,0xE0,0x03,0xE0,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFB +.db 0x00,0x00,0x00,0x00,0xE0,0x0F,0xF0,0x1F,0x10,0x1C,0x00,0x1C,0xC0,0x07,0xC0,0x0F,0x00,0x1C,0x00,0x1C,0xF0,0x1F,0xF0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFC +.db 0x00,0x00,0x00,0x00,0xE0,0x07,0xF0,0x1F,0x10,0x1C,0x00,0x1C,0x00,0x0E,0x80,0x07,0xC0,0x01,0x70,0x00,0xF0,0x1F,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFD +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFE +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ; 0xFF diff --git a/avr/modules/lcd2/font/font4.asm b/avr/modules/lcd2/font/font4.asm new file mode 100644 index 0000000..9c44a07 --- /dev/null +++ b/avr/modules/lcd2/font/font4.asm @@ -0,0 +1,258 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +; *************************************************************************** +; This is a font from the project LCD_fonts at +; https://github.com/basti79/LCD-fonts.git +; which in turn is based on a post by Benedikt K. in a forum post on +; https://www.mikrocontroller.net/topic/54860 +; *************************************************************************** + + + +; *************************************************************************** +; code + +.cseg + + + +font4_12x16: +; header + .dw font12x16MonoHandlerFn ; handlerFn + .dw 384 ; needed buffer size + .db 12, 16 ; width, height of chars + .db 32, 224 ; first char, num of chars in font +; data (12x16_horizontal_LSB_2) +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x20 +.db 0x60,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0x21 +.db 0x00,0x00,0x00,0x00,0x98,0x01,0x98,0x01,0x98,0x01,0x98,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x22 +.db 0x00,0x00,0x60,0x06,0x60,0x06,0x60,0x06,0xFC,0x0F,0x30,0x03,0x30,0x03,0x98,0x01,0x98,0x01,0xFE,0x03,0xCC,0x00,0xCC,0x00,0xCC,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x23 +.db 0x60,0x00,0x60,0x00,0xF8,0x01,0xFC,0x03,0x6C,0x00,0x6C,0x00,0xFC,0x01,0xF8,0x03,0x60,0x03,0x60,0x03,0xFC,0x03,0xF8,0x01,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0x24 +.db 0x00,0x00,0x00,0x00,0x00,0x08,0x1C,0x0C,0x1C,0x0E,0x1C,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x07,0x0E,0x07,0x06,0x07,0x00,0x00,0x00,0x00, ; 0x25 +.db 0x00,0x00,0xE0,0x00,0xB0,0x01,0x98,0x01,0x98,0x01,0xD8,0x00,0x70,0x00,0x78,0x00,0x7C,0x00,0xCC,0x06,0xCC,0x03,0x8C,0x01,0xDC,0x03,0x78,0x06,0x00,0x00,0x00,0x00, ; 0x26 +.db 0x70,0x00,0x70,0x00,0x70,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x27 +.db 0xC0,0x01,0x60,0x00,0x70,0x00,0x30,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x30,0x00,0x70,0x00,0x60,0x00,0xC0,0x01,0x00,0x00,0x00,0x00, ; 0x28 +.db 0x38,0x00,0x60,0x00,0xE0,0x00,0xC0,0x00,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x00,0xE0,0x00,0x60,0x00,0x38,0x00,0x00,0x00,0x00,0x00, ; 0x29 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x03,0x6C,0x03,0xF8,0x01,0xF0,0x00,0xFC,0x03,0xF0,0x00,0xF8,0x01,0x6C,0x03,0x6C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x2A +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFC,0x03,0xFC,0x03,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x2B +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x60,0x00,0x30,0x00, ; 0x2C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x2D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00, ; 0x2E +.db 0x00,0x00,0x00,0x08,0x00,0x0C,0x00,0x0E,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x0E,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x2F +.db 0xF0,0x01,0xFC,0x07,0x0C,0x06,0x06,0x0E,0x06,0x0F,0x86,0x0D,0xC6,0x0C,0x66,0x0C,0x36,0x0C,0x1E,0x0C,0x0E,0x0C,0x0C,0x06,0xFC,0x07,0xF0,0x01,0x00,0x00,0x00,0x00, ; 0x30 +.db 0xC0,0x00,0xE0,0x00,0xF8,0x00,0xF8,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xF8,0x07,0xF8,0x07,0x00,0x00,0x00,0x00, ; 0x31 +.db 0xF8,0x03,0xFC,0x07,0x0E,0x0E,0x06,0x0C,0x06,0x0E,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0xFE,0x0F,0xFE,0x0F,0x00,0x00,0x00,0x00, ; 0x32 +.db 0xF8,0x03,0xFC,0x07,0x0E,0x0E,0x06,0x0C,0x00,0x0C,0x00,0x0E,0xF0,0x07,0xF0,0x03,0x00,0x06,0x00,0x0C,0x06,0x0C,0x0E,0x0E,0xFC,0x07,0xF8,0x03,0x00,0x00,0x00,0x00, ; 0x33 +.db 0x80,0x03,0xC0,0x03,0xE0,0x03,0x70,0x03,0x38,0x03,0x1C,0x03,0x0E,0x03,0x06,0x03,0xFE,0x0F,0xFE,0x0F,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00, ; 0x34 +.db 0xFE,0x0F,0xFE,0x0F,0x06,0x00,0x06,0x00,0x06,0x00,0xFE,0x03,0xFC,0x07,0x00,0x0E,0x00,0x0C,0x00,0x0C,0x06,0x0C,0x0E,0x0E,0xFC,0x07,0xF8,0x03,0x00,0x00,0x00,0x00, ; 0x35 +.db 0xC0,0x03,0xE0,0x03,0x70,0x00,0x38,0x00,0x1C,0x00,0x0C,0x00,0xFE,0x03,0xFE,0x07,0x0E,0x0E,0x06,0x0C,0x06,0x0C,0x0E,0x0E,0xFC,0x07,0xF8,0x03,0x00,0x00,0x00,0x00, ; 0x36 +.db 0xFE,0x0F,0xFE,0x0F,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x80,0x01,0x80,0x01,0xC0,0x00,0xC0,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00, ; 0x37 +.db 0xF0,0x01,0xF8,0x03,0x1C,0x07,0x0C,0x06,0x0C,0x06,0x1C,0x07,0xF8,0x03,0xFC,0x07,0x0E,0x0E,0x06,0x0C,0x06,0x0C,0x0E,0x0E,0xFC,0x07,0xF8,0x03,0x00,0x00,0x00,0x00, ; 0x38 +.db 0xF8,0x03,0xFC,0x07,0x0E,0x0E,0x06,0x0C,0x06,0x0C,0x0E,0x0E,0xFC,0x0F,0xF8,0x0F,0x00,0x06,0x00,0x07,0x80,0x03,0xC0,0x01,0xF8,0x00,0x78,0x00,0x00,0x00,0x00,0x00, ; 0x39 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x3A +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x60,0x00,0x60,0x00,0x30,0x00, ; 0x3B +.db 0x00,0x03,0x80,0x03,0xC0,0x01,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x1C,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0xC0,0x01,0x80,0x03,0x00,0x03,0x00,0x00,0x00,0x00, ; 0x3C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x07,0xFC,0x07,0x00,0x00,0x00,0x00,0xFC,0x07,0xFC,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x3D +.db 0x0C,0x00,0x1C,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0xC0,0x01,0x80,0x03,0x80,0x03,0xC0,0x01,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00, ; 0x3E +.db 0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x07,0x80,0x03,0xC0,0x01,0xE0,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0x3F +.db 0xF8,0x03,0xFC,0x07,0x0C,0x06,0xE6,0x0D,0xF6,0x0D,0xB6,0x0D,0xB6,0x0D,0xB6,0x0D,0xB6,0x0D,0xF6,0x07,0xE6,0x03,0x0E,0x00,0xFC,0x03,0xF0,0x03,0x00,0x00,0x00,0x00, ; 0x40 +.db 0x60,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0x98,0x01,0x98,0x01,0x98,0x01,0x0C,0x03,0xFC,0x03,0xFC,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00, ; 0x41 +.db 0xFE,0x00,0xFE,0x01,0x86,0x03,0x06,0x03,0x06,0x03,0x86,0x03,0xFE,0x01,0xFE,0x03,0x06,0x07,0x06,0x06,0x06,0x06,0x06,0x07,0xFE,0x03,0xFE,0x01,0x00,0x00,0x00,0x00, ; 0x42 +.db 0xF0,0x01,0xF8,0x03,0x1C,0x07,0x0C,0x06,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x0C,0x06,0x1C,0x07,0xF8,0x03,0xF0,0x01,0x00,0x00,0x00,0x00, ; 0x43 +.db 0xFE,0x00,0xFE,0x01,0x86,0x03,0x06,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x03,0x86,0x03,0xFE,0x01,0xFE,0x00,0x00,0x00,0x00,0x00, ; 0x44 +.db 0xFE,0x07,0xFE,0x07,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xFE,0x01,0xFE,0x01,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00, ; 0x45 +.db 0xFE,0x07,0xFE,0x07,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xFE,0x01,0xFE,0x01,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00, ; 0x46 +.db 0xF0,0x03,0xF8,0x07,0x1C,0x06,0x0C,0x00,0x06,0x00,0x06,0x00,0xC6,0x07,0xC6,0x07,0x06,0x06,0x06,0x06,0x0C,0x06,0x1C,0x06,0xF8,0x07,0xF0,0x07,0x00,0x00,0x00,0x00, ; 0x47 +.db 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0xFE,0x07,0xFE,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00, ; 0x48 +.db 0xF8,0x01,0xF8,0x01,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x49 +.db 0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x06,0x06,0x06,0x06,0x0E,0x03,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x4A +.db 0x06,0x06,0x06,0x07,0x86,0x03,0xC6,0x01,0xE6,0x00,0x76,0x00,0x3E,0x00,0x3E,0x00,0x76,0x00,0xE6,0x00,0xC6,0x01,0x86,0x03,0x06,0x07,0x06,0x06,0x00,0x00,0x00,0x00, ; 0x4B +.db 0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00, ; 0x4C +.db 0x06,0x06,0x0E,0x07,0x0E,0x07,0x9E,0x07,0x9E,0x07,0xF6,0x06,0xF6,0x06,0x66,0x06,0x66,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00, ; 0x4D +.db 0x06,0x06,0x0E,0x06,0x0E,0x06,0x1E,0x06,0x36,0x06,0x36,0x06,0x66,0x06,0x66,0x06,0xC6,0x06,0xC6,0x06,0x86,0x07,0x06,0x07,0x06,0x07,0x06,0x06,0x00,0x00,0x00,0x00, ; 0x4E +.db 0xF0,0x00,0xF8,0x01,0x9C,0x03,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0x9C,0x03,0xF8,0x01,0xF0,0x00,0x00,0x00,0x00,0x00, ; 0x4F +.db 0xFE,0x01,0xFE,0x03,0x06,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07,0xFE,0x03,0xFE,0x01,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00, ; 0x50 +.db 0xF0,0x00,0xF8,0x01,0x9C,0x03,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0xC6,0x06,0xCC,0x03,0x9C,0x03,0xF8,0x07,0xF0,0x06,0x00,0x00,0x00,0x00, ; 0x51 +.db 0xFE,0x01,0xFE,0x03,0x06,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07,0xFE,0x03,0xFE,0x01,0xE6,0x00,0xC6,0x01,0x86,0x03,0x06,0x07,0x06,0x06,0x00,0x00,0x00,0x00, ; 0x52 +.db 0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x00,0x0E,0x00,0xFC,0x01,0xF8,0x03,0x00,0x07,0x00,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x53 +.db 0xFC,0x03,0xFC,0x03,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0x54 +.db 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x55 +.db 0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x98,0x01,0x98,0x01,0x98,0x01,0xF0,0x00,0xF0,0x00,0xF0,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0x56 +.db 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x06,0x66,0x06,0xF6,0x06,0x9E,0x07,0x0E,0x07,0x0E,0x07,0x06,0x06,0x00,0x00,0x00,0x00, ; 0x57 +.db 0x06,0x06,0x06,0x06,0x0C,0x03,0x0C,0x03,0x98,0x01,0xF0,0x00,0x60,0x00,0x60,0x00,0xF0,0x00,0x98,0x01,0x0C,0x03,0x0C,0x03,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00, ; 0x58 +.db 0x06,0x06,0x06,0x06,0x0C,0x03,0x0C,0x03,0x98,0x01,0x98,0x01,0xF0,0x00,0xF0,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0x59 +.db 0xFE,0x07,0xFE,0x07,0x00,0x03,0x00,0x03,0x80,0x01,0xC0,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00, ; 0x5A +.db 0xF8,0x01,0xF8,0x01,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x5B +.db 0x00,0x00,0x02,0x00,0x06,0x00,0x0E,0x00,0x1C,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0xC0,0x01,0x80,0x03,0x00,0x07,0x00,0x0E,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x5C +.db 0xF8,0x01,0xF8,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x5D +.db 0x40,0x00,0xE0,0x00,0xF0,0x01,0xB8,0x03,0x1C,0x07,0x0E,0x0E,0x06,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x5E +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x0F,0xFE,0x0F, ; 0x5F +.db 0x00,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0x60,0x00,0x60,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x60 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x03,0xFC,0x07,0x00,0x06,0xF8,0x07,0xFC,0x07,0x06,0x06,0x06,0x06,0xFE,0x07,0xFC,0x07,0x00,0x00,0x00,0x00, ; 0x61 +.db 0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xF6,0x01,0xFE,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07,0xFE,0x03,0xFE,0x01,0x00,0x00,0x00,0x00, ; 0x62 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x06,0x06,0x00,0x06,0x00,0x06,0x00,0x0E,0x06,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x63 +.db 0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0xF8,0x06,0xFC,0x07,0x8E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x06,0xFC,0x07,0xF8,0x07,0x00,0x00,0x00,0x00, ; 0x64 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x06,0xFE,0x07,0xFE,0x03,0x06,0x00,0x0E,0x00,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x65 +.db 0xE0,0x01,0xF0,0x01,0x38,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0xFE,0x00,0xFE,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00, ; 0x66 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x07,0xFC,0x07,0x0E,0x06,0x06,0x06,0x0E,0x07,0xFC,0x07,0xF8,0x06,0x00,0x06,0x00,0x07,0xFC,0x03,0xFC,0x01, ; 0x67 +.db 0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xF6,0x00,0xFE,0x01,0x8E,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x00,0x00,0x00,0x00, ; 0x68 +.db 0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x69 +.db 0x00,0x00,0x00,0x00,0x80,0x01,0x80,0x01,0x00,0x00,0xC0,0x01,0xC0,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x98,0x01,0xF8,0x01,0xF0,0x00, ; 0x6A +.db 0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x8C,0x01,0xCC,0x01,0xEC,0x00,0x7C,0x00,0x7C,0x00,0xEC,0x00,0xCC,0x01,0x8C,0x03,0x0C,0x03,0x00,0x00,0x00,0x00, ; 0x6B +.db 0x70,0x00,0x70,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x6C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9A,0x01,0xFE,0x03,0xFE,0x07,0x66,0x06,0x66,0x06,0x66,0x06,0x66,0x06,0x66,0x06,0x66,0x06,0x00,0x00,0x00,0x00, ; 0x6D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0xFC,0x03,0x0C,0x07,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x00,0x00,0x00,0x00, ; 0x6E +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x6F +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0xFE,0x03,0x06,0x07,0x06,0x06,0x06,0x06,0x0E,0x07,0xFE,0x03,0xF6,0x01,0x06,0x00,0x06,0x00,0x06,0x00, ; 0x70 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x07,0xFC,0x07,0x0E,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x07,0xF8,0x06,0x00,0x06,0x00,0x06,0x00,0x06, ; 0x71 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEC,0x03,0xFC,0x07,0x1C,0x06,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00, ; 0x72 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0xFE,0x01,0x06,0x00,0xFE,0x00,0xFC,0x01,0x80,0x01,0x80,0x01,0xFE,0x01,0xFC,0x00,0x00,0x00,0x00,0x00, ; 0x73 +.db 0x00,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0xFE,0x00,0xFE,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0xF8,0x01,0xF0,0x01,0x00,0x00,0x00,0x00, ; 0x74 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x07,0xF8,0x06,0x00,0x00,0x00,0x00, ; 0x75 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x0C,0x03,0x0C,0x03,0x98,0x01,0x98,0x01,0xF0,0x00,0xF0,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0x76 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x06,0x66,0x06,0x66,0x06,0x66,0x06,0x66,0x06,0xF6,0x06,0xFC,0x03,0x9C,0x03,0x08,0x01,0x00,0x00,0x00,0x00, ; 0x77 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x03,0x8E,0x03,0xDC,0x01,0xF8,0x00,0x70,0x00,0xF8,0x00,0xDC,0x01,0x8E,0x03,0x06,0x03,0x00,0x00,0x00,0x00, ; 0x78 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x0C,0x03,0x98,0x01,0x98,0x01,0xF0,0x00,0xF0,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00, ; 0x79 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x03,0xFE,0x01,0xC0,0x00,0x60,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0xFE,0x03,0xFE,0x03,0x00,0x00,0x00,0x00, ; 0x7A +.db 0xC0,0x03,0xE0,0x03,0x70,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x38,0x00,0x1C,0x00,0x38,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x70,0x00,0xE0,0x03,0xC0,0x03,0x00,0x00, ; 0x7B +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0x7C +.db 0x3C,0x00,0x7C,0x00,0xE0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x01,0x80,0x03,0xC0,0x01,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xE0,0x00,0x7C,0x00,0x3C,0x00,0x00,0x00, ; 0x7D +.db 0x00,0x00,0x00,0x00,0x38,0x06,0x6C,0x03,0xC6,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x7E +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0xF0,0x00,0x98,0x01,0x0C,0x03,0x06,0x06,0x06,0x06,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x7F +.db 0xF0,0x01,0xF8,0x03,0x1C,0x07,0x0C,0x06,0x06,0x06,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x0C,0x06,0x1C,0x07,0xF8,0x03,0xF0,0x01,0x60,0x00,0x78,0x00,0x78,0x00, ; 0x80 +.db 0x00,0x00,0x00,0x00,0x98,0x01,0x98,0x01,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x07,0xF8,0x06,0x00,0x00,0x00,0x00, ; 0x81 +.db 0x00,0x00,0x80,0x01,0xC0,0x00,0x60,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x06,0xFE,0x07,0xFE,0x07,0x06,0x00,0x0E,0x00,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x82 +.db 0x00,0x00,0x60,0x00,0xF0,0x00,0x98,0x01,0x00,0x00,0xF8,0x03,0xFC,0x07,0x00,0x06,0xF8,0x07,0xFC,0x07,0x06,0x06,0x06,0x06,0xFE,0x07,0xFC,0x07,0x00,0x00,0x00,0x00, ; 0x83 +.db 0x00,0x00,0x00,0x00,0x98,0x01,0x98,0x01,0x00,0x00,0xF8,0x03,0xFC,0x07,0x00,0x06,0xF8,0x07,0xFC,0x07,0x06,0x06,0x06,0x06,0xFE,0x07,0xFC,0x07,0x00,0x00,0x00,0x00, ; 0x84 +.db 0x00,0x00,0x30,0x00,0x60,0x00,0xC0,0x00,0x00,0x00,0xF8,0x03,0xFC,0x07,0x00,0x06,0xF8,0x07,0xFC,0x07,0x06,0x06,0x06,0x06,0xFE,0x07,0xFC,0x07,0x00,0x00,0x00,0x00, ; 0x85 +.db 0x00,0x00,0x60,0x00,0x90,0x00,0x60,0x00,0x00,0x00,0xF8,0x03,0xFC,0x07,0x00,0x06,0xF8,0x07,0xFC,0x07,0x06,0x06,0x06,0x06,0xFE,0x07,0xFC,0x07,0x00,0x00,0x00,0x00, ; 0x86 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x00,0x06,0x00,0x06,0x00,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x60,0x00,0x78,0x00, ; 0x87 +.db 0x00,0x00,0x60,0x00,0xF0,0x00,0x98,0x01,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x06,0xFE,0x07,0xFE,0x07,0x06,0x00,0x06,0x00,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x88 +.db 0x00,0x00,0x00,0x00,0x98,0x01,0x98,0x01,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x06,0xFE,0x07,0xFE,0x07,0x06,0x00,0x06,0x00,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x89 +.db 0x00,0x00,0x30,0x00,0x60,0x00,0xC0,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x06,0xFE,0x07,0xFE,0x07,0x06,0x00,0x06,0x00,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x8A +.db 0x00,0x00,0x00,0x00,0xD8,0x00,0xD8,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x8B +.db 0x00,0x00,0x60,0x00,0xF0,0x00,0x98,0x01,0x00,0x00,0x70,0x00,0x70,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x8C +.db 0x00,0x00,0x30,0x00,0x60,0x00,0xC0,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x8D +.db 0x98,0x01,0x98,0x01,0x00,0x00,0x60,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0x98,0x01,0x98,0x01,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00, ; 0x8E +.db 0x60,0x00,0x90,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0x98,0x01,0x98,0x01,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00, ; 0x8F +.db 0x80,0x01,0xC0,0x00,0x60,0x00,0xFE,0x07,0xFE,0x07,0x06,0x00,0x06,0x00,0xFE,0x01,0xFE,0x01,0x06,0x00,0x06,0x00,0x06,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00, ; 0x90 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBC,0x03,0x66,0x06,0x60,0x06,0xFC,0x03,0x66,0x00,0x66,0x00,0x66,0x06,0xDC,0x03,0x00,0x00,0x00,0x00, ; 0x91 +.db 0xE0,0x07,0xE0,0x07,0xF0,0x00,0xF0,0x00,0xF8,0x00,0xD8,0x00,0xD8,0x03,0xCC,0x03,0xCC,0x00,0xFC,0x00,0xFE,0x00,0xC6,0x00,0xC6,0x07,0xC6,0x07,0x00,0x00,0x00,0x00, ; 0x92 +.db 0x00,0x00,0x60,0x00,0xF0,0x00,0x98,0x01,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x93 +.db 0x00,0x00,0x00,0x00,0x98,0x01,0x98,0x01,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x94 +.db 0x00,0x00,0x30,0x00,0x60,0x00,0xC0,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x95 +.db 0x00,0x00,0x60,0x00,0xF0,0x00,0x98,0x01,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x07,0xF8,0x06,0x00,0x00,0x00,0x00, ; 0x96 +.db 0x00,0x00,0x30,0x00,0x60,0x00,0xC0,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x07,0xF8,0x06,0x00,0x00,0x00,0x00, ; 0x97 +.db 0x00,0x00,0x00,0x00,0x98,0x01,0x98,0x01,0x00,0x00,0x0C,0x03,0x0C,0x03,0x98,0x01,0x98,0x01,0xF0,0x00,0xF0,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00, ; 0x98 +.db 0x98,0x01,0x98,0x01,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0x99 +.db 0x00,0x00,0x00,0x00,0x98,0x01,0x98,0x01,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x07,0xF8,0x06,0x00,0x00,0x00,0x00, ; 0x9A +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x06,0xFC,0x03,0x8E,0x07,0xC6,0x06,0x66,0x06,0x36,0x06,0x1E,0x07,0xFC,0x03,0xF6,0x01,0x00,0x00,0x00,0x00, ; 0x9B +.db 0x00,0x00,0x00,0x00,0xE0,0x01,0xF0,0x03,0x30,0x03,0x30,0x00,0x30,0x00,0xF8,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0xFC,0x07,0xDC,0x03,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x9C +.db 0x00,0x00,0x00,0x00,0xF8,0x06,0xFC,0x03,0x8E,0x07,0xC6,0x06,0xC6,0x06,0x66,0x06,0x66,0x06,0x36,0x06,0x36,0x06,0x1E,0x07,0xFC,0x03,0xF6,0x01,0x00,0x00,0x00,0x00, ; 0x9D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x03,0x98,0x01,0xF0,0x00,0x60,0x00,0xF0,0x00,0x98,0x01,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x9E +.db 0xC0,0x01,0xE0,0x03,0x60,0x03,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6C,0x00,0x7C,0x00,0x38,0x00,0x00,0x00, ; 0x9F +.db 0x00,0x00,0xC0,0x00,0x60,0x00,0x30,0x00,0x00,0x00,0xF8,0x03,0xFC,0x07,0x00,0x06,0xF8,0x07,0xFC,0x07,0x06,0x06,0x06,0x06,0xFE,0x07,0xFC,0x07,0x00,0x00,0x00,0x00, ; 0xA0 +.db 0x00,0x00,0xC0,0x00,0x60,0x00,0x30,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xA1 +.db 0x00,0x00,0xC0,0x00,0x60,0x00,0x30,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xA2 +.db 0x00,0x00,0xC0,0x00,0x60,0x00,0x30,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x07,0xF8,0x06,0x00,0x00,0x00,0x00, ; 0xA3 +.db 0x00,0x00,0x00,0x00,0x70,0x03,0xD8,0x01,0x00,0x00,0xFC,0x01,0xFC,0x03,0x0C,0x07,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x06,0x00,0x00,0x00,0x00, ; 0xA4 +.db 0x70,0x03,0xD8,0x01,0x00,0x00,0x06,0x06,0x0E,0x06,0x1E,0x06,0x3E,0x06,0x76,0x06,0xE6,0x06,0xC6,0x07,0x86,0x07,0x06,0x07,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00, ; 0xA5 +.db 0xF8,0x03,0xFC,0x07,0x00,0x06,0xFC,0x07,0xFE,0x07,0x06,0x06,0xFE,0x07,0xFC,0x07,0x00,0x00,0xFC,0x03,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA6 +.db 0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0xFC,0x03,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA7 +.db 0x60,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x0E,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xA8 +.db 0x00,0x00,0x00,0x00,0xF8,0x03,0xFC,0x07,0x0E,0x0E,0xF6,0x0C,0xB6,0x0D,0xF6,0x0C,0xB6,0x0D,0xB6,0x0D,0x0E,0x0E,0xFC,0x07,0xF8,0x03,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA9 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0xFF,0x07,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAA +.db 0x00,0x00,0x00,0x00,0x0C,0x00,0x0E,0x00,0x0C,0x03,0x8C,0x01,0xDE,0x00,0x60,0x00,0xB0,0x03,0x18,0x06,0x0C,0x03,0x80,0x01,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAB +.db 0x00,0x00,0x00,0x00,0x0C,0x00,0x0E,0x00,0x0C,0x03,0x8C,0x01,0xDE,0x00,0x60,0x00,0xB0,0x06,0xD8,0x06,0xCC,0x07,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAC +.db 0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0xAD +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x03,0x8C,0x01,0xC6,0x00,0x8C,0x01,0x18,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAE +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x00,0x8C,0x01,0x18,0x03,0x8C,0x01,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAF +.db 0x11,0x01,0x44,0x04,0x11,0x01,0x44,0x04,0x11,0x01,0x44,0x04,0x11,0x01,0x44,0x04,0x11,0x01,0x44,0x04,0x11,0x01,0x44,0x04,0x11,0x01,0x44,0x04,0x11,0x01,0x44,0x04, ; 0xB0 +.db 0xAA,0x0A,0x55,0x05,0xAA,0x0A,0x55,0x05,0xAA,0x0A,0x55,0x05,0xAA,0x0A,0x55,0x05,0xAA,0x0A,0x55,0x05,0xAA,0x0A,0x55,0x05,0xAA,0x0A,0x55,0x05,0xAA,0x0A,0x55,0x05, ; 0xB1 +.db 0xEE,0x0E,0xBB,0x0B,0xEE,0x0E,0xBB,0x0B,0xEE,0x0E,0xBB,0x0B,0xEE,0x0E,0xBB,0x0B,0xEE,0x0E,0xBB,0x0B,0xEE,0x0E,0xBB,0x0B,0xEE,0x0E,0xBB,0x0B,0xEE,0x0E,0xBB,0x0B, ; 0xB2 +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xB3 +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xB4 +.db 0xC0,0x00,0x60,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0x98,0x01,0x98,0x01,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00, ; 0xB5 +.db 0x60,0x00,0xF0,0x00,0x98,0x01,0x60,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0x98,0x01,0x98,0x01,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00, ; 0xB6 +.db 0x30,0x00,0x60,0x00,0xC0,0x00,0x60,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0x98,0x01,0x98,0x01,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00, ; 0xB7 +.db 0x00,0x00,0x00,0x00,0xF8,0x03,0xFC,0x07,0x0E,0x0E,0xE6,0x0C,0xB6,0x0D,0x36,0x0C,0xB6,0x0D,0xE6,0x0C,0x0E,0x0E,0xFC,0x07,0xF8,0x03,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xB8 +.db 0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6F,0x00,0x6F,0x00,0x60,0x00,0x6F,0x00,0x6F,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00, ; 0xB9 +.db 0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00, ; 0xBA +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x7F,0x00,0x60,0x00,0x6F,0x00,0x6F,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00, ; 0xBB +.db 0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6F,0x00,0x6F,0x00,0x60,0x00,0x7F,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xBC +.db 0x00,0x00,0x60,0x00,0x60,0x00,0xF0,0x01,0xF8,0x03,0x7C,0x03,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x7C,0x03,0xF8,0x03,0xF0,0x01,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0xBD +.db 0x06,0x06,0x06,0x06,0x0C,0x03,0x0C,0x03,0x98,0x01,0x98,0x01,0xF0,0x00,0xF0,0x00,0x60,0x00,0xFC,0x03,0x60,0x00,0xFC,0x03,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0xBE +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xBF +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xE0,0x0F,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC0 +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC1 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xC2 +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xE0,0x0F,0xE0,0x0F,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xC3 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC4 +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFF,0x0F,0xFF,0x0F,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xC5 +.db 0x00,0x00,0x00,0x00,0x70,0x03,0xD8,0x01,0x00,0x00,0xF8,0x03,0xFC,0x07,0x00,0x06,0xF8,0x07,0xFC,0x07,0x06,0x06,0x06,0x06,0xFE,0x07,0xFC,0x07,0x00,0x00,0x00,0x00, ; 0xC6 +.db 0x70,0x03,0xD8,0x01,0x00,0x00,0x60,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0x98,0x01,0x98,0x01,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00, ; 0xC7 +.db 0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0xEC,0x0F,0xEC,0x0F,0x0C,0x00,0xFC,0x0F,0xFC,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC8 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x0F,0xFC,0x0F,0x0C,0x00,0xEC,0x0F,0xEC,0x0F,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00, ; 0xC9 +.db 0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0xEF,0x0F,0xEF,0x0F,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xCA +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0xEF,0x0F,0xEF,0x0F,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00, ; 0xCB +.db 0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0xEC,0x0F,0xEC,0x0F,0x0C,0x00,0xEC,0x0F,0xEC,0x0F,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00, ; 0xCC +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xCD +.db 0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0xEF,0x0F,0xEF,0x0F,0x00,0x00,0xEF,0x0F,0xEF,0x0F,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00, ; 0xCE +.db 0x00,0x00,0x06,0x06,0xF6,0x06,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF6,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xCF +.db 0x00,0x00,0x00,0x00,0xF0,0x00,0xF8,0x01,0x18,0x01,0x18,0x00,0x38,0x00,0x70,0x00,0xE0,0x00,0xF0,0x01,0x98,0x01,0x98,0x01,0xF8,0x01,0xF0,0x00,0x00,0x00,0x00,0x00, ; 0xD0 +.db 0xFC,0x00,0xFC,0x01,0x8C,0x03,0x0C,0x03,0x0C,0x06,0x0C,0x06,0x1E,0x06,0x1E,0x06,0x0C,0x06,0x0C,0x06,0x0C,0x03,0x8C,0x03,0xFC,0x01,0xFC,0x00,0x00,0x00,0x00,0x00, ; 0xD1 +.db 0x60,0x00,0xF0,0x00,0x98,0x01,0xFE,0x07,0xFE,0x07,0x06,0x00,0x06,0x00,0xFE,0x01,0xFE,0x01,0x06,0x00,0x06,0x00,0x06,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00, ; 0xD2 +.db 0x98,0x01,0x98,0x01,0x00,0x00,0xFE,0x07,0xFE,0x07,0x06,0x00,0x06,0x00,0xFE,0x01,0xFE,0x01,0x06,0x00,0x06,0x00,0x06,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00, ; 0xD3 +.db 0x18,0x00,0x30,0x00,0x60,0x00,0xFE,0x07,0xFE,0x07,0x06,0x00,0x06,0x00,0xFE,0x01,0xFE,0x01,0x06,0x00,0x06,0x00,0x06,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00, ; 0xD4 +.db 0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD5 +.db 0x80,0x01,0xC0,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xD6 +.db 0x60,0x00,0xF0,0x00,0x98,0x01,0xF8,0x01,0xF8,0x01,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xD7 +.db 0x98,0x01,0x98,0x01,0x00,0x00,0xF8,0x01,0xF8,0x01,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xD8 +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD9 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0xE0,0x0F,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xDA +.db 0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F, ; 0xDB +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F, ; 0xDC +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0xDD +.db 0x18,0x00,0x30,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xDE +.db 0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xDF +.db 0x80,0x01,0xC0,0x00,0x60,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xE0 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x98,0x01,0x0C,0x03,0x0C,0x03,0xFC,0x01,0x8C,0x03,0x0C,0x03,0x0C,0x03,0x8C,0x03,0xFC,0x01,0x0C,0x00,0x0C,0x00, ; 0xE1 +.db 0x60,0x00,0xF0,0x00,0x98,0x01,0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xE2 +.db 0x18,0x00,0x30,0x00,0x60,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xE3 +.db 0x00,0x00,0x00,0x00,0xB8,0x01,0xEC,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xE4 +.db 0x70,0x03,0xD8,0x01,0x00,0x00,0xF8,0x01,0xFC,0x03,0x0E,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0E,0x07,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xE5 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0xFE,0x03,0x7E,0x03,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00, ; 0xE6 +.db 0x00,0x00,0x00,0x00,0x3C,0x00,0x3C,0x00,0x18,0x00,0xF8,0x01,0xF8,0x03,0x18,0x03,0x18,0x03,0xF8,0x03,0xF8,0x01,0x18,0x00,0x3C,0x00,0x3C,0x00,0x00,0x00,0x00,0x00, ; 0xE7 +.db 0x3C,0x00,0x3C,0x00,0x18,0x00,0xF8,0x01,0xF8,0x03,0x18,0x03,0x18,0x03,0x18,0x03,0x18,0x03,0xF8,0x03,0xF8,0x01,0x18,0x00,0x3C,0x00,0x3C,0x00,0x00,0x00,0x00,0x00, ; 0xE8 +.db 0x80,0x01,0xC0,0x00,0x60,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xE9 +.db 0x60,0x00,0xF0,0x00,0x98,0x01,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xEA +.db 0x18,0x00,0x30,0x00,0x60,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0xFC,0x03,0xF8,0x01,0x00,0x00,0x00,0x00, ; 0xEB +.db 0x00,0x00,0x00,0x00,0x80,0x01,0xC0,0x00,0x60,0x00,0x0C,0x03,0x0C,0x03,0x98,0x01,0x98,0x01,0xF0,0x00,0xF0,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00, ; 0xEC +.db 0x80,0x01,0xC0,0x00,0x60,0x00,0x06,0x06,0x0C,0x03,0x98,0x01,0xF0,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, ; 0xED +.db 0x00,0x00,0x00,0x00,0xE0,0x01,0xE0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xEE +.db 0xC0,0x00,0x60,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xEF +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF0 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0xF8,0x01,0xF8,0x01,0x60,0x00,0x60,0x00,0x00,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF1 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0xF8,0x01,0xF8,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF2 +.db 0x00,0x00,0x00,0x00,0x0E,0x00,0x18,0x00,0x0C,0x03,0x98,0x01,0xCE,0x00,0x60,0x00,0xB0,0x06,0xD8,0x06,0xCC,0x07,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF3 +.db 0x00,0x00,0xF8,0x07,0x6C,0x03,0x66,0x03,0x66,0x03,0x66,0x03,0x6C,0x03,0x78,0x03,0x60,0x03,0x60,0x03,0x60,0x03,0x60,0x03,0x60,0x03,0x60,0x03,0x00,0x00,0x00,0x00, ; 0xF4 +.db 0x00,0x00,0xF8,0x01,0x0C,0x03,0x0C,0x00,0x0C,0x00,0xF8,0x01,0x0C,0x03,0x0C,0x03,0xF8,0x01,0x00,0x03,0x00,0x03,0x0C,0x03,0xF8,0x01,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF5 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0xFC,0x03,0xFC,0x03,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF6 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC8,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF7 +.db 0xF0,0x00,0xF8,0x01,0x98,0x01,0x98,0x01,0xF8,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF8 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x01,0x9C,0x03,0x9C,0x03,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF9 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xE0,0x00,0xE0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFA +.db 0x18,0x00,0x1C,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFB +.db 0x3C,0x00,0x60,0x00,0x38,0x00,0x60,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFC +.db 0x3C,0x00,0x60,0x00,0x38,0x00,0x0C,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFD +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFE +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ; 0xFF + diff --git a/avr/modules/lcd2/font/font5.asm b/avr/modules/lcd2/font/font5.asm new file mode 100644 index 0000000..afe78fc --- /dev/null +++ b/avr/modules/lcd2/font/font5.asm @@ -0,0 +1,258 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +; *************************************************************************** +; This is a font from the project LCD_fonts at +; https://github.com/basti79/LCD-fonts.git +; which in turn is based on a post by Benedikt K. in a forum post on +; https://www.mikrocontroller.net/topic/54860 +; *************************************************************************** + + + +; *************************************************************************** +; code + +.cseg + + + +font5_12x20: +; header + .dw font12x20MonoHandlerFn ; handlerFn + .dw 480 ; needed buffer size + .db 12, 20 ; width, height of chars + .db 32, 224 ; first char, num of chars in font +; data (16x20_horizontal_LSB_2) +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x20 +.db 0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x21 +.db 0x00,0x00,0x8C,0x01,0x8C,0x01,0x8C,0x01,0x8C,0x01,0x8C,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x22 +.db 0x00,0x00,0x00,0x00,0x20,0x02,0x20,0x02,0x10,0x01,0x10,0x01,0x10,0x01,0xFE,0x0F,0x88,0x00,0x88,0x00,0x88,0x00,0xFE,0x07,0x44,0x00,0x44,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x23 +.db 0x00,0x00,0x40,0x00,0xF0,0x01,0xF8,0x03,0x4C,0x02,0x4C,0x00,0x4C,0x00,0x78,0x00,0x70,0x00,0xC0,0x01,0xC0,0x01,0x40,0x03,0x40,0x03,0x44,0x03,0xFC,0x01,0xF8,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x24 +.db 0x00,0x00,0x00,0x00,0x1E,0x08,0x33,0x04,0x33,0x02,0x33,0x01,0xB3,0x00,0xB3,0x00,0x5E,0x00,0xA0,0x07,0xD0,0x0C,0xD0,0x0C,0xC8,0x0C,0xC4,0x0C,0xC2,0x0C,0x81,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x25 +.db 0x00,0x00,0x00,0x00,0xF0,0x00,0xF8,0x01,0x98,0x01,0x98,0x01,0xD8,0x00,0x70,0x00,0x3C,0x00,0x66,0x0C,0xE3,0x0C,0xC3,0x0C,0x83,0x07,0x87,0x07,0xFE,0x07,0xFC,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x26 +.db 0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x27 +.db 0x00,0x00,0x00,0x03,0xC0,0x03,0xE0,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0xE0,0x00,0xC0,0x03,0x00,0x03,0x00,0x00, ; 0x28 +.db 0x00,0x00,0x0C,0x00,0x3C,0x00,0x70,0x00,0x60,0x00,0xC0,0x00,0xC0,0x00,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xC0,0x00,0xC0,0x00,0x60,0x00,0x70,0x00,0x3C,0x00,0x0C,0x00,0x00,0x00, ; 0x29 +.db 0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x36,0x03,0xCE,0x03,0x00,0x00,0xD8,0x00,0x9C,0x01,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x2A +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFE,0x07,0xFE,0x07,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x2B +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x60,0x00,0x20,0x00,0x30,0x00,0x00,0x00, ; 0x2C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x2D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x2E +.db 0x00,0x00,0x00,0x06,0x00,0x03,0x00,0x03,0x80,0x01,0x80,0x01,0x80,0x01,0xC0,0x00,0xC0,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x00,0x00, ; 0x2F +.db 0x00,0x00,0x00,0x00,0xF0,0x00,0xF8,0x01,0x0C,0x03,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0x0C,0x03,0xF8,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x30 +.db 0x00,0x00,0x00,0x00,0x60,0x00,0x7C,0x00,0x66,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x31 +.db 0x00,0x00,0x00,0x00,0xF8,0x00,0xFC,0x01,0x84,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x80,0x01,0xC0,0x00,0x60,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0xFC,0x03,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x32 +.db 0x00,0x00,0x00,0x00,0xF8,0x00,0xFC,0x03,0x04,0x03,0x00,0x03,0x80,0x01,0xF8,0x00,0xF8,0x00,0x80,0x01,0x00,0x03,0x00,0x03,0x00,0x03,0x84,0x03,0xFC,0x01,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x33 +.db 0x00,0x00,0x00,0x00,0x80,0x01,0xC0,0x01,0xE0,0x01,0xA0,0x01,0x90,0x01,0x98,0x01,0x8C,0x01,0x84,0x01,0xFE,0x07,0xFE,0x07,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x34 +.db 0x00,0x00,0x00,0x00,0xF8,0x03,0xF8,0x03,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0xF8,0x00,0xF8,0x01,0x80,0x03,0x00,0x03,0x00,0x03,0x80,0x03,0xF8,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x35 +.db 0x00,0x00,0x00,0x00,0xF0,0x00,0xF8,0x01,0x1C,0x01,0x0C,0x00,0x06,0x00,0xE6,0x00,0xF6,0x01,0x8E,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8C,0x03,0xFC,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x36 +.db 0x00,0x00,0x00,0x00,0xFC,0x07,0xFC,0x07,0x00,0x06,0x00,0x03,0x00,0x01,0x80,0x01,0xC0,0x00,0x40,0x00,0x60,0x00,0x20,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x37 +.db 0x00,0x00,0x00,0x00,0xF0,0x00,0xFC,0x01,0x8C,0x01,0x8C,0x01,0x9C,0x01,0xF8,0x00,0x70,0x00,0xEC,0x01,0x86,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x38 +.db 0x00,0x00,0x00,0x00,0x78,0x00,0xFC,0x01,0x8E,0x01,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0x7C,0x03,0x38,0x03,0x00,0x03,0x80,0x01,0xC4,0x01,0xFC,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x39 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x3A +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x60,0x00,0x20,0x00,0x30,0x00,0x00,0x00, ; 0x3B +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x07,0xC0,0x03,0xE0,0x00,0x38,0x00,0x0E,0x00,0x38,0x00,0xE0,0x00,0xC0,0x03,0x00,0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x3C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x3D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x0E,0x00,0x3C,0x00,0x70,0x00,0xC0,0x01,0x00,0x07,0xC0,0x01,0x70,0x00,0x3C,0x00,0x0E,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x3E +.db 0x00,0x00,0x00,0x00,0xFE,0x00,0xFE,0x03,0x82,0x03,0x00,0x03,0x00,0x03,0x80,0x01,0xC0,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x3F +.db 0x00,0x00,0x00,0x00,0xF0,0x01,0x18,0x03,0x0C,0x06,0xC6,0x07,0x63,0x06,0x33,0x06,0x33,0x06,0x33,0x07,0x33,0x07,0xF3,0x06,0x66,0x0E,0x06,0x00,0x0C,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x40 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0xD0,0x00,0x98,0x01,0x98,0x01,0x8C,0x03,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x41 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0xFE,0x01,0x86,0x01,0x86,0x01,0xC6,0x00,0x7E,0x00,0xFE,0x00,0x86,0x01,0x06,0x03,0x06,0x03,0x06,0x03,0xFE,0x01,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x42 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0xF8,0x07,0x1C,0x04,0x0C,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x3C,0x04,0xF8,0x07,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x43 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0xFE,0x01,0x86,0x03,0x06,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x03,0x86,0x03,0xFE,0x01,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x44 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x07,0xFC,0x07,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xFC,0x03,0xFC,0x03,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xFC,0x07,0xFC,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x45 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x07,0xFC,0x07,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xFC,0x03,0xFC,0x03,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x46 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0xF8,0x07,0x1C,0x04,0x0C,0x00,0x06,0x00,0x06,0x00,0x86,0x07,0x86,0x07,0x06,0x06,0x0C,0x06,0x1C,0x06,0xF8,0x07,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x47 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0xFE,0x03,0xFE,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x48 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0xFE,0x01,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0xFE,0x01,0xFE,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x49 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0xF8,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xC0,0x01,0xFC,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x4A +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x07,0x86,0x03,0xC6,0x01,0xE6,0x00,0x66,0x00,0x36,0x00,0x3E,0x00,0x76,0x00,0xE6,0x00,0xC6,0x01,0x86,0x03,0x06,0x07,0x06,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x4B +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xFC,0x07,0xFC,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x4C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x8F,0x07,0x8B,0x06,0x8B,0x06,0xDB,0x06,0x53,0x06,0x53,0x06,0x73,0x06,0x23,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x4D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x06,0x0E,0x06,0x1E,0x06,0x1E,0x06,0x36,0x06,0x76,0x06,0x66,0x06,0xE6,0x06,0xC6,0x06,0x86,0x07,0x86,0x07,0x06,0x07,0x06,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x4E +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0xFC,0x01,0x8E,0x03,0x07,0x07,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x07,0x07,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x4F +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x01,0xFC,0x03,0x0C,0x07,0x0C,0x06,0x0C,0x06,0x0C,0x07,0xFC,0x03,0xFC,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x50 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0xFC,0x01,0x8E,0x03,0x07,0x07,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x06,0x03,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x80,0x03,0x00,0x0F,0x00,0x04,0x00,0x00, ; 0x51 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0xFE,0x01,0x86,0x01,0x86,0x01,0x86,0x01,0xC6,0x01,0xFE,0x00,0x7E,0x00,0xE6,0x00,0xC6,0x01,0x86,0x03,0x06,0x07,0x06,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x52 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0xFC,0x01,0x06,0x01,0x06,0x00,0x0E,0x00,0x3C,0x00,0xF8,0x00,0xC0,0x03,0x00,0x03,0x00,0x03,0x86,0x03,0xFE,0x01,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x53 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x54 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x55 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0C,0x06,0x06,0x06,0x06,0x0E,0x06,0x0C,0x03,0x0C,0x03,0x1C,0x03,0x98,0x01,0xB8,0x01,0xB0,0x00,0xF0,0x00,0xF0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x56 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x03,0x0C,0x03,0x0C,0x62,0x04,0x62,0x04,0xE2,0x06,0xF6,0x06,0x96,0x06,0x96,0x06,0x96,0x03,0x9C,0x03,0x9C,0x03,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x57 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0E,0x0E,0x06,0x0C,0x03,0x98,0x01,0xF8,0x00,0xF0,0x00,0x60,0x00,0xF0,0x00,0xD8,0x01,0x98,0x01,0x0C,0x03,0x06,0x07,0x03,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x58 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0C,0x06,0x06,0x0C,0x03,0x1C,0x03,0x98,0x01,0xF0,0x00,0xF0,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x59 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0xFE,0x07,0x00,0x06,0x00,0x03,0x80,0x01,0xC0,0x00,0x60,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x5A +.db 0x00,0x00,0xF0,0x03,0xF0,0x03,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0xF0,0x03,0xF0,0x03,0x00,0x00, ; 0x5B +.db 0x00,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0xC0,0x00,0xC0,0x00,0x80,0x01,0x80,0x01,0x80,0x01,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x00, ; 0x5C +.db 0x00,0x00,0xFC,0x00,0xFC,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xFC,0x00,0xFC,0x00,0x00,0x00, ; 0x5D +.db 0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0xE0,0x00,0xA0,0x00,0xB0,0x00,0xB0,0x01,0x18,0x01,0x18,0x03,0x0C,0x03,0x0C,0x02,0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x5E +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0x00,0x00, ; 0x5F +.db 0x60,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x60 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x04,0x03,0x00,0x03,0x00,0x03,0xF8,0x03,0x0C,0x03,0x06,0x03,0x86,0x03,0xFE,0x0F,0x7C,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x61 +.db 0x00,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xE6,0x00,0xF6,0x01,0x9E,0x03,0x0E,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x01,0xFE,0x01,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x62 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0xFC,0x03,0x1C,0x02,0x0E,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x0E,0x00,0x1C,0x00,0xFC,0x03,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x63 +.db 0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x78,0x03,0xFC,0x03,0x8C,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0xFC,0x03,0x38,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x64 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0xFC,0x01,0x8C,0x03,0x06,0x03,0xFE,0x03,0xFE,0x03,0x06,0x00,0x06,0x00,0x0C,0x02,0xFC,0x03,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x65 +.db 0x00,0x00,0xE0,0x07,0xF0,0x07,0x30,0x00,0x30,0x00,0xFE,0x07,0xFE,0x07,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x66 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x03,0xFC,0x03,0x8C,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0xFC,0x03,0x78,0x03,0x00,0x03,0x84,0x03,0xFC,0x01,0xF8,0x00, ; 0x67 +.db 0x00,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xE6,0x01,0xF6,0x03,0x1E,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x68 +.db 0x00,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0xFC,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x69 +.db 0x00,0x00,0x80,0x01,0x80,0x01,0x00,0x00,0x00,0x00,0xF8,0x01,0xF8,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xC0,0x01,0xFC,0x00,0x7C,0x00, ; 0x6A +.db 0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x07,0x8C,0x03,0xCC,0x01,0xEC,0x00,0x6C,0x00,0x7C,0x00,0xEC,0x00,0xCC,0x01,0x8C,0x03,0x0C,0x07,0x0C,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x6B +.db 0x00,0x00,0xFC,0x00,0xFC,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x6C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9B,0x03,0xFF,0x07,0x77,0x06,0x33,0x06,0x33,0x06,0x33,0x06,0x33,0x06,0x33,0x06,0x33,0x06,0x33,0x06,0x33,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x6D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE6,0x01,0xF6,0x03,0x1E,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x6E +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0xFC,0x03,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0xFC,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x6F +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF6,0x00,0xFE,0x01,0x8E,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x01,0xFE,0x01,0xF6,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00, ; 0x70 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x03,0xFC,0x03,0x8C,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0x7C,0x03,0x38,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03, ; 0x71 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0x03,0xEC,0x03,0x3C,0x02,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x72 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0xFC,0x01,0x0C,0x00,0x0C,0x00,0x3C,0x00,0xF0,0x01,0x80,0x03,0x00,0x03,0x04,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x73 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0xFE,0x07,0xFE,0x07,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0xF0,0x07,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x74 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0xC6,0x03,0x7E,0x03,0x3C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x75 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x0C,0x02,0x0C,0x03,0x0C,0x03,0x18,0x01,0x98,0x01,0x98,0x01,0xB0,0x00,0xF0,0x00,0xF0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x76 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x63,0x0C,0x63,0x0C,0xE2,0x04,0xF6,0x04,0x96,0x04,0x96,0x06,0x96,0x07,0x9C,0x03,0x0C,0x03,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x77 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x07,0x0C,0x03,0x98,0x01,0xB8,0x00,0xF0,0x00,0x60,0x00,0xF0,0x00,0xD8,0x01,0x98,0x01,0x0C,0x03,0x06,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x78 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x0C,0x02,0x0C,0x03,0x1C,0x03,0x98,0x01,0x98,0x01,0xB0,0x00,0xF0,0x00,0xF0,0x00,0x60,0x00,0x60,0x00,0x20,0x00,0x30,0x00,0x3C,0x00,0x1C,0x00, ; 0x79 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x03,0xFE,0x03,0x00,0x03,0x80,0x01,0xC0,0x00,0x60,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0xFE,0x03,0xFE,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x7A +.db 0x00,0x00,0xC0,0x03,0xE0,0x03,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x3C,0x00,0x3C,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xE0,0x03,0xC0,0x03,0x00,0x00, ; 0x7B +.db 0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00, ; 0x7C +.db 0x00,0x00,0x3C,0x00,0x7C,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xC0,0x03,0xC0,0x03,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7C,0x00,0x3C,0x00,0x00,0x00, ; 0x7D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x04,0xFE,0x07,0xC2,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x7E +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x04,0x02,0x04,0x02,0x04,0x02,0x04,0x02,0x04,0x02,0x04,0x02,0x04,0x02,0x04,0x02,0x04,0x02,0x04,0x02,0x04,0x02,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x7F +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0xF8,0x07,0x1C,0x04,0x0C,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x3C,0x04,0xF8,0x07,0xE0,0x03,0x40,0x00,0xE0,0x00,0x80,0x01,0xE0,0x00, ; 0x80 +.db 0x00,0x00,0x98,0x01,0x98,0x01,0x00,0x00,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0xC6,0x03,0x7E,0x03,0x3C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x81 +.db 0x80,0x01,0xC0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0xFC,0x01,0x8C,0x03,0x06,0x03,0xFE,0x03,0xFE,0x03,0x06,0x00,0x06,0x00,0x0C,0x02,0xFC,0x03,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x82 +.db 0xE0,0x00,0xB0,0x01,0x18,0x03,0x00,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x04,0x03,0x00,0x03,0x00,0x03,0xF8,0x03,0x0C,0x03,0x06,0x03,0x86,0x03,0xFE,0x0F,0x7C,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x83 +.db 0x00,0x00,0x98,0x01,0x98,0x01,0x00,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x04,0x03,0x00,0x03,0x00,0x03,0xF8,0x03,0x0C,0x03,0x06,0x03,0x86,0x03,0xFE,0x0F,0x7C,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x84 +.db 0x18,0x00,0x30,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x04,0x03,0x00,0x03,0x00,0x03,0xF8,0x03,0x0C,0x03,0x06,0x03,0x86,0x03,0xFE,0x0F,0x7C,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x85 +.db 0x90,0x00,0x90,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x04,0x03,0x00,0x03,0x00,0x03,0xF8,0x03,0x0C,0x03,0x06,0x03,0x86,0x03,0xFE,0x0F,0x7C,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x86 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0xFC,0x03,0x1C,0x02,0x0E,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x0E,0x00,0x1C,0x00,0xFC,0x03,0xF0,0x01,0x20,0x00,0x70,0x00,0xC0,0x00,0x70,0x00, ; 0x87 +.db 0xE0,0x00,0xB0,0x01,0x18,0x03,0x00,0x00,0x00,0x00,0xF0,0x00,0xFC,0x01,0x8C,0x03,0x06,0x03,0xFE,0x03,0xFE,0x03,0x06,0x00,0x06,0x00,0x0C,0x02,0xFC,0x03,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x88 +.db 0x00,0x00,0x30,0x03,0x30,0x03,0x00,0x00,0x00,0x00,0xF0,0x00,0xFC,0x01,0x8C,0x03,0x06,0x03,0xFE,0x03,0xFE,0x03,0x06,0x00,0x06,0x00,0x0C,0x02,0xFC,0x03,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x89 +.db 0x30,0x00,0x60,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0xFC,0x01,0x8C,0x03,0x06,0x03,0xFE,0x03,0xFE,0x03,0x06,0x00,0x06,0x00,0x0C,0x02,0xFC,0x03,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x8A +.db 0x00,0x00,0x98,0x01,0x98,0x01,0x00,0x00,0x00,0x00,0xFC,0x00,0xFC,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x8B +.db 0xC0,0x01,0x60,0x03,0x30,0x06,0x00,0x00,0x00,0x00,0xFC,0x00,0xFC,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x8C +.db 0x30,0x00,0x60,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0xFC,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x8D +.db 0x8C,0x01,0x8C,0x01,0x00,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0xD0,0x00,0x98,0x01,0x98,0x01,0x8C,0x03,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x8E +.db 0x60,0x00,0x90,0x00,0xF0,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0xD0,0x00,0x98,0x01,0x98,0x01,0x8C,0x03,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x8F +.db 0xC0,0x00,0x60,0x00,0x00,0x00,0xFC,0x07,0xFC,0x07,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xFC,0x03,0xFC,0x03,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xFC,0x07,0xFC,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x90 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBE,0x03,0xFE,0x07,0xE0,0x0C,0x60,0x0C,0x60,0x0C,0xFC,0x0F,0xE6,0x0F,0x63,0x00,0x63,0x00,0xFF,0x0F,0x9E,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x91 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x0F,0xE0,0x0F,0xE0,0x00,0xF0,0x00,0xD0,0x00,0xD8,0x07,0xC8,0x07,0xCC,0x00,0xFC,0x00,0xFC,0x00,0xC6,0x00,0xC2,0x0F,0xC3,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x92 +.db 0xE0,0x00,0xB0,0x01,0x18,0x03,0x00,0x00,0x00,0x00,0xF0,0x00,0xFC,0x03,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0xFC,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x93 +.db 0x00,0x00,0x98,0x01,0x98,0x01,0x00,0x00,0x00,0x00,0xF0,0x00,0xFC,0x03,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0xFC,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x94 +.db 0x18,0x00,0x30,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0xFC,0x03,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0xFC,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x95 +.db 0xE0,0x00,0xB0,0x01,0x18,0x03,0x00,0x00,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0xC6,0x03,0x7E,0x03,0x3C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x96 +.db 0x18,0x00,0x30,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0xC6,0x03,0x7E,0x03,0x3C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x97 +.db 0x00,0x00,0x98,0x01,0x98,0x01,0x00,0x00,0x00,0x00,0x06,0x06,0x0C,0x02,0x0C,0x03,0x1C,0x03,0x98,0x01,0x98,0x01,0xB0,0x00,0xF0,0x00,0xF0,0x00,0x60,0x00,0x60,0x00,0x20,0x00,0x30,0x00,0x3C,0x00,0x1C,0x00, ; 0x98 +.db 0x8C,0x01,0x8C,0x01,0x00,0x00,0xF8,0x00,0xFC,0x01,0x8E,0x03,0x07,0x07,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x07,0x07,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x99 +.db 0x8C,0x01,0x8C,0x01,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x9A +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x06,0xFC,0x03,0x0C,0x03,0x86,0x07,0xC6,0x06,0x66,0x06,0x36,0x06,0x1E,0x06,0x0C,0x03,0xFC,0x03,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x9B +.db 0x00,0x00,0x00,0x00,0xE0,0x03,0xF0,0x03,0x30,0x00,0x30,0x00,0x30,0x00,0xFC,0x00,0xFC,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0xFC,0x03,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x9C +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x06,0xFC,0x03,0x8E,0x03,0x87,0x03,0xC3,0x06,0x43,0x06,0x23,0x06,0x13,0x06,0x1B,0x06,0x0E,0x07,0x8E,0x03,0xFE,0x01,0xFB,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x9D +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x07,0x07,0x8E,0x03,0xDC,0x01,0xF8,0x00,0x70,0x00,0xF8,0x00,0xDC,0x01,0x8E,0x03,0x07,0x07,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0x9E +.db 0xC0,0x07,0xE0,0x07,0x60,0x00,0x60,0x00,0x60,0x00,0xF8,0x03,0xF8,0x03,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7E,0x00,0x3E,0x00, ; 0x9F +.db 0x80,0x01,0xC0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x04,0x03,0x00,0x03,0x00,0x03,0xF8,0x03,0x0C,0x03,0x06,0x03,0x86,0x03,0xFE,0x0F,0x7C,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA0 +.db 0x80,0x01,0xC0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0xFC,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA1 +.db 0x80,0x01,0xC0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0xFC,0x03,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0xFC,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA2 +.db 0x80,0x01,0xC0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0xC6,0x03,0x7E,0x03,0x3C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA3 +.db 0x00,0x00,0x70,0x02,0xC8,0x01,0x00,0x00,0x00,0x00,0xE6,0x01,0xF6,0x03,0x1E,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA4 +.db 0x70,0x02,0xC8,0x01,0x00,0x00,0x0E,0x06,0x0E,0x06,0x1E,0x06,0x1E,0x06,0x36,0x06,0x76,0x06,0x66,0x06,0xE6,0x06,0xC6,0x06,0x86,0x07,0x86,0x07,0x06,0x07,0x06,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA5 +.db 0x00,0x00,0x00,0x00,0xFC,0x00,0x84,0x01,0x80,0x01,0xF8,0x01,0x8C,0x01,0x8C,0x01,0xF8,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA6 +.db 0x00,0x00,0x00,0x00,0xF0,0x00,0x98,0x01,0x0C,0x03,0x0C,0x03,0x0C,0x03,0x98,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA7 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x20,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x0E,0x02,0xFC,0x03,0xF8,0x03, ; 0xA8 +.db 0x00,0x00,0x00,0x00,0xF8,0x00,0x8C,0x01,0x76,0x03,0x52,0x02,0x72,0x02,0x32,0x02,0x56,0x03,0x8C,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xA9 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0xFF,0x07,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAA +.db 0x00,0x00,0x00,0x00,0x07,0x03,0x86,0x01,0x86,0x01,0xC6,0x00,0x66,0x00,0x66,0x00,0xB6,0x07,0x30,0x0C,0x18,0x0C,0x18,0x0C,0x0C,0x06,0x06,0x03,0x86,0x01,0x83,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAB +.db 0x00,0x00,0x00,0x00,0x07,0x03,0x86,0x01,0x86,0x01,0xC6,0x00,0x66,0x00,0x66,0x00,0x36,0x06,0x30,0x07,0x98,0x06,0x58,0x06,0x2C,0x06,0xE6,0x0F,0x06,0x06,0x03,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAC +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xAD +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x06,0x18,0x03,0x8C,0x01,0xC6,0x00,0x63,0x00,0xC6,0x00,0x8C,0x01,0x18,0x03,0x30,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAE +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0xC6,0x00,0x8C,0x01,0x18,0x03,0x30,0x06,0x18,0x03,0x8C,0x01,0xC6,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xAF +.db 0x33,0x03,0x33,0x03,0x00,0x00,0x00,0x00,0x33,0x03,0x33,0x03,0x00,0x00,0x00,0x00,0x33,0x03,0x33,0x03,0x00,0x00,0x00,0x00,0x33,0x03,0x33,0x03,0x00,0x00,0x00,0x00,0x33,0x03,0x33,0x03,0x00,0x00,0x00,0x00, ; 0xB0 +.db 0xCC,0x0C,0xCC,0x0C,0x33,0x03,0x33,0x03,0xCC,0x0C,0xCC,0x0C,0x33,0x03,0x33,0x03,0xCC,0x0C,0xCC,0x0C,0x33,0x03,0x33,0x03,0xCC,0x0C,0xCC,0x0C,0x33,0x03,0x33,0x03,0xCC,0x0C,0xCC,0x0C,0x33,0x03,0x33,0x03, ; 0xB1 +.db 0xFF,0x0F,0xFF,0x0F,0x33,0x03,0x33,0x03,0xFF,0x0F,0xFF,0x0F,0x33,0x03,0x33,0x03,0xFF,0x0F,0xFF,0x0F,0x33,0x03,0x33,0x03,0xFF,0x0F,0xFF,0x0F,0x33,0x03,0x33,0x03,0xFF,0x0F,0xFF,0x0F,0x33,0x03,0x33,0x03, ; 0xB2 +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xB3 +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xB4 +.db 0xC0,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0xD0,0x00,0x98,0x01,0x98,0x01,0x8C,0x03,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xB5 +.db 0x70,0x00,0x88,0x00,0x00,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0xD0,0x00,0x98,0x01,0x98,0x01,0x8C,0x03,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xB6 +.db 0x30,0x00,0x60,0x00,0x00,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0xD0,0x00,0x98,0x01,0x98,0x01,0x8C,0x03,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xB7 +.db 0x00,0x00,0x00,0x00,0xF8,0x00,0x04,0x01,0x02,0x02,0xF3,0x06,0x09,0x04,0x05,0x04,0x05,0x04,0x05,0x04,0x05,0x04,0x09,0x04,0xF3,0x06,0x02,0x02,0x04,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xB8 +.db 0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xBF,0x01,0xBF,0x01,0x80,0x01,0xBF,0x01,0xBF,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01, ; 0xB9 +.db 0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01, ; 0xBA +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0xFF,0x01,0x80,0x01,0xBF,0x01,0xBF,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01, ; 0xBB +.db 0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xBF,0x01,0xBF,0x01,0x80,0x01,0xFF,0x01,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xBC +.db 0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0xF0,0x03,0xF8,0x03,0x5C,0x02,0x4C,0x00,0x4C,0x00,0x4C,0x00,0x4C,0x00,0x5C,0x00,0xF8,0x03,0xF0,0x01,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xBD +.db 0x00,0x00,0x00,0x00,0x07,0x0C,0x0E,0x06,0x0C,0x03,0x1C,0x03,0xB8,0x01,0xF0,0x00,0x60,0x00,0xFC,0x03,0x60,0x00,0x60,0x00,0xFC,0x03,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xBE +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xBF +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xE0,0x0F,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC0 +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC1 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xC2 +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xE0,0x0F,0xE0,0x0F,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xC3 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC4 +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFF,0x0F,0xFF,0x0F,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xC5 +.db 0x00,0x00,0x70,0x02,0xC8,0x01,0x00,0x00,0x00,0x00,0xF8,0x01,0xFC,0x03,0x04,0x03,0x00,0x03,0x00,0x03,0xF8,0x03,0x0C,0x03,0x06,0x03,0x86,0x03,0xFE,0x0F,0x7C,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC6 +.db 0x70,0x02,0xC8,0x01,0x00,0x00,0x60,0x00,0xF0,0x00,0xF0,0x00,0xD0,0x00,0x98,0x01,0x98,0x01,0x8C,0x03,0x0C,0x03,0xFC,0x03,0xFE,0x07,0x06,0x06,0x06,0x06,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC7 +.db 0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x0F,0xB0,0x0F,0x30,0x00,0xF0,0x0F,0xF0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xC8 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x0F,0xF0,0x0F,0x30,0x00,0xB0,0x0F,0xB0,0x0F,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01, ; 0xC9 +.db 0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xBF,0x0F,0xBF,0x0F,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xCA +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0xBF,0x0F,0xBF,0x0F,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01, ; 0xCB +.db 0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x0F,0xB0,0x0F,0x30,0x00,0xB0,0x0F,0xB0,0x0F,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01, ; 0xCC +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xCD +.db 0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xBF,0x0F,0xBF,0x0F,0x00,0x00,0xBF,0x0F,0xBF,0x0F,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01,0xB0,0x01, ; 0xCE +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0xF4,0x02,0xFC,0x03,0x9C,0x03,0x0C,0x03,0x0C,0x03,0x9C,0x03,0xFC,0x03,0xF4,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xCF +.db 0x00,0x00,0xDE,0x00,0x7E,0x00,0xF0,0x00,0xC8,0x01,0xF0,0x03,0xFC,0x03,0x0C,0x07,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0xFC,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD0 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0xFE,0x01,0x86,0x03,0x06,0x07,0x06,0x06,0x1F,0x06,0x1F,0x06,0x06,0x06,0x06,0x06,0x06,0x03,0x86,0x03,0xFE,0x01,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD1 +.db 0xE0,0x00,0x10,0x01,0x00,0x00,0xFC,0x07,0xFC,0x07,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xFC,0x03,0xFC,0x03,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xFC,0x07,0xFC,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD2 +.db 0x18,0x03,0x18,0x03,0x00,0x00,0xFC,0x07,0xFC,0x07,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xFC,0x03,0xFC,0x03,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xFC,0x07,0xFC,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD3 +.db 0x60,0x00,0xC0,0x00,0x00,0x00,0xFC,0x07,0xFC,0x07,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xFC,0x03,0xFC,0x03,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0xFC,0x07,0xFC,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD4 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0xFC,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD5 +.db 0xC0,0x00,0x60,0x00,0x00,0x00,0xFE,0x01,0xFE,0x01,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0xFE,0x01,0xFE,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD6 +.db 0x70,0x00,0x88,0x00,0x00,0x00,0xFE,0x01,0xFE,0x01,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0xFE,0x01,0xFE,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD7 +.db 0x8C,0x01,0x8C,0x01,0x00,0x00,0xFE,0x01,0xFE,0x01,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0xFE,0x01,0xFE,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD8 +.db 0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xD9 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0xE0,0x0F,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00, ; 0xDA +.db 0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F, ; 0xDB +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F, ; 0xDC +.db 0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00, ; 0xDD +.db 0x30,0x00,0x60,0x00,0x00,0x00,0xFE,0x01,0xFE,0x01,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0xFE,0x01,0xFE,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xDE +.db 0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xDF +.db 0xC0,0x00,0x60,0x00,0x00,0x00,0xF8,0x00,0xFC,0x01,0x8E,0x03,0x07,0x07,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x07,0x07,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE0 +.db 0x00,0x00,0xFC,0x00,0xFE,0x01,0x86,0x01,0x86,0x01,0xC6,0x00,0xC6,0x00,0x66,0x00,0xE6,0x00,0xC6,0x01,0x86,0x03,0x06,0x07,0x06,0x06,0x26,0x06,0xE6,0x07,0xC6,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE1 +.db 0x70,0x00,0x88,0x00,0x00,0x00,0xF8,0x00,0xFC,0x01,0x8E,0x03,0x07,0x07,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x07,0x07,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE2 +.db 0x30,0x00,0x60,0x00,0x00,0x00,0xF8,0x00,0xFC,0x01,0x8E,0x03,0x07,0x07,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x07,0x07,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE3 +.db 0x00,0x00,0x70,0x02,0xC8,0x01,0x00,0x00,0x00,0x00,0xF0,0x00,0xFC,0x03,0x0C,0x03,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x03,0xFC,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE4 +.db 0x70,0x02,0xC8,0x01,0x00,0x00,0xF8,0x00,0xFC,0x01,0x8E,0x03,0x07,0x07,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x07,0x07,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE5 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0xFE,0x03,0x76,0x03,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00, ; 0xE6 +.db 0x00,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xE6,0x00,0xF6,0x01,0x8E,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x01,0xFE,0x01,0xF6,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00, ; 0xE7 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xFE,0x00,0xFE,0x01,0x86,0x03,0x06,0x03,0x06,0x03,0x86,0x03,0xFE,0x01,0x7E,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE8 +.db 0xC0,0x00,0x60,0x00,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xE9 +.db 0x70,0x00,0x88,0x00,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xEA +.db 0x30,0x00,0x60,0x00,0x00,0x00,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x06,0x03,0x8E,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xEB +.db 0x80,0x01,0xC0,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x0C,0x02,0x0C,0x03,0x1C,0x03,0x98,0x01,0x98,0x01,0xB0,0x00,0xF0,0x00,0xF0,0x00,0x60,0x00,0x60,0x00,0x20,0x00,0x30,0x00,0x3C,0x00,0x1C,0x00, ; 0xEC +.db 0xC0,0x00,0x60,0x00,0x00,0x00,0x07,0x0C,0x06,0x06,0x0C,0x03,0x1C,0x03,0x98,0x01,0xF0,0x00,0xF0,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xED +.db 0xFF,0x0F,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xEE +.db 0x60,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xEF +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF0 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xFE,0x07,0xFE,0x07,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF1 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0x00,0x00,0xFF,0x0F,0x00,0x00, ; 0xF2 +.db 0x00,0x00,0x00,0x00,0x0F,0x0C,0x18,0x06,0x18,0x03,0x86,0x03,0x98,0x01,0xD8,0x00,0x6F,0x07,0x60,0x07,0xB0,0x06,0x58,0x06,0x3C,0x06,0xEC,0x0F,0x06,0x06,0x03,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF3 +.db 0x00,0x00,0x00,0x00,0xFC,0x03,0x3E,0x02,0x3E,0x02,0x3E,0x02,0x3E,0x02,0x3C,0x02,0x38,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x00,0x00, ; 0xF4 +.db 0x00,0x00,0x00,0x00,0xF0,0x01,0xF8,0x01,0x0C,0x00,0x0C,0x00,0x1C,0x00,0xF0,0x00,0xC8,0x01,0x8C,0x03,0x0C,0x03,0x1C,0x03,0xF8,0x01,0xE0,0x01,0x80,0x03,0x00,0x03,0x04,0x03,0xFC,0x01,0xF8,0x00,0x00,0x00, ; 0xF5 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF6 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x70,0x00,0xC0,0x00,0x70,0x00, ; 0xF7 +.db 0x00,0x00,0x00,0x00,0x30,0x00,0x48,0x00,0x48,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF8 +.db 0x8C,0x01,0x8C,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xF9 +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFA +.db 0x00,0x00,0x00,0x00,0x78,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFB +.db 0x00,0x00,0x00,0x00,0xF8,0x00,0x88,0x01,0x80,0x01,0xF0,0x00,0x80,0x01,0x80,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFC +.db 0x00,0x00,0x00,0x00,0xF8,0x01,0x00,0x03,0x00,0x03,0x80,0x01,0x60,0x00,0x18,0x00,0xF8,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFD +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0xFE,0x07,0xFE,0x07,0xFE,0x07,0xFE,0x07,0xFE,0x07,0xFE,0x07,0xFE,0x07,0xFE,0x07,0xFE,0x07,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ; 0xFE +.db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ; 0xFF + diff --git a/avr/modules/lcd2/font/font6x8.asm b/avr/modules/lcd2/font/font6x8.asm index 50b5696..124d44a 100644 --- a/avr/modules/lcd2/font/font6x8.asm +++ b/avr/modules/lcd2/font/font6x8.asm @@ -15,6 +15,19 @@ +; --------------------------------------------------------------------------- +; @routine font6x8MonoHandlerFn +; +; Handler for 6x8 Mono Fonts +; + +font6x8MonoHandlerFn: + cpi r23, FONT_FN_RENDER + breq font6x8MonoRenderCharacter + rjmp FONT_GenericHandler +; @end + + ; --------------------------------------------------------------------------- ; @routine font6x8RenderCharacter diff --git a/avr/modules/lcd2/font/font8x8.asm b/avr/modules/lcd2/font/font8x8.asm index f33a2dc..2f2d40a 100644 --- a/avr/modules/lcd2/font/font8x8.asm +++ b/avr/modules/lcd2/font/font8x8.asm @@ -15,6 +15,20 @@ +; --------------------------------------------------------------------------- +; @routine font8x8MonoHandlerFn +; +; Handler for 8x8 Mono Fonts +; + +font8x8MonoHandlerFn: + cpi r23, FONT_FN_RENDER + breq font8x8MonoRenderCharacter + rjmp FONT_GenericHandler +; @end + + + ; --------------------------------------------------------------------------- ; @routine font8x8RenderCharacter diff --git a/avr/modules/lcd2/font/main.asm b/avr/modules/lcd2/font/main.asm new file mode 100644 index 0000000..d86a602 --- /dev/null +++ b/avr/modules/lcd2/font/main.asm @@ -0,0 +1,167 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +; *************************************************************************** +; code + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine FONT_RenderChar + +; @param R16 character to write +; @param R1:R0 background color +; @param R3:R2 foreground color +; @param Z pointer to font +; @param X pointer to RAM to store data to +; @param r18 char width in pixel +; @param r19 char height in pixel +; @clobbers any, !Z + +FONT_RenderChar: + ldi r23, FONT_FN_RENDER + rjmp fontCallHandler +; @end + + + + +; --------------------------------------------------------------------------- +; @routine FONT_GetCharWidth + +; @param Z pointer to font +; @return R16 character width for given character set +; @clobbers any, !Z + +FONT_GetCharWidth: + ldi r23, FONT_FN_GETCHARWIDTH + rjmp fontCallHandler +; @end + + + +; --------------------------------------------------------------------------- +; @routine FONT_GetCharHeight + +; @param Z pointer to font +; @return R16 character height for given character set +; @clobbers any, !Z + +FONT_GetCharHeight: + ldi r23, FONT_FN_GETCHARHEIGHT + rjmp fontCallHandler +; @end + + + +; --------------------------------------------------------------------------- +; @routine FONT_GetStringWidth + +; @param Z pointer to font +; @param X pointer to null-terminated string in flash +; @return R16 character width for given character set +; @clobbers any, !Z + +FONT_GetStringWidthFlash: + ldi r23, FONT_FN_GETSTRINGWIDTH + rjmp fontCallHandler +; @end + + + +; --------------------------------------------------------------------------- +; @routine FONT_GetStringHeight + +; @param Z pointer to font +; @param X pointer to null-terminated string in flash +; @return R16 character width for given character set +; @clobbers any, !Z + +FONT_GetStringHeight: + ldi r23, FONT_FN_GETSTRINGHEIGHT + rjmp fontCallHandler +; @end + + + + + +; --------------------------------------------------------------------------- +; @routine fontCallHandler +; +; @param r23 function number +; @param Z pointer to font + +fontCallHandler: + lpm r17, Z+ + push r17 + lpm r17, Z + push r17 + sbiw zh:zl, 1 + ret +; @end + + + + +; --------------------------------------------------------------------------- +; @routine FONT_GenericHandler +; +; Generic handler for font functions. +; @param R23 function to call (see @ref FONT_FN_RENDER et al) + +FONT_GenericHandler: + cpi r23, FONT_FN_GETCHARWIDTH + breq fontGenericFnGetCharWidth + cpi r23, FONT_FN_GETCHARHEIGHT + breq fontGenericFnGetCharHeight + cpi r23, FONT_FN_GETSTRINGWIDTH + breq fontGenericFnGetStringWidth + cpi r23, FONT_FN_GETSTRINGHEIGHT + breq fontGenericFnGetStringHeight + ret +fontGenericFnGetCharWidth: + adiw zh:zl, FONT_OFFS_WIDTH + ld r16, X + sbiw zh:zl, FONT_OFFS_WIDTH + ret +fontGenericFnGetCharHeight: + adiw zh:zl, FONT_OFFS_HEIGHT + ld r16, X + sbiw zh:zl, FONT_OFFS_HEIGHT + ret +fontGenericFnGetStringWidth: + adiw zh:zl, FONT_OFFS_WIDTH + ld r17, X + sbiw zh:zl, FONT_OFFS_WIDTH + clr r16 + push zl + push zh + mov zl, xl + mov zh, xh +fontGenericFnGetStringWidth_loop: + lpm r18, Z+ + tst r18 + breq fontGenericFnGetStringWidth_loopEnd + add r16, r17 + rjmp fontGenericFnGetStringWidth_loop +fontGenericFnGetStringWidth_loopEnd: + pop zh + pop zl + ret +fontGenericFnGetStringHeight: + rjmp fontGenericFnGetCharHeight ; for now monospace fonts only +; @end + + + diff --git a/avr/modules/lcd2/gui/TODO b/avr/modules/lcd2/gui/TODO new file mode 100644 index 0000000..898a149 --- /dev/null +++ b/avr/modules/lcd2/gui/TODO @@ -0,0 +1,13 @@ + + +- Screen + - functions: + - show + - unshow + - touch + - key + - activeAreas: + - x, y, w, h (in FLASH) + - only small variable data in SRAM, no need for heap! + + diff --git a/avr/modules/lcd2/gui/defs.asm b/avr/modules/lcd2/gui/defs.asm new file mode 100644 index 0000000..a73cf3a --- /dev/null +++ b/avr/modules/lcd2/gui/defs.asm @@ -0,0 +1,37 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AQH_AVR_GUI_H +#define AQH_AVR_GUI_H + + + +.equ SCR_OFFS_HANDLER_LO = 0 +.equ SCR_OFFS_HANDLER_HI = 1 +.equ SCR_OFFS_X_LO = 2 +.equ SCR_OFFS_X_HI = 3 +.equ SCR_OFFS_Y_LO = 4 +.equ SCR_OFFS_Y_HI = 5 +.equ SCR_OFFS_WIDTH_LO = 6 +.equ SCR_OFFS_WIDTH_HI = 7 +.equ SCR_OFFS_HEIGHT_LO = 8 +.equ SCR_OFFS_HEIGHT_HI = 9 +.equ SCR_OFFS_BG_COL_LO = 10 +.equ SCR_OFFS_BG_COL_HI = 11 +.equ SCR_OFFS_FG_COL_LO = 12 +.equ SCR_OFFS_FG_COL_HI = 13 +.equ SCR_OFFS_FONT_LO = 14 +.equ SCR_OFFS_FONT_HI = 15 +.equ SCR_SIZE = 16 + + + + +#endif + diff --git a/avr/modules/lcd2/ili9341/main.asm b/avr/modules/lcd2/ili9341/main.asm index bbd6fb5..f86b984 100644 --- a/avr/modules/lcd2/ili9341/main.asm +++ b/avr/modules/lcd2/ili9341/main.asm @@ -21,7 +21,7 @@ .dseg -ILI9341_buffer: .byte 128 +;ILI9341_buffer: .byte 128 ; *************************************************************************** @@ -36,102 +36,12 @@ ILI9341_buffer: .byte 128 ILI9341_Init: rcall ILI9341IoInit - rcall ILI9341_Reset - rcall ILI9341_LeaveSleepMode ldi r16, 0xff rcall ILI9341_SetBacklight - - ldi r16, 0xff - mov r3, r16 - ldi r16, 0xff - mov r2, r16 - rcall ili9341Test5 - -; 0bRRRRRGGGGGGBBBBB - - ldi r16, 0b11111000 ; red - mov r3, r16 - ldi r16, 0b00000000 ; red - mov r2, r16 - rcall ili9341Test2 - -; 0bRRRRRGGGGGGBBBBB - ldi r16, 0b00000000 - mov r3, r16 - ldi r16, 0b00011111 ; blue - mov r2, r16 - rcall ili9341Test3 - -; 0bRRRRRGGGGGGBBBBB - ldi r16, 0b00000111 ; green - mov r3, r16 - ldi r16, 0b11100000 ; green - mov r2, r16 - rcall ili9341Test4 - -; set foreground color - ldi r16, 0b11100000 ; green - mov r2, r16 - ldi r16, 0b00000111 ; green - mov r3, r16 - -; set background color - ldi r16, 0b11111111 ; white - mov r0, r16 - mov r1, r16 - -#if 0 -; set Xpos - ldi r16, LOW(100) - mov r4, r16 - ldi r16, HIGH(100) - mov r5, r16 - -; setYpos - ldi r16, LOW(150) - mov r6, r16 - ldi r16, HIGH(150) - mov r7, r16 - -; set font pos - ldi zl, LOW(font2_6x8*2) - ldi zh, HIGH(font2_6x8*2) - -; set buffer pos -; ldi xl, LOW(ILI9341_buffer) -; ldi xh, HIGH(ILI9341_buffer) - ldi xl, LOW(0x260) - ldi xh, HIGH(0x260) - -; set foreground color - ldi r16, 0b00000000 ; black - mov r2, r16 - mov r3, r16 - -; set character - ldi r16, 'A' - rcall ili9341_WriteCharacterX4At - - ldi r16, 'Q' - rcall ili9341_WriteCharacterX4At - - ldi r16, 'H' - rcall ili9341_WriteCharacterX4At - - ldi r16, 'O' - rcall ili9341_WriteCharacterX4At - - ldi r16, 'M' - rcall ili9341_WriteCharacterX4At - - ldi r16, 'E' - rcall ili9341_WriteCharacterX4At -#endif - sec ret ; @end @@ -269,108 +179,6 @@ ILI9341_LeaveSleepMode: -; --------------------------------------------------------------------------- -; @routine ILI9341_FillScreen -; -; @param r17:r16 color - -ILI9341_FillScreen: -; TODO - ret -; @end - - - - - - - - - - - - - - - - - - -ili9341Test1: - rcall ili9341BeginSpi - ldi r16, 0x04 - cbi ILI9341_DC_OUTPUT, ILI9341_DC_PIN ; D low (send command) - rcall SPIHW_MasterTransfer ; (R16) - sbi ILI9341_DC_OUTPUT, ILI9341_DC_PIN ; D high (send data) - clr r16 - ; read byte 1 - rcall SPIHW_MasterTransfer ; (R16) - ; read byte 2 - rcall SPIHW_MasterTransfer ; (R16) - ; read byte 3 - rcall SPIHW_MasterTransfer ; (R16) - ; read byte 4 - rcall SPIHW_MasterTransfer ; (R16) - rcall ili9341EndSpi ; (R16) - ret - - - -; @param %0 X -; @param %1 Y -; @param %2 W -; @param %3 H -.macro M_ILI9341_FILL_RECT - ldi r16, LOW(@0) ; X0 - mov r4, r16 - ldi r16, HIGH(@0) - mov r5, r16 - - ldi r16, LOW(@1) ; Y0 - mov r6, r16 - ldi r16, HIGH(@1) - mov r7, r16 - - ldi r16, LOW(@2) ; W - mov r8, r16 - ldi r16, HIGH(@2) - mov r9, r16 - - ldi r16, LOW(@3) ; H - mov r10, r16 - ldi r16, HIGH(@3) - mov r11, r16 - - rcall ILI9341_FillRect -.endmacro - - - -ili9341Test2: - M_ILI9341_FILL_RECT 10, 20, 70, 100 - ret - - - -ili9341Test3: - M_ILI9341_FILL_RECT 90, 40, 70, 100 - ret - - - -ili9341Test4: - M_ILI9341_FILL_RECT 40, 30, 70, 100 - ret - - - -ili9341Test5: - M_ILI9341_FILL_RECT 0, 0, 319, 239 - ret - - - - ili9341InitCommands: ; display off .db 0x28, 0 @@ -421,10 +229,3 @@ ili9341InitCommands: .db 0xff, 0xff -helloWorld: .db "Hello World", 0 - - - -.include "modules/lcd2/font/font2.asm" - - diff --git a/avr/modules/lcd2/ili9341/text.asm b/avr/modules/lcd2/ili9341/text.asm index 5345247..389746b 100644 --- a/avr/modules/lcd2/ili9341/text.asm +++ b/avr/modules/lcd2/ili9341/text.asm @@ -29,11 +29,15 @@ ; @clobbers r16 (r17, r20, r21, r22, r23, r24, r25, X) ili9341_WriteCharacterX1At: - rcall ili9341FontRenderChar ; (r16, r17, r24, r25, z) - rcall ili9341BitBlit ; (r16, r17, r20, r21, r22, r23, r24, r25, X) - ; advance X (add char width to X) - add r4, r8 - adc r5, r9 + push xl + push xh + rcall ili9341FontRenderChar ; (r16, r17, r24, r25, z) + rcall ili9341BitBlit ; (r16, r17, r20, r21, r22, r23, r24, r25, X) + ; advance X (add char width to X) + add r4, r8 + adc r5, r9 + pop xh + pop xl ret ; @end @@ -54,7 +58,7 @@ ili9341_WriteCharacterX1At: ; @clobbers r16 (r17, r18, r19, r20, r21, r22, r23, r24, r25, X) ili9341_WriteCharacterX2At: - rcall ili9341FontRenderChar ; (r16, r17, r24, r25, z) + rcall ili9341FontRenderChar ; (r16, r17, r24, r25, z) rcall ili9341BitBlitStretch2 ; (r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, X) ; advance X (add double char width to X) lsl r8 ; Wx2 @@ -110,8 +114,7 @@ ili9341FontRenderChar: ; render character push xl push xh - ; call render function of the selected font (first word of font is jmp to render function) - rcall ili9341JumpToFontRenderFn ; (r17, r24, r25, x, z) + rcall FONT_RenderChar pop xh pop xl @@ -125,24 +128,6 @@ ili9341FontRenderChar: -; --------------------------------------------------------------------------- -; @routine ili9341JumpToFontRenderFn -; -; helper function to call function at the beginning of the given font -; @clobbers r17 - -ili9341JumpToFontRenderFn: - lpm r17, Z+ - push r17 - lpm r17, Z - push r17 - sbiw zh:zl, 1 - ret -; @end - - - - ; --------------------------------------------------------------------------- ; @routine textNibbleToAscii ; @@ -165,7 +150,7 @@ textNibbleToAscii_l1: - +#if 0 ; --------------------------------------------------------------------------- ; @routine ili9341_WriteCharacterX4At @@ -268,6 +253,7 @@ Debug_WriteHexBuffer_loop: brne Debug_WriteHexBuffer_loop ret +#endif diff --git a/avr/modules/lcd2/win/defs.asm b/avr/modules/lcd2/win/defs.asm index 50b50ef..86e4ebf 100644 --- a/avr/modules/lcd2/win/defs.asm +++ b/avr/modules/lcd2/win/defs.asm @@ -29,57 +29,72 @@ .equ WID_OFFS_WIDGET = OBJ_OFFS_SIZE .equ WID_OFFS_OPTIONS1 = WID_OFFS_WIDGET+0 .equ WID_OFFS_OPTIONS2 = WID_OFFS_WIDGET+1 -.equ WID_OFFS_ABS_X = WID_OFFS_WIDGET+2 -.equ WID_OFFS_ABS_Y = WID_OFFS_WIDGET+3 -.equ WID_OFFS_REL_X = WID_OFFS_WIDGET+4 -.equ WID_OFFS_REL_Y = WID_OFFS_WIDGET+5 -.equ WID_OFFS_WIDTH = WID_OFFS_WIDGET+6 -.equ WID_OFFS_HEIGHT = WID_OFFS_WIDGET+7 -.equ WID_OFFS_BG_COL_LO = WID_OFFS_WIDGET+8 -.equ WID_OFFS_BG_COL_HI = WID_OFFS_WIDGET+9 -.equ WID_OFFS_FG_COL_LO = WID_OFFS_WIDGET+10 -.equ WID_OFFS_FG_COL_HI = WID_OFFS_WIDGET+11 -.equ WID_OFFS_FONT_LO = WID_OFFS_WIDGET+12 -.equ WID_OFFS_FONT_HI = WID_OFFS_WIDGET+13 -.equ WID_OFFS_BORDER_TOP = WID_OFFS_WIDGET+14 -.equ WID_OFFS_BORDER_BOT = WID_OFFS_WIDGET+15 -.equ WID_OFFS_BORDER_LEFT = WID_OFFS_WIDGET+16 -.equ WID_OFFS_BORDER_RIGHT = WID_OFFS_WIDGET+17 +.equ WID_OFFS_ABS_X_LO = WID_OFFS_WIDGET+2 +.equ WID_OFFS_ABS_X_HI = WID_OFFS_WIDGET+3 +.equ WID_OFFS_ABS_Y_LO = WID_OFFS_WIDGET+4 +.equ WID_OFFS_ABS_Y_HI = WID_OFFS_WIDGET+5 +.equ WID_OFFS_REL_X_LO = WID_OFFS_WIDGET+6 +.equ WID_OFFS_REL_X_HI = WID_OFFS_WIDGET+7 +.equ WID_OFFS_REL_Y_LO = WID_OFFS_WIDGET+8 +.equ WID_OFFS_REL_Y_HI = WID_OFFS_WIDGET+9 +.equ WID_OFFS_WIDTH_LO = WID_OFFS_WIDGET+10 +.equ WID_OFFS_WIDTH_HI = WID_OFFS_WIDGET+11 +.equ WID_OFFS_HEIGHT_LO = WID_OFFS_WIDGET+12 +.equ WID_OFFS_HEIGHT_HI = WID_OFFS_WIDGET+13 +.equ WID_OFFS_BG_COL_LO = WID_OFFS_WIDGET+14 +.equ WID_OFFS_BG_COL_HI = WID_OFFS_WIDGET+15 +.equ WID_OFFS_FG_COL_LO = WID_OFFS_WIDGET+16 +.equ WID_OFFS_FG_COL_HI = WID_OFFS_WIDGET+17 +.equ WID_OFFS_FONT_LO = WID_OFFS_WIDGET+18 +.equ WID_OFFS_FONT_HI = WID_OFFS_WIDGET+19 +.equ WID_OFFS_BORDER_TOP = WID_OFFS_WIDGET+20 +.equ WID_OFFS_BORDER_BOT = WID_OFFS_WIDGET+21 +.equ WID_OFFS_BORDER_LEFT = WID_OFFS_WIDGET+22 +.equ WID_OFFS_BORDER_RIGHT = WID_OFFS_WIDGET+23 -.equ WID_SIZE = WID_OFFS_WIDGET+18 +.equ WID_SIZE = WID_OFFS_WIDGET+24 -.equ WID_OPTIONS1_BIT_DIRTY = 0 -.equ WID_OPTIONS1_BIT_LAYOUT = 1 +.equ WID_OPTIONS0_BIT_VISIBLE = 0 ; OBJ_OFFS_OPTIONS +.equ WID_OPTIONS0_BIT_DIRTY = 1 +.equ WID_OPTIONS0_BIT_LAYOUT = 2 -.equ WID_OPTIONS1_BIT_STRETCH_X = 2 -.equ WID_OPTIONS1_BIT_STRETCH_Y = 3 +.equ WID_OPTIONS1_BIT_STRETCH_X = 0 ; WID_OFFS_OPTIONS1 +.equ WID_OPTIONS1_BIT_STRETCH_Y = 1 -.equ WID_OPTIONS1_BIT_ALIGN_RIGHT = 4 -.equ WID_OPTIONS1_BIT_ALIGN_BOTTOM = 5 +.equ WID_OPTIONS1_BIT_HALIGN0 = 2 ; 00: left, 01: right, 11: center +.equ WID_OPTIONS1_BIT_HALIGN1 = 3 -.equ WID_OPTIONS1_BIT_EQUAL_WIDTH = 6 -.equ WID_OPTIONS1_BIT_EQUAL_HEIGHT = 7 +.equ WID_OPTIONS1_BIT_VALIGN0 = 4 ; 00: top, 01: bottom, 11: center +.equ WID_OPTIONS1_BIT_VALIGN1 = 5 + +.equ WID_OPTIONS1_BIT_FIXED_WIDTH = 6 +.equ WID_OPTIONS1_BIT_FIXED_HEIGHT = 7 + + +.equ WID_OPTIONS2_BIT_EQUAL_WIDTH = 0 +.equ WID_OPTIONS2_BIT_EQUAL_HEIGHT = 1 ; Signals -.equ OBJ_SIGNAL_CREATED = 0 -.equ OBJ_SIGNAL_DESTROY = 1 -.equ OBJ_SIGNAL_GETVALUE = 2 -.equ OBJ_SIGNAL_SETVALUE = 3 -.equ OBJ_SIGNAL_TIMER = 4 -.equ OBJ_SIGNAL_NEXTFREE = 5 +.equ OBJ_SIGNAL_DESTROY = 0 +.equ OBJ_SIGNAL_GETVALUE = 1 +.equ OBJ_SIGNAL_SETVALUE = 2 +.equ OBJ_SIGNAL_TIMER = 3 +.equ OBJ_SIGNAL_NEXTFREE = 4 -.equ WID_SIGNAL_SHOW = OBJ_SIGNAL_NEXTFREE -.equ WID_SIGNAL_HIDE = OBJ_SIGNAL_NEXTFREE+1 -.equ WID_SIGNAL_UPDATE = OBJ_SIGNAL_NEXTFREE+2 -.equ WID_SIGNAL_LAYOUT = OBJ_SIGNAL_NEXTFREE+3 -.equ WID_SIGNAL_TOUCH = OBJ_SIGNAL_NEXTFREE+4 -.equ WID_SIGNAL_MOUSE = OBJ_SIGNAL_NEXTFREE+5 -.equ WID_SIGNAL_KEY = OBJ_SIGNAL_NEXTFREE+6 -.equ WID_SIGNAL_NEXTFREE = OBJ_SIGNAL_NEXTFREE+7 +.equ WID_SIGNAL_SHOW = OBJ_SIGNAL_NEXTFREE +.equ WID_SIGNAL_HIDE = OBJ_SIGNAL_NEXTFREE+1 +.equ WID_SIGNAL_DRAW = OBJ_SIGNAL_NEXTFREE+2 +.equ WID_SIGNAL_LAYOUT = OBJ_SIGNAL_NEXTFREE+3 +.equ WID_SIGNAL_TOUCH = OBJ_SIGNAL_NEXTFREE+4 +.equ WID_SIGNAL_MOUSE = OBJ_SIGNAL_NEXTFREE+5 +.equ WID_SIGNAL_KEY = OBJ_SIGNAL_NEXTFREE+6 +.equ WID_SIGNAL_GETMINWIDTH = OBJ_SIGNAL_NEXTFREE+7 +.equ WID_SIGNAL_GETMINHEIGHT = OBJ_SIGNAL_NEXTFREE+8 +.equ WID_SIGNAL_NEXTFREE = OBJ_SIGNAL_NEXTFREE+9 @@ -92,20 +107,21 @@ .equ OBJ_LINK_OFFS_TARGET_HI = LIST_SIZE+3 .equ OBJ_LINK_SIZE = LIST_SIZE+4 ; fns: -; - removeLinksTo() -; - addLink() -; - removeLinks() +; - removeLinksTo(Y=win, r19:r18=target) +; - addLink(Y=win, r16=signal, r17=slot, r19:r18=target) +; - removeLinks(Y=win) .equ TIMER_OFFS_LIST = 0 .equ TIMER_OFFS_TIMER = LIST_SIZE .equ TIMER_OFFS_VALUE_LO = TIMER_OFFS_TIMER -.equ TIMER_OFFS_VALUE_LO = TIMER_OFFS_TIMER+1 +.equ TIMER_OFFS_VALUE_HI = TIMER_OFFS_TIMER+1 .equ TIMER_OFFS_RELOAD_LO = TIMER_OFFS_TIMER+2 .equ TIMER_OFFS_RELOAD_HI = TIMER_OFFS_TIMER+3 .equ TIMER_OFFS_OPTIONS = TIMER_OFFS_TIMER+4 -.equ TIMER_SIZE = TIMER_OFFS_TIMER+5 +.equ TIMER_OFFS_SIGNAL = TIMER_OFFS_TIMER+5 +.equ TIMER_SIZE = TIMER_OFFS_TIMER+6 diff --git a/avr/modules/lcd2/win/gui.asm b/avr/modules/lcd2/win/gui.asm new file mode 100644 index 0000000..0c64673 --- /dev/null +++ b/avr/modules/lcd2/win/gui.asm @@ -0,0 +1,22 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +.dseg + +guiRootWidget: .byte 2 + + + +.cseg + +GUI_Init: + ret +; @end + diff --git a/avr/modules/lcd2/win/object.asm b/avr/modules/lcd2/win/object.asm new file mode 100644 index 0000000..e857e3f --- /dev/null +++ b/avr/modules/lcd2/win/object.asm @@ -0,0 +1,556 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine OBJ_Init @global +; +; @param Y pointer to object SRAM +; @param r17 options +; @clobbers X + +OBJ_Init: + push r17 + mov xl, yl + mov xh, yh + clr r16 + ldi r17, OBJ_OFFS_SIZE + rcall Utils_FillSram ; (R17, X) + rcall Tree_InitObject ; (R16) + pop r17 + std Y+OBJ_OFFS_OPTIONS, r17 + ldi r16, LOW(OBJ_DefaultHandler) + std Y+OBJ_OFFS_HANDLERFN_LO, r16 + ldi r16, HIGH(OBJ_DefaultHandler) + std Y+OBJ_OFFS_HANDLERFN_HI, r16 + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine OBJ_SetHandler @global +; +; @param Y pointer to object SRAM +; @param Z pointer to handler function (word address) +; @clobbers X + +OBJ_SetHandler: + std Y+OBJ_OFFS_HANDLERFN_LO, zl + std Y+OBJ_OFFS_HANDLERFN_HI, zh + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine OBJ_GetHandler @global +; +; @param Y pointer to object SRAM +; @return Z pointer to handler function (word address) +; @clobbers none + +OBJ_GetHandler: + ldd zl, Y+OBJ_OFFS_HANDLERFN_LO + ldd zh, Y+OBJ_OFFS_HANDLERFN_HI + ret +; @end + + + +OBJ_DefaultHandler: + ret +; @end + + + + + +; --------------------------------------------------------------------------- +; @routine OBJ_free @global +; +; @param Y pointer to object in SRAM +; @clobbers any + +OBJ_free: + ; free children + push yl + push yh + rcall Tree_GetFirstChildObject ; (none) +OBJ_free_loop: + mov r16, xl + or r16, xh + breq OBJ_free_loopEnd + mov yl, xl + mov yh, xh + rcall Tree_GetNextSibling + push xl ; next + push xh ; next + rcall OBJ_free + pop xh ; next + pop xl ; next + rjmp OBJ_free_loop +OBJ_free_loopEnd: + pop yh + pop yl + + rcall Tree_UnlinkObject ; (r16, r17, x) + + push yl + push yh + ldi r16, OBJ_SIGNAL_DESTROY + rcall OBJ_Handler + pop yh + pop yl + rcall objFreeLinks + rcall objFreeTimers + mov xl, yl + mov xh, yh + rcall Heap_free + clc + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine OBJ_Handler +; +; Signal handler for an object. A signal can have up to 3 parameters +; conveyed in registers R18, R19 and X. +; +; @param Y pointer to object SRAM +; @param r16 signal +; @param R18 1st param +; @param R19 2nd param +; @param X 3rd param + +OBJ_Handler: + ldd r17, Y+OBJ_OFFS_HANDLERFN_LO + push r17 + ldd r17, Y+OBJ_OFFS_HANDLERFN_HI + push r17 + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine OBJ_ForwardSignalToChildren +; +; Signal handler for an object. A signal can have up to 3 parameters +; conveyed in registers R18, R19 and X. +; +; @param Y pointer to object SRAM +; @param r16 signal +; @param R18 1st param +; @param R19 2nd param +; @param X 3rd param +; @clobbers any, !r16, !r18, !r19, !Y + +OBJ_ForwardSignalToChildren: + push yl + push yh + rcall Tree_GetFirstChildObject ; (none) +OBJ_ForwardSignalToChildren_loop: + clc + mov r17, xl + or r17, xh + breq OBJ_ForwardSignalToChildren_loopEnd + mov yl, xl + mov yh, xh + push r16 + push r18 + push r19 + push xl + push xh + push yl + push yh + rcall OBJ_Handler + pop yh + pop yl + pop xh + pop xl + pop r19 + pop r18 + pop r16 + rcall Tree_GetNextSibling + rjmp OBJ_ForwardSignalToChildren_loop +OBJ_ForwardSignalToChildren_loopEnd: + pop yh + pop yl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine OBJ_EmitSignal +; +; @param Y pointer to object SRAM +; @param r16 signal to emit +; @param R18 1st param +; @param R19 2nd param +; @param X 3rd param + +OBJ_EmitSignal: + push yl + push yh + ldd r17, Y+OBJ_OFFS_LINKS_LO + ldd yh, Y+OBJ_OFFS_LINKS_HI + mov yl, r17 +OBJ_EmitSignal_loop: + push r16 + rcall objCheckEmitSignalForLink ; (any, !X, !Y, !R18, !R19) + pop r16 + push xl + push xh + rcall List_GetNextObject ; (none) + mov yl, xl + mov yh, xh + pop xh + pop xl + mov r17, yl + or r17, yh + brne OBJ_EmitSignal_loop +OBJ_EmitSignal_popRet: + pop yh + pop yl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine OBJ_AddLink @global +; +; @param Y pointer to object SRAM +; @param X pointer to link +; @clobbers R16, R17 + +OBJ_AddLink: + ldd r16, Y+OBJ_OFFS_LINKS_LO + ldd r17, Y+OBJ_OFFS_LINKS_HI + tst r16 + brne OBJ_AddLink_addToExisting + tst r17 + brne OBJ_AddLink_addToExisting + ; empty list, new link is first + std Y+OBJ_OFFS_LINKS_LO, xl + std Y+OBJ_OFFS_LINKS_HI, xh + rjmp OBJ_AddLink_end +OBJ_AddLink_addToExisting: + push xl + push xh + push yl + push yh + mov yl, xl + mov yh, xh + mov xl, r16 + mov xh, r17 + rcall List_AddObject ; (r16, r17, x) + pop yh + pop yl + pop xh + pop xl +OBJ_AddLink_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine OBJ_RemoveLink @global +; +; @param Y pointer to object SRAM +; @param X pointer to link +; @clobbers R16, R17 + +OBJ_RemoveLink: + ldd r16, Y+OBJ_OFFS_LINKS_LO + ldd r17, Y+OBJ_OFFS_LINKS_HI + cp r16, xl + brne OBJ_RemoveLink_notFirst + cp r17, xh + brne OBJ_RemoveLink_notFirst + clr r16 + std Y+OBJ_OFFS_LINKS_LO, r16 + std Y+OBJ_OFFS_LINKS_HI, r16 + rjmp OBJ_RemoveLink_end +OBJ_RemoveLink_notFirst: + push xl + push xh + push yl + push yh + mov yl, xl + mov yh, r17 + mov xl, r16 + mov xh, r17 + rcall List_UnlinkObject ; (r16, r17, x) + pop yh + pop yl + pop xh + pop xl +OBJ_RemoveLink_end: + ret +; @end + + + + + +; --------------------------------------------------------------------------- +; @routine OBJ_AddTimer @global +; +; @param Y pointer to object SRAM +; @param X pointer to timer +; @clobbers R16, R17 + +OBJ_AddTimer: + ldd r16, Y+OBJ_OFFS_TIMERS_LO + ldd r17, Y+OBJ_OFFS_TIMERS_HI + tst r16 + brne OBJ_AddTimer_addToExisting + tst r17 + brne OBJ_AddTimer_addToExisting + ; empty list, new timer is first + std Y+OBJ_OFFS_TIMERS_LO, xl + std Y+OBJ_OFFS_TIMERS_HI, xh + rjmp OBJ_AddTimer_end +OBJ_AddTimer_addToExisting: + push xl + push xh + push yl + push yh + mov yl, xl + mov yh, xh + mov xl, r16 + mov xh, r17 + rcall List_AddObject ; (r16, r17, x) + pop yh + pop yl + pop xh + pop xl +OBJ_AddTimer_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine OBJ_RemoveTimer @global +; +; @param Y pointer to object SRAM +; @param X pointer to timer +; @clobbers R16, R17 + +OBJ_RemoveTimer: + ldd r16, Y+OBJ_OFFS_TIMERS_LO + ldd r17, Y+OBJ_OFFS_TIMERS_HI + cp r16, xl + brne OBJ_RemoveTimer_notFirst + cp r17, xh + brne OBJ_RemoveTimer_notFirst + clr r16 + std Y+OBJ_OFFS_TIMERS_LO, r16 + std Y+OBJ_OFFS_TIMERS_HI, r16 + rjmp OBJ_RemoveTimer_end +OBJ_RemoveTimer_notFirst: + push xl + push xh + push yl + push yh + mov yl, xl + mov yh, r17 + mov xl, r16 + mov xh, r17 + rcall List_UnlinkObject ; (r16, r17, x) + pop yh + pop yl + pop xh + pop xl +OBJ_RemoveTimer_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @param r16 signal +; @param Y link +; @clobbers any, !X, !Y, !R18, !R19 + +objCheckEmitSignalForLink: + ldd r17, Y+OBJ_LINK_OFFS_SIGNAL + cp r16, r17 + brne objCheckEmitSignalForLink_ret + push yl + push yh + push xl + push xh + push r18 + push r19 + ldd r16, Y+OBJ_LINK_OFFS_SLOT + ldd r17, Y+OBJ_LINK_OFFS_TARGET_LO + ldd yh, Y+OBJ_LINK_OFFS_TARGET_HI + mov yl, r17 + rcall OBJ_Handler + pop r19 + pop r18 + pop xh + pop xl + pop yh + pop yl +objCheckEmitSignalForLink_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine objFreeLinks +; +; @clobbers r16, r17, r18, r19, r24, r25, X + +objFreeLinks: + push yl + push yh + ldd r16, Y+OBJ_OFFS_LINKS_LO + ldd r17, Y+OBJ_OFFS_LINKS_HI + clr r18 + std Y+OBJ_OFFS_LINKS_LO, r18 + std Y+OBJ_OFFS_LINKS_HI, r18 + mov yl, r16 + mov yh, r17 + ldi zl, LOW(Obj_Link_free) + ldi zh, HIGH(Obj_Link_free) + rcall List_ForEveryObject ; (r16, r17, r18, r19, r24, r25, X, Y) + pop yh + pop yl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine objFreeTimers +; +; @clobbers r16, r17, r18, r19, r24, r25, X + +objFreeTimers: + push yl + push yh + ldd r16, Y+OBJ_OFFS_TIMERS_LO + ldd r17, Y+OBJ_OFFS_TIMERS_HI + clr r18 + std Y+OBJ_OFFS_TIMERS_LO, r18 + std Y+OBJ_OFFS_TIMERS_HI, r18 + mov yl, r16 + mov yh, r17 + ldi zl, LOW(Obj_Timer_free) + ldi zh, HIGH(Obj_Timer_free) + rcall List_ForEveryObject ; (r16, r17, r18, r19, r24, r25, X, Y) + pop yh + pop yl + ret +; @end + + + + + + +; --------------------------------------------------------------------------- +; @routine OBJ_Link_new @global +; +; @return CF set if okay, cleared on error +; @return Y pointer to SRAM for link +; @clobbers r16, r17, X + +OBJ_Link_new: + ldi r24, LOW(OBJ_LINK_SIZE) + ldi r25, HIGH(OBJ_LINK_SIZE) + rcall Heap_Alloc + brcc OBJ_Link_new_end + mov yl, xl + mov yh, xh + clr r16 + ldi r17, OBJ_LINK_SIZE + bigcall Utils_FillSram ; (R17, X) + rcall List_InitObject ; (R16) + sec +OBJ_Link_new_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine OBJ_Link_free @global +; +; @param Y pointer to SRAM for link +; @clobbers r16, r17, r24, r25, X + +OBJ_Link_free: + rcall List_FiniObject ; (R16) + mov xl, yl + mov xh, yh + rcall Heap_free ; (r16, r17, r24, r25, X) + clc + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine OBJ_Timer_new @global +; +; @return CF set if okay, cleared on error +; @return Y pointer to SRAM for timer +; @clobbers r16, r17, X + +OBJ_Timer_new: + ldi r24, LOW(TIMER_SIZE) + ldi r25, HIGH(TIMER_SIZE) + rcall Heap_Alloc + brcc OBJ_Timer_new_end + mov yl, xl + mov yh, xh + clr r16 + ldi r17, TIMER_SIZE + bigcall Utils_FillSram ; (R17, X) + rcall List_InitObject ; (R16) + sec +OBJ_Timer_new_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine OBJ_Timer_free @global +; +; @param Y pointer to SRAM for timer +; @clobbers r16, r17, r24, r25, X + +OBJ_Timer_free: + rcall List_FiniObject ; (R16) + mov xl, yl + mov xh, yh + rcall Heap_free ; (r16, r17, r24, r25, X) + clc + ret +; @end + + + diff --git a/avr/modules/lcd2/win/widget.asm b/avr/modules/lcd2/win/widget.asm index 4a070d6..655aee9 100644 --- a/avr/modules/lcd2/win/widget.asm +++ b/avr/modules/lcd2/win/widget.asm @@ -8,11 +8,763 @@ ; *************************************************************************** +; *************************************************************************** +; defs + +.equ WID_WIDGET_INTER_BORDER = 2 + + + +; *************************************************************************** +; code + +.cseg + + ; --------------------------------------------------------------------------- ; @routine WID_Widget_new @global +; +; @param Y pointer to window SRAM +; @param X pointer to parent +; @param r18 WID_OFFS_OPTIONS1 +; @param r19 WID_OFFS_OPTIONS2 + +WID_Widget_Init: + push r18 + push r19 + push xl + push xh + ldi zl, LOW(WID_Widget_Handler) + ldi zh, HIGH(WID_Widget_Handler) + clr r17 + rcall OBJ_Init + pop xh + pop xl + pop r19 + pop r18 + std Y+WID_OFFS_OPTIONS1, r18 + std Y+WID_OFFS_OPTIONS2, r19 + mov r16, xl + or r16, xh + breq WID_Widget_noParent + ; copy defaults from parent + adiw xh:xl, WID_OFFS_BG_COL_LO + ld r16, X+ ; WID_OFFS_BG_COL_LO + std Y+WID_OFFS_BG_COL_LO, r16 + ld r16, X+ ; WID_OFFS_BG_COL_HI + std Y+WID_OFFS_BG_COL_HI, r16 + ld r16, X+ ; WID_OFFS_FG_COL_LO + std Y+WID_OFFS_FG_COL_LO, r16 + ld r16, X+ ; WID_OFFS_FG_COL_HI + std Y+WID_OFFS_FG_COL_HI, r16 + ld r16, X+ ; WID_OFFS_FONT_LO + std Y+WID_OFFS_FONT_LO, r16 + ld r16, X+ ; WID_OFFS_FONT_HI + std Y+WID_OFFS_FONT_HI, r16 + rjmp WID_Widget_end +WID_Widget_noParent: ; preset without parent + clr r16 + std Y+WID_OFFS_FONT_LO, r16 + std Y+WID_OFFS_FONT_HI, r16 + + std Y+WID_OFFS_FG_COL_LO, r16 ; foreground black + std Y+WID_OFFS_FG_COL_HI, r16 + dec r16 + std Y+WID_OFFS_BG_COL_LO, r16 ; background white + std Y+WID_OFFS_BG_COL_HI, r16 + + ldi r16, 2 ; default borders + std Y+WID_OFFS_BORDER_TOP, r16 + std Y+WID_OFFS_BORDER_BOT, r16 + std Y+WID_OFFS_BORDER_LEFT, r16 + std Y+WID_OFFS_BORDER_RIGHT, r16 +WID_Widget_end: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine WID_Widget_Handler +; +; Signal handler for an object. A signal can have up to 3 parameters +; conveyed in registers R18, R19 and X. +; +; @param Y pointer to object SRAM +; @param r16 signal +; @param R18 1st param +; @param R19 2nd param +; @param X 3rd param +; @clobbers any, !Y + +WID_Widget_Handler: + cpi r16, WID_SIGNAL_GETMINWIDTH + breq WID_Widget_Handler_getMinWidth + cpi r16, WID_SIGNAL_GETMINHEIGHT + breq WID_Widget_Handler_getMinHeight + cpi r16, WID_SIGNAL_LAYOUT + breq WID_Widget_Handler_layout + cpi r16, WID_SIGNAL_DRAW + breq WID_Widget_Handler_draw + ; for now just forward signal to all children +WID_Widget_Handler_forward: + rcall OBJ_ForwardSignalToChildren + ret +WID_Widget_Handler_getMinWidth: + rjmp widgetGetMinWidth +WID_Widget_Handler_getMinHeight: + rjmp widgetGetMinHeight +WID_Widget_Handler_layout: + rjmp widgetLayout +WID_Widget_Handler_draw: + rjmp wDraw +; @end + + + + +wDraw: + ldd r16, Y+OBJ_OFFS_OPTIONS + sbrs r16, WID_OPTIONS0_BIT_VISIBLE ; only draw visible widgets + rjmp wDraw_ret + cbr r16, (1< count all visible children + rcall wGetSumOfMatchingVisibleChildrenHeights ; r19:r18=sum of all children heights + pop r22 + clr r23 ; r23:r22=number of visible expandable children + ; calculate number of bytes to add to each expandable child widget + ldd r20, Y+WID_OFFS_HEIGHT_LO ; total height + ldd r21, Y+WID_OFFS_HEIGHT_HI + clr r16 + ldd r17, Y+WID_OFFS_BORDER_TOP ; subtract top border + sub r20, r17 + sbc r21, r16 + brcs wVLayout_heightTooSmall ; jmp if too small + ldd r17, Y+WID_OFFS_BORDER_BOT ; subtract bottom border + sub r20, r17 + sbc r21, r16 + brcs wVLayout_heightTooSmall ; jmp if too small + + sub r20, r18 ; r21:r20 = HEIGHT-SUM_OF_VIS_CHILDREN_HEIGHTS + sbc r21, r19 + brcc wVLayout_heightTooSmall + breq wVLayout_yDone ; nothing to distribute + bigcall Utils_Divu16_16_16 ; r17:r16 = r21:r20 / r23:r22 + ; add additional pixel to heights of expandable child widgets + rcall wAddToHeightsOfExpandableVisibleChildren + +wVLayout_yDone: + rcall wSetRelYFromHeightInVisibleChildren + rcall wAlignChildrenHorizontally +; rcall wSetAbsoluteCoords call in GUI loop after calling layout on all widgets +wVLayout_heightTooSmall: + ; TODO: how to handle this case? + ret +; @end + + + +wSetAbsoluteCoords: + push yl + push yh +wSetAbsoluteCoords_loop: + ldd r18, Y+OBJ_OFFS_OPTIONS + andi r18, WID_OPTIONS0_BIT_VISIBLE + breq wSetAbsoluteCoords_nextSibling + push yl + push yh + bigcall Tree_GetParentObject + clr r18 + clr r19 + clr r20 + clr r21 + mov r17, xl + or r17, xh + breq wSetAbsoluteCoords_r1820set + mov yl, xl + mov yh, xh + ldd r18, Y+WID_OFFS_ABS_X_LO + ldd r19, Y+WID_OFFS_ABS_X_HI + ldd r20, Y+WID_OFFS_ABS_Y_LO + ldd r21, Y+WID_OFFS_ABS_Y_HI +wSetAbsoluteCoords_r1820set: + pop yh + pop yl + ; handle X + ldd r16, Y+WID_OFFS_REL_X_LO + ldd r17, Y+WID_OFFS_REL_X_HI + add r16, r18 + adc r17, r19 + std Y+WID_OFFS_ABS_X_LO, r16 + std Y+WID_OFFS_ABS_X_HI, r17 + ; handle Y + ldd r16, Y+WID_OFFS_REL_Y_LO + ldd r17, Y+WID_OFFS_REL_Y_HI + add r16, r20 + adc r17, r21 + std Y+WID_OFFS_ABS_Y_LO, r16 + std Y+WID_OFFS_ABS_Y_HI, r17 + bigcall Tree_GetObjectBelow + rjmp wSetAbsoluteCoords_loopEnd +wSetAbsoluteCoords_nextSibling: + bigcall Tree_GetNextSibling +wSetAbsoluteCoords_loopEnd: + mov r17, xl + or r17, xh + breq wSetAbsoluteCoords_end + mov yl, xl + mov yh, xh + rjmp wSetAbsoluteCoords_loop +wSetAbsoluteCoords_end: + pop yh + pop yl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine wAlignChildrenHorizontally +; +; Horizontally align children within the width of the parent widget. +; Only changes Y+WID_OFFS_REL_X_LO/HI. +; +; @param Y pointer to object SRAM +; @clobbers r16, r17, r18, r19, r24, r25 + +wAlignChildrenHorizontally: + push yl + push yh + ldd r24, Y+WID_OFFS_WIDTH_LO ; parent width + ldd r25, Y+WID_OFFS_WIDTH_HI + ldd r19, Y+WID_OFFS_BORDER_LEFT ; subtract left border + mov r16, r19 + clr r17 + sub r24, r16 + sbc r25, r17 + ldd r16, Y+WID_OFFS_BORDER_RIGHT ; subtract right border + sub r24, r16 + sbc r25, r17 ; r25:r24=parent width minus lateral borders, r19=left border + rcall Tree_GetFirstChildObject ; (none) +wAlignChildrenHorizontally_loop: + mov r17, xl + or r17, xh + breq wAlignChildrenHorizontally_loopEnd + mov yl, xl + mov yh, yl + ldd r18, Y+OBJ_OFFS_OPTIONS + andi r18, WID_OPTIONS0_BIT_VISIBLE + breq wAlignChildrenHorizontally_loopNext + push r24 + push r25 + push r19 + rcall wAlignHorizontally + pop r19 + add r24, r19 + adc r25, r19 + sub r25, r19 + std Y+WID_OFFS_REL_X_LO, r24 + std Y+WID_OFFS_REL_X_HI, r25 + pop r25 + pop r24 +wAlignChildrenHorizontally_loopNext: + rcall Tree_GetNextSibling ; (none) + rjmp wAlignChildrenHorizontally_loop +wAlignChildrenHorizontally_loopEnd: + pop yh + pop yl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine wAlignHorizontally +; +; @param r25:r24 parent width minus lateral borders +; @return r25:r24 proposed X position relative to parent +; @clobbers r16, r17 + +wAlignHorizontally: + ldd r16, Y+WID_OFFS_OPTIONS1 + sbrc r16, WID_OPTIONS1_BIT_STRETCH_X + rjmp wAlignHorizontally_stretch + andi r16, (WID_OPTIONS1_BIT_HALIGN0 | WID_OPTIONS1_BIT_HALIGN1) + cpi r16, (0< + + + + + main.asm + + + + + diff --git a/avr/modules/led_activity/main.asm b/avr/modules/led_activity/main.asm new file mode 100644 index 0000000..091e079 --- /dev/null +++ b/avr/modules/led_activity/main.asm @@ -0,0 +1,90 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +.equ LED_ACTIVITY_TIME = 2 + + + +; *************************************************************************** +; data + +.dseg + +ledActivityTimer: .byte 1 + + +; *************************************************************************** +; code + +.cseg + + +LED_ACTIVITY_BEGIN: + + + +; --------------------------------------------------------------------------- +; LedActivity_Init +; +; @return CFLAG: set if okay, clear on error +; USED: R1, R2, R3, R4, R16, R17, X + +LedActivity_Init: + sbi LED_ACTIVITY_DDR, LED_ACTIVITY_PINNUM ; out + ldi r16, 50 + sts ledActivityTimer, r16 ; keep on for 5s at the beginning + sec + ret + + + +; --------------------------------------------------------------------------- +; @routine LedActivity_Every100ms @global +; +; @clobbers r16, r17 + +LedActivity_Every100ms: + lds r16, ledActivityTimer + tst r16 + breq LedActivity_Every100ms_ret + dec r16 + sts ledActivityTimer, r16 + brne LedActivity_Every100ms_ret + sbi LED_ACTIVITY_PORT, LED_ACTIVITY_PINNUM ; turn LED off +LedActivity_Every100ms_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LedActivity_Restart @global +; +; @clobbers r16 + +LedActivity_Trigger: + lds r16, ledActivityTimer + tst r16 + brne LedActivity_Trigger_ledIsOn + cbi LED_ACTIVITY_PORT, LED_ACTIVITY_PINNUM ; turn LED on +LedActivity_Trigger_ledIsOn: + ldi r16, LED_ACTIVITY_TIME + sts ledActivityTimer, r16 + ret +; @end + + + + +LED_ACTIVITY_END: +.equ MODULE_SIZE_LED_ACTIVITY = LED_ACTIVITY_END-LED_ACTIVITY_BEGIN + + + diff --git a/avr/modules/led_signal/0BUILD b/avr/modules/led_signal/0BUILD new file mode 100644 index 0000000..febd367 --- /dev/null +++ b/avr/modules/led_signal/0BUILD @@ -0,0 +1,11 @@ + + + + + + main.asm + + + + + diff --git a/avr/modules/led_signal/main.asm b/avr/modules/led_signal/main.asm new file mode 100644 index 0000000..8475d01 --- /dev/null +++ b/avr/modules/led_signal/main.asm @@ -0,0 +1,156 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +; *************************************************************************** +; data + +.dseg + +ledSignalTimer: .byte 1 +ledSignalFlags: .byte 1 +ledSignalRunFlags: .byte 1 +ledSignalBitCounter: .byte 1 + + +; *************************************************************************** +; code + +.cseg + + +LED_SIGNAL_BEGIN: + + + +; --------------------------------------------------------------------------- +; LedSignal_Init +; +; @return CFLAG: set if okay, clear on error +; USED: R1, R2, R3, R4, R16, R17, X + +LedSignal_Init: + sbi LED_SIGNAL_DDR, LED_SIGNAL_PINNUM ; out + clr r16 + sts ledSignalFlags, r16 + ldi r16, 100 + sts ledSignalTimer, r16 + sec + ret + + + +; --------------------------------------------------------------------------- +; @routine LedSignal_Every100ms @global +; +; @clobbers r16, r17 + +LedSignal_Every100ms: + lds r16, ledSignalTimer + dec r16 + breq LedSignal_Every100ms_timer0 + sts ledSignalTimer, r16 + cpi r16, 80 + brcs LedSignal_Every100ms_checkBit + brne LedSignal_Every100ms_ret + rcall LedSignal_Restart ; (r16, r17) + rjmp LedSignal_Every100ms_ret +LedSignal_Every100ms_checkBit: + lds r17, ledSignalRunFlags + andi r17, 1 + brne LedSignal_Every100ms_bit1 +LedSignal_Every100ms_bit0: + cpi r16, 8 + breq LedSignal_Every100ms_ledOff + rjmp LedSignal_Every100ms_ret +LedSignal_Every100ms_bit1: + cpi r16, 3 + breq LedSignal_Every100ms_ledOff + rjmp LedSignal_Every100ms_ret +LedSignal_Every100ms_ledOff: + sbi LED_SIGNAL_PORT, LED_SIGNAL_PINNUM ; off + rjmp LedSignal_Every100ms_ret +LedSignal_Every100ms_timer0: + lds r17, ledSignalBitCounter + dec r17 + brne LedSignal_Every100ms_nextBit + ldi r17, 100 + sts ledSignalTimer, r17 + rjmp LedSignal_Every100ms_ret +LedSignal_Every100ms_nextBit: + sts ledSignalBitCounter, r17 + lds r16, ledSignalRunFlags + lsr r16 + sts ledSignalRunFlags, r16 + ldi r16, 10 + sts ledSignalTimer, r16 + cbi LED_SIGNAL_PORT, LED_SIGNAL_PINNUM ; on +LedSignal_Every100ms_ret: + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LedSignal_Restart @global +; +; @clobbers r16, r17 + +LedSignal_Restart: + ldi r16, 8 + sts ledSignalBitCounter, r16 + ldi r16, 10 + sts ledSignalTimer, r16 + lds r16, ledSignalFlags + sts ledSignalRunFlags, r16 + cbi LED_SIGNAL_PORT, LED_SIGNAL_PINNUM ; on + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LedSignal_SetFlag @global +; +; @param r16 flag mask +; @clobbers r17 + +LedSignal_SetFlag: + lds r17, ledSignalFlags + or r17, r16 + sts ledSignalFlags, r17 + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine LedSignal_ClrFlag @global +; +; @param r16 flag mask +; @clobbers r17 + +LedSignal_ClrFlag: + lds r17, ledSignalFlags + com r16 + and r17, r16 + com r16 + sts ledSignalFlags, r17 + ret +; @end + + + + +LED_SIGNAL_END: +.equ MODULE_SIZE_LED_SIGNAL = LED_SIGNAL_END-LED_SIGNAL_BEGIN + + + diff --git a/avr/modules/network/buffer.asm b/avr/modules/network/buffer.asm index e3d48cf..48c8c83 100644 --- a/avr/modules/network/buffer.asm +++ b/avr/modules/network/buffer.asm @@ -27,6 +27,11 @@ NET_Buffer_Init: ldi xl, LOW(netBuffers) ldi xh, HIGH(netBuffers) + ldi r16, NET_BUFFERS_NUM + sts netBuffersFree, r16 + clr r16 + sts netBuffersMaxUsed, r16 + sts netBuffersUsed, r16 m_fixedbuf_init NET_BUFFERS_SIZE, NET_BUFFERS_NUM ret ; @end @@ -45,8 +50,26 @@ NET_Buffer_Alloc: push r15 in r15, SREG cli + + lds r17, netBuffersFree + tst r17 + breq NET_Buffer_Alloc_error + rcall NET_Buffer_Alloc_noIrq brcc NET_Buffer_Alloc_error + lds r17, netBuffersFree + dec r17 + sts netBuffersFree, r17 + lds r17, netBuffersUsed + inc r17 + sts netBuffersUsed, r17 + push r16 + lds r16, netBuffersMaxUsed + cp r16, r17 + brcc NET_Buffer_Alloc_countersSet + sts netBuffersMaxUsed, r17 +NET_Buffer_Alloc_countersSet: + pop r16 out SREG, r15 pop r15 sec @@ -62,7 +85,7 @@ NET_Buffer_Alloc_noIrq: ldi xh, HIGH(netBuffers) m_fixedbuf_reserve NET_BUFFERS_SIZE, NET_BUFFERS_NUM brcc NET_Buffer_Alloc_end - ldi r17, (1< not in use + dec r16 + breq NET_Buffer_ReleaseByAddr_release + swap r16 ; ref counter now back in high nibble + push r17 + ld r17, X + andi r17, 0x0f ; keep interface number + or r16, r17 ; or interface number into R16 (R16 now complete) + st X, r16 + pop r17 + rjmp NET_Buffer_ReleaseByAddr_done +NET_Buffer_ReleaseByAddr_release: m_fixedbuf_release + lds r16, netBuffersFree + inc r16 + sts netBuffersFree, r16 + lds r16, netBuffersUsed + dec r16 + sts netBuffersUsed, r16 +NET_Buffer_ReleaseByAddr_done: + out SREG, r15 + pop r15 + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine NET_Buffer_IncRef @global +; +; @param X pointer to start of buffer +; @clobbers R16 + +NET_Buffer_IncRef: + push r15 + in r15, SREG + cli + ld r16, X + swap r16 ; ref counter now in lower nibble + andi r16, 0x0f + breq NET_Buffer_IncRef_done ; refcounter 0? -> not in use + inc r16 + breq NET_Buffer_IncRef_done ; don't increment if refcounter at max!!! + swap r16 ; ref counter now in high nibble again + push r17 + ld r17, X + andi r17, 0x0f ; clear ref counter in r17 + or r16, r17 ; or new ref counter into r17 + st X, r16 ; store new header byte + pop r17 +NET_Buffer_IncRef_done: out SREG, r15 pop r15 ret @@ -95,10 +172,15 @@ NET_Buffer_ReleaseByAddr: ; @clobbers X (R16) NET_Buffer_ReleaseByNum: - rcall NET_Buffer_Locate ; (R16, X) - brcc NET_Buffer_ReleaseByNum_end - rcall NET_Buffer_ReleaseByAddr ; (R16) + push r15 + in r15, SREG + cli + rcall NET_Buffer_Locate ; (R16, X) + brcc NET_Buffer_ReleaseByNum_end + rcall NET_Buffer_ReleaseByAddr ; (R16) NET_Buffer_ReleaseByNum_end: + out SREG, r15 + pop r15 ret ; @end @@ -119,6 +201,8 @@ NET_Buffer_ReleaseByNum_end: NET_Buffer_Locate: cpi r16, NET_BUFFERS_NUM brcc NET_Buffer_Locate_end ; out of range + +.if NET_BUFFERS_SIZE == 32 mov xh, r16 ; * 256 clr xl lsr xh ; *128 @@ -127,10 +211,31 @@ NET_Buffer_Locate: ror xl lsr xh ; *32 ror xl +.elif NET_BUFFERS_SIZE == 28 + clr r17 + mov xl, r16 ; * 256 + clr xh + lsl xl ; * 2 + rol xh + add xl, r16 ; * 3 + adc xh, r17 + lsl xl ; * 6 + rol xh + add xl, r16 ; * 7 + adc xh, r17 + lsl xl ; * 14 + rol xh + lsl xl ; * 28 + rol xh +.else +.error "Unhandled buffer size" +.endif + ldi r17, LOW(netBuffers) add xl, r17 ldi r17, HIGH(netBuffers) adc xh, r17 + sec NET_Buffer_Locate_end: ret diff --git a/avr/modules/network/data.asm b/avr/modules/network/data.asm index c3d8dea..255e372 100644 --- a/avr/modules/network/data.asm +++ b/avr/modules/network/data.asm @@ -12,6 +12,9 @@ networkDataBegin: ; buffers for incoming and outgoing messages + netBuffersUsed: .byte 1 + netBuffersMaxUsed: .byte 1 + netBuffersFree: .byte 1 netBuffers: .byte NET_BUFFERS_NUM*NET_BUFFERS_SIZE netRingBufferMsgNumIn: .byte RINGBUFFERY_SIZE+NET_MSGNUMINBUF_SIZE diff --git a/avr/modules/network/defs.asm b/avr/modules/network/defs.asm index ff1f6d3..b670706 100644 --- a/avr/modules/network/defs.asm +++ b/avr/modules/network/defs.asm @@ -9,12 +9,19 @@ ; defs -.equ NET_MSGNUMINBUF_SIZE = 4 ; max buffer nums in ringbuffer (global incoming) -.equ NET_IFACE_OUTMSGBUF_SIZE = 4 ; max buffer nums in ringbuffer (per interface outbound) +.equ NET_BUFFERS_SIZE = 28 ; CAVE: need to adapt routine NET_Buffer_Locate when changing this value!! + +;.equ NET_MSGNUMINBUF_SIZE = 8 ; max buffer nums in ringbuffer (global incoming) +;.equ NET_IFACE_OUTMSGBUF_SIZE = 8 ; max buffer nums in ringbuffer (per interface outbound) -.equ NET_IFACE_BUFFER_INUSE_BIT = 7 +.equ NET_IFACE_BUFFER_INUSE_BIT3 = 7 +.equ NET_IFACE_BUFFER_INUSE_BIT2 = 6 +.equ NET_IFACE_BUFFER_INUSE_BIT1 = 5 +.equ NET_IFACE_BUFFER_INUSE_BIT0 = 4 +.equ NET_IFACE_BUFFER_IFACENUM3_BIT = 3 +.equ NET_IFACE_BUFFER_IFACENUM2_BIT = 2 .equ NET_IFACE_BUFFER_IFACENUM1_BIT = 1 .equ NET_IFACE_BUFFER_IFACENUM0_BIT = 0 @@ -31,27 +38,25 @@ .equ NET_IFACE_OFFS_LASTMSGID_LOW = 8 .equ NET_IFACE_OFFS_LASTMSGID_HIGH = 9 -; receiption stats +; device stats .equ NET_IFACE_OFFS_PACKETSIN_LOW = 10 .equ NET_IFACE_OFFS_PACKETSIN_HIGH = 11 -.equ NET_IFACE_OFFS_ERR_CONTENT_LOW = 12 -.equ NET_IFACE_OFFS_ERR_CONTENT_HIGH = 13 -.equ NET_IFACE_OFFS_ERR_IO_LOW = 14 -.equ NET_IFACE_OFFS_ERR_IO_HIGH = 15 -.equ NET_IFACE_OFFS_ERR_NOBUF_LOW = 16 -.equ NET_IFACE_OFFS_ERR_NOBUF_HIGH = 17 -.equ NET_IFACE_OFFS_ERR_MSGSIZE_LOW = 18 -.equ NET_IFACE_OFFS_ERR_MSGSIZE_HIGH = 19 -.equ NET_IFACE_OFFS_ERR_MISSED_LOW = 20 -.equ NET_IFACE_OFFS_ERR_MISSED_HIGH = 21 - -; send stats -.equ NET_IFACE_OFFS_PACKETSOUT_LOW = 22 -.equ NET_IFACE_OFFS_PACKETSOUT_HIGH = 23 -.equ NET_IFACE_OFFS_ERR_COLLISIONS_LOW = 24 -.equ NET_IFACE_OFFS_ERR_COLLISIONS_HIGH = 25 -.equ NET_IFACE_OFFS_ERR_BUSY_LOW = 26 -.equ NET_IFACE_OFFS_ERR_BUSY_HIGH = 27 +.equ NET_IFACE_OFFS_PACKETSOUT_LOW = 12 +.equ NET_IFACE_OFFS_PACKETSOUT_HIGH = 13 +.equ NET_IFACE_OFFS_ERR_CONTENT_LOW = 14 +.equ NET_IFACE_OFFS_ERR_CONTENT_HIGH = 15 +.equ NET_IFACE_OFFS_ERR_IO_LOW = 16 +.equ NET_IFACE_OFFS_ERR_IO_HIGH = 17 +.equ NET_IFACE_OFFS_ERR_NOBUF_LOW = 18 +.equ NET_IFACE_OFFS_ERR_NOBUF_HIGH = 19 +.equ NET_IFACE_OFFS_ERR_COLLISIONS_LOW = 20 +.equ NET_IFACE_OFFS_ERR_COLLISIONS_HIGH = 21 +.equ NET_IFACE_OFFS_ERR_BUSY_LOW = 22 +.equ NET_IFACE_OFFS_ERR_BUSY_HIGH = 23 +.equ NET_IFACE_OFFS_ERR_MSGSIZE_LOW = 24 +.equ NET_IFACE_OFFS_ERR_MSGSIZE_HIGH = 25 +.equ NET_IFACE_OFFS_ERR_MISSED_LOW = 26 +.equ NET_IFACE_OFFS_ERR_MISSED_HIGH = 27 .equ NET_IFACE_OFFS_OUTMSGRINGBUF = 28 ; RINGBUFFERY_SIZE+UART_HW_IFACE_OUTMSGBUF_SIZE diff --git a/avr/modules/network/iface.asm b/avr/modules/network/iface.asm index 33c6434..4313716 100644 --- a/avr/modules/network/iface.asm +++ b/avr/modules/network/iface.asm @@ -188,9 +188,9 @@ NET_Interface_IncCounter16_end: NET_Interface_SetIfaceNumInBuffer: ldd r16, Y+NET_IFACE_OFFS_IFACENUM - andi r16, (NET_IFACE_BUFFER_IFACENUM1_BIT | NET_IFACE_BUFFER_IFACENUM0_BIT) + andi r16, 0x0f ld r17, X - andi r17, ~(NET_IFACE_BUFFER_IFACENUM1_BIT | NET_IFACE_BUFFER_IFACENUM0_BIT) + andi r17, 0xf0 or r17, r16 st X, r17 ret @@ -205,16 +205,47 @@ NET_Interface_SetIfaceNumInBuffer: ; @clobbers R16 NET_Interface_Periodically: - ldd r16, Y+NET_IFACE_OFFS_READTIMER - inc r16 - breq NET_Interface_Periodically_l1 - std Y+NET_IFACE_OFFS_READTIMER, r16 + push r15 + in r15, SREG + cli + ldd r16, Y+NET_IFACE_OFFS_READTIMER + inc r16 + breq NET_Interface_Periodically_l1 + std Y+NET_IFACE_OFFS_READTIMER, r16 NET_Interface_Periodically_l1: - ldd r16, Y+NET_IFACE_OFFS_WRITETIMER - inc r16 - breq NET_Interface_Periodically_l2 - std Y+NET_IFACE_OFFS_WRITETIMER, r16 + ldd r16, Y+NET_IFACE_OFFS_WRITETIMER + inc r16 + breq NET_Interface_Periodically_l2 + std Y+NET_IFACE_OFFS_WRITETIMER, r16 NET_Interface_Periodically_l2: + out SREG, r15 + pop r15 + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine NET_Interface_ResetStats @global +; +; @param Y pointer to start of interface data +; @clobbers R16, R17, X + +NET_Interface_ResetStats: + push r15 + in r15, SREG + cli + clr r16 + std Y+NET_IFACE_OFFS_PACKETSIN_LOW, r16 + + mov xl, yl + mov xh, yh + adiw xh:xl, NET_IFACE_OFFS_PACKETSIN_LOW + ldi r17, ((NET_IFACE_OFFS_ERR_BUSY_HIGH+1)-NET_IFACE_OFFS_PACKETSIN_LOW) + clr r16 + rcall Utils_FillSram ; (R17, X) + out SREG, r15 + pop r15 ret ; @end diff --git a/avr/modules/network/msg/0BUILD b/avr/modules/network/msg/0BUILD index 88b6afe..8c7a484 100644 --- a/avr/modules/network/msg/0BUILD +++ b/avr/modules/network/msg/0BUILD @@ -13,6 +13,9 @@ device-w.asm memstats-w.asm pong-w.asm + range-d.asm + range-r.asm + range-w.asm reboot-d.asm reboot-r.asm recvstats-w.asm diff --git a/avr/modules/network/msg/defs.asm b/avr/modules/network/msg/defs.asm index e5b8c3d..f44fced 100644 --- a/avr/modules/network/msg/defs.asm +++ b/avr/modules/network/msg/defs.asm @@ -14,8 +14,8 @@ .equ NETMSG_CMD_PING = 10 .equ NETMSG_CMD_PONG = 11 -.equ NETMSG_CMD_SENDSTATS = 20 -.equ NETMSG_CMD_RECVSTATS = 21 +.equ NETMSG_CMD_SENDSTATS = 22 +.equ NETMSG_CMD_RECVSTATS = 23 .equ NETMSG_CMD_TWIBUSMEMBER = 30 .equ NETMSG_CMD_DEBUG = 40 @@ -26,6 +26,7 @@ .equ NETMSG_CMD_CLAIM_ADDRESS = 62 .equ NETMSG_CMD_DENY_ADDRESS = 63 .equ NETMSG_CMD_ADDRESS_RANGE = 64 +.equ NETMSG_CMD_REENUM = 65 .equ NETMSG_CMD_FLASH_START = 70 .equ NETMSG_CMD_FLASH_END = 71 diff --git a/avr/modules/network/msg/device-w.asm b/avr/modules/network/msg/device-w.asm index a1e7ec2..c173d0b 100644 --- a/avr/modules/network/msg/device-w.asm +++ b/avr/modules/network/msg/device-w.asm @@ -25,13 +25,13 @@ NETMSG_Device_Write: st X+, r16 ; msg code ldd r16, Y+NET_IFACE_OFFS_ADDRESS st X+, r16 ; src address - rcall NETMSG_Common_AddUidToBuffer ; (R16, R18, R19, R20, R21) + bigcall NETMSG_Common_AddUidToBuffer ; (R16, R18, R19, R20, R21) ldi zh, HIGH(devInfoBlock*2) ; 6-17: devInfoBlock ldi zl, LOW(devInfoBlock*2) ldi r18, 12 bigcall Utils_CopyFromFlash ; (R17, R18, X, Z) sbiw xh:xl, 20 ; go back to beginning of message (1 byte dst addr, 1 byte length, 18 bytes payload) - rcall NETMSG_CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X) + bigcall NETMSG_CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X) sbiw xh:xl, 21 ; go back to beginning of message (1 byte dst addr, 1 byte length, 18 bytes payload, 1 byte crc) ret ; @end diff --git a/avr/modules/network/msg/memstats-w.asm b/avr/modules/network/msg/memstats-w.asm index 7317936..6a71ab3 100644 --- a/avr/modules/network/msg/memstats-w.asm +++ b/avr/modules/network/msg/memstats-w.asm @@ -27,7 +27,7 @@ NETMSG_MemStats_Write: st X+, r16 ; src address ; uid - rcall NETMSG_Common_AddUidToBuffer ; (R16, R18, R19, R20, R21) + bigcall NETMSG_Common_AddUidToBuffer ; (R16, R18, R19, R20, R21) ; timestamp (0 for now) clr r16 st X+, r16 @@ -51,14 +51,10 @@ NETMSG_MemStats_Write: st X+, r21 .endif ; current buffers used - push xl - push xh - rcall NET_Buffer_CountUsed ; (r16, r17, r18, X) - pop xh - pop xl + lds r16, netBuffersUsed st X+, r16 ; max buffers used - clr r16 + lds r16, netBuffersMaxUsed st X+, r16 ; no buffer errors ldd r16, Y+NET_IFACE_OFFS_ERR_NOBUF_LOW @@ -67,7 +63,7 @@ NETMSG_MemStats_Write: st X+, r16 sbiw xh:xl, 18 ; go back to beginning of message (1 byte dst addr, 1 byte length, 16 bytes payload) - rcall NETMSG_CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X) + bigcall NETMSG_CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X) sbiw xh:xl, 19 ; go back to beginning of message (1 byte dst addr, 1 byte length, 16 bytes payload, 1 byte crc) ret ; @end diff --git a/avr/modules/network/msg/pong-w.asm b/avr/modules/network/msg/pong-w.asm index 650bece..5a70f9b 100644 --- a/avr/modules/network/msg/pong-w.asm +++ b/avr/modules/network/msg/pong-w.asm @@ -18,17 +18,17 @@ ; @clobbers R16 (R17, R18, R19, R20, R21, Z) NETMSG_Pong_Write: - st X+, r16 ; dest address - ldi r16, 6 ; msg code+src address+4 payload bytes - st X+, r16 ; msg len + st X+, r16 ; dest address + ldi r16, 6 ; msg code+src address+4 payload bytes + st X+, r16 ; msg len ldi r16, NETMSG_CMD_PONG - st X+, r16 ; msg code + st X+, r16 ; msg code ldd r16, Y+NET_IFACE_OFFS_ADDRESS - st X+, r16 ; src address - rcall NETMSG_Common_AddUidToBuffer ; (R16, R18, R19, R20, R21) + st X+, r16 ; src address + bigcall NETMSG_Common_AddUidToBuffer ; (R16, R18, R19, R20, R21) sbiw xh:xl, 8 ; go back to beginning of message (1 byte dst addr, 1 byte length, 6 bytes payload) - rcall NETMSG_CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X) + bigcall NETMSG_CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X) sbiw xh:xl, 9 ; go back to beginning of message (1 byte dst addr, 1 byte length, 6 bytes payload, 1 byte crc) ret ; @end diff --git a/avr/modules/network/msg/range-d.asm b/avr/modules/network/msg/range-d.asm new file mode 100644 index 0000000..723d8cc --- /dev/null +++ b/avr/modules/network/msg/range-d.asm @@ -0,0 +1,18 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + + +.equ NETMSG_RANGE_OFFS_UID = 4 +.equ NETMSG_RANGE_OFFS_FROM = 8 +.equ NETMSG_RANGE_OFFS_TO = 9 + + + + diff --git a/avr/modules/network/msg/range-r.asm b/avr/modules/network/msg/range-r.asm new file mode 100644 index 0000000..ad46e4c --- /dev/null +++ b/avr/modules/network/msg/range-r.asm @@ -0,0 +1,38 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +; *************************************************************************** +; code + +.cseg + + +; --------------------------------------------------------------------------- +; @routine NETMSG_RangeRead @global +; Read a RANGE message. +; +; @param X buffer to read from +; @return R18 command +; @return R20 range begin +; @return R21 range end +; @clobbers none + +NETMSG_Range_Read: + adiw xh:xl, NETMSG_OFFS_CMD + ld r18, X ; command + adiw xh:xl, NETMSG_RANGE_OFFS_FROM-NETMSG_OFFS_CMD ; skip src addr and uid + ld r20, X+ ; range from + ld r21, X ; range to + sbiw xh:xl, NETMSG_RANGE_OFFS_TO ; back to msg begin + ret +; @end + + + diff --git a/avr/modules/network/msg/range-w.asm b/avr/modules/network/msg/range-w.asm new file mode 100644 index 0000000..1511da4 --- /dev/null +++ b/avr/modules/network/msg/range-w.asm @@ -0,0 +1,44 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + + +; --------------------------------------------------------------------------- +; @routine NETMSG_Range_Write +; +; @param Y pointer to device to write msg for +; @param X pointer to buffer to write to +; @param R18 command +; @param R20 range begin +; @param R21 range end +; @clobbers R16, R18 (R17, R19, R20, R21, Z) + +NETMSG_Range_Write: + ldi r16, 0xff + st X+, r16 ; dest address + ldi r16, 8 ; msg code+src address+6 payload bytes + st X+, r16 ; msg len + st X+, r18 ; msg code + ldd r16, Y+NET_IFACE_OFFS_ADDRESS + st X+, r16 ; src address + push r20 + push r21 + rcall NETMSG_Common_AddUidToBuffer ; (R16, R18, R19, R20, R21) + pop r21 + pop r20 + st X+, r20 ; range begin + st X+, r21 ; range end + + sbiw xh:xl, 10 ; go back to beginning of message (1 byte dst addr, 1 byte length, 8 bytes payload) + rcall NETMSG_CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X) + sbiw xh:xl, 11 ; go back to beginning of message (1 byte dst addr, 1 byte length, 8 bytes payload, 1 byte crc) + ret +; @end + + + diff --git a/avr/modules/network/msg/reboot-r.asm b/avr/modules/network/msg/reboot-r.asm index a99bcf9..29af0f2 100644 --- a/avr/modules/network/msg/reboot-r.asm +++ b/avr/modules/network/msg/reboot-r.asm @@ -31,7 +31,7 @@ NETMSG_RebootRequestRead: push xl push xh adiw xh:xl, NETMSG_REBOOTREQ_OFFS_UID - rcall NETMSG_CheckUidInMsg ; (r16, r18, r19, r20, r21, X) + bigcall NETMSG_CheckUidInMsg ; (r16, r18, r19, r20, r21, X) pop xh pop xl pop r16 diff --git a/avr/modules/network/msg/recvstats-w.asm b/avr/modules/network/msg/recvstats-w.asm index d170d74..750b775 100644 --- a/avr/modules/network/msg/recvstats-w.asm +++ b/avr/modules/network/msg/recvstats-w.asm @@ -19,21 +19,52 @@ NETMSG_RecvStats_Write: ldi r16, 0xff st X+, r16 ; dest address - ldi r16, 18 ; msg code+src address+10 payload bytes + ldi r16, 19 ; msg code+src address+10 payload bytes st X+, r16 ; msg len ldi r16, NETMSG_CMD_RECVSTATS st X+, r16 ; msg code ldd r16, Y+NET_IFACE_OFFS_ADDRESS st X+, r16 ; src address - rcall NETMSG_Common_AddUidToBuffer ; (R16, R18, R19, R20, R21) - adiw yh:yl, NET_IFACE_OFFS_PACKETSIN_LOW - ldi r18, 12 - bigcall Utils_Copy_SDRAM ; (R17, R18, X, Y) - sbiw yh:yl, NET_IFACE_OFFS_PACKETSIN_LOW+12 - sbiw xh:xl, 20 ; go back to beginning of message (1 byte dst addr, 1 byte length, 18 bytes payload) - rcall NETMSG_CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X) - sbiw xh:xl, 21 ; go back to beginning of message (1 byte dst addr, 1 byte length, 18 bytes payload, 1 byte crc) + ; UID + bigcall NETMSG_Common_AddUidToBuffer ; (R16, R18, R19, R20, R21) + ; interface number + ldd r16, Y+NET_IFACE_OFFS_IFACENUM + st X+, r16 + ; packets in + ldd r16, Y+NET_IFACE_OFFS_PACKETSIN_LOW + st X+, r16 + ldd r16, Y+NET_IFACE_OFFS_PACKETSIN_HIGH + st X+, r16 + ; content error + ldd r16, Y+NET_IFACE_OFFS_ERR_CONTENT_LOW + st X+, r16 + ldd r16, Y+NET_IFACE_OFFS_ERR_CONTENT_HIGH + st X+, r16 + ; io error + ldd r16, Y+NET_IFACE_OFFS_ERR_IO_LOW + st X+, r16 + ldd r16, Y+NET_IFACE_OFFS_ERR_IO_HIGH + st X+, r16 + ; nobuf error + ldd r16, Y+NET_IFACE_OFFS_ERR_NOBUF_LOW + st X+, r16 + ldd r16, Y+NET_IFACE_OFFS_ERR_NOBUF_HIGH + st X+, r16 + ; msgsize error + ldd r16, Y+NET_IFACE_OFFS_ERR_MSGSIZE_LOW + st X+, r16 + ldd r16, Y+NET_IFACE_OFFS_ERR_MSGSIZE_HIGH + st X+, r16 + ; missed error + ldd r16, Y+NET_IFACE_OFFS_ERR_MISSED_LOW + st X+, r16 + ldd r16, Y+NET_IFACE_OFFS_ERR_MISSED_HIGH + st X+, r16 + + sbiw xh:xl, 21 ; go back to beginning of message (1 byte dst addr, 1 byte length, 18 bytes payload) + bigcall NETMSG_CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X) + sbiw xh:xl, 22 ; go back to beginning of message (1 byte dst addr, 1 byte length, 18 bytes payload, 1 byte crc) ret ; @end diff --git a/avr/modules/network/msg/sendstats-w.asm b/avr/modules/network/msg/sendstats-w.asm index f33d612..b794bcc 100644 --- a/avr/modules/network/msg/sendstats-w.asm +++ b/avr/modules/network/msg/sendstats-w.asm @@ -12,28 +12,44 @@ ; --------------------------------------------------------------------------- ; @routine NETMSG_SendStats_Write @global ; -; @param Y pointer to device to write msg for and to +; @param Y pointer to device to write msg for ; @param X pointer to buffer to write to ; @clobbers R16, R18 (R17, R19, R20, R21, Z) NETMSG_SendStats_Write: ldi r16, 0xff st X+, r16 ; dest address - ldi r16, 12 ; msg code+src address+10 payload bytes + ldi r16, 13 ; msg code+src address+11 payload bytes st X+, r16 ; msg len ldi r16, NETMSG_CMD_SENDSTATS st X+, r16 ; msg code ldd r16, Y+NET_IFACE_OFFS_ADDRESS st X+, r16 ; src address - rcall NETMSG_Common_AddUidToBuffer ; (R16, R18, R19, R20, R21) - adiw yh:yl, NET_IFACE_OFFS_PACKETSOUT_LOW - ldi r18, 6 - bigcall Utils_Copy_SDRAM ; (R17, R18, X, Y) - sbiw yh:yl, NET_IFACE_OFFS_PACKETSOUT_LOW+6 - sbiw xh:xl, 14 ; go back to beginning of message (1 byte dst addr, 1 byte length, 12 bytes payload) - rcall NETMSG_CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X) - sbiw xh:xl, 15 ; go back to beginning of message (1 byte dst addr, 1 byte length, 12 bytes payload, 1 byte crc) + ; UID + bigcall NETMSG_Common_AddUidToBuffer ; (R16, R18, R19, R20, R21) + ; interface number + ldd r16, Y+NET_IFACE_OFFS_IFACENUM + st X+, r16 + ; packets out + ldd r16, Y+NET_IFACE_OFFS_PACKETSOUT_LOW + st X+, r16 + ldd r16, Y+NET_IFACE_OFFS_PACKETSOUT_HIGH + st X+, r16 + ; collisions + ldd r16, Y+NET_IFACE_OFFS_ERR_COLLISIONS_LOW + st X+, r16 + ldd r16, Y+NET_IFACE_OFFS_ERR_COLLISIONS_HIGH + st X+, r16 + ; busy + ldd r16, Y+NET_IFACE_OFFS_ERR_BUSY_LOW + st X+, r16 + ldd r16, Y+NET_IFACE_OFFS_ERR_BUSY_HIGH + st X+, r16 + + sbiw xh:xl, 15 ; go back to beginning of message (1 byte dst addr, 1 byte length, 13 bytes payload) + bigcall NETMSG_CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X) + sbiw xh:xl, 16 ; go back to beginning of message (1 byte dst addr, 1 byte length, 12 bytes payload, 1 byte crc) ret ; @end diff --git a/avr/modules/sgp30/main.asm b/avr/modules/sgp30/main.asm index 9332a5a..e67de56 100644 --- a/avr/modules/sgp30/main.asm +++ b/avr/modules/sgp30/main.asm @@ -157,10 +157,22 @@ sgp30CheckPresence: +; --------------------------------------------------------------------------- +; @routine SGP30_EverySecond +; +; +; @return CFLAG set if okay, clear on error +; @clobbers R16, R17, R18, R19, R20, R21, R22 + +SGP30_EverySecond: + rjmp SGP30_Measure ; (R16, R17, R18, R19, R20, R21, R22) +; @end + + + ; --------------------------------------------------------------------------- ; @routine SGP30_Measure ; -; Expects interrupts being disabled! ; ; @return CFLAG set if okay, clear on error ; @clobbers R16, R17, R18, R19, R20, R21, R22 diff --git a/avr/modules/tcrt1000/main2.asm b/avr/modules/tcrt1000/main2.asm index ae6adbc..9f3090c 100644 --- a/avr/modules/tcrt1000/main2.asm +++ b/avr/modules/tcrt1000/main2.asm @@ -10,7 +10,8 @@ .equ TCRT1K_INTERVAL = 7 -.equ TCRT1K_LIMIT = 170 +;.equ TCRT1K_LIMIT = 170 +.equ TCRT1K_LIMIT = 100 .equ TCRT1K_FLAGS_VALID_BIT = 7 .equ TCRT1K_FLAGS_VALUE_BIT = 0 @@ -24,6 +25,7 @@ tcrt1kDataBegin: tcrt1kTimer: .byte 1 tcrt1kFlags: .byte 1 + tcrt1kLastValue: .byte 1 tcrt1kDataEnd: @@ -96,24 +98,25 @@ TCRT1K_Every100ms_ledOn: sbi TCRT1K_LED_PORT, TCRT1K_LED_PIN ; LED on ret TCRT1K_Every100ms_startMeasure: - sbi ADCSRA, ADSC ; start conversion + sbi ADCSRA, ADSC ; start conversion ret TCRT1K_Every100ms_readValue: sbic ADCSRA, ADSC ret ; return if bit still set, leave tcrt1kTimer at "1" ; conversion complete, read value - ldi r16, TCRT1K_INTERVAL ; restart timer + ldi r16, TCRT1K_INTERVAL ; restart timer sts tcrt1kTimer, r16 - in r16, ADCH ; read value from ADC - cbi TCRT1K_LED_PORT, TCRT1K_LED_PIN ; LED off + in r16, ADCH ; read value from ADC + sts tcrt1kLastValue, r16 + cbi TCRT1K_LED_PORT, TCRT1K_LED_PIN ; LED off ; convert to 1/0 lds r17, tcrt1kFlags - cbr r17, (1< + + + + + defs.asm + macros.asm + uartfd0.asm + + + + + diff --git a/avr/modules/uart_fd/defs.asm b/avr/modules/uart_fd/defs.asm new file mode 100644 index 0000000..e77441d --- /dev/null +++ b/avr/modules/uart_fd/defs.asm @@ -0,0 +1,47 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AVR_MODULES_UARTFD_DEFS_ASM +#define AVR_MODULES_UARTFD_DEFS_ASM + + +.equ UARTFD_SKIPPING_TIME = 2 +.equ UARTFD_READ_TIMEOUT = 5 +.equ UARTFD_WRITE_TIMEOUT = 5 + + +.equ UARTFD_IFACE_STATUS_BIT_OVERRUN = 0 +.equ UARTFD_IFACE_STATUS_BIT_HWERR = 1 +.equ UARTFD_IFACE_STATUS_BIT_BADMSGSIZE = 2 +.equ UARTFD_IFACE_STATUS_BIT_SKIPPING = 3 + + + +.equ UARTFD_IFACE_SIZE_BUFFER = NET_BUFFERS_SIZE-1 + +.equ UARTFD_IFACE_OFFS_BEGIN = NET_IFACE_SIZE +.equ UARTFD_IFACE_OFFS_STATUS = UARTFD_IFACE_OFFS_BEGIN +.equ UARTFD_IFACE_OFFS_WPOS_LOW = UARTFD_IFACE_OFFS_BEGIN+1 +.equ UARTFD_IFACE_OFFS_WPOS_HIGH = UARTFD_IFACE_OFFS_BEGIN+2 +.equ UARTFD_IFACE_OFFS_WBUFLEFT = UARTFD_IFACE_OFFS_BEGIN+3 +.equ UARTFD_IFACE_OFFS_WBUFNUM = UARTFD_IFACE_OFFS_BEGIN+4 +.equ UARTFD_IFACE_OFFS_RPOS_LOW = UARTFD_IFACE_OFFS_BEGIN+5 +.equ UARTFD_IFACE_OFFS_RPOS_HIGH = UARTFD_IFACE_OFFS_BEGIN+6 +.equ UARTFD_IFACE_OFFS_RBUFUSED = UARTFD_IFACE_OFFS_BEGIN+7 +.equ UARTFD_IFACE_OFFS_RBUFLEFT = UARTFD_IFACE_OFFS_BEGIN+8 +.equ UARTFD_IFACE_OFFS_RBUFFER = UARTFD_IFACE_OFFS_BEGIN+9 +.equ UARTFD_IFACE_SIZE = UARTFD_IFACE_OFFS_RBUFFER+UARTFD_IFACE_SIZE_BUFFER + + + + +#endif + + + diff --git a/avr/modules/uart_fd/macros.asm b/avr/modules/uart_fd/macros.asm new file mode 100644 index 0000000..8e4d550 --- /dev/null +++ b/avr/modules/uart_fd/macros.asm @@ -0,0 +1,231 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AVR_MODULES_UARTFD_MACROS_ASM +#define AVR_MODULES_UARTFD_MACROS_ASM + + +.macro M_UARTFD_SET_CHARFORMAT + ldi r16, (1< + + + + + comonuart1.asm + defs.asm + + + + + diff --git a/avr/modules/uart_hw2/comonuart0.asm b/avr/modules/uart_hw2/comonuart0.asm new file mode 100644 index 0000000..46c86da --- /dev/null +++ b/avr/modules/uart_hw2/comonuart0.asm @@ -0,0 +1,738 @@ +; *************************************************************************** +; copyright : (C) 2025 by Martin Preuss +; email : martin@libchipcard.de +; +; *************************************************************************** +; * This file is part of the project "AqHome". * +; * Please see toplevel file COPYING of that project for license details. * +; *************************************************************************** + +#ifndef AVR_MODULES_UART_HW2_COMONUART0_H +#define AVR_MODULES_UART_HW2_COMONUART0_H + + +.dseg + +comOnUart0_iface: .byte UART_HW2_IFACE_SIZE + + + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine ComOnUart0_Init @global +; +; @clobbers R16, R17, Y (X) + +ComOnUart0_Init: + rcall comOnUart0StopRx + rcall comOnUart0StopTx + + ldi yl, LOW(comOnUart0_iface) + ldi yh, HIGH(comOnUart0_iface) + rcall NET_Interface_Init ; (R16, R17, X) + ldi r16, UART_HW2_MODE_IDLE + std Y+UART_HW2_IFACE_OFFS_MODE, r16 + clr r16 + std Y+NET_IFACE_OFFS_IFACENUM, r16 + rcall comOnUart0SetAttnInput + + inr r16, COM_IRQ_ADDR_ATTN0 + sbr r16, (1< diff --git a/devices/nodes/aqua_n17.xml b/devices/nodes/aqua_n17.xml index 78a4d89..ef7a596 100644 --- a/devices/nodes/aqua_n17.xml +++ b/devices/nodes/aqua_n17.xml @@ -5,9 +5,22 @@ 17 - - - + + + + + + + + + + + + + + + + diff --git a/devices/nodes/aqua_n18.xml b/devices/nodes/aqua_n18.xml index c86c0aa..46e4212 100644 --- a/devices/nodes/aqua_n18.xml +++ b/devices/nodes/aqua_n18.xml @@ -5,10 +5,22 @@ 18 - - - - + + + + + + + + + + + + + + + + diff --git a/devices/nodes/aqua_n19.xml b/devices/nodes/aqua_n19.xml index 951c020..78a306d 100644 --- a/devices/nodes/aqua_n19.xml +++ b/devices/nodes/aqua_n19.xml @@ -5,10 +5,23 @@ 19 - - - - + + + + + + + + + + + + + + + + + diff --git a/devices/nodes/aqua_n20.xml b/devices/nodes/aqua_n20.xml index 7f5c7fd..e465cbe 100644 --- a/devices/nodes/aqua_n20.xml +++ b/devices/nodes/aqua_n20.xml @@ -5,11 +5,23 @@ 20 - - - - - + + + + + + + + + + + + + + + + + diff --git a/devices/nodes/aqua_n21.xml b/devices/nodes/aqua_n21.xml deleted file mode 100644 index 13c1c52..0000000 --- a/devices/nodes/aqua_n21.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - AQUA - N - 21 - - - - - - - - - - - - - - - - - - - - - - - diff --git a/devices/nodes/aqua_n22.xml b/devices/nodes/aqua_n22.xml index 1648b48..7e76bf1 100644 --- a/devices/nodes/aqua_n22.xml +++ b/devices/nodes/aqua_n22.xml @@ -5,16 +5,27 @@ 22 - + - - + + - - - - - + + + + + + + + + + + + + + + + diff --git a/flashnode.sh b/flashnode.sh index e881362..2b9adf8 100755 --- a/flashnode.sh +++ b/flashnode.sh @@ -23,6 +23,13 @@ case $NODE in EFUSE_ARG="-U efuse:w:0xFF:m" FILE_ARG="-U flash:w:./0-build/avr/devices/c02/boot/c02_boot.hex" ;; + n14) + DEVICE_ARG="-p t85" + HFUSE_ARG="-U hfuse:w:0xD7:m" + LFUSE_ARG="" + EFUSE_ARG="-U efuse:w:0xFE:m" + FILE_ARG="-U flash:w:./0-build/avr/devices/n14/boot/n14_boot.hex" + ;; n16) DEVICE_ARG="-p t84" HFUSE_ARG="-U hfuse:w:0xD7:m" @@ -72,6 +79,48 @@ case $NODE in EFUSE_ARG="-U efuse:w:0xFE:m" FILE_ARG="-U flash:w:./0-build/avr/devices/n25/boot/n25_boot.hex" ;; + n26) + DEVICE_ARG="-p t84" + HFUSE_ARG="-U hfuse:w:0xD7:m" + LFUSE_ARG="" + EFUSE_ARG="-U efuse:w:0xFE:m" + FILE_ARG="-U flash:w:./0-build/avr/devices/n26/boot/n26_boot.hex" + ;; + n27) + DEVICE_ARG="-p t84" + HFUSE_ARG="-U hfuse:w:0xD7:m" + LFUSE_ARG="" + EFUSE_ARG="-U efuse:w:0xFE:m" + FILE_ARG="-U flash:w:./0-build/avr/devices/n27/boot/n27_boot.hex" + ;; + n28) + DEVICE_ARG="-p t84" + HFUSE_ARG="-U hfuse:w:0xD7:m" + LFUSE_ARG="" + EFUSE_ARG="-U efuse:w:0xFE:m" + FILE_ARG="-U flash:w:./0-build/avr/devices/n28/boot/n28_boot.hex" + ;; + r04) + DEVICE_ARG="-p t841" + HFUSE_ARG="-U hfuse:w:0xD7:m" + LFUSE_ARG="" + EFUSE_ARG="-U efuse:w:0xFE:m" + FILE_ARG="-U flash:w:./0-build/avr/devices/r04/boot/r04_boot.hex" + ;; + r05) + DEVICE_ARG="-p t841" + HFUSE_ARG="-U hfuse:w:0xD7:m" + LFUSE_ARG="" + EFUSE_ARG="-U efuse:w:0xFE:m" + FILE_ARG="-U flash:w:./0-build/avr/devices/r05/boot/r05_boot.hex" + ;; + s03) + DEVICE_ARG="-p m644p" + HFUSE_ARG="-U hfuse:w:0x95:m" + LFUSE_ARG="-U lfuse:w:0xdF:m" + EFUSE_ARG="-U efuse:w:0xFF:m" + FILE_ARG="-U flash:w:./0-build/avr/devices/s03/boot/s03_boot.hex" + ;; t03) DEVICE_ARG="-p t841" HFUSE_ARG="-U hfuse:w:0xD7:m" @@ -79,6 +128,13 @@ case $NODE in EFUSE_ARG="-U efuse:w:0xFE:m" FILE_ARG="-U flash:w:./0-build/avr/devices/t03/boot/t03_boot.hex" ;; + t04) + DEVICE_ARG="-p t841" + HFUSE_ARG="-U hfuse:w:0xD7:m" + LFUSE_ARG="" + EFUSE_ARG="-U efuse:w:0xFE:m" + FILE_ARG="-U flash:w:./0-build/avr/devices/t04/boot/t04_boot.hex" + ;; *) echo "Unknown node $NODE". exit 1