diff --git a/inc/sserial.h b/inc/sserial.h index 4b9b594c..13c8ba2f 100644 --- a/inc/sserial.h +++ b/inc/sserial.h @@ -174,4 +174,5 @@ typedef struct { pd_metadata_t output_pins; pd_metadata_t fault; pd_metadata_t enable; + pd_metadata_t index_enable; } pd_table_t; diff --git a/tools/gentable.c b/tools/gentable.c new file mode 100644 index 00000000..96176501 --- /dev/null +++ b/tools/gentable.c @@ -0,0 +1,260 @@ +#include +#include +#include +#include + +#include "sserial.h" +#include "defines.h" + +memory_t memory; +uint8_t *heap_ptr; +uint32_t timeout; +pd_table_t pd_table; + +uint16_t add_pd(char *name_string, char *unit_string, uint8_t data_size_in_bits, uint8_t data_type, uint8_t data_dir, float param_min, float param_max) { + process_data_descriptor_t pdr; + pdr.record_type = RECORD_TYPE_PROCESS_DATA_RECORD; + pdr.data_size = data_size_in_bits; + pdr.data_type = data_type; + pdr.data_direction = data_dir; + pdr.param_min = param_min; + pdr.param_max = param_max; + pdr.data_addr = MEMPTR(*heap_ptr); + + heap_ptr += NUM_BYTES(data_size_in_bits); + // this aligns the heap pointer to 32bit. Not doing this causes the floats in the pd to be misaligned, which crashes the arm. + if((uint32_t)heap_ptr % 4) { + heap_ptr += 4 - (uint32_t)heap_ptr % 4; + } + + memcpy(heap_ptr, &pdr, sizeof(process_data_descriptor_t)); + // note that we don't store the names in the struct anymore. The fixed-length struct is copied into memory, and then the nmaes go in directly behind it, so they'll read out properly + + uint16_t pd_ptr = MEMPTR(*heap_ptr); // save off the ptr to return, before we modify the heap ptr + + heap_ptr = (uint8_t *)&(((process_data_descriptor_t *)heap_ptr)->names); + + // copy the strings in after the pd + strcpy((char *)heap_ptr, unit_string); + heap_ptr += strlen(unit_string) + 1; + + strcpy((char *)heap_ptr, name_string); + heap_ptr += strlen(name_string) + 1; + + // moved this up to before the pd record + /* + // this aligns the heap pointer to 32bit. Not doing this causes the floats in the pd to be misaligned, which crashes the arm. + if((uint32_t)heap_ptr % 4){ + heap_ptr += 4 - (uint32_t)heap_ptr % 4; + } + */ + + return pd_ptr; +} + +uint16_t add_mode(char *name_string, uint8_t index, uint8_t type) { + mode_descriptor_t mdr; + mdr.record_type = RECORD_TYPE_MODE_DATA_RECORD; + mdr.index = index; + mdr.type = type; //hw = 0, sw = 1 + mdr.unused = 0x00; + + memcpy(heap_ptr, &mdr, sizeof(mode_descriptor_t)); + + uint16_t md_ptr = MEMPTR(*heap_ptr); + + heap_ptr = (uint8_t *)&(((mode_descriptor_t *)heap_ptr)->names); + + strcpy((char *)heap_ptr, name_string); + heap_ptr += strlen(name_string) + 1; + + return md_ptr; +} + +void metadata(pd_metadata_t *pdm, process_data_descriptor_t *ptr) { + pdm->ptr = ptr; + pdm->range = ptr->data_type == DATA_TYPE_SIGNED ? MAX(ABS(ptr->param_min), ABS(ptr->param_max)) * 2 : ptr->param_max; + pdm->bitmax = (1 << ptr->data_size) - 1; +} + +void print_pd(process_data_descriptor_t* pd){ + int strl = strlen(&pd->names); + char* unit = &pd->names; + char* name = &pd->names+strl+1; + switch(pd->data_type){ + case DATA_TYPE_PAD: + printf("uint32_t padding : %u;\n",pd->data_size); + break; + case DATA_TYPE_BITS: + for(int i = 0;idata_size;i++){ + printf("uint32_t %s_%i : 1;\n",name,i); + } + break; + case DATA_TYPE_UNSIGNED: + case DATA_TYPE_SIGNED: + printf("sign/unsign\n"); + break; + case DATA_TYPE_FLOAT: + //TODO: check size + if(pd->data_size != 32){ + printf("warning: unsupported float size!"); + } + printf("float %s;\n",name); + break; + case DATA_TYPE_BOOLEAN: + printf("uint32_t %s : %u;\n",name,pd->data_size); + break; + case DATA_TYPE_NONVOL_UNSIGNED: + case DATA_TYPE_NONVOL_SIGNED: + case DATA_TYPE_STREAM: + case DATA_TYPE_ENCODER: + case DATA_TYPE_ENCODER_H: + case DATA_TYPE_ENCODER_L: + default: + printf("unsupported data type: 0x%02X\n",pd->data_type); + } +} + +int main(){ + + + + heap_ptr = memory.heap; + + uint16_t input_bits = 8; // this starts at 8 bits = 1 byte for the fault byte + uint16_t output_bits = 0; + + // these are temp toc arrays that the macros will write pointers into. the tocs get copied to main memory after everything else is written in + uint16_t ptoc[32]; + uint16_t gtoc[32]; + + uint16_t *ptocp = ptoc; + uint16_t *gtocp = gtoc; + process_data_descriptor_t *last_pd; + + + ADD_PROCESS_VAR(("pos_cmd", "rad", 32, DATA_TYPE_FLOAT, DATA_DIRECTION_OUTPUT, -INFINITY, INFINITY)); + metadata(&(pd_table.pos_cmd), last_pd); + ADD_PROCESS_VAR(("vel_cmd", "rad", 32, DATA_TYPE_FLOAT, DATA_DIRECTION_OUTPUT, -INFINITY, INFINITY)); + metadata(&(pd_table.vel_cmd), last_pd); + ADD_PROCESS_VAR(("output_pins", "none", 4, DATA_TYPE_BITS, DATA_DIRECTION_OUTPUT, 0, 1)); + metadata(&(pd_table.output_pins), last_pd); + ADD_PROCESS_VAR(("enable", "none", 1, DATA_TYPE_BOOLEAN, DATA_DIRECTION_OUTPUT, 0, 1)); + metadata(&(pd_table.enable), last_pd); + + ADD_PROCESS_VAR(("pos_fb", "rad", 32, DATA_TYPE_FLOAT, DATA_DIRECTION_INPUT, -INFINITY, INFINITY)); + metadata(&(pd_table.pos_fb), last_pd); + ADD_PROCESS_VAR(("vel_fb", "rad", 32, DATA_TYPE_FLOAT, DATA_DIRECTION_INPUT, -INFINITY, INFINITY)); + metadata(&(pd_table.vel_fb), last_pd); + ADD_PROCESS_VAR(("input_pins", "none", 4, DATA_TYPE_BITS, DATA_DIRECTION_INPUT, -100, 100)); + metadata(&(pd_table.input_pins), last_pd); + ADD_PROCESS_VAR(("fault", "none", 1, DATA_TYPE_BOOLEAN, DATA_DIRECTION_INPUT, 0, 1)); + metadata(&(pd_table.fault), last_pd); + ADD_PROCESS_VAR(("index_enable", "none", 1, DATA_TYPE_BOOLEAN, DATA_DIRECTION_BI_DIRECTIONAL, 0, 1)); + metadata(&(pd_table.index_enable), last_pd); + + + //ADD_PROCESS_VAR(("pos_cmd", "rad", 32, DATA_TYPE_FLOAT, DATA_DIRECTION_OUTPUT, -INFINITY, INFINITY)); + //metadata(&(pd_table.pos_cmd), last_pd); + + // ADD_PROCESS_VAR(("output_pins", "none", 4, DATA_TYPE_BITS, DATA_DIRECTION_OUTPUT, 0, 1)); + // metadata(&(pd_table.output_pins), last_pd); + // ADD_PROCESS_VAR(("enable", "none", 1, DATA_TYPE_BOOLEAN, DATA_DIRECTION_OUTPUT, 0, 1)); + // metadata(&(pd_table.enable), last_pd); + + + + //ADD_PROCESS_VAR(("pos_fb", "rad", 32, DATA_TYPE_FLOAT, DATA_DIRECTION_INPUT, -INFINITY, INFINITY)); + //metadata(&(pd_table.pos_fb), last_pd); + + // ADD_PROCESS_VAR(("input_pins", "none", 4, DATA_TYPE_BITS, DATA_DIRECTION_INPUT, -100, 100)); + // metadata(&(pd_table.input_pins), last_pd); + // ADD_PROCESS_VAR(("fault", "none", 1, DATA_TYPE_BOOLEAN, DATA_DIRECTION_INPUT, 0, 1)); + // metadata(&(pd_table.fault), last_pd); + + //globals and modes are not working. https://github.com/LinuxCNC/linuxcnc/blob/2957cc5ad0a463c39fb35c10a0c14909c09a5fb7/src/hal/drivers/mesa-hostmot2/sserial.c#L1516 + // - globals need write support + // - linuxcnc only supports globals of type DATA_TYPE_NONVOL_UNSIGNED or DATA_TYPE_NONVOL_SIGNED + //ADD_GLOBAL_VAR(("swr", "non", 8, DATA_TYPE_NONVOL_UNSIGNED, DATA_DIRECTION_OUTPUT, 0, 0)); + + //ADD_MODE(("foo", 0, 0)); + ADD_MODE(("Position mode", 0, 1)); + + // automatically create padding pds based on the mod remainder of input/output bits + if(input_bits % 8) + ADD_PROCESS_VAR(("padding", "", 8 - (input_bits % 8), DATA_TYPE_PAD, DATA_DIRECTION_INPUT, 0, 0)); + if(output_bits % 8) + ADD_PROCESS_VAR(("padding", "", 8 - (output_bits % 8), DATA_TYPE_PAD, DATA_DIRECTION_OUTPUT, 0, 0)); + + // now that all the toc entries have been added, write out the tocs to memory and set up the toc pointers + + //calculate bytes from bits + memory.discovery.input = input_bits >> 3; + memory.discovery.output = output_bits >> 3; + + memory.discovery.ptocp = MEMPTR(*heap_ptr); + + for(uint8_t i = 0; i < ptocp - ptoc; i++) { + *heap_ptr++ = ptoc[i] & 0x00FF; + *heap_ptr++ = (ptoc[i] & 0xFF00) >> 8; + } + // this is the ptoc end marker + *heap_ptr++ = 0x00; + *heap_ptr++ = 0x00; + + memory.discovery.gtocp = MEMPTR(*heap_ptr); + + for(uint8_t i = 0; i < gtocp - gtoc; i++) { + *heap_ptr++ = gtoc[i] & 0x00FF; + *heap_ptr++ = (gtoc[i] & 0xFF00) >> 8; + } + // this is the gtoc end marker + *heap_ptr++ = 0x00; + *heap_ptr++ = 0x00; + + // printf("gtoc:%u\n",memory.discovery.gtocp); + // printf("ptoc:%u\n",memory.discovery.ptocp); + // printf("%i\n",sizeof(memory_t)); + //printf("%u\n",MEMPTR(*heap_ptr)); + int nl = 0; + printf("uint8_t sserial_slave[] = {\n"); + for(int i = 0;i < MEMPTR(*heap_ptr);i++){ + //printf("%u %c\n",memory.bytes[i],memory.bytes[i]); + printf("0x%02X,",memory.bytes[i]); + nl++; + if(nl > 7){ + nl = 0; + printf("\n"); + } + } + printf("\n};\n"); + printf("uint16_t sserial_ptocp = 0x%04X;\n",memory.discovery.ptocp); + printf("uint16_t sserial_gtocp = 0x%04X;\n",memory.discovery.gtocp); + printf("\n"); + printf("typedef struct {\n"); + ptocp = (uint16_t *)(memory.bytes + memory.discovery.ptocp); + while(*ptocp != 0x0000) { + process_data_descriptor_t *pd = (process_data_descriptor_t *)(memory.bytes + *ptocp++); + //printf("0x%02X\n",pd->data_direction); + if((pd->data_direction == DATA_DIRECTION_OUTPUT || pd->data_direction == DATA_DIRECTION_BI_DIRECTIONAL) && pd->record_type == RECORD_TYPE_PROCESS_DATA_RECORD){ + print_pd(pd); + } + // printf("pd has data at %x with value %x\n", pd->data_addr, MEMU16(pd->data_addr)); + } + printf("} sserial_out_process_data_t; //size:%u bytes\n",memory.discovery.output); + printf("_Static_assert(sizeof(sserial_out_process_data_t) == %u, \"sserial_out_process_data_t size error!\");\n",memory.discovery.output); + printf("\n"); + printf("typedef struct {\n"); + ptocp = (uint16_t *)(memory.bytes + memory.discovery.ptocp); + while(*ptocp != 0x0000) { + process_data_descriptor_t *pd = (process_data_descriptor_t *)(memory.bytes + *ptocp++); + //printf("0x%02X\n",pd->data_direction); + if((pd->data_direction == DATA_DIRECTION_INPUT || pd->data_direction == DATA_DIRECTION_BI_DIRECTIONAL) && pd->record_type == RECORD_TYPE_PROCESS_DATA_RECORD){ + print_pd(pd); + } + // printf("pd has data at %x with value %x\n", pd->data_addr, MEMU16(pd->data_addr)); + } + printf("} sserial_in_process_data_t; //size:%u bytes\n",memory.discovery.input-1); + printf("_Static_assert(sizeof(sserial_in_process_data_t) == %u, \"sserial_in_process_data_t size error!\");\n",memory.discovery.input-1); + +} \ No newline at end of file