avr-fw-modules/core/src/runtime_register_proc.c

614 lines
13 KiB
C

#include <hwo/runtime.h>
#include <sys/time.h>
#include <sys/outputs.h>
#include <sys/assert.h>
#include <rb2/regbus.h>
#include <hwo/logcsr.h>
#include <sys/dbg.h>
#define WEAK __attribute__((weak))
#define IFNOTWEAK(v) ((&v == NULL) ? 0 : (v))
#define SETNOTWEAK(v,a) { if (&v != NULL) v = a; }
extern uint8_t* __brkval;
LogCSR *csrbuffer;
uint16_t dbgPtr;
uint32_t lasterror;
uint8_t dummy_can_usage(void){
return 0;
};
uint8_t can_usage(void) __attribute__((weak,alias("dummy_can_usage")));
extern int32_t _dbg_jetcan_requests WEAK,
_dbg_jetcan_misses WEAK,
_dbg_jetcan_timeouts WEAK,
_dbg_jetcan_rtt WEAK,
_dbg_jetcan_rtt_min WEAK,
_dbg_jetcan_rtt_max WEAK;
int rt_node_proc(int op,int regno,uint8_t *type,void *buffer){
uint16_t ui16;
switch (op & RNPOP_MASK){
case RNPOP_READ:
if ((regno >= 0x00F0) && (regno < 0x0100))
{
csrbuffer = get_csr_log();
*(int32_t*)buffer = (int32_t)csrbuffer->mcucsr[ regno & 0x0F];
return 0;
};
if ((regno >= 0x8600) && (regno < 0x8700))
{
ui16 = (regno & 0xFF);
*(int32_t*)buffer = output_read( ui16 );
return 0;
};
if ((regno >= 0x8700) && (regno < 0x8800))
{
ui16 = (regno & 0xFF);
if (*type & RDT_FLOAT){
*(float*)buffer = fp4816_to_float( output_current(ui16) );
} else{
*(int32_t*)buffer = output_current(ui16)>>16;
};
return 0;
};
if ((regno >= 0xA000) && (regno < 0xB000))
{
*(int32_t*)buffer = *(int32_t*)(regno & 0x0FFF);
return 0;
};
if ((regno >= 0xB000) && (regno < 0xB100))
{
list_t *l = _threading_threads.next;
thread_t *thread;
ui16 = (regno >> 4) & 0x0F;
while ((l != &_threading_threads) && (ui16--)){
l = l->next;
};
thread = (thread_t*)l;
if (&(thread->list) != &_threading_threads){
switch (regno & 0x0F){
case 0:
*(int32_t*)buffer = (uint32_t)(unsigned int)thread;
break;
case 1:
*(int32_t*)buffer = ((int)(thread->start))<<1;
break;
case 2:
*(int32_t*)buffer = (int)(thread->stack.base);
break;
case 3:
*(int32_t*)buffer = (int)(thread->stack.size);
break;
case 4:
*(int32_t*)buffer = (int)(thread->stack.stackpointer);
break;
case 5:
*(int32_t*)buffer = (int)(thread->stack.min_free);
break;
case 6:
*(int32_t*)buffer = thread->statistic.scheduled_time.seconds;
break;
case 7:
*(int32_t*)buffer = thread->statistic.scheduled_time.cycles;
break;
default:
*(int32_t*)buffer = 0;
};
} else {
*(int32_t*)buffer = 0;
};
return 0;
};
switch (regno)
{
case 0x0001:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.eeprom.serial.code,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x0002:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.flags.code,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x0003:
rb2_convert(
RDT_INT8,
(void*)&rt_ram.accesscode.accessmask,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x0004:
rb2_convert(
RDT_INT16,
(void*)&rt_ram.accesscode.servicepartner,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x0005:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.eeprom.last_auth,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x0006:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.eeprom.count_poweron,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x0007:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.eeprom.secs_powered,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x0008:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.eeprom.secs_running,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x0009:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.eeprom.next_service,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x000A:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.eeprom.service_partner,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x000B:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.eeprom.service_set_time,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x000C:
*(int32_t*)buffer = runtime_is_running();
*type = RDT_INT32;
return 0;
case 0x000E:
*(int32_t*)buffer = (&__rb2_instance)->axes;
*type = RDT_INT32;
return 0;
case 0x000F:
*(int32_t*)buffer = rb2_known_endpoints();
*type = RDT_INT32;
return 0;
case 0x0018:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.identity.hardware_id,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x0019:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.identity.hardware_revision,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x001A:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.identity.software_revision,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x001B:
rb2_convert(
RDT_INT32,
(void*)&rt_ram.identity.functional_groups,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x001C:
*(int32_t*)buffer = unixtime();
return 0;
case 0x0020:
rb2_convert(
RDT_INT16,
(void*)&__brkval,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x0021:
*(int32_t*)buffer = (int32_t)(int)__malloc_heap_end;
return 0;
case 0x0022:
rb2_convert(
RDT_INT32,
(void*)&_systick_secs,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x0023:
*(int32_t*)buffer = rt_dbg->atomic_ip;
return 0;
case 0x0024:
*(int32_t*)buffer = rt_dbg->spinlock_ip;
return 0;
case 0x0025:
*(int32_t*)buffer = _assert_current();
return 0;
case 0x0026:
*(int32_t*)buffer = _assert_current_error();
return 0;
case 0x0027:
*(int32_t*)buffer = systick_ticks() & 0x7FFFFFFFul;
return 0;
#if defined(DEBUG_SCHEDULING)
case 0x0050:
*(int32_t*)buffer = _ts_sys_time.seconds;
return 0;
case 0x0051:
*(int32_t*)buffer = _ts_sys_time.cycles;
return 0;
case 0x0052:
*(int32_t*)buffer = _ts_irq_time.seconds;
return 0;
case 0x0053:
*(int32_t*)buffer = _ts_irq_time.cycles;
return 0;
case 0x0054:
*(int32_t*)buffer = _ts_timer_resolution;
return 0;
case 0x0055:
*(int32_t*)buffer = _ts_timer_cycles_per_increment;
return 0;
case 0x0056:
*(int32_t*)buffer = _ts_timer_increments_per_second;
return 0;
case 0x0057:
*(int32_t*)buffer = __freq_cpu;
return 0;
case 0x0058:
*(int32_t*)buffer = _st_lag_current;
return 0;
case 0x0059:
*(int32_t*)buffer = _st_lag_min;
return 0;
case 0x005A:
*(int32_t*)buffer = _st_lag_max;
return 0;
case 0x005B:
*(int32_t*)buffer = ((uint32_t)rt_dbg->last_late_vect[0] << 1) | ((uint32_t)rt_dbg->last_late_vect[1] << 17);
return 0;
case 0x005C:
*(int32_t*)buffer = ((uint32_t)rt_dbg->last_late_vect[2] << 1) | ((uint32_t)rt_dbg->last_late_vect[3] << 17);;
return 0;
#endif
case 0x005D:
*(int32_t*)buffer = _dbg_rb2_usart_sync;
return 0;
case 0x005E:
*(int32_t*)buffer = _dbg_rb2_usart_sync_min;
return 0;
case 0x005F:
*(int32_t*)buffer = _dbg_rb2_usart_sync_max;
return 0;
case 0x0060:
*(int32_t*)buffer = _dbg_rb2_usart_rxtele;
return 0;
case 0x0061:
*(int32_t*)buffer = _dbg_rb2_usart_txtele;
return 0;
case 0x0062:
*(int32_t*)buffer = IFNOTWEAK(_dbg_jetcan_requests);
return 0;
case 0x0063:
*(int32_t*)buffer = IFNOTWEAK(_dbg_jetcan_timeouts);
return 0;
case 0x0064:
*(int32_t*)buffer = IFNOTWEAK(_dbg_jetcan_rtt);
return 0;
case 0x0065:
*(int32_t*)buffer = IFNOTWEAK(_dbg_jetcan_rtt_min);
return 0;
case 0x0066:
*(int32_t*)buffer = IFNOTWEAK(_dbg_jetcan_rtt_max);
return 0;
case 0x0067:
*(int32_t*)buffer = IFNOTWEAK(_dbg_jetcan_misses);
return 0;
case 0x00E9:
*(int32_t*)buffer = can_usage();
return 0;
case 0x00EA:
rb2_convert(
RDT_INT32,
(void*)&lasterror,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x00EB:
rb2_convert(
RDT_INT16,
(void*)&dbgPtr,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x00EC:
rb2_convert(
RDT_INT8,
(void*)dbgPtr,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x00ED:
rb2_convert(
RDT_INT16,
(void*)dbgPtr,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x00EE:
rb2_convert(
RDT_INT32,
(void*)dbgPtr,
*type,
&*(int32_t*)buffer
);
return 0;
case 0x00EF:
csrbuffer = get_csr_log();
*(int32_t*)buffer = (int32_t)csrbuffer->wp;
return 0;
};
break;
case RNPOP_WRITE:
if ((regno >= 0x8600) && (regno < 0x8700))
{
ui16 = (regno & 0xFF);
if (*(int32_t*)buffer){
output_on(ui16);
} else {
output_off(ui16);
};
return 0;
};
if ((regno >= 0xA000) && (regno < 0xB000))
{
*(int32_t*)(regno & 0x0FFF) = *(int32_t*)buffer;
return 0;
};
switch (regno)
{
case 0x0001:
if (rt_authorized(RTA_MANUFACT1)) {
rb2_convert(
*type,
&*(int32_t*)buffer,
RDT_INT32,
(void*)&rt_ram.eeprom.serial.code
);
return 0;
};
case 0x0004:
rt_authenticate( *(int32_t*)buffer );
return 0;
case 0x0006:
if (rt_authorized(RTA_MANUFACT1)) {
rb2_convert(
*type,
&*(int32_t*)buffer,
RDT_INT32,
(void*)&rt_ram.eeprom.count_poweron
);
return 0;
};
case 0x0007:
if (rt_authorized(RTA_MANUFACT1)) {
rb2_convert(
*type,
&*(int32_t*)buffer,
RDT_INT32,
(void*)&rt_ram.eeprom.secs_powered
);
return 0;
};
case 0x0008:
if (rt_authorized(RTA_MANUFACT1)) {
rb2_convert(
*type,
&*(int32_t*)buffer,
RDT_INT32,
(void*)&rt_ram.eeprom.secs_running
);
return 0;
};
case 0x0009:
if (rt_authorized(RTA_SERVICE2)) {
rb2_convert(
*type,
&*(int32_t*)buffer,
RDT_INT32,
(void*)&rt_ram.eeprom.next_service
);
runtime_signal();
rt_ram.eeprom.service_set_time = rt_ram.eeprom.secs_powered;
rt_ram.eeprom.service_partner = rt_ram.accesscode.servicepartner;
runtime_signal();
return 0;
};
case 0x000C:
runtime_set_running( *(int32_t*)buffer ? 1 : 0 );
return 0;
case 0x001C:
unixtime_set( *(int32_t*)buffer );
return 0;
case 0x0025:
_assert_read();
return 0;
#if defined(DEBUG_SCHEDULING)
case 0x0059:
_st_lag_min = *(int32_t*)buffer;
return 0;
case 0x005A:
_st_lag_max = *(int32_t*)buffer;
return 0;
#endif
case 0x005D:
_dbg_rb2_usart_sync = *(int32_t*)buffer;
return 0;
case 0x005E:
_dbg_rb2_usart_sync_min = *(int32_t*)buffer;
return 0;
case 0x005F:
_dbg_rb2_usart_sync_max = *(int32_t*)buffer;
return 0;
case 0x0060:
_dbg_rb2_usart_rxtele = *(int32_t*)buffer;
return 0;
case 0x0061:
_dbg_rb2_usart_txtele = *(int32_t*)buffer;
return 0;
case 0x0062:
SETNOTWEAK(_dbg_jetcan_requests, *(int32_t*)buffer);
return 0;
case 0x0063:
SETNOTWEAK(_dbg_jetcan_timeouts, *(int32_t*)buffer);
return 0;
case 0x0064:
SETNOTWEAK(_dbg_jetcan_rtt, *(int32_t*)buffer);
return 0;
case 0x0065:
SETNOTWEAK(_dbg_jetcan_rtt_min, *(int32_t*)buffer);
return 0;
case 0x0066:
SETNOTWEAK(_dbg_jetcan_rtt_max, *(int32_t*)buffer);
return 0;
case 0x0067:
SETNOTWEAK(_dbg_jetcan_misses, *(int32_t*)buffer);
return 0;
case 0x00EB:
if (rt_authorized(RTA_DEVELOPER)) {
rb2_convert(
*type,
&*(int32_t*)buffer,
RDT_INT16,
(void*)&dbgPtr
);
return 0;
};
case 0x00EC:
if (rt_authorized(RTA_DEVELOPER)) {
rb2_convert(
*type,
&*(int32_t*)buffer,
RDT_INT8,
(void*)dbgPtr
);
return 0;
};
case 0x00ED:
if (rt_authorized(RTA_DEVELOPER)) {
rb2_convert(
*type,
&*(int32_t*)buffer,
RDT_INT16,
(void*)dbgPtr
);
return 0;
};
case 0x00EE:
if (rt_authorized(RTA_DEVELOPER)) {
rb2_convert(
*type,
&*(int32_t*)buffer,
RDT_INT32,
(void*)dbgPtr
);
return 0;
};
};
break;
default:
return -EPARAM;
};
return -ENOFILE;
};
uint8_t runtime_register_proc(RB2_REGISTER *regno,RB2_TELEGRAM *telegram)
{
uint8_t t = telegram->flags.type;
return rt_node_proc( telegram->flags.read ? RNPOP_READ : RNPOP_WRITE, telegram->regno, &t, &telegram->i32);
};