#include "endat_comp.h" #include "commands.h" #include "hal.h" #include "math.h" #include "defines.h" #include "angle.h" #include "stm32f4xx_conf.h" #include "hw/hw.h" #include #include HAL_COMP(endat); HAL_PIN(pos); HAL_PIN(mpos); HAL_PIN(f1); HAL_PIN(crc); HAL_PIN(shift); HAL_PIN(timer); HAL_PIN(swap); HAL_PIN(skip); HAL_PIN(bytes); HAL_PIN(error); HAL_PIN(state); HAL_PIN(endat_error); HAL_PIN(endat_warning); HAL_PIN(endat_state); HAL_PIN(pos_len); HAL_PIN(mpos_len); HAL_PIN(pos_res); HAL_PIN(type); HAL_PIN(max_vel); HAL_PIN(req); HAL_PIN(print_time); static void nrt_init(void *ctx_ptr, hal_pin_inst_t *pin_ptr) { // struct endat_ctx_t *ctx = (struct endat_ctx_t *)ctx_ptr; struct endat_pin_ctx_t *pins = (struct endat_pin_ctx_t *)pin_ptr; GPIO_InitTypeDef GPIO_InitStruct; //TX enable for mosi GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOD, &GPIO_InitStruct); //tx enable for clock GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOD, &GPIO_InitStruct); //SPI3 RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); SPI3->CR1 |= SPI_CR1_MSTR | SPI_CR1_CPOL | SPI_CR1_CPHA | SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_BIDIMODE | SPI_BaudRatePrescaler_32; //PC12 spi3 mosi //PC10 spi3 clock GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SPI3); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SPI3); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_SetBits(GPIOD, GPIO_Pin_10); //clock tx enable // DMA_InitTypeDef dma_rx_config; // dma_rx_config.DMA_Channel = DMA_Channel_0; // dma_rx_config.DMA_PeripheralBaseAddr = (uint32_t)&FB0_SPI->DR; // dma_rx_config.DMA_Memory0BaseAddr = (uint32_t)&tim_data; // dma_rx_config.DMA_DIR = DMA_DIR_PeripheralToMemory; // dma_rx_config.DMA_BufferSize = ARRAY_SIZE(tim_data); // dma_rx_config.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // dma_rx_config.DMA_MemoryInc = DMA_MemoryInc_Enable; // dma_rx_config.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // dma_rx_config.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord; // dma_rx_config.DMA_Mode = DMA_Mode_Normal; // dma_rx_config.DMA_Priority = DMA_Priority_VeryHigh; // dma_rx_config.DMA_FIFOMode = DMA_FIFOMode_Disable; // dma_rx_config.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; // dma_rx_config.DMA_MemoryBurst = DMA_MemoryBurst_Single; // dma_rx_config.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // DMA_Cmd(DMA1_Stream2, DISABLE); // DMA_DeInit(DMA1_Stream2); // DMA_Init(DMA1_Stream2, &dma_rx_config); PIN(pos_len) = 18; // 17 PIN(mpos_len) = 12; // 15 PIN(endat_state) = 13; PIN(swap) = 1; PIN(skip) = 10; PIN(bytes) = 7; } union{ uint64_t data; uint8_t dataa[8]; } df, df1, df2; endat_cmd_t req; struct endat_ctx_t { endat_data_t data; }; static void rt_func(float period, void *ctx_ptr, hal_pin_inst_t *pin_ptr) { struct endat_ctx_t *ctx = (struct endat_ctx_t *)ctx_ptr; struct endat_pin_ctx_t *pins = (struct endat_pin_ctx_t *)pin_ptr; req = 0; uint8_t addr = 0; ctx->data.pos_bits = PIN(pos_len); ctx->data.mpos_bits = PIN(mpos_len); switch((int)PIN(endat_state)){ case 0: // reset error req = ENDAT_RESET; break; case 1: // select mem state req = ENDAT_SELECT_MEM; addr = ENDAT_MEM_STATE; break; case 2: // read error req = ENDAT_READ_ADDR; addr = ENDAT_ADDR_ERROR; break; case 3: // read warning req = ENDAT_READ_ADDR; addr = ENDAT_ADDR_WARNING; break; case 4: // select mem 0 req = ENDAT_SELECT_MEM; addr = ENDAT_MEM_PARAM0; break; case 5: // read len req = ENDAT_READ_ADDR; addr = ENDAT_ADDR_POS_LEN; break; case 6: // read type req = ENDAT_READ_ADDR; addr = ENDAT_ADDR_TYPE; break; case 7: // select mem 1 req = ENDAT_SELECT_MEM; addr = ENDAT_MEM_PARAM1; break; case 8: // read multi req = ENDAT_READ_ADDR; addr = ENDAT_ADDR_MULTITURN; break; case 9: // read res low req = ENDAT_READ_ADDR; addr = ENDAT_ADDR_RES_LOW; break; case 10: // read res high req = ENDAT_READ_ADDR; addr = ENDAT_ADDR_RES_HIGH; break; case 11: // select mem 2 req = ENDAT_SELECT_MEM; addr = ENDAT_MEM_PARAM2; break; case 12: // read max vel req = ENDAT_READ_ADDR; addr = ENDAT_ADDR_MAX_VEL; break; case 13: // read pos req = ENDAT_READ_POS; break; } if(PIN(req) > 0){ req = PIN(req); } SPI3->CR1 &= ~SPI_CR1_SPE;//disable spi SPI3->CR1 = SPI_CR1_LSBFIRST | SPI_CR1_MSTR | SPI_CR1_CPOL | SPI_CR1_CPHA | SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_BIDIMODE | SPI_BaudRatePrescaler_32; uint32_t bits = endat_tx(req, addr, 0, df.dataa, &(ctx->data)); df2.data = df.data; GPIO_SetBits(GPIOD, GPIO_Pin_15);//tx enable SPI3->CR1 |= SPI_CR1_BIDIOE;//enable output SPI3->CR1 |= SPI_CR1_SPE;//enable spi for(int i = 0; i < (bits + 7) / 8; i++){ SPI3->DR = df.dataa[i]; while(!(SPI3->SR & SPI_SR_TXE)); while(SPI3->SR & SPI_SR_BSY); } SPI3->CR1 &= ~SPI_CR1_BIDIOE;//disable output, this activates the clock GPIO_ResetBits(GPIOD, GPIO_Pin_15);//tx disable SPI3->CR1 &= ~SPI_CR1_SPE;//disable spi if(PIN(swap) > 0.0){ SPI3->CR1 = SPI_CR1_LSBFIRST | SPI_CR1_MSTR | SPI_CR1_CPOL | SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_BIDIMODE | SPI_BaudRatePrescaler_32; } else{ SPI3->CR1 = SPI_CR1_LSBFIRST | SPI_CR1_MSTR | SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_BIDIMODE | SPI_BaudRatePrescaler_32; } SPI3->CR1 |= SPI_CR1_SPE;//enable spi df.data = 0; for(int i = 0; i < MIN(sizeof(df.data), PIN(bytes)); i++){ while(!(SPI3->SR & SPI_SR_RXNE)); df.dataa[i] = SPI3->DR; } df1.data = df.data >> (int)PIN(skip); PIN(shift) = PIN(skip); while((df1.data & 1) == 0 && PIN(shift) < 32.0){ df1.data = df1.data >> 1; PIN(shift)++; } uint32_t ret = endat_rx(df1.dataa, MIN(sizeof(df1.data), PIN(bytes)) * 8, &(ctx->data)); switch((int) PIN(endat_state)){ case 12: if(ctx->data.error_bit){ PIN(endat_state) = 0; PIN(error) = 1; PIN(state) = 0; } else{ PIN(state) = 1; PIN(error) = 0; } if(ret == 0){ PIN(endat_state) = 0; PIN(error) = 1; PIN(state) = 0; } break; default: PIN(state) = 0; if(ret == 0){ PIN(endat_state) = 0; } else{ PIN(endat_state)++; } } PIN(mpos) = ctx->data.mpos; PIN(f1) = ctx->data.error_bit; PIN(crc) = ctx->data.crc; PIN(pos_len) = ctx->data.pos_bits; PIN(mpos_len) = ctx->data.mpos_bits; PIN(pos_res) = ctx->data.pos_res; PIN(type) = ctx->data.fb_type; PIN(endat_error) = ctx->data.error.reg; PIN(endat_warning) = ctx->data.warning.reg; PIN(max_vel) = ctx->data.max_vel; if(ctx->data.pos_bits){ PIN(pos) = mod(ctx->data.pos * 2.0 * M_PI / (1 << ctx->data.pos_bits)); } //TODO: wait for busy flag? SPI3->CR1 &= ~SPI_CR1_SPE;//disable spi if(PIN(print_time) > 0.0){ PIN(timer) += period; } } static void nrt_func(void *ctx_ptr, hal_pin_inst_t *pin_ptr) { struct endat_ctx_t *ctx = (struct endat_ctx_t *)ctx_ptr; struct endat_pin_ctx_t *pins = (struct endat_pin_ctx_t *)pin_ptr; if(PIN(timer) > PIN(print_time)) { PIN(timer) = 0.0; uint64_t data = df.data; uint64_t reqdata = df2.data; uint64_t pos1 = ctx->data.pos; uint64_t pos2 = ctx->data.mpos; uint64_t crc = ctx->data.crc; uint32_t shift = PIN(shift); printf("req: "); switch(req){ case ENDAT_SELECT_MEM: printf("ENDAT_SELECT_MEM\n"); break; case ENDAT_READ_ADDR: printf("ENDAT_READ_ADDR\n"); break; case ENDAT_WRITE_ADDR: printf("ENDAT_WRITE_ADDR\n"); break; case ENDAT_READ_POS: printf("ENDAT_READ_POS\n"); break; default: printf("unkonwn req\n"); } printf("req data: "); for(int i = 0; i < 64; i++){ if(reqdata & 1){ printf("1"); } else{ printf("0"); } reqdata >>= 1; if(i == 8 - 1){ printf("-"); } if(i == 8 + 8 - 1){ printf("-"); } if(i == 8 + 8 + 16 - 1){ printf("-"); } if(i == 8 + 8 + 16 + 5 - 1){ printf("-"); } } printf("\n"); printf("data: "); for(int i = 0; i < 32; i++){ if(data & 1){ printf("1"); } else{ printf("0"); } data >>= 1; if(i == shift - 1){ printf("-"); } if(i == shift + 2 - 1){ printf("-"); } if(i == shift + 2 + ctx->data.pos_bits - 1){ printf("-"); } if(i == shift + 2 + ctx->data.pos_bits + ctx->data.mpos_bits - 1){ printf("-"); } } printf("\n"); printf("pos1: "); for(int i = 0; i < 64; i++){ if(pos1 & 1){ printf("1"); } else{ printf("0"); } pos1 >>= 1; if(i == ctx->data.pos_bits - 1){ printf("-"); } } printf("\n"); printf("pos2: "); for(int i = 0; i < 64; i++){ if(pos2 & 1){ printf("1"); } else{ printf("0"); } pos2 >>= 1; if(i == ctx->data.mpos_bits - 1){ printf("-"); } } printf("\n"); printf("crc: "); for(int i = 0; i < 64; i++){ if(crc & 1){ printf("1"); } else{ printf("0"); } crc >>= 1; if(i == 5 - 1){ printf("-"); } } printf("\n\n"); } } hal_comp_t endat_comp_struct = { .name = "endat", .nrt = nrt_func, .rt = rt_func, .frt = 0, .nrt_init = nrt_init, .rt_start = 0, .frt_start = 0, .rt_stop = 0, .frt_stop = 0, .ctx_size = sizeof(struct endat_ctx_t), .pin_count = sizeof(struct endat_pin_ctx_t) / sizeof(struct hal_pin_inst_t), };