Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
87e78ae8cThis file is pinned to the selected release. Download the original to open it in your design tool.
//using FB_TX
/*
Sanyo denki absolute encoder, tested with PA035C
10 0010001000000101 10 0001110110110000 10 0011011101001010 11
10001000100000010110000111011011000010001101110100101011
10....word A......10.....word B.....10......word C....11
2.5mbit
3 16 bit words
word A:
constant, alarm/model?
word B:
16 bit pos, LSB first
word C:
1. bit: MSB pos bit
2..15: checksum/multiturn?
*/
//TODO: error,ready pin, af mapping
#define NUM_OF_SAMPLES_S 400
#define TIM_FREQ 84.0
#define TIM_DIV 5.0
#define SIG_FREQ 2.5
#define OVER (TIM_FREQ / TIM_DIV / SIG_FREQ)//one bit
#define OFFSET (OVER / 2.0)//half bit
#define SIG_POS_START 16
COMP(encs);
HAL_PIN(en) = 1.0;
HAL_PIN(start) = 0.0;
HAL_PIN(offset) = 120.0;
HAL_PIN(d) = 0.0;
HAL_PIN(pos) = 0.0;
HAL_PIN(error) = 0.0;
HAL_PIN(cc);
MEM(volatile uint32_t buf[NUM_OF_SAMPLES_S + 1]);
MEM(volatile uint32_t buf2[24]);
RT_INIT(
GPIO_InitTypeDef GPIO_InitStruct;
//TX enable
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
//TODO: AF mapping
//TX
// 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_50MHz;
// GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL ;
// GPIO_Init(GPIOB, &GPIO_InitStruct);
// GPIO_ResetBits(GPIOB,GPIO_Pin_10);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_CtrlPWMOutputs(TIM2, ENABLE);
//RX
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
//TIM8 triggers DMA to sample reply
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 32;//14MHz
TIM_TimeBaseStructure.TIM_Prescaler = 1;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
TIM_ARRPreloadConfig(TIM8,ENABLE);
TIM_DMACmd(TIM8, TIM_DMA_Update, ENABLE);
TIM_Cmd(TIM8, ENABLE);
uint32_t foo = TIM2->CCER;
uint32_t bar = foo;
bar &= ~(1<<9);//0
foo |= (1<<9);//1
int pos = 0;
buf2[pos++] = foo;
buf2[pos++] = foo;
buf2[pos++] = foo;
buf2[pos++] = foo;
buf2[pos++] = bar;
buf2[pos++] = bar;
buf2[pos++] = foo;
buf2[pos++] = bar;
buf2[pos++] = bar;
buf2[pos++] = bar;
buf2[pos++] = bar;
buf2[pos++] = bar;
buf2[pos++] = bar;
buf2[pos++] = foo;
buf2[pos++] = bar;
buf2[pos++] = bar;
buf2[pos++] = bar;
buf2[pos++] = bar;
buf2[pos++] = bar;
buf2[pos++] = bar;
buf2[pos++] = foo;
buf2[pos++] = foo;
buf2[pos++] = foo;
buf2[pos++] = foo;
);
RT(
// DMA2-Config
DMA_Cmd(DMA2_Stream1, DISABLE);
DMA_DeInit(DMA2_Stream1);
DMA_InitStructure.DMA_Channel = DMA_Channel_7; //TIM8 ch1
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM2->CCER;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&buf2;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_BufferSize = 24;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream1, &DMA_InitStructure);
TIM8->ARR = 32;//2.545 Mhz
GPIOB->BSRRL = GPIO_Pin_12;//TX enable
DMA_Cmd(DMA2_Stream1, DISABLE);
DMA_ClearFlag(DMA2_Stream1, DMA_FLAG_TCIF1);
DMA_Cmd(DMA2_Stream1, ENABLE);
while (DMA_GetFlagStatus(DMA2_Stream1, DMA_FLAG_TCIF1) == RESET);
GPIOB->BSRRH = GPIO_Pin_12;//TX disable
//DMA2-Config
DMA_Cmd(DMA2_Stream1, DISABLE);
DMA_DeInit(DMA2_Stream1);
TIM8->ARR = 4;//16.8 Mhz
DMA_InitStructure.DMA_Channel = DMA_Channel_7; //TIM8 ch1
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&GPIOB->IDR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = NUM_OF_SAMPLES_S;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream1, &DMA_InitStructure);
if(PIN(en) > 0.0){
GPIOB->BSRRH = GPIO_Pin_3;
//start DMA
DMA_Cmd(DMA2_Stream1, DISABLE);
DMA_ClearFlag(DMA2_Stream1, DMA_FLAG_TCIF1);
DMA_Cmd(DMA2_Stream1, ENABLE);
//wait for DMA transfer complete
while (DMA_GetFlagStatus(DMA2_Stream1, DMA_FLAG_TCIF1) == RESET);
GPIOB->BSRRL = GPIO_Pin_3;
int i = 0;
//skip leading ones
for(; i < NUM_OF_SAMPLES_S/5; i++){
if(!(buf[i] & GPIO_Pin_11)){
break;
}
}
//skip zeros
for(; i < NUM_OF_SAMPLES_S/5; i++){
if(buf[i] & GPIO_Pin_11){
break;
}
}
int start = i + OFFSET;//position of first bit
int d = 0;
int p = 0;
p = CLAMP((int)((18 + SIG_POS_START) * OVER + start + 0.5), 0, NUM_OF_SAMPLES_S - 1);
d += (buf[p] & GPIO_Pin_11) != 0;
for(int j = 0; j < 16; j++){
p = CLAMP((int)(((15 - j) + SIG_POS_START) * OVER + start + 0.5), 0, NUM_OF_SAMPLES_S - 1);
d = d << 1;
d += (buf[p] & GPIO_Pin_11) != 0;
}
PIN(d) = d;
PIN(start) = start;
PIN(pos) = (d * M_PI * 2.0 / 131072.0) - M_PI;
}
);
ENDCOMP;