sipo finished
This commit is contained in:
+2
-1
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
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);
|
||||
|
||||
@@ -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++;
|
||||
// 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++;
|
||||
}
|
||||
else {
|
||||
if (pUnit->callsign >= callsign) {
|
||||
callsign = (uint8_t) (pUnit->callsign + 1);
|
||||
}
|
||||
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, "=");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+2
-1
@@ -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();
|
||||
|
||||
+3
-2
@@ -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
|
||||
|
||||
+3
-3
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user