Skip to content
Snippets Groups Projects
generate_digitalvariables.py 9.47 KiB
Newer Older
from digitalvariables import DigitalVariableList


def generate_digitalvariables_header(_digialvariables):

    # already included from analog variables
    #     includes = """
    # #include "../../alarms.h"
    # """
    includes = ''

    typedef = """
// digital reading info structure
typedef struct {
    digital_value_readfunc_t readfunc;    // function to read the value (must be defined by user)
    digital_value_t value;                // last acquired value
    digital_value_t value_max;            // max value acquired (...)
    digitalalarm_info_t alarm;            // structure maintaining all the info related to the alarm    
} digital_variable_t;
    """

    countdef = """
// number of defined analog variables
#define DIGITAL_VARIABLES_COUNT {}
    """.format(_digialvariables.count())

    extern = """
    
// make digital variable list available to anyone including this file
extern digital_variable_t digital_variables[DIGITAL_VARIABLES_COUNT];
"""

    ioread_tpl = """// IO read function for variable [name]
digital_value_t [readfunc](void);
"""
    varindex_tpl = """
#define DIGITAL_VARIABLE_INDEX_[varname]  [index]    // index of the analog variable [varname] inside analog_variables array"""

    varindex_contents = ''
    index = 0
    for variable in _digialvariables.entries():
        varindex_define = varindex_tpl
        varindex_define = varindex_define.replace('[varname]', variable.name)
        varindex_define = varindex_define.replace('[index]', str(index))
        index += 1
        varindex_contents += varindex_define

    utils_tpl = """
    
// some utility functions
digital_variable_t* digital_variable_get_pointer_by_enum(enum_variable_number_t _variable_index);
digitalalarm_info_t* alarm_get_digital_alarm_ptr_by_enum(enum_alarm_number_t _alarm_index);
    """

    header_contents = includes + typedef + countdef + varindex_contents + utils_tpl + extern

    # generate the prototypes for io read
    ioread_list = list()
    for digitalvariable in _digialvariables.entries():
        ioread_source = ioread_tpl
        ioread_source = ioread_source.replace('[name]', digitalvariable.name)
        ioread_source = ioread_source.replace('[readfunc]', digitalvariable.get_read_function_name())
        ioread_list.append(ioread_source)

    header_contents += '\n'
    header_contents += '\n'.join(ioread_list)

    return header_contents


def generate_digitalvariables_source(_digialvariables):

    entry_tpl = """// Variable: [name] ([description])
{
    .readfunc = [readfunc],
    .value = 0,
    .value_max = 0,
    .alarm = {
        .implement = [alarm_implement],
        .enabled = [alarm_enabled],
        .timeout = [alarm_timeout], // [alarm_timeout_comment]
        .timeout_counter = 0,
        .timeout_counter_max = 0,
        .firecount = 0,        
        .callback = [callback]
    }
}"""

    ioread_tpl = """
// IO read function for variable [name]
digital_value_t [readfunc](void) {
    return (digital_value_t)(0 != [ioname]_GetValue());
}
"""

    ioread_tpl_active_low = """
// IO read function for variable [name] (active low)
digital_value_t [readfunc](void) {
    return (digital_value_t)(0 == [ioname]_GetValue());
}
"""

    source_list = list()
    ioread_list = list()
    for digitalvariable in _digialvariables.entries():

        if digitalvariable.alarm:
            alarm_timeout = digitalvariable.get_alarm_timeout_ticks()
            alarm_timeout_ms = digitalvariable.get_alarm_timeout_actual_ms()
            callback = digitalvariable.get_alarm_callback_name()
            if digitalvariable.alarm.enable_default is None:
                alarm_enabled_value = 'DEFAULT_' + digitalvariable.name + '_ALARM_ENABLED'
            elif digitalvariable.alarm.enable_default == True:
                alarm_enabled_value = 'true'
            elif digitalvariable.alarm.enable_default == False:
                alarm_enabled_value = 'false'
            else:
                assert False
        else:
            alarm_enabled_value = 'false'

        entry_source = entry_tpl
        entry_source = entry_source.replace('[name]', digitalvariable.name)
        entry_source = entry_source.replace('[description]', digitalvariable.description)
        entry_source = entry_source.replace('[readfunc]', digitalvariable.get_read_function_name())
        entry_source = entry_source.replace('[alarm_enabled]',alarm_enabled_value)

        if digitalvariable.alarm:
            entry_source = entry_source.replace('[alarm_implement]', 'true')
            entry_source = entry_source.replace('[alarm_timeout]', str(int(alarm_timeout)))
            entry_source = entry_source.replace('[alarm_timeout_comment]', '{} ms ({} ms real)'.format(digitalvariable.alarm.timeout_default_ms, alarm_timeout_ms))
            entry_source = entry_source.replace('[callback]', callback)
        else:
            entry_source = entry_source.replace('[alarm_implement]', 'false')
            entry_source = entry_source.replace('[alarm_timeout]', '0')
            entry_source = entry_source.replace('[alarm_timeout_comment]', 'alarm not present')
            entry_source = entry_source.replace('[callback]', 'dummy_alarm_callback')

        source_list.append(entry_source)

        if digitalvariable.active_low:
            ioread_source = ioread_tpl_active_low
        else:
            ioread_source = ioread_tpl
        ioread_source = ioread_source.replace('[name]', digitalvariable.name)
        ioread_source = ioread_source.replace('[readfunc]', digitalvariable.get_read_function_name())
        ioread_source = ioread_source.replace('[ioname]', digitalvariable.ioname)

        ioread_list.append(ioread_source)

    source_contents = ''
    # source_contents = '#include "variables.h"\n\n' # already included from analog variables...
    source_contents = '\n#include "../../mcc_generated_files/mcc.h"\n\n'
    source_contents += 'digital_variable_t digital_variables[DIGITAL_VARIABLES_COUNT] = {\n'
    source_contents += ','.join(source_list)
    source_contents += '};\n\n'

    # generate digital_variable_get_pointer_by_enum
    source_contents += 'digital_variable_t* digital_variable_get_pointer_by_enum(enum_variable_number_t _variable_index) {\n'
    source_contents += '    switch(_variable_index) {\n'
    for digitalvariable in _digialvariables.entries():
        source_contents += '        case VARIABLE_NUMBER_{}:\n'.format(digitalvariable.name)
        source_contents += '            return &(digital_variables[DIGITAL_VARIABLE_INDEX_{}]);\n'.format(digitalvariable.name)
    source_contents += '        default:\n'
    source_contents += '            error_die_forever();\n'
    source_contents += '            // should never be reached, just to avoid one warning\n'
    source_contents += '            return &(digital_variables[0]);\n'
    source_contents += '    }\n'
    source_contents += '}\n\n'

    # generate alarm_get_digital_alarm_ptr_by_enum
    source_contents += 'digitalalarm_info_t* alarm_get_digital_alarm_ptr_by_enum(enum_alarm_number_t _alarm_index) {'
    source_contents += '    switch(_alarm_index) {\n'
    for digitalvariable in _digialvariables.entries():
        if digitalvariable.alarm:
            source_contents += '        case ALARM_NUMBER_ALARM_{}:\n'.format(digitalvariable.name)
            source_contents += '            return &(digital_variables[DIGITAL_VARIABLE_INDEX_{}].alarm);\n'.format(digitalvariable.name)
    source_contents += '        default:\n'
    source_contents += '            error_die_forever();\n'
    source_contents += '            // should never be reached, just to avoid one warning\n'
    source_contents += '            return &(digital_variables[0].alarm);\n'
    source_contents += '    }\n'
    source_contents += '}\n\n'

    source_contents += '\n'.join(ioread_list)

    return source_contents


def generate_digitalalarm_callbacks_header(_digialvariables):
    alarm_callback_header_tpl = """
// Callback function for alarm on digital variable [name] ([description])
void [callback]();
"""
    source_list = list()
    for digitalvariable in _digialvariables.entries():
        if digitalvariable.alarm:
            source_list.append(
                alarm_callback_header_tpl
                    .replace('[name]', digitalvariable.name)
                    .replace('[description]', digitalvariable.description)
                    .replace('[callback]', digitalvariable.get_alarm_callback_name())
            )
    return ''.join(source_list)


def generate_digitalalarm_callbacks_source_template(_digialvariables):
    alarm_callback_source_tpl = """
// Callback function for alarm on analog variable [name] ([description])
void [callback]() {
    // TODO implement auto-generated callback function [callback]
}
"""
    source_list = list()
    for digitalvariable in _digialvariables.entries():
        if digitalvariable.alarm:
            source_list.append(
                alarm_callback_source_tpl
                    .replace('[name]', digitalvariable.name)
                    .replace('[description]', digitalvariable.description)
                    .replace('[callback]', digitalvariable.get_alarm_callback_name())
            )
    contents = '' # '#include "generated/sources/variables.h"\n' already included
    contents += ''.join(source_list)
    return contents


if __name__ == '__main__':
    digialvariables = DigitalVariableList()
    print generate_digitalvariables_header(digialvariables)
    print generate_digitalvariables_source(digialvariables)
    print generate_digitalalarm_callbacks_header(digialvariables)
    print generate_digitalalarm_callbacks_source_template(digialvariables)