Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
6828423fcThis file is pinned to the selected release. Download the original to open it in your design tool.
/*
* This file is part of the stmbl project.
*
* Copyright (C) 2013-2015 Rene Hopf <renehopf@mac.com>
* Copyright (C) 2013-2015 Nico Stute <crinq@crinq.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <math.h>
#include "hal.h"
//global hal struct
hal_struct_t hal;
char* itoa(int i){
hal.tmp[0] = (i % 10) + '0';
hal.tmp[1] = '\0';
return(hal.tmp);
}
void hal_init(){
hal.comp_type_count = 0;
for(int i = 0; i < MAX_COMP_TYPES; i++){
hal.comp_types_counter[i] = 0;
}
hal.hal_pin_count = 0;
hal.comp_count = 0;
hal.nrt_init_func_count = 0;
hal.rt_func_count = 0;
hal.nrt_func_count = 0;
hal.frt_func_count = 0;
hal.link_errors = 0;
hal.pin_errors = 0;
hal.set_errors = 0;
hal.get_errors = 0;
hal.comp_errors = 0;
hal.rt_state = RT_STOP;
hal.frt_state = FRT_STOP;
hal.hal_state = HAL_OK;
hal.active_rt_func = -1;
hal.active_frt_func = -1;
hal.active_nrt_func = -1;
strcpy(hal.error_name,"no error");
}
void hal_comp_init(){
for(int i = 0; i < hal.nrt_init_func_count; i++){ // run nrt init
hal.nrt_init[i]();
}
}
void hal_run_nrt(float period){
//run all non realtime hal functions
for(hal.active_nrt_func = 0; hal.active_nrt_func < hal.nrt_func_count; hal.active_nrt_func++){
hal.nrt[hal.active_nrt_func](period);
}
hal.active_nrt_func = -1;
}
void hal_run_rt(float period){
//run all realtime hal functions
for(hal.active_rt_func = 0; hal.active_rt_func < hal.rt_func_count; hal.active_rt_func++){
hal.rt[hal.active_rt_func](period);
}
hal.active_rt_func = -1;
}
void hal_run_frt(float period){
//run all fast realtime hal functions
for(hal.active_frt_func = 0; hal.active_frt_func < hal.frt_func_count; hal.active_frt_func++){
hal.frt[hal.active_frt_func](period);
}
hal.active_frt_func = -1;
}
int hal_start_rt(){
if(hal.rt_state == RT_STOP && hal.hal_state == HAL_OK){
hal.active_rt_func = -1;
hal.rt_state = RT_SLEEP;
return(1);
}
return(0);
}
//TODO: crashes when hal is already running?
void hal_start(){
float min = INFINITY;
int min_index = -1;
float rt_prio = 0.0;
float frt_prio = 0.0;
char added[MAX_COMPS];
for(int i = 0; i < MAX_COMPS; i++){
added[i] = 0;
}
// add rt func
hal.rt_func_count = 0;
for(int i = 0; i < hal.comp_count; i++){
min = INFINITY;
min_index = -1;
for(int j = hal.comp_count - 1; j >= 0; j--){
rt_prio = hal.hal_pins[hal.hal_comps[j]->hal_pin_start_index + 2]->source->source->value;
if(rt_prio <= min && added[j] == 0 && rt_prio >= 0.0 && hal.hal_comps[j]->rt != 0){
min = rt_prio;
min_index = j;
}
}
if(min_index >= 0){
added[min_index] = 1;
hal.rt[hal.rt_func_count++] = hal.hal_comps[min_index]->rt;
}
}
for(int i = 0; i < hal.comp_count; i++){
added[i] = 0;
}
// add frt func
hal.frt_func_count = 0;
for(int i = 0; i < hal.comp_count; i++){
min = INFINITY;
min_index = -1;
for(int j = hal.comp_count - 1; j >= 0; j--){
frt_prio = hal.hal_pins[hal.hal_comps[j]->hal_pin_start_index + 3]->source->source->value;
if(frt_prio <= min && added[j] == 0 && frt_prio >= 0.0 && hal.hal_comps[j]->frt != 0){
min = frt_prio;
min_index = j;
}
}
if(min_index >= 0){
added[min_index] = 1;
hal.frt[hal.frt_func_count++] = hal.hal_comps[min_index]->frt;
}
}
// add (de)init func
hal.rt_init_func_count = 0;
hal.rt_deinit_func_count = 0;
for(int i = 0; i < hal.comp_count; i++){
rt_prio = hal.hal_pins[hal.hal_comps[i]->hal_pin_start_index + 2]->source->source->value;
frt_prio = hal.hal_pins[hal.hal_comps[i]->hal_pin_start_index + 3]->source->source->value;
if(rt_prio >= 0.0 || frt_prio >= 0.0){
if(hal.hal_comps[i]->rt_init != 0){
hal.rt_init[hal.rt_init_func_count++] = hal.hal_comps[i]->rt_init;
}
if(hal.hal_comps[i]->rt_deinit != 0){
hal.rt_deinit[hal.rt_deinit_func_count++] = hal.hal_comps[i]->rt_deinit;
}
}
}
for(int i = 0; i < hal.rt_init_func_count; i++){
hal.rt_init[i]();
}
hal_start_rt();
if(hal.frt_func_count > 0){
hal_start_frt();
hal_enable_frt();
}
hal_enable_rt();
}
void hal_stop(){
hal_stop_frt();
hal_stop_rt();
hal_disable_frt();
hal_disable_rt();
for(; hal.rt_deinit_func_count > 0; hal.rt_deinit_func_count--){
hal.rt_deinit[hal.rt_deinit_func_count - 1]();
}
}
int hal_start_frt(){
if(hal.frt_state == FRT_STOP && hal.hal_state == HAL_OK){
hal.active_frt_func = -1;
hal.frt_state = FRT_SLEEP;
return(1);
}
return(0);
}
void hal_stop_rt(){
hal.active_rt_func = -1;
hal.rt_state = RT_STOP;
hal.active_rt_func = -1;
hal.rt_state = RT_STOP;
}
void hal_stop_frt(){
hal.active_frt_func = -1;
hal.frt_state = FRT_STOP;
hal.active_frt_func = -1;
hal.frt_state = FRT_STOP;
}
void hal_init_pin(hal_name_t name, hal_pin_t* pin, float value){
strncpy(pin->name, hal.comp_types[hal.comp_type], HAL_NAME_LENGTH);
strncat(pin->name, itoa(hal.comp_types_counter[hal.comp_type]), HAL_NAME_LENGTH);
strncat(pin->name, ".", HAL_NAME_LENGTH);
strncat(pin->name, name, HAL_NAME_LENGTH);
pin->value = value;
pin->source = pin;
hal_register_pin(pin);
}
int hal_register_pin(hal_pin_t* pin){
if(hal.hal_pin_count >= MAX_HAL_PINS){
hal.pin_errors++;
return(0);
}
for(int i = 0; i < hal.hal_pin_count; i++){
if(!strcmp(hal.hal_pins[i]->name, pin->name)){
hal.pin_errors++;
return(0);
}
}
hal.hal_pins[hal.hal_pin_count] = pin;
hal.hal_pin_count++;
return(1);
}
int hal_set_pin(hal_name_t name, float value){
for(int i = 0; i < hal.hal_pin_count; i++){
if(!strcmp(hal.hal_pins[i]->name, name)){
hal.hal_pins[i]->value = value;
hal.hal_pins[i]->source = hal.hal_pins[i];
return(1);
}
}
strcpy(hal.error_name,name);
hal.set_errors++;
return(0);
}
int hal_is_pin(hal_name_t name){
for(int i = 0; i < hal.hal_pin_count; i++){
if(!strcmp(hal.hal_pins[i]->name, name)){
return(1);
}
}
return(0);
}
int hal_is_compname(hal_name_t name){
for(int i = 0; i < hal.hal_pin_count; i++){
if(!strncmp(hal.hal_pins[i]->name, name, strlen(name))){
return(1);
}
}
return(0);
}
float hal_get_pin(hal_name_t name){
for(int i = 0; i < hal.hal_pin_count; i++){
if(!strcmp(hal.hal_pins[i]->name, name)){
return(hal.hal_pins[i]->source->source->value);
}
}
hal.get_errors++;
return(0.0);
}
hal_pin_t hal_map_pin(hal_name_t name){
for(int i = 0; i < hal.hal_pin_count; i++){
if(!strcmp(hal.hal_pins[i]->name, name)){
return(*hal.hal_pins[i]);
}
}
return(*hal.hal_pins[0]);
}
void hal_write_pin(hal_pin_t* pin, float value){
pin->value = value;
pin->source = pin;
}
float hal_read_pin(hal_pin_t* pin){
return(pin->source->source->value);
}
hal_pin_t* hal_find_pin(hal_name_t name){
for(int i = 0; i < hal.hal_pin_count; i++){
if(!strcmp(hal.hal_pins[i]->name, name)){
return(hal.hal_pins[i]);
}
}
return(0);
}
int hal_link_pins(hal_name_t source, hal_name_t sink){
hal_pin_t* d;
hal_pin_t* s;
d = hal_find_pin(source);
s = hal_find_pin(sink);
if(d != 0 && s != 0){
s->value = s->source->source->value;
s->source = d;
return(1);
}
strcpy(hal.error_name,source);
hal.link_errors++;
return(0);
}
int hal_set_comp_type(hal_name_t name){
for(int i = 0; i < hal.comp_type_count; i++){
if(!strcmp(hal.comp_types[i], name)){
hal.comp_type = i;
return(hal.comp_types_counter[hal.comp_type]++);
}
}
if(hal.comp_type_count < MAX_COMP_TYPES){
strncpy(hal.comp_types[hal.comp_type_count], name, HAL_NAME_LENGTH);
hal.comp_type = hal.comp_type_count++;
return(0);
}
hal.comp_errors++;
return(-1);
}
void hal_add_comp(hal_comp_t* comp){
if(comp != 0 && hal.comp_count < MAX_COMPS){
hal.hal_comps[hal.comp_count++] = comp;
comp->instance = hal.comp_types_counter[hal.comp_type];
if(comp->nrt_init != 0){
hal.nrt_init[hal.nrt_init_func_count++] = comp->nrt_init;
}
if(comp->nrt != 0 && hal.nrt_func_count < MAX_COMPS){
hal.nrt[hal.nrt_func_count++] = comp->nrt;
}
}
else{
hal.comp_errors++;
}
}