From 003ae692e6340878110d53f736f2904592155fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Fri, 16 Feb 2018 23:01:47 +0100 Subject: [PATCH] sipo finished --- comm/messages.c | 3 ++- framework/settings.c | 18 ++++++++++-------- framework/unit_registry.c | 29 ++++++++++++++++++----------- units/sipo/_sipo_api.c | 7 ++++++- units/sipo/_sipo_internal.h | 3 ++- units/sipo/_sipo_settings.c | 4 ++-- units/sipo/unit_sipo.c | 3 ++- utils/ini_writer.c | 3 ++- utils/ini_writer.h | 5 +++-- vfs/vfs_user.c | 6 +++--- 10 files changed, 50 insertions(+), 31 deletions(-) diff --git a/comm/messages.c b/comm/messages.c index 2348ca8..2b4105b 100644 --- a/comm/messages.c +++ b/comm/messages.c @@ -71,6 +71,7 @@ static void settings_bulkread_cb(BulkRead *bulk, uint32_t chunk, uint8_t *buffer if (bulk->offset == 0) iw_begin(); IniWriter iw = iw_init((char *)buffer, bulk->offset, chunk); + iw.tag = 1; settings_build_units_ini(&iw); } @@ -85,7 +86,7 @@ static TF_Result lst_ini_export(TinyFrame *tf, TF_Msg *msg) assert_param(bulk != NULL); bulk->frame_id = msg->frame_id; - bulk->len = iw_measure_total(settings_build_units_ini); + bulk->len = iw_measure_total(settings_build_units_ini, 1); bulk->read = settings_bulkread_cb; bulk->userdata = NULL; diff --git a/framework/settings.c b/framework/settings.c index 246a74a..f4360bc 100644 --- a/framework/settings.c +++ b/framework/settings.c @@ -229,7 +229,6 @@ static void gex_file_preamble(IniWriter *iw, const char *filename) iw_hdr_comment(iw, filename); iw_hdr_comment(iw, "GEX v%s on %s", GEX_VERSION, GEX_PLATFORM); iw_hdr_comment(iw, "built %s at %s", __DATE__, __TIME__); - iw_cmt_newline(iw); } /** Generate a config file header (write instructions) */ @@ -237,12 +236,15 @@ static void ini_preamble(IniWriter *iw, const char *filename) { gex_file_preamble(iw, filename); - iw_comment(iw, "Overwrite this file to change settings."); - #if PLAT_LOCK_BTN - iw_comment(iw, "Press the LOCK button to save them to Flash."); - #else - iw_comment(iw, "Close the LOCK jumper to save them to Flash."); - #endif + if (iw->tag == 0) { // tag 1 is set when exporting via the API + iw_cmt_newline(iw); + iw_comment(iw, "Overwrite this file to change settings."); + #if PLAT_LOCK_BTN + iw_comment(iw, "Press the LOCK button to save them to Flash."); + #else + iw_comment(iw, "Close the LOCK jumper to save them to Flash."); + #endif + } } // --- UNITS.INI --- @@ -284,7 +286,7 @@ extern void plat_print_system_pinout(IniWriter *iw); void settings_build_pinout_txt(IniWriter *iw) { gex_file_preamble(iw, "PINOUT.TXT"); - + iw_cmt_newline(iw); rsc_print_all_available(iw); ureg_print_unit_resources(iw); plat_print_system_pinout(iw); diff --git a/framework/unit_registry.c b/framework/unit_registry.c index 23d2ae8..73daea9 100644 --- a/framework/unit_registry.c +++ b/framework/unit_registry.c @@ -340,19 +340,26 @@ bool ureg_finalize_all_init(void) } else { pUnit->status = pUnit->driver->init(pUnit); if (pUnit->status != E_SUCCESS) { - dbg("!!! error initing unit %s: %s", pUnit->name, - error_get_message(pUnit->status)); + dbg("!!! error initing unit %s: %s", pUnit->name, error_get_message(pUnit->status)); } // try to assign unique callsigns - // FIXME this is wrong, sometimes leads to duplicate CS if (pUnit->callsign == 0) { - pUnit->callsign = callsign++; - } - else { - if (pUnit->callsign >= callsign) { - callsign = (uint8_t) (pUnit->callsign + 1); - } + // this is very inefficient but should be reliable + bool change = false; + do { + UlistEntry *xli = ulist_head; + while (xli != NULL) { + if (xli->unit.callsign != 0) { + if (xli->unit.callsign == callsign) { + change = true; + callsign++; + } + } + xli = xli->next; + } + } while (change && callsign < 255); + pUnit->callsign = callsign; } } @@ -398,8 +405,9 @@ void ureg_build_ini(IniWriter *iw) // Unit list iw_section(iw, "UNITS"); - iw_comment(iw, "Create units by adding their names next to a type (e.g. PIN=A,B),"); + iw_comment(iw, "Create units by adding their names next to a type (e.g. DO=A,B),"); iw_comment(iw, "remove the same way. Reload to update the unit sections below."); + iw_cmt_newline(iw); // This could certainly be done in some more efficient way ... re = ureg_head; @@ -412,7 +420,6 @@ void ureg_build_ini(IniWriter *iw) const UnitDriver *const pDriver = re->driver; - iw_cmt_newline(iw); iw_comment(iw, pDriver->description); iw_string(iw, pDriver->name); iw_string(iw, "="); diff --git a/units/sipo/_sipo_api.c b/units/sipo/_sipo_api.c index 4ea64e5..bf2e089 100644 --- a/units/sipo/_sipo_api.c +++ b/units/sipo/_sipo_api.c @@ -30,7 +30,7 @@ static void send_pulse(bool pol, GPIO_TypeDef *port, uint32_t ll) #pragma GCC push_options #pragma GCC optimize ("O2") -error_t UU_SIPO_Write(Unit *unit, const uint8_t *buffer, uint16_t buflen) +error_t UU_SIPO_Write(Unit *unit, const uint8_t *buffer, uint16_t buflen, uint16_t terminal_data) { CHECK_TYPE(unit, &UNIT_SIPO); struct priv *priv = unit->data; @@ -65,6 +65,11 @@ error_t UU_SIPO_Write(Unit *unit, const uint8_t *buffer, uint16_t buflen) } } + // load the final data - this may be used by some other circuitry or + // simply to rest the lines at a defined known level + uint16_t spread = pinmask_spread(terminal_data, mask); + priv->data_port->BSRR = spread | (((~spread) & mask) << 16); + send_pulse(priv->store_pol, priv->store_port, priv->store_ll); return E_SUCCESS; } diff --git a/units/sipo/_sipo_internal.h b/units/sipo/_sipo_internal.h index 28b5c2e..334577c 100644 --- a/units/sipo/_sipo_internal.h +++ b/units/sipo/_sipo_internal.h @@ -79,9 +79,10 @@ void USIPO_deInit(Unit *unit); * @param unit * @param buffer - buffer of data to send * @param buflen - number of bytes in the buffer + * @param terminal_data - data to set before sending the store pulse (final data lines state, will not appear in the SIPOs) * @return success */ -error_t UU_SIPO_Write(Unit *unit, const uint8_t *buffer, uint16_t buflen); +error_t UU_SIPO_Write(Unit *unit, const uint8_t *buffer, uint16_t buflen, uint16_t terminal_data); /** * Direct access to the output data pins (may be useful for debugging, or circuits that use them diff --git a/units/sipo/_sipo_settings.c b/units/sipo/_sipo_settings.c index fcd6343..52c3a88 100644 --- a/units/sipo/_sipo_settings.c +++ b/units/sipo/_sipo_settings.c @@ -103,11 +103,11 @@ void USIPO_writeIni(Unit *unit, IniWriter *iw) { struct priv *priv = unit->data; - iw_comment(iw, "Shift pin & its active edge"); + iw_comment(iw, "Shift pin & its active edge (1-rising,0-falling)"); iw_entry(iw, "shift-pin", "%c%d", priv->shift_pname, priv->shift_pnum); iw_entry(iw, "shift-pol", "%d", priv->shift_pol); - iw_comment(iw, "Store pin & its active edge (1-rising,0-falling)"); + iw_comment(iw, "Store pin & its active edge"); iw_entry(iw, "store-pin", "%c%d", priv->store_pname, priv->store_pnum); iw_entry(iw, "store-pol", "%d", priv->store_pol); diff --git a/units/sipo/unit_sipo.c b/units/sipo/unit_sipo.c index a96d900..d48cb1b 100644 --- a/units/sipo/unit_sipo.c +++ b/units/sipo/unit_sipo.c @@ -26,8 +26,9 @@ static error_t USIPO_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, case CMD_WRITE: { uint32_t len; + uint16_t terminal_packed = pp_u16(pp); const uint8_t *tail = pp_tail(pp, &len); - TRY(UU_SIPO_Write(unit, (uint8_t *) tail, (uint16_t) len)); + TRY(UU_SIPO_Write(unit, (uint8_t *) tail, (uint16_t) len, terminal_packed)); } return E_SUCCESS; diff --git a/utils/ini_writer.c b/utils/ini_writer.c index ab4e83d..2a9a4e6 100644 --- a/utils/ini_writer.c +++ b/utils/ini_writer.c @@ -119,9 +119,10 @@ void iw_entry(IniWriter *iw, const char *key, const char *format, ...) iw_newline(iw); // one newline after entry } -uint32_t iw_measure_total(void (*handler)(IniWriter *)) +uint32_t iw_measure_total(void (*handler)(IniWriter *), uint32_t tag) { IniWriter iw = iw_init(NULL, 0xFFFFFFFF, 1); + iw.tag = tag; iw_begin(); handler(&iw); iw_end(); diff --git a/utils/ini_writer.h b/utils/ini_writer.h index 7212de9..c9b8cfa 100644 --- a/utils/ini_writer.h +++ b/utils/ini_writer.h @@ -18,6 +18,7 @@ typedef struct iniwriter_ { char *ptr; uint32_t skip; uint32_t count; + uint32_t tag; // general purpose field (used to identify for which purpose is the file being read) } IniWriter; /** @@ -43,7 +44,7 @@ void iw_end(void); * @param count - number of bytes to write, truncate rest * @return structure initializer */ -#define iw_init(buffer, skip, count) (IniWriter){buffer, skip, count} +#define iw_init(xbuffer, xskip, xcount) (IniWriter){.ptr=(xbuffer), .skip=(xskip), .count=(xcount)} /** * Try to write a buffer to the file @@ -131,6 +132,6 @@ void iw_entry(IniWriter *iw, const char *key, const char *format, ...) * @param handler - function that normally writes to the writer * @return byte count */ -uint32_t iw_measure_total(void (*handler)(IniWriter *)); +uint32_t iw_measure_total(void (*handler)(IniWriter *), uint32_t tag); #endif //INIWRITER_H diff --git a/vfs/vfs_user.c b/vfs/vfs_user.c index cad2cee..d0b2809 100644 --- a/vfs/vfs_user.c +++ b/vfs/vfs_user.c @@ -73,9 +73,9 @@ void vfs_user_build_filesystem(void) // Setup the filesystem based on target parameters vfs_init(daplink_drive_name, 0/*unused "disk size"*/); - vfs_create_file("UNITS INI", read_file_units_ini, NULL, iw_measure_total(settings_build_units_ini)); - vfs_create_file("SYSTEM INI", read_file_system_ini, NULL, iw_measure_total(settings_build_system_ini)); - vfs_create_file("PINOUT TXT", read_file_pinout_txt, NULL, iw_measure_total(settings_build_pinout_txt)); + vfs_create_file("UNITS INI", read_file_units_ini, NULL, iw_measure_total(settings_build_units_ini, 0)); + vfs_create_file("SYSTEM INI", read_file_system_ini, NULL, iw_measure_total(settings_build_system_ini, 0)); + vfs_create_file("PINOUT TXT", read_file_pinout_txt, NULL, iw_measure_total(settings_build_pinout_txt, 0)); }